fix: Inconsistent and flaky unit-tests (#2892)

* Fixes for some of the failing tests

* Add readiness check to serverStart()

* Use net/http client for tests listen test

* Use different key for this test

* Run Proxy Middleware tests in parallel. Add nil checks for potential issues pointed by nilaway

* Enable parallel client tests

* Do not run timing sensitive tests in parallel

* Remove TODO

* Revert Test_Proxy_DoTimeout_Timeout, and remove t.Parallel() for it

* Do not calculate favicon len on each handler call

* Revert logic change

* Increase timeout of SaveFile tests

* Do not run time sensitive tests in parallel

* The Agent can't be run in parallel

* Do not run time sensitive tests in parallel

* Fixes based on uber/nilaway

* Revert change to Client test

* Run parallel

* Update client_test.go

* Update client_test.go

* Update cache_test.go

* Update cookiejar_test.go

* Remove parallel for test using timeouts

* Remove t.Parallel() from logger middleware tests

* Do not use testify.require in a goroutine

* Fix import, and update golangci-lint

* Remove changes to template_chain.go

* Run more tests in parallel

* Add more parallel tests

* Add more parallel tests

* SetLogger can't run in parallel

* Run more tests in parallel, fix issue with goroutine in limiter middleware

* Update internal/storage/memory, add more benchmarks

* Increase sleep for csrf test by 100 milliseconds. Implement asserted and parallel benchmarks for Session middleware

* Add 100 milliseconds to sleep during test

* Revert name change

* fix: Inconsistent and flaky unit-tests

* fix: Inconsistent and flaky unit-tests

* fix: Inconsistent and flaky unit-tests

* fix: Inconsistent and flaky unit-tests

* fix: Inconsistent and flaky unit-tests

* fix: Inconsistent and flaky unit-tests

* fix: Inconsistent and flaky unit-tests

* fix: Inconsistent and flaky unit-tests

* fix: Inconsistent and flaky unit-tests

* fix: Inconsistent and flaky unit-tests

---------

Co-authored-by: M. Efe Çetin <efectn@protonmail.com>
Co-authored-by: René <rene@gofiber.io>
pull/2911/head
Juan Calderon-Perez 2024-03-08 14:03:13 -05:00 committed by GitHub
parent 1fdef7f742
commit 0379cc59aa
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
32 changed files with 698 additions and 301 deletions

View File

@ -13,8 +13,6 @@ output:
linters-settings: linters-settings:
testifylint: testifylint:
enable-all: true enable-all: true
disable:
- go-require
errcheck: errcheck:
check-type-assertions: true check-type-assertions: true
check-blank: true check-blank: true

View File

@ -25,6 +25,7 @@ import (
"github.com/gofiber/utils/v2" "github.com/gofiber/utils/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
"github.com/valyala/fasthttp/fasthttputil" "github.com/valyala/fasthttp/fasthttputil"
@ -197,6 +198,7 @@ func (*customConstraint) Execute(param string, args ...string) bool {
} }
func Test_App_CustomConstraint(t *testing.T) { func Test_App_CustomConstraint(t *testing.T) {
t.Parallel()
app := New() app := New()
app.RegisterCustomConstraint(&customConstraint{}) app.RegisterCustomConstraint(&customConstraint{})
@ -821,20 +823,20 @@ func Test_App_ShutdownWithTimeout(t *testing.T) {
time.Sleep(5 * time.Second) time.Sleep(5 * time.Second)
return c.SendString("body") return c.SendString("body")
}) })
ln := fasthttputil.NewInmemoryListener() ln := fasthttputil.NewInmemoryListener()
go func() { go func() {
require.NoError(t, app.Listener(ln)) err := app.Listener(ln)
assert.NoError(t, err)
}() }()
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
go func() { go func() {
conn, err := ln.Dial() conn, err := ln.Dial()
if err != nil { assert.NoError(t, err)
t.Errorf("unexepcted error: %v", err)
}
if _, err = conn.Write([]byte("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")); err != nil { _, err = conn.Write([]byte("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n"))
t.Errorf("unexpected error: %v", err) assert.NoError(t, err)
}
}() }()
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
@ -866,20 +868,18 @@ func Test_App_ShutdownWithContext(t *testing.T) {
ln := fasthttputil.NewInmemoryListener() ln := fasthttputil.NewInmemoryListener()
go func() { go func() {
require.NoError(t, app.Listener(ln)) err := app.Listener(ln)
assert.NoError(t, err)
}() }()
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
go func() { go func() {
conn, err := ln.Dial() conn, err := ln.Dial()
if err != nil { assert.NoError(t, err)
t.Errorf("unexepcted error: %v", err)
}
if _, err = conn.Write([]byte("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n")); err != nil { _, err = conn.Write([]byte("GET / HTTP/1.1\r\nHost: google.com\r\n\r\n"))
t.Errorf("unexpected error: %v", err) assert.NoError(t, err)
}
}() }()
time.Sleep(1 * time.Second) time.Sleep(1 * time.Second)
@ -903,6 +903,7 @@ func Test_App_ShutdownWithContext(t *testing.T) {
// go test -run Test_App_Static_Index_Default // go test -run Test_App_Static_Index_Default
func Test_App_Static_Index_Default(t *testing.T) { func Test_App_Static_Index_Default(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Static("/prefix", "./.github/workflows") app.Static("/prefix", "./.github/workflows")
@ -932,6 +933,7 @@ func Test_App_Static_Index_Default(t *testing.T) {
// go test -run Test_App_Static_Index // go test -run Test_App_Static_Index
func Test_App_Static_Direct(t *testing.T) { func Test_App_Static_Direct(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Static("/", "./.github") app.Static("/", "./.github")
@ -960,6 +962,7 @@ func Test_App_Static_Direct(t *testing.T) {
// go test -run Test_App_Static_MaxAge // go test -run Test_App_Static_MaxAge
func Test_App_Static_MaxAge(t *testing.T) { func Test_App_Static_MaxAge(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Static("/", "./.github", Static{MaxAge: 100}) app.Static("/", "./.github", Static{MaxAge: 100})
@ -974,6 +977,7 @@ func Test_App_Static_MaxAge(t *testing.T) {
// go test -run Test_App_Static_Custom_CacheControl // go test -run Test_App_Static_Custom_CacheControl
func Test_App_Static_Custom_CacheControl(t *testing.T) { func Test_App_Static_Custom_CacheControl(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Static("/", "./.github", Static{ModifyResponse: func(c Ctx) error { app.Static("/", "./.github", Static{ModifyResponse: func(c Ctx) error {
@ -994,6 +998,7 @@ func Test_App_Static_Custom_CacheControl(t *testing.T) {
// go test -run Test_App_Static_Download // go test -run Test_App_Static_Download
func Test_App_Static_Download(t *testing.T) { func Test_App_Static_Download(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Static("/fiber.png", "./.github/testdata/fs/img/fiber.png", Static{Download: true}) app.Static("/fiber.png", "./.github/testdata/fs/img/fiber.png", Static{Download: true})
@ -1008,6 +1013,7 @@ func Test_App_Static_Download(t *testing.T) {
// go test -run Test_App_Static_Group // go test -run Test_App_Static_Group
func Test_App_Static_Group(t *testing.T) { func Test_App_Static_Group(t *testing.T) {
t.Parallel()
app := New() app := New()
grp := app.Group("/v1", func(c Ctx) error { grp := app.Group("/v1", func(c Ctx) error {
@ -1037,6 +1043,7 @@ func Test_App_Static_Group(t *testing.T) {
} }
func Test_App_Static_Wildcard(t *testing.T) { func Test_App_Static_Wildcard(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Static("*", "./.github/index.html") app.Static("*", "./.github/index.html")
@ -1054,6 +1061,7 @@ func Test_App_Static_Wildcard(t *testing.T) {
} }
func Test_App_Static_Prefix_Wildcard(t *testing.T) { func Test_App_Static_Prefix_Wildcard(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Static("/test/*", "./.github/index.html") app.Static("/test/*", "./.github/index.html")
@ -1079,6 +1087,7 @@ func Test_App_Static_Prefix_Wildcard(t *testing.T) {
} }
func Test_App_Static_Prefix(t *testing.T) { func Test_App_Static_Prefix(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Static("/john", "./.github") app.Static("/john", "./.github")
@ -1109,6 +1118,7 @@ func Test_App_Static_Prefix(t *testing.T) {
} }
func Test_App_Static_Trailing_Slash(t *testing.T) { func Test_App_Static_Trailing_Slash(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Static("/john", "./.github") app.Static("/john", "./.github")
@ -1155,6 +1165,7 @@ func Test_App_Static_Trailing_Slash(t *testing.T) {
} }
func Test_App_Static_Next(t *testing.T) { func Test_App_Static_Next(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Static("/", ".github", Static{ app.Static("/", ".github", Static{
Next: func(c Ctx) bool { Next: func(c Ctx) bool {
@ -1168,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.Run("app.Static is skipped: invoking Get handler", func(t *testing.T) {
t.Parallel()
req := httptest.NewRequest(MethodGet, "/", nil) req := httptest.NewRequest(MethodGet, "/", nil)
req.Header.Set("X-Custom-Header", "skip") req.Header.Set("X-Custom-Header", "skip")
resp, err := app.Test(req) resp, err := app.Test(req)
@ -1182,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.Run("app.Static is not skipped: serving index.html", func(t *testing.T) {
t.Parallel()
req := httptest.NewRequest(MethodGet, "/", nil) req := httptest.NewRequest(MethodGet, "/", nil)
req.Header.Set("X-Custom-Header", "don't skip") req.Header.Set("X-Custom-Header", "don't skip")
resp, err := app.Test(req) resp, err := app.Test(req)
@ -1198,6 +1211,7 @@ func Test_App_Static_Next(t *testing.T) {
// go test -run Test_App_Mixed_Routes_WithSameLen // go test -run Test_App_Mixed_Routes_WithSameLen
func Test_App_Mixed_Routes_WithSameLen(t *testing.T) { func Test_App_Mixed_Routes_WithSameLen(t *testing.T) {
t.Parallel()
app := New() app := New()
// middleware // middleware
@ -1476,6 +1490,7 @@ func (invalidView) Render(io.Writer, string, any, ...string) error { panic("impl
// go test -run Test_App_Init_Error_View // go test -run Test_App_Init_Error_View
func Test_App_Init_Error_View(t *testing.T) { func Test_App_Init_Error_View(t *testing.T) {
t.Parallel()
app := New(Config{Views: invalidView{}}) app := New(Config{Views: invalidView{}})
defer func() { defer func() {
@ -1542,23 +1557,23 @@ func Test_App_ReadTimeout(t *testing.T) {
time.Sleep(500 * time.Millisecond) time.Sleep(500 * time.Millisecond)
conn, err := net.Dial(NetworkTCP4, "127.0.0.1:4004") conn, err := net.Dial(NetworkTCP4, "127.0.0.1:4004")
require.NoError(t, err) assert.NoError(t, err)
defer func(conn net.Conn) { defer func(conn net.Conn) {
err := conn.Close() err := conn.Close()
require.NoError(t, err) assert.NoError(t, err)
}(conn) }(conn)
_, err = conn.Write([]byte("HEAD /read-timeout HTTP/1.1\r\n")) _, err = conn.Write([]byte("HEAD /read-timeout HTTP/1.1\r\n"))
require.NoError(t, err) assert.NoError(t, err)
buf := make([]byte, 1024) buf := make([]byte, 1024)
var n int var n int
n, err = conn.Read(buf) n, err = conn.Read(buf)
require.NoError(t, err) assert.NoError(t, err)
require.True(t, bytes.Contains(buf[:n], []byte("408 Request Timeout"))) 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})) require.NoError(t, app.Listen(":4004", ListenConfig{DisableStartupMessage: true}))
@ -1576,23 +1591,22 @@ func Test_App_BadRequest(t *testing.T) {
go func() { go func() {
time.Sleep(500 * time.Millisecond) time.Sleep(500 * time.Millisecond)
conn, err := net.Dial(NetworkTCP4, "127.0.0.1:4005") conn, err := net.Dial(NetworkTCP4, "127.0.0.1:4005")
require.NoError(t, err) assert.NoError(t, err)
defer func(conn net.Conn) { defer func(conn net.Conn) {
err := conn.Close() err := conn.Close()
require.NoError(t, err) assert.NoError(t, err)
}(conn) }(conn)
_, err = conn.Write([]byte("BadRequest\r\n")) _, err = conn.Write([]byte("BadRequest\r\n"))
require.NoError(t, err) assert.NoError(t, err)
buf := make([]byte, 1024) buf := make([]byte, 1024)
var n int var n int
n, err = conn.Read(buf) n, err = conn.Read(buf)
require.NoError(t, err)
require.True(t, bytes.Contains(buf[:n], []byte("400 Bad Request"))) assert.NoError(t, err)
assert.True(t, bytes.Contains(buf[:n], []byte("400 Bad Request")))
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listen(":4005", ListenConfig{DisableStartupMessage: true})) require.NoError(t, app.Listen(":4005", ListenConfig{DisableStartupMessage: true}))
@ -1612,12 +1626,12 @@ func Test_App_SmallReadBuffer(t *testing.T) {
go func() { go func() {
time.Sleep(500 * time.Millisecond) time.Sleep(500 * time.Millisecond)
req, err := http.NewRequestWithContext(context.Background(), MethodGet, "http://127.0.0.1:4006/small-read-buffer", nil) 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 var client http.Client
resp, err := client.Do(req) resp, err := client.Do(req)
require.NoError(t, err) assert.NoError(t, err)
require.Equal(t, 431, resp.StatusCode) assert.Equal(t, 431, resp.StatusCode)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listen(":4006", ListenConfig{DisableStartupMessage: true})) require.NoError(t, app.Listen(":4006", ListenConfig{DisableStartupMessage: true}))
@ -1755,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) { func Test_App_SetTLSHandler(t *testing.T) {
t.Parallel() t.Parallel()
tlsHandler := &TLSHandler{clientHelloInfo: &tls.ClientHelloInfo{ tlsHandler := &TLSHandler{clientHelloInfo: &tls.ClientHelloInfo{
@ -1815,6 +1842,7 @@ func TestApp_GetRoutes(t *testing.T) {
} }
func Test_Middleware_Route_Naming_With_Use(t *testing.T) { func Test_Middleware_Route_Naming_With_Use(t *testing.T) {
t.Parallel()
named := "named" named := "named"
app := New() app := New()
@ -1874,6 +1902,7 @@ func Test_Middleware_Route_Naming_With_Use(t *testing.T) {
} }
func Test_Route_Naming_Issue_2671_2685(t *testing.T) { func Test_Route_Naming_Issue_2671_2685(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Get("/", emptyHandler).Name("index") app.Get("/", emptyHandler).Name("index")

View File

@ -16,6 +16,7 @@ import (
"github.com/gofiber/fiber/v3/addon/retry" "github.com/gofiber/fiber/v3/addon/retry"
"github.com/gofiber/fiber/v3/internal/tlstest" "github.com/gofiber/fiber/v3/internal/tlstest"
"github.com/gofiber/utils/v2" "github.com/gofiber/utils/v2"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/valyala/bytebufferpool" "github.com/valyala/bytebufferpool"
) )
@ -277,8 +278,8 @@ func Test_Client_ConcurrencyRequests(t *testing.T) {
go func(m string) { go func(m string) {
defer wg.Done() defer wg.Done()
resp, err := client.Custom("http://example.com", m) resp, err := client.Custom("http://example.com", m)
require.NoError(t, err) assert.NoError(t, err)
require.Equal(t, "example.com "+m, utils.UnsafeString(resp.RawResponse.Body())) assert.Equal(t, "example.com "+m, utils.UnsafeString(resp.RawResponse.Body()))
}(method) }(method)
} }
} }
@ -1258,10 +1259,11 @@ func Test_Client_TLS(t *testing.T) {
}) })
go func() { go func() {
require.NoError(t, app.Listener(ln, fiber.ListenConfig{ assert.NoError(t, app.Listener(ln, fiber.ListenConfig{
DisableStartupMessage: true, DisableStartupMessage: true,
})) }))
}() }()
time.Sleep(1 * time.Second)
client := New() client := New()
resp, err := client.SetTLSConfig(clientTLSConf).Get("https://" + ln.Addr().String()) resp, err := client.SetTLSConfig(clientTLSConf).Get("https://" + ln.Addr().String())
@ -1291,10 +1293,11 @@ func Test_Client_TLS_Error(t *testing.T) {
}) })
go func() { go func() {
require.NoError(t, app.Listener(ln, fiber.ListenConfig{ assert.NoError(t, app.Listener(ln, fiber.ListenConfig{
DisableStartupMessage: true, DisableStartupMessage: true,
})) }))
}() }()
time.Sleep(1 * time.Second)
client := New() client := New()
resp, err := client.SetTLSConfig(clientTLSConf).Get("https://" + ln.Addr().String()) resp, err := client.SetTLSConfig(clientTLSConf).Get("https://" + ln.Addr().String())
@ -1321,10 +1324,11 @@ func Test_Client_TLS_Empty_TLSConfig(t *testing.T) {
}) })
go func() { go func() {
require.NoError(t, app.Listener(ln, fiber.ListenConfig{ assert.NoError(t, app.Listener(ln, fiber.ListenConfig{
DisableStartupMessage: true, DisableStartupMessage: true,
})) }))
}() }()
time.Sleep(1 * time.Second)
client := New() client := New()
resp, err := client.Get("https://" + ln.Addr().String()) resp, err := client.Get("https://" + ln.Addr().String())
@ -1579,18 +1583,17 @@ func Test_Client_SetProxyURL(t *testing.T) {
func Test_Client_SetRetryConfig(t *testing.T) { func Test_Client_SetRetryConfig(t *testing.T) {
t.Parallel() t.Parallel()
retryConfig := &retry.Config{ retryConfig := &retry.Config{
InitialInterval: 1 * time.Second, InitialInterval: 1 * time.Second,
MaxRetryCount: 3, MaxRetryCount: 3,
} }
core, client, req := newCore(), New(), AcquireRequest() core, client, req := newCore(), New(), AcquireRequest()
req.SetURL("http://example.com") req.SetURL("http://exampleretry.com")
client.SetRetryConfig(retryConfig) client.SetRetryConfig(retryConfig)
_, err := core.execute(context.Background(), client, req) _, 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.InitialInterval, client.RetryConfig().InitialInterval)
require.Equal(t, retryConfig.MaxRetryCount, client.RetryConfig().MaxRetryCount) require.Equal(t, retryConfig.MaxRetryCount, client.RetryConfig().MaxRetryCount)
} }

View File

@ -135,7 +135,6 @@ func TestCookieJarSet(t *testing.T) {
func TestCookieJarSetRepeatedCookieKeys(t *testing.T) { func TestCookieJarSetRepeatedCookieKeys(t *testing.T) {
t.Parallel() t.Parallel()
host := "fast.http" host := "fast.http"
cj := &CookieJar{} cj := &CookieJar{}
@ -158,7 +157,7 @@ func TestCookieJarSetRepeatedCookieKeys(t *testing.T) {
cookies := cj.Get(uri) cookies := cj.Get(uri)
require.Len(t, cookies, 2) 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())) require.True(t, bytes.Equal(cookies[0].Value(), cookie2.Value()))
} }

View File

@ -8,6 +8,7 @@ import (
"time" "time"
"github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/valyala/fasthttp/fasthttputil" "github.com/valyala/fasthttp/fasthttputil"
) )
@ -48,6 +49,7 @@ func Test_AddMissing_Port(t *testing.T) {
}, },
} }
for _, tt := range tests { for _, tt := range tests {
tt := tt // create a new 'tt' variable for the goroutine
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
t.Parallel() t.Parallel()
require.Equal(t, tt.want, addMissingPort(tt.args.addr, tt.args.isTLS)) require.Equal(t, tt.want, addMissingPort(tt.args.addr, tt.args.isTLS))
@ -57,7 +59,6 @@ func Test_AddMissing_Port(t *testing.T) {
func Test_Exec_Func(t *testing.T) { func Test_Exec_Func(t *testing.T) {
t.Parallel() t.Parallel()
ln := fasthttputil.NewInmemoryListener() ln := fasthttputil.NewInmemoryListener()
app := fiber.New() app := fiber.New()
@ -75,7 +76,7 @@ func Test_Exec_Func(t *testing.T) {
}) })
go func() { 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) time.Sleep(300 * time.Millisecond)
@ -134,7 +135,6 @@ func Test_Exec_Func(t *testing.T) {
func Test_Execute(t *testing.T) { func Test_Execute(t *testing.T) {
t.Parallel() t.Parallel()
ln := fasthttputil.NewInmemoryListener() ln := fasthttputil.NewInmemoryListener()
app := fiber.New() app := fiber.New()
@ -152,7 +152,7 @@ func Test_Execute(t *testing.T) {
}) })
go func() { 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) { t.Run("add user request hooks", func(t *testing.T) {

View File

@ -6,6 +6,7 @@ import (
"time" "time"
"github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/valyala/fasthttp/fasthttputil" "github.com/valyala/fasthttp/fasthttputil"
) )
@ -29,9 +30,8 @@ func startTestServer(tb testing.TB, beforeStarting func(app *fiber.App)) *testSe
ch := make(chan struct{}) ch := make(chan struct{})
go func() { go func() {
if err := app.Listener(ln, fiber.ListenConfig{DisableStartupMessage: true}); err != nil { err := app.Listener(ln, fiber.ListenConfig{DisableStartupMessage: true})
tb.Fatal(err) assert.NoError(tb, err)
}
close(ch) close(ch)
}() }()

View File

@ -11,6 +11,7 @@ import (
"testing" "testing"
"github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -587,7 +588,7 @@ func Test_Client_Logger_Debug(t *testing.T) {
addrChan := make(chan string) addrChan := make(chan string)
go func() { go func() {
require.NoError(t, app.Listen(":0", fiber.ListenConfig{ assert.NoError(t, app.Listen(":0", fiber.ListenConfig{
DisableStartupMessage: true, DisableStartupMessage: true,
ListenerAddrFunc: func(addr net.Addr) { ListenerAddrFunc: func(addr net.Addr) {
addrChan <- addr.String() addrChan <- addr.String()
@ -624,7 +625,7 @@ func Test_Client_Logger_DisableDebug(t *testing.T) {
addrChan := make(chan string) addrChan := make(chan string)
go func() { go func() {
require.NoError(t, app.Listen(":0", fiber.ListenConfig{ assert.NoError(t, app.Listen(":0", fiber.ListenConfig{
DisableStartupMessage: true, DisableStartupMessage: true,
ListenerAddrFunc: func(addr net.Addr) { ListenerAddrFunc: func(addr net.Addr) {
addrChan <- addr.String() addrChan <- addr.String()

View File

@ -15,6 +15,7 @@ import (
"time" "time"
"github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
"github.com/valyala/fasthttp/fasthttputil" "github.com/valyala/fasthttp/fasthttputil"
@ -1245,7 +1246,7 @@ func Test_Request_MaxRedirects(t *testing.T) {
return c.SendString("redirect") 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.Run("success", func(t *testing.T) {
t.Parallel() t.Parallel()

View File

@ -12,6 +12,7 @@ import (
"github.com/gofiber/fiber/v3/internal/tlstest" "github.com/gofiber/fiber/v3/internal/tlstest"
"github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -158,7 +159,7 @@ func Test_Response_Protocol(t *testing.T) {
}) })
go func() { go func() {
require.NoError(t, app.Listener(ln, fiber.ListenConfig{ assert.NoError(t, app.Listener(ln, fiber.ListenConfig{
DisableStartupMessage: true, DisableStartupMessage: true,
})) }))
}() }()

View File

@ -212,6 +212,7 @@ func Benchmark_Utils_ParamsMatch(b *testing.B) {
} }
func Test_Utils_AcceptsOfferType(t *testing.T) { func Test_Utils_AcceptsOfferType(t *testing.T) {
t.Parallel()
testCases := []struct { testCases := []struct {
description string description string
spec string spec string
@ -273,6 +274,7 @@ func Test_Utils_AcceptsOfferType(t *testing.T) {
} }
func Test_Utils_GetSplicedStrList(t *testing.T) { func Test_Utils_GetSplicedStrList(t *testing.T) {
t.Parallel()
testCases := []struct { testCases := []struct {
description string description string
headerValue string headerValue string
@ -302,6 +304,8 @@ func Test_Utils_GetSplicedStrList(t *testing.T) {
for _, tc := range testCases { for _, tc := range testCases {
t.Run(tc.description, func(t *testing.T) { t.Run(tc.description, func(t *testing.T) {
tc := tc // create a new 'tc' variable for the goroutine
t.Parallel()
dst := make([]string, 10) dst := make([]string, 10)
result := getSplicedStrList(tc.headerValue, dst) result := getSplicedStrList(tc.headerValue, dst)
require.Equal(t, tc.expectedList, result) require.Equal(t, tc.expectedList, result)

View File

@ -6,6 +6,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/valyala/bytebufferpool" "github.com/valyala/bytebufferpool"
) )
@ -215,7 +216,7 @@ func Test_Hook_OnListen(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listen(":9000")) require.NoError(t, app.Listen(":9000"))
@ -238,7 +239,7 @@ func Test_Hook_OnListenPrefork(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) 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})) require.NoError(t, app.Listen(":9000", ListenConfig{DisableStartupMessage: true, EnablePrefork: true}))
@ -254,7 +255,7 @@ func Test_Hook_OnHook(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
app.Hooks().OnFork(func(pid int) error { app.Hooks().OnFork(func(pid int) error {

View File

@ -9,48 +9,50 @@ import (
) )
// go test -run Test_Memory -v -race // go test -run Test_Memory -v -race
func Test_Memory(t *testing.T) { func Test_Memory(t *testing.T) {
t.Parallel() t.Parallel()
store := New() store := New()
var ( var (
key = "john" key = "john-internal"
val any = []byte("doe") val any = []byte("doe")
exp = 1 * time.Second exp = 1 * time.Second
) )
// Set key with value
store.Set(key, val, 0) store.Set(key, val, 0)
store.Set(key, val, 0)
result := store.Get(key) result := store.Get(key)
require.Equal(t, val, result) require.Equal(t, val, result)
// Get non-existing key
result = store.Get("empty") result = store.Get("empty")
require.Equal(t, nil, result) require.Nil(t, result)
// Set key with value and ttl
store.Set(key, val, exp) store.Set(key, val, exp)
time.Sleep(1100 * time.Millisecond) time.Sleep(1100 * time.Millisecond)
result = store.Get(key) result = store.Get(key)
require.Equal(t, nil, result) require.Nil(t, result)
// Set key with value and no expiration
store.Set(key, val, 0) store.Set(key, val, 0)
result = store.Get(key) result = store.Get(key)
require.Equal(t, val, result) require.Equal(t, val, result)
// Delete key
store.Delete(key) store.Delete(key)
result = store.Get(key) result = store.Get(key)
require.Equal(t, nil, result) require.Nil(t, result)
store.Set("john", val, 0) // Reset all keys
store.Set("doe", val, 0) store.Set("john-reset", val, 0)
store.Set("doe-reset", val, 0)
store.Reset() store.Reset()
result = store.Get("john") // Check if all keys are deleted
require.Equal(t, nil, result) result = store.Get("john-reset")
require.Nil(t, result)
result = store.Get("doe") result = store.Get("doe-reset")
require.Equal(t, nil, result) require.Nil(t, result)
} }
// go test -v -run=^$ -bench=Benchmark_Memory -benchmem -count=4 // go test -v -run=^$ -bench=Benchmark_Memory -benchmem -count=4

View File

@ -1,6 +1,8 @@
package memory package memory
import "time" import (
"time"
)
// Config defines the config for storage. // Config defines the config for storage.
type Config struct { type Config struct {

View File

@ -44,7 +44,7 @@ func New(config ...Config) *Storage {
// Get value by key // Get value by key
func (s *Storage) Get(key string) ([]byte, error) { func (s *Storage) Get(key string) ([]byte, error) {
if len(key) <= 0 { if len(key) == 0 {
return nil, nil return nil, nil
} }
s.mux.RLock() s.mux.RLock()
@ -60,7 +60,7 @@ func (s *Storage) Get(key string) ([]byte, error) {
// Set key with value // Set key with value
func (s *Storage) Set(key string, val []byte, exp time.Duration) error { func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
// Ain't Nobody Got Time For That // Ain't Nobody Got Time For That
if len(key) <= 0 || len(val) <= 0 { if len(key) == 0 || len(val) == 0 {
return nil return nil
} }
@ -79,7 +79,7 @@ func (s *Storage) Set(key string, val []byte, exp time.Duration) error {
// Delete key by key // Delete key by key
func (s *Storage) Delete(key string) error { func (s *Storage) Delete(key string) error {
// Ain't Nobody Got Time For That // Ain't Nobody Got Time For That
if len(key) <= 0 { if len(key) == 0 {
return nil return nil
} }
s.mux.Lock() s.mux.Lock()
@ -117,7 +117,7 @@ func (s *Storage) gc() {
expired = expired[:0] expired = expired[:0]
s.mux.RLock() s.mux.RLock()
for id, v := range s.db { for id, v := range s.db {
if v.expiry != 0 && v.expiry <= ts { if v.expiry != 0 && v.expiry < ts {
expired = append(expired, id) expired = append(expired, id)
} }
} }
@ -142,3 +142,29 @@ func (s *Storage) Conn() map[string]entry {
defer s.mux.RUnlock() defer s.mux.RUnlock()
return s.db 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
}

View File

@ -4,28 +4,31 @@ import (
"testing" "testing"
"time" "time"
"github.com/gofiber/utils/v2"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
var testStore = New()
func Test_Storage_Memory_Set(t *testing.T) { func Test_Storage_Memory_Set(t *testing.T) {
t.Parallel() t.Parallel()
var ( var (
key = "john" testStore = New()
val = []byte("doe") key = "john"
val = []byte("doe")
) )
err := testStore.Set(key, val, 0) err := testStore.Set(key, val, 0)
require.NoError(t, err) 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) { func Test_Storage_Memory_Set_Override(t *testing.T) {
t.Parallel() t.Parallel()
var ( var (
key = "john" testStore = New()
val = []byte("doe") key = "john"
val = []byte("doe")
) )
err := testStore.Set(key, val, 0) 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) err = testStore.Set(key, val, 0)
require.NoError(t, err) 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) { func Test_Storage_Memory_Get(t *testing.T) {
t.Parallel() t.Parallel()
var ( var (
key = "john" testStore = New()
val = []byte("doe") key = "john"
val = []byte("doe")
) )
err := testStore.Set(key, val, 0) err := testStore.Set(key, val, 0)
@ -48,11 +56,18 @@ func Test_Storage_Memory_Get(t *testing.T) {
result, err := testStore.Get(key) result, err := testStore.Get(key)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, val, result) 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) { func Test_Storage_Memory_Set_Expiration(t *testing.T) {
t.Parallel() t.Parallel()
var ( var (
testStore = New(Config{
GCInterval: 300 * time.Millisecond,
})
key = "john" key = "john"
val = []byte("doe") val = []byte("doe")
exp = 1 * time.Second exp = 1 * time.Second
@ -61,45 +76,92 @@ func Test_Storage_Memory_Set_Expiration(t *testing.T) {
err := testStore.Set(key, val, exp) err := testStore.Set(key, val, exp)
require.NoError(t, err) require.NoError(t, err)
time.Sleep(1100 * time.Millisecond) // interval + expire + buffer
} time.Sleep(1500 * time.Millisecond)
func Test_Storage_Memory_Get_Expired(t *testing.T) {
key := "john"
result, err := testStore.Get(key) result, err := testStore.Get(key)
require.NoError(t, err) 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_Set_Long_Expiration_with_Keys(t *testing.T) {
t.Parallel()
var (
testStore = New()
key = "john"
val = []byte("doe")
exp = 3 * 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.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) { func Test_Storage_Memory_Get_NotExist(t *testing.T) {
t.Parallel() t.Parallel()
testStore := New()
result, err := testStore.Get("notexist") result, err := testStore.Get("notexist")
require.NoError(t, err) 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) { func Test_Storage_Memory_Delete(t *testing.T) {
t.Parallel() t.Parallel()
var ( var (
key = "john" testStore = New()
val = []byte("doe") key = "john"
val = []byte("doe")
) )
err := testStore.Set(key, val, 0) err := testStore.Set(key, val, 0)
require.NoError(t, err) require.NoError(t, err)
keys, err := testStore.Keys()
require.NoError(t, err)
require.Len(t, keys, 1)
err = testStore.Delete(key) err = testStore.Delete(key)
require.NoError(t, err) require.NoError(t, err)
result, err := testStore.Get(key) result, err := testStore.Get(key)
require.NoError(t, err) 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) { func Test_Storage_Memory_Reset(t *testing.T) {
t.Parallel() t.Parallel()
testStore := New()
val := []byte("doe") val := []byte("doe")
err := testStore.Set("john1", val, 0) err := testStore.Set("john1", val, 0)
@ -108,52 +170,195 @@ func Test_Storage_Memory_Reset(t *testing.T) {
err = testStore.Set("john2", val, 0) err = testStore.Set("john2", val, 0)
require.NoError(t, err) require.NoError(t, err)
keys, err := testStore.Keys()
require.NoError(t, err)
require.Len(t, keys, 2)
err = testStore.Reset() err = testStore.Reset()
require.NoError(t, err) require.NoError(t, err)
result, err := testStore.Get("john1") result, err := testStore.Get("john1")
require.NoError(t, err) require.NoError(t, err)
require.Empty(t, result) require.Zero(t, len(result))
result, err = testStore.Get("john2") result, err = testStore.Get("john2")
require.NoError(t, err) 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) { func Test_Storage_Memory_Close(t *testing.T) {
t.Parallel() t.Parallel()
testStore := New()
require.NoError(t, testStore.Close()) require.NoError(t, testStore.Close())
} }
func Test_Storage_Memory_Conn(t *testing.T) { func Test_Storage_Memory_Conn(t *testing.T) {
t.Parallel() t.Parallel()
testStore := New()
require.NotNil(t, testStore.Conn()) require.NotNil(t, testStore.Conn())
} }
// go test -v -run=^$ -bench=Benchmark_Storage_Memory -benchmem -count=4 // Benchmarks for Set operation
func Benchmark_Storage_Memory(b *testing.B) { func Benchmark_Memory_Set(b *testing.B) {
keyLength := 1000 testStore := New()
keys := make([]string, keyLength) b.ReportAllocs()
for i := 0; i < keyLength; i++ { b.ResetTimer()
keys[i] = utils.UUID()
}
value := []byte("joe")
ttl := 2 * time.Second for i := 0; i < b.N; i++ {
b.Run("fiber_memory", func(b *testing.B) { _ = testStore.Set("john", []byte("doe"), 0) //nolint: errcheck // error not needed for benchmark
d := New() }
b.ReportAllocs() }
b.ResetTimer()
for n := 0; n < b.N; n++ { func Benchmark_Memory_Set_Parallel(b *testing.B) {
for _, key := range keys { testStore := New()
d.Set(key, value, ttl) b.ReportAllocs()
} b.ResetTimer()
for _, key := range keys {
_, _ = d.Get(key) b.RunParallel(func(pb *testing.PB) {
} for pb.Next() {
for _, key := range keys { _ = testStore.Set("john", []byte("doe"), 0) //nolint: errcheck // error not needed for benchmark
d.Delete(key) }
} })
}
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)
}
}
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)
} }
}) })
} }

View File

@ -268,16 +268,17 @@ func (*App) createListener(addr string, tlsConfig *tls.Config, cfg ListenConfig)
listener, err = net.Listen(cfg.ListenerNetwork, addr) listener, err = net.Listen(cfg.ListenerNetwork, 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)
}
if cfg.ListenerAddrFunc != nil { if cfg.ListenerAddrFunc != nil {
cfg.ListenerAddrFunc(listener.Addr()) cfg.ListenerAddrFunc(listener.Addr())
} }
// Wrap error comes from tls.Listen/net.Listen return listener, nil
if err != nil {
err = fmt.Errorf("failed to listen: %w", err)
}
return listener, err
} }
func (app *App) printMessages(cfg ListenConfig, ln net.Listener) { 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 { if cfg.EnablePrefork {
// Turn the `pids` variable (in the form ",a,b,c,d,e,f,etc") into a slice of PIDs // 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, ",") { for _, v := range strings.Split(pids, ",") {
if v != "" { if v != "" {
pidSlice = append(pidSlice, v) pidSlice = append(pidSlice, v)

View File

@ -16,6 +16,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
"github.com/valyala/fasthttp/fasthttputil" "github.com/valyala/fasthttp/fasthttputil"
@ -29,7 +30,7 @@ func Test_Listen(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listen(":4003", ListenConfig{DisableStartupMessage: true})) require.NoError(t, app.Listen(":4003", ListenConfig{DisableStartupMessage: true}))
@ -47,12 +48,13 @@ func Test_Listen_Graceful_Shutdown(t *testing.T) {
}) })
ln := fasthttputil.NewInmemoryListener() ln := fasthttputil.NewInmemoryListener()
errs := make(chan error)
go func() { go func() {
ctx, cancel := context.WithTimeout(context.Background(), 250*time.Millisecond) ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
defer cancel() defer cancel()
err := app.Listener(ln, ListenConfig{ errs <- app.Listener(ln, ListenConfig{
DisableStartupMessage: true, DisableStartupMessage: true,
GracefulContext: ctx, GracefulContext: ctx,
OnShutdownSuccess: func() { OnShutdownSuccess: func() {
@ -61,18 +63,30 @@ func Test_Listen_Graceful_Shutdown(t *testing.T) {
mu.Unlock() mu.Unlock()
}, },
}) })
require.NoError(t, err)
}() }()
// 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 { testCases := []struct {
Time time.Duration Time time.Duration
ExpectedBody string ExpectedBody string
ExpectedStatusCode int ExpectedStatusCode int
ExpectedErr error ExpectedErr error
}{ }{
{Time: 100 * time.Millisecond, ExpectedBody: "example.com", ExpectedStatusCode: StatusOK, ExpectedErr: nil}, {Time: 500 * 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: 3 * time.Second, ExpectedBody: "", ExpectedStatusCode: StatusOK, ExpectedErr: errors.New("InmemoryListener is already closed: use of closed network connection")},
} }
for _, tc := range testCases { for _, tc := range testCases {
@ -96,7 +110,9 @@ func Test_Listen_Graceful_Shutdown(t *testing.T) {
} }
mu.Lock() mu.Lock()
err := <-errs
require.True(t, shutdown) require.True(t, shutdown)
require.NoError(t, err)
mu.Unlock() mu.Unlock()
} }
@ -121,7 +137,7 @@ func Test_Listen_TLS(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listen(":0", ListenConfig{ require.NoError(t, app.Listen(":0", ListenConfig{
@ -146,7 +162,7 @@ func Test_Listen_TLS_Prefork(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listen(":99999", ListenConfig{ require.NoError(t, app.Listen(":99999", ListenConfig{
@ -170,7 +186,7 @@ func Test_Listen_MutualTLS(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listen(":0", ListenConfig{ require.NoError(t, app.Listen(":0", ListenConfig{
@ -197,7 +213,7 @@ func Test_Listen_MutualTLS_Prefork(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listen(":99999", ListenConfig{ require.NoError(t, app.Listen(":99999", ListenConfig{
@ -215,7 +231,7 @@ func Test_Listener(t *testing.T) {
go func() { go func() {
time.Sleep(500 * time.Millisecond) time.Sleep(500 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
ln := fasthttputil.NewInmemoryListener() ln := fasthttputil.NewInmemoryListener()
@ -223,7 +239,6 @@ func Test_Listener(t *testing.T) {
} }
func Test_App_Listener_TLS_Listener(t *testing.T) { func Test_App_Listener_TLS_Listener(t *testing.T) {
t.Parallel()
// Create tls certificate // Create tls certificate
cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key") cer, err := tls.LoadX509KeyPair("./.github/testdata/ssl.pem", "./.github/testdata/ssl.key")
if err != nil { if err != nil {
@ -240,7 +255,7 @@ func Test_App_Listener_TLS_Listener(t *testing.T) {
go func() { go func() {
time.Sleep(time.Millisecond * 500) time.Sleep(time.Millisecond * 500)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listener(ln)) require.NoError(t, app.Listener(ln))
@ -253,7 +268,7 @@ func Test_Listen_TLSConfigFunc(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listen(":0", ListenConfig{ require.NoError(t, app.Listen(":0", ListenConfig{
@ -275,7 +290,7 @@ func Test_Listen_ListenerAddrFunc(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listen(":0", ListenConfig{ require.NoError(t, app.Listen(":0", ListenConfig{
@ -297,7 +312,7 @@ func Test_Listen_BeforeServeFunc(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
wantErr := errors.New("test") wantErr := errors.New("test")
@ -320,7 +335,7 @@ func Test_Listen_ListenerNetwork(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listen(":0", ListenConfig{ require.NoError(t, app.Listen(":0", ListenConfig{
@ -335,7 +350,7 @@ func Test_Listen_ListenerNetwork(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.Listen(":0", ListenConfig{ require.NoError(t, app.Listen(":0", ListenConfig{

View File

@ -9,6 +9,7 @@ import (
) )
func Test_DefaultSystemLogger(t *testing.T) { func Test_DefaultSystemLogger(t *testing.T) {
t.Parallel()
defaultL := DefaultLogger() defaultL := DefaultLogger()
require.Equal(t, logger, defaultL) require.Equal(t, logger, defaultL)
} }
@ -24,7 +25,6 @@ func Test_SetLogger(t *testing.T) {
} }
func Test_Fiberlog_SetLevel(t *testing.T) { func Test_Fiberlog_SetLevel(t *testing.T) {
// Set up
mockLogger := &defaultLogger{} mockLogger := &defaultLogger{}
SetLogger(mockLogger) SetLogger(mockLogger)

View File

@ -45,7 +45,6 @@ func Test_Cache_CacheControl(t *testing.T) {
func Test_Cache_Expired(t *testing.T) { func Test_Cache_Expired(t *testing.T) {
t.Parallel() t.Parallel()
app := fiber.New() app := fiber.New()
app.Use(New(Config{Expiration: 2 * time.Second})) app.Use(New(Config{Expiration: 2 * time.Second}))
@ -411,7 +410,6 @@ func Test_Cache_Post(t *testing.T) {
func Test_Cache_NothingToCache(t *testing.T) { func Test_Cache_NothingToCache(t *testing.T) {
t.Parallel() t.Parallel()
app := fiber.New() app := fiber.New()
app.Use(New(Config{Expiration: -(time.Second * 1)})) app.Use(New(Config{Expiration: -(time.Second * 1)}))
@ -499,7 +497,6 @@ func Test_CustomKey(t *testing.T) {
func Test_CustomExpiration(t *testing.T) { func Test_CustomExpiration(t *testing.T) {
t.Parallel() t.Parallel()
app := fiber.New() app := fiber.New()
var called bool var called bool
var newCacheTime int var newCacheTime int
@ -522,7 +519,7 @@ func Test_CustomExpiration(t *testing.T) {
require.Equal(t, 1, newCacheTime) require.Equal(t, 1, newCacheTime)
// Sleep until the cache is expired // 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)) cachedResp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
require.NoError(t, err) require.NoError(t, err)
@ -713,7 +710,6 @@ func stableAscendingExpiration() func(c1 fiber.Ctx, c2 *Config) time.Duration {
func Test_Cache_MaxBytesOrder(t *testing.T) { func Test_Cache_MaxBytesOrder(t *testing.T) {
t.Parallel() t.Parallel()
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
MaxBytes: 2, MaxBytes: 2,
@ -750,7 +746,6 @@ func Test_Cache_MaxBytesOrder(t *testing.T) {
func Test_Cache_MaxBytesSizes(t *testing.T) { func Test_Cache_MaxBytesSizes(t *testing.T) {
t.Parallel() t.Parallel()
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{

View File

@ -261,7 +261,7 @@ func Test_CSRF_ExpiredToken_WithSession(t *testing.T) {
require.Equal(t, 200, ctx.Response.StatusCode()) require.Equal(t, 200, ctx.Response.StatusCode())
// Wait for the token to expire // Wait for the token to expire
time.Sleep(1 * time.Second) time.Sleep(1*time.Second + 100*time.Millisecond)
// Expired CSRF token // Expired CSRF token
ctx.Request.Reset() ctx.Request.Reset()

View File

@ -82,16 +82,18 @@ func New(config ...Config) fiber.Handler {
} }
} }
// Load icon if provided // Load iconData if provided
var ( var (
err error err error
icon []byte iconData []byte
iconLen string iconLenHeader string
iconLen int
) )
if cfg.Data != nil { if cfg.Data != nil {
// use the provided favicon data // use the provided favicon data
icon = cfg.Data iconData = cfg.Data
iconLen = strconv.Itoa(len(cfg.Data)) iconLenHeader = strconv.Itoa(len(cfg.Data))
iconLen = len(cfg.Data)
} else if cfg.File != "" { } else if cfg.File != "" {
// read from configured filesystem if present // read from configured filesystem if present
if cfg.FileSystem != nil { if cfg.FileSystem != nil {
@ -99,14 +101,15 @@ func New(config ...Config) fiber.Handler {
if err != nil { if err != nil {
panic(err) panic(err)
} }
if icon, err = io.ReadAll(f); err != nil { if iconData, err = io.ReadAll(f); err != nil {
panic(err) panic(err)
} }
} else if icon, err = os.ReadFile(cfg.File); err != nil { } else if iconData, err = os.ReadFile(cfg.File); err != nil {
panic(err) panic(err)
} }
iconLen = strconv.Itoa(len(icon)) iconLenHeader = strconv.Itoa(len(iconData))
iconLen = len(iconData)
} }
// Return new handler // Return new handler
@ -134,11 +137,11 @@ func New(config ...Config) fiber.Handler {
} }
// Serve cached favicon // Serve cached favicon
if len(icon) > 0 { if iconLen > 0 {
c.Set(fiber.HeaderContentLength, iconLen) c.Set(fiber.HeaderContentLength, iconLenHeader)
c.Set(fiber.HeaderContentType, hType) c.Set(fiber.HeaderContentType, hType)
c.Set(fiber.HeaderCacheControl, cfg.CacheControl) 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) return c.SendStatus(fiber.StatusNoContent)

View File

@ -47,7 +47,8 @@ func Test_Middleware_Favicon_Not_Found(t *testing.T) {
t.Parallel() t.Parallel()
defer func() { defer func() {
if err := recover(); err == nil { if err := recover(); err == nil {
t.Fatal("should cache panic") t.Error("should cache panic")
return
} }
}() }()

View File

@ -14,13 +14,13 @@ import (
"github.com/gofiber/fiber/v3/middleware/idempotency" "github.com/gofiber/fiber/v3/middleware/idempotency"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
// go test -run Test_Idempotency // go test -run Test_Idempotency
func Test_Idempotency(t *testing.T) { func Test_Idempotency(t *testing.T) {
t.Parallel() t.Parallel()
app := fiber.New() app := fiber.New()
app.Use(func(c fiber.Ctx) error { app.Use(func(c fiber.Ctx) error {
@ -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. // 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{ app.Use(idempotency.New(idempotency.Config{
Lifetime: lifetime, Lifetime: lifetime,
@ -75,7 +75,7 @@ func Test_Idempotency(t *testing.T) {
}) })
app.Post("/slow", func(c fiber.Ctx) error { app.Post("/slow", func(c fiber.Ctx) error {
time.Sleep(2 * lifetime) time.Sleep(3 * lifetime)
return c.SendString(strconv.Itoa(nextCount())) return c.SendString(strconv.Itoa(nextCount()))
}) })
@ -85,7 +85,7 @@ func Test_Idempotency(t *testing.T) {
if idempotencyKey != "" { if idempotencyKey != "" {
req.Header.Set("X-Idempotency-Key", idempotencyKey) req.Header.Set("X-Idempotency-Key", idempotencyKey)
} }
resp, err := app.Test(req, 3*lifetime) resp, err := app.Test(req, 15*time.Second)
require.NoError(t, err) require.NoError(t, err)
body, err := io.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
require.NoError(t, err) require.NoError(t, err)
@ -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, "9", doReq(fiber.MethodPost, "/", "11111111-1111-1111-1111-111111111111"))
require.Equal(t, "7", doReq(fiber.MethodPost, "/", "00000000-0000-0000-0000-000000000000")) 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"))
require.Equal(t, "10", doReq(fiber.MethodPost, "/", "00000000-0000-0000-0000-000000000000")) require.Equal(t, "10", doReq(fiber.MethodPost, "/", "00000000-0000-0000-0000-000000000000"))
@ -119,13 +119,13 @@ func Test_Idempotency(t *testing.T) {
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() 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() wg.Wait()
require.Equal(t, "11", doReq(fiber.MethodPost, "/slow", "22222222-2222-2222-2222-222222222222")) require.Equal(t, "11", doReq(fiber.MethodPost, "/slow", "22222222-2222-2222-2222-222222222222"))
} }
time.Sleep(2 * lifetime) time.Sleep(3 * lifetime)
require.Equal(t, "12", doReq(fiber.MethodPost, "/slow", "22222222-2222-2222-2222-222222222222")) require.Equal(t, "12", doReq(fiber.MethodPost, "/slow", "22222222-2222-2222-2222-222222222222"))
} }

View File

@ -6,6 +6,7 @@ import (
"github.com/gofiber/fiber/v3/middleware/idempotency" "github.com/gofiber/fiber/v3/middleware/idempotency"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -25,7 +26,7 @@ func Test_MemoryLock(t *testing.T) {
defer close(done) defer close(done)
err := l.Lock("a") err := l.Lock("a")
require.NoError(t, err) assert.NoError(t, err)
}() }()
select { select {

View File

@ -9,6 +9,7 @@ import (
"github.com/gofiber/fiber/v3" "github.com/gofiber/fiber/v3"
"github.com/gofiber/fiber/v3/internal/storage/memory" "github.com/gofiber/fiber/v3/internal/storage/memory"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
) )
@ -16,8 +17,6 @@ import (
// go test -run Test_Limiter_Concurrency_Store -race -v // go test -run Test_Limiter_Concurrency_Store -race -v
func Test_Limiter_Concurrency_Store(t *testing.T) { func Test_Limiter_Concurrency_Store(t *testing.T) {
t.Parallel() t.Parallel()
// Test concurrency using a custom store
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
@ -31,20 +30,19 @@ func Test_Limiter_Concurrency_Store(t *testing.T) {
}) })
var wg sync.WaitGroup 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++ { for i := 0; i <= 49; i++ {
wg.Add(1) 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() wg.Wait()
@ -63,8 +61,6 @@ func Test_Limiter_Concurrency_Store(t *testing.T) {
// go test -run Test_Limiter_Concurrency -race -v // go test -run Test_Limiter_Concurrency -race -v
func Test_Limiter_Concurrency(t *testing.T) { func Test_Limiter_Concurrency(t *testing.T) {
t.Parallel() t.Parallel()
// Test concurrency using a default store
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
@ -77,20 +73,19 @@ func Test_Limiter_Concurrency(t *testing.T) {
}) })
var wg sync.WaitGroup 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++ { for i := 0; i <= 49; i++ {
wg.Add(1) 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() wg.Wait()
@ -421,8 +416,6 @@ func Test_Limiter_Sliding_Window_Custom_Storage_Skip_Failed_Requests(t *testing.
// go test -run Test_Limiter_Fixed_Window_Skip_Successful_Requests -v // go test -run Test_Limiter_Fixed_Window_Skip_Successful_Requests -v
func Test_Limiter_Fixed_Window_Skip_Successful_Requests(t *testing.T) { func Test_Limiter_Fixed_Window_Skip_Successful_Requests(t *testing.T) {
t.Parallel() t.Parallel()
// Test concurrency using a default store
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
@ -461,8 +454,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 // 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) { func Test_Limiter_Fixed_Window_Custom_Storage_Skip_Successful_Requests(t *testing.T) {
t.Parallel() t.Parallel()
// Test concurrency using a default store
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
@ -502,8 +493,6 @@ func Test_Limiter_Fixed_Window_Custom_Storage_Skip_Successful_Requests(t *testin
// go test -run Test_Limiter_Sliding_Window_Skip_Successful_Requests -v // go test -run Test_Limiter_Sliding_Window_Skip_Successful_Requests -v
func Test_Limiter_Sliding_Window_Skip_Successful_Requests(t *testing.T) { func Test_Limiter_Sliding_Window_Skip_Successful_Requests(t *testing.T) {
t.Parallel() t.Parallel()
// Test concurrency using a default store
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
@ -542,8 +531,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 // 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) { func Test_Limiter_Sliding_Window_Custom_Storage_Skip_Successful_Requests(t *testing.T) {
t.Parallel() t.Parallel()
// Test concurrency using a default store
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
@ -682,7 +669,7 @@ func Test_Sliding_Window(t *testing.T) {
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
Max: 10, Max: 10,
Expiration: 2 * time.Second, Expiration: 1 * time.Second,
Storage: memory.New(), Storage: memory.New(),
LimiterMiddleware: SlidingWindow{}, LimiterMiddleware: SlidingWindow{},
})) }))
@ -706,7 +693,7 @@ func Test_Sliding_Window(t *testing.T) {
singleRequest(false) singleRequest(false)
} }
time.Sleep(2 * time.Second) time.Sleep(3 * time.Second)
for i := 0; i < 5; i++ { for i := 0; i < 5; i++ {
singleRequest(false) singleRequest(false)
@ -718,9 +705,14 @@ func Test_Sliding_Window(t *testing.T) {
singleRequest(false) 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) singleRequest(false)
} }
// requests should fail now
for i := 0; i < 5; i++ {
singleRequest(true)
}
} }

View File

@ -95,6 +95,7 @@ func Test_Logger_locals(t *testing.T) {
func Test_Logger_Next(t *testing.T) { func Test_Logger_Next(t *testing.T) {
t.Parallel() t.Parallel()
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
Next: func(_ fiber.Ctx) bool { Next: func(_ fiber.Ctx) bool {
return true return true
@ -111,6 +112,7 @@ func Test_Logger_Done(t *testing.T) {
t.Parallel() t.Parallel()
buf := bytes.NewBuffer(nil) buf := bytes.NewBuffer(nil)
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
Done: func(c fiber.Ctx, logString []byte) { Done: func(c fiber.Ctx, logString []byte) {
if c.Response().StatusCode() == fiber.StatusOK { if c.Response().StatusCode() == fiber.StatusOK {
@ -133,6 +135,7 @@ func Test_Logger_Done(t *testing.T) {
func Test_Logger_ErrorTimeZone(t *testing.T) { func Test_Logger_ErrorTimeZone(t *testing.T) {
t.Parallel() t.Parallel()
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
TimeZone: "invalid", TimeZone: "invalid",
})) }))
@ -154,6 +157,7 @@ func Test_Logger_ErrorOutput_WithoutColor(t *testing.T) {
t.Parallel() t.Parallel()
o := new(fakeErrorOutput) o := new(fakeErrorOutput)
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
Output: o, Output: o,
DisableColors: true, DisableColors: true,
@ -170,6 +174,7 @@ func Test_Logger_ErrorOutput(t *testing.T) {
t.Parallel() t.Parallel()
o := new(fakeErrorOutput) o := new(fakeErrorOutput)
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
Output: o, Output: o,
})) }))
@ -187,6 +192,7 @@ func Test_Logger_All(t *testing.T) {
defer bytebufferpool.Put(buf) defer bytebufferpool.Put(buf)
app := fiber.New() app := fiber.New()
app.Use(New(Config{ 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}", 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, Output: buf,
@ -230,10 +236,10 @@ func getLatencyTimeUnits() []struct {
// go test -run Test_Logger_WithLatency // go test -run Test_Logger_WithLatency
func Test_Logger_WithLatency(t *testing.T) { func Test_Logger_WithLatency(t *testing.T) {
t.Parallel()
buff := bytebufferpool.Get() buff := bytebufferpool.Get()
defer bytebufferpool.Put(buff) defer bytebufferpool.Put(buff)
app := fiber.New() app := fiber.New()
logger := New(Config{ logger := New(Config{
Output: buff, Output: buff,
Format: "${latency}", Format: "${latency}",
@ -258,7 +264,7 @@ func Test_Logger_WithLatency(t *testing.T) {
sleepDuration = 1 * tu.div sleepDuration = 1 * tu.div
// Create a new HTTP request to the test route // 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.NoError(t, err)
require.Equal(t, fiber.StatusOK, resp.StatusCode) require.Equal(t, fiber.StatusOK, resp.StatusCode)
@ -273,10 +279,10 @@ func Test_Logger_WithLatency(t *testing.T) {
// go test -run Test_Logger_WithLatency_DefaultFormat // go test -run Test_Logger_WithLatency_DefaultFormat
func Test_Logger_WithLatency_DefaultFormat(t *testing.T) { func Test_Logger_WithLatency_DefaultFormat(t *testing.T) {
t.Parallel()
buff := bytebufferpool.Get() buff := bytebufferpool.Get()
defer bytebufferpool.Put(buff) defer bytebufferpool.Put(buff)
app := fiber.New() app := fiber.New()
logger := New(Config{ logger := New(Config{
Output: buff, Output: buff,
}) })
@ -323,6 +329,7 @@ func Test_Query_Params(t *testing.T) {
defer bytebufferpool.Put(buf) defer bytebufferpool.Put(buf)
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
Format: "${queryParams}", Format: "${queryParams}",
Output: buf, Output: buf,
@ -343,6 +350,7 @@ func Test_Response_Body(t *testing.T) {
defer bytebufferpool.Put(buf) defer bytebufferpool.Put(buf)
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
Format: "${resBody}", Format: "${resBody}",
Output: buf, Output: buf,
@ -496,6 +504,7 @@ func Test_Response_Header(t *testing.T) {
defer bytebufferpool.Put(buf) defer bytebufferpool.Put(buf)
app := fiber.New() app := fiber.New()
app.Use(requestid.New(requestid.Config{ app.Use(requestid.New(requestid.Config{
Next: nil, Next: nil,
Header: fiber.HeaderXRequestID, Header: fiber.HeaderXRequestID,
@ -523,6 +532,7 @@ func Test_Req_Header(t *testing.T) {
defer bytebufferpool.Put(buf) defer bytebufferpool.Put(buf)
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
Format: "${reqHeader:test}", Format: "${reqHeader:test}",
Output: buf, Output: buf,
@ -546,6 +556,7 @@ func Test_ReqHeader_Header(t *testing.T) {
defer bytebufferpool.Put(buf) defer bytebufferpool.Put(buf)
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
Format: "${reqHeader:test}", Format: "${reqHeader:test}",
Output: buf, Output: buf,
@ -571,6 +582,7 @@ func Test_CustomTags(t *testing.T) {
defer bytebufferpool.Put(buf) defer bytebufferpool.Put(buf)
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
Format: "${custom_tag}", Format: "${custom_tag}",
CustomTags: map[string]LogFunc{ CustomTags: map[string]LogFunc{
@ -644,6 +656,7 @@ func Test_Logger_EnableColors(t *testing.T) {
t.Parallel() t.Parallel()
o := new(fakeOutput) o := new(fakeOutput)
app := fiber.New() app := fiber.New()
app.Use(New(Config{ app.Use(New(Config{
Output: o, Output: o,
})) }))

View File

@ -18,6 +18,17 @@ import (
"github.com/valyala/fasthttp" "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)
}
}()
}
func createProxyTestServer(t *testing.T, handler fiber.Handler) (*fiber.App, string) { func createProxyTestServer(t *testing.T, handler fiber.Handler) (*fiber.App, string) {
t.Helper() t.Helper()
@ -27,15 +38,10 @@ func createProxyTestServer(t *testing.T, handler fiber.Handler) (*fiber.App, str
ln, err := net.Listen(fiber.NetworkTCP4, "127.0.0.1:0") ln, err := net.Listen(fiber.NetworkTCP4, "127.0.0.1:0")
require.NoError(t, err) require.NoError(t, err)
go func() {
require.NoError(t, target.Listener(ln, fiber.ListenConfig{
DisableStartupMessage: true,
}))
}()
time.Sleep(2 * time.Second)
addr := ln.Addr().String() addr := ln.Addr().String()
startServer(target, ln)
return target, addr return target, addr
} }
@ -45,7 +51,9 @@ func Test_Proxy_Empty_Upstream_Servers(t *testing.T) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
require.Equal(t, "Servers cannot be empty", r) if r != "Servers cannot be empty" {
panic(r)
}
} }
}() }()
app := fiber.New() app := fiber.New()
@ -58,7 +66,9 @@ func Test_Proxy_Empty_Config(t *testing.T) {
defer func() { defer func() {
if r := recover(); r != nil { if r := recover(); r != nil {
require.Equal(t, "Servers cannot be empty", r) if r != "Servers cannot be empty" {
panic(r)
}
} }
}() }()
app := fiber.New() app := fiber.New()
@ -132,11 +142,7 @@ func Test_Proxy_Balancer_WithTlsConfig(t *testing.T) {
TlsConfig: clientTLSConf, TlsConfig: clientTLSConf,
})) }))
go func() { startServer(app, ln)
require.NoError(t, app.Listener(ln, fiber.ListenConfig{
DisableStartupMessage: true,
}))
}()
client := clientpkg.New() client := clientpkg.New()
client.SetTLSConfig(clientTLSConf) client.SetTLSConfig(clientTLSConf)
@ -163,18 +169,11 @@ func Test_Proxy_Forward_WithTlsConfig_To_Http(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
proxyServerLn = tls.NewListener(proxyServerLn, proxyServerTLSConf) proxyServerLn = tls.NewListener(proxyServerLn, proxyServerTLSConf)
app := fiber.New()
proxyAddr := proxyServerLn.Addr().String() proxyAddr := proxyServerLn.Addr().String()
app := fiber.New()
app.Use(Forward("http://" + targetAddr)) app.Use(Forward("http://" + targetAddr))
startServer(app, proxyServerLn)
go func() {
require.NoError(t, app.Listener(proxyServerLn, fiber.ListenConfig{
DisableStartupMessage: true,
}))
}()
client := clientpkg.New() client := clientpkg.New()
client.SetTimeout(5 * time.Second) client.SetTimeout(5 * time.Second)
@ -235,11 +234,7 @@ func Test_Proxy_Forward_WithClient_TLSConfig(t *testing.T) {
}) })
app.Use(Forward("https://" + addr + "/tlsfwd")) app.Use(Forward("https://" + addr + "/tlsfwd"))
go func() { startServer(app, ln)
require.NoError(t, app.Listener(ln, fiber.ListenConfig{
DisableStartupMessage: true,
}))
}()
client := clientpkg.New() client := clientpkg.New()
client.SetTLSConfig(clientTLSConf) client.SetTLSConfig(clientTLSConf)
@ -441,7 +436,7 @@ func Test_Proxy_DoRedirects_RestoreOriginalURL(t *testing.T) {
return DoRedirects(c, "http://google.com", 1) 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) require.NoError(t, err1)
_, err := io.ReadAll(resp.Body) _, err := io.ReadAll(resp.Body)
require.NoError(t, err) require.NoError(t, err)
@ -479,7 +474,7 @@ func Test_Proxy_DoTimeout_RestoreOriginalURL(t *testing.T) {
return DoTimeout(c, "http://"+addr, time.Second) 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) require.NoError(t, err1)
body, err := io.ReadAll(resp.Body) body, err := io.ReadAll(resp.Body)
require.NoError(t, err) require.NoError(t, err)
@ -490,8 +485,6 @@ func Test_Proxy_DoTimeout_RestoreOriginalURL(t *testing.T) {
// go test -race -run Test_Proxy_DoTimeout_Timeout // go test -race -run Test_Proxy_DoTimeout_Timeout
func Test_Proxy_DoTimeout_Timeout(t *testing.T) { func Test_Proxy_DoTimeout_Timeout(t *testing.T) {
t.Parallel()
_, addr := createProxyTestServer(t, func(c fiber.Ctx) error { _, addr := createProxyTestServer(t, func(c fiber.Ctx) error {
time.Sleep(time.Second * 5) time.Sleep(time.Second * 5)
return c.SendString("proxied") return c.SendString("proxied")
@ -502,8 +495,14 @@ func Test_Proxy_DoTimeout_Timeout(t *testing.T) {
return DoTimeout(c, "http://"+addr, time.Second) return DoTimeout(c, "http://"+addr, time.Second)
}) })
_, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 1*time.Second) resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 2*time.Second)
require.Equal(t, errors.New("test: timeout error after 1s"), err1) 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 // go test -race -run Test_Proxy_DoDeadline_RestoreOriginalURL
@ -530,8 +529,6 @@ func Test_Proxy_DoDeadline_RestoreOriginalURL(t *testing.T) {
// go test -race -run Test_Proxy_DoDeadline_PastDeadline // go test -race -run Test_Proxy_DoDeadline_PastDeadline
func Test_Proxy_DoDeadline_PastDeadline(t *testing.T) { func Test_Proxy_DoDeadline_PastDeadline(t *testing.T) {
t.Parallel()
_, addr := createProxyTestServer(t, func(c fiber.Ctx) error { _, addr := createProxyTestServer(t, func(c fiber.Ctx) error {
time.Sleep(time.Second * 5) time.Sleep(time.Second * 5)
return c.SendString("proxied") return c.SendString("proxied")
@ -539,7 +536,7 @@ func Test_Proxy_DoDeadline_PastDeadline(t *testing.T) {
app := fiber.New() app := fiber.New()
app.Get("/test", func(c fiber.Ctx) error { 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), 1*time.Second) _, err1 := app.Test(httptest.NewRequest(fiber.MethodGet, "/test", nil), 1*time.Second)
@ -590,14 +587,9 @@ func Test_Proxy_Forward_Global_Client(t *testing.T) {
addr := ln.Addr().String() addr := ln.Addr().String()
app.Use(Forward("http://" + addr + "/test_global_client")) app.Use(Forward("http://" + addr + "/test_global_client"))
go func() { startServer(app, ln)
require.NoError(t, app.Listener(ln, fiber.ListenConfig{
DisableStartupMessage: true,
}))
}()
client := clientpkg.New() client := clientpkg.New()
resp, err := client.Get("http://" + addr) resp, err := client.Get("http://" + addr)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, fiber.StatusOK, resp.StatusCode()) require.Equal(t, fiber.StatusOK, resp.StatusCode())
@ -622,14 +614,9 @@ func Test_Proxy_Forward_Local_Client(t *testing.T) {
Dial: fasthttp.Dial, Dial: fasthttp.Dial,
})) }))
go func() { startServer(app, ln)
require.NoError(t, app.Listener(ln, fiber.ListenConfig{
DisableStartupMessage: true,
}))
}()
client := clientpkg.New() client := clientpkg.New()
resp, err := client.Get("http://" + addr) resp, err := client.Get("http://" + addr)
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, fiber.StatusOK, resp.StatusCode()) require.Equal(t, fiber.StatusOK, resp.StatusCode())
@ -694,20 +681,10 @@ func Test_Proxy_Domain_Forward_Local(t *testing.T) {
Dial: fasthttp.Dial, Dial: fasthttp.Dial,
})) }))
startServer(app, ln)
go func() { startServer(app1, ln1)
require.NoError(t, app.Listener(ln, fiber.ListenConfig{
DisableStartupMessage: true,
}))
}()
go func() {
require.NoError(t, app1.Listener(ln1, fiber.ListenConfig{
DisableStartupMessage: true,
}))
}()
client := clientpkg.New() client := clientpkg.New()
resp, err := client.Get("http://" + localDomain + "/test?query_test=true") resp, err := client.Get("http://" + localDomain + "/test?query_test=true")
require.NoError(t, err) require.NoError(t, err)
require.Equal(t, fiber.StatusOK, resp.StatusCode()) require.Equal(t, fiber.StatusOK, resp.StatusCode())

View File

@ -346,8 +346,9 @@ func Test_Session_Save_Expiration(t *testing.T) {
t.Parallel() t.Parallel()
t.Run("save to cookie", func(t *testing.T) { t.Run("save to cookie", func(t *testing.T) {
const sessionDuration = 5 * time.Second
t.Parallel() t.Parallel()
const sessionDuration = 5 * time.Second
// session store // session store
store := New() store := New()
// fiber instance // fiber instance
@ -634,36 +635,158 @@ func Test_Session_Regenerate(t *testing.T) {
// go test -v -run=^$ -bench=Benchmark_Session -benchmem -count=4 // go test -v -run=^$ -bench=Benchmark_Session -benchmem -count=4
func Benchmark_Session(b *testing.B) { 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) { 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.ReportAllocs()
b.ResetTimer() b.ResetTimer()
for n := 0; n < b.N; n++ { for n := 0; n < b.N; n++ {
sess, _ := store.Get(c) //nolint:errcheck // We're inside a benchmark sess, _ := store.Get(c) //nolint:errcheck // We're inside a benchmark
sess.Set("john", "doe") 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) { 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(), Storage: memory.New(),
}) })
b.ReportAllocs() b.ReportAllocs()
b.ResetTimer() b.ResetTimer()
for n := 0; n < b.N; n++ { b.RunParallel(func(pb *testing.PB) {
sess, _ := store.Get(c) //nolint:errcheck // We're inside a benchmark for pb.Next() {
sess.Set("john", "doe") c := app.AcquireCtx(&fasthttp.RequestCtx{})
err = sess.Save() c.Request().Header.SetCookie(store.sessionName, "12356789")
}
require.NoError(b, err) 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)
}
})
})
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)
}
})
}) })
} }

View File

@ -399,6 +399,7 @@ func Test_App_UseMountedErrorHandlerForBestPrefixMatch(t *testing.T) {
// go test -run Test_Mount_Route_Names // go test -run Test_Mount_Route_Names
func Test_Mount_Route_Names(t *testing.T) { func Test_Mount_Route_Names(t *testing.T) {
t.Parallel()
// create sub-app with 2 handlers: // create sub-app with 2 handlers:
subApp1 := New() subApp1 := New()
subApp1.Get("/users", func(c Ctx) error { subApp1.Get("/users", func(c Ctx) error {

View File

@ -11,6 +11,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
) )
@ -28,7 +29,7 @@ func Test_App_Prefork_Child_Process(t *testing.T) {
go func() { go func() {
time.Sleep(1000 * time.Millisecond) 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})) 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() { go func() {
time.Sleep(1000 * time.Millisecond) 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())) 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() { go func() {
time.Sleep(1000 * time.Millisecond) time.Sleep(1000 * time.Millisecond)
require.NoError(t, app.Shutdown()) assert.NoError(t, app.Shutdown())
}() }()
require.NoError(t, app.prefork(":3000", nil, listenConfigDefault())) require.NoError(t, app.prefork(":3000", nil, listenConfigDefault()))

View File

@ -12,6 +12,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require" "github.com/stretchr/testify/require"
"github.com/valyala/fasthttp" "github.com/valyala/fasthttp"
"github.com/valyala/fasthttp/fasthttputil" "github.com/valyala/fasthttp/fasthttputil"
@ -249,7 +250,6 @@ func Test_Redirect_setFlash(t *testing.T) {
// go test -run Test_Redirect_Request // go test -run Test_Redirect_Request
func Test_Redirect_Request(t *testing.T) { func Test_Redirect_Request(t *testing.T) {
t.Parallel() t.Parallel()
app := New() app := New()
app.Get("/", func(c Ctx) error { app.Get("/", func(c Ctx) error {
@ -282,7 +282,7 @@ func Test_Redirect_Request(t *testing.T) {
GracefulContext: ctx, GracefulContext: ctx,
}) })
require.NoError(t, err) assert.NoError(t, err)
}() }()
// Test cases // Test cases

View File

@ -455,6 +455,7 @@ func Test_Route_Static_HasPrefix(t *testing.T) {
} }
func Test_Router_NotFound(t *testing.T) { func Test_Router_NotFound(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Use(func(c Ctx) error { app.Use(func(c Ctx) error {
return c.Next() return c.Next()
@ -472,6 +473,7 @@ func Test_Router_NotFound(t *testing.T) {
} }
func Test_Router_NotFound_HTML_Inject(t *testing.T) { func Test_Router_NotFound_HTML_Inject(t *testing.T) {
t.Parallel()
app := New() app := New()
app.Use(func(c Ctx) error { app.Use(func(c Ctx) error {
return c.Next() return c.Next()