@@ -2,6 +2,7 @@ package middleware
2
2
3
3
import (
4
4
"bytes"
5
+ "context"
5
6
"errors"
6
7
"fmt"
7
8
"io/ioutil"
@@ -328,12 +329,13 @@ func TestTimeoutCanHandleContextDeadlineOnNextHandler(t *testing.T) {
328
329
func TestTimeoutWithFullEchoStack (t * testing.T ) {
329
330
// test timeout with full http server stack running, do see what http.Server.ErrorLog contains
330
331
var testCases = []struct {
331
- name string
332
- whenPath string
333
- expectStatusCode int
334
- expectResponse string
335
- expectLogContains []string
336
- expectLogNotContains []string
332
+ name string
333
+ whenPath string
334
+ whenForceHandlerTimeout bool
335
+ expectStatusCode int
336
+ expectResponse string
337
+ expectLogContains []string
338
+ expectLogNotContains []string
337
339
}{
338
340
{
339
341
name : "404 - write response in global error handler" ,
@@ -352,14 +354,15 @@ func TestTimeoutWithFullEchoStack(t *testing.T) {
352
354
expectLogContains : []string {`"status":418,"error":"",` },
353
355
},
354
356
{
355
- name : "503 - handler timeouts, write response in timeout middleware" ,
356
- whenPath : "/?delay=50ms" ,
357
- expectResponse : "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>" ,
358
- expectStatusCode : http .StatusServiceUnavailable ,
357
+ name : "503 - handler timeouts, write response in timeout middleware" ,
358
+ whenForceHandlerTimeout : true ,
359
+ whenPath : "/" ,
360
+ expectResponse : "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>" ,
361
+ expectStatusCode : http .StatusServiceUnavailable ,
359
362
expectLogNotContains : []string {
360
363
"echo:http: superfluous response.WriteHeader call from" ,
361
- "{" , // means that logger was not called.
362
364
},
365
+ expectLogContains : []string {"http: Handler timeout" },
363
366
},
364
367
}
365
368
@@ -371,21 +374,18 @@ func TestTimeoutWithFullEchoStack(t *testing.T) {
371
374
e .Logger .SetOutput (buf )
372
375
373
376
// NOTE: timeout middleware is first as it changes Response.Writer and causes data race for logger middleware if it is not first
374
- // FIXME: I have no idea how to fix this without adding mutexes.
375
377
e .Use (TimeoutWithConfig (TimeoutConfig {
376
378
Timeout : 15 * time .Millisecond ,
377
379
}))
378
380
e .Use (Logger ())
379
381
e .Use (Recover ())
380
382
383
+ wg := sync.WaitGroup {}
384
+ if tc .whenForceHandlerTimeout {
385
+ wg .Add (1 ) // make `wg.Wait()` block until we release it with `wg.Done()`
386
+ }
381
387
e .GET ("/" , func (c echo.Context ) error {
382
- var delay time.Duration
383
- if err := echo .QueryParamsBinder (c ).Duration ("delay" , & delay ).BindError (); err != nil {
384
- return err
385
- }
386
- if delay > 0 {
387
- time .Sleep (delay )
388
- }
388
+ wg .Wait ()
389
389
return c .JSON (http .StatusTeapot , map [string ]string {"message" : "OK" })
390
390
})
391
391
@@ -401,6 +401,13 @@ func TestTimeoutWithFullEchoStack(t *testing.T) {
401
401
assert .NoError (t , err )
402
402
return
403
403
}
404
+ if tc .whenForceHandlerTimeout {
405
+ wg .Done ()
406
+ // shutdown waits for server to shutdown. this way we wait logger mw to be executed
407
+ ctx , cancel := context .WithTimeout (context .Background (), 150 * time .Millisecond )
408
+ defer cancel ()
409
+ server .Shutdown (ctx )
410
+ }
404
411
405
412
assert .Equal (t , tc .expectStatusCode , res .StatusCode )
406
413
if body , err := ioutil .ReadAll (res .Body ); err == nil {
@@ -411,10 +418,10 @@ func TestTimeoutWithFullEchoStack(t *testing.T) {
411
418
412
419
logged := buf .String ()
413
420
for _ , subStr := range tc .expectLogContains {
414
- assert .True (t , strings .Contains (logged , subStr ))
421
+ assert .True (t , strings .Contains (logged , subStr ), "expected logs to contain: %v, logged: '%v'" , subStr , logged )
415
422
}
416
423
for _ , subStr := range tc .expectLogNotContains {
417
- assert .False (t , strings .Contains (logged , subStr ))
424
+ assert .False (t , strings .Contains (logged , subStr ), "expected logs not to contain: %v, logged: '%v'" , subStr , logged )
418
425
}
419
426
})
420
427
}
0 commit comments