// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. // // Licensed under the Apache License, Version 2.0 (the "License"). You may not // use this file except in compliance with the License. A copy of the // License is located at // // http://aws.amazon.com/apache2.0/ // // or in the "license" file accompanying this file. This file is distributed // on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, // either express or implied. See the License for the specific language governing // permissions and limitations under the License. package backoffconfig import ( "testing" "time" "github.com/aws/amazon-ssm-agent/agent/log" logmocks "github.com/aws/amazon-ssm-agent/agent/mocks/log" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" ) type BackoffConfigTestSuite struct { suite.Suite mockLog log.T } func (suite *BackoffConfigTestSuite) SetupTest() { suite.mockLog = logmocks.NewMockLog() } func TestArtifactTestSuite(t *testing.T) { suite.Run(t, new(BackoffConfigTestSuite)) } func (suite *BackoffConfigTestSuite) TestBound_ReturnsNumberWhenNumberIsInRange() { number := 10 min := 0 max := 100 result, err := bound(number, min, max) assert.Nil(suite.T(), err) assert.Equal(suite.T(), number, result) } func (suite *BackoffConfigTestSuite) TestBound_ReturnsMinWhenNumberLessThanMin() { number := 10 min := 50 max := 100 result, err := bound(number, min, max) assert.Nil(suite.T(), err) assert.Equal(suite.T(), min, result) } func (suite *BackoffConfigTestSuite) TestBound_ReturnsMaxWhenNumberGreaterThanMax() { number := 10 min := 1 max := 5 result, err := bound(number, min, max) assert.Nil(suite.T(), err) assert.Equal(suite.T(), max, result) } func (suite *BackoffConfigTestSuite) TestMin_ReturnsSmallerNumber() { smaller := int64(1) larger := int64(2) assert.Equal(suite.T(), smaller, min(smaller, larger)) assert.Equal(suite.T(), smaller, min(larger, smaller)) assert.Equal(suite.T(), smaller, min(smaller, smaller)) } func (suite *BackoffConfigTestSuite) TestGetMaxElapsedTime_ReturnsMaximumPossibleElapsedTime() { expectedResult := 7 * time.Second initialInterval := 1 * time.Second maxInterval := 100 * time.Second maxDelay := 100 * time.Second growthFactor := 2.0 jitterFactor := 0.0 maxRetries := 3 result, err := getMaxElapsedTime( maxRetries, initialInterval, maxInterval, maxDelay, growthFactor, jitterFactor) assert.Nil(suite.T(), err) assert.Equal(suite.T(), expectedResult, result) } func (suite *BackoffConfigTestSuite) TestGetMaxElapsedTime_IncludesJitter() { initialInterval := 1 * time.Second maxInterval := 100 * time.Second maxDelay := 100 * time.Second growthFactor := 2.0 jitterFactor := 0.2 maxRetries := 4 expectedMillis := float64(1+2+4+8) * 1000.0 * (jitterFactor + 1) expectedResult := time.Duration(expectedMillis) * time.Millisecond result, err := getMaxElapsedTime( maxRetries, initialInterval, maxInterval, maxDelay, growthFactor, jitterFactor) assert.Nil(suite.T(), err) assert.Equal(suite.T(), expectedResult, result) } func (suite *BackoffConfigTestSuite) TestGetMaxElapsedTime_LimitsIntervals() { initialInterval := 1 * time.Second maxInterval := 2 * time.Second maxDelay := 100 * time.Second growthFactor := 2.0 jitterFactor := 0.2 maxRetries := 4 expectedMillis := float64(1+2+2+2) * 1000.0 * (jitterFactor + 1.0) expectedResult := time.Duration(expectedMillis) * time.Millisecond result, err := getMaxElapsedTime( maxRetries, initialInterval, maxInterval, maxDelay, growthFactor, jitterFactor) assert.Nil(suite.T(), err) assert.Equal(suite.T(), expectedResult, result) } func (suite *BackoffConfigTestSuite) TestGetMaxElapsedTime_LimitsTotalElapsedTime() { initialInterval := 1 * time.Second maxInterval := 2 * time.Second maxDelay := 5 * time.Second growthFactor := 2.0 jitterFactor := 0.2 maxRetries := 4 result, err := getMaxElapsedTime( maxRetries, initialInterval, maxInterval, maxDelay, growthFactor, jitterFactor) assert.Nil(suite.T(), err) assert.Equal(suite.T(), maxDelay, result) } func (suite *BackoffConfigTestSuite) TestGetExponentialBackoff_ReturnsExponentialBackoff() { initialInterval := 1 * time.Second maxRetries := 4 expectedMaxMillis := int64(float64(1+2+4+8) * 1000.0 * (defaultJitterFactor + 1)) result, err := GetExponentialBackoff(initialInterval, maxRetries) assert.Nil(suite.T(), err) assert.Equal( suite.T(), initialInterval.Milliseconds(), result.InitialInterval.Milliseconds(), "InitialInterval") assert.Equal( suite.T(), int64(defaultMaxIntervalMillis), result.MaxInterval.Milliseconds(), "MaxInterval") assert.Equal( suite.T(), defaultMultiplier, result.Multiplier, "Multiplier") assert.Equal( suite.T(), defaultJitterFactor, result.RandomizationFactor, "RandomizationFactor") assert.Equal( suite.T(), expectedMaxMillis, result.MaxElapsedTime.Milliseconds(), "MaxElapsedTime") } func (suite *BackoffConfigTestSuite) TestGetDefaultExponentialBackoff_ReturnsExponentialBackoff() { result, err := GetDefaultExponentialBackoff() assert.Nil(suite.T(), err) assert.Equal( suite.T(), defaultInitialInterval.Milliseconds(), result.InitialInterval.Milliseconds(), "InitialInterval") assert.Equal( suite.T(), int64(defaultMaxIntervalMillis), result.MaxInterval.Milliseconds(), "MaxInterval") assert.Equal( suite.T(), defaultMultiplier, result.Multiplier, "Multiplier") assert.Equal( suite.T(), defaultJitterFactor, result.RandomizationFactor, "RandomizationFactor") }