2
0

retry_test.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  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() (interface{}, 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. result, err := Retry(context.Background(), f, 5, time.Second)
  29. objs, ok := result.([]*Obj)
  30. if err != nil || !ok {
  31. t.Fatalf("Failed to correctly cast back to slice type")
  32. }
  33. t.Logf("Length: %d\n", len(objs))
  34. }
  35. func TestSuccessRetry(t *testing.T) {
  36. t.Parallel()
  37. const Expected uint64 = 3
  38. var count uint64 = 0
  39. f := func() (interface{}, error) {
  40. c := atomic.AddUint64(&count, 1)
  41. fmt.Println("Try:", c)
  42. if c == Expected {
  43. return struct{}{}, nil
  44. }
  45. return nil, fmt.Errorf("Failed: %d", c)
  46. }
  47. _, err := Retry(context.Background(), f, 5, time.Second)
  48. if err != nil {
  49. t.Fatalf("Unexpected error: %s", err)
  50. }
  51. }
  52. func TestFailRetry(t *testing.T) {
  53. t.Parallel()
  54. const Expected uint64 = 5
  55. expectedError := fmt.Sprintf("Failed: %d", Expected)
  56. var count uint64 = 0
  57. f := func() (interface{}, error) {
  58. c := atomic.AddUint64(&count, 1)
  59. fmt.Println("Try:", c)
  60. return nil, fmt.Errorf("Failed: %d", c)
  61. }
  62. _, err := Retry(context.Background(), f, 5, time.Second)
  63. if count != 5 {
  64. t.Fatalf("Expected Count: %d, Actual: %d", Expected, count)
  65. }
  66. if err.Error() != expectedError {
  67. t.Fatalf("Expected error: %s, Actual error: %s", expectedError, err.Error())
  68. }
  69. }
  70. func TestCancelRetry(t *testing.T) {
  71. t.Parallel()
  72. const Expected uint64 = 5
  73. var count uint64 = 0
  74. f := func() (interface{}, error) {
  75. c := atomic.AddUint64(&count, 1)
  76. fmt.Println("Try:", c)
  77. return nil, fmt.Errorf("Failed: %d", c)
  78. }
  79. wait := make(chan error)
  80. ctx, cancel := context.WithCancel(context.Background())
  81. // execute retry in go routine
  82. go func() {
  83. _, err := Retry(ctx, f, 5, time.Second)
  84. wait <- err
  85. }()
  86. // cancel after 2 seconds
  87. go func() {
  88. time.Sleep(time.Second * 2)
  89. cancel()
  90. }()
  91. // wait for error result
  92. e := <-wait
  93. if !IsRetryCancelledError(e) {
  94. t.Fatalf("Expected CancellationError, got: %s", e)
  95. }
  96. }