| package backoff |
| |
| import ( |
| "context" |
| "errors" |
| "fmt" |
| "log" |
| "testing" |
| "time" |
| ) |
| |
| func TestRetry(t *testing.T) { |
| const successOn = 3 |
| var i = 0 |
| |
| // This function is successful on "successOn" calls. |
| f := func() error { |
| i++ |
| log.Printf("function is called %d. time\n", i) |
| |
| if i == successOn { |
| log.Println("OK") |
| return nil |
| } |
| |
| log.Println("error") |
| return errors.New("error") |
| } |
| |
| err := Retry(f, NewExponentialBackOff()) |
| if err != nil { |
| t.Errorf("unexpected error: %s", err.Error()) |
| } |
| if i != successOn { |
| t.Errorf("invalid number of retries: %d", i) |
| } |
| } |
| |
| func TestRetryContext(t *testing.T) { |
| var cancelOn = 3 |
| var i = 0 |
| |
| ctx, cancel := context.WithCancel(context.Background()) |
| defer cancel() |
| |
| // This function cancels context on "cancelOn" calls. |
| f := func() error { |
| i++ |
| log.Printf("function is called %d. time\n", i) |
| |
| // cancelling the context in the operation function is not a typical |
| // use-case, however it allows to get predictable test results. |
| if i == cancelOn { |
| cancel() |
| } |
| |
| log.Println("error") |
| return fmt.Errorf("error (%d)", i) |
| } |
| |
| err := Retry(f, WithContext(NewConstantBackOff(time.Millisecond), ctx)) |
| if err == nil { |
| t.Errorf("error is unexpectedly nil") |
| } |
| if err.Error() != "error (3)" { |
| t.Errorf("unexpected error: %s", err.Error()) |
| } |
| if i != cancelOn { |
| t.Errorf("invalid number of retries: %d", i) |
| } |
| } |
| |
| func TestRetryPermenent(t *testing.T) { |
| const permanentOn = 3 |
| var i = 0 |
| |
| // This function fails permanently after permanentOn tries |
| f := func() error { |
| i++ |
| log.Printf("function is called %d. time\n", i) |
| |
| if i == permanentOn { |
| log.Println("permanent error") |
| return Permanent(errors.New("permanent error")) |
| } |
| |
| log.Println("error") |
| return errors.New("error") |
| } |
| |
| err := Retry(f, NewExponentialBackOff()) |
| if err == nil || err.Error() != "permanent error" { |
| t.Errorf("unexpected error: %s", err) |
| } |
| if i != permanentOn { |
| t.Errorf("invalid number of retries: %d", i) |
| } |
| } |