github.com/cenkalti/backoff/v4@v4.2.1/exponential_test.go (about) 1 package backoff 2 3 import ( 4 "math" 5 "testing" 6 "time" 7 ) 8 9 func TestBackOff(t *testing.T) { 10 var ( 11 testInitialInterval = 500 * time.Millisecond 12 testRandomizationFactor = 0.1 13 testMultiplier = 2.0 14 testMaxInterval = 5 * time.Second 15 testMaxElapsedTime = 15 * time.Minute 16 ) 17 18 exp := NewExponentialBackOff() 19 exp.InitialInterval = testInitialInterval 20 exp.RandomizationFactor = testRandomizationFactor 21 exp.Multiplier = testMultiplier 22 exp.MaxInterval = testMaxInterval 23 exp.MaxElapsedTime = testMaxElapsedTime 24 exp.Reset() 25 26 var expectedResults = []time.Duration{500, 1000, 2000, 4000, 5000, 5000, 5000, 5000, 5000, 5000} 27 for i, d := range expectedResults { 28 expectedResults[i] = d * time.Millisecond 29 } 30 31 for _, expected := range expectedResults { 32 assertEquals(t, expected, exp.currentInterval) 33 // Assert that the next backoff falls in the expected range. 34 var minInterval = expected - time.Duration(testRandomizationFactor*float64(expected)) 35 var maxInterval = expected + time.Duration(testRandomizationFactor*float64(expected)) 36 var actualInterval = exp.NextBackOff() 37 if !(minInterval <= actualInterval && actualInterval <= maxInterval) { 38 t.Error("error") 39 } 40 } 41 } 42 43 func TestGetRandomizedInterval(t *testing.T) { 44 // 33% chance of being 1. 45 assertEquals(t, 1, getRandomValueFromInterval(0.5, 0, 2)) 46 assertEquals(t, 1, getRandomValueFromInterval(0.5, 0.33, 2)) 47 // 33% chance of being 2. 48 assertEquals(t, 2, getRandomValueFromInterval(0.5, 0.34, 2)) 49 assertEquals(t, 2, getRandomValueFromInterval(0.5, 0.66, 2)) 50 // 33% chance of being 3. 51 assertEquals(t, 3, getRandomValueFromInterval(0.5, 0.67, 2)) 52 assertEquals(t, 3, getRandomValueFromInterval(0.5, 0.99, 2)) 53 } 54 55 type TestClock struct { 56 i time.Duration 57 start time.Time 58 } 59 60 func (c *TestClock) Now() time.Time { 61 t := c.start.Add(c.i) 62 c.i += time.Second 63 return t 64 } 65 66 func TestGetElapsedTime(t *testing.T) { 67 var exp = NewExponentialBackOff() 68 exp.Clock = &TestClock{} 69 exp.Reset() 70 71 var elapsedTime = exp.GetElapsedTime() 72 if elapsedTime != time.Second { 73 t.Errorf("elapsedTime=%d", elapsedTime) 74 } 75 } 76 77 func TestMaxElapsedTime(t *testing.T) { 78 var exp = NewExponentialBackOff() 79 exp.Clock = &TestClock{start: time.Time{}.Add(10000 * time.Second)} 80 // Change the currentElapsedTime to be 0 ensuring that the elapsed time will be greater 81 // than the max elapsed time. 82 exp.startTime = time.Time{} 83 assertEquals(t, Stop, exp.NextBackOff()) 84 } 85 86 func TestCustomStop(t *testing.T) { 87 var exp = NewExponentialBackOff() 88 customStop := time.Minute 89 exp.Stop = customStop 90 exp.Clock = &TestClock{start: time.Time{}.Add(10000 * time.Second)} 91 // Change the currentElapsedTime to be 0 ensuring that the elapsed time will be greater 92 // than the max elapsed time. 93 exp.startTime = time.Time{} 94 assertEquals(t, customStop, exp.NextBackOff()) 95 } 96 97 func TestBackOffOverflow(t *testing.T) { 98 var ( 99 testInitialInterval time.Duration = math.MaxInt64 / 2 100 testMaxInterval time.Duration = math.MaxInt64 101 testMultiplier = 2.1 102 ) 103 104 exp := NewExponentialBackOff() 105 exp.InitialInterval = testInitialInterval 106 exp.Multiplier = testMultiplier 107 exp.MaxInterval = testMaxInterval 108 exp.Reset() 109 110 exp.NextBackOff() 111 // Assert that when an overflow is possible, the current interval time.Duration is set to the max interval time.Duration. 112 assertEquals(t, testMaxInterval, exp.currentInterval) 113 } 114 115 func assertEquals(t *testing.T, expected, value time.Duration) { 116 if expected != value { 117 t.Errorf("got: %d, expected: %d", value, expected) 118 } 119 }