retry_test.go 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  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. const Expected uint64 = 3
  14. var count uint64 = 0
  15. f := func() (interface{}, error) {
  16. c := atomic.AddUint64(&count, 1)
  17. fmt.Println("Try:", c)
  18. if c == Expected {
  19. return []*Obj{
  20. {"A"},
  21. {"B"},
  22. {"C"},
  23. }, nil
  24. }
  25. return nil, fmt.Errorf("Failed: %d", c)
  26. }
  27. result, err := Retry(context.Background(), f, 5, time.Second)
  28. objs, ok := result.([]*Obj)
  29. if err != nil || !ok {
  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. const Expected uint64 = 3
  36. var count uint64 = 0
  37. f := func() (interface{}, error) {
  38. c := atomic.AddUint64(&count, 1)
  39. fmt.Println("Try:", c)
  40. if c == Expected {
  41. return struct{}{}, nil
  42. }
  43. return nil, fmt.Errorf("Failed: %d", c)
  44. }
  45. _, err := Retry(context.Background(), f, 5, time.Second)
  46. if err != nil {
  47. t.Fatalf("Unexpected error: %s", err)
  48. }
  49. }
  50. func TestFailRetry(t *testing.T) {
  51. const Expected uint64 = 5
  52. expectedError := fmt.Sprintf("Failed: %d", Expected)
  53. var count uint64 = 0
  54. f := func() (interface{}, error) {
  55. c := atomic.AddUint64(&count, 1)
  56. fmt.Println("Try:", c)
  57. return nil, fmt.Errorf("Failed: %d", c)
  58. }
  59. _, err := Retry(context.Background(), f, 5, time.Second)
  60. if count != 5 {
  61. t.Fatalf("Expected Count: %d, Actual: %d", Expected, count)
  62. }
  63. if err.Error() != expectedError {
  64. t.Fatalf("Expected error: %s, Actual error: %s", expectedError, err.Error())
  65. }
  66. }
  67. func TestCancelRetry(t *testing.T) {
  68. const Expected uint64 = 5
  69. var count uint64 = 0
  70. f := func() (interface{}, error) {
  71. c := atomic.AddUint64(&count, 1)
  72. fmt.Println("Try:", c)
  73. return nil, fmt.Errorf("Failed: %d", c)
  74. }
  75. wait := make(chan error)
  76. ctx, cancel := context.WithCancel(context.Background())
  77. // execute retry in go routine
  78. go func() {
  79. _, err := Retry(ctx, f, 5, time.Second)
  80. wait <- err
  81. }()
  82. // cancel after 2 seconds
  83. go func() {
  84. time.Sleep(time.Second * 2)
  85. cancel()
  86. }()
  87. // wait for error result
  88. e := <-wait
  89. if !IsRetryCancelledError(e) {
  90. t.Fatalf("Expected CancellationError, got: %s", e)
  91. }
  92. }