From 4b0093d4b68abd725c2ff295b84ff5fa493bfc36 Mon Sep 17 00:00:00 2001 From: Tit Petric Date: Sat, 5 Oct 2024 13:46:46 +0200 Subject: [PATCH 1/5] Fix testmiddleware existing (remove coupling, init) --- gateway/coprocess_bundle_test.go | 6 ++---- gateway/testutil.go | 18 +++++++++++++----- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/gateway/coprocess_bundle_test.go b/gateway/coprocess_bundle_test.go index 62dc320694a..08b3b0dbbd6 100644 --- a/gateway/coprocess_bundle_test.go +++ b/gateway/coprocess_bundle_test.go @@ -22,10 +22,6 @@ import ( "github.com/TykTechnologies/tyk/test" ) -var ( - testBundlesPath = filepath.Join(testMiddlewarePath, "bundles") -) - func pkgPath() string { _, filename, _, _ := runtime.Caller(0) return filepath.Dir(filename) + "./.." @@ -81,6 +77,8 @@ func TestBundleLoader(t *testing.T) { }) t.Run("Existing bundle with auth check", func(t *testing.T) { + testBundlesPath := filepath.Join(ts.Gw.GetConfig().MiddlewarePath, "bundles") + spec := &APISpec{ APIDefinition: &apidef.APIDefinition{ CustomMiddlewareBundle: bundleID, diff --git a/gateway/testutil.go b/gateway/testutil.go index 5a3b1d4cd38..4ce181336e3 100644 --- a/gateway/testutil.go +++ b/gateway/testutil.go @@ -59,9 +59,6 @@ var ( // to register to, but never used discardMuxer = mux.NewRouter() - // Used to store the test bundles: - testMiddlewarePath, _ = ioutil.TempDir("", "tyk-middleware-path") - defaultTestConfig config.Config EnableTestDNSMock = false MockHandle *test.DnsMockHandle @@ -1129,10 +1126,10 @@ func (s *Test) newGateway(genConf func(globalConf *config.Config)) *Gateway { var err error gwConfig.Storage.Database = mathrand.Intn(15) gwConfig.AppPath, err = ioutil.TempDir("", "tyk-test-") - if err != nil { panic(err) } + gwConfig.EnableAnalytics = true gwConfig.AnalyticsConfig.EnableGeoIP = true @@ -1150,6 +1147,13 @@ func (s *Test) newGateway(genConf func(globalConf *config.Config)) *Gateway { gwConfig.CoProcessOptions.EnableCoProcess = true gwConfig.EnableBundleDownloader = true gwConfig.BundleBaseURL = testHttpBundles + + // Used to store the test bundles: + testMiddlewarePath, err := ioutil.TempDir("", "tyk-middleware-path") + if err != nil { + panic(err) + } + gwConfig.MiddlewarePath = testMiddlewarePath // force ipv4 for now, to work around the docker bug affecting @@ -1789,9 +1793,13 @@ func BuildAPI(apiGens ...func(spec *APISpec)) (specs []*APISpec) { } func (gw *Gateway) LoadAPI(specs ...*APISpec) (out []*APISpec) { + var err error gwConf := gw.GetConfig() oldPath := gwConf.AppPath - gwConf.AppPath, _ = ioutil.TempDir("", "apps") + gwConf.AppPath, err = ioutil.TempDir("", "apps") + if err != nil { + panic(err) + } gw.SetConfig(gwConf, true) defer func() { globalConf := gw.GetConfig() From 4b31fedb66ae58ff16de4369bf5db6f724bb9895 Mon Sep 17 00:00:00 2001 From: Tit Petric Date: Sat, 5 Oct 2024 15:03:21 +0200 Subject: [PATCH 2/5] Move some testutils to httputil --- internal/httputil/headers.go | 26 +++++++++++++++++++++++++ internal/httputil/listen_proxy_proto.go | 26 +++++++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 internal/httputil/headers.go create mode 100644 internal/httputil/listen_proxy_proto.go diff --git a/internal/httputil/headers.go b/internal/httputil/headers.go new file mode 100644 index 00000000000..4aed5f6749e --- /dev/null +++ b/internal/httputil/headers.go @@ -0,0 +1,26 @@ +package httputil + +import ( + "encoding/base64" + "fmt" + "strings" +) + +// CORSHeaders is a list of CORS headers. +var CORSHeaders = []string{ + "Access-Control-Allow-Origin", + "Access-Control-Expose-Headers", + "Access-Control-Max-Age", + "Access-Control-Allow-Credentials", + "Access-Control-Allow-Methods", + "Access-Control-Allow-Headers", +} + +// AuthHeader will take username and password and return +// "Basic " + base64 encoded `username:password` for use +// in an Authorization header. +func AuthHeader(username, password string) string { + toEncode := strings.Join([]string{username, password}, ":") + encodedPass := base64.StdEncoding.EncodeToString([]byte(toEncode)) + return fmt.Sprintf("Basic %s", encodedPass) +} diff --git a/internal/httputil/listen_proxy_proto.go b/internal/httputil/listen_proxy_proto.go new file mode 100644 index 00000000000..f1aca415731 --- /dev/null +++ b/internal/httputil/listen_proxy_proto.go @@ -0,0 +1,26 @@ +package httputil + +import ( + "net" + + "github.com/pires/go-proxyproto" +) + +// TestListenProxyProto is a test utility. +func TestListenProxyProto(ls net.Listener) error { + pl := &proxyproto.Listener{Listener: ls} + for { + conn, err := pl.Accept() + if err != nil { + return err + } + recv := make([]byte, 4) + _, err = conn.Read(recv) + if err != nil { + return err + } + if _, err := conn.Write([]byte("pong")); err != nil { + return err + } + } +} From 14339cbd1caad27a6793275f8bef600967fc63ca Mon Sep 17 00:00:00 2001 From: Tit Petric Date: Sat, 5 Oct 2024 15:04:03 +0200 Subject: [PATCH 3/5] Black box some tests --- gateway/analytics_go_plugin_test.go | 2 +- gateway/api_definition_test.go | 6 +- gateway/auth_manager_test.go | 3 +- gateway/batch_requests_test.go | 3 +- gateway/blackbox_test.go | 71 ++++++++++++++++++++ gateway/cert_test.go | 19 +++--- gateway/gateway_test.go | 40 +++-------- gateway/grpc_streaming_client_test.go | 2 +- gateway/grpc_streaming_server_test.go | 2 +- gateway/grpc_test.go | 3 +- gateway/handler_error_test.go | 5 +- gateway/mascot_test.go | 3 +- gateway/middleware_test.go | 3 +- gateway/mw_basic_auth_test.go | 18 ----- gateway/mw_granular_access_test.go | 2 +- gateway/mw_graphql_granular_access_test.go | 2 +- gateway/mw_method_transform_test.go | 2 +- gateway/mw_oas_validate_request_test.go | 2 +- gateway/mw_persist_graphql_operation_test.go | 2 +- gateway/mw_rate_limiting_test.go | 2 +- gateway/mw_request_size_limit_test.go | 2 +- gateway/mw_transform.go | 4 ++ gateway/mw_transform_jq_test.go | 2 +- gateway/mw_transform_test.go | 18 ++--- gateway/mw_virtual_endpoint_test.go | 44 ------------ gateway/oauth_manager_test.go | 19 ++---- gateway/redis_signals.go | 5 +- gateway/res_handler_header_transform.go | 8 +-- gateway/res_handler_transform_test.go | 4 +- gateway/reverse_proxy.go | 8 +-- gateway/reverse_proxy_test.go | 5 +- gateway/rpc_storage_handler_test.go | 10 ++- gateway/schema_test.go | 2 +- gateway/testutil_test.go | 66 ++++++++++++++++++ gateway/tracing.go | 8 +-- gateway/tracing_test.go | 6 +- gateway/versions_handler_test.go | 2 +- 37 files changed, 225 insertions(+), 180 deletions(-) create mode 100644 gateway/blackbox_test.go create mode 100644 gateway/testutil_test.go diff --git a/gateway/analytics_go_plugin_test.go b/gateway/analytics_go_plugin_test.go index 3c583c4242a..0691366a8b8 100644 --- a/gateway/analytics_go_plugin_test.go +++ b/gateway/analytics_go_plugin_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "net/http" diff --git a/gateway/api_definition_test.go b/gateway/api_definition_test.go index cece0631fb9..09d29ea022c 100644 --- a/gateway/api_definition_test.go +++ b/gateway/api_definition_test.go @@ -869,7 +869,7 @@ func TestSyncAPISpecsDashboardSuccess(t *testing.T) { t.Fatalf("want %q, got %q", want, got) } } - ts.Gw.handleRedisEvent(&msg, handled, wg.Done) + ts.Gw.HandleRedisEvent(&msg, handled, wg.Done) ts.Gw.ReloadTestCase.TickOk(t) // Wait for the reload to finish, then check it worked @@ -1220,7 +1220,7 @@ func TestSyncAPISpecsDashboardJSONFailure(t *testing.T) { t.Fatalf("want %q, got %q", want, got) } } - ts.Gw.handleRedisEvent(&msg, handled, wg.Done) + ts.Gw.HandleRedisEvent(&msg, handled, wg.Done) ts.Gw.ReloadTestCase.TickOk(t) @@ -1237,7 +1237,7 @@ func TestSyncAPISpecsDashboardJSONFailure(t *testing.T) { var wg2 sync.WaitGroup wg2.Add(1) ts.Gw.ReloadTestCase.Reset() - ts.Gw.handleRedisEvent(&msg, handled, wg2.Done) + ts.Gw.HandleRedisEvent(&msg, handled, wg2.Done) ts.Gw.ReloadTestCase.TickOk(t) // Wait for the reload to finish, then check it worked diff --git a/gateway/auth_manager_test.go b/gateway/auth_manager_test.go index af9e52ac634..14cbaede521 100644 --- a/gateway/auth_manager_test.go +++ b/gateway/auth_manager_test.go @@ -13,6 +13,7 @@ import ( "github.com/TykTechnologies/tyk/certs" "github.com/TykTechnologies/tyk/config" + "github.com/TykTechnologies/tyk/internal/httputil" "github.com/TykTechnologies/tyk/header" @@ -221,7 +222,7 @@ func TestHashKeyFunctionChanged(t *testing.T) { Code: http.StatusOK, }) - authHeader := map[string]string{"Authorization": genAuthHeader("user", "password")} + authHeader := map[string]string{"Authorization": httputil.AuthHeader("user", "password")} testChangeHashFunc(t, authHeader, client, http.StatusUnauthorized) diff --git a/gateway/batch_requests_test.go b/gateway/batch_requests_test.go index 1aa336b6e73..cd0e22a3616 100644 --- a/gateway/batch_requests_test.go +++ b/gateway/batch_requests_test.go @@ -13,11 +13,10 @@ import ( "sync/atomic" "testing" - "github.com/TykTechnologies/tyk/certs" - "github.com/valyala/fasthttp" "github.com/TykTechnologies/tyk/apidef" + "github.com/TykTechnologies/tyk/certs" "github.com/TykTechnologies/tyk/test" ) diff --git a/gateway/blackbox_test.go b/gateway/blackbox_test.go new file mode 100644 index 00000000000..9b0fededa6d --- /dev/null +++ b/gateway/blackbox_test.go @@ -0,0 +1,71 @@ +package gateway_test + +import ( + "github.com/TykTechnologies/tyk/gateway" +) + +// These are symbol shims from the gateway package to make life easier. +// It's all test symbols that have leaked into the package API. +type ( + // Gateway is the service object. + Gateway = gateway.Gateway + ReverseProxy = gateway.ReverseProxy + APIDefinitionLoader = gateway.APIDefinitionLoader + + // Middlewares used by tests explicitly + BaseMiddleware = gateway.BaseMiddleware + TransformMiddleware = gateway.TransformMiddleware + ResponseTransformMiddleware = gateway.ResponseTransformMiddleware + + // Tests leakage. + Test = gateway.Test + TestConfig = gateway.TestConfig + TestHttpResponse = gateway.TestHttpResponse + TraceHttpRequest = gateway.TraceHttpRequest + + // Data model. + APISpec = gateway.APISpec + TransformSpec = gateway.TransformSpec + HostHealthReport = gateway.HostHealthReport + HostCheckCallBacks = gateway.HostCheckCallBacks + NotificationCommand = gateway.NotificationCommand + Notification = gateway.Notification + GraphQLRequest = gateway.GraphQLRequest + OASSchemaResponse = gateway.OASSchemaResponse + HeaderTransform = gateway.HeaderTransform + HeaderTransformOptions = gateway.HeaderTransformOptions + VersionMetas = gateway.VersionMetas + + // Interfaces (data model). + IdExtractor = gateway.IdExtractor + WebHookHandler = gateway.WebHookHandler + HTTPDashboardHandler = gateway.HTTPDashboardHandler + BaseTykResponseHandler = gateway.BaseTykResponseHandler +) + +// Constants are a coupling (data model). +const ( + TestHttpAny = gateway.TestHttpAny + EH_LogHandler = gateway.EH_LogHandler + EH_WebHook = gateway.EH_WebHook + + NoticeGroupReload = gateway.NoticeGroupReload +) + +// Global functions are a coupling. +var ( + BuildAPI = gateway.BuildAPI + BuildOASAPI = gateway.BuildOASAPI + + StartTest = gateway.StartTest + InitTestMain = gateway.InitTestMain + + CreateSession = gateway.CreateSession + CreateStandardSession = gateway.CreateStandardSession + + GetTLSClient = gateway.GetTLSClient + MockOrgID = gateway.MockOrgID + UpdateAPIVersion = gateway.UpdateAPIVersion + TransformBody = gateway.TransformBody + TestReq = gateway.TestReq +) diff --git a/gateway/cert_test.go b/gateway/cert_test.go index e133cdb6911..5260ec76df3 100644 --- a/gateway/cert_test.go +++ b/gateway/cert_test.go @@ -22,19 +22,16 @@ import ( "github.com/stretchr/testify/assert" "go.uber.org/mock/gomock" - "github.com/TykTechnologies/tyk/certs/mock" - - "github.com/TykTechnologies/tyk/internal/crypto" - - "github.com/TykTechnologies/tyk/header" - "github.com/TykTechnologies/tyk/storage" - - "github.com/TykTechnologies/tyk/user" - "github.com/TykTechnologies/tyk/apidef" "github.com/TykTechnologies/tyk/certs" + "github.com/TykTechnologies/tyk/certs/mock" "github.com/TykTechnologies/tyk/config" + "github.com/TykTechnologies/tyk/header" + "github.com/TykTechnologies/tyk/internal/crypto" + "github.com/TykTechnologies/tyk/internal/httputil" + "github.com/TykTechnologies/tyk/storage" "github.com/TykTechnologies/tyk/test" + "github.com/TykTechnologies/tyk/user" ) const ( @@ -1585,7 +1582,7 @@ func TestUpstreamCertificates_WithProtocolTCP(t *testing.T) { assert.NoError(t, err) defer ls.Close() - go listenProxyProto(ls) + go httputil.TestListenProxyProto(ls) certID, err := ts.Gw.CertificateManager.Add(combinedUpstreamCertPEM, "") defer ts.Gw.CertificateManager.Delete(certID, "") @@ -1641,7 +1638,7 @@ func TestClientCertificates_WithProtocolTLS(t *testing.T) { assert.NoError(t, err) defer upstream.Close() - go listenProxyProto(upstream) + go httputil.TestListenProxyProto(upstream) // tyk _, _, tykServerCombinedPEM, _ := crypto.GenServerCertificate() diff --git a/gateway/gateway_test.go b/gateway/gateway_test.go index 2238f65e13c..ba665e9ceac 100644 --- a/gateway/gateway_test.go +++ b/gateway/gateway_test.go @@ -19,13 +19,13 @@ import ( "time" "github.com/gorilla/websocket" - proxyproto "github.com/pires/go-proxyproto" "github.com/stretchr/testify/assert" msgpack "gopkg.in/vmihailenco/msgpack.v2" "github.com/TykTechnologies/tyk-pump/analytics" "github.com/TykTechnologies/tyk/apidef" "github.com/TykTechnologies/tyk/config" + "github.com/TykTechnologies/tyk/internal/httputil" "github.com/TykTechnologies/tyk/storage" "github.com/TykTechnologies/tyk/test" "github.com/TykTechnologies/tyk/user" @@ -573,7 +573,7 @@ func TestManagementNodeRedisEvents(t *testing.T) { t.Fatalf("want %q, got %q", want, got) } } - ts.Gw.handleRedisEvent(&msg, shouldHandle, nil) + ts.Gw.HandleRedisEvent(&msg, shouldHandle, nil) if !callbackRun { t.Fatalf("Should run callback") } @@ -582,7 +582,7 @@ func TestManagementNodeRedisEvents(t *testing.T) { notHandle := func(got NotificationCommand) { t.Fatalf("should have not handled redis event") } - ts.Gw.handleRedisEvent(msg, notHandle, nil) + ts.Gw.HandleRedisEvent(msg, notHandle, nil) }) t.Run("With signature", func(t *testing.T) { @@ -608,7 +608,7 @@ func TestManagementNodeRedisEvents(t *testing.T) { } } - ts.Gw.handleRedisEvent(&msg, shouldHandle, nil) + ts.Gw.HandleRedisEvent(&msg, shouldHandle, nil) if !callbackRun { t.Fatalf("Should run callback") } @@ -621,7 +621,7 @@ func TestManagementNodeRedisEvents(t *testing.T) { shouldFail := func(got NotificationCommand) { valid = true } - ts.Gw.handleRedisEvent(&msg, shouldFail, nil) + ts.Gw.HandleRedisEvent(&msg, shouldFail, nil) if valid { t.Fatalf("Should fail validation") } @@ -697,31 +697,13 @@ func TestReloadGoroutineLeakWithCircuitBreaker(t *testing.T) { } } -func listenProxyProto(ls net.Listener) error { - pl := &proxyproto.Listener{Listener: ls} - for { - conn, err := pl.Accept() - if err != nil { - return err - } - recv := make([]byte, 4) - _, err = conn.Read(recv) - if err != nil { - return err - } - if _, err := conn.Write([]byte("pong")); err != nil { - return err - } - } -} - func TestProxyProtocol(t *testing.T) { l, err := net.Listen("tcp", "127.0.0.1:0") if err != nil { t.Fatal(err) } defer l.Close() - go listenProxyProto(l) + go httputil.TestListenProxyProto(l) ts := StartTest(nil) t.Cleanup(ts.Close) rp, err := net.Listen("tcp", "127.0.0.1:0") @@ -1769,9 +1751,9 @@ func TestTracing(t *testing.T) { {Method: "POST", Path: "/tyk/debug", Data: `{}`, AdminAuth: true, Code: 400, BodyMatch: "Spec field is missing"}, {Method: "POST", Path: "/tyk/debug", Data: `{"Spec": {}}`, AdminAuth: true, Code: 400, BodyMatch: "Request field is missing"}, {Method: "POST", Path: "/tyk/debug", Data: `{"Spec": {}, "Request": {}}`, AdminAuth: true, Code: 400, BodyMatch: "Spec not valid, skipped!"}, - {Method: "POST", Path: "/tyk/debug", Data: traceRequest{Spec: spec.APIDefinition, Request: &traceHttpRequest{Method: "GET", Path: "/"}}, AdminAuth: true, Code: 200, BodyMatch: `401 Unauthorized`}, - {Method: "POST", Path: "/tyk/debug", Data: traceRequest{Spec: apiDefWithBundle, Request: &traceHttpRequest{Method: "GET", Path: "/", Headers: authHeaders}}, AdminAuth: true, Code: http.StatusBadRequest, BodyMatch: `Couldn't load bundle`}, - {Method: "POST", Path: "/tyk/debug", Data: traceRequest{Spec: spec.APIDefinition, Request: &traceHttpRequest{Path: "/", Headers: authHeaders}}, AdminAuth: true, Code: 200, BodyMatch: `200 OK`}, + {Method: "POST", Path: "/tyk/debug", Data: traceRequest{Spec: spec.APIDefinition, Request: &TraceHttpRequest{Method: "GET", Path: "/"}}, AdminAuth: true, Code: 200, BodyMatch: `401 Unauthorized`}, + {Method: "POST", Path: "/tyk/debug", Data: traceRequest{Spec: apiDefWithBundle, Request: &TraceHttpRequest{Method: "GET", Path: "/", Headers: authHeaders}}, AdminAuth: true, Code: http.StatusBadRequest, BodyMatch: `Couldn't load bundle`}, + {Method: "POST", Path: "/tyk/debug", Data: traceRequest{Spec: spec.APIDefinition, Request: &TraceHttpRequest{Path: "/", Headers: authHeaders}}, AdminAuth: true, Code: 200, BodyMatch: `200 OK`}, }...) t.Run("Custom auth header", func(t *testing.T) { @@ -1785,9 +1767,9 @@ func TestTracing(t *testing.T) { _, _ = ts.Run(t, []test.TestCase{ {Method: http.MethodPost, Path: "/tyk/debug", Data: traceRequest{Spec: spec.APIDefinition, - Request: &traceHttpRequest{Path: "/", Headers: authHeaders}}, AdminAuth: true, Code: 200, BodyMatch: `401 Unauthorized`}, + Request: &TraceHttpRequest{Path: "/", Headers: authHeaders}}, AdminAuth: true, Code: 200, BodyMatch: `401 Unauthorized`}, {Method: http.MethodPost, Path: "/tyk/debug", Data: traceRequest{Spec: spec.APIDefinition, - Request: &traceHttpRequest{Path: "/", Headers: customAuthHeaders}}, AdminAuth: true, Code: 200, BodyMatch: `200 OK`}, + Request: &TraceHttpRequest{Path: "/", Headers: customAuthHeaders}}, AdminAuth: true, Code: 200, BodyMatch: `200 OK`}, }...) }) } diff --git a/gateway/grpc_streaming_client_test.go b/gateway/grpc_streaming_client_test.go index 5a485d93193..76bb584b38e 100644 --- a/gateway/grpc_streaming_client_test.go +++ b/gateway/grpc_streaming_client_test.go @@ -20,7 +20,7 @@ // to perform unary, client streaming, server streaming and full duplex RPCs. // // It interacts with the route guide service whose definition can be found in routeguide/route_guide.proto. -package gateway +package gateway_test import ( "context" diff --git a/gateway/grpc_streaming_server_test.go b/gateway/grpc_streaming_server_test.go index dfca3207778..c0cf351296f 100644 --- a/gateway/grpc_streaming_server_test.go +++ b/gateway/grpc_streaming_server_test.go @@ -20,7 +20,7 @@ // to perform unary, client streaming, server streaming and full duplex RPCs. // // It implements the route guide service whose definition can be found in routeguide/route_guide.proto. -package gateway +package gateway_test import ( "context" diff --git a/gateway/grpc_test.go b/gateway/grpc_test.go index 6613fcf97cb..1e335425adf 100644 --- a/gateway/grpc_test.go +++ b/gateway/grpc_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "context" @@ -8,6 +8,7 @@ import ( "encoding/json" "fmt" "io/ioutil" + "log" "net" "net/http" "net/http/httptest" diff --git a/gateway/handler_error_test.go b/gateway/handler_error_test.go index 72cd761966d..73477936744 100644 --- a/gateway/handler_error_test.go +++ b/gateway/handler_error_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "bytes" @@ -13,7 +13,8 @@ import ( "github.com/TykTechnologies/tyk/test" ) -func (s *Test) TestHandleError_text_xml(t *testing.T) { +// Unused +func testHandleErrorTextXML(t *testing.T, s *Test) { file := filepath.Join(s.Gw.GetConfig().TemplatePath, "error_500.xml") xml := ` diff --git a/gateway/mascot_test.go b/gateway/mascot_test.go index 26a43132676..27c633dd51e 100644 --- a/gateway/mascot_test.go +++ b/gateway/mascot_test.go @@ -5,12 +5,11 @@ import ( "strings" "testing" - "github.com/TykTechnologies/tyk/gateway" "github.com/TykTechnologies/tyk/test" ) func TestMascotShowsUpOnceOnly(t *testing.T) { - ts := gateway.StartTest(nil) + ts := StartTest(nil) defer ts.Close() for i := 0; i < 7; i++ { diff --git a/gateway/middleware_test.go b/gateway/middleware_test.go index b4b8fb6f56d..7b21fa3725e 100644 --- a/gateway/middleware_test.go +++ b/gateway/middleware_test.go @@ -10,12 +10,11 @@ import ( "github.com/stretchr/testify/assert" "github.com/TykTechnologies/tyk/apidef" + "github.com/TykTechnologies/tyk/config" headers2 "github.com/TykTechnologies/tyk/header" "github.com/TykTechnologies/tyk/internal/cache" "github.com/TykTechnologies/tyk/internal/uuid" "github.com/TykTechnologies/tyk/test" - - "github.com/TykTechnologies/tyk/config" "github.com/TykTechnologies/tyk/user" ) diff --git a/gateway/mw_basic_auth_test.go b/gateway/mw_basic_auth_test.go index 48b311e461b..4e747988fb4 100644 --- a/gateway/mw_basic_auth_test.go +++ b/gateway/mw_basic_auth_test.go @@ -20,24 +20,6 @@ func genAuthHeader(username, password string) string { return fmt.Sprintf("Basic %s", encodedPass) } -func (ts *Test) testPrepareBasicAuth(cacheDisabled bool) *user.SessionState { - - session := CreateStandardSession() - session.BasicAuthData.Password = "password" - session.AccessRights = map[string]user.AccessDefinition{"test": {APIID: "test", Versions: []string{"v1"}}} - session.OrgID = "default" - - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - spec.UseBasicAuth = true - spec.BasicAuth.DisableCaching = cacheDisabled - spec.UseKeylessAccess = false - spec.Proxy.ListenPath = "/" - spec.OrgID = "default" - }) - - return session -} - func TestBasicAuth(t *testing.T) { test.Flaky(t) // TODO: TT-5223 diff --git a/gateway/mw_granular_access_test.go b/gateway/mw_granular_access_test.go index 672e6ee4b4a..292e394b928 100644 --- a/gateway/mw_granular_access_test.go +++ b/gateway/mw_granular_access_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "net/http" diff --git a/gateway/mw_graphql_granular_access_test.go b/gateway/mw_graphql_granular_access_test.go index 3bcf5ceb415..300f22665a2 100644 --- a/gateway/mw_graphql_granular_access_test.go +++ b/gateway/mw_graphql_granular_access_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "net/http" diff --git a/gateway/mw_method_transform_test.go b/gateway/mw_method_transform_test.go index b03ff41b26b..986124a564f 100644 --- a/gateway/mw_method_transform_test.go +++ b/gateway/mw_method_transform_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "net/http" diff --git a/gateway/mw_oas_validate_request_test.go b/gateway/mw_oas_validate_request_test.go index c2b259216d6..3413b53edcf 100644 --- a/gateway/mw_oas_validate_request_test.go +++ b/gateway/mw_oas_validate_request_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "context" diff --git a/gateway/mw_persist_graphql_operation_test.go b/gateway/mw_persist_graphql_operation_test.go index 2555118e6f7..b6bc1ba091c 100644 --- a/gateway/mw_persist_graphql_operation_test.go +++ b/gateway/mw_persist_graphql_operation_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "bytes" diff --git a/gateway/mw_rate_limiting_test.go b/gateway/mw_rate_limiting_test.go index 77d160fd790..36f220b6911 100644 --- a/gateway/mw_rate_limiting_test.go +++ b/gateway/mw_rate_limiting_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "net/http" diff --git a/gateway/mw_request_size_limit_test.go b/gateway/mw_request_size_limit_test.go index 53c1e44ff7c..44ac637f188 100644 --- a/gateway/mw_request_size_limit_test.go +++ b/gateway/mw_request_size_limit_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "net/http" diff --git a/gateway/mw_transform.go b/gateway/mw_transform.go index 341401746ed..cac80c7c01f 100644 --- a/gateway/mw_transform.go +++ b/gateway/mw_transform.go @@ -51,6 +51,10 @@ func (t *TransformMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Requ return nil, http.StatusOK } +func TransformBody(r *http.Request, tmeta *TransformSpec, t *TransformMiddleware) error { + return transformBody(r, tmeta, t) +} + func transformBody(r *http.Request, tmeta *TransformSpec, t *TransformMiddleware) error { body, _ := ioutil.ReadAll(r.Body) defer r.Body.Close() diff --git a/gateway/mw_transform_jq_test.go b/gateway/mw_transform_jq_test.go index c5ffe9ead7b..93b399c1d6d 100644 --- a/gateway/mw_transform_jq_test.go +++ b/gateway/mw_transform_jq_test.go @@ -1,7 +1,7 @@ //go:build jq // +build jq -package gateway +package gateway_test import ( "testing" diff --git a/gateway/mw_transform_test.go b/gateway/mw_transform_test.go index 009c484dd57..3e314b2c937 100644 --- a/gateway/mw_transform_test.go +++ b/gateway/mw_transform_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "encoding/base64" @@ -44,7 +44,7 @@ func TestTransformNonAscii(t *testing.T) { base.Spec.EnableContextVars = false transform := TransformMiddleware{base} - if err := transformBody(r, tmeta, &transform); err != nil { + if err := TransformBody(r, tmeta, &transform); err != nil { t.Fatalf("wanted nil error, got %v", err) } gotBs, err := ioutil.ReadAll(r.Body) @@ -72,7 +72,7 @@ func BenchmarkTransformNonAscii(b *testing.B) { for i := 0; i < b.N; i++ { r := TestReq(b, "GET", "/", in) - if err := transformBody(r, tmeta, &transform); err != nil { + if err := TransformBody(r, tmeta, &transform); err != nil { b.Fatalf("wanted nil error, got %v", err) } } @@ -96,7 +96,7 @@ func TestTransformXMLCrash(t *testing.T) { base.Spec.EnableContextVars = false transform := TransformMiddleware{base} - if err := transformBody(r, tmeta, &transform); err == nil { + if err := TransformBody(r, tmeta, &transform); err == nil { t.Fatalf("wanted error, got nil") } } @@ -151,7 +151,7 @@ func TestTransformJSONMarshalXMLInput(t *testing.T) { base.Spec.EnableContextVars = false transform := TransformMiddleware{base} - if err := transformBody(r, tmeta, &transform); err != nil { + if err := TransformBody(r, tmeta, &transform); err != nil { t.Fatalf("wanted nil error, got %v", err) } gotBs, err := ioutil.ReadAll(r.Body) @@ -178,7 +178,7 @@ func TestTransformJSONMarshalJSONInput(t *testing.T) { base.Spec.EnableContextVars = false transform := TransformMiddleware{base} - if err := transformBody(r, tmeta, &transform); err != nil { + if err := TransformBody(r, tmeta, &transform); err != nil { t.Fatalf("wanted nil error, got %v", err) } gotBs, err := ioutil.ReadAll(r.Body) @@ -217,7 +217,7 @@ func TestTransformJSONMarshalJSONArrayInput(t *testing.T) { base.Spec.EnableContextVars = false transform := TransformMiddleware{base} - if err := transformBody(r, tmeta, &transform); err != nil { + if err := TransformBody(r, tmeta, &transform); err != nil { t.Fatalf("wanted nil error, got %v", err) } gotBs, err := ioutil.ReadAll(r.Body) @@ -243,7 +243,7 @@ func BenchmarkTransformJSONMarshal(b *testing.B) { for i := 0; i < b.N; i++ { r := TestReq(b, "GET", "/", in) - if err := transformBody(r, tmeta, &transform); err != nil { + if err := TransformBody(r, tmeta, &transform); err != nil { b.Fatalf("wanted nil error, got %v", err) } } @@ -264,7 +264,7 @@ func TestTransformXMLMarshal(t *testing.T) { base.Spec.EnableContextVars = false transform := TransformMiddleware{base} - if err := transformBody(r, tmeta, &transform); err != nil { + if err := TransformBody(r, tmeta, &transform); err != nil { t.Fatalf("wanted nil error, got %v", err) } gotBs, err := ioutil.ReadAll(r.Body) diff --git a/gateway/mw_virtual_endpoint_test.go b/gateway/mw_virtual_endpoint_test.go index 8827d20e528..0754df74ea8 100644 --- a/gateway/mw_virtual_endpoint_test.go +++ b/gateway/mw_virtual_endpoint_test.go @@ -1,13 +1,11 @@ package gateway import ( - "encoding/base64" "net/http" "testing" "github.com/TykTechnologies/tyk/user" - "github.com/TykTechnologies/tyk/apidef" "github.com/TykTechnologies/tyk/test" ) @@ -37,48 +35,6 @@ var ( cacheDisabled = false ) -func (ts *Test) testPrepareVirtualEndpoint(js, method, path string, proxyOnError, keyless, cacheEnabled, disabled bool) { - - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - spec.APIID = "test" - spec.Proxy.ListenPath = "/" - spec.UseKeylessAccess = keyless - spec.Auth = apidef.AuthConfig{AuthHeaderName: "Authorization"} - virtualMeta := apidef.VirtualMeta{ - Disabled: disabled, - ResponseFunctionName: "testVirtData", - FunctionSourceType: apidef.UseBlob, - FunctionSourceURI: base64.StdEncoding.EncodeToString([]byte(js)), - Path: path, - Method: method, - ProxyOnError: proxyOnError, - } - if !keyless { - virtualMeta.UseSession = true - } - v := spec.VersionData.Versions["v1"] - v.UseExtendedPaths = true - v.ExtendedPaths = apidef.ExtendedPathsSet{ - Virtual: []apidef.VirtualMeta{virtualMeta}, - } - spec.VersionData.Versions["v1"] = v - - spec.ConfigData = map[string]interface{}{ - "foo": "x", - "bar": map[string]interface{}{"y": 3}, - } - - // Address https://github.com/TykTechnologies/tyk/issues/1356 - // VP should work with cache enabled - spec.CacheOptions = apidef.CacheOptions{ - EnableCache: cacheEnabled, - EnableUpstreamCacheControl: true, - CacheTimeout: 60, - CacheAllSafeRequests: true, - } - }) -} - func TestVirtualEndpoint(t *testing.T) { ts := StartTest(nil) defer ts.Close() diff --git a/gateway/oauth_manager_test.go b/gateway/oauth_manager_test.go index 92d4f965cbd..8161965ea16 100644 --- a/gateway/oauth_manager_test.go +++ b/gateway/oauth_manager_test.go @@ -8,31 +8,24 @@ import ( "bytes" "context" "encoding/json" + "fmt" + "net/http" "net/url" "path" "reflect" "strconv" "strings" "testing" + "time" + "github.com/lonelycode/osin" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "github.com/TykTechnologies/tyk/internal/redis" - + "github.com/TykTechnologies/tyk/apidef" "github.com/TykTechnologies/tyk/config" - - "fmt" - - "net/http" - - "time" - - "github.com/lonelycode/osin" - + "github.com/TykTechnologies/tyk/internal/redis" "github.com/TykTechnologies/tyk/internal/uuid" - - "github.com/TykTechnologies/tyk/apidef" "github.com/TykTechnologies/tyk/storage" "github.com/TykTechnologies/tyk/test" "github.com/TykTechnologies/tyk/user" diff --git a/gateway/redis_signals.go b/gateway/redis_signals.go index e8e79d6c7cb..6262a253e7b 100644 --- a/gateway/redis_signals.go +++ b/gateway/redis_signals.go @@ -66,7 +66,7 @@ func (gw *Gateway) startPubSubLoop() { for { err := cacheStore.StartPubSubHandler(gw.ctx, RedisPubSubChannel, func(v interface{}) { - gw.handleRedisEvent(v, nil, nil) + gw.HandleRedisEvent(v, nil, nil) }) select { @@ -95,7 +95,8 @@ func (gw *Gateway) logPubSubError(err error, message string) bool { return false } -func (gw *Gateway) handleRedisEvent(v interface{}, handled func(NotificationCommand), reloaded func()) { +// HandleRedisEvent is exported for test usage. +func (gw *Gateway) HandleRedisEvent(v interface{}, handled func(NotificationCommand), reloaded func()) { message, ok := v.(temporalmodel.Message) if !ok { return diff --git a/gateway/res_handler_header_transform.go b/gateway/res_handler_header_transform.go index 72414e79517..e5547d6b5b1 100644 --- a/gateway/res_handler_header_transform.go +++ b/gateway/res_handler_header_transform.go @@ -21,7 +21,7 @@ type HeaderTransformOptions struct { type HeaderTransform struct { BaseTykResponseHandler - config HeaderTransformOptions + Config HeaderTransformOptions } func (h *HeaderTransform) Base() *BaseTykResponseHandler { @@ -33,7 +33,7 @@ func (h *HeaderTransform) Name() string { } func (h *HeaderTransform) Init(c interface{}, spec *APISpec) error { - if err := mapstructure.Decode(c, &h.config); err != nil { + if err := mapstructure.Decode(c, &h.Config); err != nil { return err } h.Spec = spec @@ -47,12 +47,12 @@ func (h *HeaderTransform) HandleResponse(rw http.ResponseWriter, res *http.Response, req *http.Request, ses *user.SessionState) error { // Parse target_host parameter from configuration - target_url, err := url.Parse(h.config.RevProxyTransform.Target_host) + target_url, err := url.Parse(h.Config.RevProxyTransform.Target_host) if err != nil { return err } ignoreCanonical := h.Gw.GetConfig().IgnoreCanonicalMIMEHeaderKey - for _, name := range h.config.RevProxyTransform.Headers { + for _, name := range h.Config.RevProxyTransform.Headers { // check if header is present and its value is not empty val := res.Header.Get(name) if val == "" { diff --git a/gateway/res_handler_transform_test.go b/gateway/res_handler_transform_test.go index bde2768bad0..78988f7bfe7 100644 --- a/gateway/res_handler_transform_test.go +++ b/gateway/res_handler_transform_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "encoding/base64" @@ -282,7 +282,7 @@ func TestHeaderTransformBase(t *testing.T) { BaseTykResponseHandler: BaseTykResponseHandler{ // You can populate fields if needed }, - config: HeaderTransformOptions{ + Config: HeaderTransformOptions{ // You can populate fields if needed }, } diff --git a/gateway/reverse_proxy.go b/gateway/reverse_proxy.go index a7755c63f5a..75c98888e51 100644 --- a/gateway/reverse_proxy.go +++ b/gateway/reverse_proxy.go @@ -50,13 +50,7 @@ import ( var defaultUserAgent = "Tyk/" + VERSION -var corsHeaders = []string{ - "Access-Control-Allow-Origin", - "Access-Control-Expose-Headers", - "Access-Control-Max-Age", - "Access-Control-Allow-Credentials", - "Access-Control-Allow-Methods", - "Access-Control-Allow-Headers"} +var corsHeaders = httputil.CORSHeaders var sdMu sync.RWMutex diff --git a/gateway/reverse_proxy_test.go b/gateway/reverse_proxy_test.go index bfab9ab339c..ec86d794053 100644 --- a/gateway/reverse_proxy_test.go +++ b/gateway/reverse_proxy_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + "github.com/TykTechnologies/tyk/internal/httputil" "github.com/TykTechnologies/tyk/user" "github.com/TykTechnologies/tyk/header" @@ -48,7 +49,7 @@ func TestCopyHeader_NoDuplicateCORSHeaders(t *testing.T) { h.Set("Location", "https://tyk.io") if withCORS { - for _, v := range corsHeaders { + for _, v := range httputil.CORSHeaders { h.Set(v, "tyk.io") } } @@ -67,7 +68,7 @@ func TestCopyHeader_NoDuplicateCORSHeaders(t *testing.T) { for _, v := range tests { copyHeader(v.dst, v.src, false) - for _, vv := range corsHeaders { + for _, vv := range httputil.CORSHeaders { val := v.dst[vv] if n := len(val); n != 1 { t.Fatalf("%s found %d times", vv, n) diff --git a/gateway/rpc_storage_handler_test.go b/gateway/rpc_storage_handler_test.go index c02c6269bc1..dfc8d4c221c 100644 --- a/gateway/rpc_storage_handler_test.go +++ b/gateway/rpc_storage_handler_test.go @@ -8,16 +8,14 @@ import ( "net/http" "testing" - "github.com/TykTechnologies/tyk/internal/model" - "github.com/TykTechnologies/tyk/rpc" - - "github.com/TykTechnologies/tyk/apidef" - "github.com/TykTechnologies/tyk/config" - "github.com/lonelycode/osin" "github.com/stretchr/testify/assert" + "github.com/TykTechnologies/tyk/apidef" + "github.com/TykTechnologies/tyk/config" "github.com/TykTechnologies/tyk/header" + "github.com/TykTechnologies/tyk/internal/model" + "github.com/TykTechnologies/tyk/rpc" "github.com/TykTechnologies/tyk/storage" "github.com/TykTechnologies/tyk/test" "github.com/TykTechnologies/tyk/user" diff --git a/gateway/schema_test.go b/gateway/schema_test.go index 3511c75f003..2777fbe9348 100644 --- a/gateway/schema_test.go +++ b/gateway/schema_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "encoding/json" diff --git a/gateway/testutil_test.go b/gateway/testutil_test.go new file mode 100644 index 00000000000..86c27ad0e27 --- /dev/null +++ b/gateway/testutil_test.go @@ -0,0 +1,66 @@ +package gateway + +import ( + "encoding/base64" + + "github.com/TykTechnologies/tyk/apidef" + "github.com/TykTechnologies/tyk/user" +) + +func (ts *Test) testPrepareBasicAuth(cacheDisabled bool) *user.SessionState { + session := CreateStandardSession() + session.BasicAuthData.Password = "password" + session.AccessRights = map[string]user.AccessDefinition{"test": {APIID: "test", Versions: []string{"v1"}}} + session.OrgID = "default" + + ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { + spec.UseBasicAuth = true + spec.BasicAuth.DisableCaching = cacheDisabled + spec.UseKeylessAccess = false + spec.Proxy.ListenPath = "/" + spec.OrgID = "default" + }) + + return session +} + +func (ts *Test) testPrepareVirtualEndpoint(js, method, path string, proxyOnError, keyless, cacheEnabled, disabled bool) { + ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { + spec.APIID = "test" + spec.Proxy.ListenPath = "/" + spec.UseKeylessAccess = keyless + spec.Auth = apidef.AuthConfig{AuthHeaderName: "Authorization"} + virtualMeta := apidef.VirtualMeta{ + Disabled: disabled, + ResponseFunctionName: "testVirtData", + FunctionSourceType: apidef.UseBlob, + FunctionSourceURI: base64.StdEncoding.EncodeToString([]byte(js)), + Path: path, + Method: method, + ProxyOnError: proxyOnError, + } + if !keyless { + virtualMeta.UseSession = true + } + v := spec.VersionData.Versions["v1"] + v.UseExtendedPaths = true + v.ExtendedPaths = apidef.ExtendedPathsSet{ + Virtual: []apidef.VirtualMeta{virtualMeta}, + } + spec.VersionData.Versions["v1"] = v + + spec.ConfigData = map[string]interface{}{ + "foo": "x", + "bar": map[string]interface{}{"y": 3}, + } + + // Address https://github.com/TykTechnologies/tyk/issues/1356 + // VP should work with cache enabled + spec.CacheOptions = apidef.CacheOptions{ + EnableCache: cacheEnabled, + EnableUpstreamCacheControl: true, + CacheTimeout: 60, + CacheAllSafeRequests: true, + } + }) +} diff --git a/gateway/tracing.go b/gateway/tracing.go index c02146443ca..3ced434c239 100644 --- a/gateway/tracing.go +++ b/gateway/tracing.go @@ -14,14 +14,14 @@ import ( "github.com/TykTechnologies/tyk/internal/httputil" ) -type traceHttpRequest struct { +type TraceHttpRequest struct { Method string `json:"method"` Path string `json:"path"` Body string `json:"body"` Headers http.Header `json:"headers"` } -func (tr *traceHttpRequest) toRequest(ignoreCanonicalMIMEHeaderKey bool) (*http.Request, error) { +func (tr *TraceHttpRequest) ToRequest(ignoreCanonicalMIMEHeaderKey bool) (*http.Request, error) { r, err := http.NewRequest(tr.Method, tr.Path, strings.NewReader(tr.Body)) if err != nil { return nil, err @@ -39,7 +39,7 @@ func (tr *traceHttpRequest) toRequest(ignoreCanonicalMIMEHeaderKey bool) (*http. // TraceRequest is for tracing an HTTP request // swagger:model TraceRequest type traceRequest struct { - Request *traceHttpRequest `json:"request"` + Request *TraceHttpRequest `json:"request"` Spec *apidef.APIDefinition `json:"spec"` } @@ -135,7 +135,7 @@ func (gw *Gateway) traceHandler(w http.ResponseWriter, r *http.Request) { } wr := httptest.NewRecorder() - tr, err := traceReq.Request.toRequest(gw.GetConfig().IgnoreCanonicalMIMEHeaderKey) + tr, err := traceReq.Request.ToRequest(gw.GetConfig().IgnoreCanonicalMIMEHeaderKey) if err != nil { doJSONWrite(w, http.StatusInternalServerError, apiError("Unexpected failure: "+err.Error())) return diff --git a/gateway/tracing_test.go b/gateway/tracing_test.go index 9a501b5e31c..b4b02c9070c 100644 --- a/gateway/tracing_test.go +++ b/gateway/tracing_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "io/ioutil" @@ -15,9 +15,9 @@ func TestTraceHttpRequest_toRequest(t *testing.T) { const body = `{"foo":"bar"}` header := http.Header{} header.Add("key", "value") - tr := &traceHttpRequest{Path: "", Method: http.MethodPost, Body: body, Headers: header} + tr := &TraceHttpRequest{Path: "", Method: http.MethodPost, Body: body, Headers: header} - request, err := tr.toRequest(ts.Gw.GetConfig().IgnoreCanonicalMIMEHeaderKey) + request, err := tr.ToRequest(ts.Gw.GetConfig().IgnoreCanonicalMIMEHeaderKey) bodyInBytes, _ := ioutil.ReadAll(request.Body) assert.NoError(t, err) diff --git a/gateway/versions_handler_test.go b/gateway/versions_handler_test.go index 22161312d4b..68a35d28530 100644 --- a/gateway/versions_handler_test.go +++ b/gateway/versions_handler_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "encoding/json" From 4f7dac59ccf402e5580c28673efa2da17d4d2ac5 Mon Sep 17 00:00:00 2001 From: Tit Petric Date: Sat, 5 Oct 2024 15:31:54 +0200 Subject: [PATCH 4/5] Blackbox some additional tests --- gateway/blackbox_test.go | 24 +++++++------ gateway/dashboard_register.go | 8 ++--- gateway/dashboard_register_test.go | 26 ++------------ gateway/mw_ip_blacklist_test.go | 2 +- gateway/mw_ip_whitelist_test.go | 2 +- gateway/mw_validate_json_test.go | 52 +++------------------------ gateway/redis_signals.go | 8 ++--- gateway/redis_signals_test.go | 52 --------------------------- gateway/res_cache_test.go | 2 +- gateway/res_handler_go_plugin_test.go | 5 ++- gateway/server.go | 4 +-- gateway/testutil_test.go | 42 ++++++++++++++++++++++ 12 files changed, 75 insertions(+), 152 deletions(-) delete mode 100644 gateway/redis_signals_test.go diff --git a/gateway/blackbox_test.go b/gateway/blackbox_test.go index 9b0fededa6d..124196822ef 100644 --- a/gateway/blackbox_test.go +++ b/gateway/blackbox_test.go @@ -16,6 +16,10 @@ type ( BaseMiddleware = gateway.BaseMiddleware TransformMiddleware = gateway.TransformMiddleware ResponseTransformMiddleware = gateway.ResponseTransformMiddleware + ResponseCacheMiddleware = gateway.ResponseCacheMiddleware + ResponseGoPluginMiddleware = gateway.ResponseGoPluginMiddleware + IPWhiteListMiddleware = gateway.IPWhiteListMiddleware + IPBlackListMiddleware = gateway.IPBlackListMiddleware // Tests leakage. Test = gateway.Test @@ -34,7 +38,7 @@ type ( OASSchemaResponse = gateway.OASSchemaResponse HeaderTransform = gateway.HeaderTransform HeaderTransformOptions = gateway.HeaderTransformOptions - VersionMetas = gateway.VersionMetas + VersionMetas = gateway.VersionMetas // Interfaces (data model). IdExtractor = gateway.IdExtractor @@ -54,18 +58,18 @@ const ( // Global functions are a coupling. var ( - BuildAPI = gateway.BuildAPI - BuildOASAPI = gateway.BuildOASAPI + BuildAPI = gateway.BuildAPI + BuildOASAPI = gateway.BuildOASAPI - StartTest = gateway.StartTest - InitTestMain = gateway.InitTestMain + StartTest = gateway.StartTest + InitTestMain = gateway.InitTestMain CreateSession = gateway.CreateSession CreateStandardSession = gateway.CreateStandardSession - GetTLSClient = gateway.GetTLSClient - MockOrgID = gateway.MockOrgID - UpdateAPIVersion = gateway.UpdateAPIVersion - TransformBody = gateway.TransformBody - TestReq = gateway.TestReq + GetTLSClient = gateway.GetTLSClient + MockOrgID = gateway.MockOrgID + UpdateAPIVersion = gateway.UpdateAPIVersion + TransformBody = gateway.TransformBody + TestReq = gateway.TestReq ) diff --git a/gateway/dashboard_register.go b/gateway/dashboard_register.go index bc52d0528c9..2fe0beca5aa 100644 --- a/gateway/dashboard_register.go +++ b/gateway/dashboard_register.go @@ -117,10 +117,10 @@ func (gw *Gateway) reLogin() { } func (h *HTTPDashboardHandler) Init() error { - h.RegistrationEndpoint = h.Gw.buildDashboardConnStr("/register/node") - h.DeRegistrationEndpoint = h.Gw.buildDashboardConnStr("/system/node") - h.HeartBeatEndpoint = h.Gw.buildDashboardConnStr("/register/ping") - h.KeyQuotaTriggerEndpoint = h.Gw.buildDashboardConnStr("/system/key/quota_trigger") + h.RegistrationEndpoint = h.Gw.BuildDashboardConnStr("/register/node") + h.DeRegistrationEndpoint = h.Gw.BuildDashboardConnStr("/system/node") + h.HeartBeatEndpoint = h.Gw.BuildDashboardConnStr("/register/ping") + h.KeyQuotaTriggerEndpoint = h.Gw.BuildDashboardConnStr("/system/key/quota_trigger") if h.Secret = h.Gw.GetConfig().NodeSecret; h.Secret == "" { dashLog.Fatal("Node secret is not set, required for dashboard connection") diff --git a/gateway/dashboard_register_test.go b/gateway/dashboard_register_test.go index 9fa628aeacf..aa0aadc8995 100644 --- a/gateway/dashboard_register_test.go +++ b/gateway/dashboard_register_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "testing" @@ -24,29 +24,7 @@ func Test_BuildDashboardConnStr(t *testing.T) { ts.Gw.SetConfig(cfg) }() - connStr := ts.Gw.buildDashboardConnStr("/test") + connStr := ts.Gw.BuildDashboardConnStr("/test") assert.Equal(t, connStr, "http://localhost/test") } - -func Test_DashboardLifecycle(t *testing.T) { - var handler HTTPDashboardHandler - - handler = HTTPDashboardHandler{ - heartBeatStopSentinel: HeartBeatStarted, - } - assert.False(t, handler.isHeartBeatStopped()) - - handler = HTTPDashboardHandler{ - heartBeatStopSentinel: HeartBeatStopped, - } - - assert.True(t, handler.isHeartBeatStopped()) - - handler = HTTPDashboardHandler{ - heartBeatStopSentinel: HeartBeatStarted, - } - - handler.StopBeating() - assert.True(t, handler.isHeartBeatStopped()) -} diff --git a/gateway/mw_ip_blacklist_test.go b/gateway/mw_ip_blacklist_test.go index 1321e724d53..a18fe9ac590 100644 --- a/gateway/mw_ip_blacklist_test.go +++ b/gateway/mw_ip_blacklist_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "net/http" diff --git a/gateway/mw_ip_whitelist_test.go b/gateway/mw_ip_whitelist_test.go index e011f216c40..93337afd7ff 100644 --- a/gateway/mw_ip_whitelist_test.go +++ b/gateway/mw_ip_whitelist_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "net/http" diff --git a/gateway/mw_validate_json_test.go b/gateway/mw_validate_json_test.go index 70ed7593021..c9dd38b84b6 100644 --- a/gateway/mw_validate_json_test.go +++ b/gateway/mw_validate_json_test.go @@ -1,61 +1,17 @@ -package gateway +package gateway_test import ( - "encoding/json" - "fmt" "net/http" "testing" - "github.com/TykTechnologies/tyk/apidef" "github.com/TykTechnologies/tyk/test" ) -var testJsonSchema = `{ - "title": "Person", - "type": "object", - "properties": { - "firstName": { - "type": "string" - }, - "lastName": { - "type": "string" - }, - "age": { - "description": "Age in years", - "type": "integer", - "minimum": 0 - }, - "objs":{ - "enum":["a","b","c"], - "type":"string" - } - }, - "required": ["firstName", "lastName"] -}` - -func (ts *Test) testPrepareValidateJSONSchema(enabled bool) { - - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - UpdateAPIVersion(spec, "v1", func(v *apidef.VersionInfo) { - json.Unmarshal([]byte(`[ - { - "disabled": `+fmt.Sprintf("%v,", !enabled)+` - "path": "/v", - "method": "POST", - "schema": `+testJsonSchema+` - } - ]`), &v.ExtendedPaths.ValidateJSON) - }) - - spec.Proxy.ListenPath = "/" - }) -} - func TestValidateJSONSchema(t *testing.T) { ts := StartTest(nil) defer ts.Close() - ts.testPrepareValidateJSONSchema(true) + ts.TestPrepareValidateJSONSchema(true) _, _ = ts.Run(t, []test.TestCase{ {Method: http.MethodPost, Path: "/without_validation", Data: "{not_valid}", Code: http.StatusOK}, @@ -67,7 +23,7 @@ func TestValidateJSONSchema(t *testing.T) { }...) t.Run("disabled", func(t *testing.T) { - ts.testPrepareValidateJSONSchema(false) + ts.TestPrepareValidateJSONSchema(false) _, _ = ts.Run(t, []test.TestCase{ {Method: http.MethodPost, Path: "/without_validation", Data: "{not_valid}", Code: http.StatusOK}, @@ -83,7 +39,7 @@ func BenchmarkValidateJSONSchema(b *testing.B) { ts := StartTest(nil) defer ts.Close() - ts.testPrepareValidateJSONSchema(true) + ts.TestPrepareValidateJSONSchema(true) for i := 0; i < b.N; i++ { ts.Run(b, []test.TestCase{ diff --git a/gateway/redis_signals.go b/gateway/redis_signals.go index 6262a253e7b..c4f7f815a77 100644 --- a/gateway/redis_signals.go +++ b/gateway/redis_signals.go @@ -77,13 +77,9 @@ func (gw *Gateway) startPubSubLoop() { } gw.logPubSubError(err, message) - gw.addPubSubDelay(10 * time.Second) - } -} -// addPubSubDelay sleeps for duration -func (gw *Gateway) addPubSubDelay(dur time.Duration) { - time.Sleep(dur) + time.Sleep(10 * time.Second) + } } // isPubSubError returns true if err != nil, logs error diff --git a/gateway/redis_signals_test.go b/gateway/redis_signals_test.go deleted file mode 100644 index 5fd6ab7a508..00000000000 --- a/gateway/redis_signals_test.go +++ /dev/null @@ -1,52 +0,0 @@ -package gateway - -import ( - "errors" - "fmt" - "testing" - "time" - - "github.com/stretchr/testify/assert" -) - -// TestPubSubInternals is an unit test for code coverage -func TestPubSubInternals(t *testing.T) { - g := StartTest(nil) - defer g.Close() - - message := "from test, expected log output" - - testcases := []struct { - name string - testFn func(*testing.T) - }{ - { - name: "test error log, err == nil", - testFn: func(t *testing.T) { - t.Helper() - var err error - assert.False(t, g.Gw.logPubSubError(err, message)) - }, - }, - { - name: "test error log, err != nil", - testFn: func(t *testing.T) { - t.Helper() - var err = errors.New("test err") - assert.True(t, g.Gw.logPubSubError(err, message)) - }, - }, - { - name: "test add delay", - testFn: func(t *testing.T) { - t.Helper() - g.Gw.addPubSubDelay(time.Microsecond) - assert.True(t, true) - }, - }, - } - - for idx, tc := range testcases { - t.Run(fmt.Sprintf("Test case #%d: %s", idx, tc.name), tc.testFn) - } -} diff --git a/gateway/res_cache_test.go b/gateway/res_cache_test.go index 8461ac31d95..2e3d5957989 100644 --- a/gateway/res_cache_test.go +++ b/gateway/res_cache_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "testing" diff --git a/gateway/res_handler_go_plugin_test.go b/gateway/res_handler_go_plugin_test.go index 32226d5dba2..5183de562e2 100644 --- a/gateway/res_handler_go_plugin_test.go +++ b/gateway/res_handler_go_plugin_test.go @@ -1,11 +1,10 @@ -package gateway +package gateway_test import ( "testing" - "github.com/stretchr/testify/require" - "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/TykTechnologies/tyk/apidef" ) diff --git a/gateway/server.go b/gateway/server.go index aa20ee19eea..6f21da674ce 100644 --- a/gateway/server.go +++ b/gateway/server.go @@ -446,7 +446,7 @@ func (gw *Gateway) setupGlobals() { gw.readGraphqlPlaygroundTemplate() } -func (gw *Gateway) buildDashboardConnStr(resource string) string { +func (gw *Gateway) BuildDashboardConnStr(resource string) string { if gw.GetConfig().DBAppConfOptions.ConnectionString == "" && gw.GetConfig().DisableDashboardZeroConf { mainLog.Fatal("Connection string is empty, failing.") } @@ -466,7 +466,7 @@ func (gw *Gateway) syncAPISpecs() (int, error) { var s []*APISpec if gw.GetConfig().UseDBAppConfigs { - connStr := gw.buildDashboardConnStr("/system/apis") + connStr := gw.BuildDashboardConnStr("/system/apis") tmpSpecs, err := loader.FromDashboardService(connStr) if err != nil { log.Error("failed to load API specs: ", err) diff --git a/gateway/testutil_test.go b/gateway/testutil_test.go index 86c27ad0e27..4af2076a8cb 100644 --- a/gateway/testutil_test.go +++ b/gateway/testutil_test.go @@ -2,6 +2,8 @@ package gateway import ( "encoding/base64" + "encoding/json" + "fmt" "github.com/TykTechnologies/tyk/apidef" "github.com/TykTechnologies/tyk/user" @@ -64,3 +66,43 @@ func (ts *Test) testPrepareVirtualEndpoint(js, method, path string, proxyOnError } }) } + +var testJsonSchema = `{ + "title": "Person", + "type": "object", + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + }, + "age": { + "description": "Age in years", + "type": "integer", + "minimum": 0 + }, + "objs":{ + "enum":["a","b","c"], + "type":"string" + } + }, + "required": ["firstName", "lastName"] +}` + +func (ts *Test) TestPrepareValidateJSONSchema(enabled bool) { + ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { + UpdateAPIVersion(spec, "v1", func(v *apidef.VersionInfo) { + json.Unmarshal([]byte(`[ + { + "disabled": `+fmt.Sprintf("%v,", !enabled)+` + "path": "/v", + "method": "POST", + "schema": `+testJsonSchema+` + } + ]`), &v.ExtendedPaths.ValidateJSON) + }) + + spec.Proxy.ListenPath = "/" + }) +} From fc26b1cea68ecdac6f076eb279c7137663032299 Mon Sep 17 00:00:00 2001 From: Tit Petric Date: Sat, 5 Oct 2024 15:53:48 +0200 Subject: [PATCH 5/5] Update with more black box tests --- gateway/api_test.go | 13 ++-- gateway/blackbox_test.go | 28 +++++++- gateway/looping_test.go | 2 +- gateway/mw_basic_auth_test.go | 79 ++++++++++----------- gateway/mw_context_vars_test.go | 26 +------ gateway/mw_example_test.go | 2 +- gateway/mw_graphql_complexity_test.go | 3 +- gateway/mw_js_plugin_test.go | 2 +- gateway/mw_modify_headers_test.go | 2 +- gateway/mw_redis_cache.go | 4 +- gateway/mw_url_rewrite_test.go | 8 +-- gateway/mw_virtual_endpoint_test.go | 36 ++++------ gateway/res_handler_header_injector_test.go | 15 ++-- gateway/testutil_test.go | 22 +++++- 14 files changed, 126 insertions(+), 116 deletions(-) diff --git a/gateway/api_test.go b/gateway/api_test.go index 3f7f8a86a2a..05ab0c2b735 100644 --- a/gateway/api_test.go +++ b/gateway/api_test.go @@ -30,6 +30,7 @@ import ( "github.com/TykTechnologies/tyk/apidef/oas" "github.com/TykTechnologies/tyk/certs" "github.com/TykTechnologies/tyk/config" + "github.com/TykTechnologies/tyk/ctx" "github.com/TykTechnologies/tyk/internal/uuid" "github.com/TykTechnologies/tyk/storage" "github.com/TykTechnologies/tyk/test" @@ -963,7 +964,7 @@ func TestDisableKeyActionsByUserName(t *testing.T) { ts := StartTest(conf) defer ts.Close() - session := ts.testPrepareBasicAuth(false) + session := ts.TestPrepareBasicAuth(false) userName := "defaultuser1" res, _ := ts.Run(t, []test.TestCase{ { @@ -1042,7 +1043,7 @@ func TestHashKeyHandlerLegacyWithHashFunc(t *testing.T) { ts.Gw.SetConfig(globalConf) // create session with legacy key format - session := ts.testPrepareBasicAuth(false) + session := ts.TestPrepareBasicAuth(false) _, _ = ts.Run(t, []test.TestCase{ { @@ -1207,7 +1208,7 @@ func (ts *Test) testHashKeyHandlerHelper(t *testing.T, expectedHashSize int) { func (ts *Test) testHashFuncAndBAHelper(t *testing.T) { t.Helper() - session := ts.testPrepareBasicAuth(false) + session := ts.TestPrepareBasicAuth(false) _, _ = ts.Run(t, []test.TestCase{ { @@ -1953,7 +1954,7 @@ func TestContextSession(t *testing.T) { t.Fatal("expected ctxGetSession to return nil") } - ctxSetSession(r, + ctx.SetSession(r, &user.SessionState{}, false, false) @@ -1963,10 +1964,10 @@ func TestContextSession(t *testing.T) { } defer func() { if r := recover(); r == nil { - t.Fatal("expected ctxSetSession of zero val to panic") + t.Fatal("expected ctx.SetSession of zero val to panic") } }() - ctxSetSession(r, nil, false, false) + ctx.SetSession(r, nil, false, false) } func TestRotateClientSecretHandler(t *testing.T) { diff --git a/gateway/blackbox_test.go b/gateway/blackbox_test.go index 124196822ef..a8bb9776dd1 100644 --- a/gateway/blackbox_test.go +++ b/gateway/blackbox_test.go @@ -1,6 +1,9 @@ package gateway_test import ( + "net/http" + + "github.com/TykTechnologies/tyk/ctx" "github.com/TykTechnologies/tyk/gateway" ) @@ -20,6 +23,8 @@ type ( ResponseGoPluginMiddleware = gateway.ResponseGoPluginMiddleware IPWhiteListMiddleware = gateway.IPWhiteListMiddleware IPBlackListMiddleware = gateway.IPBlackListMiddleware + // Slight naming violation + MiddlewareContextVars = gateway.MiddlewareContextVars // Tests leakage. Test = gateway.Test @@ -39,6 +44,8 @@ type ( HeaderTransform = gateway.HeaderTransform HeaderTransformOptions = gateway.HeaderTransformOptions VersionMetas = gateway.VersionMetas + HeaderInjector = gateway.HeaderInjector + TransformHeaders = gateway.TransformHeaders // Interfaces (data model). IdExtractor = gateway.IdExtractor @@ -53,7 +60,8 @@ const ( EH_LogHandler = gateway.EH_LogHandler EH_WebHook = gateway.EH_WebHook - NoticeGroupReload = gateway.NoticeGroupReload + NoticeGroupReload = gateway.NoticeGroupReload + CachedResponseHeader = gateway.CachedResponseHeader ) // Global functions are a coupling. @@ -73,3 +81,21 @@ var ( TransformBody = gateway.TransformBody TestReq = gateway.TestReq ) + +// Alas, we have some internals. +var ( + proxyOnErrorEnabled = true + keylessAuthEnabled = true + cacheEnabled = true + + proxyOnErrorDisabled = false + keylessAuthDisabled = false + cacheDisabled = false +) + +func ctxGetData(r *http.Request) map[string]interface{} { + if v := r.Context().Value(ctx.ContextData); v != nil { + return v.(map[string]interface{}) + } + return nil +} diff --git a/gateway/looping_test.go b/gateway/looping_test.go index ea573350d80..b977bab6337 100644 --- a/gateway/looping_test.go +++ b/gateway/looping_test.go @@ -187,7 +187,7 @@ func TestLooping(t *testing.T) { t.Run("VirtualEndpoint or plugins", func(t *testing.T) { test.Flaky(t) // TT-10511 - ts.testPrepareVirtualEndpoint(` + ts.TestPrepareVirtualEndpoint(` function testVirtData(request, session, config) { var loopLocation = "/default" diff --git a/gateway/mw_basic_auth_test.go b/gateway/mw_basic_auth_test.go index 4e747988fb4..dd4c0e246c7 100644 --- a/gateway/mw_basic_auth_test.go +++ b/gateway/mw_basic_auth_test.go @@ -1,36 +1,29 @@ package gateway import ( - "encoding/base64" "fmt" "net/http" - "strings" "testing" "github.com/stretchr/testify/assert" + "github.com/TykTechnologies/tyk/internal/httputil" "github.com/TykTechnologies/tyk/storage" "github.com/TykTechnologies/tyk/test" "github.com/TykTechnologies/tyk/user" ) -func genAuthHeader(username, password string) string { - toEncode := strings.Join([]string{username, password}, ":") - encodedPass := base64.StdEncoding.EncodeToString([]byte(toEncode)) - return fmt.Sprintf("Basic %s", encodedPass) -} - func TestBasicAuth(t *testing.T) { test.Flaky(t) // TODO: TT-5223 ts := StartTest(nil) defer ts.Close() - session := ts.testPrepareBasicAuth(false) + session := ts.TestPrepareBasicAuth(false) - validPassword := map[string]string{"Authorization": genAuthHeader("user", "password")} - wrongPassword := map[string]string{"Authorization": genAuthHeader("user", "wrong")} - wrongFormat := map[string]string{"Authorization": genAuthHeader("user", "password:more")} + validPassword := map[string]string{"Authorization": httputil.AuthHeader("user", "password")} + wrongPassword := map[string]string{"Authorization": httputil.AuthHeader("user", "wrong")} + wrongFormat := map[string]string{"Authorization": httputil.AuthHeader("user", "password:more")} malformed := map[string]string{"Authorization": "not base64"} ts.Run(t, []test.TestCase{ @@ -93,9 +86,9 @@ func TestBasicAuthLegacyWithHashFunc(t *testing.T) { ts.Gw.SetConfig(globalConf) // create session with legacy key format - session := ts.testPrepareBasicAuth(false) + session := ts.TestPrepareBasicAuth(false) - validPassword := map[string]string{"Authorization": genAuthHeader("user", "password")} + validPassword := map[string]string{"Authorization": httputil.AuthHeader("user", "password")} ts.Run(t, []test.TestCase{ // Create base auth based key @@ -143,7 +136,7 @@ func TestBasicAuthHashKeyFunc(t *testing.T) { globalConf.BasicAuthHashKeyFunction = hashKeyFunc.in ts.Gw.SetConfig(globalConf) - session := ts.testPrepareBasicAuth(false) + session := ts.TestPrepareBasicAuth(false) ts.Gw.setBasicAuthSessionPassword(session) assert.Equal(t, hashKeyFunc.out, string(session.BasicAuthData.Hash)) @@ -173,17 +166,17 @@ func TestBasicAuthCachedUserCollision(t *testing.T) { globalConf.HashKeyFunction = "murmur64" ts.Gw.SetConfig(globalConf) - session := ts.testPrepareBasicAuth(false) + session := ts.TestPrepareBasicAuth(false) - correct := map[string]string{"Authorization": genAuthHeader("bellbell1", "password")} - remove1 := map[string]string{"Authorization": genAuthHeader("bellbell", "password")} - remove2 := map[string]string{"Authorization": genAuthHeader("bellbel", "password")} - remove3 := map[string]string{"Authorization": genAuthHeader("bellbe", "password")} - remove4 := map[string]string{"Authorization": genAuthHeader("bellb", "password")} - remove5 := map[string]string{"Authorization": genAuthHeader("bell", "password")} - add1 := map[string]string{"Authorization": genAuthHeader("bellbell11", "password")} - add2 := map[string]string{"Authorization": genAuthHeader("bellbell12", "password")} - add3 := map[string]string{"Authorization": genAuthHeader("bellbell13", "password")} + correct := map[string]string{"Authorization": httputil.AuthHeader("bellbell1", "password")} + remove1 := map[string]string{"Authorization": httputil.AuthHeader("bellbell", "password")} + remove2 := map[string]string{"Authorization": httputil.AuthHeader("bellbel", "password")} + remove3 := map[string]string{"Authorization": httputil.AuthHeader("bellbe", "password")} + remove4 := map[string]string{"Authorization": httputil.AuthHeader("bellb", "password")} + remove5 := map[string]string{"Authorization": httputil.AuthHeader("bell", "password")} + add1 := map[string]string{"Authorization": httputil.AuthHeader("bellbell11", "password")} + add2 := map[string]string{"Authorization": httputil.AuthHeader("bellbell12", "password")} + add3 := map[string]string{"Authorization": httputil.AuthHeader("bellbell13", "password")} ts.Run(t, []test.TestCase{ // Create base auth based key @@ -206,18 +199,18 @@ func TestBasicAuthCachedPasswordCollision(t *testing.T) { defer ts.Close() for _, useCache := range []bool{true, false} { - correct := map[string]string{"Authorization": genAuthHeader("bellbell1", "password")} - remove1 := map[string]string{"Authorization": genAuthHeader("bellbell1", "passwor")} - remove2 := map[string]string{"Authorization": genAuthHeader("bellbell1", "passwo")} - remove3 := map[string]string{"Authorization": genAuthHeader("bellbell1", "passw")} - remove4 := map[string]string{"Authorization": genAuthHeader("bellbell1", "pass")} - remove5 := map[string]string{"Authorization": genAuthHeader("bellbell1", "pas")} - add1 := map[string]string{"Authorization": genAuthHeader("bellbell1", "password1")} - add2 := map[string]string{"Authorization": genAuthHeader("bellbell1", "password22")} - add3 := map[string]string{"Authorization": genAuthHeader("bellbell1", "password333")} + correct := map[string]string{"Authorization": httputil.AuthHeader("bellbell1", "password")} + remove1 := map[string]string{"Authorization": httputil.AuthHeader("bellbell1", "passwor")} + remove2 := map[string]string{"Authorization": httputil.AuthHeader("bellbell1", "passwo")} + remove3 := map[string]string{"Authorization": httputil.AuthHeader("bellbell1", "passw")} + remove4 := map[string]string{"Authorization": httputil.AuthHeader("bellbell1", "pass")} + remove5 := map[string]string{"Authorization": httputil.AuthHeader("bellbell1", "pas")} + add1 := map[string]string{"Authorization": httputil.AuthHeader("bellbell1", "password1")} + add2 := map[string]string{"Authorization": httputil.AuthHeader("bellbell1", "password22")} + add3 := map[string]string{"Authorization": httputil.AuthHeader("bellbell1", "password333")} t.Run(fmt.Sprintf("Cache disabled:%v", useCache), func(t *testing.T) { - session := ts.testPrepareBasicAuth(useCache) + session := ts.TestPrepareBasicAuth(useCache) ts.Run(t, []test.TestCase{ // Create base auth based key @@ -243,11 +236,11 @@ func BenchmarkBasicAuth(b *testing.B) { ts := StartTest(nil) defer ts.Close() - session := ts.testPrepareBasicAuth(false) + session := ts.TestPrepareBasicAuth(false) - validPassword := map[string]string{"Authorization": genAuthHeader("user", "password")} - wrongPassword := map[string]string{"Authorization": genAuthHeader("user", "wrong")} - wrongFormat := map[string]string{"Authorization": genAuthHeader("user", "password:more")} + validPassword := map[string]string{"Authorization": httputil.AuthHeader("user", "password")} + wrongPassword := map[string]string{"Authorization": httputil.AuthHeader("user", "wrong")} + wrongFormat := map[string]string{"Authorization": httputil.AuthHeader("user", "password:more")} malformed := map[string]string{"Authorization": "not base64"} // Create base auth based key @@ -276,9 +269,9 @@ func BenchmarkBasicAuth_CacheEnabled(b *testing.B) { ts := StartTest(nil) defer ts.Close() - session := ts.testPrepareBasicAuth(false) + session := ts.TestPrepareBasicAuth(false) - validPassword := map[string]string{"Authorization": genAuthHeader("user", "password")} + validPassword := map[string]string{"Authorization": httputil.AuthHeader("user", "password")} // Create base auth based key ts.Run(b, test.TestCase{ @@ -302,9 +295,9 @@ func BenchmarkBasicAuth_CacheDisabled(b *testing.B) { ts := StartTest(nil) defer ts.Close() - session := ts.testPrepareBasicAuth(true) + session := ts.TestPrepareBasicAuth(true) - validPassword := map[string]string{"Authorization": genAuthHeader("user", "password")} + validPassword := map[string]string{"Authorization": httputil.AuthHeader("user", "password")} // Create base auth based key ts.Run(b, test.TestCase{ diff --git a/gateway/mw_context_vars_test.go b/gateway/mw_context_vars_test.go index bc0b9c4ae86..ac12a354ee5 100644 --- a/gateway/mw_context_vars_test.go +++ b/gateway/mw_context_vars_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "io" @@ -11,34 +11,14 @@ import ( "github.com/google/go-cmp/cmp" - "github.com/TykTechnologies/tyk/apidef" "github.com/TykTechnologies/tyk/test" ) -func (ts *Test) testPrepareContextVarsMiddleware() { - - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - spec.Proxy.ListenPath = "/" - spec.EnableContextVars = true - spec.VersionData.Versions = map[string]apidef.VersionInfo{ - "v1": { - UseExtendedPaths: true, - GlobalHeaders: map[string]string{ - "X-Static": "foo", - "X-Request-ID": "$tyk_context.request_id", - "X-Path": "$tyk_context.path", - "X-Remote-Addr": "$tyk_context.remote_addr", - }, - }, - } - }) -} - func TestContextVarsMiddleware(t *testing.T) { ts := StartTest(nil) defer ts.Close() - ts.testPrepareContextVarsMiddleware() + ts.TestPrepareContextVarsMiddleware() ts.Run(t, []test.TestCase{ {Path: "/test/path", Code: 200, BodyMatch: `"X-Remote-Addr":"127.0.0.1"`}, @@ -54,7 +34,7 @@ func BenchmarkContextVarsMiddleware(b *testing.B) { ts := StartTest(nil) defer ts.Close() - ts.testPrepareContextVarsMiddleware() + ts.TestPrepareContextVarsMiddleware() for i := 0; i < b.N; i++ { ts.Run(b, []test.TestCase{ diff --git a/gateway/mw_example_test.go b/gateway/mw_example_test.go index 9838f2c71a6..aee82e10b2e 100644 --- a/gateway/mw_example_test.go +++ b/gateway/mw_example_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "errors" diff --git a/gateway/mw_graphql_complexity_test.go b/gateway/mw_graphql_complexity_test.go index 0872bf9e210..290773b7e30 100644 --- a/gateway/mw_graphql_complexity_test.go +++ b/gateway/mw_graphql_complexity_test.go @@ -10,6 +10,7 @@ import ( "github.com/TykTechnologies/graphql-go-tools/pkg/graphql" + "github.com/TykTechnologies/tyk/ctx" "github.com/TykTechnologies/tyk/user" ) @@ -271,7 +272,7 @@ func TestGraphQLComplexityMiddleware_ProcessRequest_GraphqlLimits(t *testing.T) session := user.NewSessionState() session.MaxQueryDepth = 3 - ctxSetSession(httpReq, session, false, false) + ctx.SetSession(httpReq, session, false, false) cases := []struct { name string diff --git a/gateway/mw_js_plugin_test.go b/gateway/mw_js_plugin_test.go index f9cfce13840..9726193c071 100644 --- a/gateway/mw_js_plugin_test.go +++ b/gateway/mw_js_plugin_test.go @@ -213,7 +213,7 @@ func TestJSVMSessionMetadataUpdate(t *testing.T) { s.MetaData["same"] = "same" s.MetaData["updated"] = "old" s.MetaData["removed"] = "dummy" - ctxSetSession(req, s, true, ts.Gw.GetConfig().HashKeys) + ctx.SetSession(req, s, true, ts.Gw.GetConfig().HashKeys) const js = ` var testJSVMMiddleware = new TykJS.TykMiddleware.NewMiddleware({}); diff --git a/gateway/mw_modify_headers_test.go b/gateway/mw_modify_headers_test.go index 7093be7afd5..7c8006dc03f 100644 --- a/gateway/mw_modify_headers_test.go +++ b/gateway/mw_modify_headers_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "testing" diff --git a/gateway/mw_redis_cache.go b/gateway/mw_redis_cache.go index 3db91eba964..bc124cadd32 100644 --- a/gateway/mw_redis_cache.go +++ b/gateway/mw_redis_cache.go @@ -24,7 +24,7 @@ import ( ) const ( - cachedResponseHeader = "x-tyk-cached-response" + CachedResponseHeader = "x-tyk-cached-response" ) // RedisCacheMiddleware is a caching middleware that will pull data from Redis instead of the upstream proxy @@ -255,7 +255,7 @@ func (m *RedisCacheMiddleware) ProcessRequest(w http.ResponseWriter, r *http.Req newRes.Header.Set(header.XRateLimitRemaining, strconv.Itoa(int(quotaRemaining))) newRes.Header.Set(header.XRateLimitReset, strconv.Itoa(int(quotaRenews))) } - newRes.Header.Set(cachedResponseHeader, "1") + newRes.Header.Set(CachedResponseHeader, "1") copyHeader(w.Header(), newRes.Header, m.Gw.GetConfig().IgnoreCanonicalMIMEHeaderKey) diff --git a/gateway/mw_url_rewrite_test.go b/gateway/mw_url_rewrite_test.go index 1da2fbc3072..29b7115c18f 100644 --- a/gateway/mw_url_rewrite_test.go +++ b/gateway/mw_url_rewrite_test.go @@ -936,7 +936,7 @@ func TestRewriterTriggers(t *testing.T) { hOpt := apidef.StringRegexMap{MatchPattern: "bar"} hOpt.Init() - ctxSetSession(r, &user.SessionState{ + ctx.SetSession(r, &user.SessionState{ MetaData: map[string]interface{}{ "rewrite": "bar-baz", }, @@ -965,7 +965,7 @@ func TestRewriterTriggers(t *testing.T) { hOpt := apidef.StringRegexMap{MatchPattern: "bar-(\\w+)"} hOpt.Init() - ctxSetSession(r, &user.SessionState{ + ctx.SetSession(r, &user.SessionState{ MetaData: map[string]interface{}{ "rewrite": "bar-baz", }, @@ -994,7 +994,7 @@ func TestRewriterTriggers(t *testing.T) { hOpt := apidef.StringRegexMap{MatchPattern: "bar"} hOpt.Init() - ctxSetSession(r, &user.SessionState{ + ctx.SetSession(r, &user.SessionState{ MetaData: map[string]interface{}{ "rewrite": "bar-baz", "somevar": "someval", @@ -1051,7 +1051,7 @@ func TestRewriterTriggers(t *testing.T) { hOpt := apidef.StringRegexMap{MatchPattern: "foo"} hOpt.Init() - ctxSetSession(r, &user.SessionState{ + ctx.SetSession(r, &user.SessionState{ MetaData: map[string]interface{}{ "rewrite": "bar-baz", }, diff --git a/gateway/mw_virtual_endpoint_test.go b/gateway/mw_virtual_endpoint_test.go index 0754df74ea8..56bcbbe8e53 100644 --- a/gateway/mw_virtual_endpoint_test.go +++ b/gateway/mw_virtual_endpoint_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "net/http" @@ -25,21 +25,11 @@ function testVirtData(request, session, config) { } ` -var ( - proxyOnErrorEnabled = true - keylessAuthEnabled = true - cacheEnabled = true - - proxyOnErrorDisabled = false - keylessAuthDisabled = false - cacheDisabled = false -) - func TestVirtualEndpoint(t *testing.T) { ts := StartTest(nil) defer ts.Close() - ts.testPrepareVirtualEndpoint(virtTestJS, "GET", "/virt1", + ts.TestPrepareVirtualEndpoint(virtTestJS, "GET", "/virt1", proxyOnErrorDisabled, keylessAuthEnabled, cacheEnabled, false) _, _ = ts.Run(t, @@ -48,7 +38,7 @@ func TestVirtualEndpoint(t *testing.T) { Code: 202, BodyMatch: "foobar", HeadersNotMatch: map[string]string{ - cachedResponseHeader: "1", + CachedResponseHeader: "1", }, HeadersMatch: map[string]string{ "data-foo": "x", @@ -62,7 +52,7 @@ func TestVirtualEndpoint(t *testing.T) { HeadersMatch: map[string]string{ "data-foo": "x", "data-bar-y": "3", - cachedResponseHeader: "1", + CachedResponseHeader: "1", }, }, ) @@ -72,7 +62,7 @@ func TestVirtualEndpointNotCached(t *testing.T) { ts := StartTest(nil) defer ts.Close() - ts.testPrepareVirtualEndpoint(virtTestJS, "GET", "/virt", + ts.TestPrepareVirtualEndpoint(virtTestJS, "GET", "/virt", proxyOnErrorDisabled, keylessAuthEnabled, cacheDisabled, false) _, _ = ts.Run(t, @@ -81,7 +71,7 @@ func TestVirtualEndpointNotCached(t *testing.T) { Code: 202, BodyMatch: "foobar", HeadersNotMatch: map[string]string{ - cachedResponseHeader: "1", + CachedResponseHeader: "1", }, HeadersMatch: map[string]string{ "data-foo": "x", @@ -93,7 +83,7 @@ func TestVirtualEndpointNotCached(t *testing.T) { Code: 202, BodyMatch: "foobar", HeadersNotMatch: map[string]string{ - cachedResponseHeader: "1", + CachedResponseHeader: "1", }, HeadersMatch: map[string]string{ "data-foo": "x", @@ -118,7 +108,7 @@ func TestVirtualEndpoint500NotCached(t *testing.T) { } func testErrorResponse(ts *Test, t *testing.T, cache bool) { - ts.testPrepareVirtualEndpoint("abc", "GET", "/abc", + ts.TestPrepareVirtualEndpoint("abc", "GET", "/abc", proxyOnErrorDisabled, keylessAuthEnabled, cache, false) _, _ = ts.Run(t, @@ -126,14 +116,14 @@ func testErrorResponse(ts *Test, t *testing.T, cache bool) { Path: "/abc", Code: http.StatusInternalServerError, HeadersNotMatch: map[string]string{ - cachedResponseHeader: "1", + CachedResponseHeader: "1", }, }, test.TestCase{ Path: "/abc", Code: http.StatusInternalServerError, HeadersNotMatch: map[string]string{ - cachedResponseHeader: "1", + CachedResponseHeader: "1", }, }, ) @@ -154,7 +144,7 @@ func TestVirtualEndpointSessionMetadata(t *testing.T) { } }) - ts.testPrepareVirtualEndpoint(virtTestJS, "GET", "/abc", + ts.TestPrepareVirtualEndpoint(virtTestJS, "GET", "/abc", proxyOnErrorDisabled, keylessAuthDisabled, cacheEnabled, false) _, _ = ts.Run(t, @@ -177,7 +167,7 @@ func BenchmarkVirtualEndpoint(b *testing.B) { ts := StartTest(nil) defer ts.Close() - ts.testPrepareVirtualEndpoint(virtTestJS, "GET", "/virt", + ts.TestPrepareVirtualEndpoint(virtTestJS, "GET", "/virt", proxyOnErrorEnabled, keylessAuthEnabled, cacheEnabled, false) for i := 0; i < b.N; i++ { @@ -197,7 +187,7 @@ func TestVirtualEndpointDisabled(t *testing.T) { ts := StartTest(nil) defer ts.Close() - ts.testPrepareVirtualEndpoint(virtTestJS, "GET", "/virt2", + ts.TestPrepareVirtualEndpoint(virtTestJS, "GET", "/virt2", proxyOnErrorDisabled, keylessAuthEnabled, false, true) _, _ = ts.Run(t, diff --git a/gateway/res_handler_header_injector_test.go b/gateway/res_handler_header_injector_test.go index cc9c1f2d961..4786e628235 100644 --- a/gateway/res_handler_header_injector_test.go +++ b/gateway/res_handler_header_injector_test.go @@ -1,4 +1,4 @@ -package gateway +package gateway_test import ( "encoding/json" @@ -8,6 +8,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/TykTechnologies/tyk/apidef" + "github.com/TykTechnologies/tyk/internal/build" "github.com/TykTechnologies/tyk/test" ) @@ -95,18 +96,18 @@ func TestResponseHeaderInjection(t *testing.T) { } addHeadersCached := map[string]string{ "X-Test": "test", - cachedResponseHeader: "1", + CachedResponseHeader: "1", } deleteHeaders := map[string]string{ "X-Tyk-Test": "1", - cachedResponseHeader: "1", + CachedResponseHeader: "1", } deleteHeadersCached := map[string]string{ "X-Tyk-Test": "1", } - userAgent := fmt.Sprintf("\"User-Agent\":\"Tyk/%v\"", VERSION) + userAgent := fmt.Sprintf("\"User-Agent\":\"Tyk/%v\"", build.Version) _, _ = ts.Run(t, []test.TestCase{ // Create base auth based key @@ -132,18 +133,18 @@ func BenchmarkResponseHeaderInjection(b *testing.B) { } addHeadersCached := map[string]string{ "X-Test": "test", - cachedResponseHeader: "1", + CachedResponseHeader: "1", } deleteHeaders := map[string]string{ "X-Tyk-Test": "1", - cachedResponseHeader: "1", + CachedResponseHeader: "1", } deleteHeadersCached := map[string]string{ "X-Tyk-Test": "1", } - userAgent := fmt.Sprintf("\"User-Agent\":\"Tyk/%v\"", VERSION) + userAgent := fmt.Sprintf("\"User-Agent\":\"Tyk/%v\"", build.Version) for i := 0; i < b.N; i++ { _, _ = ts.Run(b, []test.TestCase{ diff --git a/gateway/testutil_test.go b/gateway/testutil_test.go index 4af2076a8cb..d97c607c4b4 100644 --- a/gateway/testutil_test.go +++ b/gateway/testutil_test.go @@ -9,7 +9,7 @@ import ( "github.com/TykTechnologies/tyk/user" ) -func (ts *Test) testPrepareBasicAuth(cacheDisabled bool) *user.SessionState { +func (ts *Test) TestPrepareBasicAuth(cacheDisabled bool) *user.SessionState { session := CreateStandardSession() session.BasicAuthData.Password = "password" session.AccessRights = map[string]user.AccessDefinition{"test": {APIID: "test", Versions: []string{"v1"}}} @@ -26,7 +26,25 @@ func (ts *Test) testPrepareBasicAuth(cacheDisabled bool) *user.SessionState { return session } -func (ts *Test) testPrepareVirtualEndpoint(js, method, path string, proxyOnError, keyless, cacheEnabled, disabled bool) { +func (ts *Test) TestPrepareContextVarsMiddleware() { + ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { + spec.Proxy.ListenPath = "/" + spec.EnableContextVars = true + spec.VersionData.Versions = map[string]apidef.VersionInfo{ + "v1": { + UseExtendedPaths: true, + GlobalHeaders: map[string]string{ + "X-Static": "foo", + "X-Request-ID": "$tyk_context.request_id", + "X-Path": "$tyk_context.path", + "X-Remote-Addr": "$tyk_context.remote_addr", + }, + }, + } + }) +} + +func (ts *Test) TestPrepareVirtualEndpoint(js, method, path string, proxyOnError, keyless, cacheEnabled, disabled bool) { ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { spec.APIID = "test" spec.Proxy.ListenPath = "/"