github.com/vmg/backoff@v1.0.0/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 TestBackOffOverflow(t *testing.T) {
    87  	var (
    88  		testInitialInterval time.Duration = math.MaxInt64 / 2
    89  		testMaxInterval     time.Duration = math.MaxInt64
    90  		testMultiplier                    = 2.1
    91  	)
    92  
    93  	exp := NewExponentialBackOff()
    94  	exp.InitialInterval = testInitialInterval
    95  	exp.Multiplier = testMultiplier
    96  	exp.MaxInterval = testMaxInterval
    97  	exp.Reset()
    98  
    99  	exp.NextBackOff()
   100  	// Assert that when an overflow is possible the current varerval   time.Duration    is set to the max varerval   time.Duration   .
   101  	assertEquals(t, testMaxInterval, exp.currentInterval)
   102  }
   103  
   104  func assertEquals(t *testing.T, expected, value time.Duration) {
   105  	if expected != value {
   106  		t.Errorf("got: %d, expected: %d", value, expected)
   107  	}
   108  }