From dbf2b5d5271c55494dce99a257388f4693ac4cda Mon Sep 17 00:00:00 2001 From: Srikanth Chekuri Date: Sun, 7 Aug 2022 19:22:34 +0530 Subject: [PATCH 1/2] fix: incorrect switch case eval when server response code 429 --- client/internal/httpsender.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/client/internal/httpsender.go b/client/internal/httpsender.go index fa5e4fd6..ecd307bd 100644 --- a/client/internal/httpsender.go +++ b/client/internal/httpsender.go @@ -157,8 +157,7 @@ func (h *HTTPSender) sendRequestWithRetries(ctx context.Context) (*http.Response h.callbacks.OnConnect() return resp, nil - case http.StatusTooManyRequests: - case http.StatusServiceUnavailable: + case http.StatusTooManyRequests, http.StatusServiceUnavailable: interval = recalculateInterval(interval, resp) err = fmt.Errorf("server response code=%d", resp.StatusCode) From 3a465c0c4daaff9dd2591621dc1fb2628c64444d Mon Sep 17 00:00:00 2001 From: Srikanth Chekuri Date: Thu, 18 Aug 2022 02:43:44 +0530 Subject: [PATCH 2/2] Add test for fix --- client/internal/httpsender_test.go | 57 ++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) create mode 100644 client/internal/httpsender_test.go diff --git a/client/internal/httpsender_test.go b/client/internal/httpsender_test.go new file mode 100644 index 00000000..31f1aabb --- /dev/null +++ b/client/internal/httpsender_test.go @@ -0,0 +1,57 @@ +package internal + +import ( + "context" + "net/http" + "sync/atomic" + "testing" + "time" + + "github.com/open-telemetry/opamp-go/client/types" + sharedinternal "github.com/open-telemetry/opamp-go/internal" + "github.com/open-telemetry/opamp-go/protobufs" + "github.com/stretchr/testify/assert" +) + +func TestHTTPSenderRetryForStatusTooManyRequests(t *testing.T) { + + var connectionAttempts int64 + srv := StartMockServer(t) + srv.OnRequest = func(w http.ResponseWriter, r *http.Request) { + attempt := atomic.AddInt64(&connectionAttempts, 1) + // Return a Retry-After header with a value of 1 second for first attempt. + if attempt == 1 { + w.Header().Set("Retry-After", "1") + w.WriteHeader(http.StatusTooManyRequests) + } else { + w.WriteHeader(http.StatusOK) + } + } + ctx, cancel := context.WithCancel(context.Background()) + url := "http://" + srv.Endpoint + sender := NewHTTPSender(&sharedinternal.NopLogger{}) + sender.NextMessage().Update(func(msg *protobufs.AgentToServer) { + msg.AgentDescription = &protobufs.AgentDescription{ + IdentifyingAttributes: []*protobufs.KeyValue{{ + Key: "service.name", + Value: &protobufs.AnyValue{ + Value: &protobufs.AnyValue_StringValue{StringValue: "test-service"}, + }, + }}, + } + }) + sender.callbacks = types.CallbacksStruct{ + OnConnectFunc: func() { + }, + OnConnectFailedFunc: func(_ error) { + }, + } + sender.url = url + start := time.Now() + resp, err := sender.sendRequestWithRetries(ctx) + assert.NoError(t, err) + assert.Equal(t, http.StatusOK, resp.StatusCode) + assert.True(t, time.Since(start) > time.Second) + cancel() + srv.Close() +}