Skip to content

Commit

Permalink
update tests
Browse files Browse the repository at this point in the history
  • Loading branch information
bbengfort committed Jan 3, 2024
1 parent 0664688 commit 3dc820a
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 8 deletions.
31 changes: 31 additions & 0 deletions pkg/api/v1/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import (
"context"
"net/http"
"net/http/httptest"
"sync/atomic"
"testing"
"time"

"github.com/cenkalti/backoff/v4"
"github.com/stretchr/testify/require"
"github.com/trisacrypto/courier/pkg/api/v1"
)
Expand Down Expand Up @@ -63,3 +66,31 @@ func TestStoreCertificatePassword(t *testing.T) {
err = client.StoreCertificatePassword(context.Background(), req)
require.ErrorIs(t, err, api.ErrIDRequired, "client should error if no ID is provided")
}

func TestRetriesWithBackoff(t *testing.T) {
// Create a test server
var attempts uint32
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
atomic.AddUint32(&attempts, 1)
http.Error(w, http.StatusText(http.StatusTooEarly), http.StatusTooEarly)
}))
defer ts.Close()

// Create a client to test the client method
client, err := api.New(ts.URL, api.WithRetries(10), api.WithBackoff(func() backoff.BackOff {
return backoff.NewConstantBackOff(100 * time.Millisecond)
}))
require.NoError(t, err, "could not create client")

rawClient, ok := client.(*api.APIv1)
require.True(t, ok, "expected client to be an APIv1 client")

req, err := rawClient.NewRequest(context.Background(), http.MethodGet, "/", nil, nil)
require.NoError(t, err, "could not create request")

start := time.Now()
_, err = rawClient.Do(req, nil, true)
require.Error(t, err, "expected an error to be returned")
require.Equal(t, uint32(11), attempts, "expected 10 retry attempts")
require.Greater(t, time.Since(start), 950*time.Millisecond, "expected backoff delay")
}
3 changes: 3 additions & 0 deletions pkg/api/v1/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ func ErrorResponse(err interface{}) Reply {
}

func NewStatusError(code int, err string) error {
if err == "" {
err = http.StatusText(code)
}
return &StatusError{Code: code, Err: err}
}

Expand Down
70 changes: 62 additions & 8 deletions pkg/api/v1/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,12 @@ func TestJoinStatusErrors(t *testing.T) {
})

t.Run("SingleStatusError", func(t *testing.T) {
err := api.JoinStatusErrors(1, 421*time.Millisecond, api.NewStatusError(http.StatusServiceUnavailable, "could not reach specified service"))
err := api.JoinStatusErrors(1, 421*time.Millisecond, api.NewStatusError(http.StatusServiceUnavailable, ""))
require.Error(t, err, "expected error to be returned")

serr, ok := err.(*api.StatusError)
_, ok := err.(*api.StatusError)
require.True(t, ok, "expected error to be a status error, not a multi status error")
require.Equal(t, 503, serr.Code)
require.EqualError(t, err, "[503]: Service Unavailable")
})

t.Run("SingleError", func(t *testing.T) {
Expand All @@ -37,15 +37,69 @@ func TestJoinStatusErrors(t *testing.T) {
require.EqualError(t, err, "something went wrong")
})

t.Run("MultiStatusErrors", func(t *testing.T) {})
t.Run("MultiStatusErrors", func(t *testing.T) {
err := api.JoinStatusErrors(3, 1829*time.Millisecond,
api.NewStatusError(http.StatusUnauthorized, ""),
api.NewStatusError(http.StatusServiceUnavailable, ""),
api.NewStatusError(http.StatusInsufficientStorage, ""),
)
require.Error(t, err, "expected error to be returned")

t.Run("MultiErrors", func(t *testing.T) {})
_, ok := err.(*api.MultiStatusError)
require.True(t, ok, "expected error to be a multi-status error")
require.EqualError(t, err, "after 3 attempts: [507]: Insufficient Storage")
})

t.Run("Mixed", func(t *testing.T) {})
t.Run("MultiErrors", func(t *testing.T) {
err := api.JoinStatusErrors(2, 727*time.Millisecond,
errors.New("oopsie"), errors.New("something went wrong"),
)
require.Error(t, err, "expected error to be returned")

t.Run("Deduplication", func(t *testing.T) {})
_, ok := err.(*api.MultiStatusError)
require.True(t, ok, "expected error to be a multi-status error")
require.EqualError(t, err, "after 2 attempts: something went wrong")
})

t.Run("Mixed", func(t *testing.T) {
err := api.JoinStatusErrors(2, 3217*time.Millisecond,
api.NewStatusError(http.StatusServiceUnavailable, ""),
errors.New("something went wrong"),
)
require.Error(t, err, "expected error to be returned")

_, ok := err.(*api.MultiStatusError)
require.True(t, ok, "expected error to be a multi-status error")
require.EqualError(t, err, "after 2 attempts: something went wrong")
})

t.Run("MultiDeduplication", func(t *testing.T) {})
t.Run("Deduplication", func(t *testing.T) {
err := api.JoinStatusErrors(3, 2451*time.Millisecond,
api.NewStatusError(http.StatusServiceUnavailable, ""),
api.NewStatusError(http.StatusServiceUnavailable, ""),
api.NewStatusError(http.StatusServiceUnavailable, ""),
)
require.Error(t, err, "expected error to be returned")

_, ok := err.(*api.StatusError)
require.True(t, ok, "expected error to be a status error")
require.EqualError(t, err, "[503]: Service Unavailable")
})

t.Run("MultiDeduplication", func(t *testing.T) {
err := api.JoinStatusErrors(5, 3257*time.Millisecond,
api.NewStatusError(http.StatusUnauthorized, ""),
api.NewStatusError(http.StatusServiceUnavailable, ""),
api.NewStatusError(http.StatusUnauthorized, ""),
api.NewStatusError(http.StatusInsufficientStorage, ""),
api.NewStatusError(http.StatusServiceUnavailable, ""),
)
require.Error(t, err, "expected error to be returned")

_, ok := err.(*api.MultiStatusError)
require.True(t, ok, "expected error to be a multi-status error")
require.EqualError(t, err, "after 5 attempts: [507]: Insufficient Storage")
})
}

func TestMultiStatusError(t *testing.T) {
Expand Down

0 comments on commit 3dc820a

Please sign in to comment.