From 1ac492d6aa9b9c7a66ea21ef0847909d09f0af75 Mon Sep 17 00:00:00 2001 From: alfred gedeon <28123637+alfred2g@users.noreply.github.com> Date: Tue, 16 Aug 2022 23:38:26 +0200 Subject: [PATCH] Kernel timers.c tasks.c Unit Test (#539) * Test: add multi config ability to build system * Remove Tests that are not implemented yet from the makefile * Fix header check * Test: Unit Test tasks.c * UnitTest: tasks.c Save progress * saving some work 70% coverage * coverage 77% * tasks.c coverage 90% * tasks.c coverage 95% * Cleanup and common header * Cover some extra branches, no_mutex +stack growth * Fix Makefile not to use modified version of c-preprocessor * Remove c-preprocessor errros * Rebase and add some tests * Fortify_source=1 and O0 are mutually exclusive * Style: Uncrustify code * Style: Fix indent * Fix Header checks * Add prototypes * Build: use unifdef instead of the c-preprocessor to generate different configurations * Build: fix makefile cflags * Fix UT after upgrading kernel version * Resolve conflicts and test failures * Comment fix version number * Fix build error * Update FreeRTOS/Test/CMock/Makefile Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com> Co-authored-by: Aniruddha Kanhere <60444055+AniruddhaKanhere@users.noreply.github.com> --- FreeRTOS/Test/CMock/Makefile | 137 +- FreeRTOS/Test/CMock/Readme.md | 4 + FreeRTOS/Test/CMock/config/FreeRTOSConfig.h | 6 +- FreeRTOS/Test/CMock/config/fake_port.h | 4 + FreeRTOS/Test/CMock/config/portmacro.h | 132 +- FreeRTOS/Test/CMock/coverage.mk | 99 + FreeRTOS/Test/CMock/doc/Makefile | 6 +- FreeRTOS/Test/CMock/event_groups/Makefile | 3 +- FreeRTOS/Test/CMock/list/Makefile | 2 +- FreeRTOS/Test/CMock/makefile.in | 16 +- FreeRTOS/Test/CMock/stream_buffer/Makefile | 3 +- FreeRTOS/Test/CMock/subdir.mk | 4 +- FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_1.h | 139 + FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_2.h | 134 + FreeRTOS/Test/CMock/tasks/Makefile | 181 + FreeRTOS/Test/CMock/tasks/global_vars.h | 336 ++ FreeRTOS/Test/CMock/tasks/list_macros.h | 75 + FreeRTOS/Test/CMock/tasks/tasks.yml | 32 + FreeRTOS/Test/CMock/tasks/tasks_1_utest.c | 5107 +++++++++++++++++ FreeRTOS/Test/CMock/tasks/tasks_2_utest.c | 758 +++ FreeRTOS/Test/CMock/testdir.mk | 108 +- FreeRTOS/Test/CMock/timers/FreeRTOSConfig_1.h | 139 + .../CMock/timers/FreeRTOSConfig_dynamic.h | 139 + FreeRTOS/Test/CMock/timers/Makefile | 214 +- FreeRTOS/Test/CMock/timers/global_vars.h | 105 + FreeRTOS/Test/CMock/timers/list_macros.h | 64 + FreeRTOS/Test/CMock/timers/timers_1_utest.c | 1786 ++++++ .../Test/CMock/timers/timers_dynamic_utest.c | 482 ++ FreeRTOS/Test/CMock/timers/timers_utest.c | 136 - FreeRTOS/Test/CMock/tools/callgraph.py | 4 + 30 files changed, 9953 insertions(+), 402 deletions(-) create mode 100644 FreeRTOS/Test/CMock/coverage.mk create mode 100644 FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_1.h create mode 100644 FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_2.h create mode 100644 FreeRTOS/Test/CMock/tasks/Makefile create mode 100644 FreeRTOS/Test/CMock/tasks/global_vars.h create mode 100644 FreeRTOS/Test/CMock/tasks/list_macros.h create mode 100644 FreeRTOS/Test/CMock/tasks/tasks.yml create mode 100644 FreeRTOS/Test/CMock/tasks/tasks_1_utest.c create mode 100644 FreeRTOS/Test/CMock/tasks/tasks_2_utest.c create mode 100644 FreeRTOS/Test/CMock/timers/FreeRTOSConfig_1.h create mode 100644 FreeRTOS/Test/CMock/timers/FreeRTOSConfig_dynamic.h create mode 100644 FreeRTOS/Test/CMock/timers/global_vars.h create mode 100644 FreeRTOS/Test/CMock/timers/list_macros.h create mode 100644 FreeRTOS/Test/CMock/timers/timers_1_utest.c create mode 100644 FreeRTOS/Test/CMock/timers/timers_dynamic_utest.c delete mode 100644 FreeRTOS/Test/CMock/timers/timers_utest.c diff --git a/FreeRTOS/Test/CMock/Makefile b/FreeRTOS/Test/CMock/Makefile index 3c77051cfd..4aa947e1a6 100644 --- a/FreeRTOS/Test/CMock/Makefile +++ b/FreeRTOS/Test/CMock/Makefile @@ -7,26 +7,37 @@ 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 := timers +UNITS += tasks UNITS += list UNITS += queue -#UNITS += timers UNITS += stream_buffer UNITS += message_buffer UNITS += event_groups +.PHONY: makefile.in + +UNITY_OPTIONS := -DUNITY_USE_COMMAND_LINE_ARGS +UNITY_OPTIONS += -DUNITY_OUTPUT_COLOR -DUNITY_INCLUDE_PRINT_FORMATTED COVINFO := $(BUILD_DIR)/cmock_test.info LCOV_LIST := $(foreach unit,$(UNITS),$(GENERATED_DIR)/$(unit).info ) -.PHONY: all doc clean $(UNITS) directories coverage zero_coverage \ - run run_formatted run_col_formatted run_col libs execs lcov \ +.PHONY: all doc clean $(UNITS) directories coverage zero_coverage \ + run run_formatted run_col_formatted run_col libs execs lcov \ help -all: doc coverage -execs: $(UNITS) +include makefile.in + +all: doc coverage | directories +execs: $(UNITS) | directories $(UNITS) : libs | directories $(MAKE) -C $@ +Makefile : ; + +makefile.in : ; + SHARED_LIBS := $(addprefix $(LIB_DIR)/,$(addsuffix .so,$(LIBS))) libs : $(SHARED_LIBS) @@ -35,72 +46,85 @@ doc: $(MAKE) -C doc all clean: - rm -rf build + rm -rf $(BUILD_DIR) help: - @echo -e 'Usage: $$ make \n ' - @echo -e ' where is one of: $(UNITS) doc all run run_formatted run_col run_col_formatted coverage' - -$(LIB_DIR)/libcmock.so : ${CMOCK_SRC_DIR}/cmock.c \ - ${CMOCK_SRC_DIR}/cmock.h \ - ${LIB_DIR}/libunity.so \ - Makefile - mkdir -p $(LIB_DIR) + @echo -e 'Usage: $$ make \n ' + @echo -e ' where is one of: $(UNITS) doc all run run_formatted run_col run_col_formatted coverage' + @echo -e '' + @echo -e '$(UNITS) : will build the corresponding test including all its configuration' + @echo -e 'doc : will generate doxygen docs in $(BUILD_DIR)/doc/index.html' + @echo -e 'run : will build and run all $(UNITS) and their various configurations.' + @echo -e ' It will also generate a test report in the JUnit format in $(BUILD_DIR)/report.xml' + @echo -e 'run_col : same as run but the results are in colors(pass: green, fail: red)' + @echo -e 'run_formatted : will show test case results in a formatted way' + @echo -e 'run_col_formatted : same as formatted but will show the results in colors' + @echo -e 'coverage : will run code coverage and generate html docs in $(BUILD_DIR)/coverage/index.html' + @echo -e 'all : will build documentations and coverage, which builds and runs all tests' + +$(LIB_DIR)/libcmock.so : $(CMOCK_SRC_DIR)/cmock.c \ + $(CMOCK_SRC_DIR)/cmock.h \ + $(LIB_DIR)/libunity.so \ + Makefile | directories + $(CC) -o $@ -shared -fPIC $< $(INCLUDE_DIR) + + +$(LIB_DIR)/libunity.so : $(UNITY_SRC_DIR)/unity.c \ + $(UNITY_SRC_DIR)/unity.h \ + Makefile | directories + ${CC} -o $@ $(UNITY_OPTIONS) -shared -fPIC $< + +$(LIB_DIR)/libunitymemory.so: ${UNITY_MEM_DIR}/unity_memory.c \ + ${UNITY_MEM_DIR}/unity_memory.h \ + ${LIB_DIR}/libunity.so \ + Makefile | directories ${CC} -o $@ -shared -fPIC $< ${INCLUDE_DIR} -$(LIB_DIR)/libunity.so : ${UNITY_SRC_DIR}/unity.c \ - ${UNITY_SRC_DIR}/unity.h \ - Makefile - mkdir -p $(LIB_DIR) - ${CC} -o $@ -shared -fPIC $< - -$(LIB_DIR)/libunitymemory.so: ${UNITY_MEM_DIR}/unity_memory.c \ - ${UNITY_MEM_DIR}/unity_memory.h \ - ${LIB_DIR}/libunity.so \ - Makefile - mkdir -p $(LIB_DIR) - ${CC} -o $@ -shared -fPIC $< ${INCLUDE_DIR} - -$(LIB_DIR)/libcexception.so: ${C_EXCEPTION_SRC_DIR}/CException.c \ - ${C_EXCEPTION_SRC_DIR}/CException.h - mkdir -p $(LIB_DIR) - ${CC} -o $@ -shared -fPIC $< ${INCLUDE_DIR} +$(LIB_DIR)/libcexception.so: ${C_EXCEPTION_SRC_DIR}/CException.c \ + ${C_EXCEPTION_SRC_DIR}/CException.h \ + Makefile | directories + ${CC} -o $@ -shared -fPIC $< ${INCLUDE_DIR} -run : $(UNITS) - mkdir -p $(BUILD_DIR) - rm -f $(BUILD_DIR)/unit_test_report.txt - for f in $(BIN_DIR)/*; do \ - $${f} | tee -a $(BUILD_DIR)/unit_test_report.txt; \ +run : $(UNITS) | directories + -rm -f $(BUILD_DIR)/unit_test_report.txt + for f in $(BIN_DIR)/*; do \ + $${f} | tee -a $(BUILD_DIR)/unit_test_report.txt ; \ done - cd $(BUILD_DIR) && \ - ruby $(UNITY_BIN_DIR)/parse_output.rb -xml \ - $(BUILD_DIR)/unit_test_report.txt + cd $(BUILD_DIR) && \ + ruby $(UNITY_BIN_DIR)/parse_output.rb \ + -xml $(BUILD_DIR)/unit_test_report.txt -run_col : $(UNITS) zero_coverage +run_col : $(UNITS) zero_coverage | directories for f in $(BIN_DIR)/*; do \ - ruby -r $(UNITY_BIN_DIR)/colour_reporter.rb -e "report('`$${f}`')"; done + ruby -r $(UNITY_BIN_DIR)/colour_reporter.rb -e "report('`$${f}`')"; \ + done -run_formatted : $(UNITS) zero_coverage - for f in $(BIN_DIR)/*; do \ - $${f} > $(BUILD_DIR)/output; \ - ruby $(UNITY_BIN_DIR)/parse_output.rb $(BUILD_DIR)/output ; \ +run_formatted : $(UNITS) zero_coverage | directories + for f in $(BIN_DIR)/*; do \ + $${f} > $(BUILD_DIR)/output; \ + ruby $(UNITY_BIN_DIR)/parse_output.rb $(BUILD_DIR)/output ; \ done -run_col_formatted : $(UNITS) zero_coverage - for f in $(BIN_DIR)/*; do \ - $${f} > $(BUILD_DIR)/output; \ - ruby -r $(UNITY_BIN_DIR)/colour_reporter.rb \ - -e "report('$$(ruby $(UNITY_BIN_DIR)/parse_output.rb \ - $(BUILD_DIR)/output)')"; \ +run_col_formatted : $(UNITS) zero_coverage | directories + for f in $(BIN_DIR)/*; do \ + $${f} > $(BUILD_DIR)/output; \ + ruby -r $(UNITY_BIN_DIR)/colour_reporter.rb \ + -e "report('$$(ruby $(UNITY_BIN_DIR)/parse_output.rb \ + $(BUILD_DIR)/output)')"; \ done +directories: + -mkdir -p $(BUILD_DIR) + -mkdir -p $(LIB_DIR) + -mkdir -p $(COVERAGE_DIR) + -mkdir -p $(BIN_DIR) zero_coverage : - lcov --zerocounters --directory $(BUILD_DIR) --config-file $(UT_ROOT_DIR)/lcovrc + lcov --zerocounters --directory $(BUILD_DIR) --config-file $(UT_ROOT_DIR)/lcovrc coverage : run_col - lcov --base-directory $(KERNEL_DIR) --directory $(BUILD_DIR) --capture \ - --config-file $(UT_ROOT_DIR)/lcovrc -o $(BUILD_DIR)/cmock_test.info - genhtml $(BUILD_DIR)/cmock_test.info --branch-coverage \ + lcov --base-directory $(KERNEL_DIR) --directory $(BUILD_DIR) --capture \ + --config-file $(UT_ROOT_DIR)/lcovrc -o $(COVINFO) + genhtml $(COVINFO) --branch-coverage \ --config-file $(UT_ROOT_DIR)/lcovrc --output-directory $(COVERAGE_DIR) lcov : $(COVINFO) @@ -113,6 +137,5 @@ $(COVINFO) : $(LCOV_LIST) $(LCOV_LIST) : zero_coverage make -C $(subst .info,,$(@F)) lcov -lcovhtml : $(COVINFO) - mkdir -p $(COVERAGE_DIR) +lcovhtml : $(COVINFO) | directories genhtml $(COVINFO) $(LCOV_OPTS) --output-directory $(COVERAGE_DIR) --quiet diff --git a/FreeRTOS/Test/CMock/Readme.md b/FreeRTOS/Test/CMock/Readme.md index e5ce98f8ad..a17163f79e 100644 --- a/FreeRTOS/Test/CMock/Readme.md +++ b/FreeRTOS/Test/CMock/Readme.md @@ -5,6 +5,10 @@ GCC ``` gcc: gcc (GCC) 9.2.0 ``` +unifdef +``` +version 2.12 +``` LCOV ``` lcov: LCOV version 1.14-6-g40580cd diff --git a/FreeRTOS/Test/CMock/config/FreeRTOSConfig.h b/FreeRTOS/Test/CMock/config/FreeRTOSConfig.h index 0e737294f8..9baa2add99 100644 --- a/FreeRTOS/Test/CMock/config/FreeRTOSConfig.h +++ b/FreeRTOS/Test/CMock/config/FreeRTOSConfig.h @@ -79,9 +79,13 @@ /* Run time stats gathering configuration options. */ unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */ void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */ -#define configGENERATE_RUN_TIME_STATS 1 + +#define configGENERATE_RUN_TIME_STATS 1 #define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats() #define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue() +#define portUSING_MPU_WRAPPERS 0 +#define portHAS_STACK_OVERFLOW_CHECKING 1 +#define configENABLE_MPU 0 /* Co-routine related configuration options. */ #define configUSE_CO_ROUTINES 0 diff --git a/FreeRTOS/Test/CMock/config/fake_port.h b/FreeRTOS/Test/CMock/config/fake_port.h index df43bcdb2e..5511dca028 100644 --- a/FreeRTOS/Test/CMock/config/fake_port.h +++ b/FreeRTOS/Test/CMock/config/fake_port.h @@ -42,5 +42,9 @@ void vFakePortAssertIfInterruptPriorityInvalid( void ); void vFakePortEnterCriticalSection( void ); void vFakePortExitCriticalSection( void ); +void vPortCurrentTaskDying( void * pxTaskToDelete, + volatile BaseType_t * pxPendYield ); +void portSetupTCB_CB( void * tcb ); +void vFakePortAssertIfISR(); #endif /* FAKE_PORT_H */ diff --git a/FreeRTOS/Test/CMock/config/portmacro.h b/FreeRTOS/Test/CMock/config/portmacro.h index f1f225ba2d..dbe9de0a26 100644 --- a/FreeRTOS/Test/CMock/config/portmacro.h +++ b/FreeRTOS/Test/CMock/config/portmacro.h @@ -48,11 +48,13 @@ */ #ifndef PORTMACRO_H - #define PORTMACRO_H +#define PORTMACRO_H - #ifdef __cplusplus +/* *INDENT-OFF* */ +#ifdef __cplusplus extern "C" { - #endif +#endif +/* *INDENT-ON* */ /*----------------------------------------------------------- * Port specific definitions. @@ -64,45 +66,48 @@ *----------------------------------------------------------- */ +#include + /* Type definitions. */ - #define portCHAR char - #define portFLOAT float - #define portDOUBLE double - #define portLONG long - #define portSHORT short - #define portSTACK_TYPE uint32_t - #define portBASE_TYPE long - - typedef portSTACK_TYPE StackType_t; - typedef long BaseType_t; - typedef unsigned long UBaseType_t; - - #if ( configUSE_16_BIT_TICKS == 1 ) - typedef uint16_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffff - #else - typedef uint32_t TickType_t; - #define portMAX_DELAY ( TickType_t ) 0xffffffffUL - #endif +#define portCHAR char +#define portFLOAT float +#define portDOUBLE double +#define portLONG long +#define portSHORT short +#define portSTACK_TYPE uint32_t +#define portBASE_TYPE long + +typedef portSTACK_TYPE StackType_t; +typedef long BaseType_t; +typedef unsigned long UBaseType_t; + +#if ( configUSE_16_BIT_TICKS == 1 ) + typedef uint16_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffff +#else + typedef uint32_t TickType_t; + #define portMAX_DELAY ( TickType_t ) 0xffffffffUL +#endif +#define portPOINTER_SIZE_TYPE uint64_t /*-----------------------------------------------------------*/ /* Requires definition of UBaseType_t */ - #include "fake_port.h" +#include "fake_port.h" /* Hardware specifics. */ - #define portSTACK_GROWTH ( -1 ) - #define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) - #define portBYTE_ALIGNMENT 8 - #define portNOP() __asm volatile ( "NOP" ) +#define portTICK_PERIOD_MS ( ( TickType_t ) 1000 / configTICK_RATE_HZ ) +#define portBYTE_ALIGNMENT 8 +#define portNOP() __asm volatile ( "NOP" ) /* * These define the timer to use for generating the tick interrupt. * They are put in this file so they can be shared between "port.c" * and "portisr.c". */ - #define portTIMER_REG_BASE_PTR - #define portTIMER_CLK_ENABLE_BIT - #define portTIMER_AIC_CHANNEL +#define portTIMER_REG_BASE_PTR +#define portTIMER_CLK_ENABLE_BIT +#define portTIMER_AIC_CHANNEL + /*-----------------------------------------------------------*/ /* Task utilities. */ @@ -114,39 +119,64 @@ * THUMB mode code will result in a compile time error. */ - #define portRESTORE_CONTEXT() +#define portRESTORE_CONTEXT() /*-----------------------------------------------------------*/ - #define portSAVE_CONTEXT() - #define portYIELD() vFakePortYield() - #define portYIELD_WITHIN_API() vFakePortYieldWithinAPI() - #define portYIELD_FROM_ISR() vFakePortYieldFromISR() +#define portSAVE_CONTEXT() +#define portYIELD() vFakePortYield() +#define portYIELD_WITHIN_API() vFakePortYieldWithinAPI() +#define portYIELD_FROM_ISR() vFakePortYieldFromISR() /* Critical section handling. */ - #define portDISABLE_INTERRUPTS() vFakePortDisableInterrupts() - #define portENABLE_INTERRUPTS() vFakePortEnableInterrupts() - #define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) \ +#define portDISABLE_INTERRUPTS() vFakePortDisableInterrupts() +#define portENABLE_INTERRUPTS() vFakePortEnableInterrupts() +#define portCLEAR_INTERRUPT_MASK_FROM_ISR( x ) \ vFakePortClearInterruptMaskFromISR( x ) - #define portSET_INTERRUPT_MASK_FROM_ISR() \ +#define portSET_INTERRUPT_MASK_FROM_ISR() \ ulFakePortSetInterruptMaskFromISR() - #define portSET_INTERRUPT_MASK() ulFakePortSetInterruptMask() - #define portCLEAR_INTERRUPT_MASK( x ) vFakePortClearInterruptMask( x ) - #define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() \ +#define portSET_INTERRUPT_MASK() ulFakePortSetInterruptMask() +#define portCLEAR_INTERRUPT_MASK( x ) vFakePortClearInterruptMask( x ) +#define portASSERT_IF_INTERRUPT_PRIORITY_INVALID() \ vFakePortAssertIfInterruptPriorityInvalid() +#define portENTER_CRITICAL() vFakePortEnterCriticalSection() +#define portEXIT_CRITICAL() vFakePortExitCriticalSection() - #define portENTER_CRITICAL() vFakePortEnterCriticalSection() - #define portEXIT_CRITICAL() vFakePortExitCriticalSection() +#define portPRE_TASK_DELETE_HOOK( pvTaskToDelete, pxPendYield ) \ + vPortCurrentTaskDying( ( pvTaskToDelete ), ( pxPendYield ) ) +#define portSETUP_TCB( pxTCB ) portSetupTCB_CB( pxTCB ); +#define portASSERT_IF_IN_ISR() vFakePortAssertIfISR(); - #undef portUSING_MPU_WRAPPERS -/*-----------------------------------------------------------*/ +static uint8_t ucPortCountLeadingZeros( uint32_t ulBitmap ) +{ + uint8_t ucReturn; + + ucReturn = __builtin_clz( ulBitmap ); + return ucReturn; +} + + +#define portRECORD_READY_PRIORITY( uxPriority, uxReadyPriorities ) \ + ( uxReadyPriorities ) |= ( 1UL << ( uxPriority ) ) +#define portRESET_READY_PRIORITY( uxPriority, uxReadyPriorities ) \ + ( uxReadyPriorities ) &= ~( 1UL << ( uxPriority ) ) +#define portGET_HIGHEST_PRIORITY( uxTopPriority, uxReadyPriorities ) \ + uxTopPriority = ( 31UL - ( uint32_t ) ucPortCountLeadingZeros( ( uxReadyPriorities ) ) ) /* Task function macros as described on the FreeRTOS.org WEB site. */ - #define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) void vFunction( void * pvParameters ) - #define portTASK_FUNCTION( vFunction, pvParameters ) void vFunction( void * pvParameters ) +#define portTASK_FUNCTION_PROTO( vFunction, pvParameters ) \ + volatile int fool_static = 0; \ + void vFunction( void * ( pvParameters ) ) - #ifdef __cplusplus - } - #endif +#define portTASK_FUNCTION( vFunction, pvParameters ) \ + volatile int fool_static2 = 0; \ + void vFunction( void * ( pvParameters ) ) +/*-----------------------------------------------------------*/ + +/* *INDENT-OFF* */ +#ifdef __cplusplus + } +#endif +/* *INDENT-ON* */ #endif /* PORTMACRO_H */ diff --git a/FreeRTOS/Test/CMock/coverage.mk b/FreeRTOS/Test/CMock/coverage.mk new file mode 100644 index 0000000000..95f750cf0b --- /dev/null +++ b/FreeRTOS/Test/CMock/coverage.mk @@ -0,0 +1,99 @@ +COVINFO := $(abspath $(SCRATCH_DIR)/..)/$(EXEC_PREFIX).info +COVINFO_INITIAL := $(SCRATCH_DIR)/$(EXEC_PREFIX)_initial.info +LCOV_LIST := $(addsuffix .info,$(addprefix $(SCRATCH_DIR)/,$(SUITE_UT_SRC:.c=))) +PROJ_GCDA_LIST := $(PROJ_SRC_LIST:.c=.gcda) +COV_REPORT_DIR := $(SCRATCH_DIR)/coverage +COVINFO_COMBINE := $(SCRATCH_DIR)/$(EXEC_PREFIX)_combined.info + + +GCOV_OPTS := --unconditional-branches --branch-probabilities + +# Cases that run test binaries cannot be run in parallel. +.NOTPARALLEL : $(COVINFO) $(LCOV_LIST) $(PROJ_GCDA_LIST) + +# Prevent deletion of intermediate files +NO_DELETE : $(MOCK_HDR_LIST) $(MOCK_SRC_LIST) $(MOCK_OBJ_LIST) \ + $(DEPS_OBJ_LIST) $(SF_OBJ_LIST) $(EXEC_LIST) \ + $(PROJ_PP_LIST) $(PROJ_OBJ_LIST) $(PROJ_GCDA_LIST) \ + $(SUITE_OBJ_LIST) $(RUNNER_SRC_LIST) $(RUNNER_OBJ_LIST) \ + $(COVINFO) $(LCOV_LIST) + + +# Generate gcov files by default +run : gcov + +gcov : $(PROJ_GCDA_LIST) + +clean : + rm -rf $(SCRATCH_DIR) + rm -f $(BIN_DIR)/$(PROJECT)_utest_* + rm -f $(COVINFO) + +libs : + make -C $(UT_ROOT_DIR) libs + +define run-test +$(1) +endef + +$(PROJ_GCDA_LIST) : $(EXEC_LIST) + rm -f $(PROJ_DIR)/*.gcda + mkdir -p $(BIN_DIR) + # run each test case + $(foreach bin,$^,$(call run-test,$(bin))) + +# Run and generate lcov +lcov : $(COVINFO) + +lcovhtml : $(COVINFO) + mkdir -p $(COV_REPORT_DIR) + genhtml $(COVINFO) $(LCOV_OPTS) --output-directory $(COV_REPORT_DIR) + +bin: $(EXEC_LIST) + +# Run and append to gcov data files + +# Generate callgraph for coverage filtering +$(PROJ_DIR)/callgraph.json : $(PROJ_SRC_LIST) + mkdir -p $(PROJ_DIR) +#python3 $(UT_ROOT_DIR)/tools/callgraph.py --out $@ $^ + +# Generate baseline inital coverage data from .gcno file +$(COVINFO_INITIAL) : $(EXEC_LIST) + lcov $(LCOV_OPTS) --capture --initial --directory $(SCRATCH_DIR) -o $@ + +# Run the test runner and genrate a filtered gcov.json.gz file +$(SCRATCH_DIR)/%_utest.info : $(BIN_DIR)/$(EXEC_PREFIX)_%_utest \ + $(PROJ_DIR)/callgraph.json + # Remove any existing coverage data + rm -f $(PROJ_DIR)/*.gcda + + # run the testrunner + $< + + lcov $(LCOV_OPTS) --directory $(SCRATCH_DIR) --capture -o $@ + # Gather coverage into a json.gz file + +#gcov $(GCOV_OPTS) $(SCRATCH_DIR)/$*/$(PROJECT).gcda \ +# --json-format --stdout | gzip > $(subst .info,.json.gz,$@) + + # Filter coverage based on tags in unit test file +# $(TOOLS_DIR)/filtercov.py --in $(subst .info,.json.gz,$@) \ +# --map $(PROJ_DIR)/callgraph.json \ +# --test $(PROJ_DIR)/$(PROJECT)_utest_$*.c \ +# --format lcov \ +# --out $@ + lcov $(LCOV_OPTS) --summary $@ + + # Remove temporary files + rm -f $(subst .info,.json.gz,$@) + rm -f $(PROJ_GCDA_LIST) + +# Combine lcov from each test bin into one lcov info file for the suite +$(COVINFO_COMBINE) : $(LCOV_LIST) + lcov $(LCOV_OPTS) -o $@ $(foreach cov,$(LCOV_LIST),--add-tracefile $(cov) ) + +# Add baseline / initial coverage generated by gcc to point out untagged functions +$(COVINFO) : $(COVINFO_COMBINE) $(COVINFO_INITIAL) + lcov $(LCOV_OPTS) -o $@ --add-tracefile $(COVINFO_INITIAL) --add-tracefile $(COVINFO_COMBINE) + diff --git a/FreeRTOS/Test/CMock/doc/Makefile b/FreeRTOS/Test/CMock/doc/Makefile index 5febfd9b1e..59fbf2114a 100644 --- a/FreeRTOS/Test/CMock/doc/Makefile +++ b/FreeRTOS/Test/CMock/doc/Makefile @@ -5,6 +5,8 @@ DOXY_ARGS += "ALIASES+=\"coverage=\\xrefitem coverage \\\"Coverage Target\\\" \\ DOXY_ARGS += "PROJECT_NAME=FreeRTOS Unit Tests\nGENERATE_LATEX=NO\n" DOXY_ARGS += "OUTPUT_DIRECTORY=$(DOC_DIR)" -all: - mkdir -p $(DOC_DIR) +all: | directories echo -e $(DOXY_ARGS) | doxygen - + +directories: + mkdir -p $(DOC_DIR) diff --git a/FreeRTOS/Test/CMock/event_groups/Makefile b/FreeRTOS/Test/CMock/event_groups/Makefile index da0c1886dd..825428e4c0 100644 --- a/FreeRTOS/Test/CMock/event_groups/Makefile +++ b/FreeRTOS/Test/CMock/event_groups/Makefile @@ -33,9 +33,10 @@ MOCK_FILES_FP += $(PROJECT_DIR)/list_macros.h # List any addiitonal flags needed by the preprocessor CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 +CPPFLAGS += -include list_macros.h +CFLAGS += -include list_macros.h # List any addiitonal flags needed by the compiler -CFLAGS += -include list_macros.h CFLAGS += -Wno-incompatible-pointer-types # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/list/Makefile b/FreeRTOS/Test/CMock/list/Makefile index f309ead9c9..7e865624e0 100644 --- a/FreeRTOS/Test/CMock/list/Makefile +++ b/FreeRTOS/Test/CMock/list/Makefile @@ -29,7 +29,7 @@ MOCK_FILES_FP := CPPFLAGS += -DportUSING_MPU_WRAPPERS=0 # List any addiitonal flags needed by the compiler -CFLAGS += +CFLAGS += -Wno-unused-function # Try not to edit beyond this line unless necessary. diff --git a/FreeRTOS/Test/CMock/makefile.in b/FreeRTOS/Test/CMock/makefile.in index 6ac5b8f8d5..d015395567 100644 --- a/FreeRTOS/Test/CMock/makefile.in +++ b/FreeRTOS/Test/CMock/makefile.in @@ -37,17 +37,19 @@ INCLUDE_DIR += -I$(UNITY_MEM_DIR) INCLUDE_DIR += -I$(C_EXCEPTION_SRC_DIR) # Preprocessor flags -CPPFLAGS := +CPPFLAGS := $(INCLUDE_DIR) # Compiler flags -CFLAGS := $(INCLUDE_DIR) -O0 -ggdb -pthread --std=c99 -Werror -Wall +CFLAGS := -pthread --std=c99 -Werror -Wall +CFLAGS += -fstack-protector-all +CFLAGS += -Wformat -Werror=format-security -Werror=array-bounds -Wno-unused-function + ifeq ($(ENABLE_SANITIZER),1) - CFLAGS += -fstack-protector-all - CFLAGS += -Wformat -Werror=format-security -Werror=array-bounds - CFLAGS += -D_FORTIFY_SOURCE=2 - CFLAGS += -fsanitize=address,undefined -fsanitize-recover=address + CFLAGS += -fsanitize=address,undefined -fsanitize-recover=address + CFLAGS += -O3 -ggdb3 + CPPFLAGS += -D_FORTIFY_SOURCE=2 else - CFLAGS += -U_FORTIFY_SOURCE + CFLAGS += -O0 -ggdb3 endif # Linker flags diff --git a/FreeRTOS/Test/CMock/stream_buffer/Makefile b/FreeRTOS/Test/CMock/stream_buffer/Makefile index 9871ccbcf5..5832ba6e78 100644 --- a/FreeRTOS/Test/CMock/stream_buffer/Makefile +++ b/FreeRTOS/Test/CMock/stream_buffer/Makefile @@ -12,4 +12,5 @@ SUITES += callback # $(UT_ROOT_DIR)/$(PROJECT)/$(SUITE) PROJECT := $(lastword $(subst /, ,$(dir $(abspath $(MAKEFILE_ABSPATH))))) -include ../subdir.mk \ No newline at end of file +include ../subdir.mk + diff --git a/FreeRTOS/Test/CMock/subdir.mk b/FreeRTOS/Test/CMock/subdir.mk index 4da2bb8005..d19287cf1c 100644 --- a/FreeRTOS/Test/CMock/subdir.mk +++ b/FreeRTOS/Test/CMock/subdir.mk @@ -12,12 +12,12 @@ COV_REPORT_DIR := $(SCRATCH_DIR)/coverage all: run -clean: +clean : rm -rf $(SCRATCH_DIR) rm -f $(BIN_DIR)/$(PROJECT)*_utest rm -f $(COVINFO) -libs: +libs : make -C $(UT_ROOT_DIR) libs lcov : $(COVINFO) diff --git a/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_1.h b/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_1.h new file mode 100644 index 0000000000..8ec78749ba --- /dev/null +++ b/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_1.h @@ -0,0 +1,139 @@ +/* + * FreeRTOS V202112.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 FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/* XXX: this file will be processed by unifdef to generate new header files + * that can be mocked according to the configurations desired + * it has a few limitations on the format of this file such as: + * no config that spans more than one line + * no strings in config names + * for more info please check the man file with $ man unifdef + */ + +/*----------------------------------------------------------- +* Application specific definitions. +* +* These definitions should be adjusted for your particular hardware and +* application requirements. +* +* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See +* http://www.freertos.org/a00110.html +*----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#define configUSE_TICKLESS_IDLE 1 +#define configUSE_TIME_SLICING 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 1 +#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */ +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */ +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configCHECK_FOR_STACK_OVERFLOW 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 20 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_APPLICATION_TASK_TAG 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 +#define configUSE_QUEUE_SETS 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 ) /* For test. */ +#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1 /* As there are a lot of tasks running. */ + +/* Software timer related configuration options. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 20 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) + +#define configMAX_PRIORITIES ( 9 ) + +/* Run time stats gathering configuration options. */ +unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */ +void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats() +#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue() +#define portUSING_MPU_WRAPPERS 0 +#define configENABLE_MPU 0 +#define portHAS_STACK_OVERFLOW_CHECKING 0 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 + +/* Co-routine related configuration options. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +#define portSTACK_GROWTH ( -1 ) +#define configRECORD_STACK_HIGH_ADDRESS 1 + +/* This demo makes use of one or more example stats formatting functions. These + * format the raw data provided by the uxTaskGetSystemState() function in to human + * readable ASCII form. See the notes in the implementation of vTaskList() within + * FreeRTOS/Source/tasks.c for limitations. */ +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +/* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. In most cases the linker will remove unused + * functions anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 1 + +/* It is a good idea to define configASSERT() while developing. configASSERT() + * uses the same semantics as the standard C assert() macro. */ +#define configASSERT( x ) +#define portREMOVE_STATIC_QUALIFIER 1 + +#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0 +#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_2.h b/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_2.h new file mode 100644 index 0000000000..c9231719c6 --- /dev/null +++ b/FreeRTOS/Test/CMock/tasks/FreeRTOSConfig_2.h @@ -0,0 +1,134 @@ +/* + * FreeRTOS V202112.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 FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/* XXX: this file will be processed by unifdef to generate new header files + * that can be mocked according to the configurations desired + * it has a few limitations on the format of this file such as: + * no config that spans more than one line + * no strings in config names + * for more info please check the man file with $ man unifdef + */ + +/*----------------------------------------------------------- +* Application specific definitions. +* +* These definitions should be adjusted for your particular hardware and +* application requirements. +* +* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See +* http://www.freertos.org/a00110.html +*----------------------------------------------------------*/ + +#define portSTACK_GROWTH ( 1 ) +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 1 +#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */ +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */ +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 0 /* diff config 1 */ +#define configCHECK_FOR_STACK_OVERFLOW 0 +#define configUSE_RECURSIVE_MUTEXES 0 +#define configQUEUE_REGISTRY_SIZE 20 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_APPLICATION_TASK_TAG 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 +#define configUSE_QUEUE_SETS 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 ) /* For test. */ +#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1 /* As there are a lot of tasks running. */ + +/* Software timer related configuration options. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 20 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) + +#define configMAX_PRIORITIES ( 7 ) + +/* Run time stats gathering configuration options. */ +unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */ +void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats() +#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue() +#define portUSING_MPU_WRAPPERS 0 +#define configENABLE_MPU 0 +#define portHAS_STACK_OVERFLOW_CHECKING 1 +#define portCRITICAL_NESTING_IN_TCB 1 + +/* Co-routine related configuration options. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +/* This demo makes use of one or more example stats formatting functions. These + * format the raw data provided by the uxTaskGetSystemState() function in to human + * readable ASCII form. See the notes in the implementation of vTaskList() within + * FreeRTOS/Source/tasks.c for limitations. */ +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +/* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. In most cases the linker will remove unused + * functions anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 1 + +/* It is a good idea to define configASSERT() while developing. configASSERT() + * uses the same semantics as the standard C assert() macro. */ +#define configASSERT( x ) +#define portREMOVE_STATIC_QUALIFIER 1 +#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 + + +#endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS/Test/CMock/tasks/Makefile b/FreeRTOS/Test/CMock/tasks/Makefile new file mode 100644 index 0000000000..94a9ad834b --- /dev/null +++ b/FreeRTOS/Test/CMock/tasks/Makefile @@ -0,0 +1,181 @@ +# Change according to what your unit test directory is. +# For example if testing queue.c your directory should be called queue +# and the project name should be queue +# if testing list.c your directory should be called list +# and the project name should be list + +include ../makefile.in + +PROJECT := tasks +# +# Test/CMock/tasks +PROJECT_DIR := $(abspath .) +PROJ_DIR := $(abspath .) + +# List the dependency files you wish to mock +MOCK_FILES_FP := $(KERNEL_DIR)/include/timers.h +MOCK_FILES_FP += $(KERNEL_DIR)/include/list.h +MOCK_FILES_FP += $(KERNEL_DIR)/include/portable.h +MOCK_FILES_FP += $(PROJECT_DIR)/list_macros.h + +UNDEF_MOCKED_HEADER_MACROS := -UlistLIST_IS_EMPTY -UlistGET_OWNER_OF_HEAD_ENTRY\ + -UlistIS_CONTAINED_WITHIN -UlistGET_LIST_ITEM_VALUE \ + -UlistSET_LIST_ITEM_VALUE \ + -UlistLIST_ITEM_CONTAINER -UlistCURRENT_LIST_LENGTH + +# List special compilation flags for this module +CFLAGS += -Wno-unused-function + +# List special preprocessing flags for this module +CPPFLAGS += + +# List special linking flags for this module +LDFLAGS += + +# Makefile Debug Flags (if needed) +#MAKEFLAGS += -rR + +# Try not to edit beyond this line + +COVERAGE_OPTS := -fprofile-arcs -ftest-coverage -fprofile-generate + +# build/generated/queue +SCRATCH_DIR := $(GENERATED_DIR)/$(PROJECT) + +# list.h timers.h portable.h +MOCK_FILES := $(notdir $(MOCK_FILES_FP)) + +# ...tasks/%/mocks/mock_list.o tasks/%/mocks/mock_timers.o +MOCK_OBJS := $(addprefix $(SCRATCH_DIR)/%/mocks/mock_,$(MOCK_FILES:.h=.o)) + +# ...tasks/%/mocks/mock_list.c tasks/%/mocks/mock_timers.c +MOCK_SRC_LIST := $(addprefix $(SCRATCH_DIR)/%/mocks/,$(addprefix mock_,$(MOCK_FILES:.h=.c))) + +# tasks/%/cpp/timers.h tasks/%/cpp/list.h +CPP_FILES := $(addprefix $(SCRATCH_DIR)/%/cpp/,$(notdir $(MOCK_FILES_FP))) +DEP_FILES := $(addsuffix .d,$(addprefix $(SCRATCH_DIR)/%/cpp/,$(notdir $(MOCK_FILES_FP)))) + +# tasks_1_utest.c tasks_2_utest.c ... +PROJ_SRC_LIST := $(sort $(wildcard $(PROJECT)_*_utest.c)) + +# 1_utest.c dynamic_utest.c +SUITE_UT_SRC := $(subst $(PROJECT)_,,$(PROJ_SRC_LIST)) + +# 1 2 3 config1 assert ... +DISCRIMINATOR := $(subst _utest,,$(subst .c,,$(subst $(PROJECT)_,,$(PROJ_SRC_LIST)))) + +# tasks/1/mocks tasks/2/mocks +MOCK_DIRS := $(addsuffix /mocks,$(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR))) +# queue/1/cpp queue/2/cpp +CPP_DIRS := $(addsuffix /cpp,$(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR))) +# tasks/1/include tasks/2/include +INCLUDE_DIRS := $(addsuffix /include,$(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR))) +#list/1 list/2 .... +CONFIG_DIRS := $(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR)) + +ifeq ($(MOCK_FILES_FP),) + $(shell mkdir -p $(MOCK_DIRS)) + $(shell for n in $(MOCK_DIRS) ; do touch -a $(n)/mock_dummy.c) +endif + +EXEC_LIST := $(addprefix $(BIN_DIR)/,$(patsubst %.c,%,$(PROJ_SRC_LIST))) +EXEC_PATH := $(addsuffix _%_utest,$(addprefix $(BIN_DIR)/,$(PROJECT))) +PROJ_OBJ_LIST := $(EXEC_LIST) + +.PHONY: all Makefile directories + +.SECONDARY: +all : directories $(EXEC_LIST) + +# Build the executables 1 per configuration +$(EXEC_PATH) : $(MOCK_OBJS) \ + $(SCRATCH_DIR)/%/test_runner.o \ + $(SCRATCH_DIR)/%/$(PROJECT).o \ + $(SCRATCH_DIR)/%/$(PROJECT)_utest.o \ + | libs directories + $(CC) $+ $(LDFLAGS) -o $@ + +# Mock All preprocessed header files +$(MOCK_SRC_LIST) : $(CPP_FILES) \ + Makefile \ + $(PROJECT_DIR)/$(PROJECT).yml \ + | directories + cd $(@D) && cd .. && \ + ruby $(CMOCK_EXEC_DIR)/cmock.rb -o$(PROJECT_DIR)/$(PROJECT).yml \ + $( $(SCRATCH_DIR)/$*/cpp/$$(basename $$h_file) ; \ + done + +# Build ALL the mock objects for the config +# This target is called ONLY once per configuration pattern (%) +$(MOCK_OBJS) : $(MOCK_SRC_LIST) + $(eval INCLUDE = -I$(SCRATCH_DIR)/$*/include) + $(eval INCLUDE += -I$(SCRATCH_DIR)/$*/mocks) \ + $(eval INCLUDE += -I$(KERNEL_DIR)/include) \ + for files in $^ ; do \ + new_name=$${files%.c}.o; \ + $(CC) -c $$files $(INCLUDE) $(CPPFLAGS) $(CFLAGS) -fPIC \ + -DUNITY_EXCLUDE_MATH_H -DUNITY_EXCLUDE_STDINT_H \ + -DUNITY_OUTPUT_CHAR -o $$new_name ; \ + done + +# Build test_runner.o from test_runner.c +$(SCRATCH_DIR)/%/test_runner.o : $(SCRATCH_DIR)/%/test_runner.c \ + $(SCRATCH_DIR)/%/$(PROJECT).o + $(eval INCLUDE = -I$(SCRATCH_DIR)/$*/include) + $(eval INCLUDE += -I$(SCRATCH_DIR)/$*/mocks) + $(eval INCLUDE += -I$(KERNEL_DIR)/include) + $(CC) -c $< $(INCLUDE) $(CPPFLAGS) $(CFLAGS) -o $@ + +# Build tasks_utest.o from tasks_utest_%.c +$(SCRATCH_DIR)/%/$(PROJECT)_utest.o : $(PROJECT_DIR)/$(PROJECT)_%_utest.c \ + global_vars.h \ + | directories + $(eval INCLUDE = -I$(SCRATCH_DIR)/$*/include) + $(eval INCLUDE += -I$(SCRATCH_DIR)/$*/mocks) + $(eval INCLUDE += -I$(KERNEL_DIR)/include) + $(CC) -c $< $(INCLUDE) $(CPPFLAGS) $(CFLAGS) -o $@ + +# Build tasks.o from tasks.i with the custom FreeRTOSConfig.h and place it in +# its configuration directory +$(SCRATCH_DIR)/%/$(PROJECT).o : $(SCRATCH_DIR)/%/$(PROJECT).i | directories + $(CC) -c $< $(CFLAGS) $(COVERAGE_OPTS) -o $@ + +# Build tasks.i from tasks.c with the custom FreeRTOSConfig.h and place it in +# its configuration directory +$(SCRATCH_DIR)/%/$(PROJECT).i : $(KERNEL_DIR)/$(PROJECT).c | directories + $(eval INCLUDE = -I$(SCRATCH_DIR)/$*/include) + $(eval INCLUDE += -I$(SCRATCH_DIR)/$*/mocks) \ + $(eval INCLUDE += -I$(KERNEL_DIR)/include) \ + $(CC) -E $< $(INCLUDE) $(CPPFLAGS) -include list_macros.h -o $@ + +# Generate test_runner.c which contains the main function from the test file +$(SCRATCH_DIR)/%/test_runner.c : $(PROJECT_DIR)/$(PROJECT)_%_utest.c \ + Makefile | directories + ruby $(UNITY_BIN_DIR)/generate_test_runner.rb "--use_param_tests=1" \ + $(PROJECT)_$*_utest.c $(PROJECT_DIR)/$(PROJECT).yml $@ + +# Create needed directories +directories : + -mkdir -p $(SCRATCH_DIR) + -mkdir -p $(CONFIG_DIRS) + -mkdir -p $(MOCK_DIRS) + -mkdir -p $(CPP_DIRS) + -mkdir -p $(INCLUDE_DIRS) + -mkdir -p $(BIN_DIR) + -mkdir -p $(LIB_DIR) + +EXEC_PREFIX := $(PROJECT) + +include ../coverage.mk diff --git a/FreeRTOS/Test/CMock/tasks/global_vars.h b/FreeRTOS/Test/CMock/tasks/global_vars.h new file mode 100644 index 0000000000..cb5a271952 --- /dev/null +++ b/FreeRTOS/Test/CMock/tasks/global_vars.h @@ -0,0 +1,336 @@ +/* + * FreeRTOS V202112.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 GBLOBAL_VARS_H +#define GBLOBAL_VARS_H + +#include "task.h" + +#include + +typedef struct tskTaskControlBlock /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + volatile StackType_t * pxTopOfStack; /*< Points to the location of the last item placed on the tasks stack. THIS MUST BE THE FIRST MEMBER OF THE TCB STRUCT. */ + + #if ( portUSING_MPU_WRAPPERS == 1 ) + xMPU_SETTINGS xMPUSettings; /*< The MPU settings are defined as part of the port layer. THIS MUST BE THE SECOND MEMBER OF THE TCB STRUCT. */ + #endif + + ListItem_t xStateListItem; /*< The list that the state list item of a task is reference from denotes the state of that task (Ready, Blocked, Suspended ). */ + ListItem_t xEventListItem; /*< Used to reference a task from an event list. */ + UBaseType_t uxPriority; /*< The priority of the task. 0 is the lowest priority. */ + StackType_t * pxStack; /*< Points to the start of the stack. */ + char pcTaskName[ configMAX_TASK_NAME_LEN ]; /*< Descriptive name given to the task when created. Facilitates debugging only. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + + #if ( ( portSTACK_GROWTH > 0 ) || ( configRECORD_STACK_HIGH_ADDRESS == 1 ) ) + StackType_t * pxEndOfStack; /*< Points to the highest valid address for the stack. */ + #endif + + #if ( portCRITICAL_NESTING_IN_TCB == 1 ) + UBaseType_t uxCriticalNesting; /*< Holds the critical section nesting depth for ports that do not maintain their own count in the port layer. */ + #endif + + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTCBNumber; /*< Stores a number that increments each time a TCB is created. It allows debuggers to determine when a task has been deleted and then recreated. */ + UBaseType_t uxTaskNumber; /*< Stores a number specifically for use by third party trace code. */ + #endif + + #if ( configUSE_MUTEXES == 1 ) + UBaseType_t uxBasePriority; /*< The priority last assigned to the task - used by the priority inheritance mechanism. */ + UBaseType_t uxMutexesHeld; + #endif + + #if ( configUSE_APPLICATION_TASK_TAG == 1 ) + TaskHookFunction_t pxTaskTag; + #endif + + #if ( configNUM_THREAD_LOCAL_STORAGE_POINTERS > 0 ) + void * pvThreadLocalStoragePointers[ configNUM_THREAD_LOCAL_STORAGE_POINTERS ]; + #endif + + #if ( configGENERATE_RUN_TIME_STATS == 1 ) + uint32_t ulRunTimeCounter; /*< Stores the amount of time the task has spent in the Running state. */ + #endif + + #if ( configUSE_NEWLIB_REENTRANT == 1 ) + + /* Allocate a Newlib reent structure that is specific to this task. + * Note Newlib support has been included by popular demand, but is not + * used by the FreeRTOS maintainers themselves. FreeRTOS is not + * responsible for resulting newlib operation. User must be familiar with + * newlib and must provide system-wide implementations of the necessary + * stubs. Be warned that (at the time of writing) the current newlib design + * implements a system-wide malloc() that must be provided with locks. + * + * See the third party link http://www.nadler.com/embedded/newlibAndFreeRTOS.html + * for additional information. */ + struct _reent xNewLib_reent; + #endif + + #if ( configUSE_TASK_NOTIFICATIONS == 1 ) + volatile uint32_t ulNotifiedValue[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; + volatile uint8_t ucNotifyState[ configTASK_NOTIFICATION_ARRAY_ENTRIES ]; + #endif + + /* See the comments in FreeRTOS.h with the definition of + * tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE. */ + #if ( tskSTATIC_AND_DYNAMIC_ALLOCATION_POSSIBLE != 0 ) /*lint !e731 !e9029 Macro has been consolidated for readability reasons. */ + uint8_t ucStaticallyAllocated; /*< Set to pdTRUE if the task is a statically allocated to ensure no attempt is made to free the memory. */ + #endif + + #if ( INCLUDE_xTaskAbortDelay == 1 ) + uint8_t ucDelayAborted; + #endif + + #if ( configUSE_POSIX_ERRNO == 1 ) + int iTaskErrno; + #endif +} tskTCB; + + +/* =========================== DEFINES CONSTANTS ========================== */ +typedef tskTCB TCB_t; +typedef void (* port_yield_operation)( void ); + +/* =========================== GLOBAL VARIABLES =========================== */ + + +/* ============================ MACRO FUNCTIONS ============================ */ +#define ASSERT_IF_IN_ISR_CALLED() \ + do { \ + TEST_ASSERT_TRUE( port_assert_if_in_isr_called ); \ + port_assert_if_in_isr_called = false; \ + } while( 0 ) +#define ASSERT_IF_IN_ISR_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( port_assert_if_in_isr_called ); \ + } while( 0 ) + +#define ASSERT_SETUP_TCB_CALLED() \ + do { \ + TEST_ASSERT_TRUE( port_setup_tcb_called ); \ + port_setup_tcb_called = false; \ + } while( 0 ) +#define ASSERT_SETUP_TCB_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( port_setup_tcb_called ); \ + } while( 0 ) + +#define ASSERT_PORT_YIELD_CALLED() \ + do { \ + TEST_ASSERT_TRUE( port_yield_called ); \ + port_yield_called = false; \ + } while( 0 ) + +#define ASSERT_PORT_YIELD_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( port_yield_called ); \ + } while( 0 ) + +#define ASSERT_PORT_ENABLE_INTERRUPT_CALLED() \ + do { \ + TEST_ASSERT_TRUE( port_enable_interrupts_called ); \ + port_enable_interrupts_called = false; \ + } while( 0 ) + +#define ASSERT_PORT_ENABLE_INTERRUPT_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( port_enable_interrupts_called ); \ + } while( 0 ) + +#define ASSERT_PORT_DISABLE_INTERRUPT_CALLED() \ + do { \ + TEST_ASSERT_TRUE( port_disable_interrupts_called ); \ + port_disable_interrupts_called = false; \ + } while( 0 ) + +#define ASSERT_PORT_DISABLE_INTERRUPT_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( port_disable_interrupts_called ); \ + } while( 0 ) + +#define ASSERT_PORT_YIELD_WITHIN_API_CALLED() \ + do { \ + TEST_ASSERT_TRUE( port_yield_within_api_called ); \ + port_yield_within_api_called = false; \ + } while( 0 ) + +#define ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( port_yield_within_api_called ); \ + } while( 0 ) + +#define ASSERT_TASK_DELETE_CALLED() \ + do { \ + TEST_ASSERT_TRUE( vTaskDeletePre_called ); \ + vTaskDeletePre_called = false; \ + } while( 0 ) + +#define ASSERT_TASK_DELETE_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( vTaskDeletePre_called ); \ + } while( 0 ) + +#define ASSERT_APP_TICK_HOOK_CALLED() \ + do { \ + TEST_ASSERT_TRUE( vApplicationTickHook_called ); \ + vApplicationTickHook_called = false; \ + } while( 0 ) + +#define ASSERT_APP_TICK_HOOK_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( vApplicationTickHook_called ); \ + } while( 0 ) + +#define ASSERT_PORT_CLEAR_INTERRUPT_CALLED() \ + do { \ + TEST_ASSERT_TRUE( portClear_Interrupt_called ); \ + portClear_Interrupt_called = false; \ + } while( 0 ) +#define ASSERT_PORT_CLEAR_INTERRUPT_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( portClear_Interrupt_called ); \ + } while( 0 ) + +#define ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED() \ + do { \ + TEST_ASSERT_TRUE( portClear_Interrupt_from_isr_called ); \ + portClear_Interrupt_from_isr_called = false; \ + } while( 0 ) +#define ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( portClear_Interrupt_from_isr_called ); \ + } while( 0 ) + +#define ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED() \ + do { \ + TEST_ASSERT_TRUE( portSet_Interrupt_from_isr_called ); \ + portSet_Interrupt_from_isr_called = false; \ + } while( 0 ) +#define ASSERT_PORT_SET_INTERRUPT_FROM_ISR_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( portSet_Interrupt_from_isr_called ); \ + } while( 0 ) + +#define ASSERT_PORT_SET_INTERRUPT_CALLED() \ + do { \ + TEST_ASSERT_TRUE( portSet_Interrupt_called ); \ + portSet_Interrupt_called = false; \ + } while( 0 ) +#define ASSERT_PORT_SET_INTERRUPT_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( portSet_Interrupt_called ); \ + } while( 0 ) + +#define ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED() \ + do { \ + TEST_ASSERT_TRUE( port_invalid_interrupt_called ); \ + port_invalid_interrupt_called = false; \ + } while( 0 ) + +#define ASSERT_APPLICATION_IDLE_HOOK_CALLED() \ + do { \ + TEST_ASSERT_TRUE( vApplicationIdleHook_called ); \ + vApplicationIdleHook_called = false; \ + } while( 0 ) + +#define ASSERT_APPLICATION_IDLE_HOOK_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( vApplicationIdleHook_called ); \ + } while( 0 ) + +#define ASSERT_APPLICATION_MALLOC_FAILED_HOOK_CALLED() \ + do { \ + TEST_ASSERT_TRUE( vApplicationMallocFailedHook_called ); \ + vApplicationMallocFailedHook_called = false; \ + } while( 0 ) + +#define ASSERT_APPLICATION_MALLOC_FAILED_HOOK_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( vApplicationMallocFailedHook_called ); \ + } while( 0 ) + +#define ASSERT_PORT_ALLOCATE_SECURE_CONTEXT_CALLED() \ + do { \ + TEST_ASSERT_TRUE( port_allocate_secure_context_called ); \ + port_allocate_secure_context_called = false; \ + } while( 0 ) + +#define ASSERT_PORT_ALLOCATE_SECURE_CONTEXT_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( port_allocate_secure_context_called ); \ + } while( 0 ) + +#define ASSERT_APP_STACK_OVERFLOW_HOOK_CALLED() \ + do { \ + TEST_ASSERT_TRUE( vApplicationStackOverflowHook_called ); \ + vApplicationStackOverflowHook_called = false; \ + } while( 0 ) + +#define ASSERT_APP_STACK_OVERFLOW_HOOK_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( vApplicationStackOverflowHook_called ); \ + } while( 0 ) + +#define ASSERT_GET_IDLE_TASK_MEMORY_CALLED() \ + do { \ + TEST_ASSERT_TRUE( getIddleTaskMemory_called ); \ + getIddleTaskMemory_called = false; \ + } while( 0 ) + +#define ASSERT_GET_IDLE_TASK_MEMORY_NOT_CALLED() \ + do { \ + TEST_ASSERT_FALSE( getIddleTaskMemory_called ); \ + } while( 0 ) + +#define RESET_ALL_HOOKS() \ + do { \ + vApplicationTickHook_called = false; \ + vTaskDeletePre_called = false; \ + getIddleTaskMemory_called = false; \ + port_yield_called = false; \ + port_enable_interrupts_called = false; \ + port_disable_interrupts_called = false; \ + port_yield_within_api_called = false; \ + port_setup_tcb_called = false; \ + portClear_Interrupt_called = false; \ + portSet_Interrupt_called = false; \ + portClear_Interrupt_from_isr_called = false; \ + portSet_Interrupt_from_isr_called = false; \ + port_invalid_interrupt_called = false; \ + vApplicationStackOverflowHook_called = false; \ + port_allocate_secure_context_called = false; \ + port_assert_if_in_isr_called = false; \ + } while( 0 ) + +#define HOOK_DIAG() \ + do { \ + printf( "%s Called\n", __FUNCTION__ ); \ + } while( 0 ) + +#undef HOOK_DIAG +#define HOOK_DIAG() + +#endif /* ifndef GBLOBAL_VARS_H */ diff --git a/FreeRTOS/Test/CMock/tasks/list_macros.h b/FreeRTOS/Test/CMock/tasks/list_macros.h new file mode 100644 index 0000000000..f8fbc365b5 --- /dev/null +++ b/FreeRTOS/Test/CMock/tasks/list_macros.h @@ -0,0 +1,75 @@ +/* + * FreeRTOS V202112.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( 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 listINSERT_END +void listINSERT_END( List_t * pxList, + ListItem_t * listItem ); + +#undef listREMOVE_ITEM +void listREMOVE_ITEM( ListItem_t * listItem ); + +#endif /* ifndef LIST_MACRO_H */ diff --git a/FreeRTOS/Test/CMock/tasks/tasks.yml b/FreeRTOS/Test/CMock/tasks/tasks.yml new file mode 100644 index 0000000000..7c6d2fbed1 --- /dev/null +++ b/FreeRTOS/Test/CMock/tasks/tasks.yml @@ -0,0 +1,32 @@ +:cmock: + :mock_prefix: mock_ + :when_no_prototypes: :warn + :treat_externs: :include + :treat_inlines: :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. + - "FreeRTOSConfig.h" + - "FreeRTOS.h" + - "task.h" + :weak: __attribute__((weak)) + :verbosity: 3 + :attributes: + - PRIVILEGED_FUNCTION + :strippables: + - PRIVILEGED_FUNCTION + - portDONT_DISCARD diff --git a/FreeRTOS/Test/CMock/tasks/tasks_1_utest.c b/FreeRTOS/Test/CMock/tasks/tasks_1_utest.c new file mode 100644 index 0000000000..e0fdefc5e6 --- /dev/null +++ b/FreeRTOS/Test/CMock/tasks/tasks_1_utest.c @@ -0,0 +1,5107 @@ +/* + * FreeRTOS V202112.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 tasks_utest_1.c */ + +/* Tasks includes */ +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "fake_port.h" +#include "task.h" + +#include "mock_list.h" +#include "mock_list_macros.h" +#include "mock_timers.h" +#include "mock_portable.h" + +/* Test includes. */ +#include "unity.h" +#include "global_vars.h" + +/* C runtime includes. */ +#include +#include +#include + + +/* =========================== EXTERN VARIABLES =========================== */ +extern TCB_t * volatile pxCurrentTCB; +extern List_t pxReadyTasksLists[ configMAX_PRIORITIES ]; +extern List_t xDelayedTaskList1; +extern List_t xDelayedTaskList2; +extern List_t * volatile pxDelayedTaskList; +extern List_t * volatile pxOverflowDelayedTaskList; +extern List_t xPendingReadyList; +/* INCLUDE_vTaskDelete */ +extern List_t xTasksWaitingTermination; +extern volatile UBaseType_t uxDeletedTasksWaitingCleanUp; +extern List_t xSuspendedTaskList; + +extern volatile UBaseType_t uxCurrentNumberOfTasks; +extern volatile TickType_t xTickCount; +extern volatile UBaseType_t uxTopReadyPriority; +extern volatile BaseType_t xSchedulerRunning; +extern volatile TickType_t xPendedTicks; +extern volatile BaseType_t xYieldPending; +extern volatile BaseType_t xNumOfOverflows; +extern UBaseType_t uxTaskNumber; +extern volatile TickType_t xNextTaskUnblockTime; +extern TaskHandle_t xIdleTaskHandle; +extern volatile UBaseType_t uxSchedulerSuspended; + +/* ============================= DEFINES ================================== */ +#define INITIALIZE_LIST_1E( list, list_item, owner ) \ + do { \ + ( list ).xListEnd.pxNext = &( list_item ); \ + ( list ).xListEnd.pxPrevious = &( list_item ); \ + ( list ).pxIndex = ( ListItem_t * ) &( list ).xListEnd; \ + ( list ).uxNumberOfItems = 1; \ + ( list_item ).pxNext = ( list ).pxIndex; \ + ( list_item ).pxPrevious = ( list ).pxIndex; \ + ( list_item ).pvOwner = ( owner ); \ + ( list_item ).pxContainer = &( list ); \ + } while( 0 ) + +#define INITIALIZE_LIST_2E( list, list_item, list_item2, owner, owner2 ) \ + do { \ + ( list ).xListEnd.pxNext = &( list_item ); \ + ( list ).xListEnd.pxPrevious = &( list_item2 ); \ + ( list ).pxIndex = ( ListItem_t * ) &( list ).xListEnd; \ + ( list ).uxNumberOfItems = 2; \ + ( list_item ).pxNext = &( list_item2 ); \ + ( list_item ).pxPrevious = ( list ).pxIndex; \ + ( list_item ).pvOwner = ( owner ); \ + ( list_item ).pxContainer = &( list ); \ + ( list_item2 ).pxNext = ( list ).pxIndex; \ + ( list_item2 ).pxPrevious = &( list_item ); \ + ( list_item2 ).pvOwner = ( owner2 ); \ + ( list_item2 ).pxContainer = &( list ); \ + } while( 0 ) + +#define taskNOT_WAITING_NOTIFICATION ( ( uint8_t ) 0 ) +#define taskWAITING_NOTIFICATION ( ( uint8_t ) 1 ) +#define taskNOTIFICATION_RECEIVED ( ( uint8_t ) 2 ) +#define TCB_ARRAY 10 /* simulate up to 10 tasks: add more if needed */ + +/* =========================== GLOBAL VARIABLES =========================== */ +static StaticTask_t xIdleTaskTCB; +static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + +static TCB_t * ptcb; +static StackType_t stack[ ( ( size_t ) 300 ) * sizeof( StackType_t ) ]; +static TCB_t tcb[ TCB_ARRAY ]; +static bool getIddleTaskMemoryValid = false; +static uint32_t critical_section_counter = 0; +static bool is_first_task = true; +static uint32_t created_tasks = 0; +static uint32_t create_task_priority = 3; +static port_yield_operation py_operation; + +static bool vTaskDeletePre_called = false; +static bool getIddleTaskMemory_called = false; +static bool vApplicationTickHook_called = false; +static bool port_yield_called = false; +static bool port_enable_interrupts_called = false; +static bool port_disable_interrupts_called = false; +static bool port_yield_within_api_called = false; +static bool port_setup_tcb_called = false; +static bool portClear_Interrupt_called = false; +static bool portSet_Interrupt_called = false; +static bool portClear_Interrupt_from_isr_called = false; +static bool portSet_Interrupt_from_isr_called = false; +static bool port_invalid_interrupt_called = false; +static bool vApplicationStackOverflowHook_called = false; +static bool vApplicationIdleHook_called = false; +static bool port_allocate_secure_context_called = false; +static bool port_assert_if_in_isr_called = false; +static bool vApplicationMallocFailedHook_called = false; + + +/* ============================ HOOK FUNCTIONS ============================ */ +static void dummy_operation() +{ +} + +void vFakePortAssertIfISR( void ) +{ + port_assert_if_in_isr_called = true; + HOOK_DIAG(); +} + +void port_allocate_secure_context( BaseType_t stackSize ) +{ + HOOK_DIAG(); + port_allocate_secure_context_called = true; +} + +void vApplicationIdleHook( void ) +{ + HOOK_DIAG(); + vApplicationIdleHook_called = true; +} + +void vApplicationMallocFailedHook( void ) +{ + vApplicationMallocFailedHook_called = true; + HOOK_DIAG(); +} + +void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, + StackType_t ** ppxIdleTaskStackBuffer, + uint32_t * pulIdleTaskStackSize ) +{ + HOOK_DIAG(); + + if( getIddleTaskMemoryValid == true ) + { + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + * state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + * Note that, as the array is necessarily of type StackType_t, + * configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; + } + else + { + *ppxIdleTaskTCBBuffer = NULL; + *ppxIdleTaskStackBuffer = NULL; + *pulIdleTaskStackSize = 0; + } + + getIddleTaskMemory_called = true; +} + +void vConfigureTimerForRunTimeStats( void ) +{ + HOOK_DIAG(); +} + +long unsigned int ulGetRunTimeCounterValue( void ) +{ + HOOK_DIAG(); + return 3; +} + +void vApplicationTickHook() +{ + HOOK_DIAG(); + vApplicationTickHook_called = true; +} + +void vPortCurrentTaskDying( void * pvTaskToDelete, + volatile BaseType_t * pxPendYield ) +{ + HOOK_DIAG(); + vTaskDeletePre_called = true; +} + +void vFakePortEnterCriticalSection( void ) +{ + HOOK_DIAG(); + critical_section_counter++; +} + +void vFakePortExitCriticalSection( void ) +{ + HOOK_DIAG(); + critical_section_counter--; +} + +void vFakePortYieldWithinAPI() +{ + HOOK_DIAG(); + port_yield_within_api_called = true; + py_operation(); +} + +void vFakePortYieldFromISR() +{ + HOOK_DIAG(); +} + +void vFakePortDisableInterrupts() +{ + port_disable_interrupts_called = true; + HOOK_DIAG(); +} + +void vFakePortEnableInterrupts() +{ + port_enable_interrupts_called = true; + HOOK_DIAG(); +} + +void vFakePortYield() +{ + HOOK_DIAG(); + port_yield_called = true; + py_operation(); +} + +void portSetupTCB_CB( void * tcb ) +{ + HOOK_DIAG(); + port_setup_tcb_called = true; +} + +void vFakePortClearInterruptMask( UBaseType_t bt ) +{ + HOOK_DIAG(); + portClear_Interrupt_called = true; +} + +UBaseType_t ulFakePortSetInterruptMask( void ) +{ + HOOK_DIAG(); + portSet_Interrupt_called = true; + return 1; +} + +void vFakePortClearInterruptMaskFromISR( UBaseType_t bt ) +{ + HOOK_DIAG(); + portClear_Interrupt_from_isr_called = true; +} + +UBaseType_t ulFakePortSetInterruptMaskFromISR( void ) +{ + HOOK_DIAG(); + portSet_Interrupt_from_isr_called = true; + return 1; +} + +void vFakePortAssertIfInterruptPriorityInvalid( void ) +{ + HOOK_DIAG(); + port_invalid_interrupt_called = true; +} + +void vApplicationStackOverflowHook( TaskHandle_t xTask, + char * stack ) +{ + HOOK_DIAG(); + vApplicationStackOverflowHook_called = true; +} + +/* ============================ Unity Fixtures ============================ */ +/*! called before each testcase */ +void setUp( void ) +{ + RESET_ALL_HOOKS(); + pxCurrentTCB = NULL; + memset( &tcb, 0x00, sizeof( TCB_t ) * TCB_ARRAY ); + ptcb = NULL; + memset( &pxReadyTasksLists, 0x00, configMAX_PRIORITIES * sizeof( List_t ) ); + memset( &xDelayedTaskList1, 0x00, sizeof( List_t ) ); + memset( &xDelayedTaskList2, 0x00, sizeof( List_t ) ); + + /* + * pxDelayedTaskList = NULL; + * pxOverflowDelayedTaskList = NULL; + */ + memset( &xPendingReadyList, 0x00, sizeof( List_t ) ); + + memset( &xTasksWaitingTermination, 0x00, sizeof( List_t ) ); + uxDeletedTasksWaitingCleanUp = 0; + memset( &xSuspendedTaskList, 0x00, sizeof( List_t ) ); + + uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; + xTickCount = ( TickType_t ) 500; /* configINITIAL_TICK_COUNT */ + uxTopReadyPriority = tskIDLE_PRIORITY; + xSchedulerRunning = pdFALSE; + xPendedTicks = ( TickType_t ) 0U; + xYieldPending = pdFALSE; + xNumOfOverflows = ( BaseType_t ) 0; + uxTaskNumber = ( UBaseType_t ) 0U; + xNextTaskUnblockTime = ( TickType_t ) 0U; + xIdleTaskHandle = NULL; + uxSchedulerSuspended = ( UBaseType_t ) 0; + is_first_task = true; + created_tasks = 0; + + py_operation = dummy_operation; +} + +/*! called after each testcase */ +void tearDown( void ) +{ + TEST_ASSERT_EQUAL( 0, critical_section_counter ); +} + +/*! 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 =========================== */ + +static BaseType_t pxHookFunction( void * arg ) +{ + BaseType_t * i = arg; + + return *i; +} + +static void start_scheduler() +{ + vListInitialiseItem_ExpectAnyArgs(); + vListInitialiseItem_ExpectAnyArgs(); + /* set owner */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* set owner */ + + pxPortInitialiseStack_ExpectAnyArgsAndReturn( uxIdleTaskStack ); + + if( is_first_task ) + { + is_first_task = false; + + for( int i = ( UBaseType_t ) 0U; i < ( UBaseType_t ) configMAX_PRIORITIES; i++ ) + { + vListInitialise_ExpectAnyArgs(); + } + + /* Delayed Task List 1 */ + vListInitialise_ExpectAnyArgs(); + /* Delayed Task List 2 */ + vListInitialise_ExpectAnyArgs(); + /* Pending Ready List */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskDelete */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskSuspend */ + vListInitialise_ExpectAnyArgs(); + } + + listINSERT_END_ExpectAnyArgs(); + + xTimerCreateTimerTask_ExpectAndReturn( pdPASS ); + xPortStartScheduler_ExpectAndReturn( pdTRUE ); + getIddleTaskMemoryValid = true; + vTaskStartScheduler(); + ASSERT_GET_IDLE_TASK_MEMORY_CALLED(); + TEST_ASSERT_TRUE( xSchedulerRunning ); + TEST_ASSERT_EQUAL( configINITIAL_TICK_COUNT, xTickCount ); + TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime ); +} + +static void block_task( TaskHandle_t task_to_block ) +{ + TCB_t * tcb_to_block = task_to_block; + + TEST_ASSERT_EQUAL( pxCurrentTCB, task_to_block ); + uxListRemove_ExpectAndReturn( &tcb_to_block->xStateListItem, 1 ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &tcb_to_block->xEventListItem, + &xSuspendedTaskList ); + uxListRemove_ExpectAndReturn( &tcb_to_block->xEventListItem, pdTRUE ); + vListInsertEnd_Expect( &xSuspendedTaskList, &tcb_to_block->xStateListItem ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xSuspendedTaskList, + uxCurrentNumberOfTasks ); + vTaskSuspend( task_to_block ); +} + +static TaskHandle_t create_task() +{ + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = { __FUNCTION__ }; + const uint32_t usStackDepth = 300; + void * const pvParameters = NULL; + UBaseType_t uxPriority = create_task_priority; + TaskHandle_t taskHandle; + BaseType_t ret; + + pvPortMalloc_ExpectAndReturn( usStackDepth * sizeof( StackType_t ), stack ); + pvPortMalloc_ExpectAndReturn( sizeof( TCB_t ), &tcb[ created_tasks ] ); + + vListInitialiseItem_Expect( &( tcb[ created_tasks ].xStateListItem ) ); + vListInitialiseItem_Expect( &( tcb[ created_tasks ].xEventListItem ) ); + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + + pxPortInitialiseStack_ExpectAnyArgsAndReturn( stack ); + + if( is_first_task ) + { + for( int i = ( UBaseType_t ) 0U; i < ( UBaseType_t ) configMAX_PRIORITIES; i++ ) + { + vListInitialise_ExpectAnyArgs(); + } + + /* Delayed Task List 1 */ + vListInitialise_ExpectAnyArgs(); + /* Delayed Task List 2 */ + vListInitialise_ExpectAnyArgs(); + /* Pending Ready List */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskDelete */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskSuspend */ + vListInitialise_ExpectAnyArgs(); + is_first_task = false; + } + + listINSERT_END_ExpectAnyArgs(); + ret = xTaskCreate( pxTaskCode, + pcName, + usStackDepth, + pvParameters, + uxPriority, + &taskHandle ); + TEST_ASSERT_EQUAL( pdPASS, ret ); + ASSERT_SETUP_TCB_CALLED(); + created_tasks++; + return taskHandle; +} + +/* ============================== Test Cases ============================== */ + +/*! + * @brief + */ +void test_xTaskCreateStatic_null_puxStackBuffer( void ) +{ + StaticTask_t pxTaskBuffer[ 300 ]; + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = { "unit test" }; + const uint32_t ulStackDepth = 0; + void * const pvParameters = NULL; + UBaseType_t uxPriority = 3; + TaskHandle_t ret; + + ret = xTaskCreateStatic( pxTaskCode, + pcName, + ulStackDepth, + pvParameters, + uxPriority, + NULL, + pxTaskBuffer ); + TEST_ASSERT_EQUAL( NULL, ret ); + ASSERT_SETUP_TCB_NOT_CALLED(); +} + + +/*! + * @brief + */ +void test_xTaskCreateStatic_null_pxTaskBuffer( void ) +{ + StackType_t puxStackBuffer[ 300 ]; + + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = { "unit test" }; + const uint32_t ulStackDepth = 0; + void * const pvParameters = NULL; + UBaseType_t uxPriority = 3; + TaskHandle_t ret; + + ret = xTaskCreateStatic( pxTaskCode, + pcName, + ulStackDepth, + pvParameters, + uxPriority, + puxStackBuffer, + NULL ); + TEST_ASSERT_EQUAL( NULL, ret ); + TEST_ASSERT_EQUAL( 0, uxCurrentNumberOfTasks ); + ASSERT_SETUP_TCB_NOT_CALLED(); +} + +/*! + * @brief + */ +#include +void test_xTaskCreateStatic_success( void ) +{ + StackType_t puxStackBuffer[ 300 ]; + StaticTask_t * pxTaskBuffer = malloc( sizeof( TCB_t ) ); + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = { __FUNCTION__ }; + const uint32_t ulStackDepth = 300; + void * const pvParameters = NULL; + UBaseType_t uxPriority = 3; + TaskHandle_t ret; + + memset( puxStackBuffer, 0xa5U, ulStackDepth * sizeof( StackType_t ) ); + + vListInitialiseItem_ExpectAnyArgs(); + vListInitialiseItem_ExpectAnyArgs(); + + /* set owner */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* set owner */ + pxPortInitialiseStack_ExpectAnyArgsAndReturn( puxStackBuffer ); + + for( int i = ( UBaseType_t ) 0U; i < ( UBaseType_t ) configMAX_PRIORITIES; i++ ) + { + vListInitialise_ExpectAnyArgs(); + } + + /* Delayed Task List 1 */ + vListInitialise_ExpectAnyArgs(); + /* Delayed Task List 2 */ + vListInitialise_ExpectAnyArgs(); + /* Pending Ready List */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskDelete */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskSuspend */ + vListInitialise_ExpectAnyArgs(); + + listINSERT_END_ExpectAnyArgs(); + + ret = xTaskCreateStatic( pxTaskCode, + pcName, + ulStackDepth, + pvParameters, + uxPriority, + puxStackBuffer, + pxTaskBuffer ); + ptcb = ( TCB_t * ) pxTaskBuffer; + TEST_ASSERT_EQUAL_PTR( puxStackBuffer, ptcb->pxStack ); + TEST_ASSERT_NOT_EQUAL( NULL, ret ); + TEST_ASSERT_EQUAL( 2, ptcb->ucStaticallyAllocated ); + TEST_ASSERT_EQUAL( 0, + memcmp( ptcb->pxStack, + puxStackBuffer, + ulStackDepth * sizeof( StackType_t ) ) ); + + StackType_t * pxTopOfStack = &( ptcb->pxStack[ ulStackDepth - ( uint32_t ) 1 ] ); + pxTopOfStack = ( StackType_t * ) ( ( ( portPOINTER_SIZE_TYPE ) pxTopOfStack ) + & ( ~( ( portPOINTER_SIZE_TYPE ) portBYTE_ALIGNMENT_MASK ) ) ); + + TEST_ASSERT_EQUAL( ptcb->pxEndOfStack, + pxTopOfStack ); + TEST_ASSERT_EQUAL( 0, memcmp( ptcb->pcTaskName, pcName, configMAX_TASK_NAME_LEN - 1 ) ); + + TEST_ASSERT_EQUAL( ptcb->uxPriority, uxPriority ); + + TEST_ASSERT_EQUAL( ptcb->uxBasePriority, uxPriority ); + TEST_ASSERT_EQUAL( 0, ptcb->uxMutexesHeld ); + + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + ASSERT_SETUP_TCB_CALLED(); + free( pxTaskBuffer ); +} + + +void test_xTaskCreate_success( void ) +{ + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = NULL; + const uint32_t usStackDepth = 300; + void * const pvParameters = NULL; + UBaseType_t uxPriority = configMAX_PRIORITIES; + TaskHandle_t taskHandle; + BaseType_t ret; + StackType_t stack[ ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ]; + + pvPortMalloc_ExpectAndReturn( usStackDepth * sizeof( StackType_t ), stack ); + pvPortMalloc_ExpectAndReturn( sizeof( TCB_t ), &tcb[ 0 ] ); + + vListInitialiseItem_Expect( &( tcb[ 0 ].xStateListItem ) ); + vListInitialiseItem_Expect( &( tcb[ 0 ].xEventListItem ) ); + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + pxPortInitialiseStack_ExpectAnyArgsAndReturn( stack ); + + for( int i = ( UBaseType_t ) 0U; i < ( UBaseType_t ) configMAX_PRIORITIES; i++ ) + { + vListInitialise_ExpectAnyArgs(); + } + + /* Delayed Task List 1 */ + vListInitialise_ExpectAnyArgs(); + /* Delayed Task List 2 */ + vListInitialise_ExpectAnyArgs(); + /* Pending Ready List */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskDelete */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskSuspend */ + vListInitialise_ExpectAnyArgs(); + + listINSERT_END_ExpectAnyArgs(); + + ret = xTaskCreate( pxTaskCode, + pcName, + usStackDepth, + pvParameters, + uxPriority, + &taskHandle ); + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL( pdPASS, ret ); + TEST_ASSERT_EQUAL( 0, tcb[ 0 ].ucStaticallyAllocated ); + TEST_ASSERT_EQUAL_PTR( &tcb[ 0 ], ptcb ); + TEST_ASSERT_EQUAL( stack, tcb[ 0 ].pxStack ); + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( configMAX_PRIORITIES - 1, ptcb->uxPriority ); + TEST_ASSERT_EQUAL( NULL, ptcb->pcTaskName[ 0 ] ); + ASSERT_SETUP_TCB_CALLED(); +} + +void test_xTaskCreate_success_sched_running( void ) +{ + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = NULL; + const uint32_t usStackDepth = 300; + void * const pvParameters = NULL; + UBaseType_t uxPriority = configMAX_PRIORITIES; + TaskHandle_t taskHandle; + BaseType_t ret; + StackType_t stack[ ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ]; + + start_scheduler(); + + pvPortMalloc_ExpectAndReturn( usStackDepth * sizeof( StackType_t ), stack ); + pvPortMalloc_ExpectAndReturn( sizeof( TCB_t ), &tcb[ 0 ] ); + + vListInitialiseItem_Expect( &( tcb[ 0 ].xStateListItem ) ); + vListInitialiseItem_Expect( &( tcb[ 0 ].xEventListItem ) ); + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + pxPortInitialiseStack_ExpectAnyArgsAndReturn( stack ); + listINSERT_END_ExpectAnyArgs(); + + ret = xTaskCreate( pxTaskCode, + pcName, + usStackDepth, + pvParameters, + uxPriority, + &taskHandle ); + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL( pdPASS, ret ); + TEST_ASSERT_EQUAL( 0, tcb[ 0 ].ucStaticallyAllocated ); + TEST_ASSERT_EQUAL_PTR( &tcb[ 0 ], ptcb ); + TEST_ASSERT_EQUAL( stack, tcb[ 0 ].pxStack ); + TEST_ASSERT_EQUAL( 2, uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( configMAX_PRIORITIES - 1, ptcb->uxPriority ); + TEST_ASSERT_EQUAL( NULL, ptcb->pcTaskName[ 0 ] ); + ASSERT_SETUP_TCB_CALLED(); + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +void test_xTaskCreate_success_null_task_handle( void ) +{ + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = NULL; + const uint32_t usStackDepth = 300; + void * const pvParameters = NULL; + UBaseType_t uxPriority = configMAX_PRIORITIES; + BaseType_t ret; + StackType_t stack[ ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ]; + + pvPortMalloc_ExpectAndReturn( usStackDepth * sizeof( StackType_t ), stack ); + pvPortMalloc_ExpectAndReturn( sizeof( TCB_t ), &tcb[ 0 ] ); + + vListInitialiseItem_Expect( &( tcb[ 0 ].xStateListItem ) ); + vListInitialiseItem_Expect( &( tcb[ 0 ].xEventListItem ) ); + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + pxPortInitialiseStack_ExpectAnyArgsAndReturn( stack ); + + for( int i = ( UBaseType_t ) 0U; i < ( UBaseType_t ) configMAX_PRIORITIES; i++ ) + { + vListInitialise_ExpectAnyArgs(); + } + + /* Delayed Task List 1 */ + vListInitialise_ExpectAnyArgs(); + /* Delayed Task List 2 */ + vListInitialise_ExpectAnyArgs(); + /* Pending Ready List */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskDelete */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskSuspend */ + vListInitialise_ExpectAnyArgs(); + + listINSERT_END_ExpectAnyArgs(); + + ret = xTaskCreate( pxTaskCode, + pcName, + usStackDepth, + pvParameters, + uxPriority, + NULL ); + TEST_ASSERT_EQUAL( pdPASS, ret ); + TEST_ASSERT_EQUAL( 0, tcb[ 0 ].ucStaticallyAllocated ); + TEST_ASSERT_EQUAL( stack, tcb[ 0 ].pxStack ); + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + ASSERT_SETUP_TCB_CALLED(); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + + +void test_xTaskCreate_fail_stack_malloc( void ) +{ + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = { __FUNCTION__ }; + const uint32_t usStackDepth = 300; + void * const pvParameters = NULL; + UBaseType_t uxPriority = 3; + TaskHandle_t taskHandle; + BaseType_t ret; + + pvPortMalloc_ExpectAndReturn( usStackDepth * sizeof( StackType_t ), NULL ); + + ret = xTaskCreate( pxTaskCode, + pcName, + usStackDepth, + pvParameters, + uxPriority, + &taskHandle ); + TEST_ASSERT_EQUAL( errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY, ret ); + TEST_ASSERT_EQUAL( 0, uxCurrentNumberOfTasks ); + ASSERT_SETUP_TCB_NOT_CALLED(); +} + +void test_xTaskCreate_fail_tcb_malloc( void ) +{ + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = { __FUNCTION__ }; + const uint32_t usStackDepth = 300; + void * const pvParameters = NULL; + UBaseType_t uxPriority = 3; + TaskHandle_t taskHandle; + BaseType_t ret; + StackType_t stack[ ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ]; + + pvPortMalloc_ExpectAndReturn( usStackDepth * sizeof( StackType_t ), stack ); + pvPortMalloc_ExpectAndReturn( sizeof( TCB_t ), NULL ); + vPortFree_Expect( stack ); + + ret = xTaskCreate( pxTaskCode, + pcName, + usStackDepth, + pvParameters, + uxPriority, + &taskHandle ); + TEST_ASSERT_EQUAL( errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY, ret ); + TEST_ASSERT_EQUAL( 0, uxCurrentNumberOfTasks ); + ASSERT_SETUP_TCB_NOT_CALLED(); +} + +/* -------------------------- INCLUDE_vTaskDelete --------------------------- */ +void test_vTaskDelete_sucess_current_task( void ) +{ + ptcb = ( TCB_t * ) create_task(); + + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + + /* Expectations */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, pdPASS ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, NULL ); + vListInsertEnd_ExpectAnyArgs(); + /* API call */ + vTaskDelete( ptcb ); + /* Validations */ + ASSERT_TASK_DELETE_CALLED(); + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( 1, uxDeletedTasksWaitingCleanUp ); +} + +void test_vTaskDelete_sucess_current_task_ready_empty( void ) +{ + /* Setup */ + ptcb = ( TCB_t * ) create_task(); + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + + /* Expectations */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, pdFAIL ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ], 0 ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, NULL ); + vListInsertEnd_ExpectAnyArgs(); + /* API call */ + vTaskDelete( ptcb ); + /* Validations */ + ASSERT_TASK_DELETE_CALLED(); + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( 1, uxDeletedTasksWaitingCleanUp ); +} + +void test_vTaskDelete_sucess_current_task_ready_empty_null_task( void ) +{ + ptcb = ( TCB_t * ) create_task(); + + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + + /* Expectations */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, pdFAIL ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ], 1 ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, NULL ); + vListInsertEnd_ExpectAnyArgs(); + /* API call */ + vTaskDelete( NULL ); + /* Validations */ + ASSERT_TASK_DELETE_CALLED(); + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( 1, uxDeletedTasksWaitingCleanUp ); +} + +void test_vTaskDelete_sucess_current_task_yield( void ) +{ + xSchedulerRunning = pdTRUE; + ptcb = ( TCB_t * ) create_task(); + + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + + /* Expectations */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, pdPASS ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, NULL ); + vListInsertEnd_ExpectAnyArgs(); + /* API call */ + vTaskDelete( ptcb ); + /* Validations */ + ASSERT_TASK_DELETE_CALLED(); + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( 1, uxDeletedTasksWaitingCleanUp ); +} + +void test_vTaskDelete_sucess_not_current_task( void ) +{ + ptcb = ( TCB_t * ) create_task(); + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + + /* Expectations */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, pdPASS ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, + &xPendingReadyList ); + uxListRemove_ExpectAndReturn( &ptcb->xEventListItem, pdTRUE ); + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + vPortFree_ExpectAnyArgs(); + vPortFree_ExpectAnyArgs(); + pxCurrentTCB = NULL; + /* API call */ + vTaskDelete( ptcb ); + /* Validations */ + TEST_ASSERT_EQUAL( 0, uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( 0, uxDeletedTasksWaitingCleanUp ); +} + +void test_vTaskDelete_sucess_not_current_task_no_yield( void ) +{ + xSchedulerRunning = pdTRUE; + ptcb = ( TCB_t * ) create_task(); + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + + /* Expectations */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, pdPASS ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, + &xPendingReadyList ); + uxListRemove_ExpectAndReturn( &ptcb->xEventListItem, pdTRUE ); + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + vPortFree_ExpectAnyArgs(); + vPortFree_ExpectAnyArgs(); + pxCurrentTCB = NULL; + /* API call */ + vTaskDelete( ptcb ); + /* Validations */ + TEST_ASSERT_EQUAL( 0, uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( 0, uxDeletedTasksWaitingCleanUp ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + + +void test_vTaskStartScheduler_success( void ) +{ + vListInitialiseItem_ExpectAnyArgs(); + vListInitialiseItem_ExpectAnyArgs(); + /* set owner */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* set owner */ + + pxPortInitialiseStack_ExpectAnyArgsAndReturn( uxIdleTaskStack ); + + for( int i = ( UBaseType_t ) 0U; i < ( UBaseType_t ) configMAX_PRIORITIES; i++ ) + { + vListInitialise_ExpectAnyArgs(); + } + + /* Delayed Task List 1 */ + vListInitialise_ExpectAnyArgs(); + /* Delayed Task List 2 */ + vListInitialise_ExpectAnyArgs(); + /* Pending Ready List */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskDelete */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskSuspend */ + vListInitialise_ExpectAnyArgs(); + + listINSERT_END_ExpectAnyArgs(); + + xTimerCreateTimerTask_ExpectAndReturn( pdPASS ); + xPortStartScheduler_ExpectAndReturn( pdTRUE ); + getIddleTaskMemoryValid = true; + vTaskStartScheduler(); + + ASSERT_GET_IDLE_TASK_MEMORY_CALLED(); + /* should be 2 the idle task and timer task, but the timer task is a mock */ + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( pdTRUE, xSchedulerRunning ); +} + +void test_vTaskStartScheduler_idle_fail( void ) +{ + getIddleTaskMemoryValid = false; + vTaskStartScheduler(); + + ASSERT_GET_IDLE_TASK_MEMORY_CALLED(); + /* should be 2 the idle task and timer task, but the timer task is a mock */ + TEST_ASSERT_EQUAL( 0, uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( pdFALSE, xSchedulerRunning ); +} + +void test_vTaskEndScheduler_success() +{ + vPortEndScheduler_Expect(); + vTaskEndScheduler(); + TEST_ASSERT_EQUAL( pdFALSE, xSchedulerRunning ); +} + + +void test_vTaskSuspendAll_success( void ) +{ + vTaskSuspendAll(); + TEST_ASSERT_EQUAL( 1, uxSchedulerSuspended ); + vTaskSuspendAll(); + TEST_ASSERT_EQUAL( 2, uxSchedulerSuspended ); + vTaskSuspendAll(); + TEST_ASSERT_EQUAL( 3, uxSchedulerSuspended ); +} + +void test_xTaskResumeAll_success_no_tasks( void ) +{ + BaseType_t ret; + + vTaskSuspendAll(); + ret = xTaskResumeAll(); + TEST_ASSERT_EQUAL( pdFALSE, ret ); +} + +void test_xTaskResumeAll_success_1_task_running( void ) +{ + BaseType_t ret; + + create_task(); + vTaskSuspendAll(); + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + ret = xTaskResumeAll(); + TEST_ASSERT_EQUAL( pdFALSE, ret ); +} + +void test_xTaskResumeAll_success_2_tasks_running( void ) +{ + BaseType_t ret; + TaskHandle_t taskHandle; + + taskHandle = create_task(); + ptcb = ( TCB_t * ) taskHandle; + vListInsertEnd_Ignore(); + create_task(); + vTaskSuspendAll(); + TEST_ASSERT_EQUAL( 2, uxCurrentNumberOfTasks ); + + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( ptcb ); + listREMOVE_ITEM_Expect( &( ptcb->xEventListItem ) ); + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + listINSERT_END_ExpectAnyArgs(); + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + ret = xTaskResumeAll(); + TEST_ASSERT_EQUAL( pdTRUE, ret ); + TEST_ASSERT_EQUAL( 0, uxSchedulerSuspended ); + TEST_ASSERT_TRUE( xYieldPending ); +} + +void test_xTaskResumeAll_success_2_tasks_running_xpendedticks_gt_zero( void ) +{ + BaseType_t ret; + TaskHandle_t taskHandle; + + xPendedTicks = 1; + + taskHandle = create_task(); + ptcb = ( TCB_t * ) taskHandle; + vListInsertEnd_Ignore(); + create_task(); + vTaskSuspendAll(); + TEST_ASSERT_EQUAL( 2, uxCurrentNumberOfTasks ); + + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( ptcb ); + listREMOVE_ITEM_Expect( &( ptcb->xEventListItem ) ); + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + listINSERT_END_ExpectAnyArgs(); + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /* xTaskIncrementTick */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ pxCurrentTCB->uxPriority ], + 0 ); + ret = xTaskResumeAll(); + TEST_ASSERT_EQUAL( pdTRUE, ret ); + TEST_ASSERT_EQUAL( 0, uxSchedulerSuspended ); + TEST_ASSERT_TRUE( xYieldPending ); +} + +void test_xTaskResumeAll_success_2_tasks_running_increment_ticks( void ) +{ + BaseType_t ret; + TaskHandle_t task_handle; + TaskHandle_t task_handle2; + + /* Setup */ + xPendedTicks = 2; + + create_task_priority = 2; + task_handle = create_task(); + + block_task( task_handle ); + + create_task_priority = 3; + task_handle2 = create_task(); + + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_EQUAL_PTR( task_handle2, pxCurrentTCB ); + + start_scheduler(); + vTaskSuspendAll(); + + TEST_ASSERT_EQUAL( 3, uxCurrentNumberOfTasks ); + + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( ptcb ); + listREMOVE_ITEM_Expect( &( ptcb->xEventListItem ) ); + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_ExpectAnyArgs(); + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /* xTaskIncrementTick */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ pxCurrentTCB->uxPriority ], + 0 ); + /* xTaskIncrementTick */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ pxCurrentTCB->uxPriority ], + 0 ); + /* API Call */ + ret = xTaskResumeAll(); + /* Expectations */ + TEST_ASSERT_FALSE( ret ); + TEST_ASSERT_EQUAL( 0, uxSchedulerSuspended ); + TEST_ASSERT_FALSE( xYieldPending ); +} + +void test_xTaskResumeAll_success_2_tasks_running_no_yield( void ) +{ + BaseType_t ret; + TaskHandle_t task_handle; + TaskHandle_t task_handle2; + + create_task_priority = 2; + task_handle = create_task(); + + block_task( task_handle ); + + create_task_priority = 3; + task_handle2 = create_task(); + + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_EQUAL_PTR( task_handle2, pxCurrentTCB ); + + start_scheduler(); + vTaskSuspendAll(); + + TEST_ASSERT_EQUAL( 3, uxCurrentNumberOfTasks ); + + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( ptcb ); + listREMOVE_ITEM_Expect( &( ptcb->xEventListItem ) ); + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_ExpectAnyArgs(); + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + ret = xTaskResumeAll(); + TEST_ASSERT_FALSE( ret ); + TEST_ASSERT_EQUAL( 0, uxSchedulerSuspended ); + TEST_ASSERT_FALSE( xYieldPending ); +} + +/* new priority greater than the current priority */ +void test_vTaskPrioritySet_success_gt_curr_prio( void ) +{ + TaskHandle_t taskHandle; + + create_task_priority = 3; + create_task(); + create_task_priority = 4; + taskHandle = create_task(); + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, taskHandle ); + listGET_LIST_ITEM_VALUE_ExpectAnyArgsAndReturn( 0 ); + listSET_LIST_ITEM_VALUE_Expect( &( ptcb->xEventListItem ), + configMAX_PRIORITIES - 5 ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ 5 ], + &( ptcb->xStateListItem ), + pdTRUE ); + uxListRemove_ExpectAndReturn( &( ptcb->xStateListItem ), 0 ); + /* port Reset ready priority */ + /* add task to ready list */ + listINSERT_END_Expect( &( pxReadyTasksLists[ 5 ] ), + &( ptcb->xStateListItem ) ); + + TEST_ASSERT_EQUAL( 4, ptcb->uxBasePriority ); + TEST_ASSERT_EQUAL( 4, ptcb->uxPriority ); + vTaskPrioritySet( taskHandle, create_task_priority + 1 ); + TEST_ASSERT_EQUAL( 4 + 1, ptcb->uxBasePriority ); + TEST_ASSERT_EQUAL( 4 + 1, ptcb->uxPriority ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_vTaskPrioritySet_success_gt_curr_prio_curr_tcb( void ) +{ + TaskHandle_t taskHandle; + TaskHandle_t taskHandle2; + + create_task_priority = 3; + taskHandle = create_task(); + create_task_priority = 4; + taskHandle2 = create_task(); + ptcb = ( TCB_t * ) taskHandle; + + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, taskHandle2 ); + + listGET_LIST_ITEM_VALUE_ExpectAnyArgsAndReturn( 0 ); + listSET_LIST_ITEM_VALUE_Expect( &( ptcb->xEventListItem ), 2 ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ 5 ], + &( ptcb->xStateListItem ), + pdTRUE ); + uxListRemove_ExpectAndReturn( &( ptcb->xStateListItem ), 0 ); + /* port Reset ready priority */ + /* add task to ready list */ + listINSERT_END_Expect( &( pxReadyTasksLists[ 5 ] ), + &( ptcb->xStateListItem ) ); + + TEST_ASSERT_EQUAL( 3, ptcb->uxBasePriority ); + TEST_ASSERT_EQUAL( 3, ptcb->uxPriority ); + vTaskPrioritySet( taskHandle, create_task_priority + 3 ); + TEST_ASSERT_EQUAL( 4 + 3, ptcb->uxBasePriority ); + TEST_ASSERT_EQUAL( 4 + 3, ptcb->uxPriority ); + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + + +void test_vTaskPrioritySet_success_gt_max_prio( void ) +{ + TaskHandle_t taskHandle; + + create_task_priority = 3; + taskHandle = create_task(); + ptcb = ( TCB_t * ) taskHandle; + + /* expectations */ + listGET_LIST_ITEM_VALUE_ExpectAnyArgsAndReturn( 0x80000000UL ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ 5 ], + &( ptcb->xStateListItem ), + pdTRUE ); + uxListRemove_ExpectAndReturn( &( ptcb->xStateListItem ), 0 ); + listINSERT_END_Expect( &( pxReadyTasksLists[ 5 ] ), + &( ptcb->xStateListItem ) ); + + /* API call */ + vTaskPrioritySet( taskHandle, configMAX_PRIORITIES + 5 ); + + /* validations */ + TEST_ASSERT_EQUAL( configMAX_PRIORITIES - 1, ptcb->uxBasePriority ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_vTaskPrioritySet_success_call_current_null( void ) +{ + TaskHandle_t taskHandle; + + create_task_priority = 3; + taskHandle = create_task(); + ptcb = ( TCB_t * ) taskHandle; + + /* expectations */ + listGET_LIST_ITEM_VALUE_ExpectAnyArgsAndReturn( 0x80000000UL ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ 5 ], + &( ptcb->xStateListItem ), + pdTRUE ); + uxListRemove_ExpectAndReturn( &( ptcb->xStateListItem ), 0 ); + listINSERT_END_Expect( &( pxReadyTasksLists[ 5 ] ), + &( ptcb->xStateListItem ) ); + + /* API call */ + vTaskPrioritySet( NULL, 4 ); + + /* validations */ + TEST_ASSERT_EQUAL( 4, ptcb->uxBasePriority ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} +/* ensures that setting the same priority for a tasks changes nothing */ +void test_vTaskPrioritySet_success_same_prio( void ) +{ + TaskHandle_t taskHandle; + + create_task_priority = 3; + taskHandle = create_task(); + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, ptcb ); + /* expectations */ + + /* API call */ + vTaskPrioritySet( taskHandle, 3 ); + + /* Validations */ + TEST_ASSERT_EQUAL( 3, ptcb->uxBasePriority ); + TEST_ASSERT_EQUAL( 3, ptcb->uxPriority ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + + +/* ensures if the set priority is less thatn the current priority and it is the + * current tcb the task is yielded + */ +void test_vTaskPrioritySet_success_lt_curr_prio_curr_task( void ) +{ + TaskHandle_t taskHandle; + + create_task_priority = 3; + taskHandle = create_task(); + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, ptcb ); + + /* Expectations */ + listGET_LIST_ITEM_VALUE_ExpectAnyArgsAndReturn( 0 ); + listSET_LIST_ITEM_VALUE_Expect( &( ptcb->xEventListItem ), + configMAX_PRIORITIES - 2 ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ 5 ], + &( ptcb->xStateListItem ), + pdTRUE ); + uxListRemove_ExpectAndReturn( &( ptcb->xStateListItem ), 1 ); + listINSERT_END_Expect( &( pxReadyTasksLists[ 5 ] ), + &( ptcb->xStateListItem ) ); + /* API call */ + vTaskPrioritySet( taskHandle, 2 ); + + /* Validations */ + TEST_ASSERT_EQUAL( 2, ptcb->uxBasePriority ); + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +/* ensures if the set priority is less thatn the current priority and it is not + * the current tcb the task is not yielded + */ +void test_vTaskPrioritySet_success_lt_curr_prio_not_curr_task( void ) +{ + TaskHandle_t taskHandle, taskHandle2; + + create_task_priority = 3; + taskHandle = create_task(); + create_task_priority = 4; + taskHandle2 = create_task(); + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, taskHandle2 ); + + /* Expectations */ + listGET_LIST_ITEM_VALUE_ExpectAnyArgsAndReturn( 0 ); + listSET_LIST_ITEM_VALUE_Expect( &( ptcb->xEventListItem ), + configMAX_PRIORITIES - 2 ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ 5 ], + &( ptcb->xStateListItem ), + pdFALSE ); + /* API call */ + vTaskPrioritySet( taskHandle, 2 ); + + /* Validations */ + TEST_ASSERT_EQUAL( 2, ptcb->uxBasePriority ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +/* This test ensures that if the base priority is different greater than that the current + * priority the resulting base will be equal to the new priority while the + * current priority will be equal to the inherited priority + * and port yield hook will be called + * */ +void test_vTaskPrioritySet_success_gt_curr_prio_diff_base( void ) +{ + TaskHandle_t taskHandle, taskHandle2; + + create_task_priority = 3; + taskHandle = create_task(); + create_task_priority = 4; + taskHandle2 = create_task(); + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, taskHandle2 ); + /* task handle will inherit the priorit of taskHandle2 */ + listGET_LIST_ITEM_VALUE_ExpectAnyArgsAndReturn( 0x80000000UL ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ 3 ], + &( taskHandle->xStateListItem ), + pdFALSE ); + xTaskPriorityInherit( taskHandle ); + + TEST_ASSERT_EQUAL( 4, ptcb->uxPriority ); + TEST_ASSERT_EQUAL( 3, ptcb->uxBasePriority ); + /* Expectations */ + listGET_LIST_ITEM_VALUE_ExpectAnyArgsAndReturn( 0 ); + listSET_LIST_ITEM_VALUE_Expect( &( ptcb->xEventListItem ), + configMAX_PRIORITIES - 5 ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ 5 ], + &( ptcb->xStateListItem ), + pdFALSE ); + /* API call */ + vTaskPrioritySet( taskHandle, 5 ); + + /* Validations */ + TEST_ASSERT_EQUAL( 5, ptcb->uxBasePriority ); + TEST_ASSERT_EQUAL( 4, ptcb->uxPriority ); + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +/* This test ensures that if the base priority is different less than that the current + * priority the resulting base will be equal to the new priority while the + * current priority will be equal to the inherited priority + * */ +void test_vTaskPrioritySet_success_lt_curr_prio_diff_base( void ) +{ + TaskHandle_t taskHandle, taskHandle2; + + create_task_priority = 3; + taskHandle = create_task(); + create_task_priority = 6; + taskHandle2 = create_task(); + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, taskHandle2 ); + /* task handle will inherit the priorit of taskHandle2 */ + listGET_LIST_ITEM_VALUE_ExpectAnyArgsAndReturn( 0x80000000UL ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ 3 ], + &( taskHandle->xStateListItem ), + pdFALSE ); + xTaskPriorityInherit( taskHandle ); + + TEST_ASSERT_EQUAL( 6, ptcb->uxPriority ); + TEST_ASSERT_EQUAL( 3, ptcb->uxBasePriority ); + /* Expectations */ + listGET_LIST_ITEM_VALUE_ExpectAnyArgsAndReturn( 0 ); + listSET_LIST_ITEM_VALUE_Expect( &( ptcb->xEventListItem ), + configMAX_PRIORITIES - 5 ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ 5 ], + &( ptcb->xStateListItem ), + pdFALSE ); + /* API call */ + vTaskPrioritySet( taskHandle, 5 ); + + /* Validations */ + TEST_ASSERT_EQUAL( 5, ptcb->uxBasePriority ); + TEST_ASSERT_EQUAL( 6, ptcb->uxPriority ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} +/* testing INCLUDE_uxTaskPriorityGet */ +/* Ensures the correct priority is returned */ +void test_uxTaskPriorityGet_success( void ) +{ + TaskHandle_t taskHandle; + UBaseType_t ret_priority; + + create_task_priority = 3; + taskHandle = create_task(); + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, ptcb ); + /* expectations */ + + /* API call */ + ret_priority = uxTaskPriorityGet( taskHandle ); + + /* Validations */ + TEST_ASSERT_EQUAL( 3, ret_priority ); +} + +void test_uxTaskPriorityGet_success_null_handle( void ) +{ + TaskHandle_t taskHandle; + UBaseType_t ret_priority; + + create_task_priority = 3; + taskHandle = create_task(); + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, ptcb ); + /* expectations */ + + /* API call */ + ret_priority = uxTaskPriorityGet( NULL ); + + /* Validations */ + TEST_ASSERT_EQUAL( 3, ret_priority ); +} + +void test_uxTaskPriorityGetFromISR_success( void ) +{ + TaskHandle_t taskHandle; + UBaseType_t ret_priority; + + create_task_priority = 3; + taskHandle = create_task(); + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, ptcb ); + ret_priority = uxTaskPriorityGetFromISR( taskHandle ); + + TEST_ASSERT_EQUAL( 3, ret_priority ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_uxTaskPriorityGetFromISR_success_null_handle( void ) +{ + TaskHandle_t taskHandle; + UBaseType_t ret_priority; + + create_task_priority = 3; + taskHandle = create_task(); + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, ptcb ); + ret_priority = uxTaskPriorityGetFromISR( NULL ); + + TEST_ASSERT_EQUAL( 3, ret_priority ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +/* ----------------------- testing vTaskDelay API --------------------------- */ +void test_vTaskDelay_success_gt_0_yield_called( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = ( TCB_t * ) task_handle; + TickType_t delay = 34; + /* Expectations */ + /* prvAddCurrentTaskToDelayedList */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 1 ); + listSET_LIST_ITEM_VALUE_Expect( &ptcb->xStateListItem, + xTickCount + delay ); + vListInsert_Expect( pxOverflowDelayedTaskList, &ptcb->xStateListItem ); + + /* xTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /* API call */ + vTaskDelay( delay ); + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +void test_vTaskDelay_success_gt_0_yield_not_called( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = ( TCB_t * ) task_handle; + TickType_t delay = 34; + /* Expectations */ + /* prvAddCurrentTaskToDelayedList */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, pdTRUE ); + listSET_LIST_ITEM_VALUE_Expect( &ptcb->xStateListItem, + xTickCount + delay ); + vListInsert_Expect( pxOverflowDelayedTaskList, &ptcb->xStateListItem ); + + /* xTaskResumeAll */ + + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdFALSE ); + listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &xPendingReadyList, ptcb ); + listREMOVE_ITEM_Expect( &( ptcb->xEventListItem ) ); + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* back to xTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + + /* API Call */ + vTaskDelay( delay ); + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +/* ensures that with a delay of zero no other operation or sleeping is done, the + * task in only yielded */ +void test_vTaskDelay_success_eq_0( void ) +{ + /* API Call */ + vTaskDelay( 0 ); + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +/* --------------------- testing INCLUDE_eTaskGetState ---------------------- */ +void test_eTaskGetState_success_current_tcb( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = ( TCB_t * ) task_handle; + eTaskState ret_task_state; + /* no Expectations */ + + /* API Call */ + ret_task_state = eTaskGetState( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( eRunning, ret_task_state ); +} + +void test_eTaskGetState_success_not_current_tcb_blocked_delayed( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_NOT_EQUAL( pxCurrentTCB, ptcb ); + eTaskState ret_task_state; + /* Expectations */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xStateListItem, + pxDelayedTaskList ); + + /* API Call */ + ret_task_state = eTaskGetState( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( eBlocked, ret_task_state ); +} + +void test_eTaskGetState_success_not_current_tcb_blocked_overflow( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_NOT_EQUAL( pxCurrentTCB, ptcb ); + eTaskState ret_task_state; + /* Expectations */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xStateListItem, + pxOverflowDelayedTaskList ); + + /* API Call */ + ret_task_state = eTaskGetState( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( eBlocked, ret_task_state ); +} + +void test_eTaskGetState_success_not_current_tcb_ready( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_NOT_EQUAL( pxCurrentTCB, ptcb ); + eTaskState ret_task_state; + /* Expectations */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xStateListItem, + &pxReadyTasksLists[ 0 ] ); + + /* API Call */ + ret_task_state = eTaskGetState( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( eReady, ret_task_state ); +} + +void test_eTaskGetState_success_not_current_tcb_suspended( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_NOT_EQUAL( pxCurrentTCB, ptcb ); + eTaskState ret_task_state; + /* Expectations */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xStateListItem, + &xSuspendedTaskList ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, + NULL ); + + /* API Call */ + ret_task_state = eTaskGetState( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( eSuspended, ret_task_state ); +} + +void test_eTaskGetState_success_not_current_tcb_deleted( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_NOT_EQUAL( pxCurrentTCB, ptcb ); + eTaskState ret_task_state; + /* Expectations */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xStateListItem, + &xTasksWaitingTermination ); + + /* API Call */ + ret_task_state = eTaskGetState( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( eDeleted, ret_task_state ); +} + +void test_eTaskGetState_success_not_current_tcb_deleted_not_found( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_NOT_EQUAL( pxCurrentTCB, ptcb ); + eTaskState ret_task_state; + /* Expectations */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xStateListItem, + NULL ); + /* API Call */ + ret_task_state = eTaskGetState( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( eDeleted, ret_task_state ); +} +/*else if( ( pxStateList == &xTasksWaitingTermination ) || ( pxStateList == NULL ) ) */ + +/* alternatively this can be better solved by launching a thread and calling + * notification wait, then block on the port yield function hook waiting for this + * thread to continue, and check the value of taskWAITING_NOTIFICATION */ +void test_eTaskGetState_success_not_current_tcb_wait_notif( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + create_task(); + ptcb = ( TCB_t * ) task_handle; + /* see note above */ + ptcb->ucNotifyState[ 0 ] = 1; /* taskWAITING_NOTIFICATION */ + TEST_ASSERT_NOT_EQUAL( pxCurrentTCB, ptcb ); + eTaskState ret_task_state; + /* Expectations */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xStateListItem, + &xSuspendedTaskList ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, + NULL ); + + /* API Call */ + ret_task_state = eTaskGetState( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( eBlocked, ret_task_state ); +} + +void test_eTaskGetState_success_not_current_tcb_blocked( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_NOT_EQUAL( pxCurrentTCB, ptcb ); + eTaskState ret_task_state; + /* Expectations */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xStateListItem, + &xSuspendedTaskList ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, + &xSuspendedTaskList ); + /* API Call */ + ret_task_state = eTaskGetState( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( eBlocked, ret_task_state ); +} + +/* ------------------------- INCLUDE_xTaskDelayUntil ------------------------ */ +void test_xTaskDelayUntil_success_gt_tickCount( void ) +{ + BaseType_t ret_xtask_delay; + TickType_t previousWakeTime = xTickCount + 3; + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_EQUAL( pxCurrentTCB, ptcb ); + + /* Expectations */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + /* API Call */ + ret_xtask_delay = xTaskDelayUntil( &previousWakeTime, 4 ); + /* Validations */ + TEST_ASSERT_EQUAL( pdFALSE, ret_xtask_delay ); +} + + +void test_xTaskDelayUntil_success_gt_tickCount_should_delay( void ) +{ + BaseType_t ret_xtask_delay; + + xTickCount = 1; + TickType_t previousWakeTime = xTickCount + 3; + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_EQUAL( pxCurrentTCB, ptcb ); + uxListRemove_ExpectAndReturn( &pxCurrentTCB->xStateListItem, 0 ); + listSET_LIST_ITEM_VALUE_Expect( &pxCurrentTCB->xStateListItem, 3 ); + vListInsert_Expect( pxOverflowDelayedTaskList, &ptcb->xStateListItem ); + /* xTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + + ret_xtask_delay = xTaskDelayUntil( &previousWakeTime, UINT32_MAX ); + TEST_ASSERT_EQUAL( pdTRUE, ret_xtask_delay ); +} + +void test_xTaskDelayUntil_success_prev_gt_tickCount2( void ) +{ + BaseType_t ret_xtask_delay; + TickType_t previousWakeTime = xTickCount + 5; /* 500 + 5 = 505 */ + TaskHandle_t task_handle; + TickType_t xTimeIncrement = UINT32_MAX - 5; + + /* Setup */ + task_handle = create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_EQUAL( pxCurrentTCB, ptcb ); + /* Expectations */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + /* API Call */ + ret_xtask_delay = xTaskDelayUntil( &previousWakeTime, xTimeIncrement ); + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); + TEST_ASSERT_FALSE( ret_xtask_delay ); +} +/* 0 */ + + +void test_xTaskDelayUntil_success_lt_tickCount( void ) +{ + BaseType_t ret_xtask_delay; + TickType_t previousWakeTime = xTickCount - 3; + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_EQUAL( pxCurrentTCB, ptcb ); + /* Expectations */ + /* prvResetNextTaskUnblockTime */ + uxListRemove_ExpectAndReturn( &pxCurrentTCB->xStateListItem, 0 ); + listSET_LIST_ITEM_VALUE_Expect( &pxCurrentTCB->xStateListItem, 500 + ( ( previousWakeTime + 5 ) - xTickCount ) ); + vListInsert_Expect( pxOverflowDelayedTaskList, &ptcb->xStateListItem ); + /* xTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdFALSE ); + listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &xPendingReadyList, ptcb ); + listREMOVE_ITEM_Expect( &( ptcb->xEventListItem ) ); + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* back to xTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + /* API Call */ + ret_xtask_delay = xTaskDelayUntil( &previousWakeTime, 5 ); + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); + TEST_ASSERT_EQUAL( pdTRUE, ret_xtask_delay ); +} + +void test_xTaskDelayUntil_success_lt_tickCount1( void ) +{ + BaseType_t ret_xtask_delay; + TickType_t previousWakeTime = xTickCount - 3; /* 500 - 3 = 497 */ + TaskHandle_t task_handle; + TickType_t xTimeIncrement = 3; + + /* Setup */ + task_handle = create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_EQUAL( pxCurrentTCB, ptcb ); + /* Expectations */ + /* xTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdFALSE ); + listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &xPendingReadyList, ptcb ); + listREMOVE_ITEM_Expect( &( ptcb->xEventListItem ) ); + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* back to xTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + /* API Call */ + ret_xtask_delay = xTaskDelayUntil( &previousWakeTime, xTimeIncrement ); + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); + TEST_ASSERT_FALSE( ret_xtask_delay ); +} + +void test_xTaskDelayUntil_success_lt_tickCount2( void ) +{ + BaseType_t ret_xtask_delay; + TickType_t previousWakeTime = xTickCount - 3; /* 500 - 3 = 497 */ + TaskHandle_t task_handle; + TickType_t xTimeIncrement = UINT32_MAX; + + /* Setup */ + task_handle = create_task(); + ptcb = ( TCB_t * ) task_handle; + TEST_ASSERT_EQUAL( pxCurrentTCB, ptcb ); + /* Expectations */ + /* xTaskResumeAll */ + /* prvResetNextTaskUnblockTime */ + uxListRemove_ExpectAndReturn( &pxCurrentTCB->xStateListItem, 0 ); + listSET_LIST_ITEM_VALUE_Expect( &pxCurrentTCB->xStateListItem, + ( ( previousWakeTime - 1 ) ) ); + vListInsert_Expect( pxOverflowDelayedTaskList, &ptcb->xStateListItem ); + /* xTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdFALSE ); + listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &xPendingReadyList, ptcb ); + listREMOVE_ITEM_Expect( &( ptcb->xEventListItem ) ); + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* back to xTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + /* API Call */ + ret_xtask_delay = xTaskDelayUntil( &previousWakeTime, xTimeIncrement ); + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); + TEST_ASSERT_TRUE( ret_xtask_delay ); +} + + +/* ----------------------- testing INCLUDE_vTaskSuspend ----------------------*/ +void test_vTaskSuspend_success( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = task_handle; + TEST_ASSERT_EQUAL_PTR( ptcb, pxCurrentTCB ); + xSchedulerRunning = pdFALSE; + /* Expectations */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 0 ); + /* taskRESET_READY_PRIORITY */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ], + 0 ); + /* back */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, NULL ); + vListInsertEnd_Expect( &xSuspendedTaskList, &ptcb->xStateListItem ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xSuspendedTaskList, + uxCurrentNumberOfTasks ); + /* API Call */ + vTaskSuspend( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL_PTR( NULL, pxCurrentTCB ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_vTaskSuspend_success_shced_running( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = task_handle; + TEST_ASSERT_EQUAL_PTR( ptcb, pxCurrentTCB ); + xSchedulerRunning = pdTRUE; + /* Expectations */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 0 ); + /* taskRESET_READY_PRIORITY */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ], + 0 ); + /* back */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, NULL ); + vListInsertEnd_Expect( &xSuspendedTaskList, &ptcb->xStateListItem ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + /* API Call */ + vTaskSuspend( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime ); + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +void test_vTaskSuspend_success_shced_running_not_curr( void ) +{ + TaskHandle_t task_handle, task_handle2; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + task_handle2 = create_task(); + ptcb = task_handle; + TEST_ASSERT_EQUAL_PTR( task_handle2, pxCurrentTCB ); + xSchedulerRunning = pdTRUE; + /* Expectations */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 0 ); + /* taskRESET_READY_PRIORITY */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ], + 1 ); + /* back */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, NULL ); + vListInsertEnd_Expect( &xSuspendedTaskList, &ptcb->xStateListItem ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + /* API Call */ + vTaskSuspend( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_vTaskSuspend_success_switch_context( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = task_handle; + TEST_ASSERT_EQUAL_PTR( ptcb, pxCurrentTCB ); + xSchedulerRunning = pdFALSE; + uxSchedulerSuspended = pdTRUE; + ptcb->ucNotifyState[ 0 ] = 1; /* taskWAITING_NOTIFICATION */ + /* Expectations */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 1 ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, + &xSuspendedTaskList ); + uxListRemove_ExpectAndReturn( &ptcb->xEventListItem, pdTRUE ); + vListInsertEnd_Expect( &xSuspendedTaskList, &ptcb->xStateListItem ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xSuspendedTaskList, + uxCurrentNumberOfTasks + 1 ); + /* API Call */ + vTaskSuspend( NULL ); + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); + TEST_ASSERT_EQUAL( 0, ptcb->ucNotifyState[ 0 ] ); +} + +void test_vTaskResume_fail_null_handle( void ) +{ + vTaskResume( NULL ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_vTaskResume_fail_current_tcb_null( void ) +{ + create_task(); + vTaskResume( NULL ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_vTaskResume_fail_current_tcb( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + vTaskResume( task_handle ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_vTaskResume_fail_task_not_suspended( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + create_task(); + ptcb = task_handle; + /* Expectations */ + /* prvTaskIsTaskSuspended */ + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xSuspendedTaskList, + &ptcb->xStateListItem, + pdFALSE ); + /* API Call */ + vTaskResume( task_handle ); /* not current tcb */ + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_vTaskResume_fail_task_ready( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + create_task(); + ptcb = task_handle; + /* Expectations */ + /* prvTaskIsTaskSuspended */ + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xSuspendedTaskList, + &ptcb->xStateListItem, + pdTRUE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xPendingReadyList, + &ptcb->xEventListItem, + pdTRUE ); + /* API Call */ + vTaskResume( task_handle ); /* not current tcb */ + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_vTaskResume_fail_task_event_list_not_orphan( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + create_task(); + ptcb = task_handle; + /* Expectations */ + /* prvTaskIsTaskSuspended */ + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xSuspendedTaskList, + &ptcb->xStateListItem, + pdTRUE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xPendingReadyList, + &ptcb->xEventListItem, + pdFALSE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( NULL, + &ptcb->xEventListItem, + pdFALSE ); + /* API Call */ + vTaskResume( task_handle ); /* not current tcb */ + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_vTaskResume_success_task_event_list_orphan( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 5; + create_task(); + ptcb = task_handle; + /* Expectations */ + /* prvTaskIsTaskSuspended */ + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xSuspendedTaskList, + &ptcb->xStateListItem, + pdTRUE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xPendingReadyList, + &ptcb->xEventListItem, + pdFALSE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( NULL, + &ptcb->xEventListItem, + pdTRUE ); + /* back */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, pdTRUE ); + /* prvAddTaskToReadyList*/ + listINSERT_END_Expect( &pxReadyTasksLists[ create_task_priority ], + &ptcb->xStateListItem ); + /* API Call */ + vTaskResume( task_handle ); /* not current tcb */ + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_vTaskResume_success_yield( void ) +{ + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 3; + create_task(); + ptcb = task_handle; + /* Expectations */ + /* prvTaskIsTaskSuspended */ + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xSuspendedTaskList, + &ptcb->xStateListItem, + pdTRUE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xPendingReadyList, + &ptcb->xEventListItem, + pdFALSE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( NULL, + &ptcb->xEventListItem, + pdTRUE ); + /* back */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, pdTRUE ); + /* prvAddTaskToReadyList*/ + listINSERT_END_Expect( &pxReadyTasksLists[ create_task_priority ], + &ptcb->xStateListItem ); + /* API Call */ + vTaskResume( task_handle ); /* not current tcb */ + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +void test_xTaskResumeFromISR_success( void ) +{ + TaskHandle_t task_handle; + BaseType_t ret_task_resume; + + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + /* Expectations */ + /* prvTaskIsTaskSuspended */ + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xSuspendedTaskList, + &ptcb->xStateListItem, + pdTRUE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xPendingReadyList, + &ptcb->xEventListItem, + pdFALSE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( NULL, + &ptcb->xEventListItem, + pdTRUE ); + /* back */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, pdTRUE ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ create_task_priority ], + &ptcb->xStateListItem ); + /* API Call */ + ret_task_resume = xTaskResumeFromISR( task_handle ); + + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_task_resume ); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); +} + +void test_xTaskResumeFromISR_success_sched_suspended( void ) +{ + TaskHandle_t task_handle; + BaseType_t ret_task_resume; + + uxSchedulerSuspended = pdTRUE; + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + /* Expectations */ + /* prvTaskIsTaskSuspended */ + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xSuspendedTaskList, + &ptcb->xStateListItem, + pdTRUE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xPendingReadyList, + &ptcb->xEventListItem, + pdFALSE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( NULL, + &ptcb->xEventListItem, + pdTRUE ); + /* back */ + vListInsertEnd_Expect( &xPendingReadyList, &ptcb->xEventListItem ); + /* API Call */ + ret_task_resume = xTaskResumeFromISR( task_handle ); + + /* Validations */ + TEST_ASSERT_EQUAL( pdFALSE, ret_task_resume ); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); +} + +void test_xTaskResumeFromISR_success_task_suspended( void ) +{ + TaskHandle_t task_handle; + BaseType_t ret_task_resume; + + uxSchedulerSuspended = pdTRUE; + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + /* Expectations */ + /* prvTaskIsTaskSuspended */ + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xSuspendedTaskList, + &ptcb->xStateListItem, + pdFALSE ); + /* API Call */ + ret_task_resume = xTaskResumeFromISR( task_handle ); + + /* Validations */ + TEST_ASSERT_EQUAL( pdFALSE, ret_task_resume ); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); +} + +void test_xTaskResumeFromISR_success_curr_prio_lt_suspended_task( void ) +{ + TaskHandle_t task_handle; + BaseType_t ret_task_resume; + + uxSchedulerSuspended = pdFALSE; + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 4; + create_task(); + ptcb = task_handle; + /* Expectations */ + /* prvTaskIsTaskSuspended */ + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xSuspendedTaskList, + &ptcb->xStateListItem, + pdTRUE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &xPendingReadyList, + &ptcb->xEventListItem, + pdFALSE ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( NULL, + &ptcb->xEventListItem, + pdTRUE ); + /* back */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, pdTRUE ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ create_task_priority ], + &ptcb->xStateListItem ); + /* API Call */ + ret_task_resume = xTaskResumeFromISR( task_handle ); + + /* Validations */ + TEST_ASSERT_EQUAL( pdFALSE, ret_task_resume ); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); +} + +/* testing INCLUDE_xTaskGetHandle */ + + +void test_xtaskGetHandle_success( void ) +{ + TaskHandle_t task_handle = NULL, task_handle2; + ListItem_t list_item; + + task_handle = create_task(); + ptcb = task_handle; + INITIALIZE_LIST_1E( pxReadyTasksLists[ configMAX_PRIORITIES - 1 ], + list_item, + ptcb ); + /* Expectations */ + /* prvSearchForNameWithinSingleList */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ configMAX_PRIORITIES - 1 ], + 1 ); + /* vTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + + /* API Call */ + task_handle2 = xTaskGetHandle( "create_task" ); + /* Validations */ + TEST_ASSERT_EQUAL_PTR( task_handle, task_handle2 ); +} + +void test_xtaskGetHandle_success_2elements( void ) +{ + TaskHandle_t task_handle = NULL, task_handle2, ret_task_handle; + ListItem_t list_item, list_item2; + + task_handle = create_task(); + task_handle2 = create_task(); + ptcb = task_handle; + INITIALIZE_LIST_2E( pxReadyTasksLists[ configMAX_PRIORITIES - 1 ], + list_item, list_item2, + ptcb, task_handle2 ); + /* Expectations */ + /* prvSearchForNameWithinSingleList */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ configMAX_PRIORITIES - 1 ], + 1 ); + /* vTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + + /* API Call */ + ret_task_handle = xTaskGetHandle( "create_task" ); + /* Validations */ + TEST_ASSERT_EQUAL_PTR( task_handle2, ret_task_handle ); +} + +void test_xtaskGetHandle_success_2elements_set_index( void ) +{ + TaskHandle_t task_handle = NULL, task_handle2, ret_task_handle; + ListItem_t list_item, list_item2; + + task_handle = create_task(); + task_handle2 = create_task(); + ptcb = task_handle; + INITIALIZE_LIST_2E( pxReadyTasksLists[ configMAX_PRIORITIES - 1 ], + list_item, list_item2, + task_handle, task_handle2 ); + /* advance index */ + pxReadyTasksLists[ configMAX_PRIORITIES - 1 ].pxIndex = + pxReadyTasksLists[ configMAX_PRIORITIES - 1 ].pxIndex->pxNext; + /* advance index */ + pxReadyTasksLists[ configMAX_PRIORITIES - 1 ].pxIndex = + pxReadyTasksLists[ configMAX_PRIORITIES - 1 ].pxIndex->pxNext; + /* Expectations */ + /* prvSearchForNameWithinSingleList */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ configMAX_PRIORITIES - 1 ], + 1 ); + /* vTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + + /* API Call */ + ret_task_handle = xTaskGetHandle( "create_task" ); + /* Validations */ + TEST_ASSERT_EQUAL_PTR( task_handle2, ret_task_handle ); +} + +void test_xtaskGetHandle_fail_no_task_found( void ) +{ + TaskHandle_t task_handle, task_handle2, ret_task_handle; + ListItem_t list_item, list_item2; + + task_handle = create_task(); + task_handle2 = create_task(); + ptcb = task_handle; + INITIALIZE_LIST_2E( pxReadyTasksLists[ configMAX_PRIORITIES - 1 ], + list_item, list_item2, + ptcb, task_handle2 ); + /* Expectations */ + /* prvSearchForNameWithinSingleList */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( + &pxReadyTasksLists[ configMAX_PRIORITIES - 1 ], + 2 ); + int i = configMAX_PRIORITIES - 1; + + do + { + i--; + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ i ], + 0 ); + } while( i > tskIDLE_PRIORITY ); + + listCURRENT_LIST_LENGTH_ExpectAndReturn( pxDelayedTaskList, 0 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( pxOverflowDelayedTaskList, 0 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xSuspendedTaskList, 0 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xTasksWaitingTermination, 0 ); + /* vTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + + /* API Call */ + ret_task_handle = xTaskGetHandle( "create_tasks" ); + /* Validations */ + TEST_ASSERT_EQUAL_PTR( NULL, ret_task_handle ); +} + + +void test_xtaskGetHandle_fail_no_taks_running( void ) +{ + TaskHandle_t task_handle2; + + /* Expectations */ + /* prvSearchForNameWithinSingleList */ + for( int i = configMAX_PRIORITIES; i > tskIDLE_PRIORITY; --i ) + { + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ i - 1 ], 0 ); + } + + listCURRENT_LIST_LENGTH_ExpectAndReturn( pxDelayedTaskList, 0 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( pxOverflowDelayedTaskList, 0 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xSuspendedTaskList, 0 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xTasksWaitingTermination, 0 ); + /* API Call */ + task_handle2 = xTaskGetHandle( "create_task" ); + /* Validations */ + TEST_ASSERT_EQUAL_PTR( NULL, task_handle2 ); +} + +/* testing always available functions */ +void test_xTaskGetTickCount_sucess( void ) +{ + TickType_t ret_get_tick_count; + + xTickCount = 565656; + ret_get_tick_count = xTaskGetTickCount(); + TEST_ASSERT_EQUAL( 565656, ret_get_tick_count ); +} + +void test_xTaskGetTickCountFromISR_success( void ) +{ + TickType_t ret_get_tick_count; + + /* Setup */ + xTickCount = 565656; + /* Expectations */ + /* API Call */ + ret_get_tick_count = xTaskGetTickCountFromISR(); + /* Validations */ + TEST_ASSERT_EQUAL( 565656, ret_get_tick_count ); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); +} + +void test_uxTaskGetNumberOfTasks_success( void ) +{ + UBaseType_t ret_task_num; + + create_task(); + create_task(); + create_task(); + + ret_task_num = uxTaskGetNumberOfTasks(); + + TEST_ASSERT_EQUAL( 3, ret_task_num ); +} + +void test_pcTaskGetName_success( void ) +{ + char * ret_task_name; + TaskHandle_t task_handle; + + task_handle = create_task(); + + ret_task_name = pcTaskGetName( task_handle ); + TEST_ASSERT_EQUAL_STRING( "create_task", ret_task_name ); +} + +void test_pcTaskGetName_success_null_handle( void ) +{ + char * ret_task_name; + + create_task(); + + ret_task_name = pcTaskGetName( NULL ); + TEST_ASSERT_EQUAL_STRING( "create_task", ret_task_name ); +} +void test_xTaskCatchUpTicks( void ) +{ + BaseType_t ret_taskCatchUpTicks; + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = task_handle; + uxSchedulerSuspended = pdTRUE; + /* API Call */ + ret_taskCatchUpTicks = xTaskCatchUpTicks( 500 ); + /* Validations */ + TEST_ASSERT_EQUAL( pdFALSE, ret_taskCatchUpTicks ); +} + +void test_xTaskIncrementTick_success_sched_suspended_no_switch( void ) +{ + BaseType_t ret_task_incrementtick; + TickType_t current_ticks = xPendedTicks; + + vTaskSuspendAll(); + + /* API Call */ + ret_task_incrementtick = xTaskIncrementTick(); + /* Validations */ + TEST_ASSERT_EQUAL( pdFALSE, ret_task_incrementtick ); + TEST_ASSERT_EQUAL( current_ticks + 1, xPendedTicks ); + ASSERT_APP_TICK_HOOK_CALLED(); +} + +/* ensures that the delayed task list and overflow list are switched when a + * tickcount overflow occurs */ +void test_xTaskIncrementTick_success_tickCount_overlow( void ) +{ + BaseType_t ret_task_incrementtick; + List_t * delayed, * overflow; + + uxSchedulerSuspended = pdFALSE; + delayed = pxDelayedTaskList; + overflow = pxOverflowDelayedTaskList; + xTickCount = UINT32_MAX; /* overflowed */ + create_task(); + + /* Expectations */ + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + /* back */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ pxCurrentTCB->uxPriority ], + 2 ); + /* API Call */ + ret_task_incrementtick = xTaskIncrementTick(); + + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_task_incrementtick ); + ASSERT_APP_TICK_HOOK_CALLED(); + /* make sure the lists are swapped on overflow */ + TEST_ASSERT_EQUAL_PTR( pxOverflowDelayedTaskList, delayed ); + TEST_ASSERT_EQUAL_PTR( pxDelayedTaskList, overflow ); + TEST_ASSERT_EQUAL( 1, xNumOfOverflows ); + TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime ); +} + +void test_xTaskIncrementTick_success_no_switch( void ) +{ + BaseType_t ret_task_incrementtick; + TaskHandle_t task_handle; + + /* setup */ + task_handle = create_task(); + ptcb = task_handle; + + /* Expectations */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ], + 1 ); + + /* API Call */ + ret_task_incrementtick = xTaskIncrementTick(); + + /* Validations */ + TEST_ASSERT_EQUAL( pdFALSE, ret_task_incrementtick ); + TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime ); + ASSERT_APP_TICK_HOOK_CALLED(); +} + +void test_xTaskIncrementTick_success_switch( void ) +{ + BaseType_t ret_task_incrementtick; + TaskHandle_t task_handle; + + /* setup */ + task_handle = create_task(); + ptcb = task_handle; + xPendedTicks = 3; + xTickCount = UINT32_MAX; + + /* Expectations */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ], + 3 ); + + /* API Call */ + ret_task_incrementtick = xTaskIncrementTick(); + + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_task_incrementtick ); + ASSERT_APP_TICK_HOOK_NOT_CALLED(); + TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime ); +} + +void test_xTaskIncrementTick_success_update_next_unblock( void ) +{ + BaseType_t ret_task_incrementtick; + TaskHandle_t task_handle; + TaskHandle_t task_handle2; + + /* setup */ + task_handle = create_task(); + task_handle2 = create_task(); + ptcb = task_handle; + xPendedTicks = 3; + xTickCount = 50; + xNextTaskUnblockTime = 49; /* tasks due unblocking */ + uxSchedulerSuspended = pdFALSE; + + /* Expectations */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdFALSE ); + listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( pxDelayedTaskList, task_handle2 ); + listGET_LIST_ITEM_VALUE_ExpectAndReturn( &task_handle2->xStateListItem, + xTickCount + 5 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ], + 3 ); + + /* API Call */ + ret_task_incrementtick = xTaskIncrementTick(); + + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_task_incrementtick ); + ASSERT_APP_TICK_HOOK_NOT_CALLED(); + TEST_ASSERT_EQUAL( xTickCount + 4, xNextTaskUnblockTime ); +} + +void test_xTaskIncrementTick_success_unblock_tasks( void ) +{ + BaseType_t ret_task_incrementtick; + TaskHandle_t task_handle; + TaskHandle_t task_handle2; + + /* setup */ + task_handle = create_task(); + task_handle2 = create_task(); + ptcb = task_handle; + xPendedTicks = 3; + xTickCount = 50; + xNextTaskUnblockTime = 49; /* tasks due unblocking */ + uxSchedulerSuspended = pdFALSE; + + /* Expectations */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdFALSE ); + listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( pxDelayedTaskList, task_handle2 ); + listGET_LIST_ITEM_VALUE_ExpectAndReturn( &task_handle2->xStateListItem, + xTickCount - 5 ); + listREMOVE_ITEM_Expect( &( task_handle2->xStateListItem ) ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &task_handle2->xEventListItem, NULL ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ task_handle2->uxPriority ], + &task_handle2->xStateListItem ); + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + /* back */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ], + 1 ); + + /* API Call */ + ret_task_incrementtick = xTaskIncrementTick(); + + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_task_incrementtick ); + ASSERT_APP_TICK_HOOK_NOT_CALLED(); + TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime ); +} + +void test_xTaskIncrementTick_success_unblock_tasks2( void ) +{ + BaseType_t ret_task_incrementtick; + TaskHandle_t task_handle; + TaskHandle_t task_handle2; + + /* setup */ + task_handle = create_task(); + create_task_priority = 2; + task_handle2 = create_task(); + ptcb = task_handle; + xPendedTicks = 0; + xTickCount = 50; + xNextTaskUnblockTime = 49; /* tasks due unblocking */ + uxSchedulerSuspended = pdFALSE; + vTaskMissedYield(); + + /* Expectations */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdFALSE ); + listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( pxDelayedTaskList, task_handle2 ); + listGET_LIST_ITEM_VALUE_ExpectAndReturn( &task_handle2->xStateListItem, + xTickCount - 5 ); + listREMOVE_ITEM_Expect( &( task_handle2->xStateListItem ) ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &task_handle2->xEventListItem, + &xPendingReadyList ); + listREMOVE_ITEM_Expect( &( task_handle2->xEventListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ task_handle2->uxPriority ], + &task_handle2->xStateListItem ); + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + /* back */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ ptcb->uxPriority ], + 1 ); + + /* API Call */ + ret_task_incrementtick = xTaskIncrementTick(); + + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_task_incrementtick ); + ASSERT_APP_TICK_HOOK_CALLED(); + TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime ); +} +/* testing INCLUDE_xTaskAbortDelay */ +void test_xTaskAbortDelay_fail_current_task( void ) +{ + BaseType_t ret_taskabort_delay; + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = task_handle; + + /* Expectations */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + /* API Call */ + ret_taskabort_delay = xTaskAbortDelay( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( pdFALSE, ret_taskabort_delay ); + TEST_ASSERT_EQUAL( pdFALSE, ptcb->ucDelayAborted ); +} + +void test_xTaskAbortDelay_success( void ) +{ + BaseType_t ret_taskabort_delay; + TaskHandle_t task_handle; + + create_task_priority = 4; + task_handle = create_task(); + ptcb = task_handle; + create_task_priority = 5; + create_task(); + + /* Expectations */ + /* eTaskGetState */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xStateListItem, + pxDelayedTaskList ); + /* back */ + uxListRemove_ExpectAndReturn( &tcb->xStateListItem, pdTRUE ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, NULL ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ create_task_priority ], + &ptcb->xStateListItem ); + /* xTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + /* API Call */ + ret_taskabort_delay = xTaskAbortDelay( task_handle ); + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_taskabort_delay ); + TEST_ASSERT_EQUAL( pdFALSE, ptcb->ucDelayAborted ); +} + +void test_xTaskAbortDelay_success_notdelayed( void ) +{ + BaseType_t ret_taskabort_delay; + TaskHandle_t task_handle; + TaskHandle_t task_handle2; + + create_task_priority = 6; + task_handle = create_task(); + ptcb = task_handle; + + /* Expectations 1*/ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 1 ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, + &xSuspendedTaskList ); + uxListRemove_ExpectAndReturn( &ptcb->xEventListItem, pdTRUE ); + vListInsertEnd_Expect( &xSuspendedTaskList, &ptcb->xStateListItem ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xSuspendedTaskList, + uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( pxCurrentTCB, task_handle ); + + vTaskSuspend( task_handle ); + TEST_ASSERT_EQUAL( NULL, pxCurrentTCB ); + + create_task_priority = 5; + task_handle2 = create_task(); + TEST_ASSERT_EQUAL( pxCurrentTCB, task_handle2 ); + + /* Expectations */ + /* eTaskGetState */ + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xStateListItem, + pxDelayedTaskList ); + /* back */ + uxListRemove_ExpectAndReturn( &tcb->xStateListItem, pdTRUE ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, + pxDelayedTaskList ); + uxListRemove_ExpectAndReturn( &ptcb->xEventListItem, pdTRUE ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ create_task_priority ], + &ptcb->xStateListItem ); + /* xTaskResumeAll */ + listLIST_IS_EMPTY_ExpectAndReturn( &xPendingReadyList, pdTRUE ); + /* API Call */ + ret_taskabort_delay = xTaskAbortDelay( task_handle ); + /* Validations */ + TEST_ASSERT_TRUE( ret_taskabort_delay ); + TEST_ASSERT_TRUE( xYieldPending ); + TEST_ASSERT_TRUE( ptcb->ucDelayAborted ); +} + +/* ------------------ testing INCLUDE_xTaskGetIdleTaskHandle ---------------- */ +void test_xTaskGetIdleTaskHandle_success( void ) +{ + TaskHandle_t ret_idle_handle; + int ret; + + start_scheduler(); + /* Api Call */ + ret_idle_handle = xTaskGetIdleTaskHandle(); + ptcb = ret_idle_handle; + ret = strcmp( ptcb->pcTaskName, "IDLE" ); + TEST_ASSERT_EQUAL( 0, ret ); +} + + +/* ----------------testing configUSE_APPLICATION_TASK_TAG ------------------- */ +void test_vTaskSetApplicationTaskTag_current( void ) +{ + create_task(); + + vTaskSetApplicationTaskTag( NULL, pxHookFunction ); + + TEST_ASSERT_EQUAL( &pxHookFunction, pxCurrentTCB->pxTaskTag ); +} + +void test_vTaskSetApplicationTaskTag_handle( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + + vTaskSetApplicationTaskTag( task_handle, pxHookFunction ); + TEST_ASSERT_EQUAL( &pxHookFunction, task_handle->pxTaskTag ); +} + +void test_xTaskGetApplicationTaskTag_null_tcb_current( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + vTaskSetApplicationTaskTag( task_handle, pxHookFunction ); + + TaskHookFunction_t hook_function; + hook_function = xTaskGetApplicationTaskTag( NULL ); + + TEST_ASSERT_EQUAL( &pxHookFunction, hook_function ); +} + +void test_xTaskGetApplicationTaskTag_tcb( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + vTaskSetApplicationTaskTag( task_handle, pxHookFunction ); + + TaskHookFunction_t hook_function; + hook_function = xTaskGetApplicationTaskTag( task_handle ); + + TEST_ASSERT_EQUAL( &pxHookFunction, hook_function ); +} + +void test_xTaskGetApplicationTaskTag_no_hook_set( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + TaskHookFunction_t hook_function; + + hook_function = xTaskGetApplicationTaskTag( task_handle ); + + TEST_ASSERT_EQUAL( NULL, hook_function ); +} + +void test_xTaskGetApplicationTaskTagFromISR_success( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + vTaskSetApplicationTaskTag( task_handle, pxHookFunction ); + + TaskHookFunction_t hook_function; + hook_function = xTaskGetApplicationTaskTagFromISR( task_handle ); + + TEST_ASSERT_EQUAL( &pxHookFunction, hook_function ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); +} + +void test_xTaskGetApplicationTaskTagFromISR_null_handle( void ) +{ + TaskHandle_t task_handle; + + task_handle = create_task(); + vTaskSetApplicationTaskTag( task_handle, pxHookFunction ); + + TaskHookFunction_t hook_function; + hook_function = xTaskGetApplicationTaskTagFromISR( NULL ); + + TEST_ASSERT_EQUAL( &pxHookFunction, hook_function ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); +} + +void test_xTaskCallApplicationTaskHook_success( void ) +{ + BaseType_t ret_task_hook; + TaskHandle_t task_handle; + BaseType_t i = 5; + void * args = &i; + + task_handle = create_task(); + vTaskSetApplicationTaskTag( task_handle, pxHookFunction ); + + ret_task_hook = xTaskCallApplicationTaskHook( task_handle, + args ); + TEST_ASSERT_EQUAL( i, ret_task_hook ); +} + +void test_xTaskCallApplicationTaskHook_success_null_handle( void ) +{ + BaseType_t ret_task_hook; + TaskHandle_t task_handle; + BaseType_t i = 6; + void * args = &i; + + task_handle = create_task(); + + vTaskSetApplicationTaskTag( task_handle, pxHookFunction ); + + ret_task_hook = xTaskCallApplicationTaskHook( NULL, + args ); + TEST_ASSERT_EQUAL( i, ret_task_hook ); +} + +void test_xTaskCallApplicationTaskHook_fail_no_tag_set( void ) +{ + BaseType_t ret_task_hook; + TaskHandle_t task_handle; + int i = 7; + void * args = &i; + + task_handle = create_task(); + + ret_task_hook = xTaskCallApplicationTaskHook( task_handle, + args ); + TEST_ASSERT_EQUAL( pdFAIL, ret_task_hook ); +} + +/* -------------- end testing configUSE_APPLICATION_TASK_TAG ---------------- */ +void test_vTaskSwitchContext( void ) +{ + TaskHandle_t task_handle; + TaskHandle_t task_handle2; + ListItem_t list_item, list_item2; + ListItem_t list_item3, list_item4; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 4; + task_handle2 = create_task(); + ptcb = task_handle; + + INITIALIZE_LIST_2E( pxReadyTasksLists[ 3 ], + list_item, list_item2, + ptcb, task_handle2 ); + INITIALIZE_LIST_2E( pxReadyTasksLists[ 4 ], + list_item3, list_item4, + ptcb, task_handle2 ); + + /* Setup */ + uxSchedulerSuspended = pdFALSE; + pxCurrentTCB->pxTopOfStack = pxCurrentTCB->pxStack + 4; \ + + /* Expectations */ + + /* API Call */ + vTaskSwitchContext(); + + /* Validations */ + TEST_ASSERT_EQUAL( 24, uxTopReadyPriority ); + TEST_ASSERT_FALSE( xYieldPending ); + ASSERT_APP_STACK_OVERFLOW_HOOK_NOT_CALLED(); +} + +void test_vTaskSwitchContext_detect_overflow( void ) +{ + TaskHandle_t task_handle; + TaskHandle_t task_handle2; + ListItem_t list_item, list_item2; + ListItem_t list_item3, list_item4; + + create_task_priority = 3; + task_handle = create_task(); + create_task_priority = 4; + task_handle2 = create_task(); + ptcb = task_handle; + + INITIALIZE_LIST_2E( pxReadyTasksLists[ 3 ], + list_item, list_item2, + ptcb, task_handle2 ); + INITIALIZE_LIST_2E( pxReadyTasksLists[ 4 ], + list_item3, list_item4, + ptcb, task_handle2 ); + + /* Setup */ + uxSchedulerSuspended = pdFALSE; + pxCurrentTCB->pxTopOfStack = pxCurrentTCB->pxStack; + /* Expectations */ + + /* API Call */ + vTaskSwitchContext(); + + /* Validations */ + TEST_ASSERT_EQUAL( 24, uxTopReadyPriority ); + TEST_ASSERT_FALSE( xYieldPending ); + ASSERT_APP_STACK_OVERFLOW_HOOK_CALLED(); +} + +void test_vTaskPlaceOnEventList_success( void ) +{ + TaskHandle_t task_handle; + List_t eventList; + + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + + /* Expectations */ + vListInsert_Expect( &eventList, &ptcb->xEventListItem ); + /* prvAddCurrentTaskToDelayedList */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 1 ); + listSET_LIST_ITEM_VALUE_Expect( &ptcb->xStateListItem, ( xTickCount + 34 ) ); + vListInsert_Expect( pxDelayedTaskList, &ptcb->xStateListItem ); + + /* API call */ + vTaskPlaceOnEventList( &eventList, + 34 ); + TEST_ASSERT_EQUAL( 0, xNextTaskUnblockTime ); +} +void test_vTaskPlaceOnUnorderedEventList( void ) +{ + TaskHandle_t task_handle; + List_t eventList; + + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + xNextTaskUnblockTime = 600; + + /* Expectations */ + listSET_LIST_ITEM_VALUE_Expect( &ptcb->xEventListItem, 32 | 0x80000000UL ); + listINSERT_END_Expect( &eventList, &ptcb->xEventListItem ); + /* prvAddCurrentTaskToDelayedList */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 1 ); + listSET_LIST_ITEM_VALUE_Expect( &ptcb->xStateListItem, ( xTickCount + 34 ) ); + vListInsert_Expect( pxDelayedTaskList, &ptcb->xStateListItem ); + /* API Call */ + vTaskPlaceOnUnorderedEventList( &eventList, 32, 34 ); + TEST_ASSERT_EQUAL( xTickCount + 34, xNextTaskUnblockTime ); +} + +/* testing configUSE_TIMERS */ +void test_vTaskPlaceOnEventListRestricted_indefinite( void ) +{ + List_t eventList; + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + /* Expectations */ + listINSERT_END_Expect( &eventList, &ptcb->xEventListItem ); + /* prvAddCurrentTaskToDelayedList */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 0 ); + listINSERT_END_Expect( &xSuspendedTaskList, &( ptcb->xStateListItem ) ); + /* API Call */ + vTaskPlaceOnEventListRestricted( &eventList, 100, pdTRUE ); +} + +void test_vTaskPlaceOnEventListRestricted_not_indefinite( void ) +{ + List_t eventList; + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + /* Expectations */ + listINSERT_END_Expect( &eventList, &ptcb->xEventListItem ); + /* prvAddCurrentTaskToDelayedList */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 1 ); + listSET_LIST_ITEM_VALUE_Expect( &ptcb->xStateListItem, ( xTickCount + 100 ) ); + vListInsert_Expect( pxDelayedTaskList, &ptcb->xStateListItem ); + /* API Call */ + vTaskPlaceOnEventListRestricted( &eventList, 100, pdFALSE ); +} + +void test_vTaskPlaceOnEventListRestricted_max_wait( void ) +{ + List_t eventList; + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + /* Expectations */ + listINSERT_END_Expect( &eventList, &ptcb->xEventListItem ); + /* prvAddCurrentTaskToDelayedList */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 1 ); + listSET_LIST_ITEM_VALUE_Expect( &ptcb->xStateListItem, ( xTickCount + portMAX_DELAY ) ); + vListInsert_Expect( pxDelayedTaskList, &ptcb->xStateListItem ); + /* API Call */ + vTaskPlaceOnEventListRestricted( &eventList, portMAX_DELAY, pdFALSE ); +} +/* end testing configUSE_TIMERS */ + +void test_xTaskRemoveFromEventList_fail( void ) +{ + BaseType_t ret_task_remove; + TaskHandle_t task_handle; + List_t eventList; + + /* Setup */ + uxSchedulerSuspended = pdFALSE; + task_handle = create_task(); + ptcb = task_handle; + + /* Expectations */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &eventList, ptcb ); + listREMOVE_ITEM_Expect( &( ptcb->xEventListItem ) ); + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ create_task_priority ], + &ptcb->xStateListItem ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + /* API Call */ + ret_task_remove = xTaskRemoveFromEventList( &eventList ); + /* Validations */ + TEST_ASSERT_EQUAL( pdFALSE, ret_task_remove ); + TEST_ASSERT_EQUAL( pdFALSE, xYieldPending ); +} + +void test_xTaskRemoveFromEventList_sched_suspended( void ) +{ + BaseType_t ret_task_remove; + TaskHandle_t task_handle; + TaskHandle_t task_handle2; + List_t eventList; + + /* Setup */ + uxSchedulerSuspended = pdTRUE; + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; /* unblocked */ + + /* block the higher priority task */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 1 ); + listLIST_ITEM_CONTAINER_ExpectAndReturn( &ptcb->xEventListItem, + &xSuspendedTaskList ); + uxListRemove_ExpectAndReturn( &ptcb->xEventListItem, pdTRUE ); + vListInsertEnd_Expect( &xSuspendedTaskList, &ptcb->xStateListItem ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xSuspendedTaskList, + uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( pxCurrentTCB, task_handle ); + + vTaskSuspend( task_handle ); + TEST_ASSERT_EQUAL( NULL, pxCurrentTCB ); + create_task_priority = 2; + task_handle2 = create_task(); + TEST_ASSERT_EQUAL( task_handle2, pxCurrentTCB ); + + /* Expectations */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAndReturn( &eventList, ptcb ); + /*uxListRemove_ExpectAndReturn( &ptcb->xEventListItem, pdTRUE ); */ + listREMOVE_ITEM_Expect( &( ptcb->xEventListItem ) ); + listINSERT_END_Expect( &xPendingReadyList, &ptcb->xEventListItem ); + /* API Call */ + ret_task_remove = xTaskRemoveFromEventList( &eventList ); + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_task_remove ); + TEST_ASSERT_EQUAL( pdTRUE, xYieldPending ); +} + +void test_vTaskRemoveFromUnorderedEventList( void ) +{ + ListItem_t list_item; + TickType_t xItemValue = 500; + TaskHandle_t task_handle; + + /* Setup */ + uxSchedulerSuspended = pdTRUE; + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + + /* Expectations */ + listSET_LIST_ITEM_VALUE_Expect( &list_item, xItemValue | 0x80000000UL ); + listGET_LIST_ITEM_OWNER_ExpectAndReturn( &list_item, tcb ); + listREMOVE_ITEM_Expect( &list_item ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + /* back */ + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ create_task_priority ], + &ptcb->xStateListItem ); + + /* API Call */ + vTaskRemoveFromUnorderedEventList( &list_item, + xItemValue ); + /* Validations */ + TEST_ASSERT_FALSE( xYieldPending ); +} + +void test_vTaskRemoveFromUnorderedEventList_yielding( void ) +{ + ListItem_t list_item; + TickType_t xItemValue = 500; + TaskHandle_t task_handle; + TaskHandle_t task_handle2; + + /* Setup */ + uxSchedulerSuspended = pdTRUE; + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + /* block the higher priority task */ + block_task( task_handle ); + TEST_ASSERT_EQUAL( NULL, pxCurrentTCB ); + create_task_priority = 2; + task_handle2 = create_task(); + TEST_ASSERT_EQUAL( task_handle2, pxCurrentTCB ); + + /* Expectations */ + listSET_LIST_ITEM_VALUE_Expect( &list_item, xItemValue | 0x80000000UL ); + listGET_LIST_ITEM_OWNER_ExpectAndReturn( &list_item, tcb ); + /*uxListRemove_ExpectAndReturn( &list_item, pdTRUE ); */ + listREMOVE_ITEM_Expect( &( list_item ) ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAndReturn( pxDelayedTaskList, 23 ); + /* back */ + /*uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, pdTRUE ); */ + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ create_task_priority ], + &ptcb->xStateListItem ); + + /* API Call */ + vTaskRemoveFromUnorderedEventList( &list_item, + xItemValue ); + /* Validations */ + TEST_ASSERT_TRUE( xYieldPending ); +} + +void test_vTaskSetTimeOutState_success( void ) +{ + TimeOut_t time_out; + + /* API Call */ + vTaskSetTimeOutState( &time_out ); + /* Validations */ + TEST_ASSERT_EQUAL( xNumOfOverflows, time_out.xOverflowCount ); + TEST_ASSERT_EQUAL( xTickCount, time_out.xTimeOnEntering ); +} + +void test_vTaskInternalSetTimeOutState_success( void ) +{ + TimeOut_t time_out; + + /* API Call */ + vTaskInternalSetTimeOutState( &time_out ); + /* Validations */ + TEST_ASSERT_EQUAL( xNumOfOverflows, time_out.xOverflowCount ); + TEST_ASSERT_EQUAL( xTickCount, time_out.xTimeOnEntering ); +} + +void test_xTaskCheckForTimeOut( void ) +{ + BaseType_t ret_check_timeout; + TimeOut_t time_out; + TickType_t ticks_to_wait = 5; + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + + ret_check_timeout = xTaskCheckForTimeOut( &time_out, + &ticks_to_wait ); + TEST_ASSERT_TRUE( ret_check_timeout ); +} + +void test_xTaskCheckForTimeOut_delay_aborted( void ) +{ + BaseType_t ret_check_timeout; + TimeOut_t time_out; + TickType_t ticks_to_wait = portMAX_DELAY; + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + ptcb->ucDelayAborted = pdTRUE; /* achieved by calling xTaskAbortDelay */ + + ret_check_timeout = xTaskCheckForTimeOut( &time_out, + &ticks_to_wait ); + TEST_ASSERT_TRUE( ret_check_timeout ); +} + +void test_xTaskCheckForTimeOut_max_delay( void ) +{ + BaseType_t ret_check_timeout; + TimeOut_t time_out; + TickType_t ticks_to_wait = portMAX_DELAY; + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + + ret_check_timeout = xTaskCheckForTimeOut( &time_out, + &ticks_to_wait ); + TEST_ASSERT_FALSE( ret_check_timeout ); +} + +void test_xTaskCheckForTimeOut_overflow( void ) +{ + BaseType_t ret_check_timeout; + TimeOut_t time_out; + TickType_t ticks_to_wait = 10; + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + time_out.xOverflowCount = xNumOfOverflows + 2; + time_out.xTimeOnEntering = xTickCount - 3; + + ret_check_timeout = xTaskCheckForTimeOut( &time_out, + &ticks_to_wait ); + TEST_ASSERT_TRUE( ret_check_timeout ); + TEST_ASSERT_EQUAL( 0, ticks_to_wait ); +} + +/*const TickType_t xElapsedTime = xConstTickCount - pxTimeOut->xTimeOnEntering; */ +void test_xTaskCheckForTimeOut_timeout( void ) +{ + BaseType_t ret_check_timeout; + TimeOut_t time_out; + TickType_t ticks_to_wait = 1000; + TaskHandle_t task_handle; + + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + ptcb->ucDelayAborted = pdFALSE; + time_out.xOverflowCount = xNumOfOverflows; + time_out.xTimeOnEntering = 3; + uint32_t expected = ( 1000 - ( xTickCount - time_out.xTimeOnEntering ) ); + /* API Call */ + ret_check_timeout = xTaskCheckForTimeOut( &time_out, + &ticks_to_wait ); + /* Validations */ + TEST_ASSERT_FALSE( ret_check_timeout ); + TEST_ASSERT_EQUAL( expected, ticks_to_wait ); + TEST_ASSERT_EQUAL( xTickCount, time_out.xTimeOnEntering ); +} + +void test_vTaskMissedYield( void ) +{ + TEST_ASSERT_FALSE( xYieldPending ); + vTaskMissedYield(); + TEST_ASSERT_TRUE( xYieldPending ); +} + +/* TODO: find a way to fix the iddle task UnitTest as it is an infitine loop */ +void ignore_test_prvIddleTask_yield( void ) +{ + int i = 8; + void * args = &i; + + create_task_priority = 3; + create_task(); + + /* Setup */ + uxDeletedTasksWaitingCleanUp = 0; + portTASK_FUNCTION( prvIdleTask, args ); + ( void ) fool_static2; + /* Expectations */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 2 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 0 ); + /* prvGetExpectedIdleTime */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 0 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 0 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 0 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &pxReadyTasksLists[ 0 ], 0 ); + /* API Call */ + prvIdleTask( args ); + /* Validations */ + ASSERT_PORT_ALLOCATE_SECURE_CONTEXT_CALLED(); + ASSERT_PORT_YIELD_CALLED(); + ASSERT_APPLICATION_IDLE_HOOK_CALLED(); +} +/* implement */ +/*configPRE_SUPPRESS_TICKS_AND_SLEEP_PROCESSING( xExpectedIdleTime ); */ + + +/* testing configUSE_TICKLESS_IDLE */ +void test_eTaskConfirmSleepModeStatus_abort_sleep( void ) +{ + eSleepModeStatus ret_status; + + /* Setup */ + vTaskMissedYield(); + /* Expectations */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xPendingReadyList, 0 ); + /* API Call */ + ret_status = eTaskConfirmSleepModeStatus(); + /* Validations */ + TEST_ASSERT_EQUAL( eAbortSleep, ret_status ); +} + +void test_eTaskConfirmSleepModeStatus_abort_sleep2( void ) +{ + eSleepModeStatus ret_status; + + /* Setup */ + xPendedTicks = 3; + /* Expectations */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xPendingReadyList, 0 ); + /* API Call */ + ret_status = eTaskConfirmSleepModeStatus(); + /* Validations */ + TEST_ASSERT_EQUAL( eAbortSleep, ret_status ); +} + +void test_eTaskConfirmSleepModeStatus_abort_sleep3( void ) +{ + eSleepModeStatus ret_status; + + /* Setup */ + /* Expectations */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xPendingReadyList, 3 ); + /* API Call */ + ret_status = eTaskConfirmSleepModeStatus(); + /* Validations */ + TEST_ASSERT_EQUAL( eAbortSleep, ret_status ); +} + +void test_eTaskConfirmSleepModeStatus_standard_sleep( void ) +{ + eSleepModeStatus ret_status; + + /* Setup */ + xPendedTicks = 0; + /* Expectations */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xPendingReadyList, 0 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xSuspendedTaskList, 0 ); + /* API Call */ + ret_status = eTaskConfirmSleepModeStatus(); + /* Validations */ + TEST_ASSERT_EQUAL( eStandardSleep, ret_status ); +} + +void test_eTaskConfirmSleepModeStatus_no_tasks_waiting_timeout( void ) +{ + eSleepModeStatus ret_status; + + /* Setup */ + create_task(); + xPendedTicks = 0; + /* Expectations */ + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xPendingReadyList, 0 ); + listCURRENT_LIST_LENGTH_ExpectAndReturn( &xSuspendedTaskList, 0 ); + /* API Call */ + ret_status = eTaskConfirmSleepModeStatus(); + /* Validations */ + TEST_ASSERT_EQUAL( eNoTasksWaitingTimeout, ret_status ); +} + +void test_vTaskStepTick() +{ + TickType_t save_tick_count; + + /* Setup */ + save_tick_count = xTickCount; + /* Expectations */ + /* API Call */ + vTaskStepTick( 35 ); + /* Validations */ + TEST_ASSERT_EQUAL( 35 + save_tick_count, xTickCount ); +} +/* end testing configUSE_TICKLESS_IDLE */ + + +/* testing configNUM_THREAD_LOCAL_STORAGE_POINTERS */ + +/* this test ensures that the value set is also retreived */ +void test_vTask_Set_Get_ThreadLocalStoragePointer_success( void ) +{ + TaskHandle_t task_handle; + uint32_t i = 454545; + void * pValue = &i; + void * ret_pValue; + + /* Setup */ + create_task_priority = 3; + task_handle = create_task(); + /* Expectations */ + /* API Call */ + vTaskSetThreadLocalStoragePointer( task_handle, + 0, + pValue ); + ret_pValue = pvTaskGetThreadLocalStoragePointer( task_handle, 0 ); + /* Validations */ + TEST_ASSERT_EQUAL_PTR( pValue, ret_pValue ); +} + +void test_vTask_Set_Get_ThreadLocalStoragePointer_success_null_handle( void ) +{ + uint32_t i = 454545; + void * pValue = &i; + void * ret_pValue; + + /* Setup */ + create_task_priority = 3; + create_task(); + /* Expectations */ + /* API Call */ + vTaskSetThreadLocalStoragePointer( NULL, + 0, + pValue ); + ret_pValue = pvTaskGetThreadLocalStoragePointer( NULL, 0 ); + /* Validations */ + TEST_ASSERT_EQUAL_PTR( pValue, ret_pValue ); +} +void test_vTask_Set_ThreadLocalStoragePointer_fail( void ) +{ + TaskHandle_t task_handle; + uint32_t i = 454545; + void * pValue = &i; + + /* Setup */ + create_task_priority = 3; + task_handle = create_task(); + ptcb = task_handle; + /* Expectations */ + /* API Call */ + vTaskSetThreadLocalStoragePointer( task_handle, + configNUM_THREAD_LOCAL_STORAGE_POINTERS + 2, + pValue ); + + #pragma GCC diagnostic ignored "-Warray-bounds" + void * value = *( ptcb->pvThreadLocalStoragePointers + + configNUM_THREAD_LOCAL_STORAGE_POINTERS + 2 ); + #pragma GCC diagnostic error "-Warray-bounds" + + /* this wall cause a warning, since we are reading past the end of the + * array, could remove this test case since sanitizers would easily catch it + * */ + TEST_ASSERT_NOT_EQUAL( pValue, value ); +} +void test_pvTaskGetThreadLocalStoragePointer_fail( void ) +{ + void * ret_pValue; + + ret_pValue = pvTaskGetThreadLocalStoragePointer( NULL, + configNUM_THREAD_LOCAL_STORAGE_POINTERS + 2 ); + TEST_ASSERT_NULL( ret_pValue ); +} +/* ------- end testing configNUM_THREAD_LOCAL_STORAGE_POINTERS -------------- */ + + +/* --- testing INCLUDE_xTaskGetCurrentTaskHandle || configUSE_MUTEXES == 1 -- */ +void test_xTaskGetCurrentTaskHandle( void ) +{ + TaskHandle_t task_handle; + TaskHandle_t ret_current_handle; + + /* Setup */ + task_handle = create_task(); + /* Expectations */ + + /* API Call */ + ret_current_handle = xTaskGetCurrentTaskHandle(); + /* Validations */ + TEST_ASSERT_EQUAL_PTR( task_handle, ret_current_handle ); +} +/* - end testing INCLUDE_xTaskGetCurrentTaskHandle || configUSE_MUTEXES == 1 */ + +/* testing INCLUDE_xTaskGetSchedulerState configUSE_TIMERS */ +void test_xTaskGetSchedulerState_not_running( void ) +{ + BaseType_t ret_sched_state; + + vPortEndScheduler_Expect(); + vTaskEndScheduler(); + ret_sched_state = xTaskGetSchedulerState(); + TEST_ASSERT_EQUAL( taskSCHEDULER_NOT_STARTED, ret_sched_state ); +} + +void test_xTaskGetSchedulerState_running( void ) +{ + BaseType_t ret_sched_state; + + start_scheduler(); + ret_sched_state = xTaskGetSchedulerState(); + TEST_ASSERT_EQUAL( taskSCHEDULER_RUNNING, ret_sched_state ); +} + +void test_xTaskGetSchedulerState_suspended( void ) +{ + BaseType_t ret_sched_state; + + start_scheduler(); + vTaskSuspendAll(); + ret_sched_state = xTaskGetSchedulerState(); + TEST_ASSERT_EQUAL( taskSCHEDULER_SUSPENDED, ret_sched_state ); +} +/* end testing INCLUDE_xTaskGetSchedulerState configUSE_TIMERS */ + +/* ----------------- testing configUSE_MUTEXES == 1 ------------------------- */ +void test_xTaskPriorityInherit_fail_null_param( void ) +{ + BaseType_t ret_prio_inherit; + + /* Setup */ + /* Expectations */ + /* API Call */ + ret_prio_inherit = xTaskPriorityInherit( NULL ); + /* Validations */ + TEST_ASSERT_FALSE( ret_prio_inherit ); +} + +void test_xTaskPriorityInherit_fail( void ) +{ + BaseType_t ret_prio_inherit; + TaskHandle_t mutex_holder; + + /* Setup */ + create_task_priority = 3; + create_task(); + create_task_priority = 4; + mutex_holder = create_task(); + /* Expectations */ + /* API Call */ + ret_prio_inherit = xTaskPriorityInherit( mutex_holder ); + /* Validations */ + TEST_ASSERT_FALSE( ret_prio_inherit ); +} + +void test_xTaskPriorityInherit_success_base_less( void ) +{ + BaseType_t ret_prio_inherit; + TaskHandle_t mutex_holder; + + /* Setup */ + create_task_priority = 4; + mutex_holder = create_task(); + block_task( mutex_holder ); + + create_task_priority = 3; + create_task(); + mutex_holder->uxBasePriority = 2; + /* Expectations */ + /* API Call */ + ret_prio_inherit = xTaskPriorityInherit( mutex_holder ); + /* Validations */ + TEST_ASSERT_TRUE( ret_prio_inherit ); +} + +void test_xTaskPriorityInherit_success( void ) +{ + BaseType_t ret_prio_inherit; + TaskHandle_t task_handle; + TaskHandle_t mutex_holder; + + /* Setup */ + create_task_priority = 3; + mutex_holder = create_task(); + create_task_priority = 4; + task_handle = create_task(); + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, task_handle ); + /* Expectations */ + listGET_LIST_ITEM_VALUE_ExpectAndReturn( &mutex_holder->xEventListItem, 0 ); + listSET_LIST_ITEM_VALUE_Expect( &mutex_holder->xEventListItem, + configMAX_PRIORITIES - task_handle->uxPriority ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ mutex_holder->uxPriority ], + &mutex_holder->xStateListItem, pdFALSE ); + /* API Call */ + ret_prio_inherit = xTaskPriorityInherit( mutex_holder ); + /* Validations */ + TEST_ASSERT_TRUE( ret_prio_inherit ); +} + +void test_xTaskPriorityInherit_success2( void ) +{ + BaseType_t ret_prio_inherit; + TaskHandle_t task_handle; + TaskHandle_t mutex_holder; + BaseType_t ready_prio; + + /* Setup */ + create_task_priority = 3; + mutex_holder = create_task(); + create_task_priority = 4; + task_handle = create_task(); + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, task_handle ); + ready_prio = uxTopReadyPriority; + /* Expectations */ + listGET_LIST_ITEM_VALUE_ExpectAndReturn( &mutex_holder->xEventListItem, 0 ); + listSET_LIST_ITEM_VALUE_Expect( &mutex_holder->xEventListItem, + configMAX_PRIORITIES - task_handle->uxPriority ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ mutex_holder->uxPriority ], + &mutex_holder->xStateListItem, pdTRUE ); + uxListRemove_ExpectAndReturn( &mutex_holder->xStateListItem, 0 ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ mutex_holder->uxPriority ], + &mutex_holder->xStateListItem ); + /* API Call */ + ret_prio_inherit = xTaskPriorityInherit( mutex_holder ); + /* Validations */ + TEST_ASSERT_TRUE( ret_prio_inherit ); + TEST_ASSERT_NOT_EQUAL( uxTopReadyPriority, ready_prio ); +} + +void test_xTaskPriorityInherit_success3( void ) +{ + BaseType_t ret_prio_inherit; + TaskHandle_t task_handle; + TaskHandle_t mutex_holder; + BaseType_t ready_prio; + + /* Setup */ + create_task_priority = 3; + mutex_holder = create_task(); + create_task_priority = 4; + task_handle = create_task(); + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, task_handle ); + ready_prio = uxTopReadyPriority; + /* Expectations */ + listGET_LIST_ITEM_VALUE_ExpectAndReturn( &mutex_holder->xEventListItem, 0 ); + listSET_LIST_ITEM_VALUE_Expect( &mutex_holder->xEventListItem, + configMAX_PRIORITIES - task_handle->uxPriority ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ mutex_holder->uxPriority ], + &mutex_holder->xStateListItem, pdTRUE ); + uxListRemove_ExpectAndReturn( &mutex_holder->xStateListItem, 1 ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ mutex_holder->uxPriority ], + &mutex_holder->xStateListItem ); + /* API Call */ + ret_prio_inherit = xTaskPriorityInherit( mutex_holder ); + /* Validations */ + TEST_ASSERT_TRUE( ret_prio_inherit ); + TEST_ASSERT_EQUAL( uxTopReadyPriority, ready_prio ); +} + +void test_xTaskPriorityDisinherit_fail_null_task( void ) +{ + BaseType_t ret_prio_disinherit; + + /* API Call */ + ret_prio_disinherit = xTaskPriorityDisinherit( NULL ); + /* Validations */ + TEST_ASSERT_FALSE( ret_prio_disinherit ); +} + +void test_xTaskPriorityDisinherit_success_base_eq_current_priority( void ) +{ + BaseType_t ret_prio_disinherit; + TaskHandle_t mutex_holder; + + /* Setup */ + mutex_holder = create_task(); + mutex_holder->uxMutexesHeld = 1; + /* Expectations */ + /* API Call */ + ret_prio_disinherit = xTaskPriorityDisinherit( mutex_holder ); + /* Validations */ + TEST_ASSERT_FALSE( ret_prio_disinherit ); +} + +void test_xTaskPriorityDisinherit_success_base_ne_current_priority( void ) +{ + BaseType_t ret_prio_disinherit; + TaskHandle_t mutex_holder; + BaseType_t ready_prio; + + /* Setup */ + create_task_priority = 4; + mutex_holder = create_task(); + mutex_holder->uxMutexesHeld = 1; + mutex_holder->uxPriority = 5; + uxTopReadyPriority |= ( 1 << 5 ); + ready_prio = uxTopReadyPriority; + /* Expectations */ + uxListRemove_ExpectAndReturn( &mutex_holder->xStateListItem, 0 ); + listSET_LIST_ITEM_VALUE_Expect( &mutex_holder->xEventListItem, + configMAX_PRIORITIES - mutex_holder->uxBasePriority ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ mutex_holder->uxPriority ], + &mutex_holder->xStateListItem ); + /* API Call */ + ret_prio_disinherit = xTaskPriorityDisinherit( mutex_holder ); + /* Validations */ + TEST_ASSERT_TRUE( ret_prio_disinherit ); + TEST_ASSERT_EQUAL( mutex_holder->uxBasePriority, mutex_holder->uxPriority ); + TEST_ASSERT_NOT_EQUAL( uxTopReadyPriority, ready_prio ); +} + +void test_xTaskPriorityDisinherit_success_base_ne_current_priority2( void ) +{ + BaseType_t ret_prio_disinherit; + TaskHandle_t mutex_holder; + BaseType_t ready_prio; + + /* Setup */ + create_task_priority = 4; + mutex_holder = create_task(); + mutex_holder->uxMutexesHeld = 1; + mutex_holder->uxPriority = 5; + uxTopReadyPriority |= ( 1 << 5 ); + ready_prio = uxTopReadyPriority; + /* Expectations */ + uxListRemove_ExpectAndReturn( &mutex_holder->xStateListItem, 1 ); + listSET_LIST_ITEM_VALUE_Expect( &mutex_holder->xEventListItem, + configMAX_PRIORITIES - mutex_holder->uxBasePriority ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ mutex_holder->uxPriority ], + &mutex_holder->xStateListItem ); + /* API Call */ + ret_prio_disinherit = xTaskPriorityDisinherit( mutex_holder ); + /* Validations */ + TEST_ASSERT_TRUE( ret_prio_disinherit ); + TEST_ASSERT_EQUAL( mutex_holder->uxBasePriority, mutex_holder->uxPriority ); + TEST_ASSERT_EQUAL( uxTopReadyPriority, ready_prio ); +} + +void test_xTaskPriorityDisinherit_success_mutex_held_gt_1( void ) +{ + BaseType_t ret_prio_disinherit; + TaskHandle_t mutex_holder; + + /* Setup */ + create_task_priority = 4; + mutex_holder = create_task(); + mutex_holder->uxMutexesHeld = 2; + mutex_holder->uxPriority = 5; + /* Expectations */ + /* API Call */ + ret_prio_disinherit = xTaskPriorityDisinherit( mutex_holder ); + /* Validations */ + TEST_ASSERT_FALSE( ret_prio_disinherit ); +} + +void test_pvTaskIncrementMutexHeldCount_success( void ) +{ + TaskHandle_t task_handle; + TaskHandle_t ret_task_handle; + + task_handle = create_task(); + ret_task_handle = pvTaskIncrementMutexHeldCount(); + TEST_ASSERT_EQUAL_PTR( task_handle, ret_task_handle ); + TEST_ASSERT_EQUAL( 1, task_handle->uxMutexesHeld ); +} + +void test_pvTaskIncrementMutexHeldCount_fail_null_current_tcb( void ) +{ + TaskHandle_t ret_task_handle; + + ret_task_handle = pvTaskIncrementMutexHeldCount(); + TEST_ASSERT_EQUAL( NULL, ret_task_handle ); +} + +void test_vTaskPriorityDisinheritAfterTimeout_fail_null_handle() +{ + /* Setup */ + /* Expectations */ + /* API Call */ + vTaskPriorityDisinheritAfterTimeout( NULL, + 2 ); + /* Validations */ +} + +void test_vTaskPriorityDisinheritAfterTimeout_success() +{ + TaskHandle_t mutex_holder; + + /* Setup */ + create_task_priority = 4; + mutex_holder = create_task(); + mutex_holder->uxMutexesHeld = 1; + /* Expectations */ + /* API Call */ + vTaskPriorityDisinheritAfterTimeout( mutex_holder, + create_task_priority - 1 ); + /* Validations */ + TEST_ASSERT_EQUAL( create_task_priority, mutex_holder->uxPriority ); + TEST_ASSERT_EQUAL( create_task_priority, mutex_holder->uxBasePriority ); +} + +void test_vTaskPriorityDisinheritAfterTimeout_success2() +{ + TaskHandle_t mutex_holder; + + /* Setup */ + create_task_priority = 4; + mutex_holder = create_task(); + mutex_holder->uxMutexesHeld = 1; + /* Expectations */ + /* API Call */ + vTaskPriorityDisinheritAfterTimeout( mutex_holder, + create_task_priority ); + /* Validations */ + TEST_ASSERT_EQUAL( create_task_priority, mutex_holder->uxPriority ); + TEST_ASSERT_EQUAL( create_task_priority, mutex_holder->uxBasePriority ); +} + +void test_vTaskPriorityDisinheritAfterTimeout_success3() +{ + TaskHandle_t mutex_holder; + + /* Setup */ + create_task_priority = 4; + mutex_holder = create_task(); + mutex_holder->uxMutexesHeld = 2; + /* Expectations */ + /* API Call */ + vTaskPriorityDisinheritAfterTimeout( mutex_holder, + create_task_priority + 2 ); + /* Validations */ + TEST_ASSERT_EQUAL( create_task_priority, mutex_holder->uxPriority ); + TEST_ASSERT_EQUAL( create_task_priority, mutex_holder->uxBasePriority ); +} + +void test_vTaskPriorityDisinheritAfterTimeout_success4() +{ + TaskHandle_t mutex_holder; + + /* Setup */ + create_task_priority = 4; + mutex_holder = create_task(); + mutex_holder->uxMutexesHeld = 1; + /* Expectations */ + listGET_LIST_ITEM_VALUE_ExpectAndReturn( &mutex_holder->xEventListItem, 0x80000000UL ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ mutex_holder->uxPriority ], + &mutex_holder->xStateListItem, + pdFALSE ); + /* API Call */ + vTaskPriorityDisinheritAfterTimeout( mutex_holder, + create_task_priority + 2 ); + /* Validations */ + TEST_ASSERT_EQUAL( create_task_priority + 2, mutex_holder->uxPriority ); + TEST_ASSERT_EQUAL( create_task_priority, mutex_holder->uxBasePriority ); +} + +void test_vTaskPriorityDisinheritAfterTimeout_success5() +{ + TaskHandle_t mutex_holder; + + /* Setup */ + create_task_priority = 4; + mutex_holder = create_task(); + mutex_holder->uxMutexesHeld = 1; + mutex_holder->uxPriority = 6; + /* Expectations */ + listGET_LIST_ITEM_VALUE_ExpectAndReturn( &mutex_holder->xEventListItem, 0 ); + listSET_LIST_ITEM_VALUE_Expect( &mutex_holder->xEventListItem, 0 ); + listSET_LIST_ITEM_VALUE_IgnoreArg_itemValue(); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ mutex_holder->uxPriority ], + &mutex_holder->xStateListItem, + pdTRUE ); + uxListRemove_ExpectAndReturn( &mutex_holder->xStateListItem, 1 ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ mutex_holder->uxPriority ], + &mutex_holder->xStateListItem ); + /* API Call */ + vTaskPriorityDisinheritAfterTimeout( mutex_holder, + create_task_priority - 2 ); + /* Validations */ + TEST_ASSERT_EQUAL( create_task_priority, mutex_holder->uxPriority ); + TEST_ASSERT_EQUAL( create_task_priority, mutex_holder->uxBasePriority ); +} + +void test_vTaskPriorityDisinheritAfterTimeout_success6() +{ + TaskHandle_t mutex_holder; + + /* Setup */ + create_task_priority = 4; + mutex_holder = create_task(); + mutex_holder->uxMutexesHeld = 1; + /* Expectations */ + listGET_LIST_ITEM_VALUE_ExpectAndReturn( &mutex_holder->xEventListItem, 0 ); + listSET_LIST_ITEM_VALUE_Expect( &mutex_holder->xEventListItem, 0 ); + listSET_LIST_ITEM_VALUE_IgnoreArg_itemValue(); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ mutex_holder->uxPriority ], + &mutex_holder->xStateListItem, + pdTRUE ); + uxListRemove_ExpectAndReturn( &mutex_holder->xStateListItem, 0 ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ mutex_holder->uxPriority ], + &mutex_holder->xStateListItem ); + /* API Call */ + vTaskPriorityDisinheritAfterTimeout( mutex_holder, + create_task_priority + 2 ); + /* Validations */ + TEST_ASSERT_EQUAL( create_task_priority + 2, mutex_holder->uxPriority ); +} + +/* end testing configUSE_MUTEXES == 1 */ + +/* ---------------- testing portCRITICAL_NESTING_IN_TCB --------------------- */ + +/* --------------- end testing portCRITICAL_NESTING_IN_TCB ------------------ */ + +void test_uxTaskResetEventItemValue( void ) +{ + TaskHandle_t task_handle; + TickType_t ret_task_reset; + + /* Setup */ + task_handle = create_task(); + /* Expectations */ + listGET_LIST_ITEM_VALUE_ExpectAndReturn( &task_handle->xEventListItem, 1 ); + listSET_LIST_ITEM_VALUE_Expect( &task_handle->xEventListItem, + configMAX_PRIORITIES - task_handle->uxPriority ); + /* API Call */ + ret_task_reset = uxTaskResetEventItemValue(); + /* Validations */ + TEST_ASSERT_EQUAL( 1, ret_task_reset ); +} + +/* ---------- testing configUSE_TASK_NOTIFICATIONS --------------- */ + +/* called from port task yield, to simulate that another task ran and received + * the notification */ +static void notif_received() +{ + ptcb->ucNotifyState[ 0 ] = 2; /* taskNOTIFICATION_RECEIVED */ +} + +void test_ulTaskGenericNotifyTake_sucess( void ) +{ + TaskHandle_t task_handle; + UBaseType_t uxIndexToWait = 0; + uint32_t ret_gen_notify_take; + + /* Setup */ + task_handle = create_task(); + task_handle->ulNotifiedValue[ uxIndexToWait ] = 0; + /* Expectations */ + /* API Call */ + ret_gen_notify_take = ulTaskGenericNotifyTake( uxIndexToWait, + pdFALSE, + 0 ); + /* Validations */ + TEST_ASSERT_EQUAL( 0, ret_gen_notify_take ); + TEST_ASSERT_EQUAL( 0, task_handle->ucNotifyState[ uxIndexToWait ] ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_ulTaskGenericNotifyTake_sucess2( void ) +{ + TaskHandle_t task_handle; + UBaseType_t uxIndexToWait = 0; + uint32_t ret_gen_notify_take; + + /* Setup */ + task_handle = create_task(); + task_handle->ulNotifiedValue[ uxIndexToWait ] = 2; + /* Expectations */ + /* API Call */ + ret_gen_notify_take = ulTaskGenericNotifyTake( uxIndexToWait, + pdFALSE, + 0 ); + /* Validations */ + TEST_ASSERT_EQUAL( 2, ret_gen_notify_take ); + TEST_ASSERT_EQUAL( 0, task_handle->ucNotifyState[ uxIndexToWait ] ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_ulTaskGenericNotifyTake_sucess_clear_count( void ) +{ + TaskHandle_t task_handle; + UBaseType_t uxIndexToWait = 0; + uint32_t ret_gen_notify_take; + + /* Setup */ + task_handle = create_task(); + task_handle->ulNotifiedValue[ uxIndexToWait ] = 5; + /* Expectations */ + /* API Call */ + ret_gen_notify_take = ulTaskGenericNotifyTake( uxIndexToWait, + pdTRUE, + 0 ); + /* Validations */ + TEST_ASSERT_EQUAL( 5, ret_gen_notify_take ); + TEST_ASSERT_EQUAL( 0, task_handle->ucNotifyState[ uxIndexToWait ] ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_ulTaskGenericNotifyTake_sucess_yield( void ) +{ + TaskHandle_t task_handle; + UBaseType_t uxIndexToWait = 0; + uint32_t ret_gen_notify_take; + + /* Setup */ + task_handle = create_task(); + task_handle->ulNotifiedValue[ uxIndexToWait ] = 0; + ptcb = task_handle; + /* Expectations */ + /* prvAddCurrentTaskToDelayedList */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 1 ); + listSET_LIST_ITEM_VALUE_Expect( &ptcb->xStateListItem, xTickCount + 9 ); + vListInsert_Expect( pxDelayedTaskList, &ptcb->xStateListItem ); + /* API Call */ + ret_gen_notify_take = ulTaskGenericNotifyTake( uxIndexToWait, + pdFALSE, + 9 ); + /* Validations */ + TEST_ASSERT_EQUAL( 0, ret_gen_notify_take ); + TEST_ASSERT_EQUAL( 0, task_handle->ucNotifyState[ uxIndexToWait ] ); + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +void test_xTaskGenericNotify_success( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 45; + eNotifyAction eAction = eSetBits; + uint32_t pulPreviousNotificationValue; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 32; + ptcb = task_to_notify; + /* Expectations */ + /* API Call */ + ret_task_notify = xTaskGenericNotify( task_to_notify, + uxIndexToNotify, + ulValue, + eAction, + &pulPreviousNotificationValue ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, ret_task_notify ); + TEST_ASSERT_EQUAL( 32, pulPreviousNotificationValue ); +} + + +void test_xTaskGenericNotify_success_null_pull( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 2; + eNotifyAction eAction = eSetBits; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 1; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + /* Expectations */ + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + /* API Call */ + ret_task_notify = xTaskGenericNotify( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, ret_task_notify ); + TEST_ASSERT_EQUAL( 1 | 2, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); +} + +void test_xTaskGenericNotify_success_eIncrement( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + eNotifyAction eAction = eIncrement; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 10; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + /* Expectations */ + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + /* API Call */ + ret_task_notify = xTaskGenericNotify( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, ret_task_notify ); + TEST_ASSERT_EQUAL( 11, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); +} + +void test_xTaskGenericNotify_success_eSetValueWithOverwrite( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + eNotifyAction eAction = eSetValueWithOverwrite; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 1; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + /* Expectations */ + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + /* API Call */ + ret_task_notify = xTaskGenericNotify( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, ret_task_notify ); + TEST_ASSERT_EQUAL( 5, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); +} + +void test_xTaskGenericNotify_success_eSetValueWithoutOverwrite( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + eNotifyAction eAction = eSetValueWithoutOverwrite; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 1; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + /* Expectations */ + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + /* API Call */ + ret_task_notify = xTaskGenericNotify( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, ret_task_notify ); + TEST_ASSERT_EQUAL( 5, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); +} + +void test_xTaskGenericNotify_success_eSetValueWithoutOverwrite_not_rec( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + eNotifyAction eAction = eSetValueWithoutOverwrite; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 11; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; + ptcb = task_to_notify; + /* Expectations */ + /* API Call */ + ret_task_notify = xTaskGenericNotify( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL ); + /* Validations */ + TEST_ASSERT_EQUAL( pdFAIL, ret_task_notify ); + TEST_ASSERT_EQUAL( 11, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); +} + +void test_xTaskGenericNotify_success_eNoAction( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + eNotifyAction eAction = eNoAction; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 15; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; + ptcb = task_to_notify; + /* Expectations */ + /* API Call */ + ret_task_notify = xTaskGenericNotify( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL ); + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_task_notify ); + TEST_ASSERT_EQUAL( 15, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); +} + +void test_xTaskGenericNotify_success_default( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + TaskHandle_t task_handle_current; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + eNotifyAction eAction = 10; + + /* Setup */ + create_task_priority = 7; + task_to_notify = create_task(); + block_task( task_to_notify ); + create_task_priority = 3; + task_handle_current = create_task(); /* current task */ + TEST_ASSERT_EQUAL_PTR( task_handle_current, pxCurrentTCB ); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 15; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + /* Expectations */ + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* prvResetNextTaskUnblockTime */ + listLIST_IS_EMPTY_ExpectAndReturn( pxDelayedTaskList, pdTRUE ); + /* API Call */ + ret_task_notify = xTaskGenericNotify( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL ); + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_task_notify ); + TEST_ASSERT_EQUAL( 15, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +void test_xTaskGenericNotify_success_ISR( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 45; + eNotifyAction eAction = eSetBits; + uint32_t pulPreviousNotificationValue; + BaseType_t pxHigherPriorityTaskWoken = 0; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 32; + ptcb = task_to_notify; + /* Expectations */ + /* API Call */ + ret_task_notify = xTaskGenericNotifyFromISR( task_to_notify, + uxIndexToNotify, + ulValue, + eAction, + &pulPreviousNotificationValue, + &pxHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, ret_task_notify ); + TEST_ASSERT_EQUAL( 32, pulPreviousNotificationValue ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + + +void test_xTaskGenericNotify_success_null_pull_ISR( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 2; + BaseType_t pxHigherPriorityTaskWoken = 0; + eNotifyAction eAction = eSetBits; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 1; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + vTaskSuspendAll(); + /* Expectations */ + listINSERT_END_Expect( &xPendingReadyList, &ptcb->xEventListItem ); + /* API Call */ + ret_task_notify = xTaskGenericNotifyFromISR( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL, + &pxHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, ret_task_notify ); + TEST_ASSERT_EQUAL( 1 | 2, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_xTaskGenericNotify_success_eIncrement_ISR( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + BaseType_t pxHigherPriorityTaskWoken = 0; + eNotifyAction eAction = eIncrement; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 10; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + /* Expectations */ + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* API Call */ + ret_task_notify = xTaskGenericNotifyFromISR( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL, + &pxHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, ret_task_notify ); + TEST_ASSERT_EQUAL( 11, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_xTaskGenericNotify_success_eSetValueWithOverwrite_ISR( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + BaseType_t pxHigherPriorityTaskWoken = 0; + eNotifyAction eAction = eSetValueWithOverwrite; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 1; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + /* Expectations */ + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* API Call */ + ret_task_notify = xTaskGenericNotifyFromISR( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL, + &pxHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, ret_task_notify ); + TEST_ASSERT_EQUAL( 5, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_xTaskGenericNotify_success_eSetValueWithoutOverwrite_ISR( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + BaseType_t pxHigherPriorityTaskWoken = 0; + eNotifyAction eAction = eSetValueWithoutOverwrite; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 1; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + /* Expectations */ + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* API Call */ + ret_task_notify = xTaskGenericNotifyFromISR( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL, + &pxHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, ret_task_notify ); + TEST_ASSERT_EQUAL( 5, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); + TEST_ASSERT_FALSE( pxHigherPriorityTaskWoken ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_xTaskGenericNotify_success_eSetValueWithoutOverwrite_not_rec_ISR( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + BaseType_t pxHigherPriorityTaskWoken = 0; + eNotifyAction eAction = eSetValueWithoutOverwrite; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 11; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; + ptcb = task_to_notify; + /* Expectations */ + /* API Call */ + ret_task_notify = xTaskGenericNotifyFromISR( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL, + &pxHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_EQUAL( pdFAIL, ret_task_notify ); + TEST_ASSERT_EQUAL( 11, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); + TEST_ASSERT_FALSE( pxHigherPriorityTaskWoken ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_xTaskGenericNotify_success_eNoAction_ISR( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + BaseType_t pxHigherPriorityTaskWoken = 0; + eNotifyAction eAction = eNoAction; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 15; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskNOTIFICATION_RECEIVED; + ptcb = task_to_notify; + /* Expectations */ + /* API Call */ + ret_task_notify = xTaskGenericNotifyFromISR( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL, + &pxHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_task_notify ); + TEST_ASSERT_EQUAL( 15, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); + TEST_ASSERT_FALSE( pxHigherPriorityTaskWoken ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_xTaskGenericNotify_success_default_ISR( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + TaskHandle_t task_handle_current; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + BaseType_t pxHigherPriorityTaskWoken = pdFALSE; + + eNotifyAction eAction = 10; + + /* Setup */ + create_task_priority = 7; + task_to_notify = create_task(); + block_task( task_to_notify ); + create_task_priority = 3; + task_handle_current = create_task(); /* current task */ + TEST_ASSERT_EQUAL_PTR( task_handle_current, pxCurrentTCB ); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 15; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + /* Expectations */ + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* API Call */ + ret_task_notify = xTaskGenericNotifyFromISR( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL, + &pxHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_task_notify ); + TEST_ASSERT_EQUAL( 15, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); + TEST_ASSERT_TRUE( pxHigherPriorityTaskWoken ); + TEST_ASSERT_TRUE( xYieldPending ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_xTaskGenericNotify_success_default_ISR_task_woken_null( void ) +{ + BaseType_t ret_task_notify; + TaskHandle_t task_to_notify; + TaskHandle_t task_handle_current; + UBaseType_t uxIndexToNotify = 2; + uint32_t ulValue = 5; + + eNotifyAction eAction = 10; + + /* Setup */ + create_task_priority = 7; + task_to_notify = create_task(); + block_task( task_to_notify ); + create_task_priority = 3; + task_handle_current = create_task(); /* current task */ + TEST_ASSERT_EQUAL_PTR( task_handle_current, pxCurrentTCB ); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 15; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + /* Expectations */ + listREMOVE_ITEM_Expect( &( ptcb->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &pxReadyTasksLists[ ptcb->uxPriority ], + &ptcb->xStateListItem ); + /* API Call */ + ret_task_notify = xTaskGenericNotifyFromISR( ptcb, + uxIndexToNotify, + ulValue, + eAction, + NULL, + NULL ); + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_task_notify ); + TEST_ASSERT_EQUAL( 15, ptcb->ulNotifiedValue[ uxIndexToNotify ] ); + TEST_ASSERT_EQUAL( 2, ptcb->ucNotifyState[ uxIndexToNotify ] ); + TEST_ASSERT_TRUE( xYieldPending ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + + +void test_xTaskGenericNotifyWait_success_notif_recieved( void ) +{ + UBaseType_t uxIndexToWait = 0; + uint32_t ulBitsToClearOnEntry = 0; + uint32_t ulBitsToClearOnExit = 0; + uint32_t pullNotificationValue; + TickType_t xTicksToWait = 20; + BaseType_t ret; + + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = task_handle; + ptcb->ucNotifyState[ uxIndexToWait ] = 2; /* taskNOTIFICATION_RECEIVED */ + ptcb->ulNotifiedValue[ uxIndexToWait ] = 5; + + ret = xTaskGenericNotifyWait( uxIndexToWait, + ulBitsToClearOnEntry, + ulBitsToClearOnExit, + &pullNotificationValue, + xTicksToWait ); + TEST_ASSERT_EQUAL( pdTRUE, ret ); + TEST_ASSERT_EQUAL( 5, pullNotificationValue ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_xTaskGenericNotifyWait_success_notif_not_recieved( void ) +{ + UBaseType_t uxIndexToWait = 0; + uint32_t ulBitsToClearOnEntry = 0; + uint32_t ulBitsToClearOnExit = 0; + uint32_t pullNotificationValue; + TickType_t xTicksToWait = 20; + BaseType_t ret; + + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = task_handle; + ptcb->ucNotifyState[ uxIndexToWait ] = 1; /* taskWAITING_NOTIFICATION */ + ptcb->ulNotifiedValue[ uxIndexToWait ] = 5; + /* Expectations */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 0 ); + listSET_LIST_ITEM_VALUE_Expect( &ptcb->xStateListItem, + xTickCount + xTicksToWait ); + vListInsert_Expect( pxOverflowDelayedTaskList, &ptcb->xStateListItem ); + + /* API Call */ + ret = xTaskGenericNotifyWait( uxIndexToWait, + ulBitsToClearOnEntry, + ulBitsToClearOnExit, + &pullNotificationValue, + xTicksToWait ); + /* Validations */ + TEST_ASSERT_EQUAL( pdFALSE, ret ); + TEST_ASSERT_EQUAL( 5, pullNotificationValue ); + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +void test_xTaskGenericNotifyWait_success_notif_not_recieved_no_wait( void ) +{ + UBaseType_t uxIndexToWait = 0; + uint32_t ulBitsToClearOnEntry = 0; + uint32_t ulBitsToClearOnExit = 0; + uint32_t pullNotificationValue; + TickType_t xTicksToWait = 0; + BaseType_t ret; + + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = task_handle; + ptcb->ucNotifyState[ uxIndexToWait ] = 1; /* taskWAITING_NOTIFICATION */ + ptcb->ulNotifiedValue[ uxIndexToWait ] = 5; + /* Expectations */ + + /* API Call */ + ret = xTaskGenericNotifyWait( uxIndexToWait, + ulBitsToClearOnEntry, + ulBitsToClearOnExit, + &pullNotificationValue, + xTicksToWait ); + /* Validations */ + TEST_ASSERT_EQUAL( pdFALSE, ret ); + TEST_ASSERT_EQUAL( 5, pullNotificationValue ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_xTaskGenericNotifyWait_success_notif_not_recieved_pull_null( void ) +{ + UBaseType_t uxIndexToWait = 0; + uint32_t ulBitsToClearOnEntry = 0; + uint32_t ulBitsToClearOnExit = 0; + TickType_t xTicksToWait = 0; + BaseType_t ret; + + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = task_handle; + ptcb->ucNotifyState[ uxIndexToWait ] = 1; /* taskWAITING_NOTIFICATION */ + ptcb->ulNotifiedValue[ uxIndexToWait ] = 5; + /* Expectations */ + + /* API Call */ + ret = xTaskGenericNotifyWait( uxIndexToWait, + ulBitsToClearOnEntry, + ulBitsToClearOnExit, + NULL, + xTicksToWait ); + /* Validations */ + TEST_ASSERT_FALSE( ret ); + ASSERT_PORT_YIELD_WITHIN_API_NOT_CALLED(); +} + +void test_xTaskGenericNotifyWait_success_notif_recieved_while_waiting( void ) +{ + UBaseType_t uxIndexToWait = 0; + uint32_t ulBitsToClearOnEntry = 0; + uint32_t ulBitsToClearOnExit = 0; + uint32_t pullNotificationValue; + TickType_t xTicksToWait = 20; + BaseType_t ret; + + TaskHandle_t task_handle; + + task_handle = create_task(); + ptcb = task_handle; + ptcb->ucNotifyState[ uxIndexToWait ] = 1; /* taskWAITING_NOTIFICATION */ + ptcb->ulNotifiedValue[ uxIndexToWait ] = 5; + /* Expectations */ + uxListRemove_ExpectAndReturn( &ptcb->xStateListItem, 0 ); + listSET_LIST_ITEM_VALUE_Expect( &ptcb->xStateListItem, + xTickCount + xTicksToWait ); + vListInsert_Expect( pxOverflowDelayedTaskList, &ptcb->xStateListItem ); + py_operation = ¬if_received; + + /* API Call */ + ret = xTaskGenericNotifyWait( uxIndexToWait, + ulBitsToClearOnEntry, + ulBitsToClearOnExit, + &pullNotificationValue, + xTicksToWait ); + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret ); + TEST_ASSERT_EQUAL( 5, pullNotificationValue ); + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +void test_vTaskGenericNotifyGiveFromISR_success( void ) +{ + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 1; + BaseType_t pxHigherPriorityTaskWoken = pdFALSE; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + /* Expectations */ + /*uxListRemove_ExpectAndReturn( &task_to_notify->xStateListItem, pdTRUE ); */ + listREMOVE_ITEM_Expect( &( task_to_notify->xStateListItem ) ); + /* prvAddTaskToReadyList */ + listINSERT_END_Expect( &xPendingReadyList, &task_to_notify->xEventListItem ); + /* API Call */ + vTaskGenericNotifyGiveFromISR( task_to_notify, + uxIndexToNotify, + &pxHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_FALSE( xYieldPending ); + TEST_ASSERT_FALSE( pxHigherPriorityTaskWoken ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_vTaskGenericNotifyGiveFromISR_success_scheduler_suspended( void ) +{ + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 1; + BaseType_t pxHigherPriorityTaskWoken = pdFALSE; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + vTaskSuspendAll(); + /* Expectations */ + listINSERT_END_Expect( &xPendingReadyList, &task_to_notify->xEventListItem ); + + /* API Call */ + vTaskGenericNotifyGiveFromISR( task_to_notify, + uxIndexToNotify, + &pxHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_FALSE( xYieldPending ); + TEST_ASSERT_FALSE( pxHigherPriorityTaskWoken ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_vTaskGenericNotifyGiveFromISR_success_yield_pending( void ) +{ + TaskHandle_t task_to_notify; + TaskHandle_t task_handle_current; + UBaseType_t uxIndexToNotify = 1; + BaseType_t pxHigherPriorityTaskWoken = pdFALSE; + + /* Setup */ + create_task_priority = 7; + task_to_notify = create_task(); + block_task( task_to_notify ); + create_task_priority = 3; + task_handle_current = create_task(); /* current task */ + TEST_ASSERT_EQUAL_PTR( task_handle_current, pxCurrentTCB ); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 15; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + vTaskSuspendAll(); + /* Expectations */ + listINSERT_END_Expect( &xPendingReadyList, &task_to_notify->xEventListItem ); + + /* API Call */ + vTaskGenericNotifyGiveFromISR( task_to_notify, + uxIndexToNotify, + &pxHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_TRUE( xYieldPending ); + TEST_ASSERT_TRUE( pxHigherPriorityTaskWoken ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_vTaskGenericNotifyGiveFromISR_success_null_higherpriority_task( void ) +{ + TaskHandle_t task_to_notify; + TaskHandle_t task_handle_current; + UBaseType_t uxIndexToNotify = 1; + + /* Setup */ + create_task_priority = 7; + task_to_notify = create_task(); + block_task( task_to_notify ); + create_task_priority = 3; + task_handle_current = create_task(); /* current task */ + TEST_ASSERT_EQUAL_PTR( task_handle_current, pxCurrentTCB ); + task_to_notify->ulNotifiedValue[ uxIndexToNotify ] = 15; + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskWAITING_NOTIFICATION; + ptcb = task_to_notify; + vTaskSuspendAll(); + /* Expectations */ + listINSERT_END_Expect( &xPendingReadyList, &task_to_notify->xEventListItem ); + + /* API Call */ + vTaskGenericNotifyGiveFromISR( task_to_notify, + uxIndexToNotify, + NULL ); + /* Validations */ + TEST_ASSERT_TRUE( xYieldPending ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_vTaskGenericNotifyGiveFromISR_success_not_waiting( void ) +{ + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToNotify = 1; + BaseType_t pxHigherPriorityTaskWoken = pdFALSE; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ucNotifyState[ uxIndexToNotify ] = taskNOT_WAITING_NOTIFICATION; + /* Expectations */ + + /* API Call */ + vTaskGenericNotifyGiveFromISR( task_to_notify, + uxIndexToNotify, + &pxHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_FALSE( xYieldPending ); + TEST_ASSERT_FALSE( pxHigherPriorityTaskWoken ); + ASSERT_PORT_CLEAR_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_PORT_SET_INTERRUPT_FROM_ISR_CALLED(); + ASSERT_INVALID_INTERRUPT_PRIORITY_CALLED(); +} + +void test_xTaskGenericNotifyStateClear_fail() +{ + BaseType_t ret_notify_state_clear; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToClear = 1; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ucNotifyState[ uxIndexToClear ] = taskNOT_WAITING_NOTIFICATION; + /* Expectations */ + /* API Call */ + ret_notify_state_clear = xTaskGenericNotifyStateClear( task_to_notify, + uxIndexToClear ); + /* Validations */ + TEST_ASSERT_EQUAL( pdFAIL, ret_notify_state_clear ); +} + +void test_xTaskGenericNotifyStateClear_fail_null_handler() +{ + BaseType_t ret_notify_state_clear; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToClear = 1; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ucNotifyState[ uxIndexToClear ] = taskNOT_WAITING_NOTIFICATION; + /* Expectations */ + /* API Call */ + ret_notify_state_clear = xTaskGenericNotifyStateClear( NULL, + uxIndexToClear ); + /* Validations */ + TEST_ASSERT_EQUAL( pdFAIL, ret_notify_state_clear ); +} + +void test_xTaskGenericNotifyStateClear_success() +{ + BaseType_t ret_notify_state_clear; + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToClear = 1; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ucNotifyState[ uxIndexToClear ] = taskNOTIFICATION_RECEIVED; + /* Expectations */ + /* API Call */ + ret_notify_state_clear = xTaskGenericNotifyStateClear( task_to_notify, + uxIndexToClear ); + /* Validations */ + TEST_ASSERT_EQUAL( pdPASS, ret_notify_state_clear ); + TEST_ASSERT_EQUAL( taskNOT_WAITING_NOTIFICATION, + task_to_notify->ucNotifyState[ uxIndexToClear ] ); +} + +void test_ulTaskGenericNotifyValueClear_success() +{ + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToClear = 1; + uint32_t ret_notify_clear; + uint32_t ulBitsToClear = 1; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToClear ] = 1; + /* Expectations */ + /* API Call */ + ret_notify_clear = ulTaskGenericNotifyValueClear( task_to_notify, + uxIndexToClear, + ulBitsToClear ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, ret_notify_clear ); + TEST_ASSERT_EQUAL( 0, task_to_notify->ulNotifiedValue[ uxIndexToClear ] ); +} + +void test_ulTaskGenericNotifyValueClear_success_null_handle() +{ + TaskHandle_t task_to_notify; + UBaseType_t uxIndexToClear = 1; + uint32_t ret_notify_clear; + uint32_t ulBitsToClear = 1; + + /* Setup */ + task_to_notify = create_task(); + task_to_notify->ulNotifiedValue[ uxIndexToClear ] = 3; + /* Expectations */ + /* API Call */ + ret_notify_clear = ulTaskGenericNotifyValueClear( NULL, + uxIndexToClear, + ulBitsToClear ); + /* Validations */ + TEST_ASSERT_EQUAL( 3, ret_notify_clear ); + TEST_ASSERT_EQUAL( 2, task_to_notify->ulNotifiedValue[ uxIndexToClear ] ); +} +/* ---------- end testing configUSE_TASK_NOTIFICATIONS --------------- */ diff --git a/FreeRTOS/Test/CMock/tasks/tasks_2_utest.c b/FreeRTOS/Test/CMock/tasks/tasks_2_utest.c new file mode 100644 index 0000000000..ecc130a835 --- /dev/null +++ b/FreeRTOS/Test/CMock/tasks/tasks_2_utest.c @@ -0,0 +1,758 @@ +/* + * FreeRTOS V202112.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 tasks_utest_2.c */ + +/* Tasks includes */ +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "task.h" + +#include "mock_list.h" +#include "mock_list_macros.h" +#include "mock_timers.h" +#include "mock_portable.h" + +/* Test includes. */ +#include "unity.h" +#include "global_vars.h" + +/* C runtime includes. */ +#include +#include +#include + + +/* =========================== EXTERN VARIABLES =========================== */ +extern TCB_t * volatile pxCurrentTCB; +extern List_t pxReadyTasksLists[ configMAX_PRIORITIES ]; +extern List_t xDelayedTaskList1; +extern List_t xDelayedTaskList2; +extern List_t * volatile pxDelayedTaskList; +extern List_t * volatile pxOverflowDelayedTaskList; +extern List_t xPendingReadyList; +/* INCLUDE_vTaskDelete */ +extern List_t xTasksWaitingTermination; +extern volatile UBaseType_t uxDeletedTasksWaitingCleanUp; +extern List_t xSuspendedTaskList; + +extern volatile UBaseType_t uxCurrentNumberOfTasks; +extern volatile TickType_t xTickCount; +extern volatile UBaseType_t uxTopReadyPriority; +extern volatile BaseType_t xSchedulerRunning; +extern volatile TickType_t xPendedTicks; +extern volatile BaseType_t xYieldPending; +extern volatile BaseType_t xNumOfOverflows; +extern UBaseType_t uxTaskNumber; +extern volatile TickType_t xNextTaskUnblockTime; +extern TaskHandle_t xIdleTaskHandle; +extern volatile UBaseType_t uxSchedulerSuspended; + + +/* =========================== GLOBAL VARIABLES =========================== */ +static StaticTask_t xIdleTaskTCB; +static StackType_t uxIdleTaskStack[ configMINIMAL_STACK_SIZE ]; + +static TCB_t * ptcb; +static StackType_t stack[ ( ( size_t ) 300 ) * sizeof( StackType_t ) ]; +static TCB_t tcb[ 10 ]; /* simulate up to 10 tasks: add more if needed */ +static bool getIddleTaskMemoryValid = false; +static uint32_t critical_section_counter = 0; +static bool is_first_task = true; +static uint32_t created_tasks = 0; +static uint32_t create_task_priority = 3; +static port_yield_operation py_operation; +static bool vTaskDeletePre_called = false; +static bool getIddleTaskMemory_called = false; +static bool vApplicationTickHook_called = false; +static bool port_yield_called = false; +static bool port_enable_interrupts_called = false; +static bool port_disable_interrupts_called = false; +static bool port_yield_within_api_called = false; +static bool port_setup_tcb_called = false; +static bool portClear_Interrupt_called = false; +static bool portSet_Interrupt_called = false; +static bool portClear_Interrupt_from_isr_called = false; +static bool portSet_Interrupt_from_isr_called = false; +static bool port_invalid_interrupt_called = false; +static bool vApplicationStackOverflowHook_called = false; +static bool vApplicationIdleHook_called = false; +static bool port_allocate_secure_context_called = false; +static bool port_assert_if_in_isr_called = false; +static bool vApplicationMallocFailedHook_called = false; + + +/* =========================== Static Functions =========================== */ +static void start_scheduler() +{ + vListInitialiseItem_ExpectAnyArgs(); + vListInitialiseItem_ExpectAnyArgs(); + /* set owner */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* set owner */ + + pxPortInitialiseStack_ExpectAnyArgsAndReturn( uxIdleTaskStack ); + + if( is_first_task ) + { + is_first_task = false; + + for( int i = ( UBaseType_t ) 0U; i < ( UBaseType_t ) configMAX_PRIORITIES; i++ ) + { + vListInitialise_ExpectAnyArgs(); + } + + /* Delayed Task List 1 */ + vListInitialise_ExpectAnyArgs(); + /* Delayed Task List 2 */ + vListInitialise_ExpectAnyArgs(); + /* Pending Ready List */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskDelete */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskSuspend */ + vListInitialise_ExpectAnyArgs(); + } + + listINSERT_END_ExpectAnyArgs(); + + xTimerCreateTimerTask_ExpectAndReturn( pdPASS ); + xPortStartScheduler_ExpectAndReturn( pdTRUE ); + getIddleTaskMemoryValid = true; + vTaskStartScheduler(); + ASSERT_GET_IDLE_TASK_MEMORY_CALLED(); + TEST_ASSERT_TRUE( xSchedulerRunning ); + TEST_ASSERT_EQUAL( configINITIAL_TICK_COUNT, xTickCount ); + TEST_ASSERT_EQUAL( portMAX_DELAY, xNextTaskUnblockTime ); +} +static TaskHandle_t create_task() +{ + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = { __FUNCTION__ }; + const uint32_t usStackDepth = 300; + void * const pvParameters = NULL; + UBaseType_t uxPriority = create_task_priority; + TaskHandle_t taskHandle; + BaseType_t ret; + + pvPortMalloc_ExpectAndReturn( sizeof( TCB_t ), &tcb[ created_tasks ] ); + pvPortMalloc_ExpectAndReturn( usStackDepth * sizeof( StackType_t ), stack ); + + vListInitialiseItem_Expect( &( tcb[ created_tasks ].xStateListItem ) ); + vListInitialiseItem_Expect( &( tcb[ created_tasks ].xEventListItem ) ); + /* TODO: expect set owner */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* TODO: expect set owner */ + + pxPortInitialiseStack_ExpectAnyArgsAndReturn( stack ); + + if( is_first_task ) + { + /* prvInitialiseTaskLists */ + for( int i = ( UBaseType_t ) 0U; i < ( UBaseType_t ) configMAX_PRIORITIES; i++ ) + { + vListInitialise_ExpectAnyArgs(); + } + + /* Delayed Task List 1 */ + vListInitialise_ExpectAnyArgs(); + /* Delayed Task List 2 */ + vListInitialise_ExpectAnyArgs(); + /* Pending Ready List */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskDelete */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskSuspend */ + vListInitialise_ExpectAnyArgs(); + is_first_task = false; + } + + /* prvAddTaskToReadyList */ + listINSERT_END_ExpectAnyArgs(); + ret = xTaskCreate( pxTaskCode, + pcName, + usStackDepth, + pvParameters, + uxPriority, + &taskHandle ); + TEST_ASSERT_EQUAL( pdPASS, ret ); + ASSERT_SETUP_TCB_CALLED(); + created_tasks++; + return taskHandle; +} +/* ============================ HOOK FUNCTIONS ============================ */ +static void dummy_operation() +{ + HOOK_DIAG(); +} + +void vFakePortAssertIfISR( void ) +{ + port_assert_if_in_isr_called = true; + HOOK_DIAG(); +} + +void port_allocate_secure_context( BaseType_t stackSize ) +{ + HOOK_DIAG(); + port_allocate_secure_context_called = true; +} + +void vApplicationIdleHook( void ) +{ + HOOK_DIAG(); + vApplicationIdleHook_called = true; +} + +void vApplicationMallocFailedHook( void ) +{ + vApplicationMallocFailedHook_called = true; + HOOK_DIAG(); +} + +void vApplicationGetIdleTaskMemory( StaticTask_t ** ppxIdleTaskTCBBuffer, + StackType_t ** ppxIdleTaskStackBuffer, + uint32_t * pulIdleTaskStackSize ) +{ + HOOK_DIAG(); + + if( getIddleTaskMemoryValid == true ) + { + /* Pass out a pointer to the StaticTask_t structure in which the Idle task's + * state will be stored. */ + *ppxIdleTaskTCBBuffer = &xIdleTaskTCB; + + /* Pass out the array that will be used as the Idle task's stack. */ + *ppxIdleTaskStackBuffer = uxIdleTaskStack; + + /* Pass out the size of the array pointed to by *ppxIdleTaskStackBuffer. + * Note that, as the array is necessarily of type StackType_t, + * configMINIMAL_STACK_SIZE is specified in words, not bytes. */ + *pulIdleTaskStackSize = configMINIMAL_STACK_SIZE; + } + else + { + *ppxIdleTaskTCBBuffer = NULL; + *ppxIdleTaskStackBuffer = NULL; + *pulIdleTaskStackSize = 0; + } + + getIddleTaskMemory_called = true; +} + +void vConfigureTimerForRunTimeStats( void ) +{ + HOOK_DIAG(); +} + +long unsigned int ulGetRunTimeCounterValue( void ) +{ + HOOK_DIAG(); + return 3; +} + +void vApplicationTickHook() +{ + HOOK_DIAG(); + vApplicationTickHook_called = true; +} + +void vPortCurrentTaskDying( void * pvTaskToDelete, + volatile BaseType_t * pxPendYield ) +{ + HOOK_DIAG(); + vTaskDeletePre_called = true; +} + +void vFakePortEnterCriticalSection( void ) +{ + HOOK_DIAG(); + critical_section_counter++; +} + +void vFakePortExitCriticalSection( void ) +{ + HOOK_DIAG(); + critical_section_counter--; +} + +void vFakePortYieldWithinAPI() +{ + HOOK_DIAG(); + port_yield_within_api_called = true; + py_operation(); +} + +void vFakePortYieldFromISR() +{ + HOOK_DIAG(); +} + +void vFakePortDisableInterrupts() +{ + port_disable_interrupts_called = true; + HOOK_DIAG(); +} + +void vFakePortEnableInterrupts() +{ + port_enable_interrupts_called = true; + HOOK_DIAG(); +} + +void vFakePortYield() +{ + HOOK_DIAG(); + port_yield_called = true; + py_operation(); +} + +void portSetupTCB_CB( void * tcb ) +{ + HOOK_DIAG(); + port_setup_tcb_called = true; +} + +void vFakePortClearInterruptMask( UBaseType_t bt ) +{ + HOOK_DIAG(); + portClear_Interrupt_called = true; +} + +UBaseType_t ulFakePortSetInterruptMask( void ) +{ + HOOK_DIAG(); + portSet_Interrupt_called = true; + return 1; +} + +void vFakePortClearInterruptMaskFromISR( UBaseType_t bt ) +{ + HOOK_DIAG(); + portClear_Interrupt_from_isr_called = true; +} + +UBaseType_t ulFakePortSetInterruptMaskFromISR( void ) +{ + HOOK_DIAG(); + portSet_Interrupt_from_isr_called = true; + return 1; +} + +void vFakePortAssertIfInterruptPriorityInvalid( void ) +{ + HOOK_DIAG(); + port_invalid_interrupt_called = true; +} + +void vApplicationStackOverflowHook( TaskHandle_t xTask, + char * stack ) +{ + HOOK_DIAG(); + vApplicationStackOverflowHook_called = true; +} + +/* ============================ Unity Fixtures ============================ */ +/*! called before each testcase */ +void setUp( void ) +{ + RESET_ALL_HOOKS(); + + pxCurrentTCB = NULL; + memset( &tcb, 0x00, sizeof( TCB_t ) ); + ptcb = NULL; + memset( &pxReadyTasksLists, 0x00, configMAX_PRIORITIES * sizeof( List_t ) ); + memset( &xDelayedTaskList1, 0x00, sizeof( List_t ) ); + memset( &xDelayedTaskList2, 0x00, sizeof( List_t ) ); + + /* + * pxDelayedTaskList = NULL; + * pxOverflowDelayedTaskList = NULL; + */ + memset( &xPendingReadyList, 0x00, sizeof( List_t ) ); + + memset( &xTasksWaitingTermination, 0x00, sizeof( List_t ) ); + uxDeletedTasksWaitingCleanUp = 0; + memset( &xSuspendedTaskList, 0x00, sizeof( List_t ) ); + + uxCurrentNumberOfTasks = ( UBaseType_t ) 0U; + xTickCount = ( TickType_t ) 500; /* configINITIAL_TICK_COUNT */ + uxTopReadyPriority = tskIDLE_PRIORITY; + xSchedulerRunning = pdFALSE; + xPendedTicks = ( TickType_t ) 0U; + xYieldPending = pdFALSE; + xNumOfOverflows = ( BaseType_t ) 0; + uxTaskNumber = ( UBaseType_t ) 0U; + xNextTaskUnblockTime = ( TickType_t ) 0U; + xIdleTaskHandle = NULL; + uxSchedulerSuspended = ( UBaseType_t ) 0; + /* ulTaskSwitchedInTime = 0UL; */ + /*ulTotalRunTime = 0UL; */ + is_first_task = true; + created_tasks = 0; + + py_operation = dummy_operation; +} + +/*! called after each testcase */ +void tearDown( void ) +{ + TEST_ASSERT_EQUAL( 0, critical_section_counter ); +} + +/*! called at the beginning of the whole suite */ +void suiteSetUp() +{ +} + +/*! called at the end of the whole suite */ +int suiteTearDown( int numFailures ) +{ + return numFailures; +} + +/* ============================== Test Cases ============================== */ + +/*! + * @brief create a static new task with a success path + */ +void test_xTaskCreateStatic_success( void ) +{ + StackType_t puxStackBuffer[ 300 ]; + StaticTask_t * pxTaskBuffer = malloc( sizeof( TCB_t ) ); + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = { __FUNCTION__ }; + const uint32_t ulStackDepth = 300; + void * const pvParameters = NULL; + UBaseType_t uxPriority = 3; + TaskHandle_t ret; + + /* Setup */ + memset( puxStackBuffer, 0xa5U, ulStackDepth * sizeof( StackType_t ) ); + + /* Expectations */ + vListInitialiseItem_ExpectAnyArgs(); + vListInitialiseItem_ExpectAnyArgs(); + + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + pxPortInitialiseStack_ExpectAnyArgsAndReturn( puxStackBuffer ); + + for( int i = ( UBaseType_t ) 0U; i < ( UBaseType_t ) configMAX_PRIORITIES; i++ ) + { + vListInitialise_ExpectAnyArgs(); + } + + /* Delayed Task List 1 */ + vListInitialise_ExpectAnyArgs(); + /* Delayed Task List 2 */ + vListInitialise_ExpectAnyArgs(); + /* Pending Ready List */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskDelete */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskSuspend */ + vListInitialise_ExpectAnyArgs(); + + listINSERT_END_ExpectAnyArgs(); + + /* API Call */ + ret = xTaskCreateStatic( pxTaskCode, + pcName, + ulStackDepth, + pvParameters, + uxPriority, + puxStackBuffer, + pxTaskBuffer ); + ptcb = ( TCB_t * ) pxTaskBuffer; + /* Validations */ + TEST_ASSERT_EQUAL_PTR( puxStackBuffer, ptcb->pxStack ); + TEST_ASSERT_NOT_EQUAL( NULL, ret ); + TEST_ASSERT_EQUAL( 2, ptcb->ucStaticallyAllocated ); + TEST_ASSERT_EQUAL( 0, + memcmp( ptcb->pxStack, + puxStackBuffer, + ulStackDepth * sizeof( StackType_t ) ) ); + + TEST_ASSERT_EQUAL( ptcb->pxEndOfStack, + ptcb->pxStack + ( 300 - 1 ) ); + TEST_ASSERT_EQUAL( 0, memcmp( ptcb->pcTaskName, pcName, configMAX_TASK_NAME_LEN - 1 ) ); + + TEST_ASSERT_EQUAL( ptcb->uxPriority, uxPriority ); + + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + ASSERT_SETUP_TCB_CALLED(); + free( pxTaskBuffer ); +} + +void test_xTaskCreate_success( void ) +{ + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = NULL; + const uint32_t usStackDepth = 300; + void * const pvParameters = NULL; + UBaseType_t uxPriority = configMAX_PRIORITIES; + TaskHandle_t taskHandle; + BaseType_t ret; + StackType_t stack[ ( ( size_t ) usStackDepth ) * sizeof( StackType_t ) ]; + + /* Setup */ + /* Expectations */ + pvPortMalloc_ExpectAndReturn( sizeof( TCB_t ), &tcb[ 0 ] ); + pvPortMalloc_ExpectAndReturn( usStackDepth * sizeof( StackType_t ), stack ); + + vListInitialiseItem_Expect( &( tcb[ 0 ].xStateListItem ) ); + vListInitialiseItem_Expect( &( tcb[ 0 ].xEventListItem ) ); + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + pxPortInitialiseStack_ExpectAnyArgsAndReturn( stack ); + + for( int i = ( UBaseType_t ) 0U; i < ( UBaseType_t ) configMAX_PRIORITIES; i++ ) + { + vListInitialise_ExpectAnyArgs(); + } + + /* Delayed Task List 1 */ + vListInitialise_ExpectAnyArgs(); + /* Delayed Task List 2 */ + vListInitialise_ExpectAnyArgs(); + /* Pending Ready List */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskDelete */ + vListInitialise_ExpectAnyArgs(); + /* INCLUDE_vTaskSuspend */ + vListInitialise_ExpectAnyArgs(); + + listINSERT_END_ExpectAnyArgs(); + + /* API Call */ + ret = xTaskCreate( pxTaskCode, + pcName, + usStackDepth, + pvParameters, + uxPriority, + &taskHandle ); + /* Validations */ + ptcb = ( TCB_t * ) taskHandle; + TEST_ASSERT_EQUAL( pdPASS, ret ); + TEST_ASSERT_EQUAL( 0, tcb[ 0 ].ucStaticallyAllocated ); + TEST_ASSERT_EQUAL_PTR( &tcb[ 0 ], ptcb ); + TEST_ASSERT_EQUAL( stack, tcb[ 0 ].pxStack ); + TEST_ASSERT_EQUAL( 1, uxCurrentNumberOfTasks ); + TEST_ASSERT_EQUAL( configMAX_PRIORITIES - 1, ptcb->uxPriority ); + TEST_ASSERT_EQUAL( NULL, ptcb->pcTaskName[ 0 ] ); + ASSERT_SETUP_TCB_CALLED(); +} + +void test_xTaskCreate_fail_stack_malloc( void ) +{ + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = { __FUNCTION__ }; + const uint32_t usStackDepth = 300; + void * const pvParameters = NULL; + UBaseType_t uxPriority = 3; + TaskHandle_t taskHandle; + BaseType_t ret; + + pvPortMalloc_ExpectAndReturn( sizeof( TCB_t ), NULL ); + + ret = xTaskCreate( pxTaskCode, + pcName, + usStackDepth, + pvParameters, + uxPriority, + &taskHandle ); + TEST_ASSERT_EQUAL( errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY, ret ); + TEST_ASSERT_EQUAL( 0, uxCurrentNumberOfTasks ); + ASSERT_SETUP_TCB_NOT_CALLED(); +} + +void test_xTaskCreate_fail_tcb_malloc( void ) +{ + TaskFunction_t pxTaskCode = NULL; + const char * const pcName = { __FUNCTION__ }; + const uint32_t usStackDepth = 300; + void * const pvParameters = NULL; + UBaseType_t uxPriority = 3; + TaskHandle_t taskHandle; + BaseType_t ret; + + pvPortMalloc_ExpectAndReturn( sizeof( TCB_t ), &tcb[ 0 ] ); + pvPortMalloc_ExpectAndReturn( usStackDepth * sizeof( StackType_t ), NULL ); + vPortFree_Expect( &tcb[ 0 ] ); + + ret = xTaskCreate( pxTaskCode, + pcName, + usStackDepth, + pvParameters, + uxPriority, + &taskHandle ); + TEST_ASSERT_EQUAL( errCOULD_NOT_ALLOCATE_REQUIRED_MEMORY, ret ); + TEST_ASSERT_EQUAL( 0, uxCurrentNumberOfTasks ); + ASSERT_SETUP_TCB_NOT_CALLED(); +} + +void test_vTaskPrioritySet_success_gt_curr_prio( void ) +{ + TaskHandle_t taskHandle2; + TCB_t * ptcb; + + create_task_priority = 3; + create_task(); + create_task_priority = 4; + taskHandle2 = create_task(); + ptcb = ( TCB_t * ) taskHandle2; + TEST_ASSERT_EQUAL_PTR( pxCurrentTCB, taskHandle2 ); + listGET_LIST_ITEM_VALUE_ExpectAnyArgsAndReturn( 0 ); + listSET_LIST_ITEM_VALUE_Expect( &( ptcb->xEventListItem ), + configMAX_PRIORITIES - 5 ); + listIS_CONTAINED_WITHIN_ExpectAndReturn( &pxReadyTasksLists[ 5 ], + &( ptcb->xStateListItem ), + pdTRUE ); + uxListRemove_ExpectAndReturn( &( ptcb->xStateListItem ), 0 ); + /* port Reset ready priority */ + /* add task to ready list macro */ + + listINSERT_END_Expect( &( pxReadyTasksLists[ 5 ] ), + &( ptcb->xStateListItem ) ); + + TEST_ASSERT_EQUAL( 4, ptcb->uxPriority ); + vTaskPrioritySet( taskHandle2, create_task_priority + 1 ); + TEST_ASSERT_EQUAL( 4 + 1, ptcb->uxPriority ); + ASSERT_PORT_YIELD_NOT_CALLED(); +} +/* ----------------- testing portCRITICAL_NESTING_IN_TCB ------------------- */ + +void vTaskEnterCritical( void ); +void vTaskExitCritical( void ); + +void test_vTaskExitCritical_succes( void ) +{ + TaskHandle_t task_handle; + + /* Setup */ + task_handle = create_task(); + start_scheduler(); + /* Expectations */ + /* API Call */ + vTaskExitCritical(); + /* Validations */ + TEST_ASSERT_EQUAL( 0, task_handle->uxCriticalNesting ); + ASSERT_PORT_ENABLE_INTERRUPT_NOT_CALLED(); +} + +void test_vTaskExitCritical_success_enable_interrupts( void ) +{ + TaskHandle_t task_handle; + + /* Setup */ + task_handle = create_task(); + start_scheduler(); + vTaskEnterCritical(); + ASSERT_IF_IN_ISR_CALLED(); + /* Expectations */ + /* API Call */ + vTaskExitCritical(); + /* Validations */ + TEST_ASSERT_EQUAL( 0, task_handle->uxCriticalNesting ); + ASSERT_PORT_ENABLE_INTERRUPT_CALLED(); +} + +void test_vTaskExitCritical_success_enable_too_many_nests( void ) +{ + TaskHandle_t task_handle; + + /* Setup */ + task_handle = create_task(); + start_scheduler(); + vTaskEnterCritical(); + ASSERT_IF_IN_ISR_CALLED(); + vTaskEnterCritical(); + /* Expectations */ + /* API Call */ + vTaskExitCritical(); + /* Validations */ + TEST_ASSERT_EQUAL( 1, task_handle->uxCriticalNesting ); + ASSERT_PORT_ENABLE_INTERRUPT_NOT_CALLED(); +} + +void test_vTaskExitCritical_scheduler_off( void ) +{ + TaskHandle_t task_handle; + + /* Setup */ + task_handle = create_task(); + /* Expectations */ + /* API Call */ + vTaskExitCritical(); + /* Validations */ + TEST_ASSERT_EQUAL( 0, task_handle->uxCriticalNesting ); + ASSERT_PORT_ENABLE_INTERRUPT_NOT_CALLED(); +} + +void test_vTaskEnterCritical_succes( void ) +{ + TaskHandle_t task_handle; + + /* Setup */ + task_handle = create_task(); + start_scheduler(); + /* Expectations */ + /* API Call */ + vTaskEnterCritical(); + /* Validations */ + TEST_ASSERT_EQUAL( 1, task_handle->uxCriticalNesting ); + ASSERT_IF_IN_ISR_CALLED(); +} + +void test_vTaskEnterCritical_succes_twice( void ) +{ + TaskHandle_t task_handle; + + /* Setup */ + task_handle = create_task(); + start_scheduler(); + /* Expectations */ + /* API Call */ + vTaskEnterCritical(); + ASSERT_IF_IN_ISR_CALLED(); + vTaskEnterCritical(); + /* Validations */ + TEST_ASSERT_EQUAL( 2, task_handle->uxCriticalNesting ); + ASSERT_IF_IN_ISR_NOT_CALLED(); +} + +void test_vTaskEnterCritical_no_op_no_sched( void ) +{ + TaskHandle_t task_handle; + + /* Setup */ + task_handle = create_task(); + /* Expectations */ + /* API Call */ + vTaskEnterCritical(); + /* Validations */ + TEST_ASSERT_EQUAL( 0, task_handle->uxCriticalNesting ); + ASSERT_IF_IN_ISR_NOT_CALLED(); +} diff --git a/FreeRTOS/Test/CMock/testdir.mk b/FreeRTOS/Test/CMock/testdir.mk index 25fe2ba202..b465b7ae15 100644 --- a/FreeRTOS/Test/CMock/testdir.mk +++ b/FreeRTOS/Test/CMock/testdir.mk @@ -35,7 +35,7 @@ MOCK_OBJ := $(addprefix mock_,$(MOCK_FILES:.h=.o)) MOCK_HDR_LIST := $(addprefix $(MOCKS_DIR)/,$(MOCK_HDR)) MOCK_SRC_LIST := $(addprefix $(MOCKS_DIR)/,$(MOCK_SRC)) MOCK_OBJ_LIST := $(addprefix $(SCRATCH_DIR)/,$(MOCK_OBJ)) -CFLAGS += -I$(MOCKS_DIR) +CPPFLAGS += -I$(MOCKS_DIR) # Kernel files under test PROJ_SRC_LIST := $(addprefix $(KERNEL_DIR)/,$(PROJECT_SRC)) @@ -53,10 +53,6 @@ SF_OBJ_LIST := $(addprefix $(SCRATCH_DIR)/sf_,$(SUITE_SUPPORT_SRC:.c=.o)) DEPS_OBJ_LIST := $(addprefix $(SCRATCH_DIR)/dep_,$(PROJECT_DEPS_SRC:.c=.o)) EXECS := $(addprefix $(EXEC_PREFIX)_,$(SUITE_UT_SRC:.c=)) EXEC_LIST := $(addprefix $(BIN_DIR)/,$(EXECS)) -LCOV_LIST := $(addsuffix .info,$(addprefix $(SCRATCH_DIR)/,$(SUITE_UT_SRC:.c=))) -COVINFO_INITIAL := $(SCRATCH_DIR)/$(EXEC_PREFIX)_initial.info -COVINFO_COMBINE := $(SCRATCH_DIR)/$(EXEC_PREFIX)_combined.info -COVINFO := $(abspath $(SCRATCH_DIR)/..)/$(EXEC_PREFIX).info LIBS_LIST := $(foreach lib, $(LIBS), $(LIB_DIR)/$(lib).so) # Coverage related options @@ -70,64 +66,14 @@ COV_REPORT_DIR := $(SCRATCH_DIR)/coverage NO_DELETE : $(MOCK_HDR_LIST) $(MOCK_SRC_LIST) $(MOCK_OBJ_LIST) \ $(DEPS_OBJ_LIST) $(SF_OBJ_LIST) $(EXEC_LIST) \ $(PROJ_PP_LIST) $(PROJ_OBJ_LIST) $(PROJ_GCDA_LIST) \ - $(SUITE_OBJ_LIST) $(RUNNER_SRC_LIST) $(RUNNER_OBJ_LIST) \ - $(COVINFO) $(LCOV_LIST) - -# Cases that run test binaries cannot be run in parallel. -.NOTPARALLEL : $(COVINFO) $(LCOV_LIST) $(PROJ_GCDA_LIST) + $(SUITE_OBJ_LIST) $(RUNNER_SRC_LIST) $(RUNNER_OBJ_LIST) .DEFAULT_GOAL := run -# Generate gcov files by default -run : gcov - -gcov : $(PROJ_GCDA_LIST) - -clean: - rm -rf $(SCRATCH_DIR) - rm -rf $(EXEC_LIST) - rm -rf $(COVINFO) - -$(LIBS_LIST) : - make -C $(UT_ROOT_DIR) libs - -define run-test -$(1) - -endef - -# Run and append to gcov data files -$(PROJ_GCDA_LIST) : $(EXEC_LIST) - rm -f $(PROJ_DIR)/*.gcda - mkdir -p $(BIN_DIR) - # run each test case - $(foreach bin,$^,$(call run-test,$(bin))) - -# Run and generate lcov -lcov: $(COVINFO) - -lcovhtml : $(COVINFO) - mkdir -p $(COV_REPORT_DIR) - genhtml $(COVINFO) $(LCOV_OPTS) --output-directory $(COV_REPORT_DIR) - -bin: $(EXEC_LIST) - -# Generate _mock.c / .h files -$(MOCK_HDR_LIST) $(MOCK_SRC_LIST) : $(PROJECT_DIR)/$(PROJECT).yml $(MOCK_FILES_FP) - mkdir -p $(SCRATCH_DIR) $(MOCKS_DIR) - cd $(SCRATCH_DIR) && \ - ruby $(CMOCK_EXEC_DIR)/cmock.rb -o$(PROJECT_DIR)/$(PROJECT).yml \ - $(MOCK_FILES_FP) - -# Generate callgraph for coverage filtering -$(PROJ_DIR)/callgraph.json : $(PROJ_SRC_LIST) - mkdir -p $(PROJ_DIR) - python3 $(UT_ROOT_DIR)/tools/callgraph.py --out $@ $^ - # preprocess proj files to expand macros for coverage $(PROJ_DIR)/%.i : $(KERNEL_DIR)/%.c mkdir -p $(PROJ_DIR) - $(CC) -E $< $(CPPFLAGS) $(CFLAGS) -o $@ + $(CC) -E $< $(CPPFLAGS) -o $@ # compile the project objects with coverage instrumented $(PROJ_DIR)/%.o : $(PROJ_DIR)/%.i @@ -173,39 +119,15 @@ $(EXEC_LIST) : $(BIN_DIR)/$(EXEC_PREFIX)_%_utest : $(SCRATCH_DIR)/%_utest.o $(CC) $< $(subst .o,_runner.o,$<) $(SF_OBJ_LIST) $(DEPS_OBJ_LIST) \ $(MOCK_OBJ_LIST) $(PROJ_OBJ_LIST) $(LDFLAGS) -o $@ -# Generate baseline inital coverage data from .gcno file -$(SCRATCH_DIR)/$(EXEC_PREFIX)_initial.info : $(PROJ_OBJ_LIST) - lcov $(LCOV_OPTS) --capture --initial --directory $(PROJ_DIR) -o $@ - -# Run the test runner and genrate a filtered gcov.json.gz file -$(SCRATCH_DIR)/%_utest.info : $(BIN_DIR)/$(EXEC_PREFIX)_%_utest \ - $(PROJ_DIR)/callgraph.json - # Remove any existing coverage data - rm -f $(PROJ_DIR)/*.gcda - - # run the testrunner - $< - - # Gather coverage into a json.gz file - gcov $(GCOV_OPTS) $(foreach src,$(PROJECT_SRC),$(PROJ_DIR)/$(src:.c=.gcda)) \ - --json-format --stdout | gzip > $(subst .info,.json.gz,$@) - - # Filter coverage based on tags in unit test file - $(TOOLS_DIR)/filtercov.py --in $(subst .info,.json.gz,$@) \ - --map $(PROJ_DIR)/callgraph.json \ - --test $(SUITE_DIR)/$*_utest.c \ - --format lcov \ - --out $@ - -lcov $(LCOV_OPTS) --summary $@ - - # Remove temporary files - rm -f $(subst .info,.json.gz,$@) - rm -f $(PROJ_GCDA_LIST) - -# Combine lcov from each test bin into one lcov info file for the suite -$(COVINFO_COMBINE) : $(LCOV_LIST) - lcov $(LCOV_OPTS) -o $@ $(foreach cov,$(LCOV_LIST),--add-tracefile $(cov) ) - -# Add baseline / initial coverage generated by gcc to point out untagged functions -$(COVINFO) : $(COVINFO_COMBINE) $(COVINFO_INITIAL) - lcov $(LCOV_OPTS) -o $@ --add-tracefile $(COVINFO_INITIAL) --add-tracefile $(COVINFO_COMBINE) +# Generate _mock.c / .h files +$(MOCK_HDR_LIST) $(MOCK_SRC_LIST) : $(PROJECT_DIR)/$(PROJECT).yml $(MOCK_FILES_FP) + mkdir -p $(SCRATCH_DIR) $(MOCKS_DIR) + cd $(SCRATCH_DIR) && \ + ruby $(CMOCK_EXEC_DIR)/cmock.rb -o$(PROJECT_DIR)/$(PROJECT).yml \ + $(MOCK_FILES_FP) + + +$(LIBS_LIST) : + make -C $(UT_ROOT_DIR) libs + +include $(UT_ROOT_DIR)/coverage.mk diff --git a/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_1.h b/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_1.h new file mode 100644 index 0000000000..b34b3172e9 --- /dev/null +++ b/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_1.h @@ -0,0 +1,139 @@ +/* + * FreeRTOS V202112.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 FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/* XXX: this file will be processed by unifdef to generate new header files + * that can be mocked according to the configurations desired + * it has a few limitations on the format of this file such as: + * no config that spans more than one line + * no strings in config names + * for more info please check the man file with $ man unifdef + */ + +/*----------------------------------------------------------- +* Application specific definitions. +* +* These definitions should be adjusted for your particular hardware and +* application requirements. +* +* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See +* http://www.freertos.org/a00110.html +*----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#define configUSE_TICKLESS_IDLE 1 +#define configUSE_TIME_SLICING 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 1 +#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */ +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */ +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configCHECK_FOR_STACK_OVERFLOW 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 20 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_APPLICATION_TASK_TAG 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 +#define configUSE_QUEUE_SETS 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5 +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 +#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 ) /* For test. */ +#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1 /* As there are a lot of tasks running. */ + +/* Software timer related configuration options. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 20 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) + +#define configMAX_PRIORITIES ( 9 ) + +/* Run time stats gathering configuration options. */ +unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */ +void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats() +#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue() +#define portUSING_MPU_WRAPPERS 0 +#define portHAS_STACK_OVERFLOW_CHECKING 0 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 + +/* Co-routine related configuration options. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +#define portSTACK_GROWTH ( -1 ) +#define configRECORD_STACK_HIGH_ADDRESS 1 + +/* This demo makes use of one or more example stats formatting functions. These + * format the raw data provided by the uxTaskGetSystemState() function in to human + * readable ASCII form. See the notes in the implementation of vTaskList() within + * FreeRTOS/Source/tasks.c for limitations. */ +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +/* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. In most cases the linker will remove unused + * functions anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 1 + +/* It is a good idea to define configASSERT() while developing. configASSERT() + * uses the same semantics as the standard C assert() macro. */ +#define configASSERT( x ) +#define portREMOVE_STATIC_QUALIFIER 1 + +#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0 +#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_dynamic.h b/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_dynamic.h new file mode 100644 index 0000000000..f91729962e --- /dev/null +++ b/FreeRTOS/Test/CMock/timers/FreeRTOSConfig_dynamic.h @@ -0,0 +1,139 @@ +/* + * FreeRTOS V202112.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 FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/* XXX: this file will be processed by unifdef to generate new header files + * that can be mocked according to the configurations desired + * it has a few limitations on the format of this file such as: + * no config that spans more than one line + * no strings in config names + * for more info please check the man file with $ man unifdef + */ + +/*----------------------------------------------------------- +* Application specific definitions. +* +* These definitions should be adjusted for your particular hardware and +* application requirements. +* +* THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE +* FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. See +* http://www.freertos.org/a00110.html +*----------------------------------------------------------*/ + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 1 +#define configUSE_TICKLESS_IDLE 1 +#define configUSE_TIME_SLICING 1 +#define configUSE_IDLE_HOOK 1 +#define configUSE_TICK_HOOK 1 +#define configUSE_DAEMON_TASK_STARTUP_HOOK 1 +#define configTICK_RATE_HZ ( 1000 ) /* In this non-real time simulated environment the tick frequency has to be at least a multiple of the Win32 tick frequency, and therefore very slow. */ +#define configMINIMAL_STACK_SIZE ( ( unsigned short ) 70 ) /* In this simulated case, the stack only has to hold one small structure as the real stack is part of the win32 thread. */ +#define configTOTAL_HEAP_SIZE ( ( size_t ) ( 52 * 1024 ) ) +#define configMAX_TASK_NAME_LEN ( 12 ) +#define configUSE_TRACE_FACILITY 0 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configCHECK_FOR_STACK_OVERFLOW 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configQUEUE_REGISTRY_SIZE 20 +#define configUSE_MALLOC_FAILED_HOOK 1 +#define configUSE_APPLICATION_TASK_TAG 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configUSE_ALTERNATIVE_API 0 +#define configUSE_QUEUE_SETS 1 +#define configUSE_TASK_NOTIFICATIONS 1 +#define configTASK_NOTIFICATION_ARRAY_ENTRIES 5 +#define configSUPPORT_STATIC_ALLOCATION 0 +#define configSUPPORT_DYNAMIC_ALLOCATION 1 +#define configINITIAL_TICK_COUNT ( ( TickType_t ) 0 ) /* For test. */ +#define configSTREAM_BUFFER_TRIGGER_LEVEL_TEST_MARGIN 1 /* As there are a lot of tasks running. */ + +/* Software timer related configuration options. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY ( configMAX_PRIORITIES - 1 ) +#define configTIMER_QUEUE_LENGTH 20 +#define configTIMER_TASK_STACK_DEPTH ( configMINIMAL_STACK_SIZE * 2 ) + +#define configMAX_PRIORITIES ( 9 ) + +/* Run time stats gathering configuration options. */ +unsigned long ulGetRunTimeCounterValue( void ); /* Prototype of function that returns run time counter. */ +void vConfigureTimerForRunTimeStats( void ); /* Prototype of function that initialises the run time counter. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define portCONFIGURE_TIMER_FOR_RUN_TIME_STATS() vConfigureTimerForRunTimeStats() +#define portGET_RUN_TIME_COUNTER_VALUE() ulGetRunTimeCounterValue() +#define portUSING_MPU_WRAPPERS 0 +#define portHAS_STACK_OVERFLOW_CHECKING 0 +#define configNUM_THREAD_LOCAL_STORAGE_POINTERS 5 + +/* Co-routine related configuration options. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES ( 2 ) + +#define portSTACK_GROWTH ( -1 ) +#define configRECORD_STACK_HIGH_ADDRESS 1 + +/* This demo makes use of one or more example stats formatting functions. These + * format the raw data provided by the uxTaskGetSystemState() function in to human + * readable ASCII form. See the notes in the implementation of vTaskList() within + * FreeRTOS/Source/tasks.c for limitations. */ +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +/* Set the following definitions to 1 to include the API function, or zero + * to exclude the API function. In most cases the linker will remove unused + * functions anyway. */ +#define INCLUDE_vTaskPrioritySet 1 +#define INCLUDE_uxTaskPriorityGet 1 +#define INCLUDE_vTaskDelete 1 +#define INCLUDE_vTaskCleanUpResources 0 +#define INCLUDE_vTaskSuspend 1 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetSchedulerState 1 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 1 +#define INCLUDE_xTaskGetIdleTaskHandle 1 +#define INCLUDE_xTaskGetHandle 1 +#define INCLUDE_eTaskGetState 1 +#define INCLUDE_xSemaphoreGetMutexHolder 1 +#define INCLUDE_xTimerPendFunctionCall 1 +#define INCLUDE_xTaskAbortDelay 1 + +/* It is a good idea to define configASSERT() while developing. configASSERT() + * uses the same semantics as the standard C assert() macro. */ +#define configASSERT( x ) +#define portREMOVE_STATIC_QUALIFIER 1 + +#define configINCLUDE_MESSAGE_BUFFER_AMP_DEMO 0 +#define configUSE_LIST_DATA_INTEGRITY_CHECK_BYTES 0 + +#endif /* FREERTOS_CONFIG_H */ diff --git a/FreeRTOS/Test/CMock/timers/Makefile b/FreeRTOS/Test/CMock/timers/Makefile index 44b823d426..7c5d0037f2 100644 --- a/FreeRTOS/Test/CMock/timers/Makefile +++ b/FreeRTOS/Test/CMock/timers/Makefile @@ -3,74 +3,188 @@ # and the project name should be queue # if testing list.c your directory should be called list # and the project name should be list + +include ../makefile.in + +.PRECIOUS: + PROJECT := timers +# +# Test/CMock/tasks +PROJECT_DIR := $(abspath .) +PROJ_DIR := $(abspath .) # List the dependency files you wish to mock -MOCK_FILES_FP := $(KERNEL_DIR)/include/task.h -MOCK_FILES_FP += $(KERNEL_DIR)/include/queue.h -MOCK_FILES_FP += $(KERNEL_DIR)/include/list.h -MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h +MOCK_FILES_FP := $(KERNEL_DIR)/include/task.h +MOCK_FILES_FP += $(KERNEL_DIR)/include/queue.h +MOCK_FILES_FP += $(KERNEL_DIR)/include/list.h +MOCK_FILES_FP += $(KERNEL_DIR)/include/portable.h +MOCK_FILES_FP += $(PROJECT_DIR)/list_macros.h +MOCK_FILES_FP += $(UT_ROOT_DIR)/config/fake_assert.h + +UNDEF_MOCKED_HEADER_MACROS := -UlistLIST_IS_EMPTY -UlistGET_OWNER_OF_HEAD_ENTRY\ + -UlistIS_CONTAINED_WITHIN -UlistGET_LIST_ITEM_VALUE \ + -UlistSET_LIST_ITEM_VALUE \ + -UlistLIST_ITEM_CONTAINER -UlistCURRENT_LIST_LENGTH + +# List special compilation flags for this module +CFLAGS += -Wno-unused-function + +# List special preprocessing flags for this module +CPPFLAGS += -# List the options the compilation would need -CPPFLAGS += -DconfigSUPPORT_DYNAMIC_ALLOCATION=1 -CPPFLAGS += -DconfigSUPPORT_STATIC_ALLOCATION=1 +# List special linking flags for this module +LDFLAGS += +# Makefile Debug Flags (if needed) +#MAKEFLAGS += -rR # Try not to edit beyond this line -MOCK_FILES := $(notdir $(MOCK_FILES_FP)) -MOCK_OBJ := $(addprefix mock_,$(MOCK_FILES:.h=.o)) -MOCK_SRC := $(addprefix mock_,$(MOCK_FILES:.h=.c)) -EXEC := $(PROJECT)_utest -PROJECT_DIR := $(abspath .) + +COVERAGE_OPTS := -fprofile-arcs -ftest-coverage -fprofile-generate + +# build/generated/queue SCRATCH_DIR := $(GENERATED_DIR)/$(PROJECT) -PROJ_LIB_DIR := $(SCRATCH_DIR)/lib -MOCK_OBJ_LIST := $(addprefix $(PROJ_LIB_DIR)/,$(MOCK_OBJ)) -MOCKS_DIR := $(SCRATCH_DIR)/mocks -MOCK_SRC_LIST := $(addprefix $(MOCKS_DIR)/,$(MOCK_SRC)) -CFLAGS += -I$(MOCKS_DIR) -COVERAGE_OPTS := -fprofile-arcs -ftest-coverage -fprofile-generate + +# list.h timers.h portable.h +MOCK_FILES := $(notdir $(MOCK_FILES_FP)) + +# ...tasks/%/mocks/mock_list.o tasks/%/mocks/mock_timers.o +MOCK_OBJS := $(addprefix $(SCRATCH_DIR)/%/mocks/mock_,$(MOCK_FILES:.h=.o)) + +# ...tasks/%/mocks/mock_list.c tasks/%/mocks/mock_timers.c +MOCK_SRC_LIST := $(addprefix $(SCRATCH_DIR)/%/mocks/,$(addprefix mock_,$(MOCK_FILES:.h=.c))) + +# tasks/%/cpp/timers.h tasks/%/cpp/list.h +CPP_FILES := $(addprefix $(SCRATCH_DIR)/%/cpp/,$(notdir $(MOCK_FILES_FP))) +DEP_FILES := $(addsuffix .d,$(addprefix $(SCRATCH_DIR)/%/cpp/,$(notdir $(MOCK_FILES_FP)))) + +# tasks_1_utest.c tasks_2_utest.c ... +PROJ_SRC_LIST := $(sort $(wildcard $(PROJECT)_*_utest.c)) + +# 1_utest.c dynamic_utest.c +SUITE_UT_SRC := $(subst $(PROJECT)_,,$(PROJ_SRC_LIST)) + +# timers_1_utest.c -> 1 timers_dynamic_utest -> dynamic config1 assert ... +DISCRIMINATOR := $(subst _utest,,$(subst .c,,$(subst $(PROJECT)_,,$(PROJ_SRC_LIST)))) + +# tasks/1/mocks tasks/2/mocks +MOCK_DIRS := $(addsuffix /mocks,$(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR))) +# queue/1/cpp queue/2/cpp +CPP_DIRS := $(addsuffix /cpp,$(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR))) +# tasks/1/include tasks/2/include +INCLUDE_DIRS := $(addsuffix /include,$(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR))) +#list/1 list/2 .... +CONFIG_DIRS := $(addprefix $(SCRATCH_DIR)/,$(DISCRIMINATOR)) ifeq ($(MOCK_FILES_FP),) - $(shell mkdir -p $(MOCKS_DIR)) - $(shell touch -a $(MOCKS_DIR)/mock_dummy.c) + $(shell mkdir -p $(MOCK_DIRS)) + $(shell for n in $(MOCK_DIRS) ; do touch -a $(n)/mock_dummy.c) endif -$(MOCKS_DIR)/mock_%.c : Makefile $(PROJECT_DIR)/$(PROJECT).yml | directories - cd $(SCRATCH_DIR) && \ - ruby $(CMOCK_EXEC_DIR)/cmock.rb -o$(PROJECT_DIR)/$(PROJECT).yml \ - $(MOCK_FILES_FP) +EXEC_LIST := $(addprefix $(BIN_DIR)/,$(patsubst %.c,%,$(PROJ_SRC_LIST))) +EXEC_PATH := $(addsuffix _%_utest,$(addprefix $(BIN_DIR)/,$(PROJECT))) +PROJ_OBJ_LIST := $(EXEC_LIST) + +.PHONY: all Makefile directories -$(PROJ_LIB_DIR)/mock_%.o : $(MOCKS_DIR)/mock_%.c - $(CC) -c $< -fPIC $(CFLAGS) -o $@ +.SECONDARY: +all : directories $(EXEC_LIST) -$(BIN_DIR)/$(EXEC) : $(SCRATCH_DIR)/test_runner.o \ - $(SCRATCH_DIR)/$(PROJECT).o \ - $(SCRATCH_DIR)/$(PROJECT)_utest.o \ - $(MOCK_OBJ_LIST) - $(CC) $+ $(LDFLAGS) -o $@ +# Build the executables 1 per configuration +$(EXEC_PATH) : $(MOCK_OBJS) \ + $(SCRATCH_DIR)/%/test_runner.o \ + $(SCRATCH_DIR)/%/$(PROJECT).o \ + $(SCRATCH_DIR)/%/$(PROJECT)_utest.o \ + | libs directories + $(CC) $+ $(LDFLAGS) -o $@ -$(SCRATCH_DIR)/test_runner.o : $(SCRATCH_DIR)/test_runner.c \ - $(SCRATCH_DIR)/$(PROJECT).o - $(CC) -c $< $(CPPFLAGS) $(CFLAGS) -o $@ +# Mock All preprocessed header files +$(MOCK_SRC_LIST) : $(CPP_FILES) \ + Makefile \ + $(PROJECT_DIR)/$(PROJECT).yml \ + | directories + cd $(@D) && cd .. && \ + ruby $(CMOCK_EXEC_DIR)/cmock.rb -o$(PROJECT_DIR)/$(PROJECT).yml \ + $( $(SCRATCH_DIR)/$*/cpp/$$(basename $$h_file) ; \ + done -$(SCRATCH_DIR)/$(PROJECT).o : $(KERNEL_DIR)/$(PROJECT).c - $(CC) -c $< $(CPPFLAGS) $(CFLAGS) $(COVERAGE_OPTS) -o $@ +# Build ALL the mock objects for the config +# This target is called ONLY once per configuration pattern (%) +$(MOCK_OBJS) : $(MOCK_SRC_LIST) + $(eval INCLUDE = -I$(SCRATCH_DIR)/$*/include) + $(eval INCLUDE += -I$(SCRATCH_DIR)/$*/mocks) \ + $(eval INCLUDE += -I$(KERNEL_DIR)/include) \ + for files in $^ ; do \ + new_name=$${files%.c}.o; \ + $(CC) -c $$files $(INCLUDE) $(CPPFLAGS) $(CFLAGS) -fPIC \ + -DUNITY_EXCLUDE_MATH_H -DUNITY_EXCLUDE_STDINT_H \ + -DUNITY_OUTPUT_CHAR -o $$new_name ; \ + done -$(SCRATCH_DIR)/test_runner.c : $(SCRATCH_DIR)/$(PROJECT)_utest.o \ - Makefile | directories - ruby $(UNITY_BIN_DIR)/generate_test_runner.rb $(EXEC).c \ - $(PROJECT_DIR)/$(PROJECT).yml $@ +# Build test_runner.o from test_runner.c +$(SCRATCH_DIR)/%/test_runner.o : $(SCRATCH_DIR)/%/test_runner.c \ + $(SCRATCH_DIR)/%/$(PROJECT).o + $(eval INCLUDE = -I$(SCRATCH_DIR)/$*/include) + $(eval INCLUDE += -I$(SCRATCH_DIR)/$*/mocks) + $(eval INCLUDE += -I$(KERNEL_DIR)/include) + $(CC) -c $< $(INCLUDE) $(CPPFLAGS) $(CFLAGS) -o $@ -.PHONY: directories +# Build tasks_utest.o from tasks_utest_%.c +$(SCRATCH_DIR)/%/$(PROJECT)_utest.o : $(PROJECT_DIR)/$(PROJECT)_%_utest.c \ + $(MOCK_OBJS) \ + global_vars.h \ + | directories + $(eval INCLUDE = -I$(SCRATCH_DIR)/$*/include) + $(eval INCLUDE += -I$(SCRATCH_DIR)/$*/mocks) + $(eval INCLUDE += -I$(KERNEL_DIR)/include) + $(CC) -c $< $(INCLUDE) $(CPPFLAGS) $(CFLAGS) -o $@ + +# Build tasks.o from tasks.i with the custom FreeRTOSConfig.h and place it in +# its configuration directory +$(SCRATCH_DIR)/%/$(PROJECT).o : $(SCRATCH_DIR)/%/$(PROJECT).i | directories + $(CC) -c $< $(CFLAGS) $(COVERAGE_OPTS) -o $@ + +RESET_TIMER_FUNCTION := void stopTimers() { xTimerQueue = NULL; xTimerTaskHandle = NULL; } + +# Build tasks.i from tasks.c with the custom FreeRTOSConfig.h and place it in +# its configuration directory +$(SCRATCH_DIR)/%/$(PROJECT).i : $(KERNEL_DIR)/$(PROJECT).c | directories + $(eval INCLUDE = -I$(SCRATCH_DIR)/$*/include) + $(eval INCLUDE += -I$(SCRATCH_DIR)/$*/mocks) \ + $(eval INCLUDE += -I$(KERNEL_DIR)/include) \ + grep -q '$(RESET_TIMER_FUNCTION)' $< || \ + sed -i -e '$$a$(RESET_TIMER_FUNCTION)' $< + $(CC) -E $< $(INCLUDE) $(CPPFLAGS) -include list_macros.h -o $@ + +# Generate test_runner.c which contains the main function from the test file +$(SCRATCH_DIR)/%/test_runner.c : $(PROJECT_DIR)/$(PROJECT)_%_utest.c \ + Makefile | directories + ruby $(UNITY_BIN_DIR)/generate_test_runner.rb "--use_param_tests=1" \ + $(PROJECT)_$*_utest.c $(PROJECT_DIR)/$(PROJECT).yml $@ + +# Create needed directories directories : - -mkdir $(SCRATCH_DIR) - -mkdir $(MOCKS_DIR) - -mkdir $(PROJ_LIB_DIR) + -mkdir -p $(SCRATCH_DIR) + -mkdir -p $(CONFIG_DIRS) + -mkdir -p $(MOCK_DIRS) + -mkdir -p $(CPP_DIRS) + -mkdir -p $(INCLUDE_DIRS) + -mkdir -p $(BIN_DIR) + -mkdir -p $(LIB_DIR) + +EXEC_PREFIX := $(PROJECT) -# prevent deletion by chain of implicit rules -NO_DELETE: $(MOCK_SRC_LIST) +include ../coverage.mk diff --git a/FreeRTOS/Test/CMock/timers/global_vars.h b/FreeRTOS/Test/CMock/timers/global_vars.h new file mode 100644 index 0000000000..0d0ed0c23c --- /dev/null +++ b/FreeRTOS/Test/CMock/timers/global_vars.h @@ -0,0 +1,105 @@ +/* + * FreeRTOS V202112.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 GLOBAL_VARS_H +#define GLOBAL_VARS_H + +#include "timers.h" +/* ====================== DEFINITIONS FROM timers.c ======================== */ +#define tmrNO_DELAY ( TickType_t ) 0U + +#define tmrSTATUS_IS_ACTIVE ( ( uint8_t ) 0x01 ) +#define tmrSTATUS_IS_STATICALLY_ALLOCATED ( ( uint8_t ) 0x02 ) +#define tmrSTATUS_IS_AUTORELOAD ( ( uint8_t ) 0x04 ) + +#define tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR ( ( BaseType_t ) -2 ) +#define tmrCOMMAND_EXECUTE_CALLBACK ( ( BaseType_t ) -1 ) +#define tmrCOMMAND_START_DONT_TRACE ( ( BaseType_t ) 0 ) +#define tmrCOMMAND_START ( ( BaseType_t ) 1 ) +#define tmrCOMMAND_RESET ( ( BaseType_t ) 2 ) +#define tmrCOMMAND_STOP ( ( BaseType_t ) 3 ) +#define tmrCOMMAND_CHANGE_PERIOD ( ( BaseType_t ) 4 ) +#define tmrCOMMAND_DELETE ( ( BaseType_t ) 5 ) + +#define tmrFIRST_FROM_ISR_COMMAND ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_START_FROM_ISR ( ( BaseType_t ) 6 ) +#define tmrCOMMAND_RESET_FROM_ISR ( ( BaseType_t ) 7 ) +#define tmrCOMMAND_STOP_FROM_ISR ( ( BaseType_t ) 8 ) +#define tmrCOMMAND_CHANGE_PERIOD_FROM_ISR ( ( BaseType_t ) 9 ) + +typedef struct tmrTimerControl /* The old naming convention is used to prevent breaking kernel aware debuggers. */ +{ + const char * pcTimerName; /*<< Text name. This is not used by the kernel, it is included simply to make debugging easier. */ /*lint !e971 Unqualified char types are allowed for strings and single characters only. */ + ListItem_t xTimerListItem; /*<< Standard linked list item as used by all kernel features for event management. */ + TickType_t xTimerPeriodInTicks; /*<< How quickly and often the timer expires. */ + void * pvTimerID; /*<< An ID to identify the timer. This allows the timer to be identified when the same callback is used for multiple timers. */ + TimerCallbackFunction_t pxCallbackFunction; /*<< The function that will be called when the timer expires. */ + #if ( configUSE_TRACE_FACILITY == 1 ) + UBaseType_t uxTimerNumber; /*<< An ID assigned by trace tools such as FreeRTOS+Trace */ + #endif + uint8_t ucStatus; /*<< Holds bits to say if the timer was statically allocated or not, and if it is active or not. */ +} xTIMER; + +typedef xTIMER Timer_t; + +typedef struct tmrTimerParameters +{ + TickType_t xMessageValue; /*<< An optional value used by a subset of commands, for example, when changing the period of a timer. */ + Timer_t * pxTimer; /*<< The timer to which the command will be applied. */ +} TimerParameter_t; + +typedef struct tmrCallbackParameters +{ + PendedFunction_t pxCallbackFunction; /* << The callback function to execute. */ + void * pvParameter1; /* << The value that will be used as the callback functions first parameter. */ + uint32_t ulParameter2; /* << The value that will be used as the callback functions second parameter. */ +} CallbackParameters_t; + +typedef struct tmrTimerQueueMessage +{ + BaseType_t xMessageID; /*<< The command being sent to the timer service task. */ + union + { + TimerParameter_t xTimerParameters; + + /* Don't include xCallbackParameters if it is not going to be used as + * it makes the structure (and therefore the timer queue) larger. */ + #if ( INCLUDE_xTimerPendFunctionCall == 1 ) + CallbackParameters_t xCallbackParameters; + #endif /* INCLUDE_xTimerPendFunctionCall */ + } u; +} DaemonTaskMessage_t; + + +#define HOOK_DIAG() \ + do { \ + printf( "%s Called\n", __FUNCTION__ ); \ + } while( 0 ) + + +/*#undef HOOK_DIAG */ +/*#idefine HOOK_DIAG() */ +#endif /* ifndef GLOBAL_VARS_H */ diff --git a/FreeRTOS/Test/CMock/timers/list_macros.h b/FreeRTOS/Test/CMock/timers/list_macros.h new file mode 100644 index 0000000000..409b72358f --- /dev/null +++ b/FreeRTOS/Test/CMock/timers/list_macros.h @@ -0,0 +1,64 @@ +/* + * FreeRTOS V202112.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 + +#undef listLIST_IS_EMPTY +BaseType_t listLIST_IS_EMPTY( const List_t * pxList ); + +#undef listGET_OWNER_OF_HEAD_ENTRY +void * 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( 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 +void * listGET_LIST_ITEM_OWNER( ListItem_t * listItem ); + +#endif /* ifndef LIST_MACRO_H */ diff --git a/FreeRTOS/Test/CMock/timers/timers_1_utest.c b/FreeRTOS/Test/CMock/timers/timers_1_utest.c new file mode 100644 index 0000000000..7bb92c1fbd --- /dev/null +++ b/FreeRTOS/Test/CMock/timers/timers_1_utest.c @@ -0,0 +1,1786 @@ +/* + * FreeRTOS V202112.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 timers_utest.c */ + + +/* Test includes. */ +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "portmacro.h" +#include "timers.h" + +#include "global_vars.h" + +#include "unity.h" +#include "unity_memory.h" + +/* Mock includes. */ +#include "mock_queue.h" +#include "mock_list.h" +#include "mock_list_macros.h" +#include "mock_fake_assert.h" +#include "mock_portable.h" +#include "mock_task.h" + +/* C runtime includes. */ +#include +#include +#include + +void stopTimers(); + +/* ============================ GLOBAL VARIABLES =========================== */ +static uint16_t usMallocFreeCalls = 0; +static uint32_t critical_section_counter; +static char task_memory[ 200 ]; + +static TickType_t saved_last_time = 0; + +static bool port_yield_within_api_called = false; +static bool vApplicationDaemonTaskStartupHook_Called = false; +static bool xCallback_Test_Called = pdFALSE; +static bool pended_function_4_end_called = pdFALSE; +static bool xCallback_Test_1_end_called = pdFALSE; +static bool xCallback_Test_2_end_called = pdFALSE; + +/* ================================= DEFINES ============================== */ +#define DEFAULT_TIMER_PEIOD 1000 +#define DEFAULT_TIMER_NAME "ut_timer" + +/* ============================= FUNCTION MACROS ========================== */ +#define ASSERT_APPLICATION_DAEMON_STARTUP_HOOK_CALLED() \ + do { \ + TEST_ASSERT_TRUE( vApplicationDaemonTaskStartupHook_Called ); \ + vApplicationDaemonTaskStartupHook_Called = pdFALSE; \ + } while( 0 ) + +#define ASSERT_XCALLBACK_TEST_CALLED() \ + do { \ + TEST_ASSERT_TRUE( xCallback_Test_Called ); \ + xCallback_Test_Called = pdFALSE; \ + } while( 0 ) + +#define ASSERT_PENDED_FUNCTION_4_END_CALLED() \ + do { \ + TEST_ASSERT_TRUE( pended_function_4_end_called ); \ + pended_function_4_end_called = pdFALSE; \ + } while( 0 ) + +#define ASSERT_XCALLBACK_TEST_1_END_CALLED() \ + do { \ + TEST_ASSERT_TRUE( xCallback_Test_1_end_called ); \ + xCallback_Test_1_end_called = pdFALSE; \ + } while( 0 ) + +#define ASSERT_XCALLBACK_TEST_2_END_CALLED() \ + do { \ + TEST_ASSERT_TRUE( xCallback_Test_2_end_called ); \ + xCallback_Test_2_end_called = pdFALSE; \ + } while( 0 ) + +#define ASSERT_PORT_YIELD_WITHIN_API_CALLED() \ + do { \ + TEST_ASSERT_TRUE( port_yield_within_api_called ); \ + port_yield_within_api_called = pdFALSE; \ + } while( 0 ) + +/* ============================= FUNCTION HOOKS =========================== */ +void vFakePortEnterCriticalSection( void ) +{ + critical_section_counter++; +} + +void vFakePortExitCriticalSection( void ) +{ + critical_section_counter--; +} + +void vFakePortYieldWithinAPI() +{ + HOOK_DIAG(); + port_yield_within_api_called = true; + pthread_exit( NULL ); +} + +void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, + StackType_t ** ppxTimerTaskStackBuffer, + uint32_t * pulTimerTaskStackSize ) +{ + static StaticTask_t xTimerTaskTCB; + static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} + + +void vApplicationDaemonTaskStartupHook( void ) +{ + vApplicationDaemonTaskStartupHook_Called = pdTRUE; + HOOK_DIAG(); +} + +/* ========================== CALLBACK FUNCTIONS ========================== */ +static void xCallback_Test( TimerHandle_t xTimer ) +{ + HOOK_DIAG(); + xCallback_Test_Called = pdTRUE; +} +typedef void (* PendedFunction_t)( void *, + uint32_t ); + +static void pended_function( void * arg1, + uint32_t arg2 ) +{ + HOOK_DIAG(); +} +static int32_t end_4_timer = 0; +static void pended_function_4_end( void * arg1, + uint32_t arg2 ) +{ + HOOK_DIAG(); + static int i = 4; + pended_function_4_end_called = pdTRUE; + + if( end_4_timer - 1 <= 0 ) + { + pthread_exit( &i ); + } + + end_4_timer--; +} + +static int32_t end_1_timer = 0; +static void xCallback_Test_1_end( TimerHandle_t xTimer ) +{ + HOOK_DIAG(); + static int i = 1; + + xCallback_Test_1_end_called = pdTRUE; + + if( end_1_timer - 1 <= 0 ) + { + pthread_exit( &i ); + } + + end_1_timer--; +} + +static int32_t end_2_timer = 0; +static void xCallback_Test_2_end( TimerHandle_t xTimer ) +{ + HOOK_DIAG(); + static int i = 2; + + xCallback_Test_2_end_called = pdTRUE; + + if( end_2_timer - 1 <= 0 ) + { + pthread_exit( &i ); + } + + end_2_timer--; +} + +/* Function hook to xQueueReceive used to end the testcase */ + +/* + * static BaseType_t end_queue_receive(QueueHandle_t queue, + * void *const message, + * TickType_t delay, + * int callnum) + * { + * HOOK_DIAG(); + * static int i = 5; + * pthread_exit( &i ); + * } + */ +/* ============================= STATIC FUNCTIONS ========================= */ +static void * timer_thread_function( void * args ) +{ + void * pvParameters = NULL; + + portTASK_FUNCTION( prvTimerTask, pvParameters ); + ( void ) fool_static2; /* ignore unused variable warning */ + /* API Call */ + prvTimerTask( pvParameters ); + return NULL; +} + +static void create_timer_task( void ) +{ + BaseType_t ret_xtimer; + QueueHandle_t queue_handle = ( QueueHandle_t ) 3; /* not zero */ + TaskHandle_t timer_handle = ( TaskHandle_t ) task_memory; + + /* Setup */ + /* Expectations */ + vListInitialise_ExpectAnyArgs(); + vListInitialise_ExpectAnyArgs(); + xQueueGenericCreateStatic_ExpectAnyArgsAndReturn( queue_handle ); + vQueueAddToRegistry_ExpectAnyArgs(); + xTaskCreateStatic_ExpectAnyArgsAndReturn( timer_handle ); + /* API Call */ + ret_xtimer = xTimerCreateTimerTask(); + /* Validations */ + TEST_ASSERT_TRUE( ret_xtimer ); +} + +static TimerHandle_t create_timer() +{ + uint32_t pvTimerID = 0; + TimerHandle_t xTimer = NULL; + StaticTimer_t pxTimerBuffer[ sizeof( StaticTimer_t ) ]; + QueueHandle_t queue_handle = ( QueueHandle_t ) 3; /* not zero */ + + /*pvPortMalloc_ExpectAndReturn( sizeof( Timer_t ), &pxNewTimer ); */ + vListInitialise_ExpectAnyArgs(); + vListInitialise_ExpectAnyArgs(); + xQueueGenericCreateStatic_ExpectAnyArgsAndReturn( queue_handle ); + vQueueAddToRegistry_ExpectAnyArgs(); + vListInitialiseItem_ExpectAnyArgs(); + + xTimer = xTimerCreateStatic( DEFAULT_TIMER_NAME, + DEFAULT_TIMER_PEIOD, + pdTRUE, + ( void * ) &pvTimerID, + xCallback_Test, + pxTimerBuffer ); + return xTimer; +} + +/* ============================ UNITY FIXTURES =========================== */ +void setUp( void ) +{ + vFakeAssert_Ignore(); + port_yield_within_api_called = pdFALSE; + xCallback_Test_Called = pdFALSE; + pended_function_4_end_called = pdFALSE; + xCallback_Test_1_end_called = pdFALSE; + xCallback_Test_2_end_called = pdFALSE; + /* Track calls to malloc / free */ + UnityMalloc_StartTest(); + critical_section_counter = 0; + stopTimers(); +} + +/*! called before each testcase */ +void tearDown( void ) +{ + TEST_ASSERT_EQUAL_INT_MESSAGE( 0, usMallocFreeCalls, + "free is not called the same number of times as malloc," + "you might have a memory leak!!" ); + usMallocFreeCalls = 0; + vApplicationDaemonTaskStartupHook_Called = pdFALSE; + + 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; +} + + +/* ============================== TEST FUNCTIONS ========================== */ + +/*! + * @brief success testcase for calling the test function the very first time + * expects pdPASS + */ +void test_xTimerCreateTimerTask_success( void ) +{ + BaseType_t ret_xtimer; + QueueHandle_t queue_handle = ( QueueHandle_t ) 3; /* not zero */ + char task_memory[ 200 ]; + TaskHandle_t timer_handle = ( TaskHandle_t ) task_memory; + + /* Setup */ + /* Expectations */ + vListInitialise_ExpectAnyArgs(); + vListInitialise_ExpectAnyArgs(); + xQueueGenericCreateStatic_ExpectAnyArgsAndReturn( queue_handle ); + vQueueAddToRegistry_ExpectAnyArgs(); + xTaskCreateStatic_ExpectAnyArgsAndReturn( timer_handle ); + /* API Call */ + ret_xtimer = xTimerCreateTimerTask(); + /* Validations */ + TEST_ASSERT_TRUE( ret_xtimer ); +} + +/*! + * @brief failed test case, could not create a static task + * expects pdFAIL + */ +void test_xTimerCreateTimerTask_fail_null_task( void ) +{ + BaseType_t ret_xtimer; + QueueHandle_t queue_handle = ( QueueHandle_t ) 3; /* not zero */ + + /* Setup */ + /* Expectations */ + vListInitialise_ExpectAnyArgs(); + vListInitialise_ExpectAnyArgs(); + xQueueGenericCreateStatic_ExpectAnyArgsAndReturn( queue_handle ); + vQueueAddToRegistry_ExpectAnyArgs(); + xTaskCreateStatic_ExpectAnyArgsAndReturn( NULL ); + /* API Call */ + ret_xtimer = xTimerCreateTimerTask(); + /* Validations */ + TEST_ASSERT_FALSE( ret_xtimer ); +} + +/*! + * @brief success test case, when the timer task function has already been called + * expects pdFAIL + */ +void test_xTimerCreateTimerTask_fail_null_queue( void ) +{ + BaseType_t ret_xtimer; + + /* Setup */ + /* Expectations */ + vListInitialise_ExpectAnyArgs(); + vListInitialise_ExpectAnyArgs(); + xQueueGenericCreateStatic_ExpectAnyArgsAndReturn( NULL ); + /* API Call */ + ret_xtimer = xTimerCreateTimerTask(); + /* Validations */ + TEST_ASSERT_FALSE( ret_xtimer ); +} + +/*! + * @brief success test case, creates a new timer + * expects pdPASS + */ +void test_xTimerCreateStatic_success( void ) +{ + TimerHandle_t ret_timer_create; + UBaseType_t pvTimerID; + StaticTimer_t pxTimerBuffer[ sizeof( StaticTimer_t ) ]; + + /* Setup */ + /* Expectations */ + /* prvInitialiseNewTimer */ + /* prvCheckForValidListAndQueue */ + vListInitialise_ExpectAnyArgs(); + vListInitialise_ExpectAnyArgs(); + xQueueGenericCreateStatic_ExpectAnyArgsAndReturn( NULL ); + /* Back prvInitialiseNewTimer */ + vListInitialiseItem_ExpectAnyArgs(); + /* API Call */ + ret_timer_create = xTimerCreateStatic( "ut_timer_task", + pdMS_TO_TICKS( 1000 ), + pdTRUE, + ( void * ) &pvTimerID, + xCallback_Test, + pxTimerBuffer ); + /* Validations */ + TEST_ASSERT_TRUE( ret_timer_create ); +} + +/*! + * @brief failed testcase, passing a null buffer + * expects pdFAIL + */ +void test_xTimerCreateStatic_fail_null_buffer( void ) +{ + TimerHandle_t ret_timer_create; + UBaseType_t pvTimerID; + + /* Setup */ + /* Expectations */ + /* API Call */ + ret_timer_create = xTimerCreateStatic( "ut_timer_task", + pdMS_TO_TICKS( 1000 ), + pdTRUE, + ( void * ) &pvTimerID, + xCallback_Test, + NULL ); + /* Validations */ + TEST_ASSERT_FALSE( ret_timer_create ); +} + +/*! + * @brief success testcase, adding a timer event to the queue + * expects pdPASS + */ +void test_xTimerGenericCommand_success_queue_pass( void ) +{ + BaseType_t ret_timer_generic; + TimerHandle_t xTimer; + BaseType_t pxHigherPriorityTaskWoken = pdFALSE; + const TickType_t xTicksToWait = 400; + + /* Setup */ + xTimer = create_timer(); + /* Expectations */ + + xQueueGenericSendFromISR_ExpectAnyArgsAndReturn( pdPASS ); + /* API Call */ + ret_timer_generic = xTimerGenericCommand( xTimer, + tmrFIRST_FROM_ISR_COMMAND, + 34, + &pxHigherPriorityTaskWoken, + xTicksToWait ); + /* Validations */ + TEST_ASSERT_TRUE( ret_timer_generic ); +} + +/*! + * @brief failed testcase, adding a timer event to the queue fails + * expects pdFAIL + */ +void test_xTimerGenericCommand_fail_queue_fail( void ) +{ + BaseType_t ret_timer_generic; + TimerHandle_t xTimer; + BaseType_t pxHigherPriorityTaskWoken = pdFALSE; + const TickType_t xTicksToWait = 400; + + /* Setup */ + xTimer = create_timer(); + /* Expectations */ + + xQueueGenericSendFromISR_ExpectAnyArgsAndReturn( pdFAIL ); + /* API Call */ + ret_timer_generic = xTimerGenericCommand( xTimer, + tmrFIRST_FROM_ISR_COMMAND, + 34, + &pxHigherPriorityTaskWoken, + xTicksToWait ); + /* Validations */ + TEST_ASSERT_FALSE( ret_timer_generic ); +} + +/*! + * @brief success testcase, adding a timer event from isr to the queue while + * the scheduler is running + * expects pdPASS + */ +void test_xTimerGenericCommand_success_sched_running( void ) +{ + BaseType_t ret_timer_generic; + TimerHandle_t xTimer; + BaseType_t pxHigherPriorityTaskWoken = pdFALSE; + const TickType_t xTicksToWait = 400; + + /* Setup */ + xTimer = create_timer(); + /* Expectations */ + xTaskGetSchedulerState_ExpectAndReturn( taskSCHEDULER_RUNNING ); + xQueueGenericSend_ExpectAnyArgsAndReturn( pdPASS ); + /* API Call */ + ret_timer_generic = xTimerGenericCommand( xTimer, + tmrCOMMAND_START, + 34, + &pxHigherPriorityTaskWoken, + xTicksToWait ); + /* Validations */ + TEST_ASSERT_TRUE( ret_timer_generic ); +} + +/*! + * @brief success testcase, adding a timer event from isr to the queue while + * the scheduler is *NOT* running + * expects pdPASS + */ +void test_xTimerGenericCommand_success_sched_not_running( void ) +{ + BaseType_t ret_timer_generic; + TimerHandle_t xTimer; + BaseType_t pxHigherPriorityTaskWoken = pdFALSE; + const TickType_t xTicksToWait = 400; + + /* Setup */ + xTimer = create_timer(); + /* Expectations */ + xTaskGetSchedulerState_ExpectAndReturn( taskSCHEDULER_NOT_STARTED ); + xQueueGenericSend_ExpectAnyArgsAndReturn( pdPASS ); + + /* API Call */ + ret_timer_generic = xTimerGenericCommand( xTimer, + tmrCOMMAND_START, + 34, + &pxHigherPriorityTaskWoken, + xTicksToWait ); + /* Validations */ + TEST_ASSERT_TRUE( ret_timer_generic ); +} + +/*! + * @brief failed testcase, adding a timer event while the timer task is not + * running ( xTimerCreate[Static] has not been already called ) + * expects pdFALSE + */ +void test_xTimerGenericCommand_success_null_timer_not_started( void ) +{ + BaseType_t ret_timer_generic; + TimerHandle_t xTimer = NULL; + BaseType_t pxHigherPriorityTaskWoken = pdFALSE; + const TickType_t xTicksToWait = 400; + + /* Setup */ + /* Expectations */ + /* API Call */ + ret_timer_generic = xTimerGenericCommand( xTimer, + tmrCOMMAND_START, + 34, + &pxHigherPriorityTaskWoken, + xTicksToWait ); + /* Validations */ + TEST_ASSERT_FALSE( ret_timer_generic ); +} + +/*! + * @brief sucess testcase, getter for the timer handle daemon + * expects a non NULL value + */ +void test_xTimerGetTimerDaemonTaskHandle_success( void ) +{ + TaskHandle_t ret_get_timer_handle; + + /* Setup */ + create_timer_task(); + /* Expectations */ + /* API Call */ + ret_get_timer_handle = xTimerGetTimerDaemonTaskHandle(); + /* Validations */ + TEST_ASSERT_NOT_NULL( ret_get_timer_handle ); +} + +/*! + * @brief sucess testcase, getter for the timer period in ticks + * expects a similar value to the one created + */ +void test_xTimerGetPeriod_success( void ) +{ + TickType_t ret_get_period; + TimerHandle_t xTimer; + + /* Setup */ + xTimer = create_timer(); + /* Expectations */ + /* API Call */ + ret_get_period = xTimerGetPeriod( xTimer ); + /* Validations */ + TEST_ASSERT_EQUAL( DEFAULT_TIMER_PEIOD, ret_get_period ); +} + +/*! + * @brief sucess testcase, set and test timer reload mode + */ +void test_vTimer_Set_Get_ReloadMode_success( void ) +{ + TimerHandle_t xTimer; + UBaseType_t reload_mode; + + /* Setup */ + xTimer = create_timer(); + /* Expectations */ + /* API Call */ + vTimerSetReloadMode( xTimer, pdTRUE ); + reload_mode = uxTimerGetReloadMode( xTimer ); + /* Validations */ + TEST_ASSERT_TRUE( ( xTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ) ); + TEST_ASSERT_TRUE( reload_mode ); + + /* API Call */ + vTimerSetReloadMode( xTimer, pdFALSE ); + reload_mode = uxTimerGetReloadMode( xTimer ); + /* Validations */ + TEST_ASSERT_FALSE( xTimer->ucStatus & tmrSTATUS_IS_AUTORELOAD ); + TEST_ASSERT_FALSE( reload_mode ); +} + +/*! + * @brief sucess testcase, get timer expiry time + */ +void test_xTimerGetExpiryTime( void ) +{ + TickType_t ret_timer_expiry; + TimerHandle_t xTimer; + + /* Setup */ + xTimer = create_timer(); + /* Expectations */ + listGET_LIST_ITEM_VALUE_ExpectAnyArgsAndReturn( 35 ); + /* API Call */ + ret_timer_expiry = xTimerGetExpiryTime( xTimer ); + /* Validations */ + TEST_ASSERT_EQUAL( 35, ret_timer_expiry ); +} + +/*! + * @brief sucess testcase, get and test the default timer name + */ +void test_pcTimerGetName( void ) +{ + TimerHandle_t xTimer; + const char * ret_timer_name; + + /* Setup */ + xTimer = create_timer(); + /* Expectations */ + /* API Call */ + ret_timer_name = pcTimerGetName( xTimer ); + /* Validations */ + TEST_ASSERT_EQUAL_STRING( DEFAULT_TIMER_NAME, ret_timer_name ); +} + +/*! + * @brief sucess testcase, get timer status and test if it is active + */ +void test_xTimerIsTimerActive_true( void ) +{ + BaseType_t ret_is_timer_active; + + TimerHandle_t xTimer; + + /* Setup */ + xTimer = create_timer(); + xTimer->ucStatus |= tmrSTATUS_IS_ACTIVE; + /* Expectations */ + /* API Call */ + ret_is_timer_active = xTimerIsTimerActive( xTimer ); + /* Validations */ + TEST_ASSERT_TRUE( ret_is_timer_active ); +} + +/*! + * @brief sucess testcase, get timer status and test if it is active + * expects the timer not to be active by default + */ +void test_xTimerIsTimerActive_false( void ) +{ + BaseType_t ret_is_timer_active; + TimerHandle_t xTimer; + + /* Setup */ + xTimer = create_timer(); + /* Expectations */ + /* API Call */ + ret_is_timer_active = xTimerIsTimerActive( xTimer ); + /* Validations */ + TEST_ASSERT_FALSE( ret_is_timer_active ); +} + +/*! + * @brief sucess testcase, set timer ID then tests if it was set properly + */ +void test_vTimerSetTimerID( void ) +{ + TimerHandle_t xTimer; + UBaseType_t pvNewID = 45; + UBaseType_t * saved_pvNewID; + + /* Setup */ + xTimer = create_timer(); + /* Expectations */ + /* API Call */ + vTimerSetTimerID( xTimer, ( void * ) &pvNewID ); + /* Validations */ + TEST_ASSERT_EQUAL( pvNewID, ( *( UBaseType_t * ) xTimer->pvTimerID ) ); + + saved_pvNewID = pvTimerGetTimerID( xTimer ); + TEST_ASSERT_EQUAL( pvNewID, *saved_pvNewID ); +} + +/*! + * @brief sucess testcase, sets a pended function call + */ +void test_xTimerPendFunctionCall_success( void ) +{ + BaseType_t ret_timer_pend; + UBaseType_t pvParameter1 = 0xb0b0b0; + uint32_t ulParameter2 = 0xa0a0a0; + + /* Setup */ + /* Expectations */ + xQueueGenericSend_ExpectAnyArgsAndReturn( pdTRUE ); + /* API Call */ + ret_timer_pend = xTimerPendFunctionCall( pended_function, + ( void * ) &pvParameter1, + ulParameter2, + 500 ); + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_timer_pend ); +} + +/*! + * @brief sucess testcase, sets a pended function call from ISR + */ +void test_xTimerPendFunctionCallFromISR_success( void ) +{ + BaseType_t ret_timer_pend; + UBaseType_t pvParameter1 = 0xb0b0b0; + uint32_t ulParameter2 = 0xa0a0a0; + BaseType_t xHigherPriorityTaskWoken = pdFALSE; + + /* Setup */ + /* Expectations */ + xQueueGenericSendFromISR_ExpectAnyArgsAndReturn( pdTRUE ); + /* API Call */ + ret_timer_pend = xTimerPendFunctionCallFromISR( pended_function, + ( void * ) &pvParameter1, + ulParameter2, + &xHigherPriorityTaskWoken ); + /* Validations */ + TEST_ASSERT_EQUAL( pdTRUE, ret_timer_pend ); +} + +/*! + * @brief sucess testcase, expired timer is calling the callback + */ +void test_timer_function_expired_callback( void ) +{ + Timer_t xTimer = { 0 }; + pthread_t thread_id; + int * retVal; + + /* Setup */ + end_1_timer = 1; /* exit right from the first expired timer callback */ + xTimer.ucStatus = tmrSTATUS_IS_ACTIVE; + xTimer.xTimerPeriodInTicks = 0; + xTimer.pxCallbackFunction = xCallback_Test_1_end; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + /* returns xNextExpireTime */ + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + + /* returns xTimeNow > xNextExpireTime timer expired */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 500 ); /* time now / static last_time = 0 */ + saved_last_time += 500; + /* back to prvProcessTimerOrBlockTask */ + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAndReturn( &xTimer.xTimerListItem, pdTRUE ); + + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, *retVal ); + ASSERT_XCALLBACK_TEST_1_END_CALLED(); +} + +/*! + * @brief sucess testcase, port yields when no context switch happens because of + * reusming the scheduler + */ +void test_timer_function_success3( void ) +{ + pthread_t thread_id; + int * retVal; + + /* Setup */ + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /*listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); */ + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 500 ); /* time now / static last_time = 0 */ + saved_last_time += 500; + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + /* back to prvProcessTimerOrBlockTask */ + vQueueWaitForMessageRestricted_ExpectAnyArgs(); + xTaskResumeAll_ExpectAndReturn( pdFALSE ); /* no context switch.. yield */ + /* yield called */ + + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + ASSERT_PORT_YIELD_WITHIN_API_CALLED(); +} + +/*! + * @brief sucess testcase, timer callback called + */ +void test_timer_function_success4( void ) +{ + Timer_t xTimer = { 0 }; + pthread_t thread_id; + int * retVal; + CallbackParameters_t callback_param; + + /* Setup */ + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + end_1_timer = 2; + DaemonTaskMessage_t xMessage; + xMessage.xMessageID = tmrCOMMAND_START; + xMessage.u.xCallbackParameters = callback_param; + xMessage.u.xTimerParameters.pxTimer = &xTimer; + xMessage.u.xTimerParameters.xMessageValue = saved_last_time + 300; + + xTimer.xTimerPeriodInTicks = 20; + xTimer.pxCallbackFunction = xCallback_Test_1_end; + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /*listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); */ + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 500 ); /* time now / static last_time = 0 */ + saved_last_time += 500; + /* back to prvProcessTimerOrBlockTask */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + vQueueWaitForMessageRestricted_ExpectAnyArgs(); + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* yield called */ + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, + sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvSampleTimeNow*/ + xTaskGetTickCount_ExpectAndReturn( saved_last_time - 50 ); /* time now / static last_time = 0 */ + saved_last_time -= 50; + /* prvSwitchTimerLists */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 50 ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* callback called from prvProcessExpiredTimer*/ + /* back to prvProcessReceivedCommands from prvSampleTimeNow*/ + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* back to prvProcessReceivedCommands */ + /* prvReloadTimer */ + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, *retVal ); + ASSERT_APPLICATION_DAEMON_STARTUP_HOOK_CALLED(); + ASSERT_XCALLBACK_TEST_1_END_CALLED(); +} + +void test_timer_function_success5( void ) +{ + Timer_t xTimer = { 0 }; + pthread_t thread_id; + int * retVal; + CallbackParameters_t callback_param; + + /* Setup */ + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + end_1_timer = 2; + + + + DaemonTaskMessage_t xMessage; + xMessage.xMessageID = tmrCOMMAND_START; + xMessage.u.xCallbackParameters = callback_param; + xMessage.u.xTimerParameters.pxTimer = &xTimer; + + + + end_4_timer = 10; + DaemonTaskMessage_t xMessage2; + xMessage2.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK_FROM_ISR; + xMessage2.u.xCallbackParameters = callback_param; + xMessage2.u.xTimerParameters.pxTimer = &xTimer; + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer.xTimerPeriodInTicks = 0; + xTimer.pxCallbackFunction = xCallback_Test_1_end; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /*listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); */ + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 500 ); /* time now / static last_time = 0 */ + saved_last_time += 500; + /* prvSwitchTimerLists */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + /* back to prvProcessTimerOrBlockTask */ + vQueueWaitForMessageRestricted_ExpectAnyArgs(); + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* yield called */ + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage2, + sizeof( DaemonTaskMessage_t ) ); + + + + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, + sizeof( DaemonTaskMessage_t ) ); + + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvSampleTimeNow*/ + xTaskGetTickCount_ExpectAndReturn( saved_last_time - 50 ); /* time now / static last_time = 0 */ + saved_last_time -= 50; + /* prvSwitchTimerLists */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* back to prvProcessReceivedCommands */ + /* prvReloadTimer */ + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* back to prvProcessReceivedCommands */ + /* prvReloadTimer */ + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* back to prvProcessReceivedCommands */ + /* callback called ending the test */ + /* xQueueReceive_AddCallback(end_queue_receive); */ + + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_FALSE( port_yield_within_api_called ); + ASSERT_PENDED_FUNCTION_4_END_CALLED(); +} + +void test_timer_function_success6( void ) +{ + Timer_t xTimer = { 0 }; + pthread_t thread_id; + int * retVal; + CallbackParameters_t callback_param; + + /* Setup */ + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + end_1_timer = 2; + DaemonTaskMessage_t xMessage; + xMessage.xMessageID = tmrCOMMAND_START; + xMessage.u.xCallbackParameters = callback_param; + xMessage.u.xTimerParameters.pxTimer = &xTimer; + xTimer.ucStatus = 0; + xTimer.xTimerPeriodInTicks = 0; + xTimer.pxCallbackFunction = xCallback_Test_1_end; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /*listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); */ + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 500 ); /* time now / static last_time = 0 */ + saved_last_time += 500; + /* prvSwitchTimerLists */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + /* back to prvProcessTimerOrBlockTask */ + vQueueWaitForMessageRestricted_ExpectAnyArgs(); + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* yield called */ + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, + sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvSampleTimeNow*/ + xTaskGetTickCount_ExpectAndReturn( saved_last_time - 50 ); /* time now / static last_time = 0 */ + saved_last_time -= 50; + /* prvSwitchTimerLists */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAnyArgsAndReturn( pdFAIL ); + /* back prvTimerTask */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( saved_last_time + 1 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time - 5 ); /* time now / static last_time = 0 */ + saved_last_time -= 5; + /* prvSwitchTimerLists */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /* back prvProcessTimerOrBlockTask */ + xTaskResumeAll_ExpectAndReturn( pdFALSE ); + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, + sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvInsertTimerInActiveList */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time - 50 ); /* time now / static last_time = 0 */ + saved_last_time -= 50; + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, *retVal ); +} + +void test_timer_function_success2( void ) +{ + Timer_t xTimer = { 0 }; + pthread_t thread_id; + int * retVal; + DaemonTaskMessage_t xMessage; + CallbackParameters_t callback_param; + + end_4_timer = 1; + + /* Setup */ + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer.xTimerPeriodInTicks = UINT32_MAX; + xTimer.pxCallbackFunction = xCallback_Test; + + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + xMessage.xMessageID = -1; + xMessage.u.xCallbackParameters = callback_param; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 500 ); /* time now / static last_time = 0 */ + saved_last_time += 500; + /* back to prvProcessTimerOrBlockTask */ + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAndReturn( &xTimer.xTimerListItem, pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + vListInsert_ExpectAnyArgs(); + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, sizeof( DaemonTaskMessage_t ) ); + + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /*prvTimerTask(pvParameters); */ + /* Validations */ + TEST_ASSERT_EQUAL( 4, *retVal ); + ASSERT_XCALLBACK_TEST_CALLED(); +} +void test_timer_function_success3_command_start( void ) +{ + Timer_t xTimer = { 0 }; + pthread_t thread_id; + int * retVal; + + end_2_timer = 2; + + /* Setup */ + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer.pxCallbackFunction = xCallback_Test_2_end; + xTimer.xTimerPeriodInTicks = 0; + + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 100 ); /* time now / static last_time = 0 */ + saved_last_time += 100; + /* back to prvProcessTimerOrBlockTask */ + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAndReturn( &xTimer.xTimerListItem, pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* prvProcessReceivedCommands */ + saved_last_time -= 50; + + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 2, *retVal ); +} + +void test_timer_function_success3_command_start2( void ) +{ + Timer_t xTimer = { 0 }; + pthread_t thread_id; + int * retVal; + + end_2_timer = 2; + + /* Setup */ + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer.pxCallbackFunction = xCallback_Test_2_end; + xTimer.xTimerPeriodInTicks = 0; + + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 100 ); /* time now / static last_time = 0 */ + saved_last_time += 100; + /* back to prvProcessTimerOrBlockTask */ + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAndReturn( &xTimer.xTimerListItem, pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + /* prvProcessReceivedCommands */ + saved_last_time -= 50; + + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 2, *retVal ); +} + +void test_timer_function_success3_command_start3( void ) +{ + Timer_t xTimer = { 0 }; + pthread_t thread_id; + int * retVal; + + end_2_timer = 3; + + /* Setup */ + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer.pxCallbackFunction = xCallback_Test_2_end; + xTimer.xTimerPeriodInTicks = 0; + + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 100 ); /* time now / static last_time = 0 */ + saved_last_time += 100; + /* back to prvProcessTimerOrBlockTask */ + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAndReturn( &xTimer.xTimerListItem, pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + saved_last_time -= 50; + + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 2, *retVal ); +} + +void test_timer_function_success3_command_start4( void ) +{ + Timer_t xTimer = { 0 }; + pthread_t thread_id; + int * retVal; + DaemonTaskMessage_t xMessage; + CallbackParameters_t callback_param; + + end_2_timer = 3; + + /* Setup */ + xTimer.ucStatus &= ~tmrSTATUS_IS_AUTORELOAD; + xTimer.pxCallbackFunction = xCallback_Test_2_end; + xTimer.xTimerPeriodInTicks = 0; + + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + xMessage.xMessageID = tmrCOMMAND_START; + xMessage.u.xCallbackParameters = callback_param; + xMessage.u.xTimerParameters.pxTimer = &xTimer; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 100 ); /* time now / static last_time = 0 */ + saved_last_time += 100; + /* back to prvProcessTimerOrBlockTask */ + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAndReturn( &xTimer.xTimerListItem, pdTRUE ); + /* prvInsertTimerInActiveList */ + /*listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); */ + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvSampleTimeNow*/ + xTaskGetTickCount_ExpectAndReturn( saved_last_time - 50 ); /* time now / static last_time = 0 */ + saved_last_time -= 50; + /* prvSwitchTimerLists */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 600 ); + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 2, *retVal ); +} + +void test_timer_function_success3_command_start5( void ) +{ + Timer_t xTimer = { 0 }; + Timer_t xTimer2 = { 0 }; + pthread_t thread_id; + int * retVal; + + DaemonTaskMessage_t xMessage; + DaemonTaskMessage_t xMessage2; + CallbackParameters_t callback_param; + + end_2_timer = 2; + end_4_timer = 1; + + /* Setup */ + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer.pxCallbackFunction = xCallback_Test_2_end; + xTimer.xTimerPeriodInTicks = UINT32_MAX; + + xTimer2.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer2.pxCallbackFunction = xCallback_Test_2_end; + xTimer2.xTimerPeriodInTicks = saved_last_time + 50; + + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + + xMessage.xMessageID = tmrCOMMAND_START; + xMessage.u.xCallbackParameters = callback_param; + xMessage.u.xTimerParameters.pxTimer = &xTimer; + xMessage.u.xTimerParameters.xMessageValue = saved_last_time - 500; + + xMessage2.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; + xMessage2.u.xCallbackParameters = callback_param; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 1000 ); /* time now / static last_time = 0 */ + saved_last_time += 1000; + /* back to prvProcessTimerOrBlockTask */ + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAndReturn( &xTimer.xTimerListItem, pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + vListInsert_ExpectAnyArgs(); + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvSampleTimeNow*/ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 5000 ); /* time now / static last_time = 0 */ + saved_last_time += 5000; + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + vListInsert_ExpectAnyArgs(); + /* back to prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage2, sizeof( DaemonTaskMessage_t ) ); + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 4, *retVal ); +} + +void test_timer_function_success3_command_stop( void ) +{ + Timer_t xTimer = { 0 }; + Timer_t xTimer2 = { 0 }; + pthread_t thread_id; + int * retVal; + + DaemonTaskMessage_t xMessage; + DaemonTaskMessage_t xMessage2; + CallbackParameters_t callback_param; + + end_2_timer = 2; + end_4_timer = 1; + + /* Setup */ + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer.ucStatus |= tmrSTATUS_IS_ACTIVE; + xTimer.pxCallbackFunction = xCallback_Test_2_end; + xTimer.xTimerPeriodInTicks = UINT32_MAX; + + xTimer2.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer2.pxCallbackFunction = xCallback_Test_2_end; + xTimer2.xTimerPeriodInTicks = saved_last_time + 50; + + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + + xMessage.xMessageID = tmrCOMMAND_STOP; + xMessage.u.xCallbackParameters = callback_param; + xMessage.u.xTimerParameters.pxTimer = &xTimer; + xMessage.u.xTimerParameters.xMessageValue = saved_last_time - 500; + + xMessage2.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; /* used to end the loop */ + xMessage2.u.xCallbackParameters = callback_param; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 1000 ); /* time now / static last_time = 0 */ + saved_last_time += 1000; + /* back to prvProcessTimerOrBlockTask */ + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAndReturn( &xTimer.xTimerListItem, pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + vListInsert_ExpectAnyArgs(); + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvSampleTimeNow*/ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 5000 ); /* time now / static last_time = 0 */ + saved_last_time += 5000; + /* back to prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage2, sizeof( DaemonTaskMessage_t ) ); + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 4, *retVal ); + TEST_ASSERT_FALSE( xTimer.ucStatus & tmrSTATUS_IS_ACTIVE ); +} + +void test_timer_function_success3_command_change_period( void ) +{ + Timer_t xTimer = { 0 }; + Timer_t xTimer2 = { 0 }; + pthread_t thread_id; + int * retVal; + + DaemonTaskMessage_t xMessage; + DaemonTaskMessage_t xMessage2; + CallbackParameters_t callback_param; + + end_2_timer = 2; + end_4_timer = 1; + + /* Setup */ + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer.ucStatus &= ~tmrSTATUS_IS_ACTIVE; + xTimer.pxCallbackFunction = xCallback_Test_2_end; + xTimer.xTimerPeriodInTicks = UINT32_MAX; + + xTimer2.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer2.pxCallbackFunction = xCallback_Test_2_end; + xTimer2.xTimerPeriodInTicks = saved_last_time; + + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + + xMessage.xMessageID = tmrCOMMAND_CHANGE_PERIOD; + xMessage.u.xCallbackParameters = callback_param; + xMessage.u.xTimerParameters.pxTimer = &xTimer; + xMessage.u.xTimerParameters.xMessageValue = saved_last_time; + + xMessage2.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; /* used to end the loop */ + xMessage2.u.xCallbackParameters = callback_param; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time ); /* time now / static last_time = 0 */ + /* back to prvProcessTimerOrBlockTask */ + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAndReturn( &xTimer.xTimerListItem, pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + vListInsert_ExpectAnyArgs(); + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvSampleTimeNow*/ + xTaskGetTickCount_ExpectAndReturn( saved_last_time ); /* time now / static last_time = 0 */ + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + vListInsert_ExpectAnyArgs(); + /* back to prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage2, sizeof( DaemonTaskMessage_t ) ); + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 4, *retVal ); + TEST_ASSERT_TRUE( xTimer.ucStatus & tmrSTATUS_IS_ACTIVE ); + TEST_ASSERT_EQUAL( saved_last_time, xTimer.xTimerPeriodInTicks ); +} + +void test_timer_function_success3_command_delete_static( void ) +{ + Timer_t xTimer = { 0 }; + Timer_t xTimer2 = { 0 }; + pthread_t thread_id; + int * retVal; + + DaemonTaskMessage_t xMessage; + DaemonTaskMessage_t xMessage2; + CallbackParameters_t callback_param; + + end_2_timer = 2; + end_4_timer = 1; + + /* Setup */ + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer.ucStatus |= tmrSTATUS_IS_STATICALLY_ALLOCATED; + xTimer.ucStatus &= ~tmrSTATUS_IS_ACTIVE; + xTimer.pxCallbackFunction = xCallback_Test_2_end; + xTimer.xTimerPeriodInTicks = UINT32_MAX; + + xTimer2.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer2.pxCallbackFunction = xCallback_Test_2_end; + xTimer2.xTimerPeriodInTicks = saved_last_time; + + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + + xMessage.xMessageID = tmrCOMMAND_DELETE; + xMessage.u.xCallbackParameters = callback_param; + xMessage.u.xTimerParameters.pxTimer = &xTimer; + xMessage.u.xTimerParameters.xMessageValue = saved_last_time; + + xMessage2.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; /* used to end the loop */ + xMessage2.u.xCallbackParameters = callback_param; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time ); /* time now / static last_time = 0 */ + /* back to prvProcessTimerOrBlockTask */ + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAndReturn( &xTimer.xTimerListItem, pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + vListInsert_ExpectAnyArgs(); + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvSampleTimeNow*/ + xTaskGetTickCount_ExpectAndReturn( saved_last_time ); /* time now / static last_time = 0 */ + /* back to prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage2, sizeof( DaemonTaskMessage_t ) ); + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 4, *retVal ); + TEST_ASSERT_FALSE( xTimer.ucStatus & tmrSTATUS_IS_ACTIVE ); +} + + +void test_timer_function_success3_command_unknown( void ) +{ + Timer_t xTimer = { 0 }; + Timer_t xTimer2 = { 0 }; + pthread_t thread_id; + int * retVal; + + DaemonTaskMessage_t xMessage; + DaemonTaskMessage_t xMessage2; + CallbackParameters_t callback_param; + + end_2_timer = 2; + end_4_timer = 1; + + /* Setup */ + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer.ucStatus &= ~tmrSTATUS_IS_STATICALLY_ALLOCATED; + xTimer.ucStatus &= ~tmrSTATUS_IS_ACTIVE; + xTimer.pxCallbackFunction = xCallback_Test_2_end; + xTimer.xTimerPeriodInTicks = UINT32_MAX; + + xTimer2.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer2.pxCallbackFunction = xCallback_Test_2_end; + xTimer2.xTimerPeriodInTicks = saved_last_time; + + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + + xMessage.xMessageID = tmrCOMMAND_CHANGE_PERIOD_FROM_ISR + 1; + xMessage.u.xCallbackParameters = callback_param; + xMessage.u.xTimerParameters.pxTimer = &xTimer; + xMessage.u.xTimerParameters.xMessageValue = saved_last_time; + + xMessage2.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; /* used to end the loop */ + xMessage2.u.xCallbackParameters = callback_param; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time ); /* time now / static last_time = 0 */ + /* back to prvProcessTimerOrBlockTask */ + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAndReturn( &xTimer.xTimerListItem, pdTRUE ); + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + vListInsert_ExpectAnyArgs(); + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvSampleTimeNow*/ + xTaskGetTickCount_ExpectAndReturn( saved_last_time ); /* time now / static last_time = 0 */ + /* back to prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage2, sizeof( DaemonTaskMessage_t ) ); + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 4, *retVal ); +} + +void test_timer_function_success_wrap_timer( void ) +{ + Timer_t xTimer = { 0 }; + pthread_t thread_id; + int * retVal; + CallbackParameters_t callback_param; + + /* Setup */ + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + end_1_timer = 2; + end_4_timer = 2; + DaemonTaskMessage_t xMessage; + + xMessage.xMessageID = tmrCOMMAND_START; + xMessage.u.xCallbackParameters = callback_param; + xMessage.u.xTimerParameters.pxTimer = &xTimer; + xMessage.u.xTimerParameters.xMessageValue = saved_last_time + 600; + + xTimer.xTimerPeriodInTicks = UINT32_MAX; + xTimer.pxCallbackFunction = xCallback_Test_1_end; + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /*listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); */ + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time + 500 ); /* time now / static last_time = 0 */ + saved_last_time += 500; + /* back to prvProcessTimerOrBlockTask */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + vQueueWaitForMessageRestricted_ExpectAnyArgs(); + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* yield called */ + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, + sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + + + /* prvSampleTimeNow*/ + xTaskGetTickCount_ExpectAndReturn( saved_last_time - 50 ); /* time now / static last_time = 0 */ + saved_last_time -= 50; + /* prvSwitchTimerLists */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 50 ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvReloadTimer */ + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + vListInsert_ExpectAnyArgs(); + /* callback called in prvProcessExpiredtimer */ + /* back prvSwitchTimerLists */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdTRUE ); + /* back prvSampleTimeNow */ + /* back prvProcessReceivedCommands */ + + + /* prvInsertTimerInActiveList */ + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + vListInsert_ExpectAnyArgs(); + /* back prvProcessReceivedCommands */ + + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, + sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time - 50 ); /* time now / static last_time = 0 */ + saved_last_time -= 50; + /* prvSwitchTimerLists */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 50 ); + /* prvProcessExpiredTimer */ + listGET_OWNER_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( &xTimer ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + listSET_LIST_ITEM_VALUE_ExpectAnyArgs(); + vListInsert_ExpectAnyArgs(); + + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 1, *retVal ); +} diff --git a/FreeRTOS/Test/CMock/timers/timers_dynamic_utest.c b/FreeRTOS/Test/CMock/timers/timers_dynamic_utest.c new file mode 100644 index 0000000000..179883d10e --- /dev/null +++ b/FreeRTOS/Test/CMock/timers/timers_dynamic_utest.c @@ -0,0 +1,482 @@ +/* + * FreeRTOS V202112.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 timers_utest.c */ + + +/* Test includes. */ +#include "FreeRTOS.h" +#include "FreeRTOSConfig.h" +#include "portmacro.h" +#include "timers.h" + +#include "global_vars.h" + +#include "unity.h" +#include "unity_memory.h" + +/* Mock includes. */ +#include "mock_queue.h" +#include "mock_list.h" +#include "mock_list_macros.h" +#include "mock_fake_assert.h" +#include "mock_portable.h" +#include "mock_task.h" + +/* C runtime includes. */ +#include +#include +#include + +void stopTimers(); + +/* ============================ GLOBAL VARIABLES =========================== */ +static uint16_t usMallocFreeCalls = 0; +static uint32_t critical_section_counter; +static bool port_yield_within_api_called = false; +static TickType_t saved_last_time = 0; + +/* ============================= FUNCTION HOOKS =========================== */ +void vFakePortEnterCriticalSection( void ) +{ + critical_section_counter++; +} + +void vFakePortExitCriticalSection( void ) +{ + critical_section_counter--; +} + +void vFakePortYieldWithinAPI() +{ + HOOK_DIAG(); + port_yield_within_api_called = true; + pthread_exit( NULL ); +} + +void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, + StackType_t ** ppxTimerTaskStackBuffer, + uint32_t * pulTimerTaskStackSize ) +{ + static StaticTask_t xTimerTaskTCB; + static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; + + *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; + *ppxTimerTaskStackBuffer = uxTimerTaskStack; + *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; +} + +void vApplicationDaemonTaskStartupHook( void ) +{ + HOOK_DIAG(); +} +/* ========================== CALLBACK FUNCTIONS =========================== */ +static void xCallback_Test( TimerHandle_t xTimer ) +{ + HOOK_DIAG(); +} + +static int32_t end_2_timer = 0; +static void xCallback_Test_2_end( TimerHandle_t xTimer ) +{ + HOOK_DIAG(); + static int i = 2; + + if( end_2_timer - 1 <= 0 ) + { + pthread_exit( &i ); + } + + end_2_timer--; +} + +static int32_t end_4_timer = 0; +static void pended_function_4_end( void * arg1, + uint32_t arg2 ) +{ + HOOK_DIAG(); + static int i = 4; + + if( end_4_timer - 1 <= 0 ) + { + pthread_exit( &i ); + } + + end_4_timer--; +} + +/* ============================ STATIC FUNCTIONS =========================== */ +static void * timer_thread_function( void * args ) +{ + void * pvParameters = NULL; + + portTASK_FUNCTION( prvTimerTask, pvParameters ); + ( void ) fool_static2; /* ignore unused variable warning */ + /* API Call */ + prvTimerTask( pvParameters ); + return NULL; +} + +/* ============================== UNITY FIXTURES ========================== */ + +void setUp( void ) +{ + vFakeAssert_Ignore(); + port_yield_within_api_called = false; + /* Track calls to malloc / free */ + UnityMalloc_StartTest(); + critical_section_counter = 0; + end_2_timer = 0; + end_4_timer = 0; + stopTimers(); +} + +/*! called before each testcase */ +void tearDown( void ) +{ + TEST_ASSERT_EQUAL_INT_MESSAGE( 0, usMallocFreeCalls, + "free is not called the same number of times as malloc," + "you might have a memory leak!!" ); + usMallocFreeCalls = 0; + + 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; +} + + +/* ============================== TEST FUNCTIONS ========================== */ + +/** + * @brief xTimerCreate happy path + * + */ +void test_xTimerCreateTimerTask_success( void ) +{ + BaseType_t ret_xtimer; + QueueHandle_t queue_handle = ( QueueHandle_t ) 3; /* not zero */ + + /* Setup */ + /* Expectations */ + vListInitialise_ExpectAnyArgs(); + vListInitialise_ExpectAnyArgs(); + xQueueGenericCreate_ExpectAnyArgsAndReturn( queue_handle ); + vQueueAddToRegistry_ExpectAnyArgs(); + xTaskCreate_ExpectAnyArgsAndReturn( pdTRUE ); + /* API Call */ + ret_xtimer = xTimerCreateTimerTask(); + /* Validations */ + TEST_ASSERT_TRUE( ret_xtimer ); +} + + +/** + * @brief xTimerCreate happy path + * + */ +void test_xTimerCreate_success( void ) +{ + uint32_t ulID = 0; + TimerHandle_t xTimer = NULL; + Timer_t pxNewTimer; + QueueHandle_t queue_handle = ( QueueHandle_t ) 3; /* not zero */ + + pvPortMalloc_ExpectAndReturn( sizeof( Timer_t ), &pxNewTimer ); + vListInitialise_ExpectAnyArgs(); + vListInitialise_ExpectAnyArgs(); + xQueueGenericCreate_ExpectAnyArgsAndReturn( queue_handle ); + vQueueAddToRegistry_ExpectAnyArgs(); + vListInitialiseItem_ExpectAnyArgs(); + + xTimer = xTimerCreate( "ut-timer", + pdMS_TO_TICKS( 1000 ), + pdTRUE, + &ulID, + xCallback_Test ); + + TEST_ASSERT_NOT_EQUAL( NULL, xTimer ); + TEST_ASSERT_EQUAL_PTR( &pxNewTimer, xTimer ); + TEST_ASSERT_EQUAL( tmrSTATUS_IS_AUTORELOAD, pxNewTimer.ucStatus ); + TEST_ASSERT_EQUAL_STRING( "ut-timer", pxNewTimer.pcTimerName ); + TEST_ASSERT_EQUAL( pdMS_TO_TICKS( 1000 ), pxNewTimer.xTimerPeriodInTicks ); + TEST_ASSERT_EQUAL_PTR( &ulID, pxNewTimer.pvTimerID ); + TEST_ASSERT_EQUAL_PTR( xCallback_Test, pxNewTimer.pxCallbackFunction ); +} + +void test_xTimerCreate_success_no_auto_reload( void ) +{ + uint32_t ulID = 0; + TimerHandle_t xTimer = NULL; + Timer_t pxNewTimer; + QueueHandle_t queue_handle = ( QueueHandle_t ) 3; /* not zero */ + + pvPortMalloc_ExpectAndReturn( sizeof( Timer_t ), &pxNewTimer ); + vListInitialise_ExpectAnyArgs(); + vListInitialise_ExpectAnyArgs(); + xQueueGenericCreate_ExpectAnyArgsAndReturn( queue_handle ); + vQueueAddToRegistry_ExpectAnyArgs(); + vListInitialiseItem_ExpectAnyArgs(); + + xTimer = xTimerCreate( "ut-timer", + pdMS_TO_TICKS( 1000 ), + pdFALSE, + &ulID, + xCallback_Test ); + + TEST_ASSERT_EQUAL_PTR( &pxNewTimer, xTimer ); + TEST_ASSERT_EQUAL( 0, pxNewTimer.ucStatus ); +} + +void test_xTimerCreate_success_twice( void ) +{ + uint32_t ulID = 0; + TimerHandle_t xTimer = NULL; + Timer_t pxNewTimer; + QueueHandle_t queue_handle = ( QueueHandle_t ) 3; /* not zero */ + + pvPortMalloc_ExpectAndReturn( sizeof( Timer_t ), &pxNewTimer ); + /* prvInitialiseNewTimer */ + /* prvCheckForValidListAndQueue */ + vListInitialise_ExpectAnyArgs(); + vListInitialise_ExpectAnyArgs(); + xQueueGenericCreate_ExpectAnyArgsAndReturn( queue_handle ); + vQueueAddToRegistry_ExpectAnyArgs(); + /* back prvInitialiseNewTimer */ + vListInitialiseItem_ExpectAnyArgs(); + + xTimer = xTimerCreate( "ut-timer", + pdMS_TO_TICKS( 1000 ), + pdTRUE, + &ulID, + xCallback_Test ); + + TEST_ASSERT_EQUAL_PTR( &pxNewTimer, xTimer ); + TEST_ASSERT_EQUAL_PTR( &pxNewTimer, xTimer ); + TEST_ASSERT_EQUAL( tmrSTATUS_IS_AUTORELOAD, pxNewTimer.ucStatus ); + TEST_ASSERT_EQUAL_STRING( "ut-timer", pxNewTimer.pcTimerName ); + TEST_ASSERT_EQUAL( pdMS_TO_TICKS( 1000 ), pxNewTimer.xTimerPeriodInTicks ); + TEST_ASSERT_EQUAL_PTR( &ulID, pxNewTimer.pvTimerID ); + TEST_ASSERT_EQUAL_PTR( xCallback_Test, pxNewTimer.pxCallbackFunction ); + + /* Second call to xTimerCreate */ + pvPortMalloc_ExpectAndReturn( sizeof( Timer_t ), &pxNewTimer ); + vListInitialiseItem_ExpectAnyArgs(); + xTimer = xTimerCreate( "ut-timer", + pdMS_TO_TICKS( 1000 ), + pdTRUE, + &ulID, + xCallback_Test ); + TEST_ASSERT_EQUAL_PTR( &pxNewTimer, xTimer ); +} + +void test_xTimerCreate_fail_timer_allocation( void ) +{ + uint32_t ulID = 0; + TimerHandle_t xTimer = NULL; + + pvPortMalloc_ExpectAndReturn( sizeof( Timer_t ), NULL ); + + xTimer = xTimerCreate( "ut-timer", + pdMS_TO_TICKS( 1000 ), + pdTRUE, + &ulID, + xCallback_Test ); + + TEST_ASSERT_EQUAL( NULL, xTimer ); +} +void test_xTimerCreate_fail_queue_allocation( void ) +{ + uint32_t ulID = 0; + Timer_t pxNewTimer; + TimerHandle_t xTimer = NULL; + + /* Expectations */ + pvPortMalloc_ExpectAndReturn( sizeof( Timer_t ), &pxNewTimer ); + /* prvInitialiseNewTimer */ + /* prvCheckForValidListAndQueue */ + vListInitialise_ExpectAnyArgs(); + vListInitialise_ExpectAnyArgs(); + xQueueGenericCreate_ExpectAnyArgsAndReturn( NULL ); + /* Back prvInitialiseNewTimer */ + vListInitialiseItem_ExpectAnyArgs(); + + /* API Call */ + xTimer = xTimerCreate( "ut-timer", + pdMS_TO_TICKS( 1000 ), + pdTRUE, + &ulID, + xCallback_Test ); + /* Validations */ + TEST_ASSERT_EQUAL( &pxNewTimer, xTimer ); +} + +void test_timer_function_success3_command_delete_dynamic( void ) +{ + Timer_t xTimer = { 0 }; + Timer_t xTimer2 = { 0 }; + pthread_t thread_id; + int * retVal; + + DaemonTaskMessage_t xMessage; + DaemonTaskMessage_t xMessage2; + CallbackParameters_t callback_param; + + end_2_timer = 2; + end_4_timer = 1; + + /* Setup */ + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer.ucStatus &= ~tmrSTATUS_IS_STATICALLY_ALLOCATED; + xTimer.ucStatus &= ~tmrSTATUS_IS_ACTIVE; + xTimer.pxCallbackFunction = xCallback_Test_2_end; + xTimer.xTimerPeriodInTicks = UINT32_MAX; + + xTimer2.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer2.pxCallbackFunction = xCallback_Test_2_end; + xTimer2.xTimerPeriodInTicks = saved_last_time; + + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + + xMessage.xMessageID = tmrCOMMAND_DELETE; + xMessage.u.xCallbackParameters = callback_param; + xMessage.u.xTimerParameters.pxTimer = &xTimer; + xMessage.u.xTimerParameters.xMessageValue = saved_last_time; + + xMessage2.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; /* used to end the loop */ + xMessage2.u.xCallbackParameters = callback_param; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time ); /* time now / static last_time = 0 */ + /* back to prvProcessTimerOrBlockTask */ + vQueueWaitForMessageRestricted_ExpectAnyArgs(); + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvSampleTimeNow*/ + xTaskGetTickCount_ExpectAndReturn( saved_last_time ); /* time now / static last_time = 0 */ + vPortFree_Expect( &xTimer ); /* testcase is testing this clause */ + /* back to prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage2, sizeof( DaemonTaskMessage_t ) ); + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 4, *retVal ); +} + +void test_timer_function_success3_command_delete_static( void ) +{ + Timer_t xTimer = { 0 }; + Timer_t xTimer2 = { 0 }; + pthread_t thread_id; + int * retVal; + + DaemonTaskMessage_t xMessage; + DaemonTaskMessage_t xMessage2; + CallbackParameters_t callback_param; + + end_2_timer = 2; + end_4_timer = 1; + + /* Setup */ + xTimer.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer.ucStatus |= tmrSTATUS_IS_STATICALLY_ALLOCATED; + xTimer.ucStatus &= ~tmrSTATUS_IS_ACTIVE; + xTimer.pxCallbackFunction = xCallback_Test_2_end; + xTimer.xTimerPeriodInTicks = UINT32_MAX; + + xTimer2.ucStatus |= tmrSTATUS_IS_AUTORELOAD; + xTimer2.pxCallbackFunction = xCallback_Test_2_end; + xTimer2.xTimerPeriodInTicks = saved_last_time; + + callback_param.pxCallbackFunction = &pended_function_4_end; + callback_param.pvParameter1 = NULL; + callback_param.ulParameter2 = 0xa9a9a9a9; + + xMessage.xMessageID = tmrCOMMAND_DELETE; + xMessage.u.xCallbackParameters = callback_param; + xMessage.u.xTimerParameters.pxTimer = &xTimer; + xMessage.u.xTimerParameters.xMessageValue = saved_last_time; + + xMessage2.xMessageID = tmrCOMMAND_EXECUTE_CALLBACK; /* used to end the loop */ + xMessage2.u.xCallbackParameters = callback_param; + /* Expectations */ + /* prvGetNextExpireTime */ + listLIST_IS_EMPTY_ExpectAnyArgsAndReturn( pdFALSE ); + listGET_ITEM_VALUE_OF_HEAD_ENTRY_ExpectAnyArgsAndReturn( 3 ); + /* prvProcessTimerOrBlockTask */ + vTaskSuspendAll_Expect(); + /* prvSampleTimeNow */ + xTaskGetTickCount_ExpectAndReturn( saved_last_time ); /* time now / static last_time = 0 */ + /* back to prvProcessTimerOrBlockTask */ + vQueueWaitForMessageRestricted_ExpectAnyArgs(); + xTaskResumeAll_ExpectAndReturn( pdTRUE ); + /* prvProcessExpiredTimer */ + /* prvInsertTimerInActiveList */ + /* prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage, sizeof( DaemonTaskMessage_t ) ); + listIS_CONTAINED_WITHIN_ExpectAnyArgsAndReturn( pdFALSE ); + uxListRemove_ExpectAnyArgsAndReturn( pdTRUE ); + /* prvSampleTimeNow*/ + xTaskGetTickCount_ExpectAndReturn( saved_last_time ); /* time now / static last_time = 0 */ + /* back to prvProcessReceivedCommands */ + xQueueReceive_ExpectAndReturn( NULL, NULL, tmrNO_DELAY, pdPASS ); + xQueueReceive_IgnoreArg_xQueue(); + xQueueReceive_IgnoreArg_pvBuffer(); + xQueueReceive_ReturnMemThruPtr_pvBuffer( &xMessage2, sizeof( DaemonTaskMessage_t ) ); + /* API Call */ + pthread_create( &thread_id, NULL, &timer_thread_function, NULL ); + pthread_join( thread_id, ( void ** ) &retVal ); + /* Validations */ + TEST_ASSERT_EQUAL( 4, *retVal ); + TEST_ASSERT_FALSE( xTimer.ucStatus & tmrSTATUS_IS_ACTIVE ); +} diff --git a/FreeRTOS/Test/CMock/timers/timers_utest.c b/FreeRTOS/Test/CMock/timers/timers_utest.c deleted file mode 100644 index 37ca61acbe..0000000000 --- a/FreeRTOS/Test/CMock/timers/timers_utest.c +++ /dev/null @@ -1,136 +0,0 @@ -/* - * FreeRTOS V202112.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 timers_utest.c */ - -/* C runtime includes. */ -#include -#include - -/* Test includes. */ -#include "FreeRTOS.h" -#include "FreeRTOSConfig.h" -#include "timers.h" -#include "unity.h" -#include "unity_memory.h" - -/* Mock includes. */ -#include "mock_queue.h" -#include "mock_list.h" -#include "mock_fake_assert.h" - - -/* ============================ GLOBAL VARIABLES =========================== */ -static uint16_t usMallocFreeCalls = 0; - -/* ========================== CALLBACK FUNCTIONS =========================== */ - -void * pvPortMalloc( size_t xSize ) -{ - return unity_malloc( xSize ); -} -void vPortFree( void * pv ) -{ - return unity_free( pv ); -} - -/******************************************************************************* - * Unity fixtures - ******************************************************************************/ -void setUp( void ) -{ - vFakeAssert_Ignore(); - - /* Track calls to malloc / free */ - UnityMalloc_StartTest(); -} - -/*! called before each testcase */ -void tearDown( void ) -{ - TEST_ASSERT_EQUAL_INT_MESSAGE( 0, usMallocFreeCalls, - "free is not called the same number of times as malloc," - "you might have a memory leak!!" ); - usMallocFreeCalls = 0; - - 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 void xCallback_Test( TimerHandle_t xTimer ) -{ -} - -/** - * @brief xTimerCreate happy path - * - */ -void test_xTimerCreate_Success( void ) -{ - uint32_t ulID = 0; - TimerHandle_t xTimer = NULL; - - vListInitialise_Ignore(); - xQueueGenericCreateStatic_IgnoreAndReturn( ( QueueHandle_t ) 1 ); - vQueueAddToRegistry_Ignore(); - vListInitialiseItem_Ignore(); - - xTimer = xTimerCreate( "ut-timer", - pdMS_TO_TICKS( 1000 ), - pdTRUE, - &ulID, - xCallback_Test ); - - TEST_ASSERT_NOT_EQUAL( NULL, xTimer ); - - /* HACK: Free the timer directly */ - vPortFree( ( void * ) xTimer ); -} - -void vApplicationGetTimerTaskMemory( StaticTask_t ** ppxTimerTaskTCBBuffer, - StackType_t ** ppxTimerTaskStackBuffer, - uint32_t * pulTimerTaskStackSize ) -{ - static StaticTask_t xTimerTaskTCB; - static StackType_t uxTimerTaskStack[ configTIMER_TASK_STACK_DEPTH ]; - - *ppxTimerTaskTCBBuffer = &xTimerTaskTCB; - *ppxTimerTaskStackBuffer = uxTimerTaskStack; - *pulTimerTaskStackSize = configTIMER_TASK_STACK_DEPTH; -} - -void vApplicationDaemonTaskStartupHook( void ) -{ -} diff --git a/FreeRTOS/Test/CMock/tools/callgraph.py b/FreeRTOS/Test/CMock/tools/callgraph.py index cc9d575647..7f67ed8ff4 100755 --- a/FreeRTOS/Test/CMock/tools/callgraph.py +++ b/FreeRTOS/Test/CMock/tools/callgraph.py @@ -77,6 +77,10 @@ ret = subprocess.run( capture_output=True, ) +if ret.stderr.decode("utf-8"): + print (ret.stderr.decode("utf-8")) + sys.exit(1) + lineregex = ( r"^{\s*(?P\d+)} \s*" r"(?P\S*)\(\) \<.* at "