retry_test.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. package retry
  2. import (
  3. "context"
  4. "fmt"
  5. "sync/atomic"
  6. "testing"
  7. "time"
  8. )
  9. type Obj struct {
  10. Name string
  11. }
  12. func TestPtrSliceRetry(t *testing.T) {
  13. t.Parallel()
  14. const Expected uint64 = 3
  15. var count uint64 = 0
  16. f := func() ([]*Obj, error) {
  17. c := atomic.AddUint64(&count, 1)
  18. fmt.Println("Try:", c)
  19. if c == Expected {
  20. return []*Obj{
  21. {"A"},
  22. {"B"},
  23. {"C"},
  24. }, nil
  25. }
  26. return nil, fmt.Errorf("Failed: %d", c)
  27. }
  28. objs, err := Retry(context.Background(), f, 5, time.Second)
  29. if err != nil {
  30. t.Fatalf("Failed to correctly cast back to slice type")
  31. }
  32. t.Logf("Length: %d\n", len(objs))
  33. }
  34. func TestSuccessRetry(t *testing.T) {
  35. t.Parallel()
  36. const Expected uint64 = 3
  37. var count uint64 = 0
  38. f := func() (any, error) {
  39. c := atomic.AddUint64(&count, 1)
  40. fmt.Println("Try:", c)
  41. if c == Expected {
  42. return nil, nil
  43. }
  44. return nil, fmt.Errorf("Failed: %d", c)
  45. }
  46. _, err := Retry(context.Background(), f, 5, time.Second)
  47. if err != nil {
  48. t.Fatalf("Unexpected error: %s", err)
  49. }
  50. }
  51. func TestFailRetry(t *testing.T) {
  52. t.Parallel()
  53. const Expected uint64 = 5
  54. expectedError := fmt.Sprintf("Failed: %d", Expected)
  55. var count uint64 = 0
  56. f := func() (any, error) {
  57. c := atomic.AddUint64(&count, 1)
  58. fmt.Println("Try:", c)
  59. return nil, fmt.Errorf("Failed: %d", c)
  60. }
  61. _, err := Retry(context.Background(), f, 5, time.Second)
  62. if count != 5 {
  63. t.Fatalf("Expected Count: %d, Actual: %d", Expected, count)
  64. }
  65. if err.Error() != expectedError {
  66. t.Fatalf("Expected error: %s, Actual error: %s", expectedError, err.Error())
  67. }
  68. }
  69. func TestCancelRetry(t *testing.T) {
  70. t.Parallel()
  71. const Expected uint64 = 5
  72. var count uint64 = 0
  73. f := func() (any, error) {
  74. c := atomic.AddUint64(&count, 1)
  75. fmt.Println("Try:", c)
  76. return nil, fmt.Errorf("Failed: %d", c)
  77. }
  78. wait := make(chan error)
  79. ctx, cancel := context.WithCancel(context.Background())
  80. // execute retry in go routine
  81. go func() {
  82. _, err := Retry(ctx, f, 5, time.Second)
  83. wait <- err
  84. }()
  85. // cancel after 2 seconds
  86. go func() {
  87. time.Sleep(time.Second * 2)
  88. cancel()
  89. }()
  90. // wait for error result
  91. e := <-wait
  92. if !IsRetryCancelledError(e) {
  93. t.Fatalf("Expected CancellationError, got: %s", e)
  94. }
  95. }