From e3db3b57e550ac4dfde5caeb28368207a9fd2df4 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Sun, 3 Mar 2024 00:58:06 -0500 Subject: [PATCH 01/46] Fixes for some of the failing tests --- app_test.go | 12 +- client_test.go | 243 ++++++++----------------------- listen_test.go | 14 +- middleware/logger/logger_test.go | 1 - middleware/proxy/proxy_test.go | 100 +++---------- 5 files changed, 104 insertions(+), 266 deletions(-) diff --git a/app_test.go b/app_test.go index 58c05932b2..0cf72af79d 100644 --- a/app_test.go +++ b/app_test.go @@ -821,10 +821,15 @@ func Test_App_ShutdownWithTimeout(t *testing.T) { time.Sleep(5 * time.Second) return c.SendString("body") }) + ln := fasthttputil.NewInmemoryListener() go func() { - require.NoError(t, app.Listener(ln)) + err := app.Listener(ln) + if err != nil { + panic(err) + } }() + time.Sleep(1 * time.Second) go func() { conn, err := ln.Dial() @@ -866,7 +871,10 @@ func Test_App_ShutdownWithContext(t *testing.T) { ln := fasthttputil.NewInmemoryListener() go func() { - require.NoError(t, app.Listener(ln)) + err := app.Listener(ln) + if err != nil { + panic(err) + } }() time.Sleep(1 * time.Second) diff --git a/client_test.go b/client_test.go index 57cc4e4d2e..a632665bbe 100644 --- a/client_test.go +++ b/client_test.go @@ -24,9 +24,20 @@ import ( "github.com/valyala/fasthttp/fasthttputil" ) -func Test_Client_Invalid_URL(t *testing.T) { - t.Parallel() +func startServer(app *App, ln *fasthttputil.InmemoryListener) { + go func() { + err := app.Listener(ln, ListenConfig{ + DisableStartupMessage: true, + }) + if err != nil { + panic(err) + } + }() + time.Sleep(2 * time.Second) +} + +func Test_Client_Invalid_URL(t *testing.T) { ln := fasthttputil.NewInmemoryListener() app := New() @@ -35,11 +46,8 @@ func Test_Client_Invalid_URL(t *testing.T) { return c.SendString(c.Host()) }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) a := Get("http://example.com\r\n\r\nGET /\r\n\r\n") @@ -54,8 +62,6 @@ func Test_Client_Invalid_URL(t *testing.T) { } func Test_Client_Unsupported_Protocol(t *testing.T) { - t.Parallel() - a := Get("ftp://example.com") _, body, errs := a.String() @@ -66,8 +72,6 @@ func Test_Client_Unsupported_Protocol(t *testing.T) { } func Test_Client_Get(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -76,11 +80,8 @@ func Test_Client_Get(t *testing.T) { return c.SendString(c.Host()) }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) for i := 0; i < 5; i++ { a := Get("http://example.com") @@ -96,8 +97,6 @@ func Test_Client_Get(t *testing.T) { } func Test_Client_Head(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -106,11 +105,9 @@ func Test_Client_Head(t *testing.T) { return c.SendStatus(StatusAccepted) }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) + for i := 0; i < 5; i++ { a := Head("http://example.com") @@ -125,8 +122,6 @@ func Test_Client_Head(t *testing.T) { } func Test_Client_Post(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -136,11 +131,8 @@ func Test_Client_Post(t *testing.T) { SendString(c.FormValue("foo")) }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) for i := 0; i < 5; i++ { args := AcquireArgs() @@ -163,8 +155,6 @@ func Test_Client_Post(t *testing.T) { } func Test_Client_Put(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -173,11 +163,8 @@ func Test_Client_Put(t *testing.T) { return c.SendString(c.FormValue("foo")) }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) for i := 0; i < 5; i++ { args := AcquireArgs() @@ -200,8 +187,6 @@ func Test_Client_Put(t *testing.T) { } func Test_Client_Patch(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -210,11 +195,8 @@ func Test_Client_Patch(t *testing.T) { return c.SendString(c.FormValue("foo")) }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) for i := 0; i < 5; i++ { args := AcquireArgs() @@ -237,8 +219,6 @@ func Test_Client_Patch(t *testing.T) { } func Test_Client_Delete(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -248,11 +228,8 @@ func Test_Client_Delete(t *testing.T) { SendString("deleted") }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) for i := 0; i < 5; i++ { args := AcquireArgs() @@ -272,8 +249,6 @@ func Test_Client_Delete(t *testing.T) { } func Test_Client_UserAgent(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -282,14 +257,10 @@ func Test_Client_UserAgent(t *testing.T) { return c.Send(c.Request().Header.UserAgent()) }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) t.Run("default", func(t *testing.T) { - t.Parallel() for i := 0; i < 5; i++ { a := Get("http://example.com") @@ -304,7 +275,6 @@ func Test_Client_UserAgent(t *testing.T) { }) t.Run("custom", func(t *testing.T) { - t.Parallel() for i := 0; i < 5; i++ { c := AcquireClient() c.UserAgent = "ua" @@ -324,7 +294,6 @@ func Test_Client_UserAgent(t *testing.T) { } func Test_Client_Agent_Set_Or_Add_Headers(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { c.Request().Header.VisitAll(func(key, value []byte) { if k := string(key); k == "K1" || k == "K2" { @@ -352,7 +321,6 @@ func Test_Client_Agent_Set_Or_Add_Headers(t *testing.T) { } func Test_Client_Agent_Connection_Close(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { if c.Request().Header.ConnectionClose() { return c.SendString("close") @@ -368,7 +336,6 @@ func Test_Client_Agent_Connection_Close(t *testing.T) { } func Test_Client_Agent_UserAgent(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Header.UserAgent()) } @@ -382,7 +349,6 @@ func Test_Client_Agent_UserAgent(t *testing.T) { } func Test_Client_Agent_Cookie(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.SendString( c.Cookies("k1") + c.Cookies("k2") + c.Cookies("k3") + c.Cookies("k4")) @@ -400,7 +366,6 @@ func Test_Client_Agent_Cookie(t *testing.T) { } func Test_Client_Agent_Referer(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Header.Referer()) } @@ -414,7 +379,6 @@ func Test_Client_Agent_Referer(t *testing.T) { } func Test_Client_Agent_ContentType(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Header.ContentType()) } @@ -428,8 +392,6 @@ func Test_Client_Agent_ContentType(t *testing.T) { } func Test_Client_Agent_Host(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -438,11 +400,8 @@ func Test_Client_Agent_Host(t *testing.T) { return c.SendString(c.Host()) }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) a := Get("http://1.1.1.1:8080"). Host("example.com"). @@ -460,7 +419,6 @@ func Test_Client_Agent_Host(t *testing.T) { } func Test_Client_Agent_QueryString(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().URI().QueryString()) } @@ -474,7 +432,6 @@ func Test_Client_Agent_QueryString(t *testing.T) { } func Test_Client_Agent_BasicAuth(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { // Get authorization header auth := c.Get(HeaderAuthorization) @@ -494,7 +451,6 @@ func Test_Client_Agent_BasicAuth(t *testing.T) { } func Test_Client_Agent_BodyString(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Body()) } @@ -507,7 +463,6 @@ func Test_Client_Agent_BodyString(t *testing.T) { } func Test_Client_Agent_Body(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Body()) } @@ -520,7 +475,6 @@ func Test_Client_Agent_Body(t *testing.T) { } func Test_Client_Agent_BodyStream(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Body()) } @@ -533,8 +487,6 @@ func Test_Client_Agent_BodyStream(t *testing.T) { } func Test_Client_Agent_Custom_Response(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -543,11 +495,8 @@ func Test_Client_Agent_Custom_Response(t *testing.T) { return c.SendString("custom") }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) for i := 0; i < 5; i++ { a := AcquireAgent() @@ -574,8 +523,6 @@ func Test_Client_Agent_Custom_Response(t *testing.T) { } func Test_Client_Agent_Dest(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -584,14 +531,10 @@ func Test_Client_Agent_Dest(t *testing.T) { return c.SendString("dest") }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) t.Run("small dest", func(t *testing.T) { - t.Parallel() dest := []byte("de") a := Get("http://example.com") @@ -607,7 +550,6 @@ func Test_Client_Agent_Dest(t *testing.T) { }) t.Run("enough dest", func(t *testing.T) { - t.Parallel() dest := []byte("foobar") a := Get("http://example.com") @@ -657,17 +599,12 @@ func (*readErrorConn) SetWriteDeadline(_ time.Time) error { } func Test_Client_Agent_RetryIf(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) a := Post("http://example.com"). RetryIf(func(_ *Request) bool { @@ -697,7 +634,6 @@ func Test_Client_Agent_RetryIf(t *testing.T) { } func Test_Client_Agent_Json(t *testing.T) { - t.Parallel() // Test without ctype parameter handler := func(c Ctx) error { require.Equal(t, MIMEApplicationJSON, string(c.Request().Header.ContentType())) @@ -726,7 +662,6 @@ func Test_Client_Agent_Json(t *testing.T) { } func Test_Client_Agent_Json_Error(t *testing.T) { - t.Parallel() a := Get("http://example.com"). JSONEncoder(json.Marshal). JSON(complex(1, 1)) @@ -740,7 +675,6 @@ func Test_Client_Agent_Json_Error(t *testing.T) { } func Test_Client_Agent_XML(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { require.Equal(t, MIMEApplicationXML, string(c.Request().Header.ContentType())) @@ -755,7 +689,6 @@ func Test_Client_Agent_XML(t *testing.T) { } func Test_Client_Agent_XML_Error(t *testing.T) { - t.Parallel() a := Get("http://example.com"). XML(complex(1, 1)) @@ -767,7 +700,6 @@ func Test_Client_Agent_XML_Error(t *testing.T) { } func Test_Client_Agent_Form(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { require.Equal(t, MIMEApplicationForm, string(c.Request().Header.ContentType())) @@ -788,8 +720,6 @@ func Test_Client_Agent_Form(t *testing.T) { } func Test_Client_Agent_MultipartForm(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -804,11 +734,8 @@ func Test_Client_Agent_MultipartForm(t *testing.T) { return c.Send(c.Request().Body()) }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) args := AcquireArgs() @@ -829,8 +756,6 @@ func Test_Client_Agent_MultipartForm(t *testing.T) { } func Test_Client_Agent_MultipartForm_Errors(t *testing.T) { - t.Parallel() - a := AcquireAgent() a.mw = &errorMultipartWriter{} @@ -847,8 +772,6 @@ func Test_Client_Agent_MultipartForm_Errors(t *testing.T) { } func Test_Client_Agent_MultipartForm_SendFiles(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -881,11 +804,8 @@ func Test_Client_Agent_MultipartForm_SendFiles(t *testing.T) { return c.SendString("multipart form files") }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) for i := 0; i < 5; i++ { ff := AcquireFormFile() @@ -933,8 +853,6 @@ func checkFormFile(t *testing.T, fh *multipart.FileHeader, filename string) { } func Test_Client_Agent_Multipart_Random_Boundary(t *testing.T) { - t.Parallel() - a := Post("http://example.com"). MultipartForm(nil) @@ -944,8 +862,6 @@ func Test_Client_Agent_Multipart_Random_Boundary(t *testing.T) { } func Test_Client_Agent_Multipart_Invalid_Boundary(t *testing.T) { - t.Parallel() - a := Post("http://example.com"). Boundary("*"). MultipartForm(nil) @@ -955,8 +871,6 @@ func Test_Client_Agent_Multipart_Invalid_Boundary(t *testing.T) { } func Test_Client_Agent_SendFile_Error(t *testing.T) { - t.Parallel() - a := Post("http://example.com"). SendFile("non-exist-file!", "") @@ -965,7 +879,6 @@ func Test_Client_Agent_SendFile_Error(t *testing.T) { } func Test_Client_Debug(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.SendString("debug") } @@ -989,8 +902,6 @@ func Test_Client_Debug(t *testing.T) { } func Test_Client_Agent_Timeout(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -1000,11 +911,8 @@ func Test_Client_Agent_Timeout(t *testing.T) { return c.SendString("timeout") }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) a := Get("http://example.com"). Timeout(time.Millisecond * 50) @@ -1019,8 +927,6 @@ func Test_Client_Agent_Timeout(t *testing.T) { } func Test_Client_Agent_Reuse(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -1029,11 +935,8 @@ func Test_Client_Agent_Reuse(t *testing.T) { return c.SendString("reuse") }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) a := Get("http://example.com"). Reuse() @@ -1054,8 +957,6 @@ func Test_Client_Agent_Reuse(t *testing.T) { } func Test_Client_Agent_InsecureSkipVerify(t *testing.T) { - t.Parallel() - cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") require.NoError(t, err) @@ -1076,11 +977,15 @@ func Test_Client_Agent_InsecureSkipVerify(t *testing.T) { }) go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ + //nolint:errcheck // We don't care about the error here + app.Listener(ln, ListenConfig{ DisableStartupMessage: true, - })) + }) }() + // Wait for server to start + time.Sleep(2 * time.Second) + code, body, errs := Get("https://" + ln.Addr().String()). InsecureSkipVerify(). InsecureSkipVerify(). @@ -1092,8 +997,6 @@ func Test_Client_Agent_InsecureSkipVerify(t *testing.T) { } func Test_Client_Agent_TLS(t *testing.T) { - t.Parallel() - serverTLSConf, clientTLSConf, err := tlstest.GetTLSConfigs() require.NoError(t, err) @@ -1109,11 +1012,15 @@ func Test_Client_Agent_TLS(t *testing.T) { }) go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ + //nolint:errcheck // We don't care about the error here + app.Listener(ln, ListenConfig{ DisableStartupMessage: true, - })) + }) }() + // Wait for server to start + time.Sleep(2 * time.Second) + code, body, errs := Get("https://" + ln.Addr().String()). TLSConfig(clientTLSConf). String() @@ -1124,8 +1031,6 @@ func Test_Client_Agent_TLS(t *testing.T) { } func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -1140,14 +1045,10 @@ func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { return c.SendString("redirect") }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) t.Run("success", func(t *testing.T) { - t.Parallel() a := Get("http://example.com?foo"). MaxRedirectsCount(1) @@ -1161,7 +1062,6 @@ func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { }) t.Run("error", func(t *testing.T) { - t.Parallel() a := Get("http://example.com"). MaxRedirectsCount(1) @@ -1176,8 +1076,6 @@ func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { } func Test_Client_Agent_Struct(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -1190,15 +1088,10 @@ func Test_Client_Agent_Struct(t *testing.T) { return c.SendString(`{"success"`) }) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) t.Run("success", func(t *testing.T) { - t.Parallel() - a := Get("http://example.com") a.HostClient.Dial = func(_ string) (net.Conn, error) { return ln.Dial() } @@ -1214,7 +1107,6 @@ func Test_Client_Agent_Struct(t *testing.T) { }) t.Run("pre error", func(t *testing.T) { - t.Parallel() a := Get("http://example.com") errPre := errors.New("pre errors") @@ -1232,7 +1124,6 @@ func Test_Client_Agent_Struct(t *testing.T) { }) t.Run("error", func(t *testing.T) { - t.Parallel() a := Get("http://example.com/error") a.HostClient.Dial = func(_ string) (net.Conn, error) { return ln.Dial() } @@ -1250,7 +1141,6 @@ func Test_Client_Agent_Struct(t *testing.T) { }) t.Run("nil jsonDecoder", func(t *testing.T) { - t.Parallel() a := AcquireAgent() defer ReleaseAgent(a) defer a.ConnectionClose() @@ -1270,8 +1160,6 @@ func Test_Client_Agent_Struct(t *testing.T) { } func Test_Client_Agent_Parse(t *testing.T) { - t.Parallel() - a := Get("https://example.com:10443") require.NoError(t, a.Parse()) @@ -1286,11 +1174,8 @@ func testAgent(t *testing.T, handler Handler, wrapAgent func(agent *Agent), exce app.Get("/", handler) - go func() { - require.NoError(t, app.Listener(ln, ListenConfig{ - DisableStartupMessage: true, - })) - }() + // Wait for server to start + startServer(app, ln) c := 1 if len(count) > 0 { diff --git a/listen_test.go b/listen_test.go index d92b9fb396..5e4c90fbcc 100644 --- a/listen_test.go +++ b/listen_test.go @@ -46,12 +46,13 @@ func Test_Listen_Graceful_Shutdown(t *testing.T) { }) ln := fasthttputil.NewInmemoryListener() + errs := make(chan error) go func() { - ctx, cancel := context.WithTimeout(context.Background(), 250*time.Millisecond) + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) defer cancel() - err := app.Listener(ln, ListenConfig{ + errs <- app.Listener(ln, ListenConfig{ DisableStartupMessage: true, GracefulContext: ctx, OnShutdownSuccess: func() { @@ -60,8 +61,6 @@ func Test_Listen_Graceful_Shutdown(t *testing.T) { mu.Unlock() }, }) - - require.NoError(t, err) }() testCases := []struct { @@ -70,8 +69,8 @@ func Test_Listen_Graceful_Shutdown(t *testing.T) { ExpectedStatusCode int ExceptedErrsLen int }{ - {Time: 100 * time.Millisecond, ExpectedBody: "example.com", ExpectedStatusCode: StatusOK, ExceptedErrsLen: 0}, - {Time: 500 * time.Millisecond, ExpectedBody: "", ExpectedStatusCode: 0, ExceptedErrsLen: 1}, + {Time: 500 * time.Millisecond, ExpectedBody: "example.com", ExpectedStatusCode: StatusOK, ExceptedErrsLen: 0}, + {Time: 5 * time.Second, ExpectedBody: "", ExpectedStatusCode: 0, ExceptedErrsLen: 1}, } for _, tc := range testCases { @@ -87,7 +86,9 @@ func Test_Listen_Graceful_Shutdown(t *testing.T) { } mu.Lock() + err := <-errs require.True(t, shutdown) + require.NoError(t, err) mu.Unlock() } @@ -214,7 +215,6 @@ func Test_Listener(t *testing.T) { } func Test_App_Listener_TLS_Listener(t *testing.T) { - t.Parallel() // Create tls certificate cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") if err != nil { diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index 0fb35ad121..b385ea69e0 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -273,7 +273,6 @@ func Test_Logger_WithLatency(t *testing.T) { // go test -run Test_Logger_WithLatency_DefaultFormat func Test_Logger_WithLatency_DefaultFormat(t *testing.T) { - t.Parallel() buff := bytebufferpool.Get() defer bytebufferpool.Put(buff) app := fiber.New() diff --git a/middleware/proxy/proxy_test.go b/middleware/proxy/proxy_test.go index 408ee71a5f..b31216ae33 100644 --- a/middleware/proxy/proxy_test.go +++ b/middleware/proxy/proxy_test.go @@ -16,6 +16,19 @@ import ( "github.com/valyala/fasthttp" ) +func startServer(app *fiber.App, ln net.Listener) { + go func() { + err := app.Listener(ln, fiber.ListenConfig{ + DisableStartupMessage: true, + }) + if err != nil { + panic(err) + } + }() + + time.Sleep(2 * time.Second) +} + func createProxyTestServer(t *testing.T, handler fiber.Handler) (*fiber.App, string) { t.Helper() @@ -27,21 +40,13 @@ func createProxyTestServer(t *testing.T, handler fiber.Handler) (*fiber.App, str addr := ln.Addr().String() - go func() { - require.NoError(t, target.Listener(ln, fiber.ListenConfig{ - DisableStartupMessage: true, - })) - }() - - time.Sleep(2 * time.Second) + startServer(target, ln) return target, addr } // go test -run Test_Proxy_Empty_Host func Test_Proxy_Empty_Upstream_Servers(t *testing.T) { - t.Parallel() - defer func() { if r := recover(); r != nil { require.Equal(t, "Servers cannot be empty", r) @@ -53,8 +58,6 @@ func Test_Proxy_Empty_Upstream_Servers(t *testing.T) { // go test -run Test_Proxy_Empty_Config func Test_Proxy_Empty_Config(t *testing.T) { - t.Parallel() - defer func() { if r := recover(); r != nil { require.Equal(t, "Servers cannot be empty", r) @@ -66,8 +69,6 @@ func Test_Proxy_Empty_Config(t *testing.T) { // go test -run Test_Proxy_Next func Test_Proxy_Next(t *testing.T) { - t.Parallel() - app := fiber.New() app.Use(Balancer(Config{ Servers: []string{"127.0.0.1"}, @@ -83,8 +84,6 @@ func Test_Proxy_Next(t *testing.T) { // go test -run Test_Proxy func Test_Proxy(t *testing.T) { - t.Parallel() - target, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendStatus(fiber.StatusTeapot) }) @@ -106,8 +105,6 @@ func Test_Proxy(t *testing.T) { // go test -run Test_Proxy_Balancer_WithTLSConfig func Test_Proxy_Balancer_WithTLSConfig(t *testing.T) { - t.Parallel() - serverTLSConf, _, err := tlstest.GetTLSConfigs() require.NoError(t, err) @@ -131,11 +128,7 @@ func Test_Proxy_Balancer_WithTLSConfig(t *testing.T) { TlsConfig: clientTLSConf, })) - go func() { - require.NoError(t, app.Listener(ln, fiber.ListenConfig{ - DisableStartupMessage: true, - })) - }() + startServer(app, ln) code, body, errs := fiber.Get("https://" + addr + "/tlsbalaner").TLSConfig(clientTLSConf).String() @@ -146,8 +139,6 @@ func Test_Proxy_Balancer_WithTLSConfig(t *testing.T) { // go test -run Test_Proxy_Forward_WithTLSConfig_To_Http func Test_Proxy_Forward_WithTLSConfig_To_Http(t *testing.T) { - t.Parallel() - _, targetAddr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendString("hello from target") }) @@ -166,11 +157,7 @@ func Test_Proxy_Forward_WithTLSConfig_To_Http(t *testing.T) { app.Use(Forward("http://" + targetAddr)) - go func() { - require.NoError(t, app.Listener(proxyServerLn, fiber.ListenConfig{ - DisableStartupMessage: true, - })) - }() + startServer(app, proxyServerLn) code, body, errs := fiber.Get("https://" + proxyAddr). InsecureSkipVerify(). @@ -184,8 +171,6 @@ func Test_Proxy_Forward_WithTLSConfig_To_Http(t *testing.T) { // go test -run Test_Proxy_Forward func Test_Proxy_Forward(t *testing.T) { - t.Parallel() - app := fiber.New() _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { @@ -205,8 +190,6 @@ func Test_Proxy_Forward(t *testing.T) { // go test -run Test_Proxy_Forward_WithTLSConfig func Test_Proxy_Forward_WithTLSConfig(t *testing.T) { - t.Parallel() - serverTLSConf, _, err := tlstest.GetTLSConfigs() require.NoError(t, err) @@ -228,11 +211,7 @@ func Test_Proxy_Forward_WithTLSConfig(t *testing.T) { WithTLSConfig(clientTLSConf) app.Use(Forward("https://" + addr + "/tlsfwd")) - go func() { - require.NoError(t, app.Listener(ln, fiber.ListenConfig{ - DisableStartupMessage: true, - })) - }() + startServer(app, ln) code, body, errs := fiber.Get("https://" + addr).TLSConfig(clientTLSConf).String() @@ -243,8 +222,6 @@ func Test_Proxy_Forward_WithTLSConfig(t *testing.T) { // go test -run Test_Proxy_Modify_Response func Test_Proxy_Modify_Response(t *testing.T) { - t.Parallel() - _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.Status(500).SendString("not modified") }) @@ -269,8 +246,6 @@ func Test_Proxy_Modify_Response(t *testing.T) { // go test -run Test_Proxy_Modify_Request func Test_Proxy_Modify_Request(t *testing.T) { - t.Parallel() - _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { b := c.Request().Body() return c.SendString(string(b)) @@ -296,8 +271,6 @@ func Test_Proxy_Modify_Request(t *testing.T) { // go test -run Test_Proxy_Timeout_Slow_Server func Test_Proxy_Timeout_Slow_Server(t *testing.T) { - t.Parallel() - _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { time.Sleep(300 * time.Millisecond) return c.SendString("fiber is awesome") @@ -320,8 +293,6 @@ func Test_Proxy_Timeout_Slow_Server(t *testing.T) { // go test -run Test_Proxy_With_Timeout func Test_Proxy_With_Timeout(t *testing.T) { - t.Parallel() - _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { time.Sleep(1 * time.Second) return c.SendString("fiber is awesome") @@ -344,8 +315,6 @@ func Test_Proxy_With_Timeout(t *testing.T) { // go test -run Test_Proxy_Buffer_Size_Response func Test_Proxy_Buffer_Size_Response(t *testing.T) { - t.Parallel() - _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { long := strings.Join(make([]string, 5000), "-") c.Set("Very-Long-Header", long) @@ -372,7 +341,6 @@ func Test_Proxy_Buffer_Size_Response(t *testing.T) { // go test -race -run Test_Proxy_Do_RestoreOriginalURL func Test_Proxy_Do_RestoreOriginalURL(t *testing.T) { - t.Parallel() _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendString("proxied") }) @@ -392,7 +360,6 @@ func Test_Proxy_Do_RestoreOriginalURL(t *testing.T) { // go test -race -run Test_Proxy_Do_WithRealURL func Test_Proxy_Do_WithRealURL(t *testing.T) { - t.Parallel() app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { return Do(c, "https://www.google.com") @@ -409,7 +376,6 @@ func Test_Proxy_Do_WithRealURL(t *testing.T) { // go test -race -run Test_Proxy_Do_WithRedirect func Test_Proxy_Do_WithRedirect(t *testing.T) { - t.Parallel() app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { return Do(c, "https://google.com") @@ -425,7 +391,6 @@ func Test_Proxy_Do_WithRedirect(t *testing.T) { // go test -race -run Test_Proxy_DoRedirects_RestoreOriginalURL func Test_Proxy_DoRedirects_RestoreOriginalURL(t *testing.T) { - t.Parallel() app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { return DoRedirects(c, "http://google.com", 1) @@ -441,7 +406,6 @@ func Test_Proxy_DoRedirects_RestoreOriginalURL(t *testing.T) { // go test -race -run Test_Proxy_DoRedirects_TooManyRedirects func Test_Proxy_DoRedirects_TooManyRedirects(t *testing.T) { - t.Parallel() app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { return DoRedirects(c, "http://google.com", 0) @@ -458,8 +422,6 @@ func Test_Proxy_DoRedirects_TooManyRedirects(t *testing.T) { // go test -race -run Test_Proxy_DoTimeout_RestoreOriginalURL func Test_Proxy_DoTimeout_RestoreOriginalURL(t *testing.T) { - t.Parallel() - _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendString("proxied") }) @@ -480,8 +442,6 @@ func Test_Proxy_DoTimeout_RestoreOriginalURL(t *testing.T) { // go test -race -run Test_Proxy_DoTimeout_Timeout func Test_Proxy_DoTimeout_Timeout(t *testing.T) { - t.Parallel() - _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { time.Sleep(time.Second * 5) return c.SendString("proxied") @@ -498,8 +458,6 @@ func Test_Proxy_DoTimeout_Timeout(t *testing.T) { // go test -race -run Test_Proxy_DoDeadline_RestoreOriginalURL func Test_Proxy_DoDeadline_RestoreOriginalURL(t *testing.T) { - t.Parallel() - _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendString("proxied") }) @@ -520,8 +478,6 @@ func Test_Proxy_DoDeadline_RestoreOriginalURL(t *testing.T) { // go test -race -run Test_Proxy_DoDeadline_PastDeadline func Test_Proxy_DoDeadline_PastDeadline(t *testing.T) { - t.Parallel() - _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { time.Sleep(time.Second * 5) return c.SendString("proxied") @@ -538,8 +494,6 @@ func Test_Proxy_DoDeadline_PastDeadline(t *testing.T) { // go test -race -run Test_Proxy_Do_HTTP_Prefix_URL func Test_Proxy_Do_HTTP_Prefix_URL(t *testing.T) { - t.Parallel() - _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendString("hello world") }) @@ -566,7 +520,6 @@ func Test_Proxy_Do_HTTP_Prefix_URL(t *testing.T) { // go test -race -run Test_Proxy_Forward_Global_Client func Test_Proxy_Forward_Global_Client(t *testing.T) { - t.Parallel() ln, err := net.Listen(fiber.NetworkTCP4, "127.0.0.1:0") require.NoError(t, err) WithClient(&fasthttp.Client{ @@ -580,11 +533,7 @@ func Test_Proxy_Forward_Global_Client(t *testing.T) { addr := ln.Addr().String() app.Use(Forward("http://" + addr + "/test_global_client")) - go func() { - require.NoError(t, app.Listener(ln, fiber.ListenConfig{ - DisableStartupMessage: true, - })) - }() + startServer(app, ln) code, body, errs := fiber.Get("http://" + addr).String() require.Empty(t, errs) @@ -594,7 +543,6 @@ func Test_Proxy_Forward_Global_Client(t *testing.T) { // go test -race -run Test_Proxy_Forward_Local_Client func Test_Proxy_Forward_Local_Client(t *testing.T) { - t.Parallel() ln, err := net.Listen(fiber.NetworkTCP4, "127.0.0.1:0") require.NoError(t, err) app := fiber.New() @@ -610,9 +558,12 @@ func Test_Proxy_Forward_Local_Client(t *testing.T) { Dial: fasthttp.Dial, })) go func() { - require.NoError(t, app.Listener(ln, fiber.ListenConfig{ + err := app.Listener(ln, fiber.ListenConfig{ DisableStartupMessage: true, - })) + }) + if err != nil { + panic(err) + } }() code, body, errs := fiber.Get("http://" + addr).String() @@ -623,8 +574,6 @@ func Test_Proxy_Forward_Local_Client(t *testing.T) { // go test -run Test_ProxyBalancer_Custom_Client func Test_ProxyBalancer_Custom_Client(t *testing.T) { - t.Parallel() - target, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendStatus(fiber.StatusTeapot) }) @@ -655,7 +604,6 @@ func Test_ProxyBalancer_Custom_Client(t *testing.T) { // go test -run Test_Proxy_Domain_Forward_Local func Test_Proxy_Domain_Forward_Local(t *testing.T) { - t.Parallel() ln, err := net.Listen(fiber.NetworkTCP4, "127.0.0.1:0") require.NoError(t, err) app := fiber.New() @@ -690,8 +638,6 @@ func Test_Proxy_Domain_Forward_Local(t *testing.T) { // go test -run Test_Proxy_Balancer_Forward_Local func Test_Proxy_Balancer_Forward_Local(t *testing.T) { - t.Parallel() - app := fiber.New() _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { From e84e5ef0d64e3d060e3e913bec383d01c84bdbb0 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Sun, 3 Mar 2024 01:36:39 -0500 Subject: [PATCH 02/46] Add readiness check to serverStart() --- client_test.go | 55 +++++++++++++++++++++------------- listen_test.go | 16 +++++++++- middleware/proxy/proxy_test.go | 2 +- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/client_test.go b/client_test.go index a632665bbe..7440a3ea2f 100644 --- a/client_test.go +++ b/client_test.go @@ -24,7 +24,8 @@ import ( "github.com/valyala/fasthttp/fasthttputil" ) -func startServer(app *App, ln *fasthttputil.InmemoryListener) { +func startServer(t *testing.T, app *App, ln *fasthttputil.InmemoryListener) { + t.Helper() go func() { err := app.Listener(ln, ListenConfig{ DisableStartupMessage: true, @@ -34,7 +35,19 @@ func startServer(app *App, ln *fasthttputil.InmemoryListener) { } }() - time.Sleep(2 * time.Second) + // Server readiness check + for i := 0; i < 10; i++ { + conn, err := ln.Dial() + if err == nil { + conn.Close() //nolint:errcheck // We don't care about the error here + break + } + // Wait a bit before retrying + time.Sleep(100 * time.Millisecond) + if i == 9 { + t.Fatalf("Server did not become ready in time: %v", err) + } + } } func Test_Client_Invalid_URL(t *testing.T) { @@ -47,7 +60,7 @@ func Test_Client_Invalid_URL(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) a := Get("http://example.com\r\n\r\nGET /\r\n\r\n") @@ -81,7 +94,7 @@ func Test_Client_Get(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) for i := 0; i < 5; i++ { a := Get("http://example.com") @@ -106,7 +119,7 @@ func Test_Client_Head(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) for i := 0; i < 5; i++ { a := Head("http://example.com") @@ -132,7 +145,7 @@ func Test_Client_Post(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) for i := 0; i < 5; i++ { args := AcquireArgs() @@ -164,7 +177,7 @@ func Test_Client_Put(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) for i := 0; i < 5; i++ { args := AcquireArgs() @@ -196,7 +209,7 @@ func Test_Client_Patch(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) for i := 0; i < 5; i++ { args := AcquireArgs() @@ -229,7 +242,7 @@ func Test_Client_Delete(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) for i := 0; i < 5; i++ { args := AcquireArgs() @@ -258,7 +271,7 @@ func Test_Client_UserAgent(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) t.Run("default", func(t *testing.T) { for i := 0; i < 5; i++ { @@ -401,7 +414,7 @@ func Test_Client_Agent_Host(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) a := Get("http://1.1.1.1:8080"). Host("example.com"). @@ -496,7 +509,7 @@ func Test_Client_Agent_Custom_Response(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) for i := 0; i < 5; i++ { a := AcquireAgent() @@ -532,7 +545,7 @@ func Test_Client_Agent_Dest(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) t.Run("small dest", func(t *testing.T) { dest := []byte("de") @@ -604,7 +617,7 @@ func Test_Client_Agent_RetryIf(t *testing.T) { app := New() // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) a := Post("http://example.com"). RetryIf(func(_ *Request) bool { @@ -735,7 +748,7 @@ func Test_Client_Agent_MultipartForm(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) args := AcquireArgs() @@ -805,7 +818,7 @@ func Test_Client_Agent_MultipartForm_SendFiles(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) for i := 0; i < 5; i++ { ff := AcquireFormFile() @@ -912,7 +925,7 @@ func Test_Client_Agent_Timeout(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) a := Get("http://example.com"). Timeout(time.Millisecond * 50) @@ -936,7 +949,7 @@ func Test_Client_Agent_Reuse(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) a := Get("http://example.com"). Reuse() @@ -1046,7 +1059,7 @@ func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) t.Run("success", func(t *testing.T) { a := Get("http://example.com?foo"). @@ -1089,7 +1102,7 @@ func Test_Client_Agent_Struct(t *testing.T) { }) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) t.Run("success", func(t *testing.T) { a := Get("http://example.com") @@ -1175,7 +1188,7 @@ func testAgent(t *testing.T, handler Handler, wrapAgent func(agent *Agent), exce app.Get("/", handler) // Wait for server to start - startServer(app, ln) + startServer(t, app, ln) c := 1 if len(count) > 0 { diff --git a/listen_test.go b/listen_test.go index 5e4c90fbcc..b5b6414b58 100644 --- a/listen_test.go +++ b/listen_test.go @@ -63,13 +63,27 @@ func Test_Listen_Graceful_Shutdown(t *testing.T) { }) }() + // Server readiness check + for i := 0; i < 10; i++ { + conn, err := ln.Dial() + if err == nil { + conn.Close() //nolint:errcheck // ignore error + break + } + // Wait a bit before retrying + time.Sleep(100 * time.Millisecond) + if i == 9 { + t.Fatalf("Server did not become ready in time: %v", err) + } + } + testCases := []struct { Time time.Duration ExpectedBody string ExpectedStatusCode int ExceptedErrsLen int }{ - {Time: 500 * time.Millisecond, ExpectedBody: "example.com", ExpectedStatusCode: StatusOK, ExceptedErrsLen: 0}, + {Time: 100 * time.Millisecond, ExpectedBody: "example.com", ExpectedStatusCode: StatusOK, ExceptedErrsLen: 0}, {Time: 5 * time.Second, ExpectedBody: "", ExpectedStatusCode: 0, ExceptedErrsLen: 1}, } diff --git a/middleware/proxy/proxy_test.go b/middleware/proxy/proxy_test.go index b31216ae33..0c32088b74 100644 --- a/middleware/proxy/proxy_test.go +++ b/middleware/proxy/proxy_test.go @@ -26,7 +26,7 @@ func startServer(app *fiber.App, ln net.Listener) { } }() - time.Sleep(2 * time.Second) + time.Sleep(1 * time.Second) } func createProxyTestServer(t *testing.T, handler fiber.Handler) (*fiber.App, string) { From 6783b99e967be401da5b51f1b372d9ed8bb5400a Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Sun, 3 Mar 2024 14:06:46 -0500 Subject: [PATCH 03/46] Use net/http client for tests listen test --- listen_test.go | 41 +++++++++++++++++++++++++++++++++-------- 1 file changed, 33 insertions(+), 8 deletions(-) diff --git a/listen_test.go b/listen_test.go index b5b6414b58..ab88e12258 100644 --- a/listen_test.go +++ b/listen_test.go @@ -10,6 +10,7 @@ import ( "io" "log" "net" + "net/http" "os" "strings" "sync" @@ -49,7 +50,7 @@ func Test_Listen_Graceful_Shutdown(t *testing.T) { errs := make(chan error) go func() { - ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second) defer cancel() errs <- app.Listener(ln, ListenConfig{ @@ -84,19 +85,43 @@ func Test_Listen_Graceful_Shutdown(t *testing.T) { ExceptedErrsLen int }{ {Time: 100 * time.Millisecond, ExpectedBody: "example.com", ExpectedStatusCode: StatusOK, ExceptedErrsLen: 0}, - {Time: 5 * time.Second, ExpectedBody: "", ExpectedStatusCode: 0, ExceptedErrsLen: 1}, + {Time: 3 * time.Second, ExpectedBody: "", ExpectedStatusCode: 0, ExceptedErrsLen: 1}, } for _, tc := range testCases { time.Sleep(tc.Time) - a := Get("http://example.com") - a.HostClient.Dial = func(_ string) (net.Conn, error) { return ln.Dial() } - code, body, errs := a.String() + client := &http.Client{ + Transport: &http.Transport{ + DialContext: func(_ context.Context, _, _ string) (net.Conn, error) { + return ln.Dial() + }, + }, + } + + // Making the request + actualErrsLen := 0 + resp, err := client.Get("http://example.com") //nolint:noctx // no need for context in tests + if err != nil { + actualErrsLen++ + } + + if resp != nil { + bodyBytes, err := io.ReadAll(resp.Body) + require.NoError(t, err) + body := string(bodyBytes) + + // Checking the status code and response body + require.Equal(t, tc.ExpectedStatusCode, resp.StatusCode) + require.Equal(t, tc.ExpectedBody, body) + + if resp.StatusCode >= 400 { + actualErrsLen++ + } + require.NoError(t, resp.Body.Close()) + } - require.Equal(t, tc.ExpectedStatusCode, code) - require.Equal(t, tc.ExpectedBody, body) - require.Len(t, errs, tc.ExceptedErrsLen) + require.Equal(t, tc.ExceptedErrsLen, actualErrsLen) } mu.Lock() From 5596887883f04cf7752a9e09fd711c6861f595b1 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Sun, 3 Mar 2024 14:18:03 -0500 Subject: [PATCH 04/46] Use different key for this test --- internal/storage/memory/memory_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/storage/memory/memory_test.go b/internal/storage/memory/memory_test.go index 7e70b55dfb..524e1a7445 100644 --- a/internal/storage/memory/memory_test.go +++ b/internal/storage/memory/memory_test.go @@ -83,7 +83,7 @@ func Test_Storage_Memory_Get_NotExist(t *testing.T) { func Test_Storage_Memory_Delete(t *testing.T) { t.Parallel() var ( - key = "john" + key = "john-delete" val = []byte("doe") ) From 6f05d4b850ba6d6ba9785a110635c784b8f8f3e3 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Sun, 3 Mar 2024 21:27:44 -0500 Subject: [PATCH 05/46] Run Proxy Middleware tests in parallel. Add nil checks for potential issues pointed by nilaway --- client.go | 34 +++++++---- listen.go | 15 ++--- middleware/logger/default_logger.go | 12 ++-- middleware/logger/template_chain.go | 15 +++++ middleware/proxy/proxy.go | 4 ++ middleware/proxy/proxy_test.go | 93 ++++++++++++++++++++++++----- 6 files changed, 136 insertions(+), 37 deletions(-) diff --git a/client.go b/client.go index 8825f9d815..fcb1891d1c 100644 --- a/client.go +++ b/client.go @@ -604,14 +604,24 @@ func (a *Agent) MultipartForm(args *Args) *Agent { }) } - for _, ff := range a.formFiles { - w, err := a.mw.CreateFormFile(ff.Fieldname, ff.Name) - if err != nil { - a.errs = append(a.errs, err) - continue - } - if _, err = w.Write(ff.Content); err != nil { - a.errs = append(a.errs, err) + // Check if a.formFiles is not nil to avoid nil dereference + if a.formFiles != nil { + for _, ff := range a.formFiles { + // Additionally, check if ff is not nil to avoid nil dereference + if ff == nil { + continue // Skip this iteration if ff is nil + } + w, err := a.mw.CreateFormFile(ff.Fieldname, ff.Name) + if err != nil { + a.errs = append(a.errs, err) + continue + } + // Check if ff.Content is not nil before writing + if ff.Content != nil { + if _, err = w.Write(ff.Content); err != nil { + a.errs = append(a.errs, err) + } + } } } @@ -854,10 +864,12 @@ func (a *Agent) reset() { a.Name = "" a.NoDefaultUserAgentHeader = false for i, ff := range a.formFiles { - if ff.autoRelease { - ReleaseFormFile(ff) + if ff != nil { + if ff.autoRelease { + ReleaseFormFile(ff) + } + a.formFiles[i] = nil } - a.formFiles[i] = nil } a.formFiles = a.formFiles[:0] } diff --git a/listen.go b/listen.go index e293a1ef7c..43759393d4 100644 --- a/listen.go +++ b/listen.go @@ -268,16 +268,17 @@ func (*App) createListener(addr string, tlsConfig *tls.Config, cfg ListenConfig) listener, err = net.Listen(cfg.ListenerNetwork, addr) } - if cfg.ListenerAddrFunc != nil { - cfg.ListenerAddrFunc(listener.Addr()) + // Check for error before using the listener + if err != nil { + // Wrap the error from tls.Listen/net.Listen + return nil, fmt.Errorf("failed to listen: %w", err) } - // Wrap error comes from tls.Listen/net.Listen - if err != nil { - err = fmt.Errorf("failed to listen: %w", err) + if cfg.ListenerAddrFunc != nil { + cfg.ListenerAddrFunc(listener.Addr()) } - return listener, err + return listener, nil } func (app *App) printMessages(cfg ListenConfig, ln net.Listener) { @@ -378,7 +379,7 @@ func (app *App) startupMessage(addr string, isTLS bool, pids string, cfg ListenC if cfg.EnablePrefork { // Turn the `pids` variable (in the form ",a,b,c,d,e,f,etc") into a slice of PIDs - var pidSlice []string + pidSlice := make([]string, 0) for _, v := range strings.Split(pids, ",") { if v != "" { pidSlice = append(pidSlice, v) diff --git a/middleware/logger/default_logger.go b/middleware/logger/default_logger.go index 0070b72031..8b557c0e05 100644 --- a/middleware/logger/default_logger.go +++ b/middleware/logger/default_logger.go @@ -156,11 +156,15 @@ func appendInt(output Buffer, v int) (int, error) { // writeLog writes a msg to w, printing a warning to stderr if the log fails. func writeLog(w io.Writer, msg []byte) { + if w == nil { + fmt.Fprintf(os.Stderr, "writeLog: io.Writer is nil\n") + return + } if _, err := w.Write(msg); err != nil { - // Write error to output - if _, err := w.Write([]byte(err.Error())); err != nil { - // There is something wrong with the given io.Writer - _, _ = fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) + // Attempt to write the error message to the original writer, w + if _, err := w.Write([]byte("Failed to write log message: " + err.Error())); err != nil { + // If writing to w fails, fall back to stderr + fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) } } } diff --git a/middleware/logger/template_chain.go b/middleware/logger/template_chain.go index 00015bf33d..6f1e909fbd 100644 --- a/middleware/logger/template_chain.go +++ b/middleware/logger/template_chain.go @@ -17,9 +17,24 @@ import ( func buildLogFuncChain(cfg *Config, tagFunctions map[string]LogFunc) ([][]byte, []LogFunc, error) { // process flow is copied from the fasttemplate flow https://github.com/valyala/fasttemplate/blob/2a2d1afadadf9715bfa19683cdaeac8347e5d9f9/template.go#L23-L62 templateB := utils.UnsafeBytes(cfg.Format) + if templateB == nil { + return nil, nil, errors.New("template is nil") + } + startTagB := utils.UnsafeBytes(startTag) + if startTagB == nil { + return nil, nil, errors.New("startTag is nil") + } + endTagB := utils.UnsafeBytes(endTag) + if endTagB == nil { + return nil, nil, errors.New("endTag is nil") + } + paramSeparatorB := utils.UnsafeBytes(paramSeparator) + if paramSeparatorB == nil { + return nil, nil, errors.New("paramSeparator is nil") + } var fixParts [][]byte var funcChain []LogFunc diff --git a/middleware/proxy/proxy.go b/middleware/proxy/proxy.go index 284b67c8f5..cd396ad969 100644 --- a/middleware/proxy/proxy.go +++ b/middleware/proxy/proxy.go @@ -200,6 +200,10 @@ func doAction( } func getScheme(uri []byte) []byte { + if uri == nil { + return nil + } + i := bytes.IndexByte(uri, '/') if i < 1 || uri[i-1] != ':' || i == len(uri)-1 || uri[i+1] != '/' { return nil diff --git a/middleware/proxy/proxy_test.go b/middleware/proxy/proxy_test.go index 0c32088b74..089b33b3ef 100644 --- a/middleware/proxy/proxy_test.go +++ b/middleware/proxy/proxy_test.go @@ -25,8 +25,6 @@ func startServer(app *fiber.App, ln net.Listener) { panic(err) } }() - - time.Sleep(1 * time.Second) } func createProxyTestServer(t *testing.T, handler fiber.Handler) (*fiber.App, string) { @@ -47,6 +45,8 @@ func createProxyTestServer(t *testing.T, handler fiber.Handler) (*fiber.App, str // go test -run Test_Proxy_Empty_Host func Test_Proxy_Empty_Upstream_Servers(t *testing.T) { + t.Parallel() + defer func() { if r := recover(); r != nil { require.Equal(t, "Servers cannot be empty", r) @@ -58,6 +58,8 @@ func Test_Proxy_Empty_Upstream_Servers(t *testing.T) { // go test -run Test_Proxy_Empty_Config func Test_Proxy_Empty_Config(t *testing.T) { + t.Parallel() + defer func() { if r := recover(); r != nil { require.Equal(t, "Servers cannot be empty", r) @@ -69,6 +71,8 @@ func Test_Proxy_Empty_Config(t *testing.T) { // go test -run Test_Proxy_Next func Test_Proxy_Next(t *testing.T) { + t.Parallel() + app := fiber.New() app.Use(Balancer(Config{ Servers: []string{"127.0.0.1"}, @@ -84,6 +88,8 @@ func Test_Proxy_Next(t *testing.T) { // go test -run Test_Proxy func Test_Proxy(t *testing.T) { + t.Parallel() + target, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendStatus(fiber.StatusTeapot) }) @@ -105,6 +111,8 @@ func Test_Proxy(t *testing.T) { // go test -run Test_Proxy_Balancer_WithTLSConfig func Test_Proxy_Balancer_WithTLSConfig(t *testing.T) { + t.Parallel() + serverTLSConf, _, err := tlstest.GetTLSConfigs() require.NoError(t, err) @@ -130,7 +138,10 @@ func Test_Proxy_Balancer_WithTLSConfig(t *testing.T) { startServer(app, ln) - code, body, errs := fiber.Get("https://" + addr + "/tlsbalaner").TLSConfig(clientTLSConf).String() + c := fiber.AcquireClient() + a := c.Get("https://" + addr + "/tlsbalaner").TLSConfig(clientTLSConf) + defer fiber.ReleaseClient(c) + code, body, errs := a.String() require.Empty(t, errs) require.Equal(t, fiber.StatusOK, code) @@ -139,6 +150,8 @@ func Test_Proxy_Balancer_WithTLSConfig(t *testing.T) { // go test -run Test_Proxy_Forward_WithTLSConfig_To_Http func Test_Proxy_Forward_WithTLSConfig_To_Http(t *testing.T) { + t.Parallel() + _, targetAddr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendString("hello from target") }) @@ -150,19 +163,18 @@ func Test_Proxy_Forward_WithTLSConfig_To_Http(t *testing.T) { require.NoError(t, err) proxyServerLn = tls.NewListener(proxyServerLn, proxyServerTLSConf) - - app := fiber.New() - proxyAddr := proxyServerLn.Addr().String() + app := fiber.New() app.Use(Forward("http://" + targetAddr)) - startServer(app, proxyServerLn) - code, body, errs := fiber.Get("https://" + proxyAddr). + c := fiber.AcquireClient() + a := c.Get("https://" + proxyAddr). InsecureSkipVerify(). - Timeout(5 * time.Second). - String() + Timeout(5 * time.Second) + defer fiber.ReleaseClient(c) + code, body, errs := a.String() require.Empty(t, errs) require.Equal(t, fiber.StatusOK, code) @@ -171,6 +183,8 @@ func Test_Proxy_Forward_WithTLSConfig_To_Http(t *testing.T) { // go test -run Test_Proxy_Forward func Test_Proxy_Forward(t *testing.T) { + t.Parallel() + app := fiber.New() _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { @@ -190,6 +204,8 @@ func Test_Proxy_Forward(t *testing.T) { // go test -run Test_Proxy_Forward_WithTLSConfig func Test_Proxy_Forward_WithTLSConfig(t *testing.T) { + t.Parallel() + serverTLSConf, _, err := tlstest.GetTLSConfigs() require.NoError(t, err) @@ -213,7 +229,10 @@ func Test_Proxy_Forward_WithTLSConfig(t *testing.T) { startServer(app, ln) - code, body, errs := fiber.Get("https://" + addr).TLSConfig(clientTLSConf).String() + c := fiber.AcquireClient() + a := c.Get("https://" + addr).TLSConfig(clientTLSConf) + defer fiber.ReleaseClient(c) + code, body, errs := a.String() require.Empty(t, errs) require.Equal(t, fiber.StatusOK, code) @@ -222,6 +241,8 @@ func Test_Proxy_Forward_WithTLSConfig(t *testing.T) { // go test -run Test_Proxy_Modify_Response func Test_Proxy_Modify_Response(t *testing.T) { + t.Parallel() + _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.Status(500).SendString("not modified") }) @@ -246,6 +267,8 @@ func Test_Proxy_Modify_Response(t *testing.T) { // go test -run Test_Proxy_Modify_Request func Test_Proxy_Modify_Request(t *testing.T) { + t.Parallel() + _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { b := c.Request().Body() return c.SendString(string(b)) @@ -271,6 +294,8 @@ func Test_Proxy_Modify_Request(t *testing.T) { // go test -run Test_Proxy_Timeout_Slow_Server func Test_Proxy_Timeout_Slow_Server(t *testing.T) { + t.Parallel() + _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { time.Sleep(300 * time.Millisecond) return c.SendString("fiber is awesome") @@ -293,6 +318,8 @@ func Test_Proxy_Timeout_Slow_Server(t *testing.T) { // go test -run Test_Proxy_With_Timeout func Test_Proxy_With_Timeout(t *testing.T) { + t.Parallel() + _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { time.Sleep(1 * time.Second) return c.SendString("fiber is awesome") @@ -315,6 +342,8 @@ func Test_Proxy_With_Timeout(t *testing.T) { // go test -run Test_Proxy_Buffer_Size_Response func Test_Proxy_Buffer_Size_Response(t *testing.T) { + t.Parallel() + _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { long := strings.Join(make([]string, 5000), "-") c.Set("Very-Long-Header", long) @@ -341,6 +370,7 @@ func Test_Proxy_Buffer_Size_Response(t *testing.T) { // go test -race -run Test_Proxy_Do_RestoreOriginalURL func Test_Proxy_Do_RestoreOriginalURL(t *testing.T) { + t.Parallel() _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendString("proxied") }) @@ -360,6 +390,7 @@ func Test_Proxy_Do_RestoreOriginalURL(t *testing.T) { // go test -race -run Test_Proxy_Do_WithRealURL func Test_Proxy_Do_WithRealURL(t *testing.T) { + t.Parallel() app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { return Do(c, "https://www.google.com") @@ -376,6 +407,7 @@ func Test_Proxy_Do_WithRealURL(t *testing.T) { // go test -race -run Test_Proxy_Do_WithRedirect func Test_Proxy_Do_WithRedirect(t *testing.T) { + t.Parallel() app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { return Do(c, "https://google.com") @@ -391,6 +423,7 @@ func Test_Proxy_Do_WithRedirect(t *testing.T) { // go test -race -run Test_Proxy_DoRedirects_RestoreOriginalURL func Test_Proxy_DoRedirects_RestoreOriginalURL(t *testing.T) { + t.Parallel() app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { return DoRedirects(c, "http://google.com", 1) @@ -406,6 +439,7 @@ func Test_Proxy_DoRedirects_RestoreOriginalURL(t *testing.T) { // go test -race -run Test_Proxy_DoRedirects_TooManyRedirects func Test_Proxy_DoRedirects_TooManyRedirects(t *testing.T) { + t.Parallel() app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { return DoRedirects(c, "http://google.com", 0) @@ -422,6 +456,8 @@ func Test_Proxy_DoRedirects_TooManyRedirects(t *testing.T) { // go test -race -run Test_Proxy_DoTimeout_RestoreOriginalURL func Test_Proxy_DoTimeout_RestoreOriginalURL(t *testing.T) { + t.Parallel() + _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendString("proxied") }) @@ -442,6 +478,8 @@ func Test_Proxy_DoTimeout_RestoreOriginalURL(t *testing.T) { // go test -race -run Test_Proxy_DoTimeout_Timeout func Test_Proxy_DoTimeout_Timeout(t *testing.T) { + t.Parallel() + _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { time.Sleep(time.Second * 5) return c.SendString("proxied") @@ -458,6 +496,8 @@ func Test_Proxy_DoTimeout_Timeout(t *testing.T) { // go test -race -run Test_Proxy_DoDeadline_RestoreOriginalURL func Test_Proxy_DoDeadline_RestoreOriginalURL(t *testing.T) { + t.Parallel() + _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendString("proxied") }) @@ -478,6 +518,8 @@ func Test_Proxy_DoDeadline_RestoreOriginalURL(t *testing.T) { // go test -race -run Test_Proxy_DoDeadline_PastDeadline func Test_Proxy_DoDeadline_PastDeadline(t *testing.T) { + t.Parallel() + _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { time.Sleep(time.Second * 5) return c.SendString("proxied") @@ -485,7 +527,7 @@ func Test_Proxy_DoDeadline_PastDeadline(t *testing.T) { app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { - return DoDeadline(c, "http://"+addr, time.Now().Add(time.Second)) + return DoDeadline(c, "http://"+addr, time.Now().Add(2*time.Second)) }) _, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), int((1*time.Second)/time.Millisecond)) @@ -494,6 +536,8 @@ func Test_Proxy_DoDeadline_PastDeadline(t *testing.T) { // go test -race -run Test_Proxy_Do_HTTP_Prefix_URL func Test_Proxy_Do_HTTP_Prefix_URL(t *testing.T) { + t.Parallel() + _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendString("hello world") }) @@ -520,6 +564,7 @@ func Test_Proxy_Do_HTTP_Prefix_URL(t *testing.T) { // go test -race -run Test_Proxy_Forward_Global_Client func Test_Proxy_Forward_Global_Client(t *testing.T) { + t.Parallel() ln, err := net.Listen(fiber.NetworkTCP4, "127.0.0.1:0") require.NoError(t, err) WithClient(&fasthttp.Client{ @@ -535,7 +580,11 @@ func Test_Proxy_Forward_Global_Client(t *testing.T) { app.Use(Forward("http://" + addr + "/test_global_client")) startServer(app, ln) - code, body, errs := fiber.Get("http://" + addr).String() + c := fiber.AcquireClient() + a := c.Get("http://" + addr) + defer fiber.ReleaseClient(c) + code, body, errs := a.String() + require.Empty(t, errs) require.Equal(t, fiber.StatusOK, code) require.Equal(t, "test_global_client", body) @@ -543,6 +592,7 @@ func Test_Proxy_Forward_Global_Client(t *testing.T) { // go test -race -run Test_Proxy_Forward_Local_Client func Test_Proxy_Forward_Local_Client(t *testing.T) { + t.Parallel() ln, err := net.Listen(fiber.NetworkTCP4, "127.0.0.1:0") require.NoError(t, err) app := fiber.New() @@ -566,7 +616,11 @@ func Test_Proxy_Forward_Local_Client(t *testing.T) { } }() - code, body, errs := fiber.Get("http://" + addr).String() + c := fiber.AcquireClient() + a := c.Get("http://" + addr) + defer fiber.ReleaseClient(c) + code, body, errs := a.String() + require.Empty(t, errs) require.Equal(t, fiber.StatusOK, code) require.Equal(t, "test_local_client", body) @@ -574,6 +628,8 @@ func Test_Proxy_Forward_Local_Client(t *testing.T) { // go test -run Test_ProxyBalancer_Custom_Client func Test_ProxyBalancer_Custom_Client(t *testing.T) { + t.Parallel() + target, addr := createProxyTestServer(t, func(c fiber.Ctx) error { return c.SendStatus(fiber.StatusTeapot) }) @@ -604,6 +660,7 @@ func Test_ProxyBalancer_Custom_Client(t *testing.T) { // go test -run Test_Proxy_Domain_Forward_Local func Test_Proxy_Domain_Forward_Local(t *testing.T) { + t.Parallel() ln, err := net.Listen(fiber.NetworkTCP4, "127.0.0.1:0") require.NoError(t, err) app := fiber.New() @@ -630,7 +687,11 @@ func Test_Proxy_Domain_Forward_Local(t *testing.T) { go func() { require.NoError(t, app.Listener(ln)) }() go func() { require.NoError(t, app1.Listener(ln1)) }() - code, body, errs := fiber.Get("http://" + localDomain + "/test?query_test=true").String() + c := fiber.AcquireClient() + a := c.Get("http://" + localDomain + "/test?query_test=true") + defer fiber.ReleaseClient(c) + code, body, errs := a.String() + require.Empty(t, errs) require.Equal(t, fiber.StatusOK, code) require.Equal(t, "test_local_client:true", body) @@ -638,6 +699,8 @@ func Test_Proxy_Domain_Forward_Local(t *testing.T) { // go test -run Test_Proxy_Balancer_Forward_Local func Test_Proxy_Balancer_Forward_Local(t *testing.T) { + t.Parallel() + app := fiber.New() _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { From b337ee1e651321f1fb5d750c582d62b0d8b193f8 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Sun, 3 Mar 2024 22:10:11 -0500 Subject: [PATCH 06/46] Enable parallel client tests --- client_test.go | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/client_test.go b/client_test.go index 7440a3ea2f..d4c716ae0a 100644 --- a/client_test.go +++ b/client_test.go @@ -51,6 +51,8 @@ func startServer(t *testing.T, app *App, ln *fasthttputil.InmemoryListener) { } func Test_Client_Invalid_URL(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -75,6 +77,8 @@ func Test_Client_Invalid_URL(t *testing.T) { } func Test_Client_Unsupported_Protocol(t *testing.T) { + t.Parallel() + a := Get("ftp://example.com") _, body, errs := a.String() @@ -85,6 +89,8 @@ func Test_Client_Unsupported_Protocol(t *testing.T) { } func Test_Client_Get(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -110,6 +116,8 @@ func Test_Client_Get(t *testing.T) { } func Test_Client_Head(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -135,6 +143,8 @@ func Test_Client_Head(t *testing.T) { } func Test_Client_Post(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -168,6 +178,8 @@ func Test_Client_Post(t *testing.T) { } func Test_Client_Put(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -200,6 +212,8 @@ func Test_Client_Put(t *testing.T) { } func Test_Client_Patch(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -232,6 +246,8 @@ func Test_Client_Patch(t *testing.T) { } func Test_Client_Delete(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -262,6 +278,8 @@ func Test_Client_Delete(t *testing.T) { } func Test_Client_UserAgent(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -274,6 +292,7 @@ func Test_Client_UserAgent(t *testing.T) { startServer(t, app, ln) t.Run("default", func(t *testing.T) { + t.Parallel() for i := 0; i < 5; i++ { a := Get("http://example.com") @@ -288,6 +307,7 @@ func Test_Client_UserAgent(t *testing.T) { }) t.Run("custom", func(t *testing.T) { + t.Parallel() for i := 0; i < 5; i++ { c := AcquireClient() c.UserAgent = "ua" @@ -307,6 +327,7 @@ func Test_Client_UserAgent(t *testing.T) { } func Test_Client_Agent_Set_Or_Add_Headers(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { c.Request().Header.VisitAll(func(key, value []byte) { if k := string(key); k == "K1" || k == "K2" { @@ -334,6 +355,7 @@ func Test_Client_Agent_Set_Or_Add_Headers(t *testing.T) { } func Test_Client_Agent_Connection_Close(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { if c.Request().Header.ConnectionClose() { return c.SendString("close") @@ -349,6 +371,7 @@ func Test_Client_Agent_Connection_Close(t *testing.T) { } func Test_Client_Agent_UserAgent(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Header.UserAgent()) } @@ -362,6 +385,7 @@ func Test_Client_Agent_UserAgent(t *testing.T) { } func Test_Client_Agent_Cookie(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { return c.SendString( c.Cookies("k1") + c.Cookies("k2") + c.Cookies("k3") + c.Cookies("k4")) @@ -379,6 +403,7 @@ func Test_Client_Agent_Cookie(t *testing.T) { } func Test_Client_Agent_Referer(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Header.Referer()) } @@ -392,6 +417,7 @@ func Test_Client_Agent_Referer(t *testing.T) { } func Test_Client_Agent_ContentType(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Header.ContentType()) } @@ -405,6 +431,8 @@ func Test_Client_Agent_ContentType(t *testing.T) { } func Test_Client_Agent_Host(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -432,6 +460,7 @@ func Test_Client_Agent_Host(t *testing.T) { } func Test_Client_Agent_QueryString(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().URI().QueryString()) } @@ -445,6 +474,7 @@ func Test_Client_Agent_QueryString(t *testing.T) { } func Test_Client_Agent_BasicAuth(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { // Get authorization header auth := c.Get(HeaderAuthorization) @@ -464,6 +494,7 @@ func Test_Client_Agent_BasicAuth(t *testing.T) { } func Test_Client_Agent_BodyString(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Body()) } @@ -476,6 +507,7 @@ func Test_Client_Agent_BodyString(t *testing.T) { } func Test_Client_Agent_Body(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Body()) } @@ -488,6 +520,7 @@ func Test_Client_Agent_Body(t *testing.T) { } func Test_Client_Agent_BodyStream(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Body()) } @@ -500,6 +533,8 @@ func Test_Client_Agent_BodyStream(t *testing.T) { } func Test_Client_Agent_Custom_Response(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -536,6 +571,8 @@ func Test_Client_Agent_Custom_Response(t *testing.T) { } func Test_Client_Agent_Dest(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -548,6 +585,7 @@ func Test_Client_Agent_Dest(t *testing.T) { startServer(t, app, ln) t.Run("small dest", func(t *testing.T) { + t.Parallel() dest := []byte("de") a := Get("http://example.com") @@ -563,6 +601,7 @@ func Test_Client_Agent_Dest(t *testing.T) { }) t.Run("enough dest", func(t *testing.T) { + t.Parallel() dest := []byte("foobar") a := Get("http://example.com") @@ -612,6 +651,8 @@ func (*readErrorConn) SetWriteDeadline(_ time.Time) error { } func Test_Client_Agent_RetryIf(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -647,6 +688,7 @@ func Test_Client_Agent_RetryIf(t *testing.T) { } func Test_Client_Agent_Json(t *testing.T) { + t.Parallel() // Test without ctype parameter handler := func(c Ctx) error { require.Equal(t, MIMEApplicationJSON, string(c.Request().Header.ContentType())) @@ -675,6 +717,7 @@ func Test_Client_Agent_Json(t *testing.T) { } func Test_Client_Agent_Json_Error(t *testing.T) { + t.Parallel() a := Get("http://example.com"). JSONEncoder(json.Marshal). JSON(complex(1, 1)) @@ -688,6 +731,7 @@ func Test_Client_Agent_Json_Error(t *testing.T) { } func Test_Client_Agent_XML(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { require.Equal(t, MIMEApplicationXML, string(c.Request().Header.ContentType())) @@ -702,6 +746,7 @@ func Test_Client_Agent_XML(t *testing.T) { } func Test_Client_Agent_XML_Error(t *testing.T) { + t.Parallel() a := Get("http://example.com"). XML(complex(1, 1)) @@ -713,6 +758,7 @@ func Test_Client_Agent_XML_Error(t *testing.T) { } func Test_Client_Agent_Form(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { require.Equal(t, MIMEApplicationForm, string(c.Request().Header.ContentType())) @@ -733,6 +779,8 @@ func Test_Client_Agent_Form(t *testing.T) { } func Test_Client_Agent_MultipartForm(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -769,6 +817,8 @@ func Test_Client_Agent_MultipartForm(t *testing.T) { } func Test_Client_Agent_MultipartForm_Errors(t *testing.T) { + t.Parallel() + a := AcquireAgent() a.mw = &errorMultipartWriter{} @@ -785,6 +835,8 @@ func Test_Client_Agent_MultipartForm_Errors(t *testing.T) { } func Test_Client_Agent_MultipartForm_SendFiles(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -866,6 +918,8 @@ func checkFormFile(t *testing.T, fh *multipart.FileHeader, filename string) { } func Test_Client_Agent_Multipart_Random_Boundary(t *testing.T) { + t.Parallel() + a := Post("http://example.com"). MultipartForm(nil) @@ -875,6 +929,8 @@ func Test_Client_Agent_Multipart_Random_Boundary(t *testing.T) { } func Test_Client_Agent_Multipart_Invalid_Boundary(t *testing.T) { + t.Parallel() + a := Post("http://example.com"). Boundary("*"). MultipartForm(nil) @@ -884,6 +940,8 @@ func Test_Client_Agent_Multipart_Invalid_Boundary(t *testing.T) { } func Test_Client_Agent_SendFile_Error(t *testing.T) { + t.Parallel() + a := Post("http://example.com"). SendFile("non-exist-file!", "") @@ -892,6 +950,7 @@ func Test_Client_Agent_SendFile_Error(t *testing.T) { } func Test_Client_Debug(t *testing.T) { + t.Parallel() handler := func(c Ctx) error { return c.SendString("debug") } @@ -915,6 +974,8 @@ func Test_Client_Debug(t *testing.T) { } func Test_Client_Agent_Timeout(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -940,6 +1001,8 @@ func Test_Client_Agent_Timeout(t *testing.T) { } func Test_Client_Agent_Reuse(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -970,6 +1033,8 @@ func Test_Client_Agent_Reuse(t *testing.T) { } func Test_Client_Agent_InsecureSkipVerify(t *testing.T) { + t.Parallel() + cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") require.NoError(t, err) @@ -1010,6 +1075,8 @@ func Test_Client_Agent_InsecureSkipVerify(t *testing.T) { } func Test_Client_Agent_TLS(t *testing.T) { + t.Parallel() + serverTLSConf, clientTLSConf, err := tlstest.GetTLSConfigs() require.NoError(t, err) @@ -1044,6 +1111,8 @@ func Test_Client_Agent_TLS(t *testing.T) { } func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -1062,6 +1131,7 @@ func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { startServer(t, app, ln) t.Run("success", func(t *testing.T) { + t.Parallel() a := Get("http://example.com?foo"). MaxRedirectsCount(1) @@ -1075,6 +1145,7 @@ func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { }) t.Run("error", func(t *testing.T) { + t.Parallel() a := Get("http://example.com"). MaxRedirectsCount(1) @@ -1089,6 +1160,8 @@ func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { } func Test_Client_Agent_Struct(t *testing.T) { + t.Parallel() + ln := fasthttputil.NewInmemoryListener() app := New() @@ -1105,6 +1178,8 @@ func Test_Client_Agent_Struct(t *testing.T) { startServer(t, app, ln) t.Run("success", func(t *testing.T) { + t.Parallel() + a := Get("http://example.com") a.HostClient.Dial = func(_ string) (net.Conn, error) { return ln.Dial() } @@ -1120,6 +1195,7 @@ func Test_Client_Agent_Struct(t *testing.T) { }) t.Run("pre error", func(t *testing.T) { + t.Parallel() a := Get("http://example.com") errPre := errors.New("pre errors") @@ -1137,6 +1213,7 @@ func Test_Client_Agent_Struct(t *testing.T) { }) t.Run("error", func(t *testing.T) { + t.Parallel() a := Get("http://example.com/error") a.HostClient.Dial = func(_ string) (net.Conn, error) { return ln.Dial() } @@ -1154,6 +1231,7 @@ func Test_Client_Agent_Struct(t *testing.T) { }) t.Run("nil jsonDecoder", func(t *testing.T) { + t.Parallel() a := AcquireAgent() defer ReleaseAgent(a) defer a.ConnectionClose() @@ -1173,6 +1251,8 @@ func Test_Client_Agent_Struct(t *testing.T) { } func Test_Client_Agent_Parse(t *testing.T) { + t.Parallel() + a := Get("https://example.com:10443") require.NoError(t, a.Parse()) From 53b05302f22406f483d6904a548b0ef8fe5222dd Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Sun, 3 Mar 2024 22:45:38 -0500 Subject: [PATCH 07/46] Do not run timing sensitive tests in parallel --- internal/memory/memory_test.go | 31 ++++++++++++++++--------------- middleware/logger/logger_test.go | 1 - middleware/proxy/proxy_test.go | 6 +++--- 3 files changed, 19 insertions(+), 19 deletions(-) diff --git a/internal/memory/memory_test.go b/internal/memory/memory_test.go index 76a751b78d..1dfe89e5ee 100644 --- a/internal/memory/memory_test.go +++ b/internal/memory/memory_test.go @@ -9,9 +9,7 @@ import ( ) // go test -run Test_Memory -v -race - func Test_Memory(t *testing.T) { - t.Parallel() store := New() var ( key = "john" @@ -19,38 +17,41 @@ func Test_Memory(t *testing.T) { exp = 1 * time.Second ) + // Set key with value store.Set(key, val, 0) - store.Set(key, val, 0) - result := store.Get(key) require.Equal(t, val, result) + // Get non-existing key result = store.Get("empty") - require.Equal(t, nil, result) + require.Nil(t, result) + // Set key with value and ttl store.Set(key, val, exp) time.Sleep(1100 * time.Millisecond) - result = store.Get(key) - require.Equal(t, nil, result) + require.Nil(t, result) // TODO: This is failing + // Set key with value and no expiration store.Set(key, val, 0) result = store.Get(key) require.Equal(t, val, result) + // Delete key store.Delete(key) result = store.Get(key) - require.Equal(t, nil, result) + require.Nil(t, result) - store.Set("john", val, 0) - store.Set("doe", val, 0) + // Reset all keys + store.Set("john-reset", val, 0) + store.Set("doe-reset", val, 0) store.Reset() - result = store.Get("john") - require.Equal(t, nil, result) - - result = store.Get("doe") - require.Equal(t, nil, result) + // Check if all keys are deleted + result = store.Get("john-reset") + require.Nil(t, result) + result = store.Get("doe-reset") + require.Nil(t, result) } // go test -v -run=^$ -bench=Benchmark_Memory -benchmem -count=4 diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index b385ea69e0..f24668e19a 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -230,7 +230,6 @@ func getLatencyTimeUnits() []struct { // go test -run Test_Logger_WithLatency func Test_Logger_WithLatency(t *testing.T) { - t.Parallel() buff := bytebufferpool.Get() defer bytebufferpool.Put(buff) app := fiber.New() diff --git a/middleware/proxy/proxy_test.go b/middleware/proxy/proxy_test.go index 089b33b3ef..dd24a6c03a 100644 --- a/middleware/proxy/proxy_test.go +++ b/middleware/proxy/proxy_test.go @@ -487,11 +487,11 @@ func Test_Proxy_DoTimeout_Timeout(t *testing.T) { app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { - return DoTimeout(c, "http://"+addr, time.Second) + return DoTimeout(c, "http://"+addr, 1*time.Second) }) - _, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), int((1*time.Second)/time.Millisecond)) - require.Equal(t, errors.New("test: timeout error 1000ms"), err1) + _, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), int((1*time.Second)/(10*time.Millisecond))) + require.Equal(t, errors.New("test: timeout error 100ms"), err1) } // go test -race -run Test_Proxy_DoDeadline_RestoreOriginalURL From f1969ccbd96840f38131f4f6843ca2ef006a9143 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Sun, 3 Mar 2024 22:49:23 -0500 Subject: [PATCH 08/46] Remove TODO --- internal/memory/memory_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/memory/memory_test.go b/internal/memory/memory_test.go index 1dfe89e5ee..dc637b690a 100644 --- a/internal/memory/memory_test.go +++ b/internal/memory/memory_test.go @@ -30,7 +30,7 @@ func Test_Memory(t *testing.T) { store.Set(key, val, exp) time.Sleep(1100 * time.Millisecond) result = store.Get(key) - require.Nil(t, result) // TODO: This is failing + require.Nil(t, result) // Set key with value and no expiration store.Set(key, val, 0) From dac9a75baa99c72684ceb17628d62299c89337ce Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Sun, 3 Mar 2024 23:02:17 -0500 Subject: [PATCH 09/46] Revert Test_Proxy_DoTimeout_Timeout, and remove t.Parallel() for it --- client_test.go | 2 ++ middleware/proxy/proxy_test.go | 8 +++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client_test.go b/client_test.go index d4c716ae0a..a5feedaf2a 100644 --- a/client_test.go +++ b/client_test.go @@ -1054,6 +1054,7 @@ func Test_Client_Agent_InsecureSkipVerify(t *testing.T) { return c.SendString("ignore tls") }) + // We can't use startServer here because the listener is a different type go func() { //nolint:errcheck // We don't care about the error here app.Listener(ln, ListenConfig{ @@ -1091,6 +1092,7 @@ func Test_Client_Agent_TLS(t *testing.T) { return c.SendString("tls") }) + // We can't use startServer here because the listener is a different type go func() { //nolint:errcheck // We don't care about the error here app.Listener(ln, ListenConfig{ diff --git a/middleware/proxy/proxy_test.go b/middleware/proxy/proxy_test.go index dd24a6c03a..51fc978cd6 100644 --- a/middleware/proxy/proxy_test.go +++ b/middleware/proxy/proxy_test.go @@ -478,8 +478,6 @@ func Test_Proxy_DoTimeout_RestoreOriginalURL(t *testing.T) { // go test -race -run Test_Proxy_DoTimeout_Timeout func Test_Proxy_DoTimeout_Timeout(t *testing.T) { - t.Parallel() - _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { time.Sleep(time.Second * 5) return c.SendString("proxied") @@ -487,11 +485,11 @@ func Test_Proxy_DoTimeout_Timeout(t *testing.T) { app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { - return DoTimeout(c, "http://"+addr, 1*time.Second) + return DoTimeout(c, "http://"+addr, time.Second) }) - _, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), int((1*time.Second)/(10*time.Millisecond))) - require.Equal(t, errors.New("test: timeout error 100ms"), err1) + _, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), int((1*time.Second)/time.Millisecond)) + require.Equal(t, errors.New("test: timeout error 1000ms"), err1) } // go test -race -run Test_Proxy_DoDeadline_RestoreOriginalURL From d7fce2df1225b9e3feb5d5c22f9ba72bdededd30 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Sun, 3 Mar 2024 23:53:23 -0500 Subject: [PATCH 10/46] Do not calculate favicon len on each handler call --- middleware/favicon/favicon.go | 42 ++++++++++++++++++---------------- middleware/proxy/proxy_test.go | 4 +--- 2 files changed, 23 insertions(+), 23 deletions(-) diff --git a/middleware/favicon/favicon.go b/middleware/favicon/favicon.go index 66fb6e6000..c589650e32 100644 --- a/middleware/favicon/favicon.go +++ b/middleware/favicon/favicon.go @@ -82,16 +82,18 @@ func New(config ...Config) fiber.Handler { } } - // Load icon if provided + // Load iconData if provided var ( - err error - icon []byte - iconLen string + err error + iconData []byte + iconLenHeader string + iconLen int ) if cfg.Data != nil { // use the provided favicon data - icon = cfg.Data - iconLen = strconv.Itoa(len(cfg.Data)) + iconData = cfg.Data + iconLenHeader = strconv.Itoa(len(cfg.Data)) + iconLen = len(cfg.Data) } else if cfg.File != "" { // read from configured filesystem if present if cfg.FileSystem != nil { @@ -99,14 +101,15 @@ func New(config ...Config) fiber.Handler { if err != nil { panic(err) } - if icon, err = io.ReadAll(f); err != nil { + if iconData, err = io.ReadAll(f); err != nil { panic(err) } - } else if icon, err = os.ReadFile(cfg.File); err != nil { + } else if iconData, err = os.ReadFile(cfg.File); err != nil { panic(err) } - iconLen = strconv.Itoa(len(icon)) + iconLenHeader = strconv.Itoa(len(iconData)) + iconLen = len(iconData) } // Return new handler @@ -121,24 +124,23 @@ func New(config ...Config) fiber.Handler { return c.Next() } - // Only allow GET, HEAD and OPTIONS requests - if c.Method() != fiber.MethodGet && c.Method() != fiber.MethodHead { - if c.Method() != fiber.MethodOptions { - c.Status(fiber.StatusMethodNotAllowed) - } else { - c.Status(fiber.StatusOK) - } + // Only allow GET, HEAD, and OPTIONS requests + if c.Method() != fiber.MethodGet && c.Method() != fiber.MethodHead && c.Method() != fiber.MethodOptions { + c.Status(fiber.StatusMethodNotAllowed) c.Set(fiber.HeaderAllow, hAllow) - c.Set(fiber.HeaderContentLength, hZero) return nil } + if c.Method() == fiber.MethodOptions { + return c.SendStatus(fiber.StatusOK) + } + // Serve cached favicon - if len(icon) > 0 { - c.Set(fiber.HeaderContentLength, iconLen) + if iconLen > 0 { + c.Set(fiber.HeaderContentLength, iconLenHeader) c.Set(fiber.HeaderContentType, hType) c.Set(fiber.HeaderCacheControl, cfg.CacheControl) - return c.Status(fiber.StatusOK).Send(icon) + return c.Status(fiber.StatusOK).Send(iconData) } return c.SendStatus(fiber.StatusNoContent) diff --git a/middleware/proxy/proxy_test.go b/middleware/proxy/proxy_test.go index 51fc978cd6..1aeab45d1e 100644 --- a/middleware/proxy/proxy_test.go +++ b/middleware/proxy/proxy_test.go @@ -516,8 +516,6 @@ func Test_Proxy_DoDeadline_RestoreOriginalURL(t *testing.T) { // go test -race -run Test_Proxy_DoDeadline_PastDeadline func Test_Proxy_DoDeadline_PastDeadline(t *testing.T) { - t.Parallel() - _, addr := createProxyTestServer(t, func(c fiber.Ctx) error { time.Sleep(time.Second * 5) return c.SendString("proxied") @@ -525,7 +523,7 @@ func Test_Proxy_DoDeadline_PastDeadline(t *testing.T) { app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { - return DoDeadline(c, "http://"+addr, time.Now().Add(2*time.Second)) + return DoDeadline(c, "http://"+addr, time.Now().Add(time.Second)) }) _, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), int((1*time.Second)/time.Millisecond)) From c9a033c1fffb05e60454d4679376aa47a22f7ee3 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Mon, 4 Mar 2024 00:01:36 -0500 Subject: [PATCH 11/46] Revert logic change --- middleware/favicon/favicon.go | 15 ++++++++------- middleware/proxy/proxy_test.go | 2 +- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/middleware/favicon/favicon.go b/middleware/favicon/favicon.go index c589650e32..f1de00cb3d 100644 --- a/middleware/favicon/favicon.go +++ b/middleware/favicon/favicon.go @@ -124,17 +124,18 @@ func New(config ...Config) fiber.Handler { return c.Next() } - // Only allow GET, HEAD, and OPTIONS requests - if c.Method() != fiber.MethodGet && c.Method() != fiber.MethodHead && c.Method() != fiber.MethodOptions { - c.Status(fiber.StatusMethodNotAllowed) + // Only allow GET, HEAD and OPTIONS requests + if c.Method() != fiber.MethodGet && c.Method() != fiber.MethodHead { + if c.Method() != fiber.MethodOptions { + c.Status(fiber.StatusMethodNotAllowed) + } else { + c.Status(fiber.StatusOK) + } c.Set(fiber.HeaderAllow, hAllow) + c.Set(fiber.HeaderContentLength, hZero) return nil } - if c.Method() == fiber.MethodOptions { - return c.SendStatus(fiber.StatusOK) - } - // Serve cached favicon if iconLen > 0 { c.Set(fiber.HeaderContentLength, iconLenHeader) diff --git a/middleware/proxy/proxy_test.go b/middleware/proxy/proxy_test.go index 1aeab45d1e..ab86ea5e96 100644 --- a/middleware/proxy/proxy_test.go +++ b/middleware/proxy/proxy_test.go @@ -523,7 +523,7 @@ func Test_Proxy_DoDeadline_PastDeadline(t *testing.T) { app := fiber.New() app.Get("/test", func(c fiber.Ctx) error { - return DoDeadline(c, "http://"+addr, time.Now().Add(time.Second)) + return DoDeadline(c, "http://"+addr, time.Now().Add(2*time.Second)) }) _, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), int((1*time.Second)/time.Millisecond)) From ec9192f0e2aefa2c92d0ed1e1ff8f277e3fa8d13 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Mon, 4 Mar 2024 00:08:39 -0500 Subject: [PATCH 12/46] Increase timeout of SaveFile tests --- ctx_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ctx_test.go b/ctx_test.go index fb601bf49b..ace7896739 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -3193,7 +3193,7 @@ func Test_Ctx_SaveFile(t *testing.T) { req.Header.Set("Content-Type", writer.FormDataContentType()) req.Header.Set("Content-Length", strconv.Itoa(len(body.Bytes()))) - resp, err := app.Test(req) + resp, err := app.Test(req, 2000) require.NoError(t, err, "app.Test(req)") require.Equal(t, StatusOK, resp.StatusCode, "Status code") } @@ -3235,7 +3235,7 @@ func Test_Ctx_SaveFileToStorage(t *testing.T) { req.Header.Set("Content-Type", writer.FormDataContentType()) req.Header.Set("Content-Length", strconv.Itoa(len(body.Bytes()))) - resp, err := app.Test(req) + resp, err := app.Test(req, 2000) require.NoError(t, err, "app.Test(req)") require.Equal(t, StatusOK, resp.StatusCode, "Status code") } From 394496f58da1dab9a647ae5ab016ab52e625ecb1 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Mon, 4 Mar 2024 00:19:48 -0500 Subject: [PATCH 13/46] Do not run time sensitive tests in parallel --- middleware/limiter/limiter_test.go | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/middleware/limiter/limiter_test.go b/middleware/limiter/limiter_test.go index 7b88d1d521..5bcb535cc9 100644 --- a/middleware/limiter/limiter_test.go +++ b/middleware/limiter/limiter_test.go @@ -15,9 +15,6 @@ import ( // go test -run Test_Limiter_Concurrency_Store -race -v func Test_Limiter_Concurrency_Store(t *testing.T) { - t.Parallel() - // Test concurrency using a custom store - app := fiber.New() app.Use(New(Config{ @@ -62,9 +59,6 @@ func Test_Limiter_Concurrency_Store(t *testing.T) { // go test -run Test_Limiter_Concurrency -race -v func Test_Limiter_Concurrency(t *testing.T) { - t.Parallel() - // Test concurrency using a default store - app := fiber.New() app.Use(New(Config{ @@ -343,7 +337,6 @@ func Test_Limiter_Fixed_Window_Custom_Storage_Skip_Failed_Requests(t *testing.T) // go test -run Test_Limiter_Sliding_Window_Skip_Failed_Requests -v func Test_Limiter_Sliding_Window_Skip_Failed_Requests(t *testing.T) { - t.Parallel() app := fiber.New() app.Use(New(Config{ @@ -420,9 +413,6 @@ func Test_Limiter_Sliding_Window_Custom_Storage_Skip_Failed_Requests(t *testing. // go test -run Test_Limiter_Fixed_Window_Skip_Successful_Requests -v func Test_Limiter_Fixed_Window_Skip_Successful_Requests(t *testing.T) { - t.Parallel() - // Test concurrency using a default store - app := fiber.New() app.Use(New(Config{ @@ -460,9 +450,6 @@ func Test_Limiter_Fixed_Window_Skip_Successful_Requests(t *testing.T) { // go test -run Test_Limiter_Fixed_Window_Custom_Storage_Skip_Successful_Requests -v func Test_Limiter_Fixed_Window_Custom_Storage_Skip_Successful_Requests(t *testing.T) { - t.Parallel() - // Test concurrency using a default store - app := fiber.New() app.Use(New(Config{ @@ -501,9 +488,6 @@ func Test_Limiter_Fixed_Window_Custom_Storage_Skip_Successful_Requests(t *testin // go test -run Test_Limiter_Sliding_Window_Skip_Successful_Requests -v func Test_Limiter_Sliding_Window_Skip_Successful_Requests(t *testing.T) { - t.Parallel() - // Test concurrency using a default store - app := fiber.New() app.Use(New(Config{ @@ -541,9 +525,6 @@ func Test_Limiter_Sliding_Window_Skip_Successful_Requests(t *testing.T) { // go test -run Test_Limiter_Sliding_Window_Custom_Storage_Skip_Successful_Requests -v func Test_Limiter_Sliding_Window_Custom_Storage_Skip_Successful_Requests(t *testing.T) { - t.Parallel() - // Test concurrency using a default store - app := fiber.New() app.Use(New(Config{ @@ -678,7 +659,6 @@ func Benchmark_Limiter(b *testing.B) { // go test -run Test_Sliding_Window -race -v func Test_Sliding_Window(t *testing.T) { - t.Parallel() app := fiber.New() app.Use(New(Config{ Max: 10, From bca9f1fcb5937c5a9f3516d084c61d146e168174 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Mon, 4 Mar 2024 00:37:19 -0500 Subject: [PATCH 14/46] The Agent can't be run in parallel --- client_test.go | 88 ++++---------------------------------------------- 1 file changed, 6 insertions(+), 82 deletions(-) diff --git a/client_test.go b/client_test.go index a5feedaf2a..a69e504eb9 100644 --- a/client_test.go +++ b/client_test.go @@ -51,8 +51,6 @@ func startServer(t *testing.T, app *App, ln *fasthttputil.InmemoryListener) { } func Test_Client_Invalid_URL(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -77,8 +75,6 @@ func Test_Client_Invalid_URL(t *testing.T) { } func Test_Client_Unsupported_Protocol(t *testing.T) { - t.Parallel() - a := Get("ftp://example.com") _, body, errs := a.String() @@ -89,8 +85,6 @@ func Test_Client_Unsupported_Protocol(t *testing.T) { } func Test_Client_Get(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -116,8 +110,6 @@ func Test_Client_Get(t *testing.T) { } func Test_Client_Head(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -143,8 +135,6 @@ func Test_Client_Head(t *testing.T) { } func Test_Client_Post(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -178,8 +168,6 @@ func Test_Client_Post(t *testing.T) { } func Test_Client_Put(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -212,8 +200,6 @@ func Test_Client_Put(t *testing.T) { } func Test_Client_Patch(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -246,8 +232,6 @@ func Test_Client_Patch(t *testing.T) { } func Test_Client_Delete(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -278,8 +262,6 @@ func Test_Client_Delete(t *testing.T) { } func Test_Client_UserAgent(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -292,7 +274,6 @@ func Test_Client_UserAgent(t *testing.T) { startServer(t, app, ln) t.Run("default", func(t *testing.T) { - t.Parallel() for i := 0; i < 5; i++ { a := Get("http://example.com") @@ -307,7 +288,6 @@ func Test_Client_UserAgent(t *testing.T) { }) t.Run("custom", func(t *testing.T) { - t.Parallel() for i := 0; i < 5; i++ { c := AcquireClient() c.UserAgent = "ua" @@ -327,7 +307,6 @@ func Test_Client_UserAgent(t *testing.T) { } func Test_Client_Agent_Set_Or_Add_Headers(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { c.Request().Header.VisitAll(func(key, value []byte) { if k := string(key); k == "K1" || k == "K2" { @@ -355,7 +334,6 @@ func Test_Client_Agent_Set_Or_Add_Headers(t *testing.T) { } func Test_Client_Agent_Connection_Close(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { if c.Request().Header.ConnectionClose() { return c.SendString("close") @@ -371,7 +349,6 @@ func Test_Client_Agent_Connection_Close(t *testing.T) { } func Test_Client_Agent_UserAgent(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Header.UserAgent()) } @@ -385,7 +362,6 @@ func Test_Client_Agent_UserAgent(t *testing.T) { } func Test_Client_Agent_Cookie(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.SendString( c.Cookies("k1") + c.Cookies("k2") + c.Cookies("k3") + c.Cookies("k4")) @@ -403,7 +379,6 @@ func Test_Client_Agent_Cookie(t *testing.T) { } func Test_Client_Agent_Referer(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Header.Referer()) } @@ -417,7 +392,6 @@ func Test_Client_Agent_Referer(t *testing.T) { } func Test_Client_Agent_ContentType(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Header.ContentType()) } @@ -431,8 +405,6 @@ func Test_Client_Agent_ContentType(t *testing.T) { } func Test_Client_Agent_Host(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -460,7 +432,6 @@ func Test_Client_Agent_Host(t *testing.T) { } func Test_Client_Agent_QueryString(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().URI().QueryString()) } @@ -474,7 +445,6 @@ func Test_Client_Agent_QueryString(t *testing.T) { } func Test_Client_Agent_BasicAuth(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { // Get authorization header auth := c.Get(HeaderAuthorization) @@ -494,7 +464,6 @@ func Test_Client_Agent_BasicAuth(t *testing.T) { } func Test_Client_Agent_BodyString(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Body()) } @@ -507,7 +476,6 @@ func Test_Client_Agent_BodyString(t *testing.T) { } func Test_Client_Agent_Body(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Body()) } @@ -520,7 +488,6 @@ func Test_Client_Agent_Body(t *testing.T) { } func Test_Client_Agent_BodyStream(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.Send(c.Request().Body()) } @@ -533,8 +500,6 @@ func Test_Client_Agent_BodyStream(t *testing.T) { } func Test_Client_Agent_Custom_Response(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -571,8 +536,6 @@ func Test_Client_Agent_Custom_Response(t *testing.T) { } func Test_Client_Agent_Dest(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -585,10 +548,11 @@ func Test_Client_Agent_Dest(t *testing.T) { startServer(t, app, ln) t.Run("small dest", func(t *testing.T) { - t.Parallel() dest := []byte("de") - a := Get("http://example.com") + c := AcquireClient() + a := c.Get("http://example.com") + defer ReleaseClient(c) a.HostClient.Dial = func(_ string) (net.Conn, error) { return ln.Dial() } @@ -601,10 +565,11 @@ func Test_Client_Agent_Dest(t *testing.T) { }) t.Run("enough dest", func(t *testing.T) { - t.Parallel() dest := []byte("foobar") - a := Get("http://example.com") + c := AcquireClient() + a := c.Get("http://example.com") + defer ReleaseClient(c) a.HostClient.Dial = func(_ string) (net.Conn, error) { return ln.Dial() } @@ -651,8 +616,6 @@ func (*readErrorConn) SetWriteDeadline(_ time.Time) error { } func Test_Client_Agent_RetryIf(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -688,7 +651,6 @@ func Test_Client_Agent_RetryIf(t *testing.T) { } func Test_Client_Agent_Json(t *testing.T) { - t.Parallel() // Test without ctype parameter handler := func(c Ctx) error { require.Equal(t, MIMEApplicationJSON, string(c.Request().Header.ContentType())) @@ -717,7 +679,6 @@ func Test_Client_Agent_Json(t *testing.T) { } func Test_Client_Agent_Json_Error(t *testing.T) { - t.Parallel() a := Get("http://example.com"). JSONEncoder(json.Marshal). JSON(complex(1, 1)) @@ -731,7 +692,6 @@ func Test_Client_Agent_Json_Error(t *testing.T) { } func Test_Client_Agent_XML(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { require.Equal(t, MIMEApplicationXML, string(c.Request().Header.ContentType())) @@ -746,7 +706,6 @@ func Test_Client_Agent_XML(t *testing.T) { } func Test_Client_Agent_XML_Error(t *testing.T) { - t.Parallel() a := Get("http://example.com"). XML(complex(1, 1)) @@ -758,7 +717,6 @@ func Test_Client_Agent_XML_Error(t *testing.T) { } func Test_Client_Agent_Form(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { require.Equal(t, MIMEApplicationForm, string(c.Request().Header.ContentType())) @@ -779,8 +737,6 @@ func Test_Client_Agent_Form(t *testing.T) { } func Test_Client_Agent_MultipartForm(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -817,8 +773,6 @@ func Test_Client_Agent_MultipartForm(t *testing.T) { } func Test_Client_Agent_MultipartForm_Errors(t *testing.T) { - t.Parallel() - a := AcquireAgent() a.mw = &errorMultipartWriter{} @@ -835,8 +789,6 @@ func Test_Client_Agent_MultipartForm_Errors(t *testing.T) { } func Test_Client_Agent_MultipartForm_SendFiles(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -918,8 +870,6 @@ func checkFormFile(t *testing.T, fh *multipart.FileHeader, filename string) { } func Test_Client_Agent_Multipart_Random_Boundary(t *testing.T) { - t.Parallel() - a := Post("http://example.com"). MultipartForm(nil) @@ -929,8 +879,6 @@ func Test_Client_Agent_Multipart_Random_Boundary(t *testing.T) { } func Test_Client_Agent_Multipart_Invalid_Boundary(t *testing.T) { - t.Parallel() - a := Post("http://example.com"). Boundary("*"). MultipartForm(nil) @@ -940,8 +888,6 @@ func Test_Client_Agent_Multipart_Invalid_Boundary(t *testing.T) { } func Test_Client_Agent_SendFile_Error(t *testing.T) { - t.Parallel() - a := Post("http://example.com"). SendFile("non-exist-file!", "") @@ -950,7 +896,6 @@ func Test_Client_Agent_SendFile_Error(t *testing.T) { } func Test_Client_Debug(t *testing.T) { - t.Parallel() handler := func(c Ctx) error { return c.SendString("debug") } @@ -974,8 +919,6 @@ func Test_Client_Debug(t *testing.T) { } func Test_Client_Agent_Timeout(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -1001,8 +944,6 @@ func Test_Client_Agent_Timeout(t *testing.T) { } func Test_Client_Agent_Reuse(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -1033,8 +974,6 @@ func Test_Client_Agent_Reuse(t *testing.T) { } func Test_Client_Agent_InsecureSkipVerify(t *testing.T) { - t.Parallel() - cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") require.NoError(t, err) @@ -1076,8 +1015,6 @@ func Test_Client_Agent_InsecureSkipVerify(t *testing.T) { } func Test_Client_Agent_TLS(t *testing.T) { - t.Parallel() - serverTLSConf, clientTLSConf, err := tlstest.GetTLSConfigs() require.NoError(t, err) @@ -1113,8 +1050,6 @@ func Test_Client_Agent_TLS(t *testing.T) { } func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -1133,7 +1068,6 @@ func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { startServer(t, app, ln) t.Run("success", func(t *testing.T) { - t.Parallel() a := Get("http://example.com?foo"). MaxRedirectsCount(1) @@ -1147,7 +1081,6 @@ func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { }) t.Run("error", func(t *testing.T) { - t.Parallel() a := Get("http://example.com"). MaxRedirectsCount(1) @@ -1162,8 +1095,6 @@ func Test_Client_Agent_MaxRedirectsCount(t *testing.T) { } func Test_Client_Agent_Struct(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := New() @@ -1180,8 +1111,6 @@ func Test_Client_Agent_Struct(t *testing.T) { startServer(t, app, ln) t.Run("success", func(t *testing.T) { - t.Parallel() - a := Get("http://example.com") a.HostClient.Dial = func(_ string) (net.Conn, error) { return ln.Dial() } @@ -1197,7 +1126,6 @@ func Test_Client_Agent_Struct(t *testing.T) { }) t.Run("pre error", func(t *testing.T) { - t.Parallel() a := Get("http://example.com") errPre := errors.New("pre errors") @@ -1215,7 +1143,6 @@ func Test_Client_Agent_Struct(t *testing.T) { }) t.Run("error", func(t *testing.T) { - t.Parallel() a := Get("http://example.com/error") a.HostClient.Dial = func(_ string) (net.Conn, error) { return ln.Dial() } @@ -1233,7 +1160,6 @@ func Test_Client_Agent_Struct(t *testing.T) { }) t.Run("nil jsonDecoder", func(t *testing.T) { - t.Parallel() a := AcquireAgent() defer ReleaseAgent(a) defer a.ConnectionClose() @@ -1253,8 +1179,6 @@ func Test_Client_Agent_Struct(t *testing.T) { } func Test_Client_Agent_Parse(t *testing.T) { - t.Parallel() - a := Get("https://example.com:10443") require.NoError(t, a.Parse()) From 457d20c931d5d0dc626b100e2cc219d4d184a40e Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Mon, 4 Mar 2024 00:40:09 -0500 Subject: [PATCH 15/46] Do not run time sensitive tests in parallel --- middleware/cache/cache_test.go | 6 ------ 1 file changed, 6 deletions(-) diff --git a/middleware/cache/cache_test.go b/middleware/cache/cache_test.go index 1beee76d62..519e6aeb1d 100644 --- a/middleware/cache/cache_test.go +++ b/middleware/cache/cache_test.go @@ -498,8 +498,6 @@ func Test_CustomKey(t *testing.T) { } func Test_CustomExpiration(t *testing.T) { - t.Parallel() - app := fiber.New() var called bool var newCacheTime int @@ -712,8 +710,6 @@ func stableAscendingExpiration() func(c1 fiber.Ctx, c2 *Config) time.Duration { } func Test_Cache_MaxBytesOrder(t *testing.T) { - t.Parallel() - app := fiber.New() app.Use(New(Config{ MaxBytes: 2, @@ -749,8 +745,6 @@ func Test_Cache_MaxBytesOrder(t *testing.T) { } func Test_Cache_MaxBytesSizes(t *testing.T) { - t.Parallel() - app := fiber.New() app.Use(New(Config{ From 62fe598d51692621f9354e5ee1bd9f411e776fd6 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Mon, 4 Mar 2024 23:57:41 -0500 Subject: [PATCH 16/46] Fixes based on uber/nilaway --- client/client_test.go | 6 +++++- client/response.go | 6 ++++++ listen_test.go | 4 ++-- middleware/session/session.go | 7 +++++++ redirect.go | 29 ++++++++++++++++++++++++++--- 5 files changed, 46 insertions(+), 6 deletions(-) diff --git a/client/client_test.go b/client/client_test.go index 4fd2e484a6..63c095bfef 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1262,6 +1262,7 @@ func Test_Client_TLS(t *testing.T) { DisableStartupMessage: true, })) }() + time.Sleep(1 * time.Second) client := NewClient() resp, err := client.SetTLSConfig(clientTLSConf).Get("https://" + ln.Addr().String()) @@ -1295,6 +1296,7 @@ func Test_Client_TLS_Error(t *testing.T) { DisableStartupMessage: true, })) }() + time.Sleep(1 * time.Second) client := NewClient() resp, err := client.SetTLSConfig(clientTLSConf).Get("https://" + ln.Addr().String()) @@ -1325,6 +1327,7 @@ func Test_Client_TLS_Empty_TLSConfig(t *testing.T) { DisableStartupMessage: true, })) }() + time.Sleep(1 * time.Second) client := NewClient() resp, err := client.Get("https://" + ln.Addr().String()) @@ -1590,9 +1593,10 @@ func Test_Client_SetRetryConfig(t *testing.T) { client.SetRetryConfig(retryConfig) _, err := core.execute(context.Background(), client, req) - require.NoError(t, err) + require.Error(t, err) require.Equal(t, retryConfig.InitialInterval, client.RetryConfig().InitialInterval) require.Equal(t, retryConfig.MaxRetryCount, client.RetryConfig().MaxRetryCount) + ReleaseRequest(req) } func Benchmark_Client_Request(b *testing.B) { diff --git a/client/response.go b/client/response.go index f6ecd6fcd8..81348a795e 100644 --- a/client/response.go +++ b/client/response.go @@ -73,11 +73,17 @@ func (r *Response) String() string { // JSON method will unmarshal body to json. func (r *Response) JSON(v any) error { + if r.client == nil { + return errors.New("cannot unmarshal JSON: client is nil") + } return r.client.jsonUnmarshal(r.Body(), v) } // XML method will unmarshal body to xml. func (r *Response) XML(v any) error { + if r.client == nil { + return errors.New("cannot unmarshal XML: client is nil") + } return r.client.xmlUnmarshal(r.Body(), v) } diff --git a/listen_test.go b/listen_test.go index 877d459e61..ac4c1370c3 100644 --- a/listen_test.go +++ b/listen_test.go @@ -84,8 +84,8 @@ func Test_Listen_Graceful_Shutdown(t *testing.T) { ExpectedStatusCode int ExpectedErr error }{ - {Time: 100 * time.Millisecond, ExpectedBody: "example.com", ExpectedStatusCode: StatusOK, ExpectedErr: nil}, - {Time: 500 * time.Millisecond, ExpectedBody: "", ExpectedStatusCode: StatusOK, ExpectedErr: errors.New("InmemoryListener is already closed: use of closed network connection")}, + {Time: 500 * time.Millisecond, ExpectedBody: "example.com", ExpectedStatusCode: StatusOK, ExpectedErr: nil}, + {Time: 3 * time.Second, ExpectedBody: "", ExpectedStatusCode: StatusOK, ExpectedErr: errors.New("InmemoryListener is already closed: use of closed network connection")}, } for _, tc := range testCases { diff --git a/middleware/session/session.go b/middleware/session/session.go index c257343968..71ffebf56c 100644 --- a/middleware/session/session.go +++ b/middleware/session/session.go @@ -214,6 +214,10 @@ func (s *Session) SetExpiry(exp time.Duration) { } func (s *Session) setSession() { + if s.config == nil { + return + } + if s.config.source == SourceHeader { s.ctx.Request().Header.SetBytesV(s.config.sessionName, []byte(s.id)) s.ctx.Response().Header.SetBytesV(s.config.sessionName, []byte(s.id)) @@ -246,6 +250,9 @@ func (s *Session) setSession() { } func (s *Session) delSession() { + if s.config == nil { + return + } if s.config.source == SourceHeader { s.ctx.Request().Header.Del(s.config.sessionName) s.ctx.Response().Header.Del(s.config.sessionName) diff --git a/redirect.go b/redirect.go index 98053db80a..ae693c8a9b 100644 --- a/redirect.go +++ b/redirect.go @@ -119,6 +119,10 @@ func (r *Redirect) WithInput() *Redirect { // Get flash messages. func (r *Redirect) Messages() map[string]string { + if r.c == nil { + return make(map[string]string) // Return an empty map if `c` is nil. + } + msgs := r.c.redirectionMessages flashMessages := make(map[string]string, len(msgs)) @@ -135,8 +139,11 @@ func (r *Redirect) Messages() map[string]string { // Get flash message by key. func (r *Redirect) Message(key string) string { - msgs := r.c.redirectionMessages + if r.c == nil { + return "" + } + msgs := r.c.redirectionMessages for _, msg := range msgs { k, v := parseMessage(msg) @@ -149,6 +156,10 @@ func (r *Redirect) Message(key string) string { // Get old input data. func (r *Redirect) OldInputs() map[string]string { + if r.c == nil { + return make(map[string]string) + } + msgs := r.c.redirectionMessages oldInputs := make(map[string]string, len(msgs)) @@ -156,7 +167,7 @@ func (r *Redirect) OldInputs() map[string]string { k, v := parseMessage(msg) if strings.HasPrefix(k, OldInputDataPrefix) { - // remove "old_input_data_" part from key + // Remove "old_input_data_" part from key oldInputs[k[len(OldInputDataPrefix):]] = v } } @@ -165,8 +176,11 @@ func (r *Redirect) OldInputs() map[string]string { // Get old input data by key. func (r *Redirect) OldInput(key string) string { - msgs := r.c.redirectionMessages + if r.c == nil { + return "" + } + msgs := r.c.redirectionMessages for _, msg := range msgs { k, v := parseMessage(msg) @@ -188,6 +202,10 @@ func (r *Redirect) To(location string) error { // Route redirects to the Route registered in the app with appropriate parameters. // If you want to send queries or params to route, you should use config parameter. func (r *Redirect) Route(name string, config ...RedirectConfig) error { + if r.c == nil { + return errors.New("redirect context is nil") + } + // Check config cfg := RedirectConfig{} if len(config) > 0 { @@ -272,6 +290,11 @@ func (r *Redirect) Back(fallback ...string) error { // setFlash is a method to get flash messages before removing them func (r *Redirect) setFlash() { + if r.c == nil { + // Handle the nil case, possibly logging an error or returning early. + return + } + // parse flash messages cookieValue := r.c.Cookies(FlashCookieName) From 3e2b5c0f533d8dd2bfa95efbf7a12cdae746c69a Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Tue, 5 Mar 2024 00:04:19 -0500 Subject: [PATCH 17/46] Revert change to Client test --- client/client_test.go | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/client/client_test.go b/client/client_test.go index 63c095bfef..8aa2d93307 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1581,8 +1581,6 @@ func Test_Client_SetProxyURL(t *testing.T) { } func Test_Client_SetRetryConfig(t *testing.T) { - t.Parallel() - retryConfig := &retry.Config{ InitialInterval: 1 * time.Second, MaxRetryCount: 3, @@ -1593,10 +1591,9 @@ func Test_Client_SetRetryConfig(t *testing.T) { client.SetRetryConfig(retryConfig) _, err := core.execute(context.Background(), client, req) - require.Error(t, err) + require.NoError(t, err) require.Equal(t, retryConfig.InitialInterval, client.RetryConfig().InitialInterval) require.Equal(t, retryConfig.MaxRetryCount, client.RetryConfig().MaxRetryCount) - ReleaseRequest(req) } func Benchmark_Client_Request(b *testing.B) { From 8a0bee662ac4f861e5b0a4f54672ad67c11afb19 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Tue, 5 Mar 2024 00:06:31 -0500 Subject: [PATCH 18/46] Run parallel --- client/client_test.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/client/client_test.go b/client/client_test.go index 8aa2d93307..75a922a4b5 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1581,6 +1581,8 @@ func Test_Client_SetProxyURL(t *testing.T) { } func Test_Client_SetRetryConfig(t *testing.T) { + t.Parallel() + retryConfig := &retry.Config{ InitialInterval: 1 * time.Second, MaxRetryCount: 3, From 87b553b709b27a0bd3ca4cddead56149b148c331 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez <835733+gaby@users.noreply.github.com> Date: Tue, 5 Mar 2024 01:28:23 -0500 Subject: [PATCH 19/46] Update client_test.go --- client/client_test.go | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/client/client_test.go b/client/client_test.go index 75a922a4b5..947c8dbbfc 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1581,8 +1581,6 @@ func Test_Client_SetProxyURL(t *testing.T) { } func Test_Client_SetRetryConfig(t *testing.T) { - t.Parallel() - retryConfig := &retry.Config{ InitialInterval: 1 * time.Second, MaxRetryCount: 3, @@ -1593,7 +1591,7 @@ func Test_Client_SetRetryConfig(t *testing.T) { client.SetRetryConfig(retryConfig) _, err := core.execute(context.Background(), client, req) - require.NoError(t, err) + require.Error(t, err) require.Equal(t, retryConfig.InitialInterval, client.RetryConfig().InitialInterval) require.Equal(t, retryConfig.MaxRetryCount, client.RetryConfig().MaxRetryCount) } From 0615e27afabcd45c32af9427bf2d9ebe7dae8982 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez <835733+gaby@users.noreply.github.com> Date: Tue, 5 Mar 2024 01:31:19 -0500 Subject: [PATCH 20/46] Update client_test.go --- client/client_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/client_test.go b/client/client_test.go index 947c8dbbfc..e6ba9d7b66 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1587,7 +1587,7 @@ func Test_Client_SetRetryConfig(t *testing.T) { } core, client, req := newCore(), NewClient(), AcquireRequest() - req.SetURL("http://example.com") + req.SetURL("http://exampleretry.com") client.SetRetryConfig(retryConfig) _, err := core.execute(context.Background(), client, req) From a4ad846db45db1039e0d9505cef9f03a9052aab6 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez <835733+gaby@users.noreply.github.com> Date: Tue, 5 Mar 2024 01:41:30 -0500 Subject: [PATCH 21/46] Update cache_test.go --- middleware/cache/cache_test.go | 4 ---- 1 file changed, 4 deletions(-) diff --git a/middleware/cache/cache_test.go b/middleware/cache/cache_test.go index 519e6aeb1d..dcdb38d0e0 100644 --- a/middleware/cache/cache_test.go +++ b/middleware/cache/cache_test.go @@ -44,8 +44,6 @@ func Test_Cache_CacheControl(t *testing.T) { } func Test_Cache_Expired(t *testing.T) { - t.Parallel() - app := fiber.New() app.Use(New(Config{Expiration: 2 * time.Second})) @@ -410,8 +408,6 @@ func Test_Cache_Post(t *testing.T) { } func Test_Cache_NothingToCache(t *testing.T) { - t.Parallel() - app := fiber.New() app.Use(New(Config{Expiration: -(time.Second * 1)})) From 1e771482d1f1de06fc46d67ee8081024dfb9beba Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez <835733+gaby@users.noreply.github.com> Date: Tue, 5 Mar 2024 01:45:42 -0500 Subject: [PATCH 22/46] Update cookiejar_test.go --- client/cookiejar_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/client/cookiejar_test.go b/client/cookiejar_test.go index 3b6fdcda83..397301450b 100644 --- a/client/cookiejar_test.go +++ b/client/cookiejar_test.go @@ -134,8 +134,6 @@ func TestCookieJarSet(t *testing.T) { } func TestCookieJarSetRepeatedCookieKeys(t *testing.T) { - t.Parallel() - host := "fast.http" cj := &CookieJar{} From 37fd5397b738ffae4023063ad14817e2dfb95f47 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Tue, 5 Mar 2024 09:57:15 -0500 Subject: [PATCH 23/46] Remove parallel for test using timeouts --- client/core_test.go | 13 ------------- ctx_test.go | 4 ++-- middleware/idempotency/idempotency_test.go | 2 -- redirect.go | 1 - redirect_test.go | 2 -- 5 files changed, 2 insertions(+), 20 deletions(-) diff --git a/client/core_test.go b/client/core_test.go index 1b8ea42b9d..f56f066b70 100644 --- a/client/core_test.go +++ b/client/core_test.go @@ -56,8 +56,6 @@ func Test_AddMissing_Port(t *testing.T) { } func Test_Exec_Func(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := fiber.New() @@ -81,7 +79,6 @@ func Test_Exec_Func(t *testing.T) { time.Sleep(300 * time.Millisecond) t.Run("normal request", func(t *testing.T) { - t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() core.ctx = context.Background() core.client = client @@ -97,7 +94,6 @@ func Test_Exec_Func(t *testing.T) { }) t.Run("the request return an error", func(t *testing.T) { - t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() core.ctx = context.Background() core.client = client @@ -114,7 +110,6 @@ func Test_Exec_Func(t *testing.T) { }) t.Run("the request timeout", func(t *testing.T) { - t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() @@ -133,8 +128,6 @@ func Test_Exec_Func(t *testing.T) { } func Test_Execute(t *testing.T) { - t.Parallel() - ln := fasthttputil.NewInmemoryListener() app := fiber.New() @@ -156,7 +149,6 @@ func Test_Execute(t *testing.T) { }() t.Run("add user request hooks", func(t *testing.T) { - t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() client.AddRequestHook(func(_ *Client, _ *Request) error { require.Equal(t, "http://example.com", req.URL()) @@ -173,7 +165,6 @@ func Test_Execute(t *testing.T) { }) t.Run("add user response hooks", func(t *testing.T) { - t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() client.AddResponseHook(func(_ *Client, _ *Response, req *Request) error { require.Equal(t, "http://example.com", req.URL()) @@ -190,7 +181,6 @@ func Test_Execute(t *testing.T) { }) t.Run("no timeout", func(t *testing.T) { - t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() client.SetDial(func(_ string) (net.Conn, error) { @@ -204,7 +194,6 @@ func Test_Execute(t *testing.T) { }) t.Run("client timeout", func(t *testing.T) { - t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() client.SetTimeout(500 * time.Millisecond) client.SetDial(func(_ string) (net.Conn, error) { @@ -217,7 +206,6 @@ func Test_Execute(t *testing.T) { }) t.Run("request timeout", func(t *testing.T) { - t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() client.SetDial(func(_ string) (net.Conn, error) { @@ -231,7 +219,6 @@ func Test_Execute(t *testing.T) { }) t.Run("request timeout has higher level", func(t *testing.T) { - t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() client.SetTimeout(30 * time.Millisecond) diff --git a/ctx_test.go b/ctx_test.go index ace7896739..fb601bf49b 100644 --- a/ctx_test.go +++ b/ctx_test.go @@ -3193,7 +3193,7 @@ func Test_Ctx_SaveFile(t *testing.T) { req.Header.Set("Content-Type", writer.FormDataContentType()) req.Header.Set("Content-Length", strconv.Itoa(len(body.Bytes()))) - resp, err := app.Test(req, 2000) + resp, err := app.Test(req) require.NoError(t, err, "app.Test(req)") require.Equal(t, StatusOK, resp.StatusCode, "Status code") } @@ -3235,7 +3235,7 @@ func Test_Ctx_SaveFileToStorage(t *testing.T) { req.Header.Set("Content-Type", writer.FormDataContentType()) req.Header.Set("Content-Length", strconv.Itoa(len(body.Bytes()))) - resp, err := app.Test(req, 2000) + resp, err := app.Test(req) require.NoError(t, err, "app.Test(req)") require.Equal(t, StatusOK, resp.StatusCode, "Status code") } diff --git a/middleware/idempotency/idempotency_test.go b/middleware/idempotency/idempotency_test.go index a0e8dce69a..82bfcbbe01 100644 --- a/middleware/idempotency/idempotency_test.go +++ b/middleware/idempotency/idempotency_test.go @@ -19,8 +19,6 @@ import ( // go test -run Test_Idempotency func Test_Idempotency(t *testing.T) { - t.Parallel() - app := fiber.New() app.Use(func(c fiber.Ctx) error { diff --git a/redirect.go b/redirect.go index ae693c8a9b..0eb06a15de 100644 --- a/redirect.go +++ b/redirect.go @@ -291,7 +291,6 @@ func (r *Redirect) Back(fallback ...string) error { // setFlash is a method to get flash messages before removing them func (r *Redirect) setFlash() { if r.c == nil { - // Handle the nil case, possibly logging an error or returning early. return } diff --git a/redirect_test.go b/redirect_test.go index 6dd2ae6d19..187971f687 100644 --- a/redirect_test.go +++ b/redirect_test.go @@ -248,8 +248,6 @@ func Test_Redirect_setFlash(t *testing.T) { // go test -run Test_Redirect_Request func Test_Redirect_Request(t *testing.T) { - t.Parallel() - app := New() app.Get("/", func(c Ctx) error { From 6cd5e578742b999f752999a728b952fc75b8039c Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Tue, 5 Mar 2024 10:14:15 -0500 Subject: [PATCH 24/46] Remove t.Parallel() from logger middleware tests --- middleware/logger/logger_test.go | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index dfe7bd0b12..05a95702a8 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -23,7 +23,6 @@ import ( // go test -run Test_Logger func Test_Logger(t *testing.T) { - t.Parallel() app := fiber.New() buf := bytebufferpool.Get() @@ -46,7 +45,6 @@ func Test_Logger(t *testing.T) { // go test -run Test_Logger_locals func Test_Logger_locals(t *testing.T) { - t.Parallel() app := fiber.New() buf := bytebufferpool.Get() @@ -93,7 +91,6 @@ func Test_Logger_locals(t *testing.T) { // go test -run Test_Logger_Next func Test_Logger_Next(t *testing.T) { - t.Parallel() app := fiber.New() app.Use(New(Config{ Next: func(_ fiber.Ctx) bool { @@ -108,7 +105,6 @@ func Test_Logger_Next(t *testing.T) { // go test -run Test_Logger_Done func Test_Logger_Done(t *testing.T) { - t.Parallel() buf := bytes.NewBuffer(nil) app := fiber.New() app.Use(New(Config{ @@ -131,7 +127,6 @@ func Test_Logger_Done(t *testing.T) { // go test -run Test_Logger_ErrorTimeZone func Test_Logger_ErrorTimeZone(t *testing.T) { - t.Parallel() app := fiber.New() app.Use(New(Config{ TimeZone: "invalid", @@ -151,7 +146,6 @@ func (o *fakeErrorOutput) Write([]byte) (int, error) { // go test -run Test_Logger_ErrorOutput_WithoutColor func Test_Logger_ErrorOutput_WithoutColor(t *testing.T) { - t.Parallel() o := new(fakeErrorOutput) app := fiber.New() app.Use(New(Config{ @@ -167,7 +161,6 @@ func Test_Logger_ErrorOutput_WithoutColor(t *testing.T) { // go test -run Test_Logger_ErrorOutput func Test_Logger_ErrorOutput(t *testing.T) { - t.Parallel() o := new(fakeErrorOutput) app := fiber.New() app.Use(New(Config{ @@ -182,7 +175,6 @@ func Test_Logger_ErrorOutput(t *testing.T) { // go test -run Test_Logger_All func Test_Logger_All(t *testing.T) { - t.Parallel() buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) @@ -316,7 +308,6 @@ func Test_Logger_WithLatency_DefaultFormat(t *testing.T) { // go test -run Test_Query_Params func Test_Query_Params(t *testing.T) { - t.Parallel() buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) @@ -336,7 +327,6 @@ func Test_Query_Params(t *testing.T) { // go test -run Test_Response_Body func Test_Response_Body(t *testing.T) { - t.Parallel() buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) @@ -371,7 +361,6 @@ func Test_Response_Body(t *testing.T) { // go test -run Test_Logger_AppendUint func Test_Logger_AppendUint(t *testing.T) { - t.Parallel() app := fiber.New() buf := bytebufferpool.Get() @@ -394,7 +383,6 @@ func Test_Logger_AppendUint(t *testing.T) { // go test -run Test_Logger_Data_Race -race func Test_Logger_Data_Race(t *testing.T) { - t.Parallel() app := fiber.New() buf := bytebufferpool.Get() @@ -489,7 +477,6 @@ func Benchmark_Logger(b *testing.B) { // go test -run Test_Response_Header func Test_Response_Header(t *testing.T) { - t.Parallel() buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) @@ -516,7 +503,6 @@ func Test_Response_Header(t *testing.T) { // go test -run Test_Req_Header func Test_Req_Header(t *testing.T) { - t.Parallel() buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) @@ -539,7 +525,6 @@ func Test_Req_Header(t *testing.T) { // go test -run Test_ReqHeader_Header func Test_ReqHeader_Header(t *testing.T) { - t.Parallel() buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) @@ -562,7 +547,6 @@ func Test_ReqHeader_Header(t *testing.T) { // go test -run Test_CustomTags func Test_CustomTags(t *testing.T) { - t.Parallel() customTag := "it is a custom tag" buf := bytebufferpool.Get() @@ -592,7 +576,6 @@ func Test_CustomTags(t *testing.T) { // go test -run Test_Logger_ByteSent_Streaming func Test_Logger_ByteSent_Streaming(t *testing.T) { - t.Parallel() app := fiber.New() buf := bytebufferpool.Get() @@ -639,7 +622,6 @@ func (o *fakeOutput) Write(b []byte) (int, error) { // go test -run Test_Logger_EnableColors func Test_Logger_EnableColors(t *testing.T) { - t.Parallel() o := new(fakeOutput) app := fiber.New() app.Use(New(Config{ From aae8c3b12b19b4e17b579eb76342b23c8571221a Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Tue, 5 Mar 2024 23:36:17 -0500 Subject: [PATCH 25/46] Do not use testify.require in a goroutine --- app_test.go | 60 +++++++++------------- client/client_test.go | 11 ++-- client/core_test.go | 5 +- client/helper_test.go | 6 +-- client/hooks_test.go | 5 +- client/request_test.go | 3 +- client/response_test.go | 3 +- ctx.go | 9 ++-- hooks_test.go | 7 +-- listen_test.go | 25 ++++----- middleware/favicon/favicon_test.go | 3 +- middleware/idempotency/idempotency_test.go | 10 ++-- middleware/idempotency/locker_test.go | 3 +- middleware/logger/logger_test.go | 33 ++++++++++++ prefork_test.go | 7 +-- redirect_test.go | 3 +- 16 files changed, 115 insertions(+), 78 deletions(-) diff --git a/app_test.go b/app_test.go index 34f7ce8749..12a9467e7f 100644 --- a/app_test.go +++ b/app_test.go @@ -25,6 +25,7 @@ import ( "github.com/gofiber/utils/v2" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/valyala/fasthttp" "github.com/valyala/fasthttp/fasthttputil" @@ -825,21 +826,16 @@ func Test_App_ShutdownWithTimeout(t *testing.T) { ln := fasthttputil.NewInmemoryListener() go func() { err := app.Listener(ln) - if err != nil { - panic(err) - } + assert.NoError(t, err) }() time.Sleep(1 * time.Second) go func() { conn, err := ln.Dial() - if err != nil { - t.Errorf("unexepcted error: %v", err) - } + assert.NoError(t, err) - if _, err = conn.Write([]byte("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")); err != nil { - t.Errorf("unexpected error: %v", err) - } + _, err = conn.Write([]byte("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")) + assert.NoError(t, err) }() time.Sleep(1 * time.Second) @@ -872,22 +868,17 @@ func Test_App_ShutdownWithContext(t *testing.T) { go func() { err := app.Listener(ln) - if err != nil { - panic(err) - } + assert.NoError(t, err) }() time.Sleep(1 * time.Second) go func() { conn, err := ln.Dial() - if err != nil { - t.Errorf("unexepcted error: %v", err) - } + assert.NoError(t, err) - if _, err = conn.Write([]byte("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")); err != nil { - t.Errorf("unexpected error: %v", err) - } + _, err = conn.Write([]byte("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")) + assert.NoError(t, err) }() time.Sleep(1 * time.Second) @@ -1550,23 +1541,23 @@ func Test_App_ReadTimeout(t *testing.T) { time.Sleep(500 * time.Millisecond) conn, err := net.Dial(NetworkTCP4, "127.0.0.1:4004") - require.NoError(t, err) + assert.NoError(t, err) defer func(conn net.Conn) { err := conn.Close() - require.NoError(t, err) + assert.NoError(t, err) }(conn) _, err = conn.Write([]byte("HEAD /read-timeout HTTP/1.1\r\n")) - require.NoError(t, err) + assert.NoError(t, err) buf := make([]byte, 1024) var n int n, err = conn.Read(buf) - require.NoError(t, err) - require.True(t, bytes.Contains(buf[:n], []byte("408 Request Timeout"))) + assert.NoError(t, err) + assert.True(t, bytes.Contains(buf[:n], []byte("408 Request Timeout"))) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":4004", ListenConfig{DisableStartupMessage: true})) @@ -1584,23 +1575,22 @@ func Test_App_BadRequest(t *testing.T) { go func() { time.Sleep(500 * time.Millisecond) conn, err := net.Dial(NetworkTCP4, "127.0.0.1:4005") - require.NoError(t, err) + assert.NoError(t, err) defer func(conn net.Conn) { err := conn.Close() - require.NoError(t, err) + assert.NoError(t, err) }(conn) _, err = conn.Write([]byte("BadRequest\r\n")) - require.NoError(t, err) + assert.NoError(t, err) buf := make([]byte, 1024) var n int n, err = conn.Read(buf) - require.NoError(t, err) - require.True(t, bytes.Contains(buf[:n], []byte("400 Bad Request"))) - - require.NoError(t, app.Shutdown()) + assert.NoError(t, err) + assert.True(t, bytes.Contains(buf[:n], []byte("400 Bad Request"))) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":4005", ListenConfig{DisableStartupMessage: true})) @@ -1620,12 +1610,12 @@ func Test_App_SmallReadBuffer(t *testing.T) { go func() { time.Sleep(500 * time.Millisecond) req, err := http.NewRequestWithContext(context.Background(), MethodGet, "http://127.0.0.1:4006/small-read-buffer", nil) - require.NoError(t, err) + assert.NoError(t, err) var client http.Client resp, err := client.Do(req) - require.NoError(t, err) - require.Equal(t, 431, resp.StatusCode) - require.NoError(t, app.Shutdown()) + assert.NoError(t, err) + assert.Equal(t, 431, resp.StatusCode) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":4006", ListenConfig{DisableStartupMessage: true})) diff --git a/client/client_test.go b/client/client_test.go index e6ba9d7b66..be1edbfaac 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -16,6 +16,7 @@ import ( "github.com/gofiber/fiber/v3/addon/retry" "github.com/gofiber/fiber/v3/internal/tlstest" "github.com/gofiber/utils/v2" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/valyala/bytebufferpool" ) @@ -277,8 +278,8 @@ func Test_Client_ConcurrencyRequests(t *testing.T) { go func(m string) { defer wg.Done() resp, err := client.Custom("http://example.com", m) - require.NoError(t, err) - require.Equal(t, "example.com "+m, utils.UnsafeString(resp.RawResponse.Body())) + assert.NoError(t, err) + assert.Equal(t, "example.com "+m, utils.UnsafeString(resp.RawResponse.Body())) }(method) } } @@ -1258,7 +1259,7 @@ func Test_Client_TLS(t *testing.T) { }) go func() { - require.NoError(t, app.Listener(ln, fiber.ListenConfig{ + assert.NoError(t, app.Listener(ln, fiber.ListenConfig{ DisableStartupMessage: true, })) }() @@ -1292,7 +1293,7 @@ func Test_Client_TLS_Error(t *testing.T) { }) go func() { - require.NoError(t, app.Listener(ln, fiber.ListenConfig{ + assert.NoError(t, app.Listener(ln, fiber.ListenConfig{ DisableStartupMessage: true, })) }() @@ -1323,7 +1324,7 @@ func Test_Client_TLS_Empty_TLSConfig(t *testing.T) { }) go func() { - require.NoError(t, app.Listener(ln, fiber.ListenConfig{ + assert.NoError(t, app.Listener(ln, fiber.ListenConfig{ DisableStartupMessage: true, })) }() diff --git a/client/core_test.go b/client/core_test.go index f56f066b70..37b9ca2bf4 100644 --- a/client/core_test.go +++ b/client/core_test.go @@ -8,6 +8,7 @@ import ( "time" "github.com/gofiber/fiber/v3" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/valyala/fasthttp/fasthttputil" ) @@ -73,7 +74,7 @@ func Test_Exec_Func(t *testing.T) { }) go func() { - require.NoError(t, app.Listener(ln, fiber.ListenConfig{DisableStartupMessage: true})) + assert.NoError(t, app.Listener(ln, fiber.ListenConfig{DisableStartupMessage: true})) }() time.Sleep(300 * time.Millisecond) @@ -145,7 +146,7 @@ func Test_Execute(t *testing.T) { }) go func() { - require.NoError(t, app.Listener(ln, fiber.ListenConfig{DisableStartupMessage: true})) + assert.NoError(t, app.Listener(ln, fiber.ListenConfig{DisableStartupMessage: true})) }() t.Run("add user request hooks", func(t *testing.T) { diff --git a/client/helper_test.go b/client/helper_test.go index 67380f3470..c1f689e764 100644 --- a/client/helper_test.go +++ b/client/helper_test.go @@ -6,6 +6,7 @@ import ( "time" "github.com/gofiber/fiber/v3" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/valyala/fasthttp/fasthttputil" ) @@ -29,9 +30,8 @@ func startTestServer(tb testing.TB, beforeStarting func(app *fiber.App)) *testSe ch := make(chan struct{}) go func() { - if err := app.Listener(ln, fiber.ListenConfig{DisableStartupMessage: true}); err != nil { - tb.Fatal(err) - } + err := app.Listener(ln, fiber.ListenConfig{DisableStartupMessage: true}) + assert.NoError(tb, err) close(ch) }() diff --git a/client/hooks_test.go b/client/hooks_test.go index a555bba833..4915a04e37 100644 --- a/client/hooks_test.go +++ b/client/hooks_test.go @@ -11,6 +11,7 @@ import ( "testing" "github.com/gofiber/fiber/v3" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -587,7 +588,7 @@ func Test_Client_Logger_Debug(t *testing.T) { addrChan := make(chan string) go func() { - require.NoError(t, app.Listen(":0", fiber.ListenConfig{ + assert.NoError(t, app.Listen(":0", fiber.ListenConfig{ DisableStartupMessage: true, ListenerAddrFunc: func(addr net.Addr) { addrChan <- addr.String() @@ -624,7 +625,7 @@ func Test_Client_Logger_DisableDebug(t *testing.T) { addrChan := make(chan string) go func() { - require.NoError(t, app.Listen(":0", fiber.ListenConfig{ + assert.NoError(t, app.Listen(":0", fiber.ListenConfig{ DisableStartupMessage: true, ListenerAddrFunc: func(addr net.Addr) { addrChan <- addr.String() diff --git a/client/request_test.go b/client/request_test.go index 07e5254e15..d5e5da2416 100644 --- a/client/request_test.go +++ b/client/request_test.go @@ -15,6 +15,7 @@ import ( "time" "github.com/gofiber/fiber/v3" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/valyala/fasthttp" "github.com/valyala/fasthttp/fasthttputil" @@ -1245,7 +1246,7 @@ func Test_Request_MaxRedirects(t *testing.T) { return c.SendString("redirect") }) - go func() { require.NoError(t, app.Listener(ln, fiber.ListenConfig{DisableStartupMessage: true})) }() + go func() { assert.NoError(t, app.Listener(ln, fiber.ListenConfig{DisableStartupMessage: true})) }() t.Run("success", func(t *testing.T) { t.Parallel() diff --git a/client/response_test.go b/client/response_test.go index 622e835714..ea5c14f792 100644 --- a/client/response_test.go +++ b/client/response_test.go @@ -12,6 +12,7 @@ import ( "github.com/gofiber/fiber/v3/internal/tlstest" "github.com/gofiber/fiber/v3" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -158,7 +159,7 @@ func Test_Response_Protocol(t *testing.T) { }) go func() { - require.NoError(t, app.Listener(ln, fiber.ListenConfig{ + assert.NoError(t, app.Listener(ln, fiber.ListenConfig{ DisableStartupMessage: true, })) }() diff --git a/ctx.go b/ctx.go index 7f41048de3..95bd7d8ea6 100644 --- a/ctx.go +++ b/ctx.go @@ -1319,12 +1319,13 @@ func (c *DefaultCtx) Render(name string, bind Map, layouts ...string) error { var rendered bool for i := len(c.app.mountFields.appListKeys) - 1; i >= 0; i-- { prefix := c.app.mountFields.appListKeys[i] - app := c.app.mountFields.appList[prefix] + app, exists := c.app.mountFields.appList[prefix] + if !exists || app == nil { // Check if app exists and is not nil + continue // Skip this iteration if app is nil + } if prefix == "" || strings.Contains(c.OriginalURL(), prefix) { if len(layouts) == 0 && app.config.ViewsLayout != "" { - layouts = []string{ - app.config.ViewsLayout, - } + layouts = []string{app.config.ViewsLayout} } // Render template from Views diff --git a/hooks_test.go b/hooks_test.go index 91ad87bef7..f96f570706 100644 --- a/hooks_test.go +++ b/hooks_test.go @@ -6,6 +6,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/valyala/bytebufferpool" ) @@ -215,7 +216,7 @@ func Test_Hook_OnListen(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":9000")) @@ -238,7 +239,7 @@ func Test_Hook_OnListenPrefork(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":9000", ListenConfig{DisableStartupMessage: true, EnablePrefork: true})) @@ -254,7 +255,7 @@ func Test_Hook_OnHook(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() app.Hooks().OnFork(func(pid int) error { diff --git a/listen_test.go b/listen_test.go index ac4c1370c3..762fe8291d 100644 --- a/listen_test.go +++ b/listen_test.go @@ -16,6 +16,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/valyala/fasthttp" "github.com/valyala/fasthttp/fasthttputil" @@ -29,7 +30,7 @@ func Test_Listen(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":4003", ListenConfig{DisableStartupMessage: true})) @@ -136,7 +137,7 @@ func Test_Listen_TLS(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":0", ListenConfig{ @@ -161,7 +162,7 @@ func Test_Listen_TLS_Prefork(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":99999", ListenConfig{ @@ -185,7 +186,7 @@ func Test_Listen_MutualTLS(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":0", ListenConfig{ @@ -212,7 +213,7 @@ func Test_Listen_MutualTLS_Prefork(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":99999", ListenConfig{ @@ -230,7 +231,7 @@ func Test_Listener(t *testing.T) { go func() { time.Sleep(500 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() ln := fasthttputil.NewInmemoryListener() @@ -254,7 +255,7 @@ func Test_App_Listener_TLS_Listener(t *testing.T) { go func() { time.Sleep(time.Millisecond * 500) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listener(ln)) @@ -267,7 +268,7 @@ func Test_Listen_TLSConfigFunc(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":0", ListenConfig{ @@ -289,7 +290,7 @@ func Test_Listen_ListenerAddrFunc(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":0", ListenConfig{ @@ -311,7 +312,7 @@ func Test_Listen_BeforeServeFunc(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() wantErr := errors.New("test") @@ -334,7 +335,7 @@ func Test_Listen_ListenerNetwork(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":0", ListenConfig{ @@ -349,7 +350,7 @@ func Test_Listen_ListenerNetwork(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.Listen(":0", ListenConfig{ diff --git a/middleware/favicon/favicon_test.go b/middleware/favicon/favicon_test.go index ecf550b2a3..5c2fe618d6 100644 --- a/middleware/favicon/favicon_test.go +++ b/middleware/favicon/favicon_test.go @@ -47,7 +47,8 @@ func Test_Middleware_Favicon_Not_Found(t *testing.T) { t.Parallel() defer func() { if err := recover(); err == nil { - t.Fatal("should cache panic") + t.Error("should cache panic") + return } }() diff --git a/middleware/idempotency/idempotency_test.go b/middleware/idempotency/idempotency_test.go index 82bfcbbe01..fa062a77fa 100644 --- a/middleware/idempotency/idempotency_test.go +++ b/middleware/idempotency/idempotency_test.go @@ -13,12 +13,14 @@ import ( "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/middleware/idempotency" "github.com/valyala/fasthttp" + "gotest.tools/assert" "github.com/stretchr/testify/require" ) // go test -run Test_Idempotency func Test_Idempotency(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(func(c fiber.Ctx) error { @@ -73,7 +75,7 @@ func Test_Idempotency(t *testing.T) { }) app.Post("/slow", func(c fiber.Ctx) error { - time.Sleep(2 * lifetime) + time.Sleep(4 * lifetime) return c.SendString(strconv.Itoa(nextCount())) }) @@ -83,7 +85,7 @@ func Test_Idempotency(t *testing.T) { if idempotencyKey != "" { req.Header.Set("X-Idempotency-Key", idempotencyKey) } - resp, err := app.Test(req, 3*lifetime) + resp, err := app.Test(req, 5*lifetime) require.NoError(t, err) body, err := io.ReadAll(resp.Body) require.NoError(t, err) @@ -117,13 +119,13 @@ func Test_Idempotency(t *testing.T) { wg.Add(1) go func() { defer wg.Done() - require.Equal(t, "11", doReq(fiber.MethodPost, "/slow", "22222222-2222-2222-2222-222222222222")) + assert.Equal(t, "11", doReq(fiber.MethodPost, "/slow", "22222222-2222-2222-2222-222222222222")) }() } wg.Wait() require.Equal(t, "11", doReq(fiber.MethodPost, "/slow", "22222222-2222-2222-2222-222222222222")) } - time.Sleep(2 * lifetime) + time.Sleep(4 * lifetime) require.Equal(t, "12", doReq(fiber.MethodPost, "/slow", "22222222-2222-2222-2222-222222222222")) } diff --git a/middleware/idempotency/locker_test.go b/middleware/idempotency/locker_test.go index 19589dc7bf..3b4a3ca78a 100644 --- a/middleware/idempotency/locker_test.go +++ b/middleware/idempotency/locker_test.go @@ -6,6 +6,7 @@ import ( "github.com/gofiber/fiber/v3/middleware/idempotency" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -25,7 +26,7 @@ func Test_MemoryLock(t *testing.T) { defer close(done) err := l.Lock("a") - require.NoError(t, err) + assert.NoError(t, err) }() select { diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index 05a95702a8..b830720cdc 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -23,6 +23,7 @@ import ( // go test -run Test_Logger func Test_Logger(t *testing.T) { + t.Parallel() app := fiber.New() buf := bytebufferpool.Get() @@ -45,6 +46,7 @@ func Test_Logger(t *testing.T) { // go test -run Test_Logger_locals func Test_Logger_locals(t *testing.T) { + t.Parallel() app := fiber.New() buf := bytebufferpool.Get() @@ -91,7 +93,9 @@ func Test_Logger_locals(t *testing.T) { // go test -run Test_Logger_Next func Test_Logger_Next(t *testing.T) { + t.Parallel() app := fiber.New() + app.Use(New(Config{ Next: func(_ fiber.Ctx) bool { return true @@ -105,8 +109,10 @@ func Test_Logger_Next(t *testing.T) { // go test -run Test_Logger_Done func Test_Logger_Done(t *testing.T) { + t.Parallel() buf := bytes.NewBuffer(nil) app := fiber.New() + app.Use(New(Config{ Done: func(c fiber.Ctx, logString []byte) { if c.Response().StatusCode() == fiber.StatusOK { @@ -127,7 +133,9 @@ func Test_Logger_Done(t *testing.T) { // go test -run Test_Logger_ErrorTimeZone func Test_Logger_ErrorTimeZone(t *testing.T) { + t.Parallel() app := fiber.New() + app.Use(New(Config{ TimeZone: "invalid", })) @@ -146,8 +154,10 @@ func (o *fakeErrorOutput) Write([]byte) (int, error) { // go test -run Test_Logger_ErrorOutput_WithoutColor func Test_Logger_ErrorOutput_WithoutColor(t *testing.T) { + t.Parallel() o := new(fakeErrorOutput) app := fiber.New() + app.Use(New(Config{ Output: o, DisableColors: true, @@ -161,8 +171,10 @@ func Test_Logger_ErrorOutput_WithoutColor(t *testing.T) { // go test -run Test_Logger_ErrorOutput func Test_Logger_ErrorOutput(t *testing.T) { + t.Parallel() o := new(fakeErrorOutput) app := fiber.New() + app.Use(New(Config{ Output: o, })) @@ -175,10 +187,12 @@ func Test_Logger_ErrorOutput(t *testing.T) { // go test -run Test_Logger_All func Test_Logger_All(t *testing.T) { + t.Parallel() buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) app := fiber.New() + app.Use(New(Config{ Format: "${pid}${reqHeaders}${referer}${scheme}${protocol}${ip}${ips}${host}${url}${ua}${body}${route}${black}${red}${green}${yellow}${blue}${magenta}${cyan}${white}${reset}${error}${reqHeader:test}${query:test}${form:test}${cookie:test}${non}", Output: buf, @@ -225,6 +239,7 @@ func Test_Logger_WithLatency(t *testing.T) { buff := bytebufferpool.Get() defer bytebufferpool.Put(buff) app := fiber.New() + logger := New(Config{ Output: buff, Format: "${latency}", @@ -267,6 +282,7 @@ func Test_Logger_WithLatency_DefaultFormat(t *testing.T) { buff := bytebufferpool.Get() defer bytebufferpool.Put(buff) app := fiber.New() + logger := New(Config{ Output: buff, }) @@ -308,10 +324,12 @@ func Test_Logger_WithLatency_DefaultFormat(t *testing.T) { // go test -run Test_Query_Params func Test_Query_Params(t *testing.T) { + t.Parallel() buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) app := fiber.New() + app.Use(New(Config{ Format: "${queryParams}", Output: buf, @@ -327,10 +345,12 @@ func Test_Query_Params(t *testing.T) { // go test -run Test_Response_Body func Test_Response_Body(t *testing.T) { + t.Parallel() buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) app := fiber.New() + app.Use(New(Config{ Format: "${resBody}", Output: buf, @@ -361,6 +381,7 @@ func Test_Response_Body(t *testing.T) { // go test -run Test_Logger_AppendUint func Test_Logger_AppendUint(t *testing.T) { + t.Parallel() app := fiber.New() buf := bytebufferpool.Get() @@ -383,6 +404,7 @@ func Test_Logger_AppendUint(t *testing.T) { // go test -run Test_Logger_Data_Race -race func Test_Logger_Data_Race(t *testing.T) { + t.Parallel() app := fiber.New() buf := bytebufferpool.Get() @@ -477,10 +499,12 @@ func Benchmark_Logger(b *testing.B) { // go test -run Test_Response_Header func Test_Response_Header(t *testing.T) { + t.Parallel() buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) app := fiber.New() + app.Use(requestid.New(requestid.Config{ Next: nil, Header: fiber.HeaderXRequestID, @@ -503,10 +527,12 @@ func Test_Response_Header(t *testing.T) { // go test -run Test_Req_Header func Test_Req_Header(t *testing.T) { + t.Parallel() buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) app := fiber.New() + app.Use(New(Config{ Format: "${reqHeader:test}", Output: buf, @@ -525,10 +551,12 @@ func Test_Req_Header(t *testing.T) { // go test -run Test_ReqHeader_Header func Test_ReqHeader_Header(t *testing.T) { + t.Parallel() buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) app := fiber.New() + app.Use(New(Config{ Format: "${reqHeader:test}", Output: buf, @@ -547,12 +575,14 @@ func Test_ReqHeader_Header(t *testing.T) { // go test -run Test_CustomTags func Test_CustomTags(t *testing.T) { + t.Parallel() customTag := "it is a custom tag" buf := bytebufferpool.Get() defer bytebufferpool.Put(buf) app := fiber.New() + app.Use(New(Config{ Format: "${custom_tag}", CustomTags: map[string]LogFunc{ @@ -576,6 +606,7 @@ func Test_CustomTags(t *testing.T) { // go test -run Test_Logger_ByteSent_Streaming func Test_Logger_ByteSent_Streaming(t *testing.T) { + t.Parallel() app := fiber.New() buf := bytebufferpool.Get() @@ -622,8 +653,10 @@ func (o *fakeOutput) Write(b []byte) (int, error) { // go test -run Test_Logger_EnableColors func Test_Logger_EnableColors(t *testing.T) { + t.Parallel() o := new(fakeOutput) app := fiber.New() + app.Use(New(Config{ Output: o, })) diff --git a/prefork_test.go b/prefork_test.go index b71bb56ef0..63cd635acd 100644 --- a/prefork_test.go +++ b/prefork_test.go @@ -11,6 +11,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -28,7 +29,7 @@ func Test_App_Prefork_Child_Process(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.prefork("[::1]:", nil, ListenConfig{ListenerNetwork: NetworkTCP6})) @@ -43,7 +44,7 @@ func Test_App_Prefork_Child_Process(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.prefork("127.0.0.1:", config, listenConfigDefault())) @@ -57,7 +58,7 @@ func Test_App_Prefork_Master_Process(t *testing.T) { go func() { time.Sleep(1000 * time.Millisecond) - require.NoError(t, app.Shutdown()) + assert.NoError(t, app.Shutdown()) }() require.NoError(t, app.prefork(":3000", nil, listenConfigDefault())) diff --git a/redirect_test.go b/redirect_test.go index 187971f687..d1c7bff82f 100644 --- a/redirect_test.go +++ b/redirect_test.go @@ -12,6 +12,7 @@ import ( "testing" "time" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/valyala/fasthttp" "github.com/valyala/fasthttp/fasthttputil" @@ -280,7 +281,7 @@ func Test_Redirect_Request(t *testing.T) { GracefulContext: ctx, }) - require.NoError(t, err) + assert.NoError(t, err) }() // Test cases From 1fe579e4490c20254daeed785fd54e110e9f3db5 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Tue, 5 Mar 2024 23:39:01 -0500 Subject: [PATCH 26/46] Fix import, and update golangci-lint --- .golangci.yml | 2 -- middleware/idempotency/idempotency_test.go | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 1f55c987fb..9dfb719117 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -13,8 +13,6 @@ output: linters-settings: testifylint: enable-all: true - disable: - - go-require errcheck: check-type-assertions: true check-blank: true diff --git a/middleware/idempotency/idempotency_test.go b/middleware/idempotency/idempotency_test.go index fa062a77fa..20d8577024 100644 --- a/middleware/idempotency/idempotency_test.go +++ b/middleware/idempotency/idempotency_test.go @@ -13,8 +13,8 @@ import ( "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/middleware/idempotency" "github.com/valyala/fasthttp" - "gotest.tools/assert" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) From bd33f04e548c32038eda685287e4913d628296d6 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Tue, 5 Mar 2024 23:48:56 -0500 Subject: [PATCH 27/46] Remove changes to template_chain.go --- middleware/logger/template_chain.go | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/middleware/logger/template_chain.go b/middleware/logger/template_chain.go index 6f1e909fbd..00015bf33d 100644 --- a/middleware/logger/template_chain.go +++ b/middleware/logger/template_chain.go @@ -17,24 +17,9 @@ import ( func buildLogFuncChain(cfg *Config, tagFunctions map[string]LogFunc) ([][]byte, []LogFunc, error) { // process flow is copied from the fasttemplate flow https://github.com/valyala/fasttemplate/blob/2a2d1afadadf9715bfa19683cdaeac8347e5d9f9/template.go#L23-L62 templateB := utils.UnsafeBytes(cfg.Format) - if templateB == nil { - return nil, nil, errors.New("template is nil") - } - startTagB := utils.UnsafeBytes(startTag) - if startTagB == nil { - return nil, nil, errors.New("startTag is nil") - } - endTagB := utils.UnsafeBytes(endTag) - if endTagB == nil { - return nil, nil, errors.New("endTag is nil") - } - paramSeparatorB := utils.UnsafeBytes(paramSeparator) - if paramSeparatorB == nil { - return nil, nil, errors.New("paramSeparator is nil") - } var fixParts [][]byte var funcChain []LogFunc From 41360ccb8d78009d8dcf5cb337da8fd82e3b95ae Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Wed, 6 Mar 2024 00:08:34 -0500 Subject: [PATCH 28/46] Run more tests in parallel --- client/cookiejar_test.go | 1 + client/core_test.go | 11 +++++++++++ internal/memory/memory_test.go | 3 ++- 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/client/cookiejar_test.go b/client/cookiejar_test.go index 397301450b..fadee9294d 100644 --- a/client/cookiejar_test.go +++ b/client/cookiejar_test.go @@ -134,6 +134,7 @@ func TestCookieJarSet(t *testing.T) { } func TestCookieJarSetRepeatedCookieKeys(t *testing.T) { + t.Parallel() host := "fast.http" cj := &CookieJar{} diff --git a/client/core_test.go b/client/core_test.go index 37b9ca2bf4..5cff869b3b 100644 --- a/client/core_test.go +++ b/client/core_test.go @@ -57,6 +57,7 @@ func Test_AddMissing_Port(t *testing.T) { } func Test_Exec_Func(t *testing.T) { + t.Parallel() ln := fasthttputil.NewInmemoryListener() app := fiber.New() @@ -80,6 +81,7 @@ func Test_Exec_Func(t *testing.T) { time.Sleep(300 * time.Millisecond) t.Run("normal request", func(t *testing.T) { + t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() core.ctx = context.Background() core.client = client @@ -95,6 +97,7 @@ func Test_Exec_Func(t *testing.T) { }) t.Run("the request return an error", func(t *testing.T) { + t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() core.ctx = context.Background() core.client = client @@ -111,6 +114,7 @@ func Test_Exec_Func(t *testing.T) { }) t.Run("the request timeout", func(t *testing.T) { + t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond) defer cancel() @@ -129,6 +133,7 @@ func Test_Exec_Func(t *testing.T) { } func Test_Execute(t *testing.T) { + t.Parallel() ln := fasthttputil.NewInmemoryListener() app := fiber.New() @@ -150,6 +155,7 @@ func Test_Execute(t *testing.T) { }() t.Run("add user request hooks", func(t *testing.T) { + t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() client.AddRequestHook(func(_ *Client, _ *Request) error { require.Equal(t, "http://example.com", req.URL()) @@ -166,6 +172,7 @@ func Test_Execute(t *testing.T) { }) t.Run("add user response hooks", func(t *testing.T) { + t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() client.AddResponseHook(func(_ *Client, _ *Response, req *Request) error { require.Equal(t, "http://example.com", req.URL()) @@ -182,6 +189,7 @@ func Test_Execute(t *testing.T) { }) t.Run("no timeout", func(t *testing.T) { + t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() client.SetDial(func(_ string) (net.Conn, error) { @@ -195,6 +203,7 @@ func Test_Execute(t *testing.T) { }) t.Run("client timeout", func(t *testing.T) { + t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() client.SetTimeout(500 * time.Millisecond) client.SetDial(func(_ string) (net.Conn, error) { @@ -207,6 +216,7 @@ func Test_Execute(t *testing.T) { }) t.Run("request timeout", func(t *testing.T) { + t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() client.SetDial(func(_ string) (net.Conn, error) { @@ -220,6 +230,7 @@ func Test_Execute(t *testing.T) { }) t.Run("request timeout has higher level", func(t *testing.T) { + t.Parallel() core, client, req := newCore(), NewClient(), AcquireRequest() client.SetTimeout(30 * time.Millisecond) diff --git a/internal/memory/memory_test.go b/internal/memory/memory_test.go index dc637b690a..b4a1983e4c 100644 --- a/internal/memory/memory_test.go +++ b/internal/memory/memory_test.go @@ -10,9 +10,10 @@ import ( // go test -run Test_Memory -v -race func Test_Memory(t *testing.T) { + t.Parallel() store := New() var ( - key = "john" + key = "john-internal" val any = []byte("doe") exp = 1 * time.Second ) From d812b0d77cd095ab549dd66e8cc1905df1ea069e Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Wed, 6 Mar 2024 00:27:23 -0500 Subject: [PATCH 29/46] Add more parallel tests --- client/client_test.go | 1 + client/response.go | 6 ------ middleware/cache/cache_test.go | 5 +++++ middleware/logger/default_logger.go | 12 ++++-------- router_test.go | 2 ++ 5 files changed, 12 insertions(+), 14 deletions(-) diff --git a/client/client_test.go b/client/client_test.go index be1edbfaac..9d8c1263c1 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1582,6 +1582,7 @@ func Test_Client_SetProxyURL(t *testing.T) { } func Test_Client_SetRetryConfig(t *testing.T) { + t.Parallel() retryConfig := &retry.Config{ InitialInterval: 1 * time.Second, MaxRetryCount: 3, diff --git a/client/response.go b/client/response.go index 81348a795e..f6ecd6fcd8 100644 --- a/client/response.go +++ b/client/response.go @@ -73,17 +73,11 @@ func (r *Response) String() string { // JSON method will unmarshal body to json. func (r *Response) JSON(v any) error { - if r.client == nil { - return errors.New("cannot unmarshal JSON: client is nil") - } return r.client.jsonUnmarshal(r.Body(), v) } // XML method will unmarshal body to xml. func (r *Response) XML(v any) error { - if r.client == nil { - return errors.New("cannot unmarshal XML: client is nil") - } return r.client.xmlUnmarshal(r.Body(), v) } diff --git a/middleware/cache/cache_test.go b/middleware/cache/cache_test.go index dcdb38d0e0..cec919abd3 100644 --- a/middleware/cache/cache_test.go +++ b/middleware/cache/cache_test.go @@ -44,6 +44,7 @@ func Test_Cache_CacheControl(t *testing.T) { } func Test_Cache_Expired(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(New(Config{Expiration: 2 * time.Second})) @@ -408,6 +409,7 @@ func Test_Cache_Post(t *testing.T) { } func Test_Cache_NothingToCache(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(New(Config{Expiration: -(time.Second * 1)})) @@ -494,6 +496,7 @@ func Test_CustomKey(t *testing.T) { } func Test_CustomExpiration(t *testing.T) { + t.Parallel() app := fiber.New() var called bool var newCacheTime int @@ -706,6 +709,7 @@ func stableAscendingExpiration() func(c1 fiber.Ctx, c2 *Config) time.Duration { } func Test_Cache_MaxBytesOrder(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(New(Config{ MaxBytes: 2, @@ -741,6 +745,7 @@ func Test_Cache_MaxBytesOrder(t *testing.T) { } func Test_Cache_MaxBytesSizes(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(New(Config{ diff --git a/middleware/logger/default_logger.go b/middleware/logger/default_logger.go index 8b557c0e05..0070b72031 100644 --- a/middleware/logger/default_logger.go +++ b/middleware/logger/default_logger.go @@ -156,15 +156,11 @@ func appendInt(output Buffer, v int) (int, error) { // writeLog writes a msg to w, printing a warning to stderr if the log fails. func writeLog(w io.Writer, msg []byte) { - if w == nil { - fmt.Fprintf(os.Stderr, "writeLog: io.Writer is nil\n") - return - } if _, err := w.Write(msg); err != nil { - // Attempt to write the error message to the original writer, w - if _, err := w.Write([]byte("Failed to write log message: " + err.Error())); err != nil { - // If writing to w fails, fall back to stderr - fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) + // Write error to output + if _, err := w.Write([]byte(err.Error())); err != nil { + // There is something wrong with the given io.Writer + _, _ = fmt.Fprintf(os.Stderr, "Failed to write to log, %v\n", err) } } } diff --git a/router_test.go b/router_test.go index 5b29bbc3c2..5d7c95c14c 100644 --- a/router_test.go +++ b/router_test.go @@ -455,6 +455,7 @@ func Test_Route_Static_HasPrefix(t *testing.T) { } func Test_Router_NotFound(t *testing.T) { + t.Parallel() app := New() app.Use(func(c Ctx) error { return c.Next() @@ -472,6 +473,7 @@ func Test_Router_NotFound(t *testing.T) { } func Test_Router_NotFound_HTML_Inject(t *testing.T) { + t.Parallel() app := New() app.Use(func(c Ctx) error { return c.Next() From 3386121f1d511518047a6c47d342deb1065f3fb2 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Wed, 6 Mar 2024 00:53:08 -0500 Subject: [PATCH 30/46] Add more parallel tests --- .github/workflows/test.yml | 5 ++++- app_test.go | 18 ++++++++++++++++++ client/core_test.go | 1 + helpers_test.go | 4 ++++ log/fiberlog_test.go | 3 ++- mount_test.go | 1 + redirect.go | 28 +++------------------------- redirect_test.go | 1 + 8 files changed, 34 insertions(+), 27 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 37c923d44b..a19fbea7fe 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,10 @@ jobs: - name: Install gotestsum run: go install gotest.tools/gotestsum@v1.11.0 - - name: Test + - name: Run go vet + run: go vet ./... + + - name: Run tests run: gotestsum -f testname -- ./... -race -count=1 -coverprofile=coverage.txt -covermode=atomic - name: Upload coverage reports to Codecov diff --git a/app_test.go b/app_test.go index 12a9467e7f..81981e17a6 100644 --- a/app_test.go +++ b/app_test.go @@ -198,6 +198,7 @@ func (*customConstraint) Execute(param string, args ...string) bool { } func Test_App_CustomConstraint(t *testing.T) { + t.Parallel() app := New() app.RegisterCustomConstraint(&customConstraint{}) @@ -902,6 +903,7 @@ func Test_App_ShutdownWithContext(t *testing.T) { // go test -run Test_App_Static_Index_Default func Test_App_Static_Index_Default(t *testing.T) { + t.Parallel() app := New() app.Static("/prefix", "./.github/workflows") @@ -931,6 +933,7 @@ func Test_App_Static_Index_Default(t *testing.T) { // go test -run Test_App_Static_Index func Test_App_Static_Direct(t *testing.T) { + t.Parallel() app := New() app.Static("/", "./.github") @@ -959,6 +962,7 @@ func Test_App_Static_Direct(t *testing.T) { // go test -run Test_App_Static_MaxAge func Test_App_Static_MaxAge(t *testing.T) { + t.Parallel() app := New() app.Static("/", "./.github", Static{MaxAge: 100}) @@ -973,6 +977,7 @@ func Test_App_Static_MaxAge(t *testing.T) { // go test -run Test_App_Static_Custom_CacheControl func Test_App_Static_Custom_CacheControl(t *testing.T) { + t.Parallel() app := New() app.Static("/", "./.github", Static{ModifyResponse: func(c Ctx) error { @@ -993,6 +998,7 @@ func Test_App_Static_Custom_CacheControl(t *testing.T) { // go test -run Test_App_Static_Download func Test_App_Static_Download(t *testing.T) { + t.Parallel() app := New() app.Static("/fiber.png", "./.github/testdata/fs/img/fiber.png", Static{Download: true}) @@ -1007,6 +1013,7 @@ func Test_App_Static_Download(t *testing.T) { // go test -run Test_App_Static_Group func Test_App_Static_Group(t *testing.T) { + t.Parallel() app := New() grp := app.Group("/v1", func(c Ctx) error { @@ -1036,6 +1043,7 @@ func Test_App_Static_Group(t *testing.T) { } func Test_App_Static_Wildcard(t *testing.T) { + t.Parallel() app := New() app.Static("*", "./.github/index.html") @@ -1053,6 +1061,7 @@ func Test_App_Static_Wildcard(t *testing.T) { } func Test_App_Static_Prefix_Wildcard(t *testing.T) { + t.Parallel() app := New() app.Static("/test/*", "./.github/index.html") @@ -1078,6 +1087,7 @@ func Test_App_Static_Prefix_Wildcard(t *testing.T) { } func Test_App_Static_Prefix(t *testing.T) { + t.Parallel() app := New() app.Static("/john", "./.github") @@ -1108,6 +1118,7 @@ func Test_App_Static_Prefix(t *testing.T) { } func Test_App_Static_Trailing_Slash(t *testing.T) { + t.Parallel() app := New() app.Static("/john", "./.github") @@ -1154,6 +1165,7 @@ func Test_App_Static_Trailing_Slash(t *testing.T) { } func Test_App_Static_Next(t *testing.T) { + t.Parallel() app := New() app.Static("/", ".github", Static{ Next: func(c Ctx) bool { @@ -1167,6 +1179,7 @@ func Test_App_Static_Next(t *testing.T) { }) t.Run("app.Static is skipped: invoking Get handler", func(t *testing.T) { + t.Parallel() req := httptest.NewRequest(MethodGet, "/", nil) req.Header.Set("X-Custom-Header", "skip") resp, err := app.Test(req) @@ -1181,6 +1194,7 @@ func Test_App_Static_Next(t *testing.T) { }) t.Run("app.Static is not skipped: serving index.html", func(t *testing.T) { + t.Parallel() req := httptest.NewRequest(MethodGet, "/", nil) req.Header.Set("X-Custom-Header", "don't skip") resp, err := app.Test(req) @@ -1197,6 +1211,7 @@ func Test_App_Static_Next(t *testing.T) { // go test -run Test_App_Mixed_Routes_WithSameLen func Test_App_Mixed_Routes_WithSameLen(t *testing.T) { + t.Parallel() app := New() // middleware @@ -1475,6 +1490,7 @@ func (invalidView) Render(io.Writer, string, any, ...string) error { panic("impl // go test -run Test_App_Init_Error_View func Test_App_Init_Error_View(t *testing.T) { + t.Parallel() app := New(Config{Views: invalidView{}}) defer func() { @@ -1813,6 +1829,7 @@ func TestApp_GetRoutes(t *testing.T) { } func Test_Middleware_Route_Naming_With_Use(t *testing.T) { + t.Parallel() named := "named" app := New() @@ -1872,6 +1889,7 @@ func Test_Middleware_Route_Naming_With_Use(t *testing.T) { } func Test_Route_Naming_Issue_2671_2685(t *testing.T) { + t.Parallel() app := New() app.Get("/", emptyHandler).Name("index") diff --git a/client/core_test.go b/client/core_test.go index 5cff869b3b..fcdb125cb9 100644 --- a/client/core_test.go +++ b/client/core_test.go @@ -49,6 +49,7 @@ func Test_AddMissing_Port(t *testing.T) { }, } for _, tt := range tests { + tt := tt // create a new 'tt' variable for the goroutine t.Run(tt.name, func(t *testing.T) { t.Parallel() require.Equal(t, tt.want, addMissingPort(tt.args.addr, tt.args.isTLS)) diff --git a/helpers_test.go b/helpers_test.go index ee0caa80b3..a905cf64ba 100644 --- a/helpers_test.go +++ b/helpers_test.go @@ -212,6 +212,7 @@ func Benchmark_Utils_ParamsMatch(b *testing.B) { } func Test_Utils_AcceptsOfferType(t *testing.T) { + t.Parallel() testCases := []struct { description string spec string @@ -273,6 +274,7 @@ func Test_Utils_AcceptsOfferType(t *testing.T) { } func Test_Utils_GetSplicedStrList(t *testing.T) { + t.Parallel() testCases := []struct { description string headerValue string @@ -302,6 +304,8 @@ func Test_Utils_GetSplicedStrList(t *testing.T) { for _, tc := range testCases { t.Run(tc.description, func(t *testing.T) { + tc := tc // create a new 'tc' variable for the goroutine + t.Parallel() dst := make([]string, 10) result := getSplicedStrList(tc.headerValue, dst) require.Equal(t, tc.expectedList, result) diff --git a/log/fiberlog_test.go b/log/fiberlog_test.go index ca6e93c83a..8c5ae4d702 100644 --- a/log/fiberlog_test.go +++ b/log/fiberlog_test.go @@ -9,11 +9,13 @@ import ( ) func Test_DefaultSystemLogger(t *testing.T) { + t.Parallel() defaultL := DefaultLogger() require.Equal(t, logger, defaultL) } func Test_SetLogger(t *testing.T) { + t.Parallel() setLog := &defaultLogger{ stdlog: log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds), depth: 6, @@ -24,7 +26,6 @@ func Test_SetLogger(t *testing.T) { } func Test_Fiberlog_SetLevel(t *testing.T) { - // Set up mockLogger := &defaultLogger{} SetLogger(mockLogger) diff --git a/mount_test.go b/mount_test.go index b2c82c2952..cd021b248a 100644 --- a/mount_test.go +++ b/mount_test.go @@ -399,6 +399,7 @@ func Test_App_UseMountedErrorHandlerForBestPrefixMatch(t *testing.T) { // go test -run Test_Mount_Route_Names func Test_Mount_Route_Names(t *testing.T) { + t.Parallel() // create sub-app with 2 handlers: subApp1 := New() subApp1.Get("/users", func(c Ctx) error { diff --git a/redirect.go b/redirect.go index 0eb06a15de..98053db80a 100644 --- a/redirect.go +++ b/redirect.go @@ -119,10 +119,6 @@ func (r *Redirect) WithInput() *Redirect { // Get flash messages. func (r *Redirect) Messages() map[string]string { - if r.c == nil { - return make(map[string]string) // Return an empty map if `c` is nil. - } - msgs := r.c.redirectionMessages flashMessages := make(map[string]string, len(msgs)) @@ -139,11 +135,8 @@ func (r *Redirect) Messages() map[string]string { // Get flash message by key. func (r *Redirect) Message(key string) string { - if r.c == nil { - return "" - } - msgs := r.c.redirectionMessages + for _, msg := range msgs { k, v := parseMessage(msg) @@ -156,10 +149,6 @@ func (r *Redirect) Message(key string) string { // Get old input data. func (r *Redirect) OldInputs() map[string]string { - if r.c == nil { - return make(map[string]string) - } - msgs := r.c.redirectionMessages oldInputs := make(map[string]string, len(msgs)) @@ -167,7 +156,7 @@ func (r *Redirect) OldInputs() map[string]string { k, v := parseMessage(msg) if strings.HasPrefix(k, OldInputDataPrefix) { - // Remove "old_input_data_" part from key + // remove "old_input_data_" part from key oldInputs[k[len(OldInputDataPrefix):]] = v } } @@ -176,11 +165,8 @@ func (r *Redirect) OldInputs() map[string]string { // Get old input data by key. func (r *Redirect) OldInput(key string) string { - if r.c == nil { - return "" - } - msgs := r.c.redirectionMessages + for _, msg := range msgs { k, v := parseMessage(msg) @@ -202,10 +188,6 @@ func (r *Redirect) To(location string) error { // Route redirects to the Route registered in the app with appropriate parameters. // If you want to send queries or params to route, you should use config parameter. func (r *Redirect) Route(name string, config ...RedirectConfig) error { - if r.c == nil { - return errors.New("redirect context is nil") - } - // Check config cfg := RedirectConfig{} if len(config) > 0 { @@ -290,10 +272,6 @@ func (r *Redirect) Back(fallback ...string) error { // setFlash is a method to get flash messages before removing them func (r *Redirect) setFlash() { - if r.c == nil { - return - } - // parse flash messages cookieValue := r.c.Cookies(FlashCookieName) diff --git a/redirect_test.go b/redirect_test.go index d1c7bff82f..a77bfbc4ec 100644 --- a/redirect_test.go +++ b/redirect_test.go @@ -249,6 +249,7 @@ func Test_Redirect_setFlash(t *testing.T) { // go test -run Test_Redirect_Request func Test_Redirect_Request(t *testing.T) { + t.Parallel() app := New() app.Get("/", func(c Ctx) error { From aa5c6dddcd019b2efdd7ea1411a781dba8f7e040 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Wed, 6 Mar 2024 01:00:03 -0500 Subject: [PATCH 31/46] SetLogger can't run in parallel --- ctx.go | 9 ++++----- log/fiberlog_test.go | 1 - middleware/proxy/proxy.go | 4 ---- middleware/session/session.go | 7 ------- 4 files changed, 4 insertions(+), 17 deletions(-) diff --git a/ctx.go b/ctx.go index 95bd7d8ea6..7f41048de3 100644 --- a/ctx.go +++ b/ctx.go @@ -1319,13 +1319,12 @@ func (c *DefaultCtx) Render(name string, bind Map, layouts ...string) error { var rendered bool for i := len(c.app.mountFields.appListKeys) - 1; i >= 0; i-- { prefix := c.app.mountFields.appListKeys[i] - app, exists := c.app.mountFields.appList[prefix] - if !exists || app == nil { // Check if app exists and is not nil - continue // Skip this iteration if app is nil - } + app := c.app.mountFields.appList[prefix] if prefix == "" || strings.Contains(c.OriginalURL(), prefix) { if len(layouts) == 0 && app.config.ViewsLayout != "" { - layouts = []string{app.config.ViewsLayout} + layouts = []string{ + app.config.ViewsLayout, + } } // Render template from Views diff --git a/log/fiberlog_test.go b/log/fiberlog_test.go index 8c5ae4d702..315afe7290 100644 --- a/log/fiberlog_test.go +++ b/log/fiberlog_test.go @@ -15,7 +15,6 @@ func Test_DefaultSystemLogger(t *testing.T) { } func Test_SetLogger(t *testing.T) { - t.Parallel() setLog := &defaultLogger{ stdlog: log.New(os.Stderr, "", log.LstdFlags|log.Lshortfile|log.Lmicroseconds), depth: 6, diff --git a/middleware/proxy/proxy.go b/middleware/proxy/proxy.go index cf22ca7dc0..167a0e6f31 100644 --- a/middleware/proxy/proxy.go +++ b/middleware/proxy/proxy.go @@ -192,10 +192,6 @@ func doAction( } func getScheme(uri []byte) []byte { - if uri == nil { - return nil - } - i := bytes.IndexByte(uri, '/') if i < 1 || uri[i-1] != ':' || i == len(uri)-1 || uri[i+1] != '/' { return nil diff --git a/middleware/session/session.go b/middleware/session/session.go index 71ffebf56c..c257343968 100644 --- a/middleware/session/session.go +++ b/middleware/session/session.go @@ -214,10 +214,6 @@ func (s *Session) SetExpiry(exp time.Duration) { } func (s *Session) setSession() { - if s.config == nil { - return - } - if s.config.source == SourceHeader { s.ctx.Request().Header.SetBytesV(s.config.sessionName, []byte(s.id)) s.ctx.Response().Header.SetBytesV(s.config.sessionName, []byte(s.id)) @@ -250,9 +246,6 @@ func (s *Session) setSession() { } func (s *Session) delSession() { - if s.config == nil { - return - } if s.config.source == SourceHeader { s.ctx.Request().Header.Del(s.config.sessionName) s.ctx.Response().Header.Del(s.config.sessionName) From c28c9de5ca08109ba3a6f7aac82ca15e232566eb Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Wed, 6 Mar 2024 10:08:19 -0500 Subject: [PATCH 32/46] Run more tests in parallel, fix issue with goroutine in limiter middleware --- .github/workflows/test.yml | 3 -- middleware/limiter/limiter_test.go | 51 +++++++++++++++++------------- middleware/logger/logger_test.go | 2 +- middleware/proxy/proxy_test.go | 4 +-- middleware/session/session_test.go | 3 +- 5 files changed, 34 insertions(+), 29 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a19fbea7fe..5843692594 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,9 +33,6 @@ jobs: - name: Install gotestsum run: go install gotest.tools/gotestsum@v1.11.0 - - name: Run go vet - run: go vet ./... - - name: Run tests run: gotestsum -f testname -- ./... -race -count=1 -coverprofile=coverage.txt -covermode=atomic diff --git a/middleware/limiter/limiter_test.go b/middleware/limiter/limiter_test.go index 5bcb535cc9..7c7d337c43 100644 --- a/middleware/limiter/limiter_test.go +++ b/middleware/limiter/limiter_test.go @@ -9,12 +9,14 @@ import ( "github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3/internal/storage/memory" + "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/valyala/fasthttp" ) // go test -run Test_Limiter_Concurrency_Store -race -v func Test_Limiter_Concurrency_Store(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(New(Config{ @@ -28,20 +30,19 @@ func Test_Limiter_Concurrency_Store(t *testing.T) { }) var wg sync.WaitGroup - singleRequest := func(wg *sync.WaitGroup) { - defer wg.Done() - resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil)) - require.NoError(t, err) - require.Equal(t, fiber.StatusOK, resp.StatusCode) - - body, err := io.ReadAll(resp.Body) - require.NoError(t, err) - require.Equal(t, "Hello tester!", string(body)) - } for i := 0; i <= 49; i++ { wg.Add(1) - go singleRequest(&wg) + go func(wg *sync.WaitGroup) { + defer wg.Done() + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil)) + assert.NoError(t, err) + assert.Equal(t, fiber.StatusOK, resp.StatusCode) + + body, err := io.ReadAll(resp.Body) + assert.NoError(t, err) + assert.Equal(t, "Hello tester!", string(body)) + }(&wg) } wg.Wait() @@ -59,6 +60,7 @@ func Test_Limiter_Concurrency_Store(t *testing.T) { // go test -run Test_Limiter_Concurrency -race -v func Test_Limiter_Concurrency(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(New(Config{ @@ -71,20 +73,19 @@ func Test_Limiter_Concurrency(t *testing.T) { }) var wg sync.WaitGroup - singleRequest := func(wg *sync.WaitGroup) { - defer wg.Done() - resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil)) - require.NoError(t, err) - require.Equal(t, fiber.StatusOK, resp.StatusCode) - - body, err := io.ReadAll(resp.Body) - require.NoError(t, err) - require.Equal(t, "Hello tester!", string(body)) - } for i := 0; i <= 49; i++ { wg.Add(1) - go singleRequest(&wg) + go func(wg *sync.WaitGroup) { + defer wg.Done() + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil)) + assert.NoError(t, err) + assert.Equal(t, fiber.StatusOK, resp.StatusCode) + + body, err := io.ReadAll(resp.Body) + assert.NoError(t, err) + assert.Equal(t, "Hello tester!", string(body)) + }(&wg) } wg.Wait() @@ -337,6 +338,7 @@ func Test_Limiter_Fixed_Window_Custom_Storage_Skip_Failed_Requests(t *testing.T) // go test -run Test_Limiter_Sliding_Window_Skip_Failed_Requests -v func Test_Limiter_Sliding_Window_Skip_Failed_Requests(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(New(Config{ @@ -413,6 +415,7 @@ func Test_Limiter_Sliding_Window_Custom_Storage_Skip_Failed_Requests(t *testing. // go test -run Test_Limiter_Fixed_Window_Skip_Successful_Requests -v func Test_Limiter_Fixed_Window_Skip_Successful_Requests(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(New(Config{ @@ -450,6 +453,7 @@ func Test_Limiter_Fixed_Window_Skip_Successful_Requests(t *testing.T) { // go test -run Test_Limiter_Fixed_Window_Custom_Storage_Skip_Successful_Requests -v func Test_Limiter_Fixed_Window_Custom_Storage_Skip_Successful_Requests(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(New(Config{ @@ -488,6 +492,7 @@ func Test_Limiter_Fixed_Window_Custom_Storage_Skip_Successful_Requests(t *testin // go test -run Test_Limiter_Sliding_Window_Skip_Successful_Requests -v func Test_Limiter_Sliding_Window_Skip_Successful_Requests(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(New(Config{ @@ -525,6 +530,7 @@ func Test_Limiter_Sliding_Window_Skip_Successful_Requests(t *testing.T) { // go test -run Test_Limiter_Sliding_Window_Custom_Storage_Skip_Successful_Requests -v func Test_Limiter_Sliding_Window_Custom_Storage_Skip_Successful_Requests(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(New(Config{ @@ -659,6 +665,7 @@ func Benchmark_Limiter(b *testing.B) { // go test -run Test_Sliding_Window -race -v func Test_Sliding_Window(t *testing.T) { + t.Parallel() app := fiber.New() app.Use(New(Config{ Max: 10, diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index b830720cdc..0aa517bcf5 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -264,7 +264,7 @@ 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), 2*time.Second) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 3*time.Second) require.NoError(t, err) require.Equal(t, fiber.StatusOK, resp.StatusCode) diff --git a/middleware/proxy/proxy_test.go b/middleware/proxy/proxy_test.go index ab7098138d..03b2873582 100644 --- a/middleware/proxy/proxy_test.go +++ b/middleware/proxy/proxy_test.go @@ -436,7 +436,7 @@ 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)) + resp, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 2*time.Second) require.NoError(t, err1) _, err := io.ReadAll(resp.Body) require.NoError(t, err) @@ -474,7 +474,7 @@ 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)) + resp, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 2*time.Second) require.NoError(t, err1) body, err := io.ReadAll(resp.Body) require.NoError(t, err) diff --git a/middleware/session/session_test.go b/middleware/session/session_test.go index ab2741b95e..bb7e9d6286 100644 --- a/middleware/session/session_test.go +++ b/middleware/session/session_test.go @@ -346,8 +346,9 @@ func Test_Session_Save_Expiration(t *testing.T) { t.Parallel() t.Run("save to cookie", func(t *testing.T) { - const sessionDuration = 5 * time.Second t.Parallel() + + const sessionDuration = 5 * time.Second // session store store := New() // fiber instance From ea8b6a2b36f3a84b813c0cfd90db88c5999c19cf Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Wed, 6 Mar 2024 22:18:37 -0500 Subject: [PATCH 33/46] Update internal/storage/memory, add more benchmarks --- internal/storage/memory/config.go | 4 +- internal/storage/memory/memory.go | 36 ++- internal/storage/memory/memory_test.go | 292 +++++++++++++++++++++---- 3 files changed, 280 insertions(+), 52 deletions(-) diff --git a/internal/storage/memory/config.go b/internal/storage/memory/config.go index 07d13edb5b..f4bab841c7 100644 --- a/internal/storage/memory/config.go +++ b/internal/storage/memory/config.go @@ -1,6 +1,8 @@ package memory -import "time" +import ( + "time" +) // Config defines the config for storage. type Config struct { diff --git a/internal/storage/memory/memory.go b/internal/storage/memory/memory.go index 279728f58d..c32ae20c58 100644 --- a/internal/storage/memory/memory.go +++ b/internal/storage/memory/memory.go @@ -1,5 +1,3 @@ -// Package memory Is a copy of the storage memory from the external storage packet as a purpose to test the behavior -// in the unittests when using a storages from these packets package memory import ( @@ -44,7 +42,7 @@ func New(config ...Config) *Storage { // Get value by key func (s *Storage) Get(key string) ([]byte, error) { - if len(key) <= 0 { + if len(key) == 0 { return nil, nil } s.mux.RLock() @@ -60,7 +58,7 @@ func (s *Storage) Get(key string) ([]byte, error) { // Set key with value func (s *Storage) Set(key string, val []byte, exp time.Duration) error { // Ain't Nobody Got Time For That - if len(key) <= 0 || len(val) <= 0 { + if len(key) == 0 || len(val) == 0 { return nil } @@ -79,7 +77,7 @@ func (s *Storage) Set(key string, val []byte, exp time.Duration) error { // Delete key by key func (s *Storage) Delete(key string) error { // Ain't Nobody Got Time For That - if len(key) <= 0 { + if len(key) == 0 { return nil } s.mux.Lock() @@ -117,7 +115,7 @@ func (s *Storage) gc() { expired = expired[:0] s.mux.RLock() for id, v := range s.db { - if v.expiry != 0 && v.expiry <= ts { + if v.expiry != 0 && v.expiry < ts { expired = append(expired, id) } } @@ -142,3 +140,29 @@ func (s *Storage) Conn() map[string]entry { defer s.mux.RUnlock() return s.db } + +// Return all the keys +func (s *Storage) Keys() ([][]byte, error) { + s.mux.RLock() + defer s.mux.RUnlock() + + if len(s.db) == 0 { + return nil, nil + } + + ts := utils.Timestamp() + keys := make([][]byte, 0, len(s.db)) + for key, v := range s.db { + // Filter out the expired keys + if v.expiry == 0 || v.expiry > ts { + keys = append(keys, []byte(key)) + } + } + + // Double check if no valid keys were found + if len(keys) == 0 { + return nil, nil + } + + return keys, nil +} diff --git a/internal/storage/memory/memory_test.go b/internal/storage/memory/memory_test.go index 524e1a7445..d1ad8f4576 100644 --- a/internal/storage/memory/memory_test.go +++ b/internal/storage/memory/memory_test.go @@ -4,28 +4,31 @@ import ( "testing" "time" - "github.com/gofiber/utils/v2" "github.com/stretchr/testify/require" ) -var testStore = New() - func Test_Storage_Memory_Set(t *testing.T) { t.Parallel() var ( - key = "john" - val = []byte("doe") + testStore = New() + key = "john" + val = []byte("doe") ) err := testStore.Set(key, val, 0) require.NoError(t, err) + + keys, err := testStore.Keys() + require.NoError(t, err) + require.Len(t, keys, 1) } func Test_Storage_Memory_Set_Override(t *testing.T) { t.Parallel() var ( - key = "john" - val = []byte("doe") + testStore = New() + key = "john" + val = []byte("doe") ) err := testStore.Set(key, val, 0) @@ -33,13 +36,18 @@ func Test_Storage_Memory_Set_Override(t *testing.T) { err = testStore.Set(key, val, 0) require.NoError(t, err) + + keys, err := testStore.Keys() + require.NoError(t, err) + require.Len(t, keys, 1) } func Test_Storage_Memory_Get(t *testing.T) { t.Parallel() var ( - key = "john" - val = []byte("doe") + testStore = New() + key = "john" + val = []byte("doe") ) err := testStore.Set(key, val, 0) @@ -48,58 +56,109 @@ func Test_Storage_Memory_Get(t *testing.T) { result, err := testStore.Get(key) require.NoError(t, err) require.Equal(t, val, result) + + keys, err := testStore.Keys() + require.NoError(t, err) + require.Len(t, keys, 1) } func Test_Storage_Memory_Set_Expiration(t *testing.T) { t.Parallel() var ( - key = "john" - val = []byte("doe") - exp = 1 * time.Second + testStore = New() + key = "john" + val = []byte("doe") + exp = 1 * time.Second ) err := testStore.Set(key, val, exp) require.NoError(t, err) time.Sleep(1100 * time.Millisecond) + + result, err := testStore.Get(key) + require.NoError(t, err) + require.Zero(t, len(result)) + + keys, err := testStore.Keys() + require.NoError(t, err) + require.Nil(t, keys) } -func Test_Storage_Memory_Get_Expired(t *testing.T) { - key := "john" +func Test_Storage_Memory_Set_Long_Expiration_with_Keys(t *testing.T) { + t.Parallel() + var ( + testStore = New() + key = "john" + val = []byte("doe") + exp = 5 * time.Second + ) + + keys, err := testStore.Keys() + require.NoError(t, err) + require.Nil(t, keys) + + err = testStore.Set(key, val, exp) + require.NoError(t, err) + + time.Sleep(1100 * time.Millisecond) + + keys, err = testStore.Keys() + require.NoError(t, err) + require.Len(t, keys, 1) + time.Sleep(4000 * time.Millisecond) result, err := testStore.Get(key) require.NoError(t, err) - require.Empty(t, result) + require.Zero(t, len(result)) + + keys, err = testStore.Keys() + require.NoError(t, err) + require.Nil(t, keys) } func Test_Storage_Memory_Get_NotExist(t *testing.T) { t.Parallel() - + testStore := New() result, err := testStore.Get("notexist") require.NoError(t, err) - require.Empty(t, result) + require.Zero(t, len(result)) + + keys, err := testStore.Keys() + require.NoError(t, err) + require.Nil(t, keys) } func Test_Storage_Memory_Delete(t *testing.T) { t.Parallel() var ( - key = "john-delete" - val = []byte("doe") + testStore = New() + key = "john" + val = []byte("doe") ) err := testStore.Set(key, val, 0) require.NoError(t, err) + keys, err := testStore.Keys() + require.NoError(t, err) + require.Len(t, keys, 1) + err = testStore.Delete(key) require.NoError(t, err) result, err := testStore.Get(key) require.NoError(t, err) - require.Empty(t, result) + require.Zero(t, len(result)) + + keys, err = testStore.Keys() + require.NoError(t, err) + require.Nil(t, keys) } func Test_Storage_Memory_Reset(t *testing.T) { t.Parallel() + testStore := New() val := []byte("doe") err := testStore.Set("john1", val, 0) @@ -108,52 +167,195 @@ func Test_Storage_Memory_Reset(t *testing.T) { err = testStore.Set("john2", val, 0) require.NoError(t, err) + keys, err := testStore.Keys() + require.NoError(t, err) + require.Len(t, keys, 2) + err = testStore.Reset() require.NoError(t, err) result, err := testStore.Get("john1") require.NoError(t, err) - require.Empty(t, result) + require.Zero(t, len(result)) result, err = testStore.Get("john2") require.NoError(t, err) - require.Empty(t, result) + require.Zero(t, len(result)) + + keys, err = testStore.Keys() + require.NoError(t, err) + require.Nil(t, keys) } func Test_Storage_Memory_Close(t *testing.T) { t.Parallel() + testStore := New() require.NoError(t, testStore.Close()) } func Test_Storage_Memory_Conn(t *testing.T) { t.Parallel() + testStore := New() require.NotNil(t, testStore.Conn()) } -// go test -v -run=^$ -bench=Benchmark_Storage_Memory -benchmem -count=4 -func Benchmark_Storage_Memory(b *testing.B) { - keyLength := 1000 - keys := make([]string, keyLength) - for i := 0; i < keyLength; i++ { - keys[i] = utils.UUID() +// Benchmarks for Set operation +func Benchmark_Memory_Set(b *testing.B) { + testStore := New() + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _ = testStore.Set("john", []byte("doe"), 0) //nolint: errcheck // error not needed for benchmark + } +} + +func Benchmark_Memory_Set_Parallel(b *testing.B) { + testStore := New() + b.ReportAllocs() + b.ResetTimer() + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _ = testStore.Set("john", []byte("doe"), 0) //nolint: errcheck // error not needed for benchmark + } + }) +} + +func Benchmark_Memory_Set_Asserted(b *testing.B) { + testStore := New() + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + err := testStore.Set("john", []byte("doe"), 0) + require.NoError(b, err) } - value := []byte("joe") - - ttl := 2 * time.Second - b.Run("fiber_memory", func(b *testing.B) { - d := New() - b.ReportAllocs() - b.ResetTimer() - for n := 0; n < b.N; n++ { - for _, key := range keys { - d.Set(key, value, ttl) - } - for _, key := range keys { - _, _ = d.Get(key) - } - for _, key := range keys { - d.Delete(key) - } +} + +func Benchmark_Memory_Set_Asserted_Parallel(b *testing.B) { + testStore := New() + b.ReportAllocs() + b.ResetTimer() + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + err := testStore.Set("john", []byte("doe"), 0) + require.NoError(b, err) + } + }) +} + +// Benchmarks for Get operation +func Benchmark_Memory_Get(b *testing.B) { + testStore := New() + err := testStore.Set("john", []byte("doe"), 0) + require.NoError(b, err) + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, _ = testStore.Get("john") //nolint: errcheck // error not needed for benchmark + } +} + +func Benchmark_Memory_Get_Parallel(b *testing.B) { + testStore := New() + err := testStore.Set("john", []byte("doe"), 0) + require.NoError(b, err) + + b.ReportAllocs() + b.ResetTimer() + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _, _ = testStore.Get("john") //nolint: errcheck // error not needed for benchmark + } + }) +} + +func Benchmark_Memory_Get_Asserted(b *testing.B) { + testStore := New() + err := testStore.Set("john", []byte("doe"), 0) + require.NoError(b, err) + + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _, err := testStore.Get("john") + require.NoError(b, err) + } +} + +func Benchmark_Memory_Get_Asserted_Parallel(b *testing.B) { + testStore := New() + err := testStore.Set("john", []byte("doe"), 0) + require.NoError(b, err) + + b.ReportAllocs() + b.ResetTimer() + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _, err := testStore.Get("john") + require.NoError(b, err) + } + }) +} + +// Benchmarks for SetAndDelete operation +func Benchmark_Memory_SetAndDelete(b *testing.B) { + testStore := New() + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + _ = testStore.Set("john", []byte("doe"), 0) //nolint: errcheck // error not needed for benchmark + _ = testStore.Delete("john") //nolint: errcheck // error not needed for benchmark + } +} + +func Benchmark_Memory_SetAndDelete_Parallel(b *testing.B) { + testStore := New() + b.ReportAllocs() + b.ResetTimer() + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + _ = testStore.Set("john", []byte("doe"), 0) //nolint: errcheck // error not needed for benchmark + _ = testStore.Delete("john") //nolint: errcheck // error not needed for benchmark + } + }) +} + +func Benchmark_Memory_SetAndDelete_Asserted(b *testing.B) { + testStore := New() + b.ReportAllocs() + b.ResetTimer() + + for i := 0; i < b.N; i++ { + err := testStore.Set("john", []byte("doe"), 0) + require.NoError(b, err) + + err = testStore.Delete("john") + require.NoError(b, err) + } +} + +func Benchmark_Memory_SetAndDelete_Asserted_Parallel(b *testing.B) { + testStore := New() + b.ReportAllocs() + b.ResetTimer() + + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + err := testStore.Set("john", []byte("doe"), 0) + require.NoError(b, err) + + err = testStore.Delete("john") + require.NoError(b, err) } }) } From fef02a70c72777917fcac5e3b462ab8572b6354d Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Wed, 6 Mar 2024 23:48:37 -0500 Subject: [PATCH 34/46] Increase sleep for csrf test by 100 milliseconds. Implement asserted and parallel benchmarks for Session middleware --- middleware/csrf/csrf_test.go | 2 +- middleware/session/session_test.go | 144 ++++++++++++++++++++++++++--- 2 files changed, 134 insertions(+), 12 deletions(-) diff --git a/middleware/csrf/csrf_test.go b/middleware/csrf/csrf_test.go index 99cbf85e48..e4a91fd2b2 100644 --- a/middleware/csrf/csrf_test.go +++ b/middleware/csrf/csrf_test.go @@ -261,7 +261,7 @@ func Test_CSRF_ExpiredToken_WithSession(t *testing.T) { require.Equal(t, 200, ctx.Response.StatusCode()) // Wait for the token to expire - time.Sleep(1 * time.Second) + time.Sleep(1*time.Second + 100*time.Millisecond) // Expired CSRF token ctx.Request.Reset() diff --git a/middleware/session/session_test.go b/middleware/session/session_test.go index bb7e9d6286..02bd52d4e2 100644 --- a/middleware/session/session_test.go +++ b/middleware/session/session_test.go @@ -635,36 +635,158 @@ func Test_Session_Regenerate(t *testing.T) { // go test -v -run=^$ -bench=Benchmark_Session -benchmem -count=4 func Benchmark_Session(b *testing.B) { - app, store := fiber.New(), New() - c := app.AcquireCtx(&fasthttp.RequestCtx{}) - defer app.ReleaseCtx(c) - c.Request().Header.SetCookie(store.sessionName, "12356789") - - var err error b.Run("default", func(b *testing.B) { + app, store := fiber.New(), New() + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + defer app.ReleaseCtx(c) + c.Request().Header.SetCookie(store.sessionName, "12356789") + b.ReportAllocs() b.ResetTimer() for n := 0; n < b.N; n++ { sess, _ := store.Get(c) //nolint:errcheck // We're inside a benchmark sess.Set("john", "doe") - err = sess.Save() + _ = sess.Save() //nolint:errcheck // We're inside a benchmark } - - require.NoError(b, err) }) b.Run("storage", func(b *testing.B) { - store = New(Config{ + app := fiber.New() + store := New(Config{ Storage: memory.New(), }) + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + defer app.ReleaseCtx(c) + c.Request().Header.SetCookie(store.sessionName, "12356789") + b.ReportAllocs() b.ResetTimer() for n := 0; n < b.N; n++ { sess, _ := store.Get(c) //nolint:errcheck // We're inside a benchmark sess.Set("john", "doe") + _ = sess.Save() //nolint:errcheck // We're inside a benchmark + } + }) +} + +// go test -v -run=^$ -bench=Benchmark_Session_Parallel -benchmem -count=4 +func Benchmark_Session_Parallel(b *testing.B) { + b.Run("default", func(b *testing.B) { + app, store := fiber.New(), New() + b.ReportAllocs() + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + c.Request().Header.SetCookie(store.sessionName, "12356789") + + sess, _ := store.Get(c) //nolint:errcheck // We're inside a benchmark + sess.Set("john", "doe") + _ = sess.Save() //nolint:errcheck // We're inside a benchmark + app.ReleaseCtx(c) + } + }) + }) + + b.Run("storage", func(b *testing.B) { + app := fiber.New() + store := New(Config{ + Storage: memory.New(), + }) + b.ReportAllocs() + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + c.Request().Header.SetCookie(store.sessionName, "12356789") + + sess, _ := store.Get(c) //nolint:errcheck // We're inside a benchmark + sess.Set("john", "doe") + _ = sess.Save() //nolint:errcheck // We're inside a benchmark + app.ReleaseCtx(c) + } + }) + }) +} + +// go test -v -run=^$ -bench=Benchmark_Session_Asserted -benchmem -count=4 +func Benchmark_Session_Asserted(b *testing.B) { + b.Run("default", func(b *testing.B) { + app, store := fiber.New(), New() + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + defer app.ReleaseCtx(c) + c.Request().Header.SetCookie(store.sessionName, "12356789") + + b.ReportAllocs() + b.ResetTimer() + for n := 0; n < b.N; n++ { + sess, err := store.Get(c) + require.NoError(b, err) + sess.Set("john", "doe") + err = sess.Save() + require.NoError(b, err) + } + }) + + b.Run("storage", func(b *testing.B) { + app := fiber.New() + store := New(Config{ + Storage: memory.New(), + }) + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + defer app.ReleaseCtx(c) + c.Request().Header.SetCookie(store.sessionName, "12356789") + + b.ReportAllocs() + b.ResetTimer() + for n := 0; n < b.N; n++ { + sess, err := store.Get(c) + require.NoError(b, err) + sess.Set("john", "doe") err = sess.Save() + require.NoError(b, err) } + }) +} + +// go test -v -run=^$ -bench=Benchmark_Session_Asserted_Parallel -benchmem -count=4 +func Benchmark_Session_Asserted_Parallel(b *testing.B) { + b.Run("default", func(b *testing.B) { + app, store := fiber.New(), New() + b.ReportAllocs() + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + c.Request().Header.SetCookie(store.sessionName, "12356789") + + sess, err := store.Get(c) + require.NoError(b, err) + sess.Set("john", "doe") + require.NoError(b, sess.Save()) + app.ReleaseCtx(c) + } + }) + }) - require.NoError(b, err) + b.Run("storage", func(b *testing.B) { + app := fiber.New() + store := New(Config{ + Storage: memory.New(), + }) + b.ReportAllocs() + b.ResetTimer() + b.RunParallel(func(pb *testing.PB) { + for pb.Next() { + c := app.AcquireCtx(&fasthttp.RequestCtx{}) + c.Request().Header.SetCookie(store.sessionName, "12356789") + + sess, err := store.Get(c) + require.NoError(b, err) + sess.Set("john", "doe") + require.NoError(b, sess.Save()) + app.ReleaseCtx(c) + } + }) }) } From ad09022e4d92869a74e505db5e51215437768ef4 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Wed, 6 Mar 2024 23:52:55 -0500 Subject: [PATCH 35/46] Add 100 milliseconds to sleep during test --- middleware/cache/cache_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/middleware/cache/cache_test.go b/middleware/cache/cache_test.go index cec919abd3..8966ec7ac2 100644 --- a/middleware/cache/cache_test.go +++ b/middleware/cache/cache_test.go @@ -519,7 +519,7 @@ func Test_CustomExpiration(t *testing.T) { require.Equal(t, 1, newCacheTime) // Sleep until the cache is expired - time.Sleep(1 * time.Second) + time.Sleep(1*time.Second + 100*time.Millisecond) cachedResp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil)) require.NoError(t, err) From 2ea11178e38f4838a0a1993ef17c0a52e46c5db8 Mon Sep 17 00:00:00 2001 From: Juan Calderon-Perez Date: Thu, 7 Mar 2024 00:56:52 -0500 Subject: [PATCH 36/46] Revert name change --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5843692594..37c923d44b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,7 @@ jobs: - name: Install gotestsum run: go install gotest.tools/gotestsum@v1.11.0 - - name: Run tests + - name: Test run: gotestsum -f testname -- ./... -race -count=1 -coverprofile=coverage.txt -covermode=atomic - name: Upload coverage reports to Codecov From 864885ed23bb85d5b0f8194595763ad50be6c19e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= Date: Thu, 7 Mar 2024 16:43:06 +0100 Subject: [PATCH 37/46] fix: Inconsistent and flaky unit-tests --- internal/storage/memory/memory.go | 2 ++ internal/storage/memory/memory_test.go | 10 ++++++---- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/internal/storage/memory/memory.go b/internal/storage/memory/memory.go index c32ae20c58..e2f305d28b 100644 --- a/internal/storage/memory/memory.go +++ b/internal/storage/memory/memory.go @@ -1,3 +1,5 @@ +// Package memory Is a copy of the storage memory from the external storage packet as a purpose to test the behavior +// in the unittests when using a storages from these packets package memory import ( diff --git a/internal/storage/memory/memory_test.go b/internal/storage/memory/memory_test.go index d1ad8f4576..fecbad2ee5 100644 --- a/internal/storage/memory/memory_test.go +++ b/internal/storage/memory/memory_test.go @@ -65,10 +65,12 @@ func Test_Storage_Memory_Get(t *testing.T) { func Test_Storage_Memory_Set_Expiration(t *testing.T) { t.Parallel() var ( - testStore = New() - key = "john" - val = []byte("doe") - exp = 1 * time.Second + testStore = New(Config{ + GCInterval: 300 * time.Millisecond, + }) + key = "john" + val = []byte("doe") + exp = 1 * time.Second ) err := testStore.Set(key, val, exp) From a1366ac72d7d7f76df075a8d5b85dd76578958ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= Date: Thu, 7 Mar 2024 17:19:21 +0100 Subject: [PATCH 38/46] fix: Inconsistent and flaky unit-tests --- app_test.go | 13 +++++++++++++ middleware/proxy/proxy_test.go | 10 ++++++++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/app_test.go b/app_test.go index 81981e17a6..68f0413bb1 100644 --- a/app_test.go +++ b/app_test.go @@ -1769,6 +1769,19 @@ func Test_App_Test_no_timeout_infinitely(t *testing.T) { } } +func Test_App_Test_timeout(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), 100*time.Millisecond) + require.Equal(t, errors.New("test: timeout error after 100ms"), err) +} + func Test_App_SetTLSHandler(t *testing.T) { t.Parallel() tlsHandler := &TLSHandler{clientHelloInfo: &tls.ClientHelloInfo{ diff --git a/middleware/proxy/proxy_test.go b/middleware/proxy/proxy_test.go index 9ee43a4f9a..b9da7af911 100644 --- a/middleware/proxy/proxy_test.go +++ b/middleware/proxy/proxy_test.go @@ -495,8 +495,14 @@ func Test_Proxy_DoTimeout_Timeout(t *testing.T) { return DoTimeout(c, "http://"+addr, 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) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 2*time.Second) + require.NoError(t, err) + body, err := io.ReadAll(resp.Body) + require.NoError(t, err) + + require.Equal(t, "timeout", string(body)) + require.Equal(t, fiber.StatusInternalServerError, resp.StatusCode) + require.Equal(t, "/test", resp.Request.URL.String()) } // go test -race -run Test_Proxy_DoDeadline_RestoreOriginalURL From efb201e70975f8c012d01f56ede0352535ee3807 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= Date: Fri, 8 Mar 2024 16:16:35 +0100 Subject: [PATCH 39/46] fix: Inconsistent and flaky unit-tests --- client/cookiejar_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/cookiejar_test.go b/client/cookiejar_test.go index fadee9294d..2b72bdf34a 100644 --- a/client/cookiejar_test.go +++ b/client/cookiejar_test.go @@ -157,7 +157,7 @@ func TestCookieJarSetRepeatedCookieKeys(t *testing.T) { cookies := cj.Get(uri) require.Len(t, cookies, 2) - require.Equal(t, cookies[0], cookie2) + require.Equal(t, cookies[0].String(), cookie2.String()) require.True(t, bytes.Equal(cookies[0].Value(), cookie2.Value())) } From bfcbd92a37fabf998971348de5075a4a01903ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= Date: Fri, 8 Mar 2024 16:22:23 +0100 Subject: [PATCH 40/46] fix: Inconsistent and flaky unit-tests --- middleware/idempotency/idempotency_test.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/middleware/idempotency/idempotency_test.go b/middleware/idempotency/idempotency_test.go index 20d8577024..a17aea01aa 100644 --- a/middleware/idempotency/idempotency_test.go +++ b/middleware/idempotency/idempotency_test.go @@ -75,7 +75,7 @@ func Test_Idempotency(t *testing.T) { }) app.Post("/slow", func(c fiber.Ctx) error { - time.Sleep(4 * lifetime) + time.Sleep(3 * lifetime) return c.SendString(strconv.Itoa(nextCount())) }) @@ -85,7 +85,8 @@ func Test_Idempotency(t *testing.T) { if idempotencyKey != "" { req.Header.Set("X-Idempotency-Key", idempotencyKey) } - resp, err := app.Test(req, 5*lifetime) + // double timeout time for slow route + resp, err := app.Test(req, 6*lifetime) require.NoError(t, err) body, err := io.ReadAll(resp.Body) require.NoError(t, err) @@ -125,7 +126,7 @@ func Test_Idempotency(t *testing.T) { wg.Wait() require.Equal(t, "11", doReq(fiber.MethodPost, "/slow", "22222222-2222-2222-2222-222222222222")) } - time.Sleep(4 * lifetime) + time.Sleep(3 * lifetime) require.Equal(t, "12", doReq(fiber.MethodPost, "/slow", "22222222-2222-2222-2222-222222222222")) } From 1431315c42be7998036e9b3b53d0644da81423e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= Date: Fri, 8 Mar 2024 16:53:43 +0100 Subject: [PATCH 41/46] fix: Inconsistent and flaky unit-tests --- middleware/idempotency/idempotency_test.go | 3 +-- middleware/limiter/limiter_test.go | 13 +++++++++---- 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/middleware/idempotency/idempotency_test.go b/middleware/idempotency/idempotency_test.go index a17aea01aa..4d4e788e7b 100644 --- a/middleware/idempotency/idempotency_test.go +++ b/middleware/idempotency/idempotency_test.go @@ -85,8 +85,7 @@ func Test_Idempotency(t *testing.T) { if idempotencyKey != "" { req.Header.Set("X-Idempotency-Key", idempotencyKey) } - // double timeout time for slow route - resp, err := app.Test(req, 6*lifetime) + resp, err := app.Test(req, 15*time.Second) require.NoError(t, err) body, err := io.ReadAll(resp.Body) require.NoError(t, err) diff --git a/middleware/limiter/limiter_test.go b/middleware/limiter/limiter_test.go index 7c7d337c43..ed4470e9a8 100644 --- a/middleware/limiter/limiter_test.go +++ b/middleware/limiter/limiter_test.go @@ -669,7 +669,7 @@ func Test_Sliding_Window(t *testing.T) { app := fiber.New() app.Use(New(Config{ Max: 10, - Expiration: 2 * time.Second, + Expiration: 1 * time.Second, Storage: memory.New(), LimiterMiddleware: SlidingWindow{}, })) @@ -693,7 +693,7 @@ func Test_Sliding_Window(t *testing.T) { singleRequest(false) } - time.Sleep(2 * time.Second) + time.Sleep(3 * time.Second) for i := 0; i < 5; i++ { singleRequest(false) @@ -705,9 +705,14 @@ func Test_Sliding_Window(t *testing.T) { singleRequest(false) } - time.Sleep(4 * time.Second) + time.Sleep(3 * time.Second) - for i := 0; i < 9; i++ { + for i := 0; i < 10; i++ { singleRequest(false) } + + // requests should fail now + for i := 0; i < 5; i++ { + singleRequest(true) + } } From ff2e33734282433bdb2f0f86a6913c3e7b555e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= Date: Fri, 8 Mar 2024 17:13:49 +0100 Subject: [PATCH 42/46] fix: Inconsistent and flaky unit-tests --- middleware/idempotency/idempotency_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/middleware/idempotency/idempotency_test.go b/middleware/idempotency/idempotency_test.go index 4d4e788e7b..f8a4030a1e 100644 --- a/middleware/idempotency/idempotency_test.go +++ b/middleware/idempotency/idempotency_test.go @@ -54,7 +54,7 @@ func Test_Idempotency(t *testing.T) { }) // Needs to be at least a second as the memory storage doesn't support shorter durations. - const lifetime = 1 * time.Second + const lifetime = 2 * time.Second app.Use(idempotency.New(idempotency.Config{ Lifetime: lifetime, @@ -108,7 +108,7 @@ func Test_Idempotency(t *testing.T) { require.Equal(t, "9", doReq(fiber.MethodPost, "/", "11111111-1111-1111-1111-111111111111")) require.Equal(t, "7", doReq(fiber.MethodPost, "/", "00000000-0000-0000-0000-000000000000")) - time.Sleep(2 * lifetime) + time.Sleep(4 * lifetime) require.Equal(t, "10", doReq(fiber.MethodPost, "/", "00000000-0000-0000-0000-000000000000")) require.Equal(t, "10", doReq(fiber.MethodPost, "/", "00000000-0000-0000-0000-000000000000")) From 686bac2f4f439e46f5f0a8b2ba5d9213119fee79 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= Date: Fri, 8 Mar 2024 17:19:53 +0100 Subject: [PATCH 43/46] fix: Inconsistent and flaky unit-tests --- internal/storage/memory/memory_test.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/internal/storage/memory/memory_test.go b/internal/storage/memory/memory_test.go index fecbad2ee5..ae1930a143 100644 --- a/internal/storage/memory/memory_test.go +++ b/internal/storage/memory/memory_test.go @@ -76,7 +76,8 @@ func Test_Storage_Memory_Set_Expiration(t *testing.T) { err := testStore.Set(key, val, exp) require.NoError(t, err) - time.Sleep(1100 * time.Millisecond) + // interval + expire + buffer + time.Sleep(1500 * time.Millisecond) result, err := testStore.Get(key) require.NoError(t, err) From 53f512883a5436d955314e76d749d68dbb44dbe4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= Date: Fri, 8 Mar 2024 17:34:35 +0100 Subject: [PATCH 44/46] fix: Inconsistent and flaky unit-tests --- internal/storage/memory/memory_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/internal/storage/memory/memory_test.go b/internal/storage/memory/memory_test.go index ae1930a143..347e9f5f47 100644 --- a/internal/storage/memory/memory_test.go +++ b/internal/storage/memory/memory_test.go @@ -94,7 +94,7 @@ func Test_Storage_Memory_Set_Long_Expiration_with_Keys(t *testing.T) { testStore = New() key = "john" val = []byte("doe") - exp = 5 * time.Second + exp = 3 * time.Second ) keys, err := testStore.Keys() From af52a43ab6d17b68a901506486176b446258e628 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= Date: Fri, 8 Mar 2024 19:21:55 +0100 Subject: [PATCH 45/46] fix: Inconsistent and flaky unit-tests --- .github/workflows/test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 37c923d44b..b98918b64f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,6 +17,7 @@ name: Test jobs: Build: strategy: + max-parallel: 4 matrix: go-version: [1.20.x, 1.21.x, 1.22.x] platform: [ubuntu-latest, windows-latest, macos-latest, macos-14] From c20898588a6f7ff020680639e2f86063fd864299 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= Date: Fri, 8 Mar 2024 19:29:17 +0100 Subject: [PATCH 46/46] fix: Inconsistent and flaky unit-tests --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b98918b64f..37c923d44b 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,7 +17,6 @@ name: Test jobs: Build: strategy: - max-parallel: 4 matrix: go-version: [1.20.x, 1.21.x, 1.22.x] platform: [ubuntu-latest, windows-latest, macos-latest, macos-14]