12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- package retry
- import (
- "context"
- "errors"
- "testing"
- "time"
- "github.com/stretchr/testify/assert"
- "github.com/tal-tech/go-zero/core/logx"
- "google.golang.org/grpc"
- "google.golang.org/grpc/codes"
- "google.golang.org/grpc/metadata"
- "google.golang.org/grpc/status"
- )
- func TestRetryWithDisable(t *testing.T) {
- opt := &options{}
- assert.EqualValues(t, &options{}, parseRetryCallOptions(opt, WithDisable()))
- }
- func TestRetryWithMax(t *testing.T) {
- n := 5
- for i := 0; i < n; i++ {
- opt := &options{}
- assert.EqualValues(t, &options{max: i}, parseRetryCallOptions(opt, WithMax(i)))
- }
- }
- func TestRetryWithBackoff(t *testing.T) {
- opt := &options{}
- retryCallOptions := parseRetryCallOptions(opt, WithBackoff(func(attempt int) time.Duration {
- return time.Millisecond
- }))
- assert.EqualValues(t, time.Millisecond, retryCallOptions.backoffFunc(1))
- }
- func TestRetryWithCodes(t *testing.T) {
- opt := &options{}
- c := []codes.Code{codes.Unknown, codes.NotFound}
- options := parseRetryCallOptions(opt, WithCodes(c...))
- assert.EqualValues(t, c, options.codes)
- }
- func TestRetryWithPerRetryTimeout(t *testing.T) {
- opt := &options{}
- options := parseRetryCallOptions(opt, WithPerRetryTimeout(time.Millisecond))
- assert.EqualValues(t, time.Millisecond, options.perCallTimeout)
- }
- func Test_waitRetryBackoff(t *testing.T) {
- logx.Disable()
- opt := &options{perCallTimeout: time.Second, backoffFunc: func(attempt int) time.Duration {
- return time.Second
- }}
- logger := logx.WithContext(context.Background())
- err := waitRetryBackoff(logger, 1, context.Background(), opt)
- assert.NoError(t, err)
- ctx, cancelFunc := context.WithTimeout(context.Background(), time.Millisecond)
- defer cancelFunc()
- err = waitRetryBackoff(logger, 1, ctx, opt)
- assert.ErrorIs(t, err, status.FromContextError(context.DeadlineExceeded).Err())
- }
- func Test_isRetriable(t *testing.T) {
- assert.False(t, isRetriable(status.FromContextError(context.DeadlineExceeded).Err(), &options{codes: DefaultRetriableCodes}))
- assert.True(t, isRetriable(status.Error(codes.ResourceExhausted, ""), &options{codes: DefaultRetriableCodes}))
- assert.False(t, isRetriable(errors.New("error"), &options{}))
- }
- func Test_perCallContext(t *testing.T) {
- opt := &options{perCallTimeout: time.Second, includeRetryHeader: true}
- ctx := metadata.NewIncomingContext(context.Background(), map[string][]string{"1": {"1"}})
- callContext := perCallContext(ctx, opt, 1)
- md, ok := metadata.FromOutgoingContext(callContext)
- assert.True(t, ok)
- assert.EqualValues(t, metadata.MD{"1": {"1"}, AttemptMetadataKey: {"1"}}, md)
- }
- func Test_filterCallOptions(t *testing.T) {
- grpcEmptyCallOpt := &grpc.EmptyCallOption{}
- retryCallOpt := &CallOption{}
- options, retryCallOptions := filterCallOptions([]grpc.CallOption{
- grpcEmptyCallOpt,
- retryCallOpt,
- })
- assert.EqualValues(t, []grpc.CallOption{grpcEmptyCallOpt}, options)
- assert.EqualValues(t, []*CallOption{retryCallOpt}, retryCallOptions)
- }
|