104 lines
2.3 KiB
Go
104 lines
2.3 KiB
Go
package retry
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/google/go-cmp/cmp"
|
|
)
|
|
|
|
func success(context.Context) error { return nil }
|
|
|
|
func wait(ctx context.Context) error {
|
|
<-ctx.Done()
|
|
return ctx.Err()
|
|
}
|
|
|
|
var failErr = errors.New("woops !")
|
|
|
|
func fail(context.Context) error { return failErr }
|
|
|
|
type failOnce bool
|
|
|
|
func (ran *failOnce) Run(context.Context) error {
|
|
if !*ran {
|
|
*ran = true
|
|
return failErr
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func TestConfig_Run(t *testing.T) {
|
|
cancelledCtx, cancel := context.WithCancel(context.Background())
|
|
cancel()
|
|
type fields struct {
|
|
StartTimeout time.Duration
|
|
RetryDelay func() time.Duration
|
|
Tries int
|
|
}
|
|
type args struct {
|
|
ctx context.Context
|
|
fn func(context.Context) error
|
|
}
|
|
tests := []struct {
|
|
name string
|
|
fields fields
|
|
args args
|
|
wantErr error
|
|
}{
|
|
{"success",
|
|
fields{StartTimeout: time.Second},
|
|
args{context.Background(), success},
|
|
nil},
|
|
{"context cancelled",
|
|
fields{StartTimeout: time.Second},
|
|
args{cancelledCtx, wait},
|
|
context.Canceled},
|
|
{"timeout",
|
|
fields{StartTimeout: 20 * time.Millisecond, RetryDelay: func() time.Duration { return 10 * time.Millisecond }},
|
|
args{cancelledCtx, fail},
|
|
failErr},
|
|
{"success after one failure",
|
|
fields{Tries: 2, RetryDelay: func() time.Duration { return 0 }},
|
|
args{context.Background(), new(failOnce).Run},
|
|
nil},
|
|
{"fail after one failure",
|
|
fields{Tries: 1, RetryDelay: func() time.Duration { return 0 }},
|
|
args{context.Background(), new(failOnce).Run},
|
|
&RetryExhaustedError{failErr},
|
|
},
|
|
}
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
cfg := Config{
|
|
StartTimeout: tt.fields.StartTimeout,
|
|
RetryDelay: tt.fields.RetryDelay,
|
|
Tries: tt.fields.Tries,
|
|
}
|
|
err := cfg.Run(tt.args.ctx, tt.args.fn)
|
|
if diff := cmp.Diff(err, tt.wantErr, DeepAllowUnexported(RetryExhaustedError{}, errors.New(""))); diff != "" {
|
|
t.Fatalf("Config.Run() unexpected error: %s", diff)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBackoff_Linear(t *testing.T) {
|
|
b := Backoff{
|
|
InitialBackoff: 2 * time.Minute,
|
|
Multiplier: 2,
|
|
}
|
|
|
|
linear := (&b).Linear
|
|
|
|
if linear() != 2*time.Minute {
|
|
t.Fatal("first backoff should be 2 minutes")
|
|
}
|
|
|
|
if linear() != 4*time.Minute {
|
|
t.Fatal("second backoff should be 4 minutes")
|
|
}
|
|
}
|