From 62b099879a57927b0fe60ffa83a4f6d61b420bb6 Mon Sep 17 00:00:00 2001 From: RW Date: Thu, 3 Apr 2025 13:36:30 +0200 Subject: [PATCH] =?UTF-8?q?=F0=9F=A7=AA=20fix:=20Logger=20Middleware=20tes?= =?UTF-8?q?ts=20to=20use=20regex=20for=20time=20validation=20(#3392)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * test: rewrite logger format tests to use regex for time validation * test: rewrite logger format tests to use regex for time validation --- middleware/logger/logger_test.go | 107 ++++++++++++++----------------- 1 file changed, 49 insertions(+), 58 deletions(-) diff --git a/middleware/logger/logger_test.go b/middleware/logger/logger_test.go index edce174c..915480d4 100644 --- a/middleware/logger/logger_test.go +++ b/middleware/logger/logger_test.go @@ -11,6 +11,7 @@ import ( "net/http" "net/http/httptest" "os" + "regexp" "runtime" "strconv" "sync" @@ -25,6 +26,11 @@ import ( "github.com/valyala/fasthttp" ) +const ( + pathFooBar = "/?foo=bar" + httpProto = "HTTP/1.1" +) + func benchmarkSetup(b *testing.B, app *fiber.App, uri string) { b.Helper() @@ -459,7 +465,7 @@ func Test_Logger_All(t *testing.T) { // Alias colors colors := app.Config().ColorScheme - resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil)) + resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, pathFooBar, nil)) require.NoError(t, err) require.Equal(t, fiber.StatusNotFound, resp.StatusCode) @@ -473,23 +479,21 @@ func Test_Logger_CLF_Format(t *testing.T) { defer bytebufferpool.Put(buf) app := fiber.New() - app.Use(New(Config{ Format: CommonFormat, Stream: buf, })) - resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil)) - require.NoError(t, err) - require.Equal(t, fiber.StatusNotFound, resp.StatusCode) + method := fiber.MethodGet + status := fiber.StatusNotFound + bytesSent := 0 - expected := fmt.Sprintf("0.0.0.0 - - [%s] \"%s %s %s\" %d %d\n", - time.Now().Format("15:04:05"), - fiber.MethodGet, "/?foo=bar", "HTTP/1.1", - fiber.StatusNotFound, - 0) - logResponse := buf.String() - require.Equal(t, expected, logResponse) + resp, err := app.Test(httptest.NewRequest(method, pathFooBar, nil)) + require.NoError(t, err) + require.Equal(t, status, resp.StatusCode) + + pattern := fmt.Sprintf(`0\.0\.0\.0 - - \[\d{2}:\d{2}:\d{2}\] "%s %s %s" %d %d`, method, regexp.QuoteMeta(pathFooBar), httpProto, status, bytesSent) + require.Regexp(t, pattern, buf.String()) } func Test_Logger_Combined_CLF_Format(t *testing.T) { @@ -498,29 +502,27 @@ func Test_Logger_Combined_CLF_Format(t *testing.T) { defer bytebufferpool.Put(buf) app := fiber.New() - app.Use(New(Config{ Format: CombinedFormat, Stream: buf, })) - const expectedUA = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" - const expectedReferer = "http://example.com" - req := httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil) - req.Header.Set("Referer", expectedReferer) - req.Header.Set("User-Agent", expectedUA) + + method := fiber.MethodGet + status := fiber.StatusNotFound + bytesSent := 0 + referer := "http://example.com" + ua := "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3729.169 Safari/537.36" + + req := httptest.NewRequest(method, pathFooBar, nil) + req.Header.Set("Referer", referer) + req.Header.Set("User-Agent", ua) + resp, err := app.Test(req) require.NoError(t, err) - require.Equal(t, fiber.StatusNotFound, resp.StatusCode) + require.Equal(t, status, resp.StatusCode) - expected := fmt.Sprintf("0.0.0.0 - - [%s] %q %d %d %q %q\n", - time.Now().Format("15:04:05"), - fmt.Sprintf("%s %s %s", fiber.MethodGet, "/?foo=bar", "HTTP/1.1"), - fiber.StatusNotFound, - 0, - expectedReferer, - expectedUA) - logResponse := buf.String() - require.Equal(t, expected, logResponse) + pattern := fmt.Sprintf(`0\.0\.0\.0 - - \[\d{2}:\d{2}:\d{2}\] "%s %s %s" %d %d "%s" "%s"`, method, regexp.QuoteMeta(pathFooBar), httpProto, status, bytesSent, regexp.QuoteMeta(referer), regexp.QuoteMeta(ua)) //nolint:gocritic // double quoting for regex and string is not needed + require.Regexp(t, pattern, buf.String()) } func Test_Logger_Json_Format(t *testing.T) { @@ -529,28 +531,23 @@ func Test_Logger_Json_Format(t *testing.T) { defer bytebufferpool.Put(buf) app := fiber.New() - app.Use(New(Config{ Format: JSONFormat, Stream: buf, })) - req := httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil) + method := fiber.MethodGet + status := fiber.StatusNotFound + ip := "0.0.0.0" + bytesSent := 0 + + req := httptest.NewRequest(method, pathFooBar, nil) resp, err := app.Test(req) require.NoError(t, err) - require.Equal(t, fiber.StatusNotFound, resp.StatusCode) + require.Equal(t, status, resp.StatusCode) - expected := fmt.Sprintf( - "{\"time\":%q,\"ip\":%q,\"method\":%q,\"url\":%q,\"status\":%d,\"bytesSent\":%d}\n", - time.Now().Format("15:04:05"), - "0.0.0.0", - fiber.MethodGet, - "/?foo=bar", - fiber.StatusNotFound, - 0, - ) - logResponse := buf.String() - require.Equal(t, expected, logResponse) + pattern := fmt.Sprintf(`\{"time":"\d{2}:\d{2}:\d{2}","ip":"%s","method":%q,"url":"%s","status":%d,"bytesSent":%d\}`, regexp.QuoteMeta(ip), method, regexp.QuoteMeta(pathFooBar), status, bytesSent) //nolint:gocritic // double quoting for regex and string is not needed + require.Regexp(t, pattern, buf.String()) } func Test_Logger_ECS_Format(t *testing.T) { @@ -559,30 +556,24 @@ func Test_Logger_ECS_Format(t *testing.T) { defer bytebufferpool.Put(buf) app := fiber.New() - app.Use(New(Config{ Format: ECSFormat, Stream: buf, })) - req := httptest.NewRequest(fiber.MethodGet, "/?foo=bar", nil) + method := fiber.MethodGet + status := fiber.StatusNotFound + ip := "0.0.0.0" + bytesSent := 0 + msg := fmt.Sprintf("%s %s responded with %d", method, pathFooBar, status) + + req := httptest.NewRequest(method, pathFooBar, nil) resp, err := app.Test(req) require.NoError(t, err) - require.Equal(t, fiber.StatusNotFound, resp.StatusCode) + require.Equal(t, status, resp.StatusCode) - expected := fmt.Sprintf( - "{\"@timestamp\":%q,\"ecs\":{\"version\":\"1.6.0\"},\"client\":{\"ip\":%q},\"http\":{\"request\":{\"method\":%q,\"url\":%q,\"protocol\":%q},\"response\":{\"status_code\":%d,\"body\":{\"bytes\":%d}}},\"log\":{\"level\":\"INFO\",\"logger\":\"fiber\"},\"message\":%q}\n", - time.Now().Format("15:04:05"), - "0.0.0.0", - fiber.MethodGet, - "/?foo=bar", - "HTTP/1.1", - fiber.StatusNotFound, - 0, - fmt.Sprintf("%s %s responded with %d", fiber.MethodGet, "/?foo=bar", fiber.StatusNotFound), - ) - logResponse := buf.String() - require.Equal(t, expected, logResponse) + pattern := fmt.Sprintf(`\{"@timestamp":"\d{2}:\d{2}:\d{2}","ecs":\{"version":"1.6.0"\},"client":\{"ip":"%s"\},"http":\{"request":\{"method":%q,"url":"%s","protocol":%q\},"response":\{"status_code":%d,"body":\{"bytes":%d\}\}\},"log":\{"level":"INFO","logger":"fiber"\},"message":"%s"\}`, regexp.QuoteMeta(ip), method, regexp.QuoteMeta(pathFooBar), httpProto, status, bytesSent, regexp.QuoteMeta(msg)) //nolint:gocritic // double quoting for regex and string is not needed + require.Regexp(t, pattern, buf.String()) } func getLatencyTimeUnits() []struct {