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  }