mirror of
https://github.com/labstack/echo.git
synced 2024-12-24 20:14:31 +02:00
Timeout mw: rework how test waits for timeout. Using sleep as delay i… (#2187)
* Timeout mw: rework how test waits for timeout. Using sleep as delay is problematic when CI worker is slower than usual.
This commit is contained in:
parent
28797c761d
commit
d5f883707b
@ -2,6 +2,7 @@ package middleware
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -330,6 +331,7 @@ func TestTimeoutWithFullEchoStack(t *testing.T) {
|
|||||||
var testCases = []struct {
|
var testCases = []struct {
|
||||||
name string
|
name string
|
||||||
whenPath string
|
whenPath string
|
||||||
|
whenForceHandlerTimeout bool
|
||||||
expectStatusCode int
|
expectStatusCode int
|
||||||
expectResponse string
|
expectResponse string
|
||||||
expectLogContains []string
|
expectLogContains []string
|
||||||
@ -353,13 +355,14 @@ func TestTimeoutWithFullEchoStack(t *testing.T) {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "503 - handler timeouts, write response in timeout middleware",
|
name: "503 - handler timeouts, write response in timeout middleware",
|
||||||
whenPath: "/?delay=50ms",
|
whenForceHandlerTimeout: true,
|
||||||
|
whenPath: "/",
|
||||||
expectResponse: "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>",
|
expectResponse: "<html><head><title>Timeout</title></head><body><h1>Timeout</h1></body></html>",
|
||||||
expectStatusCode: http.StatusServiceUnavailable,
|
expectStatusCode: http.StatusServiceUnavailable,
|
||||||
expectLogNotContains: []string{
|
expectLogNotContains: []string{
|
||||||
"echo:http: superfluous response.WriteHeader call from",
|
"echo:http: superfluous response.WriteHeader call from",
|
||||||
"{", // means that logger was not called.
|
|
||||||
},
|
},
|
||||||
|
expectLogContains: []string{"http: Handler timeout"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,21 +374,18 @@ func TestTimeoutWithFullEchoStack(t *testing.T) {
|
|||||||
e.Logger.SetOutput(buf)
|
e.Logger.SetOutput(buf)
|
||||||
|
|
||||||
// NOTE: timeout middleware is first as it changes Response.Writer and causes data race for logger middleware if it is not first
|
// NOTE: timeout middleware is first as it changes Response.Writer and causes data race for logger middleware if it is not first
|
||||||
// FIXME: I have no idea how to fix this without adding mutexes.
|
|
||||||
e.Use(TimeoutWithConfig(TimeoutConfig{
|
e.Use(TimeoutWithConfig(TimeoutConfig{
|
||||||
Timeout: 15 * time.Millisecond,
|
Timeout: 15 * time.Millisecond,
|
||||||
}))
|
}))
|
||||||
e.Use(Logger())
|
e.Use(Logger())
|
||||||
e.Use(Recover())
|
e.Use(Recover())
|
||||||
|
|
||||||
|
wg := sync.WaitGroup{}
|
||||||
|
if tc.whenForceHandlerTimeout {
|
||||||
|
wg.Add(1) // make `wg.Wait()` block until we release it with `wg.Done()`
|
||||||
|
}
|
||||||
e.GET("/", func(c echo.Context) error {
|
e.GET("/", func(c echo.Context) error {
|
||||||
var delay time.Duration
|
wg.Wait()
|
||||||
if err := echo.QueryParamsBinder(c).Duration("delay", &delay).BindError(); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if delay > 0 {
|
|
||||||
time.Sleep(delay)
|
|
||||||
}
|
|
||||||
return c.JSON(http.StatusTeapot, map[string]string{"message": "OK"})
|
return c.JSON(http.StatusTeapot, map[string]string{"message": "OK"})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -401,6 +401,13 @@ func TestTimeoutWithFullEchoStack(t *testing.T) {
|
|||||||
assert.NoError(t, err)
|
assert.NoError(t, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
if tc.whenForceHandlerTimeout {
|
||||||
|
wg.Done()
|
||||||
|
// shutdown waits for server to shutdown. this way we wait logger mw to be executed
|
||||||
|
ctx, cancel := context.WithTimeout(context.Background(), 150*time.Millisecond)
|
||||||
|
defer cancel()
|
||||||
|
server.Shutdown(ctx)
|
||||||
|
}
|
||||||
|
|
||||||
assert.Equal(t, tc.expectStatusCode, res.StatusCode)
|
assert.Equal(t, tc.expectStatusCode, res.StatusCode)
|
||||||
if body, err := ioutil.ReadAll(res.Body); err == nil {
|
if body, err := ioutil.ReadAll(res.Body); err == nil {
|
||||||
@ -411,10 +418,10 @@ func TestTimeoutWithFullEchoStack(t *testing.T) {
|
|||||||
|
|
||||||
logged := buf.String()
|
logged := buf.String()
|
||||||
for _, subStr := range tc.expectLogContains {
|
for _, subStr := range tc.expectLogContains {
|
||||||
assert.True(t, strings.Contains(logged, subStr))
|
assert.True(t, strings.Contains(logged, subStr), "expected logs to contain: %v, logged: '%v'", subStr, logged)
|
||||||
}
|
}
|
||||||
for _, subStr := range tc.expectLogNotContains {
|
for _, subStr := range tc.expectLogNotContains {
|
||||||
assert.False(t, strings.Contains(logged, subStr))
|
assert.False(t, strings.Contains(logged, subStr), "expected logs not to contain: %v, logged: '%v'", subStr, logged)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user