packer-cn/common/retry/retry_test.go

104 lines
2.3 KiB
Go
Raw Normal View History

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")
}
}