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