From 417007878182afca8729cce352dd6309a10af796 Mon Sep 17 00:00:00 2001 From: Volodymyr Komarov Date: Sun, 26 Nov 2023 11:14:06 +0200 Subject: [PATCH 1/2] Add logger tests --- logger/log_test.go | 133 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 133 insertions(+) create mode 100644 logger/log_test.go diff --git a/logger/log_test.go b/logger/log_test.go new file mode 100644 index 0000000..df004dc --- /dev/null +++ b/logger/log_test.go @@ -0,0 +1,133 @@ +package logger + +import ( + "bytes" + "fmt" + "log" + "net" + "testing" + + "github.com/cash-track/gateway/config" + "github.com/stretchr/testify/assert" + "github.com/valyala/fasthttp" +) + +func TestDebugRequest(t *testing.T) { + var output bytes.Buffer + log.SetOutput(&output) + + config.Global.DebugHttp = false + + req := fasthttp.Request{} + req.Header.Set("Host", "127.0.0.1") + + DebugRequest(&req, "API") + + logs := output.String() + + assert.NotContains(t, logs, "DEBUG REQ API") + assert.NotContains(t, logs, "127.0.0.1") + + config.Global.DebugHttp = true + + DebugRequest(&req, "API") + + logs = output.String() + + assert.Contains(t, logs, "DEBUG REQ API") + assert.Contains(t, logs, "127.0.0.1") + +} + +func TestDebugResponse(t *testing.T) { + var output bytes.Buffer + log.SetOutput(&output) + + config.Global.DebugHttp = false + + resp := fasthttp.Response{} + resp.Header.Set("Host", "127.0.0.1") + + DebugResponse(&resp, "API") + + logs := output.String() + + assert.NotContains(t, logs, "DEBUG RESP API") + assert.NotContains(t, logs, "127.0.0.1") + + config.Global.DebugHttp = true + + DebugResponse(&resp, "API") + + logs = output.String() + + assert.Contains(t, logs, "DEBUG RESP API") + assert.Contains(t, logs, "127.0.0.1") + +} + +func TestDebugHandler(t *testing.T) { + var output bytes.Buffer + log.SetOutput(&output) + config.Global.DebugHttp = true + + ctx := fasthttp.RequestCtx{} + ctx.Request.Header.Set("Host", "127.0.0.1") + ctx.Response.Header.Set("Host", "127.0.0.2") + + h := DebugHandler(func(ctx *fasthttp.RequestCtx) {}) + h(&ctx) + + logs := output.String() + + assert.Contains(t, logs, "DEBUG REQ") + assert.Contains(t, logs, "127.0.0.1") + assert.Contains(t, logs, "127.0.0.2") +} + +func TestDebugHandlerIgnorePath(t *testing.T) { + var output bytes.Buffer + log.SetOutput(&output) + config.Global.DebugHttp = true + + ctx := fasthttp.RequestCtx{} + ctx.Request.URI().SetPath("/live") + ctx.Request.Header.Set("Host", "127.0.0.1") + ctx.Response.Header.Set("Host", "127.0.0.2") + + h := DebugHandler(func(ctx *fasthttp.RequestCtx) {}) + h(&ctx) + + logs := output.String() + + assert.NotContains(t, logs, "DEBUG REQ") + assert.NotContains(t, logs, "127.0.0.1") + assert.NotContains(t, logs, "127.0.0.2") +} + +func TestFullForwarded(t *testing.T) { + var output bytes.Buffer + log.SetOutput(&output) + config.Global.DebugHttp = true + + ctx := fasthttp.RequestCtx{} + ctx.SetRemoteAddr(&net.TCPAddr{IP: []byte{0xA, 0x0, 0x0, 0x1}}) + + req := fasthttp.Request{} + req.Header.SetMethod(fasthttp.MethodPost) + req.SetRequestURI("/test?one=two%203") + req.SetBody([]byte("123")) + + resp := fasthttp.Response{} + resp.SetStatusCode(fasthttp.StatusBadRequest) + resp.SetBody([]byte("4567")) + + FullForwarded(&ctx, &req, &resp, "API") + + logs := output.String() + + fmt.Print(logs) + + assert.Contains(t, logs, "[10.0.0.1] POST /test?one=two%203 (body 3b) => API resp 400 (4b)") + +} From ab6a0d7b097df575662534516a65897598c65f59 Mon Sep 17 00:00:00 2001 From: Volodymyr Komarov Date: Thu, 14 Dec 2023 22:49:47 +0200 Subject: [PATCH 2/2] Add logger tests --- main.go | 23 ++++++++++++----- router/api/client/client_test.go | 43 +++++++++++++++++++++++++++++++ router/api/client/forward_test.go | 42 ++++++++++++++++++++++++++++++ router/router_test.go | 28 ++++++++++++++++++++ 4 files changed, 130 insertions(+), 6 deletions(-) create mode 100644 router/api/client/client_test.go create mode 100644 router/api/client/forward_test.go create mode 100644 router/router_test.go diff --git a/main.go b/main.go index 5b6eff3..76d45c4 100644 --- a/main.go +++ b/main.go @@ -12,6 +12,11 @@ import ( "github.com/cash-track/gateway/router" ) +const ( + readBufferSize = 1024 * 8 + writeBufferSize = 1024 * 8 +) + func main() { config.Global.Load() @@ -25,25 +30,31 @@ func main() { h = fasthttp.CompressHandler(h) } + s := &fasthttp.Server{ + Handler: h, + ReadBufferSize: readBufferSize, + WriteBufferSize: writeBufferSize, + } + if config.Global.HttpsEnabled { - startTls(h) + startTls(s) } else { - start(h) + start(s) } } -func start(h fasthttp.RequestHandler) { +func start(s *fasthttp.Server) { log.Printf("Listening on HTTP %s", config.Global.Address) - if err := fasthttp.ListenAndServe(config.Global.Address, h); err != nil { + if err := s.ListenAndServe(config.Global.Address); err != nil { log.Fatalf("Error in HTTP server: %v", err) } } -func startTls(h fasthttp.RequestHandler) { +func startTls(s *fasthttp.Server) { log.Printf("Listening on HTTPS %s", config.Global.Address) - if err := fasthttp.ListenAndServeTLS(config.Global.Address, config.Global.HttpsCrt, config.Global.HttpsKey, h); err != nil { + if err := s.ListenAndServeTLS(config.Global.Address, config.Global.HttpsCrt, config.Global.HttpsKey); err != nil { log.Fatalf("Error in HTTPS server: %v", err) } } diff --git a/router/api/client/client_test.go b/router/api/client/client_test.go new file mode 100644 index 0000000..6b69185 --- /dev/null +++ b/router/api/client/client_test.go @@ -0,0 +1,43 @@ +package client + +import ( + "net/url" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/valyala/fasthttp" + + "github.com/cash-track/gateway/config" +) + +func TestNewClient(t *testing.T) { + NewClient() + + assert.NotNil(t, client) + assert.True(t, client.NoDefaultUserAgentHeader) + assert.True(t, client.DisableHeaderNamesNormalizing) + assert.True(t, client.DisablePathNormalizing) +} + +func TestSetRequestURI(t *testing.T) { + config.Global.ApiURI, _ = url.Parse("http://api.test.com") + + uri := fasthttp.URI{} + + setRequestURI(&uri, []byte("/users/create one")) + + assert.Equal(t, "http://api.test.com/users/create%20one", uri.String()) +} + +func TestCopyRequestURI(t *testing.T) { + config.Global.ApiURI, _ = url.Parse("http://api.test.com") + + src := fasthttp.URI{} + src.SetPath("/api/users/create one") + src.SetQueryString("one=two%203") + dest := fasthttp.URI{} + + copyRequestURI(&src, &dest) + + assert.Equal(t, "http://api.test.com/users/create%20one?one=two%203", dest.String()) +} diff --git a/router/api/client/forward_test.go b/router/api/client/forward_test.go new file mode 100644 index 0000000..4196ef2 --- /dev/null +++ b/router/api/client/forward_test.go @@ -0,0 +1,42 @@ +package client + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/valyala/fasthttp" + + "github.com/cash-track/gateway/headers" +) + +func TestForwardResponse(t *testing.T) { + ctx := fasthttp.RequestCtx{} + + resp := fasthttp.Response{} + resp.SetStatusCode(fasthttp.StatusUnauthorized) + resp.SetBody([]byte("not allowed\n\r")) + resp.Header.Set(headers.AccessControlAllowOrigin, "test.com") + resp.Header.Set(headers.AccessControlMaxAge, "3600") + resp.Header.Set(headers.AccessControlAllowMethods, "GET,POST") + resp.Header.Set(headers.AccessControlAllowHeaders, "Content-Type,Accept-Language") + resp.Header.Set(headers.ContentType, "text/plain") + resp.Header.Set(headers.RetryAfter, "200") + resp.Header.Set(headers.Vary, "Content-Type,X-Rate-Limit") + resp.Header.Set(headers.XRateLimit, "123") + resp.Header.Set(headers.XRateLimitRemaining, "2") + + err := ForwardResponse(&ctx, &resp) + + assert.NoError(t, err) + + assert.Equal(t, "test.com", string(ctx.Response.Header.Peek(headers.AccessControlAllowOrigin))) + assert.Equal(t, "true", string(ctx.Response.Header.Peek(headers.AccessControlAllowCredentials))) + assert.Equal(t, "GET,POST", string(ctx.Response.Header.Peek(headers.AccessControlAllowMethods))) + assert.Equal(t, "Content-Type,Accept-Language", string(ctx.Response.Header.Peek(headers.AccessControlAllowHeaders))) + assert.Equal(t, "3600", string(ctx.Response.Header.Peek(headers.AccessControlMaxAge))) + assert.Equal(t, "text/plain", string(ctx.Response.Header.Peek(headers.ContentType))) + assert.Equal(t, "200", string(ctx.Response.Header.Peek(headers.RetryAfter))) + assert.Equal(t, "Content-Type,X-Rate-Limit", string(ctx.Response.Header.Peek(headers.Vary))) + assert.Equal(t, "123", string(ctx.Response.Header.Peek(headers.XRateLimit))) + assert.Equal(t, "2", string(ctx.Response.Header.Peek(headers.XRateLimitRemaining))) +} diff --git a/router/router_test.go b/router/router_test.go new file mode 100644 index 0000000..eb324b9 --- /dev/null +++ b/router/router_test.go @@ -0,0 +1,28 @@ +package router + +import ( + "testing" + + "github.com/stretchr/testify/assert" +) + +func TestNew(t *testing.T) { + r := New() + + l := r.List() + + assert.Len(t, l, 2) + + assert.NotNil(t, l["*"]) + assert.Len(t, l["*"], 3) + assert.Contains(t, l["*"], "/live") + assert.Contains(t, l["*"], "/ready") + assert.Contains(t, l["*"], "/api/{path:*}") + + assert.NotNil(t, l["POST"]) + assert.Len(t, l["POST"], 4) + assert.Contains(t, l["POST"], "/api/auth/login") + assert.Contains(t, l["POST"], "/api/auth/logout") + assert.Contains(t, l["POST"], "/api/auth/register") + assert.Contains(t, l["POST"], "/api/auth/provider/google") +}