retry_test.go 1.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. package backoff
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "log"
  7. "testing"
  8. "time"
  9. )
  10. func TestRetry(t *testing.T) {
  11. const successOn = 3
  12. var i = 0
  13. // This function is successful on "successOn" calls.
  14. f := func() error {
  15. i++
  16. log.Printf("function is called %d. time\n", i)
  17. if i == successOn {
  18. log.Println("OK")
  19. return nil
  20. }
  21. log.Println("error")
  22. return errors.New("error")
  23. }
  24. err := Retry(f, NewExponentialBackOff())
  25. if err != nil {
  26. t.Errorf("unexpected error: %s", err.Error())
  27. }
  28. if i != successOn {
  29. t.Errorf("invalid number of retries: %d", i)
  30. }
  31. }
  32. func TestRetryContext(t *testing.T) {
  33. var cancelOn = 3
  34. var i = 0
  35. ctx, cancel := context.WithCancel(context.Background())
  36. defer cancel()
  37. // This function cancels context on "cancelOn" calls.
  38. f := func() error {
  39. i++
  40. log.Printf("function is called %d. time\n", i)
  41. // cancelling the context in the operation function is not a typical
  42. // use-case, however it allows to get predictable test results.
  43. if i == cancelOn {
  44. cancel()
  45. }
  46. log.Println("error")
  47. return fmt.Errorf("error (%d)", i)
  48. }
  49. err := Retry(f, WithContext(NewConstantBackOff(time.Millisecond), ctx))
  50. if err == nil {
  51. t.Errorf("error is unexpectedly nil")
  52. }
  53. if err.Error() != "error (3)" {
  54. t.Errorf("unexpected error: %s", err.Error())
  55. }
  56. if i != cancelOn {
  57. t.Errorf("invalid number of retries: %d", i)
  58. }
  59. }
  60. func TestRetryPermenent(t *testing.T) {
  61. const permanentOn = 3
  62. var i = 0
  63. // This function fails permanently after permanentOn tries
  64. f := func() error {
  65. i++
  66. log.Printf("function is called %d. time\n", i)
  67. if i == permanentOn {
  68. log.Println("permanent error")
  69. return Permanent(errors.New("permanent error"))
  70. }
  71. log.Println("error")
  72. return errors.New("error")
  73. }
  74. err := Retry(f, NewExponentialBackOff())
  75. if err == nil || err.Error() != "permanent error" {
  76. t.Errorf("unexpected error: %s", err)
  77. }
  78. if i != permanentOn {
  79. t.Errorf("invalid number of retries: %d", i)
  80. }
  81. }