1package backoff 2 3import ( 4 "reflect" 5 "sync" 6 "testing" 7 "time" 8) 9 10func Test1(t *testing.T) { 11 12 b := &Backoff{ 13 Min: 100 * time.Millisecond, 14 Max: 10 * time.Second, 15 Factor: 2, 16 } 17 18 equals(t, b.Duration(), 100*time.Millisecond) 19 equals(t, b.Duration(), 200*time.Millisecond) 20 equals(t, b.Duration(), 400*time.Millisecond) 21 b.Reset() 22 equals(t, b.Duration(), 100*time.Millisecond) 23} 24 25func TestForAttempt(t *testing.T) { 26 27 b := &Backoff{ 28 Min: 100 * time.Millisecond, 29 Max: 10 * time.Second, 30 Factor: 2, 31 } 32 33 equals(t, b.ForAttempt(0), 100*time.Millisecond) 34 equals(t, b.ForAttempt(1), 200*time.Millisecond) 35 equals(t, b.ForAttempt(2), 400*time.Millisecond) 36 b.Reset() 37 equals(t, b.ForAttempt(0), 100*time.Millisecond) 38} 39 40func Test2(t *testing.T) { 41 42 b := &Backoff{ 43 Min: 100 * time.Millisecond, 44 Max: 10 * time.Second, 45 Factor: 1.5, 46 } 47 48 equals(t, b.Duration(), 100*time.Millisecond) 49 equals(t, b.Duration(), 150*time.Millisecond) 50 equals(t, b.Duration(), 225*time.Millisecond) 51 b.Reset() 52 equals(t, b.Duration(), 100*time.Millisecond) 53} 54 55func Test3(t *testing.T) { 56 57 b := &Backoff{ 58 Min: 100 * time.Nanosecond, 59 Max: 10 * time.Second, 60 Factor: 1.75, 61 } 62 63 equals(t, b.Duration(), 100*time.Nanosecond) 64 equals(t, b.Duration(), 175*time.Nanosecond) 65 equals(t, b.Duration(), 306*time.Nanosecond) 66 b.Reset() 67 equals(t, b.Duration(), 100*time.Nanosecond) 68} 69 70func Test4(t *testing.T) { 71 b := &Backoff{ 72 Min: 500 * time.Second, 73 Max: 100 * time.Second, 74 Factor: 1, 75 } 76 77 equals(t, b.Duration(), b.Max) 78} 79 80func TestGetAttempt(t *testing.T) { 81 b := &Backoff{ 82 Min: 100 * time.Millisecond, 83 Max: 10 * time.Second, 84 Factor: 2, 85 } 86 equals(t, b.Attempt(), float64(0)) 87 equals(t, b.Duration(), 100*time.Millisecond) 88 equals(t, b.Attempt(), float64(1)) 89 equals(t, b.Duration(), 200*time.Millisecond) 90 equals(t, b.Attempt(), float64(2)) 91 equals(t, b.Duration(), 400*time.Millisecond) 92 equals(t, b.Attempt(), float64(3)) 93 b.Reset() 94 equals(t, b.Attempt(), float64(0)) 95 equals(t, b.Duration(), 100*time.Millisecond) 96 equals(t, b.Attempt(), float64(1)) 97} 98 99func TestJitter(t *testing.T) { 100 b := &Backoff{ 101 Min: 100 * time.Millisecond, 102 Max: 10 * time.Second, 103 Factor: 2, 104 Jitter: true, 105 } 106 107 equals(t, b.Duration(), 100*time.Millisecond) 108 between(t, b.Duration(), 100*time.Millisecond, 200*time.Millisecond) 109 between(t, b.Duration(), 100*time.Millisecond, 400*time.Millisecond) 110 b.Reset() 111 equals(t, b.Duration(), 100*time.Millisecond) 112} 113 114func TestCopy(t *testing.T) { 115 b := &Backoff{ 116 Min: 100 * time.Millisecond, 117 Max: 10 * time.Second, 118 Factor: 2, 119 } 120 b2 := b.Copy() 121 equals(t, b, b2) 122} 123 124func TestConcurrent(t *testing.T) { 125 b := &Backoff{ 126 Min: 100 * time.Millisecond, 127 Max: 10 * time.Second, 128 Factor: 2, 129 } 130 131 wg := &sync.WaitGroup{} 132 133 test := func() { 134 time.Sleep(b.Duration()) 135 wg.Done() 136 } 137 138 wg.Add(2) 139 go test() 140 go test() 141 wg.Wait() 142} 143 144func between(t *testing.T, actual, low, high time.Duration) { 145 t.Helper() 146 if actual < low { 147 t.Fatalf("Got %s, Expecting >= %s", actual, low) 148 } 149 if actual > high { 150 t.Fatalf("Got %s, Expecting <= %s", actual, high) 151 } 152} 153 154func equals(t *testing.T, v1, v2 interface{}) { 155 t.Helper() 156 if !reflect.DeepEqual(v1, v2) { 157 t.Fatalf("Got %v, Expecting %v", v1, v2) 158 } 159} 160