diff --git a/app.go b/app.go index e1e607e6fa..c4a26e7772 100644 --- a/app.go +++ b/app.go @@ -14,9 +14,11 @@ import ( "encoding/xml" "errors" "fmt" + "io" "net" "net/http" "net/http/httputil" + "os" "reflect" "strconv" "strings" @@ -901,13 +903,33 @@ func (app *App) Hooks() *Hooks { return app.hooks } +// TestConfig is a struct holding Test settings +type TestConfig struct { + // Timeout defines the maximum duration a + // test can run before timing out. + // Default: time.Second + Timeout time.Duration + + // FailOnTimeout specifies whether the test + // should return a timeout error if the HTTP response + // exceeds the Timeout duration. + // Default: true + FailOnTimeout bool +} + // Test is used for internal debugging by passing a *http.Request. -// Timeout is optional and defaults to 1s, -1 will disable it completely. -func (app *App) Test(req *http.Request, timeout ...time.Duration) (*http.Response, error) { - // Set timeout - to := 1 * time.Second - if len(timeout) > 0 { - to = timeout[0] +// Config is optional and defaults to a 1s error on timeout, +// 0 timeout will disable it completely. +func (app *App) Test(req *http.Request, config ...TestConfig) (*http.Response, error) { + // Default config + cfg := TestConfig{ + Timeout: time.Second, + FailOnTimeout: true, + } + + // Override config if provided + if len(config) > 0 { + cfg = config[0] } // Add Content-Length if not provided with body @@ -946,12 +968,15 @@ func (app *App) Test(req *http.Request, timeout ...time.Duration) (*http.Respons }() // Wait for callback - if to >= 0 { + if cfg.Timeout > 0 { // With timeout select { case err = <-channel: - case <-time.After(to): - return nil, fmt.Errorf("test: timeout error after %s", to) + case <-time.After(cfg.Timeout): + conn.Close() //nolint:errcheck, revive // It is fine to ignore the error here + if cfg.FailOnTimeout { + return nil, os.ErrDeadlineExceeded + } } } else { // Without timeout @@ -969,6 +994,9 @@ func (app *App) Test(req *http.Request, timeout ...time.Duration) (*http.Respons // Convert raw http response to *http.Response res, err := http.ReadResponse(buffer, req) if err != nil { + if errors.Is(err, io.ErrUnexpectedEOF) { + return nil, errors.New("test: got empty response") + } return nil, fmt.Errorf("failed to read response: %w", err) } diff --git a/app_test.go b/app_test.go index 9699c85bce..a99796a2c1 100644 --- a/app_test.go +++ b/app_test.go @@ -16,6 +16,7 @@ import ( "net" "net/http" "net/http/httptest" + "os" "reflect" "regexp" "runtime" @@ -1124,7 +1125,9 @@ func Test_Test_Timeout(t *testing.T) { app.Get("/", testEmptyHandler) - resp, err := app.Test(httptest.NewRequest(MethodGet, "/", nil), -1) + resp, err := app.Test(httptest.NewRequest(MethodGet, "/", nil), TestConfig{ + Timeout: 0, + }) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") @@ -1133,7 +1136,10 @@ func Test_Test_Timeout(t *testing.T) { return nil }) - _, err = app.Test(httptest.NewRequest(MethodGet, "/timeout", nil), 20*time.Millisecond) + _, err = app.Test(httptest.NewRequest(MethodGet, "/timeout", nil), TestConfig{ + Timeout: 20 * time.Millisecond, + FailOnTimeout: true, + }) require.Error(t, err, "app.Test(req)") } @@ -1432,7 +1438,9 @@ func Test_App_Test_no_timeout_infinitely(t *testing.T) { }) req := httptest.NewRequest(MethodGet, "/", nil) - _, err = app.Test(req, -1) + _, err = app.Test(req, TestConfig{ + Timeout: 0, + }) }() tk := time.NewTimer(5 * time.Second) @@ -1460,8 +1468,27 @@ func Test_App_Test_timeout(t *testing.T) { return nil }) - _, err := app.Test(httptest.NewRequest(MethodGet, "/", nil), 100*time.Millisecond) - require.Equal(t, errors.New("test: timeout error after 100ms"), err) + _, err := app.Test(httptest.NewRequest(MethodGet, "/", nil), TestConfig{ + Timeout: 100 * time.Millisecond, + FailOnTimeout: true, + }) + require.Equal(t, os.ErrDeadlineExceeded, err) +} + +func Test_App_Test_timeout_empty_response(t *testing.T) { + t.Parallel() + + app := New() + app.Get("/", func(_ Ctx) error { + time.Sleep(1 * time.Second) + return nil + }) + + _, err := app.Test(httptest.NewRequest(MethodGet, "/", nil), TestConfig{ + Timeout: 100 * time.Millisecond, + FailOnTimeout: false, + }) + require.Equal(t, errors.New("test: got empty response"), err) } func Test_App_SetTLSHandler(t *testing.T) { diff --git a/ctx_test.go b/ctx_test.go index af56197c58..6254f5dfdf 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -3243,7 +3243,10 @@ func Test_Static_Compress(t *testing.T) { req := httptest.NewRequest(MethodGet, "/file", nil) req.Header.Set("Accept-Encoding", algo) - resp, err := app.Test(req, 10*time.Second) + resp, err := app.Test(req, TestConfig{ + Timeout: 10 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") diff --git a/docs/api/app.md b/docs/api/app.md index 8c7f8979bc..6582159c0f 100644 --- a/docs/api/app.md +++ b/docs/api/app.md @@ -641,10 +641,10 @@ func (app *App) SetTLSHandler(tlsHandler *TLSHandler) ## Test -Testing your application is done with the `Test` method. Use this method for creating `_test.go` files or when you need to debug your routing logic. The default timeout is `1s`; to disable a timeout altogether, pass `-1` as the second argument. +Testing your application is done with the `Test` method. Use this method for creating `_test.go` files or when you need to debug your routing logic. The default timeout is `1s`; to disable a timeout altogether, pass a `TestConfig` struct with `Timeout: 0`. ```go title="Signature" -func (app *App) Test(req *http.Request, msTimeout ...int) (*http.Response, error) +func (app *App) Test(req *http.Request, config ...TestConfig) (*http.Response, error) ``` ```go title="Example" @@ -685,6 +685,31 @@ func main() { } ``` +If not provided, TestConfig is set to the following defaults: + +```go title="Default TestConfig" +config := fiber.TestConfig{ + Timeout: time.Second(), + FailOnTimeout: true, +} +``` + +:::caution + +This is **not** the same as supplying an empty `TestConfig{}` to +`app.Test(), but rather be the equivalent of supplying: + +```go title="Empty TestConfig" +cfg := fiber.TestConfig{ + Timeout: 0, + FailOnTimeout: false, +} +``` + +This would make a Test that has no timeout. + +::: + ## Hooks `Hooks` is a method to return the [hooks](./hooks.md) property. diff --git a/docs/whats_new.md b/docs/whats_new.md index 0a47dca491..8677a0080f 100644 --- a/docs/whats_new.md +++ b/docs/whats_new.md @@ -75,7 +75,8 @@ We have made several changes to the Fiber app, including: ### Methods changes -- Test -> timeout changed to 1 second +- Test -> Replaced timeout with a config parameter + - -1 represents no timeout -> 0 represents no timeout - Listen -> has a config parameter - Listener -> has a config parameter @@ -184,6 +185,68 @@ To enable the routing changes above we had to slightly adjust the signature of t + Add(methods []string, path string, handler Handler, middleware ...Handler) Router ``` +### Test Config + +The `app.Test()` method now allows users to customize their test configurations: + +
+Example + +```go +// Create a test app with a handler to test +app := fiber.New() +app.Get("/", func(c fiber.Ctx) { + return c.SendString("hello world") +}) + +// Define the HTTP request and custom TestConfig to test the handler +req := httptest.NewRequest(MethodGet, "/", nil) +testConfig := fiber.TestConfig{ + Timeout: 0, + FailOnTimeout: false, +} + +// Test the handler using the request and testConfig +resp, err := app.Test(req, testConfig) +``` + +
+ +To provide configurable testing capabilities, we had to change +the signature of the `Test` method. + +```diff +- Test(req *http.Request, timeout ...time.Duration) (*http.Response, error) ++ Test(req *http.Request, config ...fiber.TestConfig) (*http.Response, error) +``` + +The `TestConfig` struct provides the following configuration options: + +- `Timeout`: The duration to wait before timing out the test. Use 0 for no timeout. +- `FailOnTimeout`: Controls the behavior when a timeout occurs: + - When true, the test will return an `os.ErrDeadlineExceeded` if the test exceeds the `Timeout` duration. + - When false, the test will return the partial response received before timing out. + +If a custom `TestConfig` isn't provided, then the following will be used: + +```go +testConfig := fiber.TestConfig{ + Timeout: time.Second, + FailOnTimeout: true, +} +``` + +**Note:** Using this default is **NOT** the same as providing an empty `TestConfig` as an argument to `app.Test()`. + +An empty `TestConfig` is the equivalent of: + +```go +testConfig := fiber.TestConfig{ + Timeout: 0, + FailOnTimeout: false, +} +``` + --- ## 🧠 Context diff --git a/helpers.go b/helpers.go index 90621b1c42..526074032a 100644 --- a/helpers.go +++ b/helpers.go @@ -613,13 +613,36 @@ func isNoCache(cacheControl string) bool { } type testConn struct { - r bytes.Buffer - w bytes.Buffer + r bytes.Buffer + w bytes.Buffer + isClosed bool + sync.Mutex } -func (c *testConn) Read(b []byte) (int, error) { return c.r.Read(b) } //nolint:wrapcheck // This must not be wrapped -func (c *testConn) Write(b []byte) (int, error) { return c.w.Write(b) } //nolint:wrapcheck // This must not be wrapped -func (*testConn) Close() error { return nil } +func (c *testConn) Read(b []byte) (int, error) { + c.Lock() + defer c.Unlock() + + return c.r.Read(b) //nolint:wrapcheck // This must not be wrapped +} + +func (c *testConn) Write(b []byte) (int, error) { + c.Lock() + defer c.Unlock() + + if c.isClosed { + return 0, errors.New("testConn is closed") + } + return c.w.Write(b) //nolint:wrapcheck // This must not be wrapped +} + +func (c *testConn) Close() error { + c.Lock() + defer c.Unlock() + + c.isClosed = true + return nil +} func (*testConn) LocalAddr() net.Addr { return &net.TCPAddr{Port: 0, Zone: "", IP: net.IPv4zero} } func (*testConn) RemoteAddr() net.Addr { return &net.TCPAddr{Port: 0, Zone: "", IP: net.IPv4zero} } diff --git a/helpers_test.go b/helpers_test.go index ddee434098..28a5df2ae7 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -514,6 +514,48 @@ func Test_Utils_TestConn_Deadline(t *testing.T) { require.NoError(t, conn.SetWriteDeadline(time.Time{})) } +func Test_Utils_TestConn_ReadWrite(t *testing.T) { + t.Parallel() + conn := &testConn{} + + // Verify read of request + _, err := conn.r.Write([]byte("Request")) + require.NoError(t, err) + + req := make([]byte, 7) + _, err = conn.Read(req) + require.NoError(t, err) + require.Equal(t, []byte("Request"), req) + + // Verify write of response + _, err = conn.Write([]byte("Response")) + require.NoError(t, err) + + res := make([]byte, 8) + _, err = conn.w.Read(res) + require.NoError(t, err) + require.Equal(t, []byte("Response"), res) +} + +func Test_Utils_TestConn_Closed_Write(t *testing.T) { + t.Parallel() + conn := &testConn{} + + // Verify write of response + _, err := conn.Write([]byte("Response 1\n")) + require.NoError(t, err) + + // Close early, write should fail + conn.Close() //nolint:errcheck, revive // It is fine to ignore the error here + _, err = conn.Write([]byte("Response 2\n")) + require.Error(t, err) + + res := make([]byte, 11) + _, err = conn.w.Read(res) + require.NoError(t, err) + require.Equal(t, []byte("Response 1\n"), res) +} + func Test_Utils_IsNoCache(t *testing.T) { t.Parallel() testCases := []struct { diff --git a/middleware/compress/compress_test.go b/middleware/compress/compress_test.go index f258ba4460..da482fe77b 100644 --- a/middleware/compress/compress_test.go +++ b/middleware/compress/compress_test.go @@ -16,6 +16,11 @@ import ( var filedata []byte +var testConfig = fiber.TestConfig{ + Timeout: 10 * time.Second, + FailOnTimeout: true, +} + func init() { dat, err := os.ReadFile("../../.github/README.md") if err != nil { @@ -39,7 +44,7 @@ func Test_Compress_Gzip(t *testing.T) { req := httptest.NewRequest(fiber.MethodGet, "/", nil) req.Header.Set("Accept-Encoding", "gzip") - resp, err := app.Test(req, 10*time.Second) + resp, err := app.Test(req, testConfig) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") require.Equal(t, "gzip", resp.Header.Get(fiber.HeaderContentEncoding)) @@ -72,7 +77,7 @@ func Test_Compress_Different_Level(t *testing.T) { req := httptest.NewRequest(fiber.MethodGet, "/", nil) req.Header.Set("Accept-Encoding", algo) - resp, err := app.Test(req, 10*time.Second) + resp, err := app.Test(req, testConfig) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") require.Equal(t, algo, resp.Header.Get(fiber.HeaderContentEncoding)) @@ -99,7 +104,7 @@ func Test_Compress_Deflate(t *testing.T) { req := httptest.NewRequest(fiber.MethodGet, "/", nil) req.Header.Set("Accept-Encoding", "deflate") - resp, err := app.Test(req, 10*time.Second) + resp, err := app.Test(req, testConfig) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") require.Equal(t, "deflate", resp.Header.Get(fiber.HeaderContentEncoding)) @@ -123,7 +128,7 @@ func Test_Compress_Brotli(t *testing.T) { req := httptest.NewRequest(fiber.MethodGet, "/", nil) req.Header.Set("Accept-Encoding", "br") - resp, err := app.Test(req, 10*time.Second) + resp, err := app.Test(req, testConfig) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") require.Equal(t, "br", resp.Header.Get(fiber.HeaderContentEncoding)) @@ -147,7 +152,7 @@ func Test_Compress_Zstd(t *testing.T) { req := httptest.NewRequest(fiber.MethodGet, "/", nil) req.Header.Set("Accept-Encoding", "zstd") - resp, err := app.Test(req, 10*time.Second) + resp, err := app.Test(req, testConfig) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") require.Equal(t, "zstd", resp.Header.Get(fiber.HeaderContentEncoding)) @@ -171,7 +176,7 @@ func Test_Compress_Disabled(t *testing.T) { req := httptest.NewRequest(fiber.MethodGet, "/", nil) req.Header.Set("Accept-Encoding", "br") - resp, err := app.Test(req, 10*time.Second) + resp, err := app.Test(req, testConfig) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") require.Equal(t, "", resp.Header.Get(fiber.HeaderContentEncoding)) diff --git a/middleware/idempotency/idempotency_test.go b/middleware/idempotency/idempotency_test.go index 91394ca26a..56b10d9c03 100644 --- a/middleware/idempotency/idempotency_test.go +++ b/middleware/idempotency/idempotency_test.go @@ -82,7 +82,10 @@ func Test_Idempotency(t *testing.T) { if idempotencyKey != "" { req.Header.Set("X-Idempotency-Key", idempotencyKey) } - resp, err := app.Test(req, 15*time.Second) + resp, err := app.Test(req, fiber.TestConfig{ + Timeout: 15 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err) body, err := io.ReadAll(resp.Body) require.NoError(t, err) diff --git a/middleware/keyauth/keyauth_test.go b/middleware/keyauth/keyauth_test.go index 9da675fe8f..72c9d3c1b4 100644 --- a/middleware/keyauth/keyauth_test.go +++ b/middleware/keyauth/keyauth_test.go @@ -14,6 +14,10 @@ import ( const CorrectKey = "specials: !$%,.#\"!?~`<>@$^*(){}[]|/\\123" +var testConfig = fiber.TestConfig{ + Timeout: 0, +} + func Test_AuthSources(t *testing.T) { // define test cases testSources := []string{"header", "cookie", "query", "param", "form"} @@ -104,7 +108,7 @@ func Test_AuthSources(t *testing.T) { req.URL.Path = r } - res, err := app.Test(req, -1) + res, err := app.Test(req, testConfig) require.NoError(t, err, test.description) @@ -209,7 +213,7 @@ func TestMultipleKeyLookup(t *testing.T) { q.Add("key", CorrectKey) req.URL.RawQuery = q.Encode() - res, err := app.Test(req, -1) + res, err := app.Test(req, testConfig) require.NoError(t, err) @@ -226,7 +230,7 @@ func TestMultipleKeyLookup(t *testing.T) { // construct a second request without proper key req, err = http.NewRequestWithContext(context.Background(), fiber.MethodGet, "/foo", nil) require.NoError(t, err) - res, err = app.Test(req, -1) + res, err = app.Test(req, testConfig) require.NoError(t, err) errBody, err := io.ReadAll(res.Body) require.NoError(t, err) @@ -350,7 +354,7 @@ func Test_MultipleKeyAuth(t *testing.T) { req.Header.Set("key", test.APIKey) } - res, err := app.Test(req, -1) + res, err := app.Test(req, testConfig) require.NoError(t, err, test.description) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index b69668f336..946db05d80 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -300,7 +300,10 @@ func Test_Logger_WithLatency(t *testing.T) { sleepDuration = 1 * tu.div // Create a new HTTP request to the test route - resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 3*time.Second) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), fiber.TestConfig{ + Timeout: 3 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err) require.Equal(t, fiber.StatusOK, resp.StatusCode) @@ -341,7 +344,10 @@ func Test_Logger_WithLatency_DefaultFormat(t *testing.T) { sleepDuration = 1 * tu.div // Create a new HTTP request to the test route - resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 2*time.Second) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err) require.Equal(t, fiber.StatusOK, resp.StatusCode) diff --git a/middleware/pprof/pprof_test.go b/middleware/pprof/pprof_test.go index 7a279d488d..874ca104a9 100644 --- a/middleware/pprof/pprof_test.go +++ b/middleware/pprof/pprof_test.go @@ -11,6 +11,11 @@ import ( "github.com/stretchr/testify/require" ) +var testConfig = fiber.TestConfig{ + Timeout: 5 * time.Second, + FailOnTimeout: true, +} + func Test_Non_Pprof_Path(t *testing.T) { app := fiber.New() @@ -105,7 +110,7 @@ func Test_Pprof_Subs(t *testing.T) { if sub == "profile" { target += "?seconds=1" } - resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, target, nil), 5*time.Second) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, target, nil), testConfig) require.NoError(t, err) require.Equal(t, 200, resp.StatusCode) }) @@ -132,7 +137,7 @@ func Test_Pprof_Subs_WithPrefix(t *testing.T) { if sub == "profile" { target += "?seconds=1" } - resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, target, nil), 5*time.Second) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, target, nil), testConfig) require.NoError(t, err) require.Equal(t, 200, resp.StatusCode) }) diff --git a/middleware/proxy/proxy_test.go b/middleware/proxy/proxy_test.go index 713488a52b..a810825135 100644 --- a/middleware/proxy/proxy_test.go +++ b/middleware/proxy/proxy_test.go @@ -2,10 +2,10 @@ package proxy import ( "crypto/tls" - "errors" "io" "net" "net/http/httptest" + "os" "strings" "testing" "time" @@ -110,7 +110,10 @@ func Test_Proxy(t *testing.T) { return c.SendStatus(fiber.StatusTeapot) }) - resp, err := target.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), 2*time.Second) + resp, err := target.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err) require.Equal(t, fiber.StatusTeapot, resp.StatusCode) @@ -172,7 +175,10 @@ func Test_Proxy_Balancer_IPv6_Upstream(t *testing.T) { return c.SendStatus(fiber.StatusTeapot) }) - resp, err := target.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), 2*time.Second) + resp, err := target.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err) require.Equal(t, fiber.StatusTeapot, resp.StatusCode) @@ -195,7 +201,10 @@ func Test_Proxy_Balancer_IPv6_Upstream_With_DialDualStack(t *testing.T) { return c.SendStatus(fiber.StatusTeapot) }) - resp, err := target.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), 2*time.Second) + resp, err := target.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err) require.Equal(t, fiber.StatusTeapot, resp.StatusCode) @@ -221,7 +230,10 @@ func Test_Proxy_Balancer_IPv4_Upstream_With_DialDualStack(t *testing.T) { return c.SendStatus(fiber.StatusTeapot) }) - resp, err := target.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), 2*time.Second) + resp, err := target.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err) require.Equal(t, fiber.StatusTeapot, resp.StatusCode) @@ -399,7 +411,10 @@ func Test_Proxy_Timeout_Slow_Server(t *testing.T) { Timeout: 600 * time.Millisecond, })) - resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), 2*time.Second) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err) require.Equal(t, fiber.StatusOK, resp.StatusCode) @@ -423,7 +438,10 @@ func Test_Proxy_With_Timeout(t *testing.T) { Timeout: 100 * time.Millisecond, })) - resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), 2*time.Second) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err) require.Equal(t, fiber.StatusInternalServerError, resp.StatusCode) @@ -521,7 +539,10 @@ func Test_Proxy_DoRedirects_RestoreOriginalURL(t *testing.T) { return DoRedirects(c, "http://google.com", 1) }) - resp, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 2*time.Second) + resp, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err1) _, err := io.ReadAll(resp.Body) require.NoError(t, err) @@ -559,7 +580,10 @@ func Test_Proxy_DoTimeout_RestoreOriginalURL(t *testing.T) { return DoTimeout(c, "http://"+addr, time.Second) }) - resp, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 2*time.Second) + resp, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err1) body, err := io.ReadAll(resp.Body) require.NoError(t, err) @@ -580,7 +604,10 @@ func Test_Proxy_DoTimeout_Timeout(t *testing.T) { return DoTimeout(c, "http://"+addr, time.Second) }) - resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 2*time.Second) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err) body, err := io.ReadAll(resp.Body) require.NoError(t, err) @@ -624,8 +651,11 @@ func Test_Proxy_DoDeadline_PastDeadline(t *testing.T) { return DoDeadline(c, "http://"+addr, time.Now().Add(2*time.Second)) }) - _, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 1*time.Second) - require.Equal(t, errors.New("test: timeout error after 1s"), err1) + _, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), fiber.TestConfig{ + Timeout: 1 * time.Second, + FailOnTimeout: true, + }) + require.Equal(t, os.ErrDeadlineExceeded, err1) } // go test -race -run Test_Proxy_Do_HTTP_Prefix_URL @@ -717,7 +747,10 @@ func Test_ProxyBalancer_Custom_Client(t *testing.T) { return c.SendStatus(fiber.StatusTeapot) }) - resp, err := target.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), 2*time.Second) + resp, err := target.Test(httptest.NewRequest(fiber.MethodGet, "/", nil), fiber.TestConfig{ + Timeout: 2 * time.Second, + FailOnTimeout: true, + }) require.NoError(t, err) require.Equal(t, fiber.StatusTeapot, resp.StatusCode) diff --git a/middleware/static/static_test.go b/middleware/static/static_test.go index 4d736b0c43..4e1d7a96d8 100644 --- a/middleware/static/static_test.go +++ b/middleware/static/static_test.go @@ -15,6 +15,11 @@ import ( "github.com/stretchr/testify/require" ) +var testConfig = fiber.TestConfig{ + Timeout: 10 * time.Second, + FailOnTimeout: true, +} + // go test -run Test_Static_Index_Default func Test_Static_Index_Default(t *testing.T) { t.Parallel() @@ -738,7 +743,7 @@ func Test_Static_Compress(t *testing.T) { // request non-compressable file (less than 200 bytes), Content Lengh will remain the same req := httptest.NewRequest(fiber.MethodGet, "/css/style.css", nil) req.Header.Set("Accept-Encoding", algo) - resp, err := app.Test(req, 10*time.Second) + resp, err := app.Test(req, testConfig) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") @@ -748,7 +753,7 @@ func Test_Static_Compress(t *testing.T) { // request compressable file, ContentLenght will change req = httptest.NewRequest(fiber.MethodGet, "/index.html", nil) req.Header.Set("Accept-Encoding", algo) - resp, err = app.Test(req, 10*time.Second) + resp, err = app.Test(req, testConfig) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") @@ -769,7 +774,7 @@ func Test_Static_Compress_WithoutEncoding(t *testing.T) { // request compressable file without encoding req := httptest.NewRequest(fiber.MethodGet, "/index.html", nil) - resp, err := app.Test(req, 10*time.Second) + resp, err := app.Test(req, testConfig) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") @@ -792,7 +797,7 @@ func Test_Static_Compress_WithoutEncoding(t *testing.T) { req = httptest.NewRequest(fiber.MethodGet, "/"+fileName, nil) req.Header.Set("Accept-Encoding", algo) - resp, err = app.Test(req, 10*time.Second) + resp, err = app.Test(req, testConfig) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code") @@ -833,7 +838,7 @@ func Test_Static_Compress_WithFileSuffixes(t *testing.T) { req := httptest.NewRequest(fiber.MethodGet, "/"+fileName, nil) req.Header.Set("Accept-Encoding", algo) - resp, err := app.Test(req, 10*time.Second) + resp, err := app.Test(req, testConfig) require.NoError(t, err, "app.Test(req)") require.Equal(t, 200, resp.StatusCode, "Status code")