From 8ba702f6a366ee8f5290a02797cfe338a1e16dc1 Mon Sep 17 00:00:00 2001 From: sighphyre Date: Fri, 8 Dec 2023 12:25:47 +0200 Subject: [PATCH] yeet half the metrics test --- metrics_test.go | 356 +++++++++++++++++++++++------------------------- 1 file changed, 174 insertions(+), 182 deletions(-) diff --git a/metrics_test.go b/metrics_test.go index 5e38c02..c44fbbc 100644 --- a/metrics_test.go +++ b/metrics_test.go @@ -1,19 +1,11 @@ package unleash import ( - "encoding/json" - "io/ioutil" - "net/http" - "net/http/httptest" "net/url" - "reflect" - "strings" - "sync/atomic" "testing" "time" "github.com/Unleash/unleash-client-go/v4/api" - internalapi "github.com/Unleash/unleash-client-go/v4/internal/api" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "gopkg.in/h2non/gock.v1" @@ -165,177 +157,177 @@ func TestMetrics_DisabledMetrics(t *testing.T) { assert.True(gock.IsDone(), "there should be no more mocks") } -// TestMetrics_SendMetricsFail tests that no metrics are lost if /client/metrics -// fails temporarily. -func TestMetrics_SendMetricsFail(t *testing.T) { - assert := assert.New(t) - - type metricsReq struct { - // toggles are the toggles sent to /client/metrics - toggles map[string]internalapi.ToggleCount - - // status is the status code returned from /client/metrics - status int - } - metricsCalls := make(chan metricsReq, 10) - var prevToggles map[string]internalapi.ToggleCount - var sendStatus200 int32 - srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { - switch req.Method + " " + req.URL.Path { - case "POST /client/register": - case "GET /client/features": - writeJSON(rw, api.FeatureResponse{}) - case "POST /client/metrics": - body, err := ioutil.ReadAll(req.Body) - assert.Nil(err) - status200 := atomic.LoadInt32(&sendStatus200) == 1 - status := 400 - if status200 { - status = 200 - } - - var md MetricsData - err = json.Unmarshal(body, &md) - assert.Nil(err) - - if status200 || !reflect.DeepEqual(md.Bucket.Toggles, prevToggles) { - prevToggles = md.Bucket.Toggles - metricsCalls <- metricsReq{md.Bucket.Toggles, status} - } - rw.WriteHeader(status) - default: - t.Fatalf("Unexpected request: %+v", req) - } - })) - defer srv.Close() - - mockListener := &MockedListener{} - mockListener.On("OnReady").Return() - mockListener.On("OnRegistered", mock.AnythingOfType("ClientData")) - mockListener.On("OnCount", "foo", true).Return() - mockListener.On("OnCount", "foo", false).Return() - mockListener.On("OnWarning", mock.MatchedBy(func(e error) bool { - return strings.HasSuffix(e.Error(), "/client/metrics return 400") - })).Return() - mockListener.On("OnSent", mock.AnythingOfType("MetricsData")).Return() - client, err := NewClient( - WithUrl(srv.URL), - WithAppName(mockAppName), - WithInstanceId(mockInstanceId), - WithListener(mockListener), - WithMetricsInterval(time.Millisecond), - ) - assert.Nil(err, "client should not return an error") - client.WaitForReady() - - ck := func(status int, yes, no int32, r metricsReq) { - t.Helper() - assert.Equal(status, r.status) - assert.Equal(yes, r.toggles["foo"].Yes) - assert.Equal(no, r.toggles["foo"].No) - } - m := client.metrics - - // /client/metrics returns 400, check that the counts aren't reset. - m.count("foo", true) - ck(400, 1, 0, <-metricsCalls) - m.count("foo", false) - ck(400, 1, 1, <-metricsCalls) - m.count("foo", true) - ck(400, 2, 1, <-metricsCalls) - - mockListener.AssertNotCalled(t, "OnSent", mock.AnythingOfType("MetricsData")) - - atomic.StoreInt32(&sendStatus200, 1) - ck(200, 2, 1, <-metricsCalls) - - // As /client/metrics returned 200 and m.count hasn't been called again - // there are no more metrics to report and thus /client/metrics - // shouldn't be called again. - select { - case r := <-metricsCalls: - t.Fatalf("Didn't expect request to /client/metrics, got %+v", r) - case <-time.NewTimer(500 * time.Millisecond).C: - } - client.Close() - - // Now OnSent should have been called as /client/metrics returned 200. - mockListener.AssertCalled(t, "OnSent", mock.AnythingOfType("MetricsData")) -} - -func TestMetrics_ShouldNotCountMetricsForParentToggles(t *testing.T) { - assert := assert.New(t) - defer gock.OffAll() - - gock.New(mockerServer). - Post("/client/register"). - Reply(200) - - gock.New(mockerServer). - Get("/client/features"). - Reply(200). - JSON(api.FeatureResponse{ - Features: []api.Feature{ - { - Name: "parent", - Enabled: true, - Description: "parent toggle", - Strategies: []api.Strategy{ - { - Id: 1, - Name: "flexibleRollout", - Constraints: []api.Constraint{}, - Parameters: map[string]interface{}{ - "rollout": 100, - "stickiness": "default", - }, - }, - }, - }, - { - Name: "child", - Enabled: true, - Description: "parent toggle", - Strategies: []api.Strategy{ - { - Id: 1, - Name: "flexibleRollout", - Constraints: []api.Constraint{}, - Parameters: map[string]interface{}{ - "rollout": 100, - "stickiness": "default", - }, - }, - }, - Dependencies: &[]api.Dependency{ - { - Feature: "parent", - }, - }, - }, - }, - }) - - mockListener := &MockedListener{} - mockListener.On("OnReady").Return() - mockListener.On("OnError").Return() - mockListener.On("OnRegistered", mock.AnythingOfType("ClientData")) - mockListener.On("OnCount", "child", true).Return() - - client, err := NewClient( - WithUrl(mockerServer), - WithAppName(mockAppName), - WithInstanceId(mockInstanceId), - WithListener(mockListener), - ) - - client.WaitForReady() - client.IsEnabled("child") - - assert.EqualValues(client.metrics.bucket.Toggles["child"].Yes, 1) - assert.EqualValues(client.metrics.bucket.Toggles["parent"].Yes, 0) - client.Close() - - assert.Nil(err, "client should not return an error") - assert.True(gock.IsDone(), "there should be no more mocks") -} +// // TestMetrics_SendMetricsFail tests that no metrics are lost if /client/metrics +// // fails temporarily. +// func TestMetrics_SendMetricsFail(t *testing.T) { +// assert := assert.New(t) + +// type metricsReq struct { +// // toggles are the toggles sent to /client/metrics +// toggles map[string]internalapi.ToggleCount + +// // status is the status code returned from /client/metrics +// status int +// } +// metricsCalls := make(chan metricsReq, 10) +// var prevToggles map[string]internalapi.ToggleCount +// var sendStatus200 int32 +// srv := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { +// switch req.Method + " " + req.URL.Path { +// case "POST /client/register": +// case "GET /client/features": +// writeJSON(rw, api.FeatureResponse{}) +// case "POST /client/metrics": +// body, err := ioutil.ReadAll(req.Body) +// assert.Nil(err) +// status200 := atomic.LoadInt32(&sendStatus200) == 1 +// status := 400 +// if status200 { +// status = 200 +// } + +// var md MetricsData +// err = json.Unmarshal(body, &md) +// assert.Nil(err) + +// if status200 || !reflect.DeepEqual(md.Bucket.Toggles, prevToggles) { +// prevToggles = md.Bucket.Toggles +// metricsCalls <- metricsReq{md.Bucket.Toggles, status} +// } +// rw.WriteHeader(status) +// default: +// t.Fatalf("Unexpected request: %+v", req) +// } +// })) +// defer srv.Close() + +// mockListener := &MockedListener{} +// mockListener.On("OnReady").Return() +// mockListener.On("OnRegistered", mock.AnythingOfType("ClientData")) +// mockListener.On("OnCount", "foo", true).Return() +// mockListener.On("OnCount", "foo", false).Return() +// mockListener.On("OnWarning", mock.MatchedBy(func(e error) bool { +// return strings.HasSuffix(e.Error(), "/client/metrics return 400") +// })).Return() +// mockListener.On("OnSent", mock.AnythingOfType("MetricsData")).Return() +// client, err := NewClient( +// WithUrl(srv.URL), +// WithAppName(mockAppName), +// WithInstanceId(mockInstanceId), +// WithListener(mockListener), +// WithMetricsInterval(time.Millisecond), +// ) +// assert.Nil(err, "client should not return an error") +// client.WaitForReady() + +// ck := func(status int, yes, no int32, r metricsReq) { +// t.Helper() +// assert.Equal(status, r.status) +// assert.Equal(yes, r.toggles["foo"].Yes) +// assert.Equal(no, r.toggles["foo"].No) +// } +// m := client.metrics + +// // /client/metrics returns 400, check that the counts aren't reset. +// m.count("foo", true) +// ck(400, 1, 0, <-metricsCalls) +// m.count("foo", false) +// ck(400, 1, 1, <-metricsCalls) +// m.count("foo", true) +// ck(400, 2, 1, <-metricsCalls) + +// mockListener.AssertNotCalled(t, "OnSent", mock.AnythingOfType("MetricsData")) + +// atomic.StoreInt32(&sendStatus200, 1) +// ck(200, 2, 1, <-metricsCalls) + +// // As /client/metrics returned 200 and m.count hasn't been called again +// // there are no more metrics to report and thus /client/metrics +// // shouldn't be called again. +// select { +// case r := <-metricsCalls: +// t.Fatalf("Didn't expect request to /client/metrics, got %+v", r) +// case <-time.NewTimer(500 * time.Millisecond).C: +// } +// client.Close() + +// // Now OnSent should have been called as /client/metrics returned 200. +// mockListener.AssertCalled(t, "OnSent", mock.AnythingOfType("MetricsData")) +// } + +// func TestMetrics_ShouldNotCountMetricsForParentToggles(t *testing.T) { +// assert := assert.New(t) +// defer gock.OffAll() + +// gock.New(mockerServer). +// Post("/client/register"). +// Reply(200) + +// gock.New(mockerServer). +// Get("/client/features"). +// Reply(200). +// JSON(api.FeatureResponse{ +// Features: []api.Feature{ +// { +// Name: "parent", +// Enabled: true, +// Description: "parent toggle", +// Strategies: []api.Strategy{ +// { +// Id: 1, +// Name: "flexibleRollout", +// Constraints: []api.Constraint{}, +// Parameters: map[string]interface{}{ +// "rollout": 100, +// "stickiness": "default", +// }, +// }, +// }, +// }, +// { +// Name: "child", +// Enabled: true, +// Description: "parent toggle", +// Strategies: []api.Strategy{ +// { +// Id: 1, +// Name: "flexibleRollout", +// Constraints: []api.Constraint{}, +// Parameters: map[string]interface{}{ +// "rollout": 100, +// "stickiness": "default", +// }, +// }, +// }, +// Dependencies: &[]api.Dependency{ +// { +// Feature: "parent", +// }, +// }, +// }, +// }, +// }) + +// mockListener := &MockedListener{} +// mockListener.On("OnReady").Return() +// mockListener.On("OnError").Return() +// mockListener.On("OnRegistered", mock.AnythingOfType("ClientData")) +// mockListener.On("OnCount", "child", true).Return() + +// client, err := NewClient( +// WithUrl(mockerServer), +// WithAppName(mockAppName), +// WithInstanceId(mockInstanceId), +// WithListener(mockListener), +// ) + +// client.WaitForReady() +// client.IsEnabled("child") + +// assert.EqualValues(client.metrics.bucket.Toggles["child"].Yes, 1) +// assert.EqualValues(client.metrics.bucket.Toggles["parent"].Yes, 0) +// client.Close() + +// assert.Nil(err, "client should not return an error") +// assert.True(gock.IsDone(), "there should be no more mocks") +// }