From c93063a4cfe6eb6a93c33ae51b7a78d64a76daa7 Mon Sep 17 00:00:00 2001 From: Archit Aggarwal Date: Fri, 23 Jul 2021 03:11:10 +0000 Subject: [PATCH 1/6] Add mechanism to validate code example --- .github/workflows/ci.yml | 11 ++- .../code_examples/backoff_algorithm_posix.c | 84 +++++++++++++++++++ docs/doxygen/config.doxyfile | 2 +- docs/doxygen/pages.dox | 17 +++- 4 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 docs/doxygen/code_examples/backoff_algorithm_posix.c diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ab22e79..6c530ae 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -17,7 +17,7 @@ jobs: cmake -S test -B build/ \ -G "Unix Makefiles" \ -DCMAKE_BUILD_TYPE=Debug \ - -DBUILD_CLONE_SUBMODULES=ON \ + -DBUILD_UNIT_TESTS=ON \ -DCMAKE_C_FLAGS='--coverage -Wall -Wextra -Werror' make -C build/ all - name: Test @@ -35,6 +35,15 @@ jobs: uses: FreeRTOS/CI-CD-Github-Actions/coverage-cop@main with: path: ./build/coverage.info + build-code-example: + runs-on: ubuntu-latest + steps: + - name: Clone This Repo + uses: actions/checkout@v2 + - name: Build code example + run: | + cmake -S test -b Build -DBUILD_CODE_EXAMPLE=ON + make -C build code_example_posix -j8 complexity: runs-on: ubuntu-latest steps: diff --git a/docs/doxygen/code_examples/backoff_algorithm_posix.c b/docs/doxygen/code_examples/backoff_algorithm_posix.c new file mode 100644 index 0000000..978a63e --- /dev/null +++ b/docs/doxygen/code_examples/backoff_algorithm_posix.c @@ -0,0 +1,84 @@ +#include "backoff_algorithm.h" +#include +#include +#include +#include +#include + +/* The maximum number of retries for the example code. */ +#define RETRY_MAX_ATTEMPTS ( 5U ) + +/* The maximum back-off delay (in milliseconds) for between retries in the example. */ +#define RETRY_MAX_BACKOFF_DELAY_MS ( 5000U ) + +/* The base back-off delay (in milliseconds) for retry configuration in the example. */ +#define RETRY_BACKOFF_BASE_MS ( 500U ) + +int main() +{ + /* @[code_example_backoffalgorithm_initializeparams] */ + /* Variables used in this example. */ + BackoffAlgorithmStatus_t retryStatus = BackoffAlgorithmSuccess; + BackoffAlgorithmContext_t retryParams; + char serverAddress[] = "amazon.com"; + uint16_t nextRetryBackoff = 0; + + /* Initialize reconnect attempts and interval. */ + BackoffAlgorithm_InitializeParams( &retryParams, + RETRY_BACKOFF_BASE_MS, + RETRY_MAX_BACKOFF_DELAY_MS, + RETRY_MAX_ATTEMPTS ); + /* @[code_example_backoffalgorithm_initializeparams] */ + + int32_t dnsStatus = -1; + struct addrinfo hints; + struct addrinfo ** pListHead = NULL; + struct timespec tp; + + /* Add hints to retrieve only TCP sockets in getaddrinfo. */ + ( void ) memset( &hints, 0, sizeof( hints ) ); + + /* Address family of either IPv4 or IPv6. */ + hints.ai_family = AF_UNSPEC; + /* TCP Socket. */ + hints.ai_socktype = ( int32_t ) SOCK_STREAM; + hints.ai_protocol = IPPROTO_TCP; + + /* @[code_example_backoffalgorithm_getnextbackoff] */ + + /* 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 + { + /* Perform a DNS lookup on the given host name. */ + dnsStatus = getaddrinfo( serverAddress, NULL, &hints, pListHead ); + + /* Retry if DNS resolution query failed. */ + if( dnsStatus != 0 ) + { + /* 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 across devices is different + * and possibility of network collision between devices attempting retries can be avoided. + * + * For the simplicity of this code example, the pseudo random number generator, rand() + * function is used. */ + retryStatus = BackoffAlgorithm_GetNextBackoff( &retryParams, rand(), &nextRetryBackoff ); + + /* Wait for the calculated backoff period before the next retry attempt of querying DNS. + * As usleep() takes nanoseconds as the parameter, we multiply the backoff period by 1000. */ + ( void ) usleep( nextRetryBackoff * 1000U ); + } + } while( ( dnsStatus != 0 ) && ( retryStatus != BackoffAlgorithmRetriesExhausted ) ); + + /* @[code_example_backoffalgorithm_getnextbackoff] */ + + return dnsStatus; +} diff --git a/docs/doxygen/config.doxyfile b/docs/doxygen/config.doxyfile index 01da3ef..665f932 100644 --- a/docs/doxygen/config.doxyfile +++ b/docs/doxygen/config.doxyfile @@ -797,7 +797,7 @@ EXCLUDE_SYMLINKS = NO # that contain example code fragments that are included (see the \include # command). -EXAMPLE_PATH = source/include docs/doxygen/include +EXAMPLE_PATH = source/include docs/doxygen/include docs/doxygen/code_examples # If the value of the EXAMPLE_PATH tag contains directories, you can use the # EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and diff --git a/docs/doxygen/pages.dox b/docs/doxygen/pages.dox index 89d5e3a..c17cf6e 100644 --- a/docs/doxygen/pages.dox +++ b/docs/doxygen/pages.dox @@ -61,19 +61,34 @@ every path of execution and achieve 100% branch coverage.

