From 69264bcec98282e702d847c745fa45e70b5b1195 Mon Sep 17 00:00:00 2001 From: Tit Petric Date: Tue, 7 Nov 2023 08:27:02 +0100 Subject: [PATCH] Remove new analytics test dependant on pump --- gateway/analytics_test.go | 516 -------------------------------------- 1 file changed, 516 deletions(-) diff --git a/gateway/analytics_test.go b/gateway/analytics_test.go index 92c90c5ca5c..83ebf98d3e8 100644 --- a/gateway/analytics_test.go +++ b/gateway/analytics_test.go @@ -1,527 +1,11 @@ package gateway import ( - "encoding/base64" - "net/http" - "net/http/httptest" - "strings" "testing" - "time" - "github.com/TykTechnologies/tyk-pump/analytics" - "github.com/TykTechnologies/tyk/apidef" "github.com/TykTechnologies/tyk/config" - "github.com/TykTechnologies/tyk/test" - "github.com/TykTechnologies/tyk/user" - "github.com/stretchr/testify/assert" ) -func TestAnalytics_Write(t *testing.T) { - test.Flaky(t) - tcs := []struct { - TestName string - analyticsSerializer string - }{ - { - TestName: "Testing analytics flows with msgpack", - analyticsSerializer: "", - }, - { - TestName: "Testing analytics flows with protobuf", - analyticsSerializer: "protobuf", - }, - } - - for _, tc := range tcs { - t.Run(tc.TestName, func(t *testing.T) { - ts := StartTest(func(globalConf *config.Config) { - globalConf.AnalyticsConfig.SerializerType = tc.analyticsSerializer - }, TestConfig{ - Delay: 20 * time.Millisecond, - }) - - defer ts.Close() - base := ts.Gw.GetConfig() - - redisAnalyticsKeyName := analyticsKeyName + ts.Gw.Analytics.analyticsSerializer.GetSuffix() - - // Cleanup before test - // let records to be sent - ts.Gw.Analytics.Store.GetAndDeleteSet(redisAnalyticsKeyName) - - t.Run("Log errors", func(t *testing.T) { - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - spec.UseKeylessAccess = false - spec.Proxy.ListenPath = "/" - }) - - _, err := ts.Run(t, []test.TestCase{ - {Path: "/", Code: 401}, - {Path: "/", Code: 401}, - }...) - - if err != nil { - t.Error("Error executing test case") - } - - //Restart will empty the analytics buffer into redis, stop the analytics processing and start it again - ts.Gw.Analytics.Flush() - - results := ts.Gw.Analytics.Store.GetAndDeleteSet(redisAnalyticsKeyName) - assert.Equal(t, 2, len(results), "Should return 2 records") - - var record analytics.AnalyticsRecord - err = ts.Gw.Analytics.analyticsSerializer.Decode([]byte(results[0].(string)), &record) - if err != nil { - t.Error("Error decoding analytics") - } - if record.ResponseCode != 401 { - t.Error("Analytics record do not match: ", record) - } - }) - - t.Run("Log success", func(t *testing.T) { - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - spec.UseKeylessAccess = false - spec.Proxy.ListenPath = "/" - }) - - key := CreateSession(ts.Gw) - - authHeaders := map[string]string{ - "authorization": key, - } - - _, err := ts.Run(t, test.TestCase{ - Path: "/", Headers: authHeaders, Code: 200, - }) - if err != nil { - t.Error("Error executing test case") - } - // let records to to be sent - - ts.Gw.Analytics.Flush() - - results := ts.Gw.Analytics.Store.GetAndDeleteSet(redisAnalyticsKeyName) - if len(results) != 1 { - t.Error("Should return 1 record: ", len(results)) - } - - var record analytics.AnalyticsRecord - err = ts.Gw.Analytics.analyticsSerializer.Decode([]byte(results[0].(string)), &record) - if err != nil { - t.Error("Error decoding analytics") - } - if record.ResponseCode != 200 { - t.Error("Analytics record do not match", record) - } - }) - - t.Run("Detailed analytics with api spec config enabled", func(t *testing.T) { - defer func() { - ts.Gw.SetConfig(base) - }() - - globalConf := ts.Gw.GetConfig() - globalConf.AnalyticsConfig.EnableDetailedRecording = false - ts.Gw.SetConfig(globalConf) - - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - spec.UseKeylessAccess = false - spec.Proxy.ListenPath = "/" - spec.EnableDetailedRecording = true - }) - - key := CreateSession(ts.Gw) - - authHeaders := map[string]string{ - "authorization": key, - } - - _, err := ts.Run(t, test.TestCase{ - Path: "/", Headers: authHeaders, Code: 200, - }) - if err != nil { - t.Error("Error executing test case") - } - - // let records to be sent - ts.Gw.Analytics.Flush() - - results := ts.Gw.Analytics.Store.GetAndDeleteSet(redisAnalyticsKeyName) - if len(results) != 1 { - t.Error("Should return 1 record: ", len(results)) - } - - var record analytics.AnalyticsRecord - err = ts.Gw.Analytics.analyticsSerializer.Decode([]byte(results[0].(string)), &record) - if err != nil { - t.Error("Error decoding analytics") - } - if record.ResponseCode != 200 { - t.Error("Analytics record do not match", record) - } - - if record.RawRequest == "" { - t.Error("Detailed request info not found", record) - } - - if record.RawResponse == "" { - t.Error("Detailed response info not found", record) - } - }) - - t.Run("Detailed analytics with only key flag set", func(t *testing.T) { - defer func() { - ts.Gw.SetConfig(base) - }() - globalConf := ts.Gw.GetConfig() - globalConf.AnalyticsConfig.EnableDetailedRecording = false - ts.Gw.SetConfig(globalConf) - - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - spec.UseKeylessAccess = false - spec.Proxy.ListenPath = "/" - spec.EnableDetailedRecording = false - }) - - key := CreateSession(ts.Gw, func(sess *user.SessionState) { - sess.EnableDetailedRecording = true - }) - - authHeaders := map[string]string{ - "authorization": key, - } - - _, err := ts.Run(t, test.TestCase{ - Path: "/", Headers: authHeaders, Code: 200, - }) - if err != nil { - t.Error("Error executing test case") - } - - // let records to to be sent - ts.Gw.Analytics.Flush() - - results := ts.Gw.Analytics.Store.GetAndDeleteSet(redisAnalyticsKeyName) - if len(results) != 1 { - t.Error("Should return 1 record: ", len(results)) - } - - var record analytics.AnalyticsRecord - err = ts.Gw.Analytics.analyticsSerializer.Decode([]byte(results[0].(string)), &record) - if err != nil { - t.Error("Error decoding analytics") - } - if record.ResponseCode != 200 { - t.Error("Analytics record do not match", record) - } - - if record.RawRequest == "" { - t.Error("Detailed request info not found", record) - } - - if record.RawResponse == "" { - t.Error("Detailed response info not found", record) - } - }) - - t.Run("Detailed analytics", func(t *testing.T) { - defer func() { - ts.Gw.SetConfig(base) - }() - globalConf := ts.Gw.GetConfig() - globalConf.AnalyticsConfig.EnableDetailedRecording = true - ts.Gw.SetConfig(globalConf) - - // Since we changed config, we need to force all APIs be reloaded - ts.Gw.BuildAndLoadAPI() - - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - spec.UseKeylessAccess = false - spec.Proxy.ListenPath = "/" - }) - - key := CreateSession(ts.Gw) - - authHeaders := map[string]string{ - "authorization": key, - } - - _, err := ts.Run(t, test.TestCase{ - Path: "/", Headers: authHeaders, Code: 200, - }) - if err != nil { - t.Error("Error executing test case") - } - // let records to to be sent - ts.Gw.Analytics.Flush() - - results := ts.Gw.Analytics.Store.GetAndDeleteSet(redisAnalyticsKeyName) - if len(results) != 1 { - t.Error("Should return 1 record: ", len(results)) - } - - var record analytics.AnalyticsRecord - err = ts.Gw.Analytics.analyticsSerializer.Decode([]byte(results[0].(string)), &record) - if err != nil { - t.Error("Error decoding analytics") - } - if record.ResponseCode != 200 { - t.Error("Analytics record do not match", record) - } - - if record.RawRequest == "" { - t.Error("Detailed request info not found", record) - } - - if record.RawResponse == "" { - t.Error("Detailed response info not found", record) - } - }) - - t.Run("Detailed analytics with latency", func(t *testing.T) { - defer func() { - ts.Gw.SetConfig(base) - }() - globalConf := ts.Gw.GetConfig() - globalConf.AnalyticsConfig.EnableDetailedRecording = true - ts.Gw.SetConfig(globalConf) - ls := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - // We are delaying the response by 2 ms. This is important because anytime - // less than 0 eg 0.2 ms will be round off to 0 which is not good to check if we have - // latency correctly set. - time.Sleep(2 * time.Millisecond) - })) - defer ls.Close() - - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - spec.UseKeylessAccess = false - spec.Proxy.ListenPath = "/" - spec.Proxy.TargetURL = ls.URL - }) - - key := CreateSession(ts.Gw) - - authHeaders := map[string]string{ - "authorization": key, - } - - _, err := ts.Run(t, test.TestCase{ - Path: "/", Headers: authHeaders, Code: 200, - }) - if err != nil { - t.Error("Error executing test case") - } - - // let records to to be sent - ts.Gw.Analytics.Flush() - - results := ts.Gw.Analytics.Store.GetAndDeleteSet(redisAnalyticsKeyName) - if len(results) != 1 { - t.Error("Should return 1 record: ", len(results)) - } - - var record analytics.AnalyticsRecord - err = ts.Gw.Analytics.analyticsSerializer.Decode([]byte(results[0].(string)), &record) - if err != nil { - t.Error("Error decoding analytics") - } - if record.ResponseCode != 200 { - t.Error("Analytics record do not match", record) - } - - if record.RawRequest == "" { - t.Error("Detailed request info not found", record) - } - - if record.RawResponse == "" { - t.Error("Detailed response info not found", record) - } - if record.Latency.Total == 0 { - t.Error("expected total latency to be set") - } - if record.Latency.Upstream == 0 { - t.Error("expected upstream latency to be set") - } - if record.Latency.Total != record.RequestTime { - t.Errorf("expected %d got %d", record.RequestTime, record.Latency.Total) - } - }) - - t.Run("Detailed analytics with cache", func(t *testing.T) { - defer func() { - ts.Gw.SetConfig(base) - }() - globalConf := ts.Gw.GetConfig() - globalConf.AnalyticsConfig.EnableDetailedRecording = true - ts.Gw.SetConfig(globalConf) - - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - spec.UseKeylessAccess = false - spec.Proxy.ListenPath = "/" - spec.CacheOptions = apidef.CacheOptions{ - CacheTimeout: 120, - EnableCache: true, - CacheAllSafeRequests: true, - } - }) - - key := CreateSession(ts.Gw) - - authHeaders := map[string]string{ - "authorization": key, - } - - _, err := ts.Run(t, []test.TestCase{ - {Path: "/", Headers: authHeaders, Code: 200}, - {Path: "/", Headers: authHeaders, Code: 200}, - }...) - if err != nil { - t.Error("Error executing test case") - } - - // let records to be sent - ts.Gw.Analytics.Flush() - - results := ts.Gw.Analytics.Store.GetAndDeleteSet(redisAnalyticsKeyName) - assert.Equal(t, 2, len(results)) - - // Take second cached request - var record analytics.AnalyticsRecord - err = ts.Gw.Analytics.analyticsSerializer.Decode([]byte(results[1].(string)), &record) - if err != nil { - t.Error("Error decoding analytics") - } - if record.ResponseCode != 200 { - t.Error("Analytics record do not match", record) - } - - if record.RawRequest == "" { - t.Error("Detailed request info not found", record) - } - - if record.RawResponse == "" { - t.Error("Detailed response info not found", record) - } - }) - - t.Run("Upstream error analytics", func(t *testing.T) { - defer func() { - ts.Gw.SetConfig(base) - }() - ls := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - time.Sleep(2 * time.Millisecond) - w.WriteHeader(http.StatusOK) - })) - defer ls.Close() - - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - spec.UseKeylessAccess = false - spec.Proxy.ListenPath = "/" - spec.Proxy.TargetURL = ls.URL - }) - - key := CreateSession(ts.Gw) - - authHeaders := map[string]string{ - "authorization": key, - } - - client := http.Client{ - Timeout: 1 * time.Millisecond, - } - _, err := ts.Run(t, test.TestCase{ - Path: "/", Headers: authHeaders, Code: 499, Client: &client, ErrorMatch: "context deadline exceeded", - }) - assert.NotNil(t, err) - - // we wait until the request finish - time.Sleep(3 * time.Millisecond) - // let records to to be sent - ts.Gw.Analytics.Flush() - - results := ts.Gw.Analytics.Store.GetAndDeleteSet(redisAnalyticsKeyName) - assert.Len(t, results, 1) - - var record analytics.AnalyticsRecord - err = ts.Gw.Analytics.analyticsSerializer.Decode([]byte(results[0].(string)), &record) - assert.Nil(t, err) - - // expect a status 499 (context canceled) from the request - assert.Equal(t, 499, record.ResponseCode) - // expect that the analytic record maintained the APIKey - assert.Equal(t, key, record.APIKey) - - }) - t.Run("Chunked response analytics", func(t *testing.T) { - defer func() { - ts.Gw.SetConfig(base) - }() - globalConf := ts.Gw.GetConfig() - globalConf.AnalyticsConfig.EnableDetailedRecording = true - ts.Gw.SetConfig(globalConf) - - // Since we changed config, we need to force all APIs be reloaded - ts.Gw.BuildAndLoadAPI() - - ts.Gw.BuildAndLoadAPI(func(spec *APISpec) { - spec.UseKeylessAccess = false - spec.Proxy.ListenPath = "/" - }) - - key := CreateSession(ts.Gw) - - authHeaders := map[string]string{ - "authorization": key, - } - - _, err := ts.Run(t, test.TestCase{ - Path: "/chunked", Headers: authHeaders, Code: 200, - }) - if err != nil { - t.Error("Error executing test case") - } - // let records to to be sent - ts.Gw.Analytics.Flush() - - results := ts.Gw.Analytics.Store.GetAndDeleteSet(redisAnalyticsKeyName) - if len(results) != 1 { - t.Error("Should return 1 record: ", len(results)) - } - - var record analytics.AnalyticsRecord - err = ts.Gw.Analytics.analyticsSerializer.Decode([]byte(results[0].(string)), &record) - if err != nil { - t.Error("Error decoding analytics") - } - if record.ResponseCode != 200 { - t.Error("Analytics record do not match", record) - } - - if record.RawRequest == "" { - t.Error("Detailed request info not found", record) - } - - if record.RawResponse == "" { - t.Error("Detailed response info not found", record) - } - - rawResponse, err := base64.StdEncoding.DecodeString(record.RawResponse) - if err != nil { - t.Error("error decoding response") - } - - decoded := string(rawResponse) - if strings.Contains(decoded, "1a") { - t.Error("Response should not have chunked characters") - } - }) - }) - } - -} - func TestGeoIPLookup(t *testing.T) { ts := StartTest(nil) defer ts.Close()