main
1package retry
2
3import (
4 "context"
5 "errors"
6 "testing"
7 "time"
8)
9
10func TestDo_Success(t *testing.T) {
11 cfg := Config{
12 MaxAttempts: 3,
13 BaseDelay: time.Millisecond,
14 MaxDelay: 10 * time.Millisecond,
15 Multiplier: 2.0,
16 }
17
18 calls := 0
19 err := Do(context.Background(), cfg, func() error {
20 calls++
21 return nil
22 })
23
24 if err != nil {
25 t.Errorf("expected nil error, got %v", err)
26 }
27 if calls != 1 {
28 t.Errorf("expected 1 call, got %d", calls)
29 }
30}
31
32func TestDo_RetryThenSuccess(t *testing.T) {
33 cfg := Config{
34 MaxAttempts: 3,
35 BaseDelay: time.Millisecond,
36 MaxDelay: 10 * time.Millisecond,
37 Multiplier: 2.0,
38 }
39
40 calls := 0
41 err := Do(context.Background(), cfg, func() error {
42 calls++
43 if calls < 3 {
44 return errors.New("temporary error")
45 }
46 return nil
47 })
48
49 if err != nil {
50 t.Errorf("expected nil error, got %v", err)
51 }
52 if calls != 3 {
53 t.Errorf("expected 3 calls, got %d", calls)
54 }
55}
56
57func TestDo_MaxAttemptsExceeded(t *testing.T) {
58 cfg := Config{
59 MaxAttempts: 2,
60 BaseDelay: time.Millisecond,
61 MaxDelay: 10 * time.Millisecond,
62 Multiplier: 2.0,
63 }
64
65 testErr := errors.New("persistent error")
66 calls := 0
67 err := Do(context.Background(), cfg, func() error {
68 calls++
69 return testErr
70 })
71
72 if err == nil {
73 t.Error("expected error, got nil")
74 }
75 if !errors.Is(err, ErrMaxAttemptsExceeded) {
76 t.Errorf("expected ErrMaxAttemptsExceeded, got %v", err)
77 }
78 if !errors.Is(err, testErr) {
79 t.Errorf("expected wrapped testErr, got %v", err)
80 }
81 if calls != 2 {
82 t.Errorf("expected 2 calls, got %d", calls)
83 }
84}
85
86func TestDo_ContextCancellation(t *testing.T) {
87 cfg := Config{
88 MaxAttempts: 10,
89 BaseDelay: 100 * time.Millisecond,
90 MaxDelay: time.Second,
91 Multiplier: 2.0,
92 }
93
94 ctx, cancel := context.WithCancel(context.Background())
95 calls := 0
96
97 go func() {
98 time.Sleep(10 * time.Millisecond)
99 cancel()
100 }()
101
102 err := Do(ctx, cfg, func() error {
103 calls++
104 return errors.New("keep retrying")
105 })
106
107 if !errors.Is(err, context.Canceled) {
108 t.Errorf("expected context.Canceled, got %v", err)
109 }
110}