@@ -78,6 +78,9 @@ type serverTester struct {
78
78
sc * serverConn
79
79
testConnFramer
80
80
81
+ callsMu sync.Mutex
82
+ calls []* serverHandlerCall
83
+
81
84
// If http2debug!=2, then we capture Frame debug logs that will be written
82
85
// to t.Log after a test fails. The read and write logs use separate locks
83
86
// and buffers so we don't accidentally introduce synchronization between
@@ -188,6 +191,10 @@ func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}
188
191
h1server .ErrorLog = log .New (io .MultiWriter (stderrv (), twriter {t : t , st : st }, & st .serverLogBuf ), "" , log .LstdFlags )
189
192
}
190
193
194
+ if handler == nil {
195
+ handler = serverTesterHandler {st }.ServeHTTP
196
+ }
197
+
191
198
t .Cleanup (func () {
192
199
st .Close ()
193
200
time .Sleep (goAwayTimeout ) // give server time to shut down
@@ -226,6 +233,50 @@ func (c *netConnWithConnectionState) ConnectionState() tls.ConnectionState {
226
233
return c .state
227
234
}
228
235
236
+ type serverTesterHandler struct {
237
+ st * serverTester
238
+ }
239
+
240
+ func (h serverTesterHandler ) ServeHTTP (w http.ResponseWriter , req * http.Request ) {
241
+ call := & serverHandlerCall {
242
+ w : w ,
243
+ req : req ,
244
+ ch : make (chan func ()),
245
+ }
246
+ h .st .t .Cleanup (call .exit )
247
+ h .st .callsMu .Lock ()
248
+ h .st .calls = append (h .st .calls , call )
249
+ h .st .callsMu .Unlock ()
250
+ for f := range call .ch {
251
+ f ()
252
+ }
253
+ }
254
+
255
+ // serverHandlerCall is a call to the server handler's ServeHTTP method.
256
+ type serverHandlerCall struct {
257
+ w http.ResponseWriter
258
+ req * http.Request
259
+ closeOnce sync.Once
260
+ ch chan func ()
261
+ }
262
+
263
+ // do executes f in the handler's goroutine.
264
+ func (call * serverHandlerCall ) do (f func (http.ResponseWriter , * http.Request )) {
265
+ donec := make (chan struct {})
266
+ call .ch <- func () {
267
+ defer close (donec )
268
+ f (call .w , call .req )
269
+ }
270
+ <- donec
271
+ }
272
+
273
+ // exit causes the handler to return.
274
+ func (call * serverHandlerCall ) exit () {
275
+ call .closeOnce .Do (func () {
276
+ close (call .ch )
277
+ })
278
+ }
279
+
229
280
// newServerTesterWithRealConn creates a test server listening on a localhost port.
230
281
// Mostly superseded by newServerTester, which creates a test server using a fake
231
282
// net.Conn and synthetic time. This function is still around because some benchmarks
@@ -350,6 +401,19 @@ func (st *serverTester) addLogFilter(phrase string) {
350
401
st .logFilter = append (st .logFilter , phrase )
351
402
}
352
403
404
+ func (st * serverTester ) nextHandlerCall () * serverHandlerCall {
405
+ st .t .Helper ()
406
+ synctest .Wait ()
407
+ st .callsMu .Lock ()
408
+ defer st .callsMu .Unlock ()
409
+ if len (st .calls ) == 0 {
410
+ st .t .Fatal ("expected server handler call, got none" )
411
+ }
412
+ call := st .calls [0 ]
413
+ st .calls = st .calls [1 :]
414
+ return call
415
+ }
416
+
353
417
func (st * serverTester ) stream (id uint32 ) * stream {
354
418
ch := make (chan * stream , 1 )
355
419
st .sc .serveMsgCh <- func (int ) {
@@ -1265,15 +1329,11 @@ func testServer_Handler_Sends_WindowUpdate(t testing.TB) {
1265
1329
//
1266
1330
// This also needs to be less than MAX_FRAME_SIZE.
1267
1331
const windowSize = 65535 * 2
1268
- puppet := newHandlerPuppet ()
1269
- st := newServerTester (t , func (w http.ResponseWriter , r * http.Request ) {
1270
- puppet .act (w , r )
1271
- }, func (s * Server ) {
1332
+ st := newServerTester (t , nil , func (s * Server ) {
1272
1333
s .MaxUploadBufferPerConnection = windowSize
1273
1334
s .MaxUploadBufferPerStream = windowSize
1274
1335
})
1275
1336
defer st .Close ()
1276
- defer puppet .done ()
1277
1337
1278
1338
st .greet ()
1279
1339
st .writeHeaders (HeadersFrameParam {
@@ -1282,13 +1342,14 @@ func testServer_Handler_Sends_WindowUpdate(t testing.TB) {
1282
1342
EndStream : false , // data coming
1283
1343
EndHeaders : true ,
1284
1344
})
1345
+ call := st .nextHandlerCall ()
1285
1346
1286
1347
// Write less than half the max window of data and consume it.
1287
1348
// The server doesn't return flow control yet, buffering the 1024 bytes to
1288
1349
// combine with a future update.
1289
1350
data := make ([]byte , windowSize )
1290
1351
st .writeData (1 , false , data [:1024 ])
1291
- puppet .do (readBodyHandler (t , string (data [:1024 ])))
1352
+ call .do (readBodyHandler (t , string (data [:1024 ])))
1292
1353
1293
1354
// Write up to the window limit.
1294
1355
// The server returns the buffered credit.
@@ -1297,7 +1358,7 @@ func testServer_Handler_Sends_WindowUpdate(t testing.TB) {
1297
1358
st .wantWindowUpdate (1 , 1024 )
1298
1359
1299
1360
// The handler consumes the data and the server returns credit.
1300
- puppet .do (readBodyHandler (t , string (data [1024 :])))
1361
+ call .do (readBodyHandler (t , string (data [1024 :])))
1301
1362
st .wantWindowUpdate (0 , windowSize - 1024 )
1302
1363
st .wantWindowUpdate (1 , windowSize - 1024 )
1303
1364
}
@@ -1309,15 +1370,11 @@ func TestServer_Handler_Sends_WindowUpdate_Padding(t *testing.T) {
1309
1370
}
1310
1371
func testServer_Handler_Sends_WindowUpdate_Padding (t testing.TB ) {
1311
1372
const windowSize = 65535 * 2
1312
- puppet := newHandlerPuppet ()
1313
- st := newServerTester (t , func (w http.ResponseWriter , r * http.Request ) {
1314
- puppet .act (w , r )
1315
- }, func (s * Server ) {
1373
+ st := newServerTester (t , nil , func (s * Server ) {
1316
1374
s .MaxUploadBufferPerConnection = windowSize
1317
1375
s .MaxUploadBufferPerStream = windowSize
1318
1376
})
1319
1377
defer st .Close ()
1320
- defer puppet .done ()
1321
1378
1322
1379
st .greet ()
1323
1380
st .writeHeaders (HeadersFrameParam {
@@ -1326,6 +1383,7 @@ func testServer_Handler_Sends_WindowUpdate_Padding(t testing.TB) {
1326
1383
EndStream : false ,
1327
1384
EndHeaders : true ,
1328
1385
})
1386
+ call := st .nextHandlerCall ()
1329
1387
1330
1388
// Write half a window of data, with some padding.
1331
1389
// The server doesn't return the padding yet, buffering the 5 bytes to combine
@@ -1337,7 +1395,7 @@ func testServer_Handler_Sends_WindowUpdate_Padding(t testing.TB) {
1337
1395
// The handler consumes the body.
1338
1396
// The server returns flow control for the body and padding
1339
1397
// (4 bytes of padding + 1 byte of length).
1340
- puppet .do (readBodyHandler (t , string (data )))
1398
+ call .do (readBodyHandler (t , string (data )))
1341
1399
st .wantWindowUpdate (0 , uint32 (len (data )+ 1 + len (pad )))
1342
1400
st .wantWindowUpdate (1 , uint32 (len (data )+ 1 + len (pad )))
1343
1401
}
0 commit comments