*/ +/** +@page backoff_algorithm_example Code Example of backoffAlgorithm API +@brief Example POSIX application of retrying DNS resolution operation with exponential backoff-and-jitter with the backoffAlgorithm library. + +@include backoff_algorithm_posix.c + */ + /** @page backoff_algorithm_functions Functions @brief Primary functions of the backoffAlgorithm library:

@subpage define_backoffalgorithm_initializeparams
@subpage define_backoffalgorithm_getnextbackoff
+For a code example of using backoffAlgorithm library for retrying operation with exponential back-off and jitter, refer to @ref backoff_algorithm_example. + @page define_backoffalgorithm_initializeparams BackoffAlgorithm_InitializeParams @snippet backoff_algorithm.h define_backoffalgorithm_initializeparams @copydoc BackoffAlgorithm_InitializeParams +From the @ref backoff_algorithm_example, following is the part relevant to the @ref BackoffAlgorithm_InitializeParams API. +@snippet backoff_algorithm_posix.c code_example_backoffalgorithm_initializeparams + @page define_backoffalgorithm_getnextbackoff BackoffAlgorithm_GetNextBackoff -@snippet backoff_algorithm.h define_backoffalgorithm_getnextbackoff @copydoc BackoffAlgorithm_GetNextBackoff + +From the @ref backoff_algorithm_example, following is the part relevant to the @ref BackoffAlgorithm_GetNextBackoff API. +@snippet backoff_algorithm_posix.c code_example_backoffalgorithm_getnextbackoff + */ From 1b48ca6b861cc234032e7f1b0ddfbb9ee83c9c4b Mon Sep 17 00:00:00 2001 From: Archit Aggarwal Date: Thu, 22 Jul 2021 20:54:53 -0700 Subject: [PATCH 2/6] Minor doc updates from review comments Co-authored-by: Archit Gupta <71798289+archigup@users.noreply.github.com> --- docs/doxygen/pages.dox | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/doxygen/pages.dox b/docs/doxygen/pages.dox index c17cf6e..643e56a 100644 --- a/docs/doxygen/pages.dox +++ b/docs/doxygen/pages.dox @@ -62,8 +62,8 @@ every path of execution and achieve 100% branch coverage. */ /** -@page backoff_algorithm_example Code Example of backoffAlgorithm API -@brief Example POSIX application of retrying DNS resolution operation with exponential backoff-and-jitter with the backoffAlgorithm library. +@page backoff_algorithm_example Code Example for backoffAlgorithm API +@brief Example POSIX application that retries DNS resolution operation with exponential backoff-and-jitter using the backoffAlgorithm library. @include backoff_algorithm_posix.c */ @@ -74,7 +74,7 @@ every path of execution and achieve 100% branch coverage. @subpage define_backoffalgorithm_initializeparams
@subpage define_backoffalgorithm_getnextbackoff
-For a code example of using backoffAlgorithm library for retrying operation with exponential back-off and jitter, refer to @ref backoff_algorithm_example. +For a code example of using backoffAlgorithm library for retrying operations with exponential back-off and jitter, refer to @ref backoff_algorithm_example. @page define_backoffalgorithm_initializeparams BackoffAlgorithm_InitializeParams @snippet backoff_algorithm.h define_backoffalgorithm_initializeparams From 0b48d4ba482d32e02b79bb7c1e83772aacee28df Mon Sep 17 00:00:00 2001 From: Archit Aggarwal Date: Fri, 23 Jul 2021 03:56:10 +0000 Subject: [PATCH 3/6] Add CMakeLists.txt file update missed in previous commit --- test/CMakeLists.txt | 72 ++++++++++++++++++++++++++------------------- 1 file changed, 42 insertions(+), 30 deletions(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 13aad94..561904d 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -22,8 +22,8 @@ set( UNIT_TEST_DIR ${MODULE_ROOT_DIR}/test/unit-test CACHE INTERNAL "backoffAlgo set( UNITY_DIR ${UNIT_TEST_DIR}/Unity CACHE INTERNAL "Unity library source directory." ) # Configure options to always show in CMake GUI. -option( BUILD_CLONE_SUBMODULES - "Set this to ON to automatically clone any required Git submodules. When OFF, submodules must be manually cloned." +option( BUILD_UNIT_TESTS + "Set this to ON to build unit tests. This will clone the required Unity test framework submodule if it is not cloned already." OFF ) # Set output directories. @@ -47,41 +47,53 @@ target_include_directories( coverity_analysis # ==================================== Unit Test Configuration ==================================== -# Include Unity build configuration. -include( unit-test/unity_build.cmake ) +if(${BUILD_CODE_EXAMPLE}) -# Check if the Unity source directory exists, and if not present, clone the submodule -# if BUILD_CLONE_SUBMODULES configuration is enabled. -if( NOT EXISTS ${UNITY_DIR}/src ) - # Attempt to clone Unity. - if( ${BUILD_CLONE_SUBMODULES} ) + # Target for code example binary. + add_executable( code_example_posix + ${MODULE_ROOT_DIR}/docs/doxygen/code_examples/backoff_algorithm_posix.c ) + + target_link_libraries( code_example_posix coverity_analysis ) + +endif() + +# ==================================== Unit Test Configuration ==================================== + +if(${BUILD_UNIT_TESTS}) + + # Include Unity build configuration. + include( unit-test/unity_build.cmake ) + + # Check if the Unity source directory exists, and if not present, clone the submodule + # if BUILD_CLONE_SUBMODULES configuration is enabled. + if( NOT EXISTS ${UNITY_DIR}/src ) + # Attempt to clone Unity. clone_unity() - else() - message( FATAL_ERROR "The required submodule Unity does not exist. Either clone it manually, or set BUILD_CLONE_SUBMODULES to 1 to automatically clone it during build." ) endif() -endif() -# Add unit test and coverage configuration. + # Add unit test and coverage configuration. + + # Use CTest utility for managing test runs. This has to be added BEFORE + # defining test targets with add_test() + enable_testing() -# Use CTest utility for managing test runs. This has to be added BEFORE -# defining test targets with add_test() -enable_testing() + # Add build targets for Unity and Unit, required for unit testing. + add_unity_targets() -# Add build targets for Unity and Unit, required for unit testing. -add_unity_targets() + # Add function to enable Unity based tests and coverage. + include( ${MODULE_ROOT_DIR}/tools/unity/create_test.cmake ) -# Add function to enable Unity based tests and coverage. -include( ${MODULE_ROOT_DIR}/tools/unity/create_test.cmake ) + # Include build configuration for unit tests. + add_subdirectory( unit-test ) -# Include build configuration for unit tests. -add_subdirectory( unit-test ) + # ==================================== Coverage Analysis configuration ============================ -# ==================================== Coverage Analysis configuration ============================ + # Add a target for running coverage on tests. + add_custom_target( coverage + COMMAND ${CMAKE_COMMAND} -DUNITY_DIR=${UNITY_DIR} + -P ${MODULE_ROOT_DIR}/tools/unity/coverage.cmake + DEPENDS unity backoff_algorithm_utest + WORKING_DIRECTORY ${CMAKE_BINARY_DIR} + ) -# Add a target for running coverage on tests. -add_custom_target( coverage - COMMAND ${CMAKE_COMMAND} -DUNITY_DIR=${UNITY_DIR} - -P ${MODULE_ROOT_DIR}/tools/unity/coverage.cmake - DEPENDS unity backoff_algorithm_utest - WORKING_DIRECTORY ${CMAKE_BINARY_DIR} -) +endif() \ No newline at end of file From 9841ec6a66a0340129c91971dcf7efde9bf2e52f Mon Sep 17 00:00:00 2001 From: Archit Aggarwal Date: Fri, 23 Jul 2021 04:00:17 +0000 Subject: [PATCH 4/6] Fix indentation issue causing CI checks from not running --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6c530ae..d3798b6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,7 +36,7 @@ jobs: with: path: ./build/coverage.info build-code-example: - runs-on: ubuntu-latest + runs-on: ubuntu-latest steps: - name: Clone This Repo uses: actions/checkout@v2 From 6ca727f3e05566c0348fa67a2a4667a5bb129ff0 Mon Sep 17 00:00:00 2001 From: Archit Aggarwal Date: Fri, 23 Jul 2021 04:02:36 +0000 Subject: [PATCH 5/6] Fix CI failures --- .github/workflows/ci.yml | 4 ++-- docs/doxygen/pages.dox | 2 +- lexicon.txt | 5 ++++- test/CMakeLists.txt | 4 ++-- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index d3798b6..31f5976 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -42,8 +42,8 @@ jobs: uses: actions/checkout@v2 - name: Build code example run: | - cmake -S test -b Build -DBUILD_CODE_EXAMPLE=ON - make -C build code_example_posix -j8 + cmake -S test -B Build -DBUILD_CODE_EXAMPLE=ON + make -C Build code_example_posix -j8 complexity: runs-on: ubuntu-latest steps: diff --git a/docs/doxygen/pages.dox b/docs/doxygen/pages.dox index 643e56a..1c1b260 100644 --- a/docs/doxygen/pages.dox +++ b/docs/doxygen/pages.dox @@ -65,7 +65,7 @@ every path of execution and achieve 100% branch coverage. @page backoff_algorithm_example Code Example for backoffAlgorithm API @brief Example POSIX application that retries DNS resolution operation with exponential backoff-and-jitter using the backoffAlgorithm library. -@include backoff_algorithm_posix.c +@include backoff_algorithm_posix.c */ /** diff --git a/lexicon.txt b/lexicon.txt index 4eadb40..5e17bca 100644 --- a/lexicon.txt +++ b/lexicon.txt @@ -41,9 +41,11 @@ os param pcontext pnextbackoff +posix pretrycontext pretryparams prng +rand randomvalue readme rm @@ -57,4 +59,5 @@ td toolchain tr trng -utils +usleep +utils \ No newline at end of file diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 561904d..b323092 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -54,9 +54,9 @@ if(${BUILD_CODE_EXAMPLE}) ${MODULE_ROOT_DIR}/docs/doxygen/code_examples/backoff_algorithm_posix.c ) target_link_libraries( code_example_posix coverity_analysis ) - + endif() - + # ==================================== Unit Test Configuration ==================================== if(${BUILD_UNIT_TESTS}) From fc3fe7925a746db2d35705465db3cbe7d37b1ea7 Mon Sep 17 00:00:00 2001 From: Archit Aggarwal Date: Fri, 23 Jul 2021 10:59:22 -0700 Subject: [PATCH 6/6] Add newline Co-authored-by: Paul Bartell --- test/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index b323092..becb94e 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -96,4 +96,4 @@ if(${BUILD_UNIT_TESTS}) WORKING_DIRECTORY ${CMAKE_BINARY_DIR} ) -endif() \ No newline at end of file +endif()