From 0f569ff957c24b9fc46c16dd1dbea030d00f9dd7 Mon Sep 17 00:00:00 2001 From: Joseph Hickey Date: Tue, 17 Aug 2021 14:03:20 -0400 Subject: [PATCH] Fix #1866, Add ES API test cases Adds ES functional test cases to cover all missing items that were identified as part of the scrub in issue #1724. Where a specific condition is not testable because it requires a failure of another subsystem, it is marked as `covtest` to indicate it is only verifiable in coverage test environment. --- modules/cfe_testcase/src/cfe_test.h | 2 +- modules/cfe_testcase/src/es_counter_test.c | 22 +++-- modules/cfe_testcase/src/es_info_test.c | 26 +++-- modules/cfe_testcase/src/es_mempool_test.c | 95 ++++++++++++++---- modules/cfe_testcase/src/es_misc_test.c | 28 +++++- modules/cfe_testcase/src/es_task_test.c | 106 ++++++++++++++++++++- modules/core_api/fsw/inc/cfe_es.h | 15 ++- 7 files changed, 238 insertions(+), 56 deletions(-) diff --git a/modules/cfe_testcase/src/cfe_test.h b/modules/cfe_testcase/src/cfe_test.h index f011eab3b..e156a8c1d 100644 --- a/modules/cfe_testcase/src/cfe_test.h +++ b/modules/cfe_testcase/src/cfe_test.h @@ -50,7 +50,7 @@ typedef struct CFE_FS_FileWriteMetaData_t FuncTestState; /* Generic utility counter */ - int Count; + int32 Count; /* Table information used by all table tests */ CFE_TBL_Handle_t TblHandle; diff --git a/modules/cfe_testcase/src/es_counter_test.c b/modules/cfe_testcase/src/es_counter_test.c index 544d0fa4d..8dbda779d 100644 --- a/modules/cfe_testcase/src/es_counter_test.c +++ b/modules/cfe_testcase/src/es_counter_test.c @@ -30,7 +30,7 @@ void TestCounterCreateDelete(void) { - CFE_ES_CounterId_t Ids[CFE_PLATFORM_ES_MAX_GEN_COUNTERS]; + CFE_ES_CounterId_t Ids[CFE_PLATFORM_ES_MAX_GEN_COUNTERS + 1]; CFE_ES_CounterId_t TestId; CFE_ES_CounterId_t CheckId; char CounterName[CFE_MISSION_MAX_API_LEN]; @@ -48,22 +48,26 @@ void TestCounterCreateDelete(void) UtAssert_INT32_EQ(CFE_ES_RegisterGenCounter(NULL, CounterName), CFE_ES_BAD_ARGUMENT); /* Create up to CFE_PLATFORM_ES_MAX_GEN_COUNTERS and confirm success */ - for (NumCounters = 0; NumCounters < CFE_PLATFORM_ES_MAX_GEN_COUNTERS; ++NumCounters) + /* Note that this loop may execute fewer than CFE_PLATFORM_ES_MAX_GEN_COUNTERS times, + * if another unrelated app has already registered a counter. Because this test + * cannot control for those pre-conditions, anything within range is acceptable */ + for (NumCounters = 0; NumCounters <= CFE_PLATFORM_ES_MAX_GEN_COUNTERS; ++NumCounters) { snprintf(CounterName, sizeof(CounterName), "C%u", (unsigned int)NumCounters); - Status = CFE_ES_RegisterGenCounter(&Ids[NumCounters], CounterName); - if (Status != CFE_SUCCESS) + CFE_Assert_STATUS_STORE(CFE_ES_RegisterGenCounter(&Ids[NumCounters], CounterName)); + + /* When the max limit is reached, should return CFE_ES_NO_RESOURCE_IDS_AVAILABLE */ + if (CFE_Assert_STATUS_MAY_BE(CFE_ES_NO_RESOURCE_IDS_AVAILABLE)) { break; } + + /* If max limit not reached, should return CFE_SUCCESS, anything else is a test fail */ + CFE_Assert_STATUS_MAY_BE(CFE_SUCCESS); } /* Confirm that the expected number of counters were created */ - UtAssert_UINT32_EQ(NumCounters, CFE_PLATFORM_ES_MAX_GEN_COUNTERS); - - /* Attempt to create one too many */ - snprintf(CounterName, sizeof(CounterName), "extra"); - UtAssert_INT32_EQ(CFE_ES_RegisterGenCounter(&TestId, CounterName), CFE_ES_NO_RESOURCE_IDS_AVAILABLE); + UtAssert_UINT32_LTEQ(NumCounters, CFE_PLATFORM_ES_MAX_GEN_COUNTERS); /* pick a single counter ID from the middle of the set for more detail testing of support APIs */ TestId = Ids[NumCounters / 2]; diff --git a/modules/cfe_testcase/src/es_info_test.c b/modules/cfe_testcase/src/es_info_test.c index 4bbedd85e..3f3cd635d 100644 --- a/modules/cfe_testcase/src/es_info_test.c +++ b/modules/cfe_testcase/src/es_info_test.c @@ -125,11 +125,12 @@ void TestAppInfo(void) CFE_UtAssert_RESOURCEID_UNDEFINED(AppIdByName); UtAssert_INT32_EQ(CFE_ES_GetAppID(NULL), CFE_ES_BAD_ARGUMENT); UtAssert_INT32_EQ(CFE_ES_GetAppIDByName(NULL, TEST_EXPECTED_APP_NAME), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetAppIDByName(&AppIdByName, NULL), CFE_ES_BAD_ARGUMENT); UtAssert_INT32_EQ(CFE_ES_GetAppName(AppNameBuf, CFE_ES_APPID_UNDEFINED, sizeof(AppNameBuf)), CFE_ES_ERR_RESOURCEID_NOT_VALID); UtAssert_INT32_EQ(CFE_ES_GetAppName(NULL, TestAppId, sizeof(AppNameBuf)), CFE_ES_BAD_ARGUMENT); UtAssert_INT32_EQ(CFE_ES_GetAppInfo(&TestAppInfo, CFE_ES_APPID_UNDEFINED), CFE_ES_ERR_RESOURCEID_NOT_VALID); - UtAssert_INT32_EQ(CFE_ES_GetAppInfo(NULL, CFE_ES_APPID_UNDEFINED), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetAppInfo(NULL, TestAppId), CFE_ES_BAD_ARGUMENT); } void TestTaskInfo(void) @@ -158,13 +159,14 @@ void TestTaskInfo(void) UtAssert_INT32_EQ(TaskInfo.ExecutionCounter, AppInfo.ExecutionCounter); UtAssert_INT32_EQ(CFE_ES_GetTaskInfo(&TaskInfo, CFE_ES_TASKID_UNDEFINED), CFE_ES_ERR_RESOURCEID_NOT_VALID); - UtAssert_INT32_EQ(CFE_ES_GetTaskInfo(NULL, CFE_ES_TASKID_UNDEFINED), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetTaskInfo(NULL, TaskId), CFE_ES_BAD_ARGUMENT); UtAssert_INT32_EQ(CFE_ES_GetTaskID(NULL), CFE_ES_BAD_ARGUMENT); } void TestLibInfo(void) { - CFE_ES_LibId_t LibIdByName; + CFE_ES_LibId_t LibId; + CFE_ES_LibId_t CheckId; CFE_ES_AppInfo_t LibInfo; const char * LibName = "ASSERT_LIB"; const char * InvalidName = "INVALID_NAME"; @@ -172,9 +174,9 @@ void TestLibInfo(void) UtPrintf("Testing: CFE_ES_GetLibIDByName, CFE_ES_GetLibName, CFE_ES_GetLibInfo"); - UtAssert_INT32_EQ(CFE_ES_GetLibIDByName(&LibIdByName, LibName), CFE_SUCCESS); - UtAssert_INT32_EQ(CFE_ES_GetLibInfo(&LibInfo, LibIdByName), CFE_SUCCESS); - UtAssert_INT32_EQ(CFE_ES_GetLibName(LibNameBuf, LibIdByName, sizeof(LibNameBuf)), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_ES_GetLibIDByName(&LibId, LibName), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_ES_GetLibInfo(&LibInfo, LibId), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_ES_GetLibName(LibNameBuf, LibId, sizeof(LibNameBuf)), CFE_SUCCESS); UtAssert_StrCmp(LibNameBuf, LibName, "CFE_ES_GetLibName() = %s", LibNameBuf); UtAssert_True(LibInfo.Type == CFE_ES_AppType_LIBRARY, "Lib Info -> Type = %d", (int)LibInfo.Type); UtAssert_StrCmp(LibInfo.Name, LibName, "Lib Info -> Name = %s", LibInfo.Name); @@ -210,13 +212,17 @@ void TestLibInfo(void) UtAssert_True(strlen(LibInfo.MainTaskName) == 0, "Lib Info -> Task Name = %s", LibInfo.MainTaskName); UtAssert_True(LibInfo.NumOfChildTasks == 0, "Lib Info -> Child Tasks = %d", (int)LibInfo.NumOfChildTasks); - UtAssert_INT32_EQ(CFE_ES_GetLibIDByName(&LibIdByName, InvalidName), CFE_ES_ERR_NAME_NOT_FOUND); - UtAssert_INT32_EQ(CFE_ES_GetLibInfo(&LibInfo, LibIdByName), CFE_ES_ERR_RESOURCEID_NOT_VALID); + UtAssert_INT32_EQ(CFE_ES_GetLibIDByName(&CheckId, InvalidName), CFE_ES_ERR_NAME_NOT_FOUND); + CFE_UtAssert_RESOURCEID_UNDEFINED(CheckId); + UtAssert_INT32_EQ(CFE_ES_GetLibInfo(&LibInfo, CFE_ES_LIBID_UNDEFINED), CFE_ES_ERR_RESOURCEID_NOT_VALID); + UtAssert_INT32_EQ(CFE_ES_GetLibInfo(NULL, LibId), CFE_ES_BAD_ARGUMENT); UtAssert_INT32_EQ(CFE_ES_GetLibIDByName(NULL, LibName), CFE_ES_BAD_ARGUMENT); - UtAssert_INT32_EQ(CFE_ES_GetLibInfo(NULL, LibIdByName), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetLibIDByName(&CheckId, NULL), CFE_ES_BAD_ARGUMENT); + CFE_UtAssert_RESOURCEID_UNDEFINED(CheckId); UtAssert_INT32_EQ(CFE_ES_GetLibName(LibNameBuf, CFE_ES_LIBID_UNDEFINED, sizeof(LibNameBuf)), CFE_ES_ERR_RESOURCEID_NOT_VALID); - UtAssert_INT32_EQ(CFE_ES_GetLibName(NULL, LibIdByName, sizeof(LibNameBuf)), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetLibName(LibNameBuf, LibId, 0), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetLibName(NULL, LibId, sizeof(LibNameBuf)), CFE_ES_BAD_ARGUMENT); } void TestResetType(void) diff --git a/modules/cfe_testcase/src/es_mempool_test.c b/modules/cfe_testcase/src/es_mempool_test.c index 32fe359b6..a3f97354e 100644 --- a/modules/cfe_testcase/src/es_mempool_test.c +++ b/modules/cfe_testcase/src/es_mempool_test.c @@ -33,52 +33,96 @@ #include "cfe_test.h" +typedef struct +{ + uint32 Mem[128]; +} CFE_FT_PoolMemBlock_t; + +static CFE_FT_PoolMemBlock_t CFE_FT_PoolMemBlock[CFE_PLATFORM_ES_MAX_MEMORY_POOLS + 1]; + void TestMemPoolCreate(void) { CFE_ES_MemHandle_t PoolID; - int8 Pool[1024]; UtPrintf("Testing: CFE_ES_PoolCreateNoSem, CFE_ES_PoolCreate, CFE_ES_PoolCreateEx"); - UtAssert_INT32_EQ(CFE_ES_PoolCreateNoSem(&PoolID, Pool, sizeof(Pool)), CFE_SUCCESS); - UtAssert_INT32_EQ(CFE_ES_PoolCreateNoSem(NULL, Pool, sizeof(Pool)), CFE_ES_BAD_ARGUMENT); - UtAssert_INT32_EQ(CFE_ES_PoolCreateNoSem(&PoolID, NULL, sizeof(Pool)), CFE_ES_BAD_ARGUMENT); - UtAssert_INT32_EQ(CFE_ES_PoolCreateNoSem(&PoolID, Pool, 0), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_PoolCreateNoSem(&PoolID, CFE_FT_PoolMemBlock, sizeof(CFE_FT_PoolMemBlock)), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_ES_PoolCreateNoSem(NULL, CFE_FT_PoolMemBlock, sizeof(CFE_FT_PoolMemBlock)), + CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_PoolCreateNoSem(&PoolID, NULL, sizeof(CFE_FT_PoolMemBlock)), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_PoolCreateNoSem(&PoolID, CFE_FT_PoolMemBlock, 0), CFE_ES_BAD_ARGUMENT); UtAssert_INT32_EQ(CFE_ES_PoolDelete(PoolID), CFE_SUCCESS); - UtAssert_INT32_EQ(CFE_ES_PoolCreate(&PoolID, Pool, sizeof(Pool)), CFE_SUCCESS); - UtAssert_INT32_EQ(CFE_ES_PoolCreate(NULL, Pool, sizeof(Pool)), CFE_ES_BAD_ARGUMENT); - UtAssert_INT32_EQ(CFE_ES_PoolCreate(&PoolID, NULL, sizeof(Pool)), CFE_ES_BAD_ARGUMENT); - UtAssert_INT32_EQ(CFE_ES_PoolCreate(&PoolID, Pool, 0), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_PoolCreate(&PoolID, CFE_FT_PoolMemBlock, sizeof(CFE_FT_PoolMemBlock)), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_ES_PoolCreate(NULL, CFE_FT_PoolMemBlock, sizeof(CFE_FT_PoolMemBlock)), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_PoolCreate(&PoolID, NULL, sizeof(CFE_FT_PoolMemBlock)), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_PoolCreate(&PoolID, CFE_FT_PoolMemBlock, 0), CFE_ES_BAD_ARGUMENT); UtAssert_INT32_EQ(CFE_ES_PoolDelete(PoolID), CFE_SUCCESS); - UtAssert_INT32_EQ(CFE_ES_PoolCreateEx(&PoolID, Pool, sizeof(Pool), 0, NULL, CFE_ES_NO_MUTEX), CFE_SUCCESS); - UtAssert_INT32_EQ(CFE_ES_PoolCreateEx(NULL, Pool, sizeof(Pool), 0, NULL, CFE_ES_NO_MUTEX), CFE_ES_BAD_ARGUMENT); - UtAssert_INT32_EQ(CFE_ES_PoolCreateEx(&PoolID, NULL, sizeof(Pool), 0, NULL, CFE_ES_NO_MUTEX), CFE_ES_BAD_ARGUMENT); - UtAssert_INT32_EQ(CFE_ES_PoolCreateEx(&PoolID, Pool, 0, 0, NULL, CFE_ES_NO_MUTEX), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ( + CFE_ES_PoolCreateEx(&PoolID, CFE_FT_PoolMemBlock, sizeof(CFE_FT_PoolMemBlock), 0, NULL, CFE_ES_NO_MUTEX), + CFE_SUCCESS); + UtAssert_INT32_EQ( + CFE_ES_PoolCreateEx(NULL, CFE_FT_PoolMemBlock, sizeof(CFE_FT_PoolMemBlock), 0, NULL, CFE_ES_NO_MUTEX), + CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_PoolCreateEx(&PoolID, NULL, sizeof(CFE_FT_PoolMemBlock), 0, NULL, CFE_ES_NO_MUTEX), + CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_PoolCreateEx(&PoolID, CFE_FT_PoolMemBlock, 0, 0, NULL, CFE_ES_NO_MUTEX), + CFE_ES_BAD_ARGUMENT); UtAssert_INT32_EQ(CFE_ES_PoolDelete(PoolID), CFE_SUCCESS); } +void TestMemPoolCreateMax(void) +{ + CFE_ES_MemHandle_t PoolID[CFE_PLATFORM_ES_MAX_MEMORY_POOLS + 1]; + uint32 NumPools; + + UtPrintf("Testing: CFE_ES_PoolCreate Max Limit"); + + NumPools = 0; + while (NumPools <= CFE_PLATFORM_ES_MAX_MEMORY_POOLS) + { + CFE_Assert_STATUS_STORE(CFE_ES_PoolCreateEx(&PoolID[NumPools], &CFE_FT_PoolMemBlock[NumPools], + sizeof(CFE_FT_PoolMemBlock_t), 0, NULL, CFE_ES_NO_MUTEX)); + if (CFE_Assert_STATUS_MAY_BE(CFE_ES_NO_RESOURCE_IDS_AVAILABLE)) + { + /* limit reached */ + break; + } + CFE_Assert_STATUS_MUST_BE(CFE_SUCCESS); + ++NumPools; + } + + UtAssert_UINT32_LTEQ(NumPools, CFE_PLATFORM_ES_MAX_MEMORY_POOLS); + + /* Clean up */ + while (NumPools > 0) + { + --NumPools; + UtAssert_INT32_EQ(CFE_ES_PoolDelete(PoolID[NumPools]), CFE_SUCCESS); + } +} + void TestMemPoolGetBuf(void) { CFE_ES_MemHandle_t PoolID; int8 Pool[1024]; - size_t Buffer = 512; - size_t BufferBig = 2048; - CFE_ES_MemPoolBuf_t addressp = CFE_ES_MEMPOOLBUF_C(0); + size_t BufferSize = 512; + size_t BufferBig = 2048; + CFE_ES_MemPoolBuf_t addressp = CFE_ES_MEMPOOLBUF_C(0); UtPrintf("Testing: TestMemPoolGetBuf"); UtAssert_INT32_EQ(CFE_ES_PoolCreate(&PoolID, Pool, sizeof(Pool)), CFE_SUCCESS); - UtAssert_INT32_EQ(CFE_ES_GetPoolBuf(&addressp, PoolID, Buffer), Buffer); + UtAssert_INT32_EQ(CFE_ES_GetPoolBuf(&addressp, PoolID, BufferSize), BufferSize); - UtAssert_INT32_EQ(CFE_ES_GetPoolBuf(NULL, PoolID, Buffer), CFE_ES_BAD_ARGUMENT); - UtAssert_INT32_EQ(CFE_ES_GetPoolBuf(&addressp, CFE_ES_MEMHANDLE_UNDEFINED, Buffer), + UtAssert_INT32_EQ(CFE_ES_GetPoolBuf(NULL, PoolID, BufferSize), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetPoolBuf(&addressp, CFE_ES_MEMHANDLE_UNDEFINED, BufferSize), CFE_ES_ERR_RESOURCEID_NOT_VALID); - UtAssert_INT32_EQ(CFE_ES_GetPoolBuf(&addressp, PoolID, Buffer), CFE_ES_ERR_MEM_BLOCK_SIZE); - UtAssert_INT32_EQ(CFE_ES_PutPoolBuf(PoolID, addressp), Buffer); + UtAssert_INT32_EQ(CFE_ES_GetPoolBuf(&addressp, PoolID, BufferSize), CFE_ES_ERR_MEM_BLOCK_SIZE); + UtAssert_INT32_EQ(CFE_ES_PutPoolBuf(PoolID, addressp), BufferSize); UtAssert_INT32_EQ(CFE_ES_GetPoolBuf(&addressp, PoolID, BufferBig), CFE_ES_ERR_MEM_BLOCK_SIZE); @@ -104,6 +148,9 @@ void TestMemPoolBufInfo(void) UtAssert_INT32_EQ(CFE_ES_GetPoolBufInfo(CFE_ES_MEMHANDLE_UNDEFINED, addressp), CFE_ES_ERR_RESOURCEID_NOT_VALID); UtAssert_INT32_EQ(CFE_ES_GetPoolBufInfo(PoolID, NULL), CFE_ES_BAD_ARGUMENT); + /* Pass an address from some other memory which is not part of the pool */ + UtAssert_INT32_EQ(CFE_ES_GetPoolBufInfo(PoolID, &Buffer), CFE_ES_BUFFER_NOT_IN_POOL); + UtAssert_INT32_EQ(CFE_ES_PoolDelete(PoolID), CFE_SUCCESS); } @@ -145,13 +192,19 @@ void TestMemPoolDelete(void) UtAssert_UINT32_EQ(Stats.CheckErrCtr, 0); UtAssert_UINT32_EQ(Stats.NumFreeBytes, sizeof(Buffer)); + UtAssert_INT32_EQ(CFE_ES_GetMemPoolStats(NULL, PoolID), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetMemPoolStats(&Stats, CFE_ES_MEMHANDLE_UNDEFINED), CFE_ES_ERR_RESOURCEID_NOT_VALID); + UtAssert_INT32_EQ(CFE_ES_PoolDelete(PoolID), CFE_SUCCESS); UtAssert_INT32_EQ(CFE_ES_GetMemPoolStats(&Stats, PoolID), CFE_ES_ERR_RESOURCEID_NOT_VALID); + UtAssert_INT32_EQ(CFE_ES_PoolDelete(PoolID), CFE_ES_ERR_RESOURCEID_NOT_VALID); + UtAssert_INT32_EQ(CFE_ES_PoolDelete(CFE_ES_MEMHANDLE_UNDEFINED), CFE_ES_ERR_RESOURCEID_NOT_VALID); } void ESMemPoolTestSetup(void) { UtTest_Add(TestMemPoolCreate, NULL, NULL, "Test Mem Pool Create"); + UtTest_Add(TestMemPoolCreateMax, NULL, NULL, "Test Mem Pool Create Maximum"); UtTest_Add(TestMemPoolGetBuf, NULL, NULL, "Test Mem Pool Get Buf"); UtTest_Add(TestMemPoolBufInfo, NULL, NULL, "Test Mem Pool Buf Info"); UtTest_Add(TestMemPoolPutBuf, NULL, NULL, "Test Mem Pool Put Buf"); diff --git a/modules/cfe_testcase/src/es_misc_test.c b/modules/cfe_testcase/src/es_misc_test.c index 6545efa29..ec71d5bc6 100644 --- a/modules/cfe_testcase/src/es_misc_test.c +++ b/modules/cfe_testcase/src/es_misc_test.c @@ -58,11 +58,33 @@ void TestCalculateCRC(void) void TestWriteToSysLog(void) { const char *TestString = "Test String for CFE_ES_WriteToSysLog Functional Test"; + uint32 Iterations = CFE_PLATFORM_ES_SYSTEM_LOG_SIZE / 50; UtPrintf("Testing: CFE_ES_WriteToSysLog"); - CFE_ES_WriteToSysLog("MIR (Manual Inspection Required) for CFE_ES_WriteToSysLog"); - CFE_ES_WriteToSysLog(NULL); - CFE_ES_WriteToSysLog("%s", TestString); + + UtAssert_INT32_EQ(CFE_ES_WriteToSysLog(NULL), CFE_ES_BAD_ARGUMENT); + + CFE_Assert_STATUS_STORE(CFE_ES_WriteToSysLog("MIR (Manual Inspection Required) for CFE_ES_WriteToSysLog")); + if (!CFE_Assert_STATUS_MAY_BE(CFE_ES_ERR_SYS_LOG_FULL)) + { + CFE_Assert_STATUS_MUST_BE(CFE_SUCCESS); + } + + /* The test string is a little over 50 chars in length, so writing it repeatedly should fill it up. */ + /* This does depend on whether the system is set to OVERWRITE or DISCARD mode, though - + * in OVERWRITE mode, the system log will never fill, and therefore CFE_ES_ERR_SYS_LOG_FULL cannot be tested */ + Iterations = 1 + (CFE_PLATFORM_ES_SYSTEM_LOG_SIZE / strlen(TestString)); + + while (Iterations > 0) + { + --Iterations; + CFE_Assert_STATUS_STORE(CFE_ES_WriteToSysLog("%s", TestString)); + if (CFE_Assert_STATUS_MAY_BE(CFE_ES_ERR_SYS_LOG_FULL)) + { + break; + } + CFE_Assert_STATUS_MUST_BE(CFE_SUCCESS); + } UtAssert_MIR("MIR (Manual Inspection Required) for CFE_ES_WriteToSysLog"); } diff --git a/modules/cfe_testcase/src/es_task_test.c b/modules/cfe_testcase/src/es_task_test.c index bd9f64bf4..fe0814ec4 100644 --- a/modules/cfe_testcase/src/es_task_test.c +++ b/modules/cfe_testcase/src/es_task_test.c @@ -43,6 +43,49 @@ void TaskFunction(void) return; } +/* A task function that verifies the behavior of other APIs when those are called from a child task */ +void TaskFunctionCheckChildTaskContext(void) +{ + CFE_ES_TaskId_t TaskId; + CFE_ES_AppId_t AppId; + CFE_ES_AppInfo_t AppInfo; + + /* extra startup delay before first assert, to make sure parent task has reached its wait loop */ + OS_TaskDelay(100); + + /* If invoked from the context of a child task, this should return an error */ + UtAssert_INT32_EQ(CFE_ES_CreateChildTask(&TaskId, "Test", TaskFunction, OSAL_TASK_STACK_ALLOCATE, 4096, 150, 0), + CFE_ES_ERR_CHILD_TASK_CREATE); + + /* Likewise attempting to delete the main task of the app from a child task should fail */ + UtAssert_INT32_EQ(CFE_ES_GetAppID(&AppId), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_ES_GetAppInfo(&AppInfo, AppId), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_ES_DeleteChildTask(AppInfo.MainTaskId), CFE_ES_ERR_CHILD_TASK_DELETE_MAIN_TASK); + + UtAssert_True(true, "CFE_ES_ExitChildTask() called"); + CFE_ES_ExitChildTask(); +} + +/* A task function that verifies the behavior of other APIs when those are called from a non-CFE app task */ +void TaskFunctionCheckNonAppContext(void) +{ + CFE_ES_TaskId_t TaskId; + CFE_ES_AppId_t AppId; + + /* extra startup delay before first assert, to make sure parent task has reached its wait loop */ + OS_TaskDelay(100); + + UtAssert_INT32_EQ(CFE_ES_GetAppID(&AppId), CFE_ES_ERR_RESOURCEID_NOT_VALID); + UtAssert_INT32_EQ(CFE_ES_GetTaskID(&TaskId), CFE_ES_ERR_RESOURCEID_NOT_VALID); + + UtAssert_INT32_EQ( + CFE_ES_CreateChildTask(&TaskId, "TaskName", TaskFunction, CFE_ES_TASK_STACK_ALLOCATE, 4096, 200, 0), + CFE_ES_ERR_RESOURCEID_NOT_VALID); + + UtAssert_True(true, "OS_TaskExit() called"); + OS_TaskExit(); +} + void TaskExitFunction(void) { while (CFE_FT_Global.Count < 200) @@ -64,22 +107,76 @@ void TestCreateChild(void) size_t StackSize = CFE_PLATFORM_ES_PERF_CHILD_STACK_SIZE; CFE_ES_TaskPriority_Atom_t Priority = CFE_PLATFORM_ES_PERF_CHILD_PRIORITY; uint32 Flags = 0; - int ExpectedCount = 5; + int32 ExpectedCount = 5; + int32 RetryCount; + char TaskNameBuf[16]; + osal_id_t OtherTaskId; + OS_task_prop_t task_prop; CFE_FT_Global.Count = 0; - UtAssert_INT32_EQ(CFE_ES_CreateChildTask(&TaskId, TaskName, TaskFunction, StackPointer, StackSize, Priority, Flags), CFE_SUCCESS); OS_TaskDelay(500); - UtAssert_True(ExpectedCount >= CFE_FT_Global.Count - 1 && ExpectedCount <= CFE_FT_Global.Count + 1, - "countCopy (%d) == count (%d)", (int)ExpectedCount, (int)CFE_FT_Global.Count); + UtAssert_INT32_GT(CFE_FT_Global.Count, ExpectedCount - 1); + UtAssert_INT32_LT(CFE_FT_Global.Count, ExpectedCount + 1); + /* Create task with same name - note the name conflict is detected by OSAL, not CFE here, and the error code is + * translated */ UtAssert_INT32_EQ( CFE_ES_CreateChildTask(&TaskId2, TaskName, TaskFunction, StackPointer, StackSize, Priority, Flags), CFE_STATUS_EXTERNAL_RESOURCE_FAIL); UtAssert_INT32_EQ(CFE_ES_DeleteChildTask(TaskId), CFE_SUCCESS); + /* Also Confirm behavior of child task create/delete when called from a child task */ + CFE_FT_Global.Count = 0; + UtAssert_INT32_EQ(CFE_ES_CreateChildTask(&TaskId, TaskName, TaskFunctionCheckChildTaskContext, StackPointer, + StackSize, Priority, Flags), + CFE_SUCCESS); + + /* wait for task to exit itself */ + RetryCount = 0; + while (RetryCount < 10) + { + /* + * poll until CFE_ES_GetTaskName() returns an error, then the task has exited + * + * NOTE: this intentionally does not Assert the status here, because the child task is + * also doing asserts at the time this loop is running. Once the child task finishes, + * it is OK to do asserts from this task again + */ + if (CFE_Assert_STATUS_STORE(CFE_ES_GetTaskName(TaskNameBuf, TaskId, sizeof(TaskNameBuf))) != CFE_SUCCESS) + { + break; + } + OS_TaskDelay(100); + ++RetryCount; + } + + /* Retroactively confirm that the previous call to CFE_ES_GetTaskName() returned RESOURCEID_NOT_VALID */ + CFE_Assert_STATUS_MUST_BE(CFE_ES_ERR_RESOURCEID_NOT_VALID); + + /* Now do the same but instead of a CFE child task, make an OSAL task that is not associated with a CFE app */ + UtAssert_INT32_EQ(OS_TaskCreate(&OtherTaskId, "NonCfe", TaskFunctionCheckNonAppContext, OSAL_TASK_STACK_ALLOCATE, + 4096, OSAL_PRIORITY_C(200), 0), + OS_SUCCESS); + + /* wait for task to exit itself */ + RetryCount = 0; + while (RetryCount < 10) + { + /* + * poll until OS_TaskGetInfo() returns an error, then the task has exited + */ + if (OS_TaskGetInfo(OtherTaskId, &task_prop) != OS_SUCCESS) + { + break; + } + + OS_TaskDelay(100); + ++RetryCount; + } + UtAssert_INT32_EQ(CFE_ES_CreateChildTask(NULL, TaskName, TaskFunction, StackPointer, StackSize, Priority, Flags), CFE_ES_BAD_ARGUMENT); UtAssert_INT32_EQ(CFE_ES_CreateChildTask(&TaskId, NULL, TaskFunction, StackPointer, StackSize, Priority, Flags), @@ -114,6 +211,7 @@ void TestChildTaskName(void) UtAssert_StrCmp(TaskNameBuf, TaskName, "CFE_ES_GetTaskName() = %s", TaskNameBuf); UtAssert_INT32_EQ(CFE_ES_GetTaskIDByName(NULL, TaskName), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetTaskIDByName(&TaskIdByName, NULL), CFE_ES_BAD_ARGUMENT); UtAssert_INT32_EQ(CFE_ES_GetTaskIDByName(&TaskIdByName, INVALID_TASK_NAME), CFE_ES_ERR_NAME_NOT_FOUND); CFE_UtAssert_RESOURCEID_UNDEFINED(TaskIdByName); diff --git a/modules/core_api/fsw/inc/cfe_es.h b/modules/core_api/fsw/inc/cfe_es.h index 44e6e79c3..7e34b8308 100644 --- a/modules/core_api/fsw/inc/cfe_es.h +++ b/modules/core_api/fsw/inc/cfe_es.h @@ -420,7 +420,7 @@ bool CFE_ES_RunLoop(uint32 *RunStatus); ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS State successfully achieved -** \retval #CFE_ES_OPERATION_TIMED_OUT Timeout was reached +** \retval #CFE_ES_OPERATION_TIMED_OUT \covtest Timeout was reached ** ** \sa #CFE_ES_RunLoop ** @@ -651,7 +651,7 @@ CFE_Status_t CFE_ES_GetAppName(char *AppName, CFE_ES_AppId_t AppId, size_t Buffe ** ** \param[in] LibId Library ID of Library whose name is being requested. ** -** \param[in] BufferLength The maximum number of characters, including the null terminator, that can be put +** \param[in] BufferLength The maximum number of characters @nonzero, including the null terminator, that can be put ** into the \c LibName buffer. This routine will truncate the name to this length, ** if necessary. ** @@ -903,8 +903,7 @@ CFE_Status_t CFE_ES_GetTaskName(char *TaskName, CFE_ES_TaskId_t TaskId, size_t B ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS -** \retval #CFE_ES_NOT_IMPLEMENTED \copybrief CFE_ES_NOT_IMPLEMENTED -** \retval #CFE_ES_ERR_CHILD_TASK_DELETE \copybrief CFE_ES_ERR_CHILD_TASK_DELETE +** \retval #CFE_ES_ERR_CHILD_TASK_DELETE \covtest \copybrief CFE_ES_ERR_CHILD_TASK_DELETE ** \retval #CFE_ES_ERR_CHILD_TASK_DELETE_MAIN_TASK \copybrief CFE_ES_ERR_CHILD_TASK_DELETE_MAIN_TASK ** \retval #CFE_ES_ERR_RESOURCEID_NOT_VALID \copybrief CFE_ES_ERR_RESOURCEID_NOT_VALID ** @@ -1072,7 +1071,7 @@ void CFE_ES_ProcessAsyncEvent(void); ** \retval #CFE_ES_CDS_INVALID_SIZE \copybrief CFE_ES_CDS_INVALID_SIZE ** \retval #CFE_ES_CDS_INVALID_NAME \copybrief CFE_ES_CDS_INVALID_NAME ** \retval #CFE_ES_BAD_ARGUMENT \copybrief CFE_ES_BAD_ARGUMENT -** \retval #CFE_ES_CDS_INVALID \copybrief CFE_ES_CDS_INVALID +** \retval #CFE_ES_CDS_INVALID \covtest \copybrief CFE_ES_CDS_INVALID ** ** \sa #CFE_ES_CopyToCDS, #CFE_ES_RestoreFromCDS ** @@ -1185,7 +1184,7 @@ CFE_Status_t CFE_ES_CopyToCDS(CFE_ES_CDSHandle_t Handle, const void *DataToCopy) ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS ** \retval #CFE_ES_ERR_RESOURCEID_NOT_VALID \copybrief CFE_ES_ERR_RESOURCEID_NOT_VALID -** \retval #CFE_ES_CDS_BLOCK_CRC_ERR \copybrief CFE_ES_CDS_BLOCK_CRC_ERR +** \retval #CFE_ES_CDS_BLOCK_CRC_ERR \covtest \copybrief CFE_ES_CDS_BLOCK_CRC_ERR ** \retval #CFE_ES_BAD_ARGUMENT \copybrief CFE_ES_BAD_ARGUMENT ** ** \sa #CFE_ES_RegisterCDS, #CFE_ES_CopyToCDS @@ -1309,7 +1308,7 @@ CFE_Status_t CFE_ES_PoolCreate(CFE_ES_MemHandle_t *PoolID, void *MemPtr, size_t ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS ** \retval #CFE_ES_BAD_ARGUMENT \copybrief CFE_ES_BAD_ARGUMENT ** \retval #CFE_ES_NO_RESOURCE_IDS_AVAILABLE \copybrief CFE_ES_NO_RESOURCE_IDS_AVAILABLE -** \retval #CFE_STATUS_EXTERNAL_RESOURCE_FAIL \copybrief CFE_STATUS_EXTERNAL_RESOURCE_FAIL +** \retval #CFE_STATUS_EXTERNAL_RESOURCE_FAIL \covtest \copybrief CFE_STATUS_EXTERNAL_RESOURCE_FAIL ** ** \sa #CFE_ES_PoolCreate, #CFE_ES_PoolCreateNoSem, #CFE_ES_GetPoolBuf, #CFE_ES_PutPoolBuf, #CFE_ES_GetMemPoolStats ** @@ -1356,7 +1355,7 @@ int32 CFE_ES_PoolDelete(CFE_ES_MemHandle_t PoolID); ** ** \param[in] Handle The handle to the memory pool as returned by #CFE_ES_PoolCreate or #CFE_ES_PoolCreateNoSem. ** -** \param[in] Size The size of the buffer requested @nonzero. NOTE: The size allocated may be larger. +** \param[in] Size The size of the buffer requested. NOTE: The size allocated may be larger. ** ** \return Bytes Allocated, or error code \ref CFEReturnCodes ** \retval #CFE_ES_ERR_RESOURCEID_NOT_VALID \copybrief CFE_ES_ERR_RESOURCEID_NOT_VALID