@@ -78,6 +78,9 @@ type serverTester struct {
7878 sc * serverConn
7979 testConnFramer
8080
81+ callsMu sync.Mutex
82+ calls []* serverHandlerCall
83+
8184 // If http2debug!=2, then we capture Frame debug logs that will be written
8285 // to t.Log after a test fails. The read and write logs use separate locks
8386 // and buffers so we don't accidentally introduce synchronization between
@@ -188,6 +191,10 @@ func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}
188191 h1server .ErrorLog = log .New (io .MultiWriter (stderrv (), twriter {t : t , st : st }, & st .serverLogBuf ), "" , log .LstdFlags )
189192 }
190193
194+ if handler == nil {
195+ handler = serverTesterHandler {st }.ServeHTTP
196+ }
197+
191198 t .Cleanup (func () {
192199 st .Close ()
193200 time .Sleep (goAwayTimeout ) // give server time to shut down
@@ -226,6 +233,50 @@ func (c *netConnWithConnectionState) ConnectionState() tls.ConnectionState {
226233 return c .state
227234}
228235
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+
229280// newServerTesterWithRealConn creates a test server listening on a localhost port.
230281// Mostly superseded by newServerTester, which creates a test server using a fake
231282// net.Conn and synthetic time. This function is still around because some benchmarks
@@ -350,6 +401,19 @@ func (st *serverTester) addLogFilter(phrase string) {
350401 st .logFilter = append (st .logFilter , phrase )
351402}
352403
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+
353417func (st * serverTester ) stream (id uint32 ) * stream {
354418 ch := make (chan * stream , 1 )
355419 st .sc .serveMsgCh <- func (int ) {
@@ -1265,15 +1329,11 @@ func testServer_Handler_Sends_WindowUpdate(t testing.TB) {
12651329 //
12661330 // This also needs to be less than MAX_FRAME_SIZE.
12671331 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 ) {
12721333 s .MaxUploadBufferPerConnection = windowSize
12731334 s .MaxUploadBufferPerStream = windowSize
12741335 })
12751336 defer st .Close ()
1276- defer puppet .done ()
12771337
12781338 st .greet ()
12791339 st .writeHeaders (HeadersFrameParam {
@@ -1282,13 +1342,14 @@ func testServer_Handler_Sends_WindowUpdate(t testing.TB) {
12821342 EndStream : false , // data coming
12831343 EndHeaders : true ,
12841344 })
1345+ call := st .nextHandlerCall ()
12851346
12861347 // Write less than half the max window of data and consume it.
12871348 // The server doesn't return flow control yet, buffering the 1024 bytes to
12881349 // combine with a future update.
12891350 data := make ([]byte , windowSize )
12901351 st .writeData (1 , false , data [:1024 ])
1291- puppet .do (readBodyHandler (t , string (data [:1024 ])))
1352+ call .do (readBodyHandler (t , string (data [:1024 ])))
12921353
12931354 // Write up to the window limit.
12941355 // The server returns the buffered credit.
@@ -1297,7 +1358,7 @@ func testServer_Handler_Sends_WindowUpdate(t testing.TB) {
12971358 st .wantWindowUpdate (1 , 1024 )
12981359
12991360 // 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 :])))
13011362 st .wantWindowUpdate (0 , windowSize - 1024 )
13021363 st .wantWindowUpdate (1 , windowSize - 1024 )
13031364}
@@ -1309,15 +1370,11 @@ func TestServer_Handler_Sends_WindowUpdate_Padding(t *testing.T) {
13091370}
13101371func testServer_Handler_Sends_WindowUpdate_Padding (t testing.TB ) {
13111372 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 ) {
13161374 s .MaxUploadBufferPerConnection = windowSize
13171375 s .MaxUploadBufferPerStream = windowSize
13181376 })
13191377 defer st .Close ()
1320- defer puppet .done ()
13211378
13221379 st .greet ()
13231380 st .writeHeaders (HeadersFrameParam {
@@ -1326,6 +1383,7 @@ func testServer_Handler_Sends_WindowUpdate_Padding(t testing.TB) {
13261383 EndStream : false ,
13271384 EndHeaders : true ,
13281385 })
1386+ call := st .nextHandlerCall ()
13291387
13301388 // Write half a window of data, with some padding.
13311389 // 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) {
13371395 // The handler consumes the body.
13381396 // The server returns flow control for the body and padding
13391397 // (4 bytes of padding + 1 byte of length).
1340- puppet .do (readBodyHandler (t , string (data )))
1398+ call .do (readBodyHandler (t , string (data )))
13411399 st .wantWindowUpdate (0 , uint32 (len (data )+ 1 + len (pad )))
13421400 st .wantWindowUpdate (1 , uint32 (len (data )+ 1 + len (pad )))
13431401}
0 commit comments