diff --git a/README.md b/README.md
index 8822f11..98e2b66 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-## backOffAlgorithm Library
+## backoffAlgorithm Library
This repository contains the backoffAlgorithm library, a utility library to calculate backoff period for network operation retries (like failed network connection with server) using an exponential backoff with jitter algorithm. The backoffAlgorithm library is distributed under the [MIT Open Source License](LICENSE).
@@ -22,6 +22,7 @@ The example below shows how to use the backoffAlgorithm library to retry a DNS r
#include
#include
#include
+#include
/* The maximum number of retries for the example code. */
#define RETRY_MAX_ATTEMPTS ( 5U )
@@ -32,28 +33,6 @@ The example below shows how to use the backoffAlgorithm library to retry a DNS r
/* The base back-off delay (in milliseconds) for retry configuration in the example. */
#define RETRY_BACKOFF_BASE_MS ( 500U )
-/**
- * A random number generator to provide to the backoffAlgorithm
- * library.
- *
- * This function is used in the exponential backoff with jitter algorithm
- * to calculate the backoff value for the next retry attempt.
- *
- * It is recommended to either use a True Random Number Generator (TRNG) for
- * calculation of unique back-off values in devices so that collision between
- * devices attempting retries at the same intervals can be avoided.
- *
- * For the simplicity of the code example, this function is a pseudo
- * random number generator.
- *
- * @return The generated random number. This example function ALWAYS succeeds
- * in generating a random number.
- */
-static int32_t pseudoRng()
-{
- return( rand() % ( INT32_MAX ) );
-}
-
int main()
{
/* Variables used in this example. */
@@ -65,6 +44,7 @@ int main()
int32_t dnsStatus = -1;
struct addrinfo hints;
struct addrinfo ** pListHead;
+ struct timespec tp;
/* Add hints to retrieve only TCP sockets in getaddrinfo. */
( void ) memset( &hints, 0, sizeof( hints ) );
@@ -77,10 +57,19 @@ int main()
/* Initialize reconnect attempts and interval. */
BackoffAlgorithm_InitializeParams( &retryParams,
- RETRY_BACKOFF_BASE_MS,
- RETRY_MAX_BACKOFF_DELAY_MS,
- RETRY_MAX_ATTEMPTS,
- pseudoRng );
+ RETRY_BACKOFF_BASE_MS,
+ RETRY_MAX_BACKOFF_DELAY_MS,
+ RETRY_MAX_ATTEMPTS );
+
+
+ /* Seed the pseudo random number generator used in this example (with call to
+ * rand() function provided by ISO C standard library) for use in backoff period
+ * calculation when retrying failed DNS resolution. */
+
+ /* Get current time to seed pseudo random number generator. */
+ ( void ) clock_gettime( CLOCK_REALTIME, &tp );
+ /* Seed pseudo random number generator with seconds. */
+ srand( tp.tv_sec );
do
{
@@ -90,8 +79,14 @@ int main()
/* Retry if DNS resolution query failed. */
if( dnsStatus != 0 )
{
- /* Get back-off value (in milliseconds) for the next retry. */
- retryStatus = BackoffAlgorithm_GetNextBackoff( &retryParams, &nextRetryBackOff );
+ /* Generate a random number and get back-off value (in milliseconds) for the next retry.
+ * Note: It is recommended to use a random number generator that is seeded with
+ * device-specific entropy source so that backoff calculation in devices is different
+ * and possibility of network collision between devices attempting retries can be avoided.
+ *
+ * For the simplicity of the code example, the pseudo random number generator, rand() function
+ * is used. */
+ retryStatus = BackoffAlgorithm_GetNextBackoff( &retryParams, rand(), &nextRetryBackOff );
}
} while( ( dnsStatus != 0 ) && ( retryStatus != BackoffAlgorithmRetriesExhausted ) );
diff --git a/docs/doxygen/pages.dox b/docs/doxygen/pages.dox
index 3d15406..b928771 100644
--- a/docs/doxygen/pages.dox
+++ b/docs/doxygen/pages.dox
@@ -36,7 +36,7 @@ For a reference example of using the library, refer to the related README sectio
- Code size of backoffAlgorithm library files (sizes generated with [GCC for ARM Cortex-M toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads/9-2020-q2-update)) |
+ Code size (in bytes) of backoffAlgorithm library files (sizes generated with [GCC for ARM Cortex-M toolchain](https://developer.arm.com/tools-and-software/open-source-software/developer-tools/gnu-toolchain/gnu-rm/downloads/9-2020-q2-update)) |
File |
@@ -46,9 +46,9 @@ For a reference example of using the library, refer to the related README sectio
backoff_algorithm.c |
- 0.6K |
- 0.2K |
- 0.2K |
+ 678 |
+ 140 |
+ 136 |
@@ -61,13 +61,12 @@ All functions in the backoffAlgorithm library operate only on the buffer provide
local variables on the stack.
-Random Number Generator
+Random Number Generation
-The library requires a platform-specific random number generator for the "jitter"
-part of the algorithm when generating the next backoff value. To avoid calculation
-of the same random numbers across your fleet of devices attempting retry of network
-operations, it is RECOMMENDED to provide a random number generator that is seeded with
-an entropy source unique to the device.
+The library takes a random number each time it calculates the backoff period value for the
+retry attempt. To avoid calculation of the same random numbers across your fleet of devices
+attempting retry of network operations, it is RECOMMENDED to generate the random number with
+a random number generator that is seeded with an entropy source unique to the device.
Compliance & Coverage
diff --git a/lexicon.txt b/lexicon.txt
index 292e85a..dfd4203 100644
--- a/lexicon.txt
+++ b/lexicon.txt
@@ -2,7 +2,11 @@ api
apis
aws
backoff
+backoff
backoffalgorithm
+backoffalgorithmretriesexhausted
+backoffalgorithmrngfailure
+backoffalgorithmsuccess
backoffbase
br
com
@@ -13,6 +17,7 @@ getaddrinfo
https
ifndef
inc
+ingroup
iot
longjmp
maxattempts
@@ -21,20 +26,17 @@ min
mockrng
noninfringement
param
+pcontext
pnextbackoff
pretrycontext
pretryparams
prng
-backoffalgorithmretriesexhausted
-backoffalgorithmrngfailure
-backoffalgorithmsuccess
+randomvalue
rng
sdk
shouldn
stderr
sublicense
tcp
-utils
-ingroup
-backoff
-pcontext
\ No newline at end of file
+trng
+utils
\ No newline at end of file
diff --git a/source/backoff_algorithm.c b/source/backoff_algorithm.c
index 6d1132c..db66ad8 100644
--- a/source/backoff_algorithm.c
+++ b/source/backoff_algorithm.c
@@ -36,10 +36,10 @@
/*-----------------------------------------------------------*/
BackoffAlgorithmStatus_t BackoffAlgorithm_GetNextBackoff( BackoffAlgorithmContext_t * pRetryContext,
+ uint32_t randomValue,
uint16_t * pNextBackOff )
{
BackoffAlgorithmStatus_t status = BackoffAlgorithmSuccess;
- int32_t randomVal = 0;
assert( pRetryContext != NULL );
assert( pNextBackOff != NULL );
@@ -48,34 +48,24 @@ BackoffAlgorithmStatus_t BackoffAlgorithm_GetNextBackoff( BackoffAlgorithmContex
if( ( pRetryContext->attemptsDone < pRetryContext->maxRetryAttempts ) ||
( pRetryContext->maxRetryAttempts == BACKOFF_ALGORITHM_RETRY_FOREVER ) )
{
- /* Generate a random number. */
- randomVal = pRetryContext->pRng();
+ /* The next backoff value is a random value between 0 and the maximum jitter value
+ * for the retry attempt. */
- if( randomVal < 0 )
+ /* Choose a random value for back-off time between 0 and the max jitter value. */
+ *pNextBackOff = ( uint16_t ) ( randomValue % ( pRetryContext->nextJitterMax + 1U ) );
+
+ /* Increment the retry attempt. */
+ pRetryContext->attemptsDone++;
+
+ /* Double the max jitter value for the next retry attempt, only
+ * if the new value will be less than the max backoff time value. */
+ if( pRetryContext->nextJitterMax < ( pRetryContext->maxBackoffDelay / 2U ) )
{
- status = BackoffAlgorithmRngFailure;
+ pRetryContext->nextJitterMax += pRetryContext->nextJitterMax;
}
else
{
- /* The next backoff value is a random value between 0 and the maximum jitter value
- * for the retry attempt. */
-
- /* Choose a random value for back-off time between 0 and the max jitter value. */
- *pNextBackOff = ( uint16_t ) ( randomVal % ( pRetryContext->nextJitterMax + 1U ) );
-
- /* Increment the retry attempt. */
- pRetryContext->attemptsDone++;
-
- /* Double the max jitter value for the next retry attempt, only
- * if the new value will be less than the max backoff time value. */
- if( pRetryContext->nextJitterMax < ( pRetryContext->maxBackOffDelay / 2U ) )
- {
- pRetryContext->nextJitterMax += pRetryContext->nextJitterMax;
- }
- else
- {
- pRetryContext->nextJitterMax = pRetryContext->maxBackOffDelay;
- }
+ pRetryContext->nextJitterMax = pRetryContext->maxBackoffDelay;
}
}
else
@@ -94,17 +84,15 @@ BackoffAlgorithmStatus_t BackoffAlgorithm_GetNextBackoff( BackoffAlgorithmContex
void BackoffAlgorithm_InitializeParams( BackoffAlgorithmContext_t * pContext,
uint16_t backOffBase,
uint16_t maxBackOff,
- uint32_t maxAttempts,
- BackoffAlgorithm_RNG_t pRng )
+ uint32_t maxAttempts )
{
assert( pContext != NULL );
/* Initialize the context with parameters used in calculating the backoff
* value for the next retry attempt. */
pContext->nextJitterMax = backOffBase;
- pContext->maxBackOffDelay = maxBackOff;
+ pContext->maxBackoffDelay = maxBackOff;
pContext->maxRetryAttempts = maxAttempts;
- pContext->pRng = pRng;
/* The total number of retry attempts is zero at initialization. */
pContext->attemptsDone = 0;
diff --git a/source/include/backoff_algorithm.h b/source/include/backoff_algorithm.h
index c15a22c..6dab41e 100644
--- a/source/include/backoff_algorithm.h
+++ b/source/include/backoff_algorithm.h
@@ -42,20 +42,6 @@
*/
#define BACKOFF_ALGORITHM_RETRY_FOREVER 0
-/**
- * @brief Interface for a random number generator.
- * The user should supply the platform-specific random number generator to the
- * library through the @ref BackoffAlgorithm_InitializeParams API function.
- *
- * @note It is recommended that a true random number generator is supplied
- * to the library. The random number generator should be seeded with an entropy
- * source in the system.
- *
- * @return The random number if successful; otherwise a negative value to indicate
- * failure.
- */
-typedef int32_t ( * BackoffAlgorithm_RNG_t )();
-
/**
* @ingroup backoff_algorithm_enum_types
* @brief Status for @ref BackoffAlgorithm_GetNextBackoff.
@@ -63,7 +49,6 @@ typedef int32_t ( * BackoffAlgorithm_RNG_t )();
typedef enum BackoffAlgorithmStatus
{
BackoffAlgorithmSuccess = 0, /**< @brief The function successfully calculated the next back-off value. */
- BackoffAlgorithmRngFailure = 1, /**< @brief The function encountered failure in generating random number. */
BackoffAlgorithmRetriesExhausted /**< @brief The function exhausted all retry attempts. */
} BackoffAlgorithmStatus_t;
@@ -77,7 +62,7 @@ typedef struct BackoffAlgorithmContext
/**
* @brief The maximum backoff delay (in milliseconds) between consecutive retry attempts.
*/
- uint16_t maxBackOffDelay;
+ uint16_t maxBackoffDelay;
/**
* @brief The total number of retry attempts completed.
@@ -94,12 +79,6 @@ typedef struct BackoffAlgorithmContext
* @brief The maximum number of retry attempts.
*/
uint32_t maxRetryAttempts;
-
- /**
- * @brief The random number generator function used for calculating the
- * backoff value for the next retry attempt.
- */
- BackoffAlgorithm_RNG_t pRng;
} BackoffAlgorithmContext_t;
/**
@@ -115,15 +94,12 @@ typedef struct BackoffAlgorithmContext
* use in the exponential backoff and jitter model.
* @param[in] maxAttempts The maximum number of retry attempts. Set the value to
* #BACKOFF_ALGORITHM_RETRY_FOREVER to retry for ever.
- * @param[in] pRng The platform-specific function to use for random number generation.
- * The random number generator should be seeded before calling this function.
*/
/* @[define_backoffalgorithm_initializeparams] */
void BackoffAlgorithm_InitializeParams( BackoffAlgorithmContext_t * pContext,
uint16_t backOffBase,
uint16_t maxBackOff,
- uint32_t maxAttempts,
- BackoffAlgorithm_RNG_t pRng );
+ uint32_t maxAttempts );
/* @[define_backoffalgorithm_initializeparams] */
/**
@@ -135,15 +111,22 @@ void BackoffAlgorithm_InitializeParams( BackoffAlgorithmContext_t * pContext,
*
* @param[in, out] pRetryContext Structure containing parameters for the next backoff
* value calculation.
+ * @param[in] randomValue The random value to use for calculation of the backoff period.
+ * The random value should be in the range of [0, UINT32_MAX].
* @param[out] pNextBackOff This will be populated with the backoff value (in milliseconds)
* for the next retry attempt. The value does not exceed the maximum backoff delay
* configured in the context.
*
- * @return #BackoffAlgorithmSuccess after a successful sleep, #BackoffAlgorithmRngFailure for a failure
- * in random number generation, #BackoffAlgorithmRetriesExhausted when all attempts are exhausted.
+ * @note For generating a random number, it is recommended to use a Random Number Generator
+ * that is seeded with a device-specific entropy source so that possibility of collisions
+ * between multiple devices retrying the network operations can be mitigated.
+ *
+ * @return #BackoffAlgorithmSuccess after a successful sleep;
+ * #BackoffAlgorithmRetriesExhausted when all attempts are exhausted.
*/
/* @[define_backoffalgorithm_getnextbackoff] */
BackoffAlgorithmStatus_t BackoffAlgorithm_GetNextBackoff( BackoffAlgorithmContext_t * pRetryContext,
+ uint32_t randomValue,
uint16_t * pNextBackOff );
/* @[define_backoffalgorithm_getnextbackoff] */
diff --git a/test/unit-test/backoff_algorithm_utest.c b/test/unit-test/backoff_algorithm_utest.c
index 71f94bc..26fdc36 100644
--- a/test/unit-test/backoff_algorithm_utest.c
+++ b/test/unit-test/backoff_algorithm_utest.c
@@ -33,9 +33,6 @@
/* Backoff Algorithm library include */
#include "backoff_algorithm.h"
-/* Return value of mockRng. */
-static int32_t randomValToReturn;
-
#define TEST_BACKOFF_BASE_VALUE ( 1000 )
#define TEST_BACKOFF_MAX_VALUE ( 10000 )
#define TEST_MAX_ATTEMPTS ( 5 )
@@ -43,35 +40,27 @@ static int32_t randomValToReturn;
static BackoffAlgorithmContext_t retryParams;
/* Return value of #BackoffAlgorithm_GetNextBackoff. */
static BackoffAlgorithmStatus_t BackoffAlgorithmStatus;
-static uint16_t nextBackOff;
-
-/**
- * @brief A mock random number generator.
- */
-static int32_t mockRng()
-{
- return randomValToReturn;
-}
+static uint16_t nextBackoff;
+static uint32_t testRandomVal;
/* ============================ UNITY FIXTURES ============================ */
/* Called before each test method. */
void setUp()
{
- /* Initialize context with random number generator that succeeds. */
+ /* Initialize context. */
BackoffAlgorithm_InitializeParams( &retryParams,
TEST_BACKOFF_BASE_VALUE,
TEST_BACKOFF_MAX_VALUE,
- TEST_MAX_ATTEMPTS,
- mockRng );
+ TEST_MAX_ATTEMPTS );
}
/* Called after each test method. */
void tearDown()
{
- randomValToReturn = 0;
+ testRandomVal = 0;
BackoffAlgorithmStatus = BackoffAlgorithmSuccess;
- nextBackOff = 0;
+ nextBackoff = 0;
}
/* Called at the beginning of the whole suite. */
@@ -93,15 +82,13 @@ int suiteTearDown( int numFailures )
static void verifyContextData( BackoffAlgorithmContext_t * pContext,
uint32_t expectedAttemptsDone,
uint16_t expectedNextJitterMax,
- uint16_t expectedMaxBackOff,
- uint32_t expectedMaxAttempts,
- BackoffAlgorithm_RNG_t pExpectedRng )
+ uint16_t expectedMaxBackoff,
+ uint32_t expectedMaxAttempts )
{
TEST_ASSERT_EQUAL( expectedNextJitterMax, pContext->nextJitterMax );
TEST_ASSERT_EQUAL( expectedAttemptsDone, pContext->attemptsDone );
TEST_ASSERT_EQUAL( expectedMaxAttempts, pContext->maxRetryAttempts );
- TEST_ASSERT_EQUAL( expectedMaxBackOff, pContext->maxBackOffDelay );
- TEST_ASSERT_EQUAL_PTR( pExpectedRng, pContext->pRng );
+ TEST_ASSERT_EQUAL( expectedMaxBackoff, pContext->maxBackoffDelay );
}
/**
@@ -113,8 +100,7 @@ void test_BackoffAlgorithm_InitializeParams_Invalid_Context( void )
catch_assert( BackoffAlgorithm_InitializeParams( NULL /* Invalid context */,
TEST_BACKOFF_BASE_VALUE,
TEST_BACKOFF_MAX_VALUE,
- TEST_MAX_ATTEMPTS,
- mockRng ) );
+ TEST_MAX_ATTEMPTS ) );
}
/**
@@ -126,53 +112,12 @@ void test_BackoffAlgorithm_InitializeParams_Sets_Jitter_Correctly( void )
BackoffAlgorithm_InitializeParams( &retryParams,
TEST_BACKOFF_BASE_VALUE,
TEST_BACKOFF_MAX_VALUE,
- TEST_MAX_ATTEMPTS,
- mockRng );
+ TEST_MAX_ATTEMPTS );
verifyContextData( &retryParams,
0,
TEST_BACKOFF_BASE_VALUE,
TEST_BACKOFF_MAX_VALUE,
- TEST_MAX_ATTEMPTS,
- mockRng );
-}
-
-/**
- * @brief Test that #BackoffAlgorithm_GetNextBackoff returns the expected failure
- * and does not update the context data when the random number generator fails.
- */
-void test_BackoffAlgorithm_GetNextBackoff_Rng_Failure( void )
-{
- int32_t testNegativeVal[] = { -1, -10 };
- uint iter = 0;
-
- /* Initialize context with random number generator that fails. */
- BackoffAlgorithm_InitializeParams( &retryParams,
- TEST_BACKOFF_BASE_VALUE,
- TEST_BACKOFF_MAX_VALUE,
- BACKOFF_ALGORITHM_RETRY_FOREVER,
- mockRng );
-
- /* Test the #BackoffAlgorithm_GetNextBackoff API with the 2 negative values
- * from the mock random number generator. */
-
- for( ; iter < sizeof( testNegativeVal ) / sizeof( int32_t ); iter++ )
- {
- /* Set the random value generated to be negative. */
- randomValToReturn = testNegativeVal[ iter ];
-
- /* Make sure that the API function returns RNG failure.*/
- TEST_ASSERT_EQUAL( BackoffAlgorithmRngFailure,
- BackoffAlgorithm_GetNextBackoff( &retryParams, &nextBackOff ) );
-
- /* Make sure that the context data has not changed as the call to
- * BackoffAlgorithm_GetNextBackoff failed. */
- verifyContextData( &retryParams,
- 0,
- TEST_BACKOFF_BASE_VALUE,
- TEST_BACKOFF_MAX_VALUE,
- BACKOFF_ALGORITHM_RETRY_FOREVER,
- mockRng );
- }
+ TEST_MAX_ATTEMPTS );
}
/**
@@ -188,17 +133,17 @@ void test_BackoffAlgorithm_GetNextBackoff_Success_RandVal_Less_Than_Jitter_Max(
int iter = 1;
uint16_t expectedAttemptsDone = 0;
uint16_t expectedNextJitterMax = TEST_BACKOFF_BASE_VALUE;
- uint16_t expectedNextBackOff = 0;
+ uint16_t expectedNextBackoff = 0;
for( ; iter < 2; iter++ )
{
- /* Set the random value to be generated as a value lower than
+ /* Set the random value as a value lower than
* the jitter max value for the next retry attempt. */
- randomValToReturn = retryParams.nextJitterMax / 2;
+ testRandomVal = retryParams.nextJitterMax / 2;
/* As the random value is less than the max jitter value, the expected
* next backoff value should remain the same as the random value. */
- expectedNextBackOff = randomValToReturn;
+ expectedNextBackoff = testRandomVal;
/* The jitter max value should double with the above call for use in next call. */
expectedNextJitterMax *= 2;
@@ -210,16 +155,15 @@ void test_BackoffAlgorithm_GetNextBackoff_Success_RandVal_Less_Than_Jitter_Max(
/* Call the BackoffAlgorithm_GetNextBackoff API a couple times. */
TEST_ASSERT_EQUAL( BackoffAlgorithmSuccess,
- BackoffAlgorithm_GetNextBackoff( &retryParams, &nextBackOff ) );
- TEST_ASSERT_EQUAL( expectedNextBackOff, nextBackOff );
+ BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, &nextBackoff ) );
+ TEST_ASSERT_EQUAL( expectedNextBackoff, nextBackoff );
/* Verify that the context data for expected data after the API call. */
verifyContextData( &retryParams,
expectedAttemptsDone,
expectedNextJitterMax,
TEST_BACKOFF_MAX_VALUE,
- TEST_MAX_ATTEMPTS,
- mockRng );
+ TEST_MAX_ATTEMPTS );
}
}
@@ -239,9 +183,9 @@ void test_BackoffAlgorithm_GetNextBackoff_Success_RandVal_More_Than_Jitter_Max(
for( ; iter < 2; iter++ )
{
- /* Set the random value to be generated as a value greater than
+ /* Set the random value as a value greater than
* the jitter max value for the next retry attempt. */
- randomValToReturn = retryParams.nextJitterMax + 1;
+ testRandomVal = retryParams.nextJitterMax + 1;
/* The jitter max value should double with the above call for use in next call. */
expectedNextJitterMax *= 2;
@@ -253,20 +197,19 @@ void test_BackoffAlgorithm_GetNextBackoff_Success_RandVal_More_Than_Jitter_Max(
/* As the random value is greater than the jitter max value, the expected
* next backoff value should be truncated to a value within the jitter window
* for the retry attempt. */
- uint16_t expectedNextBackOff = ( randomValToReturn % ( retryParams.nextJitterMax + 1U ) );
+ uint16_t expectedNextBackoff = ( testRandomVal % ( retryParams.nextJitterMax + 1U ) );
/* Call the BackoffAlgorithm_GetNextBackoff API a couple times. */
TEST_ASSERT_EQUAL( BackoffAlgorithmSuccess,
- BackoffAlgorithm_GetNextBackoff( &retryParams, &nextBackOff ) );
- TEST_ASSERT_EQUAL( expectedNextBackOff, nextBackOff );
+ BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, &nextBackoff ) );
+ TEST_ASSERT_EQUAL( expectedNextBackoff, nextBackoff );
/* Verify that the context data for expected data after the API call. */
verifyContextData( &retryParams,
expectedAttemptsDone,
expectedNextJitterMax,
TEST_BACKOFF_MAX_VALUE,
- TEST_MAX_ATTEMPTS,
- mockRng );
+ TEST_MAX_ATTEMPTS );
}
}
@@ -282,9 +225,9 @@ void test_BackoffAlgorithm_GetNextBackoff_Attempts_Exhausted()
/* Call the BackoffAlgorithm_GetNextBackoff API. */
TEST_ASSERT_EQUAL( BackoffAlgorithmRetriesExhausted,
- BackoffAlgorithm_GetNextBackoff( &retryParams, &nextBackOff ) );
+ BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, &nextBackoff ) );
/* Make sure that the value of the output parameter has not changed. */
- TEST_ASSERT_EQUAL( 0, nextBackOff );
+ TEST_ASSERT_EQUAL( 0, nextBackoff );
/* Make sure that the context data has not changed as the call to
* BackoffAlgorithm_GetNextBackoff failed. */
@@ -292,15 +235,14 @@ void test_BackoffAlgorithm_GetNextBackoff_Attempts_Exhausted()
TEST_MAX_ATTEMPTS /* Number of attempts shouldn't change */,
TEST_BACKOFF_BASE_VALUE,
TEST_BACKOFF_MAX_VALUE,
- TEST_MAX_ATTEMPTS,
- mockRng );
+ TEST_MAX_ATTEMPTS );
}
/**
- * @brief Test that the value of the next max jitter has a lower bound that will
- * then be capped at some max threshold.
+ * @brief Tests that the #BackoffAlgorithm_GetNextBackoff API does not calculate a backoff period
+ * beyond the configured maximum backoff period.
*/
-void test_BackoffAlgorithm_GetNextBackoff_Returns_Cap_BackOff( void )
+void test_BackoffAlgorithm_GetNextBackoff_Returns_Cap_Backoff( void )
{
/* Initialize to 0 attempts, so the max value of next jitter will increase. */
retryParams.attemptsDone = 0U;
@@ -310,17 +252,17 @@ void test_BackoffAlgorithm_GetNextBackoff_Returns_Cap_BackOff( void )
* the configured maximum backoff value. */
retryParams.nextJitterMax = ( TEST_BACKOFF_MAX_VALUE / 2U ) + 1;
- /* Set the random value to be generated equal to the current jitter max value.
+ /* Set the random value equal to the current jitter max value.
* Thus, the BackoffAlgorithm_GetNextBackoff API should return the random value as
* the next back-off value. */
- randomValToReturn = retryParams.nextJitterMax;
- uint16_t expectedBackOffVal = randomValToReturn;
+ testRandomVal = retryParams.nextJitterMax;
+ uint16_t expectedBackoffVal = testRandomVal;
/* Call the BackoffAlgorithm_GetNextBackoff API. */
TEST_ASSERT_EQUAL( BackoffAlgorithmSuccess,
- BackoffAlgorithm_GetNextBackoff( &retryParams, &nextBackOff ) );
+ BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, &nextBackoff ) );
/* Make sure that the expected value is returned for the next backoff. */
- TEST_ASSERT_EQUAL( expectedBackOffVal, nextBackOff );
+ TEST_ASSERT_EQUAL( expectedBackoffVal, nextBackoff );
/* Verify that the next jitter max value has been set to the cap back-off value
* configured in the context. */
@@ -328,44 +270,50 @@ void test_BackoffAlgorithm_GetNextBackoff_Returns_Cap_BackOff( void )
1,
TEST_BACKOFF_MAX_VALUE /* New jitter max */,
TEST_BACKOFF_MAX_VALUE,
- TEST_MAX_ATTEMPTS,
- mockRng );
+ TEST_MAX_ATTEMPTS );
- /* Now, set the random value to be generated as the maximum back-off value to
+ /* Now, set the random value as the maximum back-off value to
* expect that the next back-off value returned by the API is the maximum
* back-off value.*/
- randomValToReturn = TEST_BACKOFF_MAX_VALUE;
+ testRandomVal = TEST_BACKOFF_MAX_VALUE;
/* Call BackoffAlgorithm_GetNextBackoff API again to verify that it now returns the
* cap value as the next back-off value. */
TEST_ASSERT_EQUAL( BackoffAlgorithmSuccess,
- BackoffAlgorithm_GetNextBackoff( &retryParams, &nextBackOff ) );
+ BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, &nextBackoff ) );
/* Make sure that the capped backoff value is returned as the next backoff value . */
- TEST_ASSERT_EQUAL( TEST_BACKOFF_MAX_VALUE, nextBackOff );
+ TEST_ASSERT_EQUAL( TEST_BACKOFF_MAX_VALUE, nextBackoff );
/* Verify that the context data for expected data after the API call. */
verifyContextData( &retryParams,
2,
TEST_BACKOFF_MAX_VALUE /* jitter max remains unchanged */,
TEST_BACKOFF_MAX_VALUE,
- TEST_MAX_ATTEMPTS,
- mockRng );
+ TEST_MAX_ATTEMPTS );
}
/**
- * @brief Test that the value of the next max jitter has a lower bound that will
- * then be capped at some max threshold.
+ * @brief Tests the #BackoffAlgorithm_GetNextBackoff API when the next jitter max value
+ * is one lower than half of the maximum backoff value. This tests that the API does not
+ * update the next jitter max to the maximum backoff value in this case.
*/
-void test_BackoffAlgorithm_GetNextBackoff_Returns_Rand_Val( void )
+void test_BackoffAlgorithm_GetNextBackoff_NextJitterMax_Below_Cap_Backoff( void )
{
+ /* Initialize context.
+ * Use the configuration constant of retrying forever to achieve branch coverage in tests
+ * for the configuration. */
+ BackoffAlgorithm_InitializeParams( &retryParams,
+ TEST_BACKOFF_BASE_VALUE,
+ TEST_BACKOFF_MAX_VALUE,
+ BACKOFF_ALGORITHM_RETRY_FOREVER );
+
/* Initialize to 0 attempts, so the max value of next jitter will increase. */
retryParams.attemptsDone = 0U;
- /* Set the returned random value to zero to test that the
- * BackoffAlgorithm_GetNextBackoff API will return zero as the
- * next back-off value.*/
- randomValToReturn = 0;
+ /* Set the random value to zero to test that the BackoffAlgorithm_GetNextBackoff
+ * API will return zero as the next back-off value.*/
+ testRandomVal = 0;
/* Update the next jitter max value to one less than half of max backoff
* to make sure that the BackoffAlgorithm_GetNextBackoff API does not update it
@@ -374,17 +322,16 @@ void test_BackoffAlgorithm_GetNextBackoff_Returns_Rand_Val( void )
/* Call the BackoffAlgorithm_GetNextBackoff API. */
TEST_ASSERT_EQUAL( BackoffAlgorithmSuccess,
- BackoffAlgorithm_GetNextBackoff( &retryParams, &nextBackOff ) );
+ BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, &nextBackoff ) );
/* Make sure that zero is returned as the next backoff value . */
- TEST_ASSERT_EQUAL( 0, nextBackOff );
+ TEST_ASSERT_EQUAL( 0, nextBackoff );
/* Verify that the context data for expected data after the API call. */
verifyContextData( &retryParams,
1,
TEST_BACKOFF_MAX_VALUE - 2U /* next jitter max value */,
TEST_BACKOFF_MAX_VALUE,
- TEST_MAX_ATTEMPTS,
- mockRng );
+ BACKOFF_ALGORITHM_RETRY_FOREVER );
}
/**
@@ -394,8 +341,8 @@ void test_BackoffAlgorithm_GetNextBackoff_Returns_Rand_Val( void )
void test_BackoffAlgorithm_GetNextBackoff_Invalid_Params()
{
/* Invalid context. */
- catch_assert( BackoffAlgorithm_GetNextBackoff( NULL, &nextBackOff ) );
+ catch_assert( BackoffAlgorithm_GetNextBackoff( NULL, testRandomVal, &nextBackoff ) );
/* Invalid output parameter for next back-off. */
- catch_assert( BackoffAlgorithm_GetNextBackoff( &retryParams, NULL ) );
+ catch_assert( BackoffAlgorithm_GetNextBackoff( &retryParams, testRandomVal, NULL ) );
}