diff --git a/modules/cfe_testcase/CMakeLists.txt b/modules/cfe_testcase/CMakeLists.txt index 1318d7926..d8af5ea3d 100644 --- a/modules/cfe_testcase/CMakeLists.txt +++ b/modules/cfe_testcase/CMakeLists.txt @@ -5,6 +5,7 @@ add_cfe_app(cfe_testcase src/es_info_test.c src/es_task_test.c src/es_cds_test.c + src/es_counter_test.c src/es_misc_test.c src/es_mempool_test.c src/fs_header_test.c diff --git a/modules/cfe_testcase/src/cfe_test.c b/modules/cfe_testcase/src/cfe_test.c index 016eadc57..681535e68 100644 --- a/modules/cfe_testcase/src/cfe_test.c +++ b/modules/cfe_testcase/src/cfe_test.c @@ -52,6 +52,7 @@ void CFE_TestMain(void) * Register test cases in UtAssert */ ESCDSTestSetup(); + ESCounterTestSetup(); ESInfoTestSetup(); ESMemPoolTestSetup(); ESMiscTestSetup(); diff --git a/modules/cfe_testcase/src/cfe_test.h b/modules/cfe_testcase/src/cfe_test.h index e661c6849..ce2cf6ca7 100644 --- a/modules/cfe_testcase/src/cfe_test.h +++ b/modules/cfe_testcase/src/cfe_test.h @@ -79,6 +79,7 @@ typedef struct void CFE_TestMain(void); void ESCDSTestSetup(void); +void ESCounterTestSetup(void); void ESInfoTestSetup(void); void ESMemPoolTestSetup(void); void ESMiscTestSetup(void); diff --git a/modules/cfe_testcase/src/es_counter_test.c b/modules/cfe_testcase/src/es_counter_test.c new file mode 100644 index 000000000..e28ef2f92 --- /dev/null +++ b/modules/cfe_testcase/src/es_counter_test.c @@ -0,0 +1,166 @@ +/************************************************************************* +** +** GSC-18128-1, "Core Flight Executive Version 6.7" +** +** Copyright (c) 2006-2019 United States Government as represented by +** the Administrator of the National Aeronautics and Space Administration. +** All Rights Reserved. +** +** Licensed under the Apache License, Version 2.0 (the "License"); +** you may not use this file except in compliance with the License. +** You may obtain a copy of the License at +** +** http://www.apache.org/licenses/LICENSE-2.0 +** +** Unless required by applicable law or agreed to in writing, software +** distributed under the License is distributed on an "AS IS" BASIS, +** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +** See the License for the specific language governing permissions and +** limitations under the License. +** +*************************************************************************/ + +/** + * @file + * + * Functional test of ES Generic Counter APIs + */ + +#include "cfe_test.h" + +void TestCounterCreateDelete(void) +{ + CFE_ES_CounterId_t Ids[CFE_PLATFORM_ES_MAX_GEN_COUNTERS]; + CFE_ES_CounterId_t TestId; + CFE_ES_CounterId_t CheckId; + char CounterName[CFE_MISSION_MAX_API_LEN]; + char CheckName[CFE_MISSION_MAX_API_LEN]; + CFE_Status_t Status; + uint32 NumCounters; + uint32 Idx; + + UtPrintf("Testing: CFE_ES_RegisterGenCounter"); + + snprintf(CounterName, sizeof(CounterName), "ut"); + + /* Confirm proper bad argument rejection */ + UtAssert_INT32_EQ(CFE_ES_RegisterGenCounter(&Ids[0], NULL), CFE_ES_BAD_ARGUMENT); + 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) + { + snprintf(CounterName, sizeof(CounterName), "C%u", (unsigned int)NumCounters); + Status = CFE_ES_RegisterGenCounter(&Ids[NumCounters], CounterName); + if (Status != CFE_SUCCESS) + { + break; + } + } + + /* 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); + + /* pick a single counter ID from the middle of the set for more detail testing of support APIs */ + TestId = Ids[NumCounters / 2]; + snprintf(CounterName, sizeof(CounterName), "C%u", (unsigned int)NumCounters / 2); + + UtPrintf("Testing: CFE_ES_CounterID_ToIndex"); + + /* Confirm CFE_ES_CounterID_ToIndex works (nominal) */ + Idx = UINT32_MAX; + UtAssert_INT32_EQ(CFE_ES_CounterID_ToIndex(TestId, &Idx), CFE_SUCCESS); + UtAssert_UINT32_LT(Idx, CFE_PLATFORM_ES_MAX_GEN_COUNTERS); + + /* Confirm proper rejection of bad args in CFE_ES_CounterID_ToIndex */ + UtAssert_INT32_EQ(CFE_ES_CounterID_ToIndex(CFE_ES_COUNTERID_UNDEFINED, &Idx), CFE_ES_ERR_RESOURCEID_NOT_VALID); + UtAssert_INT32_EQ(CFE_ES_CounterID_ToIndex(TestId, NULL), CFE_ES_BAD_ARGUMENT); + + UtPrintf("Testing: CFE_ES_GetGenCounterIDByName, CFE_ES_GetGenCounterName"); + + /* Confirm conversion To/From Name */ + UtAssert_INT32_EQ(CFE_ES_GetGenCounterIDByName(&CheckId, CounterName), CFE_SUCCESS); + cFE_FTAssert_ResourceID_EQ(CheckId, TestId); + UtAssert_INT32_EQ(CFE_ES_GetGenCounterName(CheckName, TestId, sizeof(CheckName)), CFE_SUCCESS); + UtAssert_STRINGBUF_EQ(CheckName, sizeof(CheckName), CounterName, sizeof(CounterName)); + + UtAssert_INT32_EQ(CFE_ES_GetGenCounterIDByName(&CheckId, "na"), CFE_ES_ERR_NAME_NOT_FOUND); + + /* Confirm proper rejection of bad args in conversion To/From Name */ + UtAssert_INT32_EQ(CFE_ES_GetGenCounterIDByName(NULL, CounterName), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetGenCounterIDByName(&CheckId, NULL), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetGenCounterName(CheckName, CFE_ES_COUNTERID_UNDEFINED, sizeof(CounterName)), + CFE_ES_ERR_RESOURCEID_NOT_VALID); + UtAssert_INT32_EQ(CFE_ES_GetGenCounterName(CheckName, TestId, 0), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetGenCounterName(NULL, TestId, sizeof(CounterName)), CFE_ES_BAD_ARGUMENT); + + UtPrintf("Testing: CFE_ES_DeleteGenCounter"); + + /* Confirm proper rejection of bad args in CFE_ES_DeleteGenCounter (this returns CFE_ES_BAD_ARGUMENT instead) */ + UtAssert_INT32_EQ(CFE_ES_DeleteGenCounter(CFE_ES_COUNTERID_UNDEFINED), CFE_ES_BAD_ARGUMENT); + + /* Delete last counter to test duplicate name rejection (needs a free slot) */ + --NumCounters; + UtAssert_INT32_EQ(CFE_ES_DeleteGenCounter(Ids[NumCounters]), CFE_SUCCESS); + snprintf(CounterName, sizeof(CounterName), "C%u", (unsigned int)0); + UtAssert_INT32_EQ(CFE_ES_RegisterGenCounter(&TestId, CounterName), CFE_ES_ERR_DUPLICATE_NAME); + + /* Delete remainder of counters */ + while (NumCounters > 0) + { + Status = CFE_ES_DeleteGenCounter(Ids[NumCounters - 1]); + if (Status != CFE_SUCCESS) + { + break; + } + + --NumCounters; + } + + UtAssert_ZERO(NumCounters); +} + +void TestCounterGetSet(void) +{ + CFE_ES_CounterId_t TestId; + uint32 CountVal; + + UtPrintf("Testing: CFE_ES_GetGenCount, CFE_ES_SetGenCount, CFE_ES_IncrementGenCounter"); + + /* Setup - create a single counter */ + UtAssert_INT32_EQ(CFE_ES_RegisterGenCounter(&TestId, "ut"), CFE_SUCCESS); + + /* Get and set its count - should be initially 0 */ + CountVal = UINT32_MAX; + UtAssert_INT32_EQ(CFE_ES_GetGenCount(TestId, &CountVal), CFE_SUCCESS); + UtAssert_ZERO(CountVal); + UtAssert_INT32_EQ(CFE_ES_SetGenCount(TestId, 5), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_ES_GetGenCount(TestId, &CountVal), CFE_SUCCESS); + UtAssert_UINT32_EQ(CountVal, 5); + UtAssert_INT32_EQ(CFE_ES_IncrementGenCounter(TestId), CFE_SUCCESS); + UtAssert_INT32_EQ(CFE_ES_GetGenCount(TestId, &CountVal), CFE_SUCCESS); + UtAssert_UINT32_EQ(CountVal, 6); + + /* + * Confirm bad arg rejection in Get/Set/Increment + * Note these APIs return CFE_ES_BAD_ARGUMENT rather than + * CFE_ES_ERR_RESOURCEID_NOT_VALID on a bad ID (historical) + */ + UtAssert_INT32_EQ(CFE_ES_GetGenCount(TestId, NULL), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_GetGenCount(CFE_ES_COUNTERID_UNDEFINED, &CountVal), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_IncrementGenCounter(CFE_ES_COUNTERID_UNDEFINED), CFE_ES_BAD_ARGUMENT); + UtAssert_INT32_EQ(CFE_ES_SetGenCount(CFE_ES_COUNTERID_UNDEFINED, 0), CFE_ES_BAD_ARGUMENT); + + /* Teardown - delete the counter */ + UtAssert_INT32_EQ(CFE_ES_DeleteGenCounter(TestId), CFE_SUCCESS); +} + +void ESCounterTestSetup(void) +{ + UtTest_Add(TestCounterCreateDelete, NULL, NULL, "Test Counter Create/Delete"); + UtTest_Add(TestCounterGetSet, NULL, NULL, "Test Counter Get/Set"); +} diff --git a/modules/core_api/fsw/inc/cfe_es.h b/modules/core_api/fsw/inc/cfe_es.h index 53061b4a3..2fcb96603 100644 --- a/modules/core_api/fsw/inc/cfe_es.h +++ b/modules/core_api/fsw/inc/cfe_es.h @@ -163,7 +163,7 @@ CFE_Status_t CFE_ES_TaskID_ToIndex(CFE_ES_TaskId_t TaskID, uint32 *Idx); * for future use. * * @param[in] CounterId Counter ID to convert - * @param[out] Idx Buffer where the calculated index will be stored + * @param[out] Idx Buffer where the calculated index will be stored @nonnull * * @return Execution status, see @ref CFEReturnCodes * @retval #CFE_SUCCESS @copybrief CFE_SUCCESS @@ -1494,15 +1494,16 @@ void CFE_ES_PerfLogAdd(uint32 Marker, uint32 EntryExit); ** can be used for inter-task management. ** ** \par Assumptions, External Events, and Notes: -** None. +** The initial value of all newly registered counters is 0. ** -** \param[in] *CounterName The Name of the generic counter. +** \param[out] CounterIdPtr Buffer to store the Counter Id of the newly created counter @nonnull. +** \param[in] CounterName The Name of the generic counter @nonnull. ** -** \param[out] *CounterIdPtr The Counter Id of the newly created counter. ** ** \return Execution status, see \ref CFEReturnCodes -** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS -** \retval #CFE_ES_BAD_ARGUMENT \copybrief CFE_ES_BAD_ARGUMENT +** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS +** \retval #CFE_ES_BAD_ARGUMENT \copybrief CFE_ES_BAD_ARGUMENT +** \retval #CFE_ES_ERR_DUPLICATE_NAME \copybrief CFE_ES_ERR_DUPLICATE_NAME ** ** \sa #CFE_ES_IncrementGenCounter, #CFE_ES_DeleteGenCounter, #CFE_ES_SetGenCount, #CFE_ES_GetGenCount, *#CFE_ES_GetGenCounterIDByName @@ -1588,9 +1589,9 @@ CFE_Status_t CFE_ES_SetGenCount(CFE_ES_CounterId_t CounterId, uint32 Count); ** \par Assumptions, External Events, and Notes: ** None. ** -** \param[in] CounterId The Counter to get the value from. +** \param[in] CounterId The Counter to get the value from. ** -** \param[in] *Count The value of the Counter. +** \param[out] Count Buffer to store value of the Counter @nonnull. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -1612,8 +1613,8 @@ CFE_Status_t CFE_ES_GetGenCount(CFE_ES_CounterId_t CounterId, uint32 *Count); ** \par Assumptions, External Events, and Notes: ** None. ** -** \param[out] CounterIdPtr Pointer to variable that is to receive the Counter's ID. -** \param[in] CounterName Pointer to null terminated character string containing a Counter name. +** \param[out] CounterIdPtr Pointer to variable that is to receive the Counter's ID @nonnull. +** \param[in] CounterName Pointer to null terminated character string containing a Counter name @nonnull. ** ** \return Execution status, see \ref CFEReturnCodes ** \retval #CFE_SUCCESS \copybrief CFE_SUCCESS @@ -1636,12 +1637,12 @@ CFE_Status_t CFE_ES_GetGenCounterIDByName(CFE_ES_CounterId_t *CounterIdPtr, cons ** \par Assumptions, External Events, and Notes: ** In the case of a failure (#CFE_ES_ERR_RESOURCEID_NOT_VALID), an empty string is returned. ** -** \param[out] CounterName Pointer to a character array of at least \c BufferLength in size that will +** \param[out] CounterName Pointer to a character array @nonnull of at least \c BufferLength in size that will ** be filled with the Counter name. ** ** \param[in] CounterId ID of Counter 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, including the null terminator @nonzero, that can be put ** into the \c CounterName buffer. This routine will truncate the name to this length, ** if necessary. **