From fb0c517148baa5af2924042edc6f4c42c3cc4599 Mon Sep 17 00:00:00 2001 From: Ming Yue Date: Thu, 1 Apr 2021 01:57:42 -0700 Subject: Add event_groups.c Unit Test (#536) * Added event_groups.c Unit Test. * Formatted and more comments. * Formatted * Split some test cases and add comment and coverage tag. * Update test cases. * Remove xEventGroupDelete Invalid Input test case, since the implementation does not handle this. --- FreeRTOS/Test/CMock/Makefile | 9 +- FreeRTOS/Test/CMock/event_groups/Makefile | 49 ++ FreeRTOS/Test/CMock/event_groups/event_groups.yml | 32 + .../Test/CMock/event_groups/event_groups_utest.c | 793 +++++++++++++++++++++ FreeRTOS/Test/CMock/event_groups/list_macros.h | 73 ++ 5 files changed, 952 insertions(+), 4 deletions(-) create mode 100644 FreeRTOS/Test/CMock/event_groups/Makefile create mode 100644 FreeRTOS/Test/CMock/event_groups/event_groups.yml create mode 100644 FreeRTOS/Test/CMock/event_groups/event_groups_utest.c create mode 100644 FreeRTOS/Test/CMock/event_groups/list_macros.h diff --git a/FreeRTOS/Test/CMock/Makefile b/FreeRTOS/Test/CMock/Makefile index 5b27de418..177a974a3 100644 --- a/FreeRTOS/Test/CMock/Makefile +++ b/FreeRTOS/Test/CMock/Makefile @@ -7,11 +7,12 @@ export CC ?= /usr/local/bin/gcc export LD ?= /usr/local/bin/ld # Add units here when adding a new unit test directory with the same name -UNITS += list +#UNITS += list #UNITS += queue -#UNITS += timers -UNITS += stream_buffer -UNITS += message_buffer +#UNITS += timers +#UNITS += stream_buffer +#UNITS += message_buffer +UNITS += event_groups COVINFO := $(BUILD_DIR)/cmock_test.info LCOV_LIST := $(foreach unit,$(UNITS),$(GENERATED_DIR)/$(unit).info ) diff --git a/FreeRTOS/Test/CMock/event_groups/Makefile b/FreeRTOS/Test/CMock/event_groups/Makefile new file mode 100644 index 000000000..d220ed760 --- /dev/null +++ b/FreeRTOS/Test/CMock/event_groups/Makefile @@ -0,0 +1,49 @@ +# indent with spaces +.RECIPEPREFIX := $(.RECIPEPREFIX) $(.RECIPEPREFIX) + +# Do not move this line below the include +MAKEFILE_ABSPATH := $(abspath $(lastword $(MAKEFILE_LIST))) +include ../makefile.in + +# PROJECT_SRC lists the .c files under test +PROJECT_SRC := event_groups.c + +# PROJECT_DEPS_SRC list the .c file that are dependencies of PROJECT_SRC files +# Files in PROJECT_DEPS_SRC are excluded from coverage measurements +PROJECT_DEPS_SRC := + +# PROJECT_HEADER_DEPS: headers that should be excluded from coverage measurements. +PROJECT_HEADER_DEPS := FreeRTOS.h + +# SUITE_UT_SRC: .c files that contain test cases (must end in _utest.c) +SUITE_UT_SRC := event_groups_utest.c + +# SUITE_SUPPORT_SRC: .c files used for testing that do not contain test cases. +# Paths are relative to PROJECT_DIR +SUITE_SUPPORT_SRC := + +# List the headers used by PROJECT_SRC that you would like to mock +MOCK_FILES_FP += $(KERNEL_DIR)/include/task.h +MOCK_FILES_FP += $(KERNEL_DIR)/include/list.h +MOCK_FILES_FP += $(KERNEL_DIR)/include/timers.h +MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h +MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_port.h +MOCK_FILES_FP += $(PROJECT_DIR)/list_macros.h + + +# List any addiitonal flags needed by the preprocessor +CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 + +# List any addiitonal flags needed by the compiler +CFLAGS += -include list_macros.h + +# Try not to edit beyond this line unless necessary. + +# Project is determined based on path: $(UT_ROOT_DIR)/$(PROJECT) +PROJECT := $(lastword $(subst /, ,$(dir $(abspath $(MAKEFILE_ABSPATH))))) + +export + +include ../testdir.mk + + diff --git a/FreeRTOS/Test/CMock/event_groups/event_groups.yml b/FreeRTOS/Test/CMock/event_groups/event_groups.yml new file mode 100644 index 000000000..de9ad9be4 --- /dev/null +++ b/FreeRTOS/Test/CMock/event_groups/event_groups.yml @@ -0,0 +1,32 @@ +:cmock: + :mock_prefix: mock_ + :when_no_prototypes: :warn + :treat_externs: :include + :enforce_strict_ordering: TRUE + :plugins: + - :ignore + - :ignore_arg + - :expect_any_args + - :array + - :callback + - :return_thru_ptr + :callback_include_count: true # include a count arg when calling the callback + :callback_after_arg_check: false # check arguments before calling the callback + :treat_as: + uint8: HEX8 + uint16: HEX16 + uint32: UINT32 + int8: INT8 + bool: UINT8 + :includes: # This will add these includes to each mock. + - + - "FreeRTOS.h" + :treat_externs: :exclude # Now the extern-ed functions will be mocked. + :weak: __attribute__((weak)) + :verbosity: 3 + :attributes: + - PRIVILEGED_FUNCTION + :strippables: + - PRIVILEGED_FUNCTION + - portDONT_DISCARD + :treat_externs: :include diff --git a/FreeRTOS/Test/CMock/event_groups/event_groups_utest.c b/FreeRTOS/Test/CMock/event_groups/event_groups_utest.c new file mode 100644 index 000000000..6db3418d2 --- /dev/null +++ b/FreeRTOS/Test/CMock/event_groups/event_groups_utest.c @@ -0,0 +1,793 @@ +/* + * FreeRTOS V202012.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ +/*! @file list_utest.c */ + +/* C runtime includes. */ +#include +#include + +/* List includes */ +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "event_groups.h" + +/* Test includes. */ +#include "unity.h" +#include "unity_memory.h" + +/* Mock includes. */ +#include "mock_task.h" +#include "mock_timers.h" +#include "mock_list.h" +#include "mock_list_macros.h" +#include "mock_fake_assert.h" +#include "mock_fake_port.h" + + +/* =========================== DEFINES CONSTANTS ========================== */ +#define BIT_0 ( 1 << 0 ) +#define BIT_2 ( 1 << 2 ) +#define BIT_4 ( 1 << 4 ) +#define ALL_SYNC_BITS ( BIT_0 | BIT_2 | BIT_4 ) + +/* =========================== GLOBAL VARIABLES =========================== */ + +/** + * @brief Global message buffer handle used for tests. + */ +static EventGroupHandle_t xEventGroupHandle; +static List_t xListTemp = { 0 }; +static List_t * pxListTemp = &xListTemp; +static ListItem_t xListItemDummy = { 0 }; +static ListItem_t * pxListItem_HasTaskBlockOnBit0 = &xListItemDummy; + +/* =========================== EXTERN VARIABLES =========================== */ + +/* ========================== CALLBACK FUNCTIONS =========================== */ + +void * pvPortMalloc( size_t xSize ) +{ + return unity_malloc( xSize ); +} +void vPortFree( void * pv ) +{ + return unity_free( pv ); +} + +/* ============================ Unity Fixtures ============================ */ +/*! called before each testcase */ +void setUp( void ) +{ + xEventGroupHandle = NULL; + + pxListTemp->pxIndex = ( ListItem_t * ) &( pxListTemp->xListEnd ); + pxListTemp->xListEnd.xItemValue = portMAX_DELAY; + pxListTemp->xListEnd.pxNext = ( ListItem_t * ) &( pxListTemp->xListEnd ); + pxListTemp->xListEnd.pxPrevious = ( ListItem_t * ) &( pxListTemp->xListEnd ); + pxListTemp->uxNumberOfItems = ( UBaseType_t ) 0U; + + pxListItem_HasTaskBlockOnBit0->xItemValue = BIT_0; + + vFakeAssert_Ignore(); + vFakePortEnterCriticalSection_Ignore(); + vFakePortExitCriticalSection_Ignore(); + ulFakePortSetInterruptMaskFromISR_IgnoreAndReturn( 0U ); + vFakePortClearInterruptMaskFromISR_Ignore(); + + /* Track calls to malloc / free */ + UnityMalloc_StartTest(); +} + +/*! called after each testcase */ +void tearDown( void ) +{ + UnityMalloc_EndTest(); +} + +/*! called at the beginning of the whole suite */ +void suiteSetUp() +{ +} + +/*! called at the end of the whole suite */ +int suiteTearDown( int numFailures ) +{ + return numFailures; +} + +/* =========================== Static Functions =========================== */ + + +/* ============================== Test Cases ============================== */ + +/*! + * @brief validate dynamically creating and deleting a new RTOS event group, + * @coverage xEventGroupCreate vEventGroupDelete + */ +void test_xEventGroupDynamicCreateAndDelete_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + /* Expectation of Function: vEventGroupDelete */ + vTaskSuspendAll_Ignore(); + listCURRENT_LIST_LENGTH_ExpectAnyArgsAndReturn( 1 ); + vTaskRemoveFromUnorderedEventList_Ignore(); + listCURRENT_LIST_LENGTH_ExpectAnyArgsAndReturn( 0 ); + xTaskResumeAll_IgnoreAndReturn( 1 ); + + /* API to Test */ + xEventGroupHandle = xEventGroupCreate(); + TEST_ASSERT_NOT_EQUAL( NULL, xEventGroupHandle ); + + vEventGroupDelete( xEventGroupHandle ); +} + + +/*! + * @brief validate dynamically creating a event group failed when malloc failed + * @coverage xEventGroupCreate + */ +void test_xEventGroupDynamicCreate_FailMalloc( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Ignore(); + UnityMalloc_MakeMallocFailAfterCount( 0 ); + + /* API to Test */ + xEventGroupHandle = xEventGroupCreate(); + + /* Validate */ + TEST_ASSERT_EQUAL( NULL, xEventGroupHandle ); +} + +/*! + * @brief validate statically creating and deleting a new RTOS event group, + * @coverage xEventGroupCreateStatic vEventGroupDelete + */ +void test_xEventGroupStaticCreate_Success( void ) +{ + /* Expectation of Function: xEventGroupCreateStatic */ + vListInitialise_Ignore(); + + /* Expectation of Function: vEventGroupDelete */ + vTaskSuspendAll_Ignore(); + listCURRENT_LIST_LENGTH_ExpectAnyArgsAndReturn( 1 ); + vTaskRemoveFromUnorderedEventList_Ignore(); + listCURRENT_LIST_LENGTH_ExpectAnyArgsAndReturn( 0 ); + xTaskResumeAll_IgnoreAndReturn( 1 ); + + /* API to Test */ + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + + /* Validate */ + TEST_ASSERT_NOT_EQUAL( NULL, xEventGroupHandle ); + + /* Clean */ + vEventGroupDelete( xEventGroupHandle ); +} + +/*! + * @brief validate statically creating and deleting a new RTOS event group, + * + */ +void test_xEventGroupStaticCreate_InvalidInput_Failed( void ) +{ + /* Expectation of Function: xEventGroupCreateStatic */ + vListInitialise_Ignore(); + + /* API to Test */ + xEventGroupHandle = xEventGroupCreateStatic( NULL ); + + /* Validate */ + TEST_ASSERT_EQUAL( NULL, xEventGroupHandle ); +} + +/*! + * @brief validate setting event bits when not tasked is blocked by that event bits + * @coverage xEventGroupSetBits + */ +void test_xEventGroupSetBits_NoTaskBlockedOnBits_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupSetBits */ + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + vTaskSuspendAll_Ignore(); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + listGET_LIST_ITEM_VALUE_IgnoreAndReturn( 0 ); + xTaskResumeAll_IgnoreAndReturn( 1 ); + + /* Set-up */ + EventBits_t uxBits; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + + /* API to Test */ + uxBits = xEventGroupSetBits( xEventGroupHandle, BIT_0 | BIT_4 ); + + /* Validate */ + TEST_ASSERT_EQUAL( ( BIT_0 | BIT_4 ), uxBits & ( BIT_0 | BIT_4 ) ); +} + +/*! + * @brief validate setting event bits when some tasks are blocked by that event bits + * @coverage xEventGroupSetBits + */ +void test_xEventGroupSetBits_WithTaskBlockedOnBits_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupSetBits */ + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + vTaskSuspendAll_Ignore(); + listGET_NEXT_ExpectAnyArgsAndReturn( pxListItem_HasTaskBlockOnBit0 ); + listGET_LIST_ITEM_VALUE_IgnoreAndReturn( BIT_0 ); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + vTaskRemoveFromUnorderedEventList_Ignore(); + xTaskResumeAll_IgnoreAndReturn( 1 ); + + /* Set-up */ + EventBits_t uxBits; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + + /* API to Test */ + uxBits = xEventGroupSetBits( xEventGroupHandle, BIT_0 ); + + /* Validate */ + TEST_ASSERT_EQUAL( ( BIT_0 ), uxBits & ( BIT_0 ) ); +} + +/*! + * @brief validate the callback fucntion of setting event bits + * @coverage vEventGroupSetBitsCallback + */ +void test_vEventGroupSetBitsCallback_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupSetBits */ + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + vTaskSuspendAll_Ignore(); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + listGET_LIST_ITEM_VALUE_IgnoreAndReturn( 0 ); + xTaskResumeAll_IgnoreAndReturn( 1 ); + + /* Set-up */ + EventBits_t uxReturn; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + + /* API to Test */ + vEventGroupSetBitsCallback( xEventGroupHandle, BIT_0 ); + uxReturn = xEventGroupGetBits( xEventGroupHandle ); + + /* Validate: Expect to return and BIT_0 and BIT_2 was set */ + TEST_ASSERT_EQUAL( BIT_0, uxReturn & BIT_0 ); +} + +/*! + * @brief validate getting current event bits + * @coverage xEventGroupGetBits xEventGroupSetBits + */ +void test_xEventGroupGetBits_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupSetBits */ + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + vTaskSuspendAll_Ignore(); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + listGET_LIST_ITEM_VALUE_IgnoreAndReturn( 0 ); + xTaskResumeAll_IgnoreAndReturn( 1 ); + + /* Expectation of Function: "xEventGroupGetBits" --> xEventGroupSetBits( xEventGroup, 0 ) */ + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + + /* Set-up */ + EventBits_t uxBitsSetVal, uxBitsGetVal; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + + /* API to Test */ + uxBitsSetVal = xEventGroupSetBits( xEventGroupHandle, BIT_0 | BIT_4 ); + uxBitsGetVal = xEventGroupSetBits( xEventGroupHandle, 0 ); /* See event_groups.h: #define xEventGroupGetBits( xEventGroup ) xEventGroupClearBits( xEventGroup, 0 ) */ + + /* Validate */ + TEST_ASSERT_EQUAL( uxBitsSetVal, uxBitsGetVal ); +} + +/*! + * @brief validate getting current event bits from ISR + * @coverage xEventGroupGetBitsFromISR + */ +void test_xEventGroupGetBitsFromISR_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Set-up */ + EventBits_t uxReturn; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + + /* API to Test */ + uxReturn = xEventGroupGetBitsFromISR( xEventGroupHandle ); + + /* Validate */ + TEST_ASSERT_EQUAL( 0, uxReturn ); +} + +/*! + * @brief validate clearing event bits + * @coverage xEventGroupClearBits + */ +void test_xEventGroupClearBits_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupSetBits */ + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + vTaskSuspendAll_Ignore(); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + listGET_LIST_ITEM_VALUE_IgnoreAndReturn( 0 ); + xTaskResumeAll_IgnoreAndReturn( 1 ); + + /* Set-up */ + EventBits_t uxBitsSetVal, uxBitsGetVal; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + + /* API to Test */ + uxBitsSetVal = xEventGroupSetBits( xEventGroupHandle, BIT_0 | BIT_4 ); + TEST_ASSERT_EQUAL( ( BIT_0 | BIT_4 ), uxBitsSetVal & ( BIT_0 | BIT_4 ) ); + uxBitsSetVal = xEventGroupClearBits( xEventGroupHandle, BIT_4 ); + uxBitsGetVal = xEventGroupGetBits( xEventGroupHandle ); + + /* Validate */ + TEST_ASSERT_EQUAL( uxBitsSetVal, uxBitsGetVal | BIT_4 ); + TEST_ASSERT_EQUAL( 0, uxBitsGetVal & BIT_4 ); +} + +/*! + * @brief validate the callback fucntion of clearing event bits + * @coverage vEventGroupClearBitsCallback + */ +void test_vEventGroupClearBitsCallback_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupSetBits */ + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + vTaskSuspendAll_Ignore(); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + listGET_LIST_ITEM_VALUE_IgnoreAndReturn( 0 ); + xTaskResumeAll_IgnoreAndReturn( 1 ); + + /* Set-up */ + EventBits_t uxReturn; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + uxReturn = xEventGroupSetBits( xEventGroupHandle, BIT_0 ); + + /* API to Test */ + vEventGroupClearBitsCallback( xEventGroupHandle, BIT_0 ); + uxReturn = xEventGroupGetBits( xEventGroupHandle ); + + /* Validate: Expect to return and BIT_0 and BIT_2 was set */ + TEST_ASSERT_EQUAL( 0, uxReturn & BIT_0 ); +} + +/*! + * @brief validate waiting on for all bits are set when currently no bits are set. Clear the bit before return. + * @coverage xEventGroupWaitBits + */ +void test_xEventGroupWaitBits_WhenNoBitWasSet_WaitForBoth_ClearBit_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupWaitBits */ + vTaskSuspendAll_Ignore(); + xTaskGetSchedulerState_IgnoreAndReturn( taskSCHEDULER_SUSPENDED ); + vTaskPlaceOnUnorderedEventList_Ignore(); + xTaskResumeAll_IgnoreAndReturn( 1 ); + uxTaskResetEventItemValue_IgnoreAndReturn( 0 ); + + /* Set-up */ + EventBits_t uxBitsSetVal, uxBitsGetVal; + const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + uxBitsSetVal = xEventGroupGetBits( xEventGroupHandle ); + + /* API to Test */ + uxBitsGetVal = xEventGroupWaitBits( + xEventGroupHandle, /* The event group being tested. */ + BIT_0 | BIT_4, /* The bits within the event group to wait for. */ + pdTRUE, /* BIT_0 & BIT_4 should be cleared before returning. */ + pdTRUE, /* Wait for both bits. */ + xTicksToWait ); /* Wait a maximum of 100ms for either bit to be set. */ + + /* Validate: Expect to time-out and BitValue unchanged */ + TEST_ASSERT_EQUAL( uxBitsSetVal, uxBitsGetVal ); +} + +/*! + * @brief validate non-block waiting on for either one bits is set when currently no bits are set. + * Don't clear the bit before return. + * @coverage xEventGroupWaitBits + */ +void test_xEventGroupWaitBits_WhenNoBitWasSet_NonBlock_WaitForEither_NoClear_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupWaitBits */ + vTaskSuspendAll_Ignore(); + xTaskGetSchedulerState_IgnoreAndReturn( taskSCHEDULER_SUSPENDED ); + vTaskPlaceOnUnorderedEventList_Ignore(); + xTaskResumeAll_IgnoreAndReturn( 1 ); + uxTaskResetEventItemValue_IgnoreAndReturn( 0 ); + + /* Set-up */ + EventBits_t uxBitsSetVal, uxBitsGetVal; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + uxBitsSetVal = xEventGroupGetBits( xEventGroupHandle ); + + /* API to Test */ + uxBitsGetVal = xEventGroupWaitBits( + xEventGroupHandle, /* The event group being tested. */ + BIT_0 | BIT_4, /* The bits within the event group to wait for. */ + pdFALSE, /* BIT_0 & BIT_4 should not be cleared before returning. */ + pdFALSE, /* Don't wait for both bits, either bit will do. */ + 0 ); /* Don't block and wait */ + + /* Validate: Expect return and BitValue unchanged */ + TEST_ASSERT_EQUAL( uxBitsSetVal, uxBitsGetVal ); +} + +/*! + * @brief validate waiting on for either one bits. The function should return when one bits are set. + * Don't clear the bit before return. + * @coverage xEventGroupWaitBits + */ +void test_xEventGroupWaitBits_WhenBitWasSet_WaitForEither_NoClear_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupSetBits */ + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + vTaskSuspendAll_Ignore(); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + listGET_LIST_ITEM_VALUE_IgnoreAndReturn( 0 ); + xTaskResumeAll_IgnoreAndReturn( 1 ); + + /* Expectation of Function: xEventGroupWaitBits */ + xTaskGetSchedulerState_IgnoreAndReturn( taskSCHEDULER_SUSPENDED ); + vTaskPlaceOnUnorderedEventList_Ignore(); + uxTaskResetEventItemValue_IgnoreAndReturn( 0 ); + + /* Set-up */ + EventBits_t uxBitsSetVal, uxBitsGetVal; + const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + uxBitsSetVal = xEventGroupSetBits( xEventGroupHandle, BIT_0 ); /* BIT_0 was set */ + + /* API to Test */ + uxBitsSetVal = xEventGroupWaitBits( + xEventGroupHandle, /* The event group being tested. */ + BIT_0 | BIT_4, /* The bits within the event group to wait for. */ + pdFALSE, /* BIT_0 & BIT_4 should not be cleared before returning. */ + pdFALSE, /* Don't wait for both bits, either bit will do. */ + xTicksToWait ); /* Wait a maximum of 100ms for either bit to be set. */ + uxBitsGetVal = xEventGroupGetBits( xEventGroupHandle ); + + /* Validate: Expect to return because BIT_0 was set */ + TEST_ASSERT_EQUAL( BIT_0, uxBitsSetVal ); + TEST_ASSERT_EQUAL( BIT_0, uxBitsGetVal & BIT_0 ); +} + +/*! + * @brief validate waiting on for all bits are set. Don't clear the bit before return. + * @coverage xEventGroupWaitBits + */ +void test_xEventGroupWaitBits_WhenBitWasSet_WaitForBoth_WithClear_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupSetBits x2 */ + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + vTaskSuspendAll_Ignore(); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + listGET_LIST_ITEM_VALUE_IgnoreAndReturn( 0 ); + xTaskResumeAll_IgnoreAndReturn( 1 ); + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + + /* Expectation of Function: xEventGroupWaitBits */ + xTaskGetSchedulerState_IgnoreAndReturn( taskSCHEDULER_SUSPENDED ); + vTaskPlaceOnUnorderedEventList_Ignore(); + uxTaskResetEventItemValue_IgnoreAndReturn( 0 ); + + /* Set-up */ + EventBits_t uxBitsSetVal, uxBitsGetVal; + const TickType_t xTicksToWait = 100 / portTICK_PERIOD_MS; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + uxBitsSetVal = xEventGroupSetBits( xEventGroupHandle, BIT_0 ); /* BIT_0 was set */ + uxBitsSetVal = xEventGroupSetBits( xEventGroupHandle, BIT_4 ); /* BIT_4 was set */ + TEST_ASSERT_EQUAL( BIT_0 | BIT_4, uxBitsSetVal ); + + /* API to Test */ + uxBitsSetVal = xEventGroupWaitBits( + xEventGroupHandle, /* The event group being tested. */ + BIT_0 | BIT_4, /* The bits within the event group to wait for. */ + pdTRUE, /* BIT_0 & BIT_4 should be cleared before returning. */ + pdTRUE, /* Wait for both bits. */ + xTicksToWait ); /* Wait a maximum of 100ms for either bit to be set. */ + uxBitsGetVal = xEventGroupGetBits( xEventGroupHandle ); + + /* Validate: Expect to return because both BIT_0 and BIT_4 was set and then cleared */ + TEST_ASSERT_EQUAL( BIT_0 | BIT_4, uxBitsSetVal & ( BIT_0 | BIT_4 ) ); + TEST_ASSERT_EQUAL( 0, uxBitsGetVal & ( BIT_0 | BIT_4 ) ); +} + +/*! + * @brief validate tasks sync on event bits: + * Set BIT_0 before reach the sync point and wait for all sync bits are set. + * Should return due to timeout. + * @coverage xEventGroupSync + */ +void test_xEventGroupSync_SetBits_BlockWait_NotSynced_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupSetBits */ + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + vTaskSuspendAll_Ignore(); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + xTaskResumeAll_IgnoreAndReturn( 1 ); + listGET_LIST_ITEM_VALUE_IgnoreAndReturn( 0 ); + + /* Expectation of Function: xEventGroupSync */ + xTaskGetSchedulerState_IgnoreAndReturn( taskSCHEDULER_SUSPENDED ); + vTaskPlaceOnUnorderedEventList_Ignore(); + uxTaskResetEventItemValue_IgnoreAndReturn( 0 ); + + /* Set-up */ + EventBits_t uxReturn; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + + /* API to Test */ + uxReturn = xEventGroupSync( xEventGroupHandle, BIT_0, ALL_SYNC_BITS, portMAX_DELAY ); + + /* Validate: Expect to timeout and BIT_0 was set */ + TEST_ASSERT_EQUAL( BIT_0, uxReturn ); +} + +/*! + * @brief validate tasks sync on event bits: + * Non-Block wait for all sync bits are set. + * Should return due to timeout. + * @coverage xEventGroupSync + */ +void test_xEventGroupSync_NoSetBit_NonBlockWait_NotSynced_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupSetBits x2 */ + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + vTaskSuspendAll_Ignore(); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + xTaskResumeAll_IgnoreAndReturn( 1 ); + listGET_LIST_ITEM_VALUE_IgnoreAndReturn( 0 ); + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + + /* Expectation of Function: xEventGroupSync */ + xTaskGetSchedulerState_IgnoreAndReturn( taskSCHEDULER_SUSPENDED ); + vTaskPlaceOnUnorderedEventList_Ignore(); + uxTaskResetEventItemValue_IgnoreAndReturn( 0 ); + + /* Set-up */ + EventBits_t uxReturn; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + uxReturn = xEventGroupSetBits( xEventGroupHandle, ( BIT_0 | BIT_2 ) ); + TEST_ASSERT_EQUAL( ( BIT_0 | BIT_2 ), uxReturn ); + + /* API to Test */ + uxReturn = xEventGroupSync( xEventGroupHandle, 0, ALL_SYNC_BITS, 0 ); + + /* Validate: Expect to return and BIT_0 and BIT_2 was set */ + TEST_ASSERT_EQUAL( ( BIT_0 | BIT_2 ), uxReturn ); +} + +/*! + * @brief validate tasks sync on event bits: + * Set BIT_0 before reach the sync point and wait for all sync bits are set. + * Should return due to reach the sync point. + * @coverage xEventGroupSync + */ +void test_xEventGroupSync_SetBits_BlockWait_Synced_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Expectation of Function: xEventGroupSetBits x2 */ + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + vTaskSuspendAll_Ignore(); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + xTaskResumeAll_IgnoreAndReturn( 1 ); + listGET_LIST_ITEM_VALUE_IgnoreAndReturn( 0 ); + listGET_END_MARKER_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + listGET_NEXT_ExpectAnyArgsAndReturn( ( ListItem_t * ) NULL ); + + /* Expectation of Function: xEventGroupSync */ + xTaskGetSchedulerState_IgnoreAndReturn( taskSCHEDULER_SUSPENDED ); + vTaskPlaceOnUnorderedEventList_Ignore(); + uxTaskResetEventItemValue_IgnoreAndReturn( 0 ); + + /* Set-up */ + EventBits_t uxReturn; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + + /* API to Test */ + uxReturn = xEventGroupSetBits( xEventGroupHandle, ALL_SYNC_BITS ); + uxReturn = xEventGroupSync( xEventGroupHandle, 0, ALL_SYNC_BITS, portMAX_DELAY ); + + /* Validate: Expect to return and BIT_0 and BIT_2 was set */ + TEST_ASSERT_EQUAL( ALL_SYNC_BITS, uxReturn ); +} + +/*! + * @brief validate getting event group number + * @coverage uxEventGroupGetNumber + */ +void test_uxEventGroupGetNumber_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Set-up */ + UBaseType_t xReturn; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + + /* API to Test */ + xReturn = uxEventGroupGetNumber( NULL ); + TEST_ASSERT_EQUAL( 0, xReturn ); + xReturn = uxEventGroupGetNumber( xEventGroupHandle ); + TEST_ASSERT_EQUAL( 0, xReturn ); +} + +/*! + * @brief validate setting event bits. + * @coverage vEventGroupSetNumber + */ +void test_vEventGroupSetNumber_Success( void ) +{ + /* Expectation of Function: xEventGroupCreate */ + vListInitialise_Expect( 0 ); + vListInitialise_IgnoreArg_pxList(); + vListInitialise_ReturnThruPtr_pxList( pxListTemp ); + + /* Set-up */ + UBaseType_t xReturn; + StaticEventGroup_t xCreatedEventGroup = { 0 }; + xEventGroupHandle = xEventGroupCreateStatic( &xCreatedEventGroup ); + + /* API to Test */ + vEventGroupSetNumber( xEventGroupHandle, 3 ); + xReturn = uxEventGroupGetNumber( xEventGroupHandle ); + + /* Validate */ + TEST_ASSERT_EQUAL( 3, xReturn ); +} + +/*! + * @brief validate clearing event bits from ISR. + * @coverage xEventGroupClearBitsFromISR + */ +void test_xEventGroupClearBitsFromISR_Success( void ) +{ + /* Expectation of Function: xEventGroupClearBitsFromISR */ + xTimerPendFunctionCallFromISR_ExpectAndReturn( vEventGroupClearBitsCallback, NULL, 1, NULL, pdPASS ); + xTimerPendFunctionCallFromISR_IgnoreArg_pvParameter1(); + xTimerPendFunctionCallFromISR_IgnoreArg_ulParameter2(); + xTimerPendFunctionCallFromISR_IgnoreArg_pxHigherPriorityTaskWoken(); + + /* API to Test */ + ( void ) xEventGroupClearBitsFromISR( NULL, BIT_0 ); +} + +/*! + * @brief validate setting event bits from ISR. + * @coverage xEventGroupClearBitsFromISR + */ +void test_xEventGroupSetBitsFromISR_Success( void ) +{ + /* Expectation of Function: xEventGroupSetBitsFromISR */ + xTimerPendFunctionCallFromISR_ExpectAndReturn( vEventGroupSetBitsCallback, NULL, 1, pdFALSE, pdPASS ); + xTimerPendFunctionCallFromISR_IgnoreArg_pvParameter1(); + xTimerPendFunctionCallFromISR_IgnoreArg_ulParameter2(); + xTimerPendFunctionCallFromISR_IgnoreArg_pxHigherPriorityTaskWoken(); + + /* Set-up */ + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + /* API to Test */ + ( void ) xEventGroupSetBitsFromISR( NULL, BIT_0, &xHigherPriorityTaskWoken ); +} diff --git a/FreeRTOS/Test/CMock/event_groups/list_macros.h b/FreeRTOS/Test/CMock/event_groups/list_macros.h new file mode 100644 index 000000000..480886b5e --- /dev/null +++ b/FreeRTOS/Test/CMock/event_groups/list_macros.h @@ -0,0 +1,73 @@ +/* + * FreeRTOS V202012.00 + * Copyright (C) 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy of + * this software and associated documentation files (the "Software"), to deal in + * the Software without restriction, including without limitation the rights to + * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of + * the Software, and to permit persons to whom the Software is furnished to do so, + * subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS + * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR + * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER + * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN + * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + * + * https://www.FreeRTOS.org + * https://github.com/FreeRTOS + * + */ + +#ifndef LIST_MACRO_H +#define LIST_MACRO_H + +#include +#include +#include +#include + +struct tskTaskControlBlock; +typedef struct tskTaskControlBlock TCB_t; + +#undef listLIST_IS_EMPTY +BaseType_t listLIST_IS_EMPTY( const List_t * pxList ); + +#undef listGET_OWNER_OF_HEAD_ENTRY +TCB_t * listGET_OWNER_OF_HEAD_ENTRY( const List_t * pxList ); + +#undef listIS_CONTAINED_WITHIN +BaseType_t listIS_CONTAINED_WITHIN( List_t * list, + const ListItem_t * listItem ); + +#undef listGET_LIST_ITEM_VALUE +TickType_t listGET_LIST_ITEM_VALUE( ListItem_t * listItem ); + +#undef listSET_LIST_ITEM_VALUE +void listSET_LIST_ITEM_VALUE( ListItem_t * listItem, + TickType_t itemValue ); + +#undef listLIST_ITEM_CONTAINER +List_t * listLIST_ITEM_CONTAINER( const ListItem_t * listItem ); + +#undef listCURRENT_LIST_LENGTH +UBaseType_t listCURRENT_LIST_LENGTH( const List_t * list ); + +#undef listGET_ITEM_VALUE_OF_HEAD_ENTRY +TickType_t listGET_ITEM_VALUE_OF_HEAD_ENTRY( List_t * list ); + +#undef listGET_LIST_ITEM_OWNER +TCB_t * listGET_LIST_ITEM_OWNER( ListItem_t * listItem ); + +#undef listGET_END_MARKER +ListItem_t * listGET_END_MARKER( ListItem_t * pxList ); + +#undef listGET_NEXT +ListItem_t * listGET_NEXT( ListItem_t * pxList ); + +#endif /* ifndef LIST_MACRO_H */ -- cgit v1.2.1