From 7c756b98fc2efec30f1aa81703b996d9aa9e0910 Mon Sep 17 00:00:00 2001 From: dacarter22 Date: Fri, 14 Mar 2025 15:35:21 +0000 Subject: [PATCH 01/12] [nasa/nos#450] Coverage increased 0%-65% --- fsw/cfs/CMakeLists.txt | 4 + fsw/cfs/unit-test/CMakeLists.txt | 48 ++ .../coveragetest_generic_css_app.c | 467 ++++++++++++++++++ .../generic_css_app_coveragetest_common.h | 67 +++ fsw/cfs/unit-test/inc/ut_generic_css_app.h | 51 ++ 5 files changed, 637 insertions(+) create mode 100755 fsw/cfs/unit-test/CMakeLists.txt create mode 100755 fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c create mode 100755 fsw/cfs/unit-test/coveragetest/generic_css_app_coveragetest_common.h create mode 100755 fsw/cfs/unit-test/inc/ut_generic_css_app.h diff --git a/fsw/cfs/CMakeLists.txt b/fsw/cfs/CMakeLists.txt index 8cd0b8d..812bd3d 100755 --- a/fsw/cfs/CMakeLists.txt +++ b/fsw/cfs/CMakeLists.txt @@ -16,3 +16,7 @@ aux_source_directory(src APP_SRC_FILES) # Create the app module add_cfe_app(generic_css ${APP_SRC_FILES} ../shared/generic_css_device.c) + +if (ENABLE_UNIT_TESTS) + add_subdirectory(unit-test) +endif (ENABLE_UNIT_TESTS) diff --git a/fsw/cfs/unit-test/CMakeLists.txt b/fsw/cfs/unit-test/CMakeLists.txt new file mode 100755 index 0000000..787f45b --- /dev/null +++ b/fsw/cfs/unit-test/CMakeLists.txt @@ -0,0 +1,48 @@ +################################################################## +# +# Coverage Unit Test build recipe +# +# This CMake file contains the recipe for building the generic_css unit tests. +# It is invoked from the parent directory when unit tests are enabled. +# +################################################################## + +# +# +# NOTE on the subdirectory structures here: +# +# - "inc" provides local header files shared between the coveragetest, +# wrappers, and overrides source code units +# - "coveragetest" contains source code for the actual unit test cases +# The primary objective is to get line/path coverage on the FSW +# code units. +# + +# Use the UT assert public API, and allow direct +# inclusion of source files that are normally private +include_directories(${PROJECT_SOURCE_DIR}/fsw/src) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc) +include_directories(${hwlib_MISSION_DIR}/fsw/public_inc) + + +# Add a coverage test executable called "generic_css-ALL" that +# covers all of the functions in generic_css_app. +# +# Also note in a more complex app/lib the coverage test can also +# be broken down into smaller units (in which case one should use +# a unique suffix other than "ALL" for each unit). For example, +# OSAL implements a separate coverage test per source unit. +add_cfe_coverage_test(generic_css ALL + "coveragetest/coveragetest_generic_css_app.c" + "../src/generic_css_app.c" + "../../shared/generic_css_device.c" + "../../../../../fsw/apps/hwlib/fsw/stubs/libi2c.c" + "../../../../../fsw/apps/hwlib/fsw/stubs/libuart.c" + +) + +# The generic_css uses library functions provided by generic_css_lib so must be linked +# with the generic_css_lib stub library (this is mainly just an example of how this +# can be done). +#add_cfe_coverage_dependency(generic_css ALL generic_css_lib) + diff --git a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c new file mode 100755 index 0000000..e4dabb3 --- /dev/null +++ b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c @@ -0,0 +1,467 @@ +/* +** 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: coveragetest_generic_css_app.c +** +** Purpose: +** Coverage Unit Test cases for the GENERIC_CSS Application +** +** Notes: +** This implements various test cases to exercise all code +** paths through all functions defined in the GENERIC_CSS application. +** +** It is primarily focused at providing examples of the various +** stub configurations, hook functions, and wrapper calls that +** are often needed when coercing certain code paths through +** complex functions. +*/ + +/* + * Includes + */ + +#include "generic_css_app_coveragetest_common.h" +#include "ut_generic_css_app.h" + +/* to get the GENERIC_CSS_LIB_Function() declaration */ + +typedef struct +{ + uint16 ExpectedEvent; + uint32 MatchCount; + const char *ExpectedFormat; +} UT_CheckEvent_t; + +/* + * An example hook function to check for a specific event. + */ +static int32 UT_CheckEvent_Hook(void *UserObj, int32 StubRetcode, uint32 CallCount, const UT_StubContext_t *Context, + va_list va) +{ + UT_CheckEvent_t *State = UserObj; + uint16 EventId; + const char * Spec; + + /* + * The CFE_EVS_SendEvent stub passes the EventID as the + * first context argument. + */ + if (Context->ArgCount > 0) + { + EventId = UT_Hook_GetArgValueByName(Context, "EventID", uint16); + if (EventId == State->ExpectedEvent) + { + if (State->ExpectedFormat != NULL) + { + Spec = UT_Hook_GetArgValueByName(Context, "Spec", const char *); + if (Spec != NULL) + { + /* + * Example of how to validate the full argument set. + * ------------------------------------------------ + * + * If really desired one can call something like: + * + * char TestText[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH]; + * vsnprintf(TestText, sizeof(TestText), Spec, va); + * + * And then compare the output (TestText) to the expected fully-rendered string. + * + * NOTE: While this can be done, use with discretion - This isn't really + * verifying that the FSW code unit generated the correct event text, + * rather it is validating what the system snprintf() library function + * produces when passed the format string and args. + * + * This type of check has been demonstrated to make tests very fragile, + * because it is influenced by many factors outside the control of the + * test case. + * + * __This derived string is not an actual output of the unit under test__ + */ + if (strcmp(Spec, State->ExpectedFormat) == 0) + { + ++State->MatchCount; + } + } + } + else + { + ++State->MatchCount; + } + } + } + + return 0; +} + +/* + * Helper function to set up for event checking + * This attaches the hook function to CFE_EVS_SendEvent + */ +static void UT_CheckEvent_Setup(UT_CheckEvent_t *Evt, uint16 ExpectedEvent, const char *ExpectedFormat) +{ + memset(Evt, 0, sizeof(*Evt)); + Evt->ExpectedEvent = ExpectedEvent; + Evt->ExpectedFormat = ExpectedFormat; + UT_SetVaHookFunction(UT_KEY(CFE_EVS_SendEvent), UT_CheckEvent_Hook, Evt); +} + +/* +********************************************************************************** +** TEST CASE FUNCTIONS +********************************************************************************** +*/ + +void Test_CSS_AppMain(void) +{ + CFE_SB_MsgId_t MsgId = CFE_SB_INVALID_MSG_ID; + + /* + * Test Case For: + * void CSS_AppMain( void ) + */ + + UT_CheckEvent_t EventTest; + + /* + * CSS_AppMain does not return a value, + * but it has several internal decision points + * that need to be exercised here. + * + * First call it in "nominal" mode where all + * dependent calls should be successful by default. + */ + CSS_AppMain(); + + /* + * Confirm that CFE_ES_ExitApp() was called at the end of execution + */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_ExitApp)) == 1, "CFE_ES_ExitApp() called"); + + /* + * Now set up individual cases for each of the error paths. + * The first is for GENERIC_CSS_AppInit(). As this is in the same + * code unit, it is not a stub where the return code can be + * easily set. In order to get this to fail, an underlying + * call needs to fail, and the error gets propagated through. + * The call to CFE_EVS_Register is the first opportunity. + * Any identifiable (non-success) return code should work. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); + + /* + * Just call the function again. It does not return + * the value, so there is nothing to test for here directly. + * However, it should show up in the coverage report that + * the GENERIC_CSS_AppInit() failure path was taken. + */ + CSS_AppMain(); + + /* + * This can validate that the internal "RunStatus" was + * set to CFE_ES_RunStatus_APP_ERROR, by querying the struct directly. + * + * It is always advisable to include the _actual_ values + * when asserting on conditions, so if/when it fails, the + * log will show what the incorrect value was. + */ + UtAssert_True(GENERIC_CSS_AppData.RunStatus == CFE_ES_RunStatus_APP_ERROR, + "GENERIC_CSS_AppData.RunStatus (%lu) == CFE_ES_RunStatus_APP_ERROR", + (unsigned long)GENERIC_CSS_AppData.RunStatus); + + /* + * Note that CFE_ES_RunLoop returns a boolean value, + * so in order to exercise the internal "while" loop, + * it needs to return TRUE. But this also needs to return + * FALSE in order to get out of the loop, otherwise + * it will stay there infinitely. + * + * The deferred retcode will accomplish this. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); + + /* Set up buffer for command processing */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); + + /* + * Invoke again + */ + CSS_AppMain(); + + /* + * Confirm that CFE_SB_ReceiveBuffer() (inside the loop) was called + */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_ReceiveBuffer)) == 1, "CFE_SB_ReceiveBuffer() called"); + + /* + * Now also make the CFE_SB_ReceiveBuffer call fail, + * to exercise that error path. This sends an + * event which can be checked with a hook function. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); + UT_SetDeferredRetcode(UT_KEY(CFE_SB_ReceiveBuffer), 1, CFE_SB_PIPE_RD_ERR); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PIPE_ERR_EID, "GENERIC_CSS: SB Pipe Read Error = %d"); + + /* + * Invoke again + */ + CSS_AppMain(); + + /* + * Confirm that the event was generated + */ + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_PIPE_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); +} + +void Test_GENERIC_CSS_AppInit(void) +{ + /* + * Test Case For: + * int32 GENERIC_CSS_AppInit( void ) + */ + + /* nominal case should return CFE_SUCCESS */ + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SUCCESS); + + /* trigger a failure for each of the sub-calls, + * and confirm a write to syslog for each. + * Note that this count accumulates, because the status + * is _not_ reset between these test cases. */ + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_EVS_INVALID_PARAMETER); + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_WriteToSysLog)) == 1, "CFE_ES_WriteToSysLog() called"); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_CreatePipe), 1, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 1, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 2, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); +} + +void Test_GENERIC_CSS_ProcessCommandPacket(void) +{ + /* + * Test Case For: + * void GENERIC_CSS_ProcessCommandPacket + */ + /* a buffer large enough for any command message */ + union + { + CFE_SB_Buffer_t SBBuf; + GENERIC_CSS_NoArgs_cmd_t Noop; + } TestMsg; + CFE_SB_MsgId_t TestMsgId; + CFE_MSG_FcnCode_t FcnCode; + size_t MsgSize; + UT_CheckEvent_t EventTest; + + memset(&TestMsg, 0, sizeof(TestMsg)); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PROCESS_CMD_ERR_EID, NULL); + + /* + * The CFE_MSG_GetMsgId() stub uses a data buffer to hold the + * message ID values to return. + */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); + FcnCode = GENERIC_CSS_NOOP_CC; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_CMD_ERR_EID not generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* invalid message id */ + TestMsgId = CFE_SB_INVALID_MSG_ID; + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); +} + +void Test_GENERIC_CSS_ProcessGroundCommand(void) +{ + /* + * Test Case For: + * void GENERIC_CSS_ProcessGroundCommand + */ + CFE_SB_MsgId_t TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); + CFE_MSG_FcnCode_t FcnCode; + size_t Size; + + /* a buffer large enough for any command message */ + union + { + CFE_SB_Buffer_t SBBuf; + GENERIC_CSS_NoArgs_cmd_t Noop; + GENERIC_CSS_NoArgs_cmd_t Reset; + } TestMsg; + UT_CheckEvent_t EventTest; + + memset(&TestMsg, 0, sizeof(TestMsg)); + + /* + * call with each of the supported command codes + * The CFE_MSG_GetFcnCode stub allows the code to be + * set to whatever is needed. There is no return + * value here and the actual implementation of these + * commands have separate test cases, so this just + * needs to exercise the "switch" statement. + */ + + /* test dispatch of NOOP */ + FcnCode = GENERIC_CSS_NOOP_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_NOOP_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_NOOP_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of RESET */ + FcnCode = GENERIC_CSS_RESET_COUNTERS_CC; + Size = sizeof(TestMsg.Reset); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_RESET_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_RESET_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test an invalid CC */ + FcnCode = 99; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_ERR_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); +} + +void Test_GENERIC_CSS_ReportHousekeeping(void) +{ + /* + * Test Case For: + * void GENERIC_CSS_ReportHousekeeping() + */ + CFE_MSG_Message_t *MsgSend; + CFE_MSG_Message_t *MsgTimestamp; + CFE_SB_MsgId_t MsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_TLM); + + /* Set message id to return so GENERIC_CSS_Housekeeping will be called */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); + + /* Set up to capture send message address */ + UT_SetDataBuffer(UT_KEY(CFE_SB_TransmitMsg), &MsgSend, sizeof(MsgSend), false); + + /* Set up to capture timestamp message address */ + UT_SetDataBuffer(UT_KEY(CFE_SB_TimeStampMsg), &MsgTimestamp, sizeof(MsgTimestamp), false); + + /* Call unit under test, NULL pointer confirms command access is through APIs */ + GENERIC_CSS_ReportHousekeeping(); + + /* Confirm message sent*/ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TransmitMsg)) == 1, "CFE_SB_TransmitMsg() called once"); + UtAssert_True(MsgSend == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, "CFE_SB_TransmitMsg() address matches expected"); + + /* Confirm timestamp msg address */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TimeStampMsg)) == 1, "CFE_SB_TimeStampMsg() called once"); + UtAssert_True(MsgTimestamp == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, + "CFE_SB_TimeStampMsg() address matches expected"); +} + +void Test_GENERIC_CSS_VerifyCmdLength(void) +{ + /* + * Test Case For: + * bool GENERIC_CSS_VerifyCmdLength + */ + UT_CheckEvent_t EventTest; + size_t size = 1; + CFE_MSG_FcnCode_t fcncode = 2; + CFE_SB_MsgId_t msgid = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); + + /* + * test a match case + */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); + + GENERIC_CSS_VerifyCmdLength(NULL, size); + + /* + * Confirm that the event was NOT generated + */ + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_LEN_ERR_EID NOT generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* + * test a mismatch case + */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &msgid, sizeof(msgid), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &fcncode, sizeof(fcncode), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); + GENERIC_CSS_VerifyCmdLength(NULL, size + 1); + + /* + * Confirm that the event WAS generated + */ + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_LEN_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); +} + +/* + * Setup function prior to every test + */ +void Generic_css_UT_Setup(void) +{ + UT_ResetState(0); +} + +/* + * Teardown function after every test + */ +void Generic_css_UT_TearDown(void) {} + +/* + * Register the test cases to execute with the unit test tool + */ +void UtTest_Setup(void) +{ + ADD_TEST(CSS_AppMain); + ADD_TEST(GENERIC_CSS_AppInit); + ADD_TEST(GENERIC_CSS_ProcessCommandPacket); + ADD_TEST(GENERIC_CSS_ProcessGroundCommand); + ADD_TEST(GENERIC_CSS_ReportHousekeeping); + ADD_TEST(GENERIC_CSS_VerifyCmdLength); +} diff --git a/fsw/cfs/unit-test/coveragetest/generic_css_app_coveragetest_common.h b/fsw/cfs/unit-test/coveragetest/generic_css_app_coveragetest_common.h new file mode 100755 index 0000000..c5aea46 --- /dev/null +++ b/fsw/cfs/unit-test/coveragetest/generic_css_app_coveragetest_common.h @@ -0,0 +1,67 @@ +/* +** 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 + * + * Common definitions for all generic_css_app coverage tests + */ + +#ifndef GENERIC_CSS_APP_COVERAGETEST_COMMON_H +#define GENERIC_CSS_APP_COVERAGETEST_COMMON_H + +/* + * Includes + */ + +#include "utassert.h" +#include "uttest.h" +#include "utstubs.h" + +#include "cfe.h" +#include "generic_css_events.h" +#include "generic_css_app.h" + +/* + * Macro to call a function and check its int32 return code + */ +#define UT_TEST_FUNCTION_RC(func, exp) \ + { \ + int32 rcexp = exp; \ + int32 rcact = func; \ + UtAssert_True(rcact == rcexp, "%s (%ld) == %s (%ld)", #func, (long)rcact, #exp, (long)rcexp); \ + } + +/* + * Macro to add a test case to the list of tests to execute + */ +#define ADD_TEST(test) UtTest_Add((Test_##test), Generic_css_UT_Setup, Generic_css_UT_TearDown, #test) + +/* + * Setup function prior to every test + */ +void Generic_css_UT_Setup(void); + +/* + * Teardown function after every test + */ +void Generic_css_UT_TearDown(void); + +#endif /* GENERIC_CSS_APP_COVERAGETEST_COMMON_H */ diff --git a/fsw/cfs/unit-test/inc/ut_generic_css_app.h b/fsw/cfs/unit-test/inc/ut_generic_css_app.h new file mode 100755 index 0000000..2540055 --- /dev/null +++ b/fsw/cfs/unit-test/inc/ut_generic_css_app.h @@ -0,0 +1,51 @@ +/* +** 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 + * + * + * Purpose: + * Extra scaffolding functions for the generic_css_app unit test + * + * Notes: + * This is an extra UT-specific extern declaration + * to obtain access to an internal data structure + * + * UT often needs to modify internal data structures in ways that + * actual applications never would (bypassing the normal API) in + * order to exercise or set up for off-nominal cases. + */ + +#ifndef UT_GENERIC_CSS_APP_H +#define UT_GENERIC_CSS_APP_H + +/* + * Necessary to include these here to get the definition of the + * "GENERIC_CSS_APP_Data_t" typedef. + */ +#include "generic_css_app.h" + +/* + * Allow UT access to the global "GENERIC_CSS_APP_Data" object. + */ +//extern GENERIC_CSS_AppData_t GENERIC_CSS_APP_Data; + +#endif /* UT_GENERIC_CSS_APP_H */ From de7dee9bd4c9242160498894e4e51ef927159b04 Mon Sep 17 00:00:00 2001 From: dacarter22 Date: Sun, 16 Mar 2025 23:50:26 -0400 Subject: [PATCH 02/12] [nasa/nos3#450] coverage up to 88%] --- .../coveragetest_generic_css_app.c | 924 ++++++++++-------- 1 file changed, 498 insertions(+), 426 deletions(-) diff --git a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c index e4dabb3..37a14fc 100755 --- a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c +++ b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c @@ -38,430 +38,502 @@ * Includes */ -#include "generic_css_app_coveragetest_common.h" -#include "ut_generic_css_app.h" - -/* to get the GENERIC_CSS_LIB_Function() declaration */ - -typedef struct -{ - uint16 ExpectedEvent; - uint32 MatchCount; - const char *ExpectedFormat; -} UT_CheckEvent_t; - -/* - * An example hook function to check for a specific event. - */ -static int32 UT_CheckEvent_Hook(void *UserObj, int32 StubRetcode, uint32 CallCount, const UT_StubContext_t *Context, - va_list va) -{ - UT_CheckEvent_t *State = UserObj; - uint16 EventId; - const char * Spec; - - /* - * The CFE_EVS_SendEvent stub passes the EventID as the - * first context argument. - */ - if (Context->ArgCount > 0) - { - EventId = UT_Hook_GetArgValueByName(Context, "EventID", uint16); - if (EventId == State->ExpectedEvent) - { - if (State->ExpectedFormat != NULL) - { - Spec = UT_Hook_GetArgValueByName(Context, "Spec", const char *); - if (Spec != NULL) - { - /* - * Example of how to validate the full argument set. - * ------------------------------------------------ - * - * If really desired one can call something like: - * - * char TestText[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH]; - * vsnprintf(TestText, sizeof(TestText), Spec, va); - * - * And then compare the output (TestText) to the expected fully-rendered string. - * - * NOTE: While this can be done, use with discretion - This isn't really - * verifying that the FSW code unit generated the correct event text, - * rather it is validating what the system snprintf() library function - * produces when passed the format string and args. - * - * This type of check has been demonstrated to make tests very fragile, - * because it is influenced by many factors outside the control of the - * test case. - * - * __This derived string is not an actual output of the unit under test__ - */ - if (strcmp(Spec, State->ExpectedFormat) == 0) - { - ++State->MatchCount; - } - } - } - else - { - ++State->MatchCount; - } - } - } - - return 0; -} - -/* - * Helper function to set up for event checking - * This attaches the hook function to CFE_EVS_SendEvent - */ -static void UT_CheckEvent_Setup(UT_CheckEvent_t *Evt, uint16 ExpectedEvent, const char *ExpectedFormat) -{ - memset(Evt, 0, sizeof(*Evt)); - Evt->ExpectedEvent = ExpectedEvent; - Evt->ExpectedFormat = ExpectedFormat; - UT_SetVaHookFunction(UT_KEY(CFE_EVS_SendEvent), UT_CheckEvent_Hook, Evt); -} - -/* -********************************************************************************** -** TEST CASE FUNCTIONS -********************************************************************************** -*/ - -void Test_CSS_AppMain(void) -{ - CFE_SB_MsgId_t MsgId = CFE_SB_INVALID_MSG_ID; - - /* - * Test Case For: - * void CSS_AppMain( void ) - */ - - UT_CheckEvent_t EventTest; - - /* - * CSS_AppMain does not return a value, - * but it has several internal decision points - * that need to be exercised here. - * - * First call it in "nominal" mode where all - * dependent calls should be successful by default. - */ - CSS_AppMain(); - - /* - * Confirm that CFE_ES_ExitApp() was called at the end of execution - */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_ExitApp)) == 1, "CFE_ES_ExitApp() called"); - - /* - * Now set up individual cases for each of the error paths. - * The first is for GENERIC_CSS_AppInit(). As this is in the same - * code unit, it is not a stub where the return code can be - * easily set. In order to get this to fail, an underlying - * call needs to fail, and the error gets propagated through. - * The call to CFE_EVS_Register is the first opportunity. - * Any identifiable (non-success) return code should work. - */ - UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); - - /* - * Just call the function again. It does not return - * the value, so there is nothing to test for here directly. - * However, it should show up in the coverage report that - * the GENERIC_CSS_AppInit() failure path was taken. - */ - CSS_AppMain(); - - /* - * This can validate that the internal "RunStatus" was - * set to CFE_ES_RunStatus_APP_ERROR, by querying the struct directly. - * - * It is always advisable to include the _actual_ values - * when asserting on conditions, so if/when it fails, the - * log will show what the incorrect value was. - */ - UtAssert_True(GENERIC_CSS_AppData.RunStatus == CFE_ES_RunStatus_APP_ERROR, - "GENERIC_CSS_AppData.RunStatus (%lu) == CFE_ES_RunStatus_APP_ERROR", - (unsigned long)GENERIC_CSS_AppData.RunStatus); - - /* - * Note that CFE_ES_RunLoop returns a boolean value, - * so in order to exercise the internal "while" loop, - * it needs to return TRUE. But this also needs to return - * FALSE in order to get out of the loop, otherwise - * it will stay there infinitely. - * - * The deferred retcode will accomplish this. - */ - UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); - - /* Set up buffer for command processing */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); - - /* - * Invoke again - */ - CSS_AppMain(); - - /* - * Confirm that CFE_SB_ReceiveBuffer() (inside the loop) was called - */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_ReceiveBuffer)) == 1, "CFE_SB_ReceiveBuffer() called"); - - /* - * Now also make the CFE_SB_ReceiveBuffer call fail, - * to exercise that error path. This sends an - * event which can be checked with a hook function. - */ - UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); - UT_SetDeferredRetcode(UT_KEY(CFE_SB_ReceiveBuffer), 1, CFE_SB_PIPE_RD_ERR); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PIPE_ERR_EID, "GENERIC_CSS: SB Pipe Read Error = %d"); - - /* - * Invoke again - */ - CSS_AppMain(); - - /* - * Confirm that the event was generated - */ - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_PIPE_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); -} - -void Test_GENERIC_CSS_AppInit(void) -{ - /* - * Test Case For: - * int32 GENERIC_CSS_AppInit( void ) - */ - - /* nominal case should return CFE_SUCCESS */ - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SUCCESS); - - /* trigger a failure for each of the sub-calls, - * and confirm a write to syslog for each. - * Note that this count accumulates, because the status - * is _not_ reset between these test cases. */ - UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_EVS_INVALID_PARAMETER); - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_WriteToSysLog)) == 1, "CFE_ES_WriteToSysLog() called"); - - UT_SetDeferredRetcode(UT_KEY(CFE_SB_CreatePipe), 1, CFE_SB_BAD_ARGUMENT); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); - - UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 1, CFE_SB_BAD_ARGUMENT); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); - - UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 2, CFE_SB_BAD_ARGUMENT); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); -} - -void Test_GENERIC_CSS_ProcessCommandPacket(void) -{ - /* - * Test Case For: - * void GENERIC_CSS_ProcessCommandPacket - */ - /* a buffer large enough for any command message */ - union - { - CFE_SB_Buffer_t SBBuf; - GENERIC_CSS_NoArgs_cmd_t Noop; - } TestMsg; - CFE_SB_MsgId_t TestMsgId; - CFE_MSG_FcnCode_t FcnCode; - size_t MsgSize; - UT_CheckEvent_t EventTest; - - memset(&TestMsg, 0, sizeof(TestMsg)); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PROCESS_CMD_ERR_EID, NULL); - - /* - * The CFE_MSG_GetMsgId() stub uses a data buffer to hold the - * message ID values to return. - */ - TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); - FcnCode = GENERIC_CSS_NOOP_CC; - MsgSize = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); - GENERIC_CSS_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_CMD_ERR_EID not generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* invalid message id */ - TestMsgId = CFE_SB_INVALID_MSG_ID; - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - GENERIC_CSS_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); -} - -void Test_GENERIC_CSS_ProcessGroundCommand(void) -{ - /* - * Test Case For: - * void GENERIC_CSS_ProcessGroundCommand - */ - CFE_SB_MsgId_t TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); - CFE_MSG_FcnCode_t FcnCode; - size_t Size; - - /* a buffer large enough for any command message */ - union - { - CFE_SB_Buffer_t SBBuf; - GENERIC_CSS_NoArgs_cmd_t Noop; - GENERIC_CSS_NoArgs_cmd_t Reset; - } TestMsg; - UT_CheckEvent_t EventTest; - - memset(&TestMsg, 0, sizeof(TestMsg)); - - /* - * call with each of the supported command codes - * The CFE_MSG_GetFcnCode stub allows the code to be - * set to whatever is needed. There is no return - * value here and the actual implementation of these - * commands have separate test cases, so this just - * needs to exercise the "switch" statement. - */ - - /* test dispatch of NOOP */ - FcnCode = GENERIC_CSS_NOOP_CC; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_NOOP_INF_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_NOOP_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of RESET */ - FcnCode = GENERIC_CSS_RESET_COUNTERS_CC; - Size = sizeof(TestMsg.Reset); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_RESET_INF_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_RESET_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test an invalid CC */ - FcnCode = 99; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_ERR_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); -} - -void Test_GENERIC_CSS_ReportHousekeeping(void) -{ - /* - * Test Case For: - * void GENERIC_CSS_ReportHousekeeping() - */ - CFE_MSG_Message_t *MsgSend; - CFE_MSG_Message_t *MsgTimestamp; - CFE_SB_MsgId_t MsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_TLM); - - /* Set message id to return so GENERIC_CSS_Housekeeping will be called */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); - - /* Set up to capture send message address */ - UT_SetDataBuffer(UT_KEY(CFE_SB_TransmitMsg), &MsgSend, sizeof(MsgSend), false); - - /* Set up to capture timestamp message address */ - UT_SetDataBuffer(UT_KEY(CFE_SB_TimeStampMsg), &MsgTimestamp, sizeof(MsgTimestamp), false); - - /* Call unit under test, NULL pointer confirms command access is through APIs */ - GENERIC_CSS_ReportHousekeeping(); - - /* Confirm message sent*/ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TransmitMsg)) == 1, "CFE_SB_TransmitMsg() called once"); - UtAssert_True(MsgSend == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, "CFE_SB_TransmitMsg() address matches expected"); - - /* Confirm timestamp msg address */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TimeStampMsg)) == 1, "CFE_SB_TimeStampMsg() called once"); - UtAssert_True(MsgTimestamp == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, - "CFE_SB_TimeStampMsg() address matches expected"); -} - -void Test_GENERIC_CSS_VerifyCmdLength(void) -{ - /* - * Test Case For: - * bool GENERIC_CSS_VerifyCmdLength - */ - UT_CheckEvent_t EventTest; - size_t size = 1; - CFE_MSG_FcnCode_t fcncode = 2; - CFE_SB_MsgId_t msgid = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); - - /* - * test a match case - */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); - - GENERIC_CSS_VerifyCmdLength(NULL, size); - - /* - * Confirm that the event was NOT generated - */ - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_LEN_ERR_EID NOT generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* - * test a mismatch case - */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &msgid, sizeof(msgid), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &fcncode, sizeof(fcncode), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); - GENERIC_CSS_VerifyCmdLength(NULL, size + 1); - - /* - * Confirm that the event WAS generated - */ - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_LEN_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); -} - -/* - * Setup function prior to every test - */ -void Generic_css_UT_Setup(void) -{ - UT_ResetState(0); -} - -/* - * Teardown function after every test - */ -void Generic_css_UT_TearDown(void) {} - -/* - * Register the test cases to execute with the unit test tool + #include "generic_css_app_coveragetest_common.h" + #include "ut_generic_css_app.h" + + /* to get the GENERIC_CSS_LIB_Function() declaration */ + + typedef struct + { + uint16 ExpectedEvent; + uint32 MatchCount; + const char *ExpectedFormat; + } UT_CheckEvent_t; + + /* + * An example hook function to check for a specific event. + */ + static int32 UT_CheckEvent_Hook(void *UserObj, int32 StubRetcode, uint32 CallCount, const UT_StubContext_t *Context, + va_list va) + { + UT_CheckEvent_t *State = UserObj; + uint16 EventId; + const char * Spec; + + /* + * The CFE_EVS_SendEvent stub passes the EventID as the + * first context argument. + */ + if (Context->ArgCount > 0) + { + EventId = UT_Hook_GetArgValueByName(Context, "EventID", uint16); + if (EventId == State->ExpectedEvent) + { + if (State->ExpectedFormat != NULL) + { + Spec = UT_Hook_GetArgValueByName(Context, "Spec", const char *); + if (Spec != NULL) + { + /* + * Example of how to validate the full argument set. + * ------------------------------------------------ + * + * If really desired one can call something like: + * + * char TestText[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH]; + * vsnprintf(TestText, sizeof(TestText), Spec, va); + * + * And then compare the output (TestText) to the expected fully-rendered string. + * + * NOTE: While this can be done, use with discretion - This isn't really + * verifying that the FSW code unit generated the correct event text, + * rather it is validating what the system snprintf() library function + * produces when passed the format string and args. + * + * This type of check has been demonstrated to make tests very fragile, + * because it is influenced by many factors outside the control of the + * test case. + * + * __This derived string is not an actual output of the unit under test__ + */ + if (strcmp(Spec, State->ExpectedFormat) == 0) + { + ++State->MatchCount; + } + } + } + else + { + ++State->MatchCount; + } + } + } + + return 0; + } + + /* + * Helper function to set up for event checking + * This attaches the hook function to CFE_EVS_SendEvent + */ + static void UT_CheckEvent_Setup(UT_CheckEvent_t *Evt, uint16 ExpectedEvent, const char *ExpectedFormat) + { + memset(Evt, 0, sizeof(*Evt)); + Evt->ExpectedEvent = ExpectedEvent; + Evt->ExpectedFormat = ExpectedFormat; + UT_SetVaHookFunction(UT_KEY(CFE_EVS_SendEvent), UT_CheckEvent_Hook, Evt); + } + + /* + ********************************************************************************** + ** TEST CASE FUNCTIONS + ********************************************************************************** */ -void UtTest_Setup(void) -{ - ADD_TEST(CSS_AppMain); - ADD_TEST(GENERIC_CSS_AppInit); - ADD_TEST(GENERIC_CSS_ProcessCommandPacket); - ADD_TEST(GENERIC_CSS_ProcessGroundCommand); - ADD_TEST(GENERIC_CSS_ReportHousekeeping); - ADD_TEST(GENERIC_CSS_VerifyCmdLength); -} + + void Test_CSS_AppMain(void) + { + CFE_SB_MsgId_t MsgId = CFE_SB_INVALID_MSG_ID; + + /* + * Test Case For: + * void CSS_AppMain( void ) + */ + + UT_CheckEvent_t EventTest; + + /* + * CSS_AppMain does not return a value, + * but it has several internal decision points + * that need to be exercised here. + * + * First call it in "nominal" mode where all + * dependent calls should be successful by default. + */ + CSS_AppMain(); + + /* + * Confirm that CFE_ES_ExitApp() was called at the end of execution + */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_ExitApp)) == 1, "CFE_ES_ExitApp() called"); + + /* + * Now set up individual cases for each of the error paths. + * The first is for GENERIC_CSS_AppInit(). As this is in the same + * code unit, it is not a stub where the return code can be + * easily set. In order to get this to fail, an underlying + * call needs to fail, and the error gets propagated through. + * The call to CFE_EVS_Register is the first opportunity. + * Any identifiable (non-success) return code should work. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); + + /* + * Just call the function again. It does not return + * the value, so there is nothing to test for here directly. + * However, it should show up in the coverage report that + * the GENERIC_CSS_AppInit() failure path was taken. + */ + CSS_AppMain(); + + /* + * This can validate that the internal "RunStatus" was + * set to CFE_ES_RunStatus_APP_ERROR, by querying the struct directly. + * + * It is always advisable to include the _actual_ values + * when asserting on conditions, so if/when it fails, the + * log will show what the incorrect value was. + */ + UtAssert_True(GENERIC_CSS_AppData.RunStatus == CFE_ES_RunStatus_APP_ERROR, + "GENERIC_CSS_AppData.RunStatus (%lu) == CFE_ES_RunStatus_APP_ERROR", + (unsigned long)GENERIC_CSS_AppData.RunStatus); + + /* + * Note that CFE_ES_RunLoop returns a boolean value, + * so in order to exercise the internal "while" loop, + * it needs to return TRUE. But this also needs to return + * FALSE in order to get out of the loop, otherwise + * it will stay there infinitely. + * + * The deferred retcode will accomplish this. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); + + /* Set up buffer for command processing */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); + + /* + * Invoke again + */ + CSS_AppMain(); + + /* + * Confirm that CFE_SB_ReceiveBuffer() (inside the loop) was called + */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_ReceiveBuffer)) == 1, "CFE_SB_ReceiveBuffer() called"); + + /* + * Now also make the CFE_SB_ReceiveBuffer call fail, + * to exercise that error path. This sends an + * event which can be checked with a hook function. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); + UT_SetDeferredRetcode(UT_KEY(CFE_SB_ReceiveBuffer), 1, CFE_SB_PIPE_RD_ERR); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PIPE_ERR_EID, "GENERIC_CSS: SB Pipe Read Error = %d"); + + /* + * Invoke again + */ + CSS_AppMain(); + + /* + * Confirm that the event was generated + */ + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_PIPE_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + } + + void Test_GENERIC_CSS_AppInit(void) + { + /* + * Test Case For: + * int32 GENERIC_CSS_AppInit( void ) + */ + + /* nominal case should return CFE_SUCCESS */ + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SUCCESS); + + /* trigger a failure for each of the sub-calls, + * and confirm a write to syslog for each. + * Note that this count accumulates, because the status + * is _not_ reset between these test cases. */ + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_EVS_INVALID_PARAMETER); + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_WriteToSysLog)) == 1, "CFE_ES_WriteToSysLog() called"); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_CreatePipe), 1, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 1, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 2, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); + } + + void Test_GENERIC_CSS_ProcessCommandPacket(void) + { + /* + * Test Case For: + * void GENERIC_CSS_ProcessCommandPacket + */ + /* a buffer large enough for any command message */ + union + { + CFE_SB_Buffer_t SBBuf; + GENERIC_CSS_NoArgs_cmd_t Noop; + } TestMsg; + CFE_SB_MsgId_t TestMsgId; + CFE_MSG_FcnCode_t FcnCode; + size_t MsgSize; + UT_CheckEvent_t EventTest; + + memset(&TestMsg, 0, sizeof(TestMsg)); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PROCESS_CMD_ERR_EID, NULL); + + /* + * The CFE_MSG_GetMsgId() stub uses a data buffer to hold the + * message ID values to return. + */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); + FcnCode = GENERIC_CSS_NOOP_CC; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_CMD_ERR_EID not generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* invalid message id */ + TestMsgId = CFE_SB_INVALID_MSG_ID; + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* Request_HK message id */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); + FcnCode = GENERIC_CSS_REQ_HK_TLM; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_HK_ERR_EID not generated (%u)", + (unsigned int)EventTest.MatchCount); + + + } + + void Test_GENERIC_CSS_ProcessGroundCommand(void) + { + /* + * Test Case For: + * void GENERIC_CSS_ProcessGroundCommand + */ + CFE_SB_MsgId_t TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); + CFE_MSG_FcnCode_t FcnCode; + size_t Size; + + /* a buffer large enough for any command message */ + union + { + CFE_SB_Buffer_t SBBuf; + GENERIC_CSS_NoArgs_cmd_t Noop; + GENERIC_CSS_NoArgs_cmd_t Reset; + } TestMsg; + UT_CheckEvent_t EventTest; + + memset(&TestMsg, 0, sizeof(TestMsg)); + + /* + * call with each of the supported command codes + * The CFE_MSG_GetFcnCode stub allows the code to be + * set to whatever is needed. There is no return + * value here and the actual implementation of these + * commands have separate test cases, so this just + * needs to exercise the "switch" statement. + */ + + /* test dispatch of NOOP */ + FcnCode = GENERIC_CSS_NOOP_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_NOOP_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_NOOP_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of RESET */ + FcnCode = GENERIC_CSS_RESET_COUNTERS_CC; + Size = sizeof(TestMsg.Reset); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_RESET_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_RESET_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test an invalid CC */ + FcnCode = 99; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_ERR_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of ENABLE */ + FcnCode = GENERIC_CSS_ENABLE_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_ENABLE_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ENABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of DISABLE */ + FcnCode = GENERIC_CSS_DISABLE_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_DISABLE_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_DISABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + } + + void Test_GENERIC_CSS_ReportHousekeeping(void) + { + /* + * Test Case For: + * void GENERIC_CSS_ReportHousekeeping() + */ + CFE_MSG_Message_t *MsgSend; + CFE_MSG_Message_t *MsgTimestamp; + CFE_SB_MsgId_t MsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_TLM); + + /* Set message id to return so GENERIC_CSS_Housekeeping will be called */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); + + /* Set up to capture send message address */ + UT_SetDataBuffer(UT_KEY(CFE_SB_TransmitMsg), &MsgSend, sizeof(MsgSend), false); + + /* Set up to capture timestamp message address */ + UT_SetDataBuffer(UT_KEY(CFE_SB_TimeStampMsg), &MsgTimestamp, sizeof(MsgTimestamp), false); + + /* Call unit under test, NULL pointer confirms command access is through APIs */ + GENERIC_CSS_ReportHousekeeping(); + + /* Confirm message sent*/ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TransmitMsg)) == 1, "CFE_SB_TransmitMsg() called once"); + UtAssert_True(MsgSend == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, "CFE_SB_TransmitMsg() address matches expected"); + + /* Confirm timestamp msg address */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TimeStampMsg)) == 1, "CFE_SB_TimeStampMsg() called once"); + UtAssert_True(MsgTimestamp == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, + "CFE_SB_TimeStampMsg() address matches expected"); + } + + void Test_GENERIC_CSS_ReportDeviceTelemetry(void) + { + /* + * Test Case For: + * void Test_GENERIC_CSS_ReportDeviceTelemetry() + */ + CFE_MSG_Message_t *MsgSend; + CFE_MSG_Message_t *MsgTimestamp; + CFE_SB_MsgId_t MsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_DATA_TLM); + + /* Set message id to return so GENERIC_CSS_Housekeeping will be called */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); + + /* Set up to capture send message address */ + UT_SetDataBuffer(UT_KEY(CFE_SB_TransmitMsg), &MsgSend, sizeof(MsgSend), false); + + /* Set up to capture timestamp message address */ + UT_SetDataBuffer(UT_KEY(CFE_SB_TimeStampMsg), &MsgTimestamp, sizeof(MsgTimestamp), false); + + /* Call unit under test, NULL pointer confirms command access is through APIs */ + GENERIC_CSS_ReportDeviceTelemetry(); + + /* Confirm message sent*/ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TransmitMsg)) == 1, "CFE_SB_TransmitMsg() called once"); + UtAssert_True(MsgSend == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, "CFE_SB_TransmitMsg() address matches expected"); + + /* Confirm timestamp msg address */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TimeStampMsg)) == 1, "CFE_SB_TimeStampMsg() called once"); + UtAssert_True(MsgTimestamp == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, + "CFE_SB_TimeStampMsg() address matches expected"); + } + + void Test_GENERIC_CSS_VerifyCmdLength(void) + { + /* + * Test Case For: + * bool GENERIC_CSS_VerifyCmdLength + */ + + + UT_CheckEvent_t EventTest; + size_t size = 1; + CFE_MSG_FcnCode_t fcncode = 2; + CFE_SB_MsgId_t msgid = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); + + /* + * test a match case + */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); + + GENERIC_CSS_VerifyCmdLength(NULL, size); + + /* + * Confirm that the event was NOT generated + */ + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_LEN_ERR_EID NOT generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* + * test a mismatch case + */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &msgid, sizeof(msgid), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &fcncode, sizeof(fcncode), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); + GENERIC_CSS_VerifyCmdLength(NULL, size + 1); + + /* + * Confirm that the event WAS generated + */ + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_LEN_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + } + + /* + * Setup function prior to every test + */ + void Generic_css_UT_Setup(void) + { + UT_ResetState(0); + } + + /* + * Teardown function after every test + */ + void Generic_css_UT_TearDown(void) {} + + /* + * Register the test cases to execute with the unit test tool + */ + void UtTest_Setup(void) + { + ADD_TEST(CSS_AppMain); + ADD_TEST(GENERIC_CSS_AppInit); + ADD_TEST(GENERIC_CSS_ProcessCommandPacket); + ADD_TEST(GENERIC_CSS_ProcessGroundCommand); + ADD_TEST(GENERIC_CSS_ReportHousekeeping); + ADD_TEST(GENERIC_CSS_ReportDeviceTelemetry); + ADD_TEST(GENERIC_CSS_VerifyCmdLength); + } + \ No newline at end of file From 33570fdbeb4a7e056ed2442187fc3ef3bda6d0aa Mon Sep 17 00:00:00 2001 From: dacarter22 Date: Tue, 18 Mar 2025 13:50:56 -0400 Subject: [PATCH 03/12] [nasa/nos3#450] CSS coverage at 92% --- .../coveragetest/coveragetest_css_app.c | 583 ++++++++++++++++++ 1 file changed, 583 insertions(+) create mode 100644 fsw/unit-test/coveragetest/coveragetest_css_app.c diff --git a/fsw/unit-test/coveragetest/coveragetest_css_app.c b/fsw/unit-test/coveragetest/coveragetest_css_app.c new file mode 100644 index 0000000..c305e6e --- /dev/null +++ b/fsw/unit-test/coveragetest/coveragetest_css_app.c @@ -0,0 +1,583 @@ +/* +** 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: coveragetest_generic_torquer_app.c +** +** Purpose: +** Coverage Unit Test cases for the GENERIC_TORQUER Application +** +** Notes: +** This implements various test cases to exercise all code +** paths through all functions defined in the GENERIC_TORQUER application. +** +** It is primarily focused at providing examples of the various +** stub configurations, hook functions, and wrapper calls that +** are often needed when coercing certain code paths through +** complex functions. +*/ + +/* + * Includes + */ + + #include "generic_torquer_app_coveragetest_common.h" + #include "ut_generic_torquer_app.h" + + /* to get the GENERIC_TORQUER_LIB_Function() declaration */ + + typedef struct + { + uint16 ExpectedEvent; + uint32 MatchCount; + const char *ExpectedFormat; + } UT_CheckEvent_t; + + /* + * An example hook function to check for a specific event. + */ + static int32 UT_CheckEvent_Hook(void *UserObj, int32 StubRetcode, uint32 CallCount, const UT_StubContext_t *Context, + va_list va) + { + UT_CheckEvent_t *State = UserObj; + uint16 EventId; + const char * Spec; + + /* + * The CFE_EVS_SendEvent stub passes the EventID as the + * first context argument. + */ + if (Context->ArgCount > 0) + { + EventId = UT_Hook_GetArgValueByName(Context, "EventID", uint16); + if (EventId == State->ExpectedEvent) + { + if (State->ExpectedFormat != NULL) + { + Spec = UT_Hook_GetArgValueByName(Context, "Spec", const char *); + if (Spec != NULL) + { + /* + * Example of how to validate the full argument set. + * ------------------------------------------------ + * + * If really desired one can call something like: + * + * char TestText[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH]; + * vsnprintf(TestText, sizeof(TestText), Spec, va); + * + * And then compare the output (TestText) to the expected fully-rendered string. + * + * NOTE: While this can be done, use with discretion - This isn't really + * verifying that the FSW code unit generated the correct event text, + * rather it is validating what the system snprintf() library function + * produces when passed the format string and args. + * + * This type of check has been demonstrated to make tests very fragile, + * because it is influenced by many factors outside the control of the + * test case. + * + * __This derived string is not an actual output of the unit under test__ + */ + if (strcmp(Spec, State->ExpectedFormat) == 0) + { + ++State->MatchCount; + } + } + } + else + { + ++State->MatchCount; + } + } + } + + return 0; + } + + /* + * Helper function to set up for event checking + * This attaches the hook function to CFE_EVS_SendEvent + */ + static void UT_CheckEvent_Setup(UT_CheckEvent_t *Evt, uint16 ExpectedEvent, const char *ExpectedFormat) + { + memset(Evt, 0, sizeof(*Evt)); + Evt->ExpectedEvent = ExpectedEvent; + Evt->ExpectedFormat = ExpectedFormat; + UT_SetVaHookFunction(UT_KEY(CFE_EVS_SendEvent), UT_CheckEvent_Hook, Evt); + } + + /* + ********************************************************************************** + ** TEST CASE FUNCTIONS + ********************************************************************************** + */ + + void Test_TORQUER_AppMain(void) + { + CFE_SB_MsgId_t MsgId = CFE_SB_INVALID_MSG_ID; + + /* + * Test Case For: + * void TORQUER_AppMain( void ) + */ + + UT_CheckEvent_t EventTest; + + /* + * TORQUER_AppMain does not return a value, + * but it has several internal decision points + * that need to be exercised here. + * + * First call it in "nominal" mode where all + * dependent calls should be successful by default. + */ + TORQUER_AppMain(); + + /* + * Confirm that CFE_ES_ExitApp() was called at the end of execution + */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_ExitApp)) == 1, "CFE_ES_ExitApp() called"); + + /* + * Now set up individual cases for each of the error paths. + * The first is for GENERIC_TORQUER_AppInit(). As this is in the same + * code unit, it is not a stub where the return code can be + * easily set. In order to get this to fail, an underlying + * call needs to fail, and the error gets propagated through. + * The call to CFE_EVS_Register is the first opportunity. + * Any identifiable (non-success) return code should work. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); + + /* + * Just call the function again. It does not return + * the value, so there is nothing to test for here directly. + * However, it should show up in the coverage report that + * the GENERIC_TORQUER_AppInit() failure path was taken. + */ + TORQUER_AppMain(); + + /* + * This can validate that the internal "RunStatus" was + * set to CFE_ES_RunStatus_APP_ERROR, by querying the struct directly. + * + * It is always advisable to include the _actual_ values + * when asserting on conditions, so if/when it fails, the + * log will show what the incorrect value was. + */ + UtAssert_True(GENERIC_TORQUER_AppData.RunStatus == CFE_ES_RunStatus_APP_ERROR, + "GENERIC_TORQUER_AppData.RunStatus (%lu) == CFE_ES_RunStatus_APP_ERROR", + (unsigned long)GENERIC_TORQUER_AppData.RunStatus); + + /* + * Note that CFE_ES_RunLoop returns a boolean value, + * so in order to exercise the internal "while" loop, + * it needs to return TRUE. But this also needs to return + * FALSE in order to get out of the loop, otherwise + * it will stay there infinitely. + * + * The deferred retcode will accomplish this. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); + + /* Set up buffer for command processing */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); + + /* + * Invoke again + */ + TORQUER_AppMain(); + + /* + * Confirm that CFE_SB_ReceiveBuffer() (inside the loop) was called + */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_ReceiveBuffer)) == 1, "CFE_SB_ReceiveBuffer() called"); + + /* + * Now also make the CFE_SB_ReceiveBuffer call fail, + * to exercise that error path. This sends an + * event which can be checked with a hook function. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); + UT_SetDeferredRetcode(UT_KEY(CFE_SB_ReceiveBuffer), 1, CFE_SB_PIPE_RD_ERR); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_PIPE_ERR_EID, "GENERIC_TORQUER: SB Pipe Read Error = %d"); + + /* + * Invoke again + */ + TORQUER_AppMain(); + + /* + * Confirm that the event was generated + */ + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_PIPE_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + } + + void Test_GENERIC_TORQUER_AppInit(void) + { + /* + * Test Case For: + * int32 GENERIC_TORQUER_AppInit( void ) + */ + + /* nominal case should return CFE_SUCCESS */ + UT_TEST_FUNCTION_RC(GENERIC_TORQUER_AppInit(), CFE_SUCCESS); + + /* trigger a failure for each of the sub-calls, + * and confirm a write to syslog for each. + * Note that this count accumulates, because the status + * is _not_ reset between these test cases. */ + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); + UT_TEST_FUNCTION_RC(GENERIC_TORQUER_AppInit(), CFE_EVS_INVALID_PARAMETER); + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_WriteToSysLog)) == 1, "CFE_ES_WriteToSysLog() called"); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_CreatePipe), 1, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_TORQUER_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 1, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_TORQUER_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 2, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_TORQUER_AppInit(), CFE_SB_BAD_ARGUMENT); + } + + void Test_GENERIC_TORQUER_ProcessCommandPacket(void) + { + /* + * Test Case For: + * void GENERIC_TORQUER_ProcessCommandPacket + */ + /* a buffer large enough for any command message */ + union + { + CFE_SB_Buffer_t SBBuf; + GENERIC_TORQUER_NoArgs_cmd_t Noop; + } TestMsg; + CFE_SB_MsgId_t TestMsgId; + CFE_MSG_FcnCode_t FcnCode; + size_t MsgSize; + UT_CheckEvent_t EventTest; + + memset(&TestMsg, 0, sizeof(TestMsg)); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_PROCESS_CMD_ERR_EID, NULL); + + /* + * The CFE_MSG_GetMsgId() stub uses a data buffer to hold the + * message ID values to return. + */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_TORQUER_CMD_MID); + FcnCode = GENERIC_TORQUER_NOOP_CC; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_TORQUER_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_TORQUER_CMD_ERR_EID not generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* invalid message id */ + TestMsgId = CFE_SB_INVALID_MSG_ID; + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + GENERIC_TORQUER_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_TORQUER_REQ_HK_MID); + FcnCode = GENERIC_TORQUER_REQ_HK_TLM; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_TORQUER_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_TORQUER_CMD_ERR_EID not generated (%u)", + (unsigned int)EventTest.MatchCount); + } + + void Test_GENERIC_TORQUER_ProcessGroundCommand(void) + { + /* + * Test Case For: + * void GENERIC_TORQUER_ProcessGroundCommand + */ + CFE_SB_MsgId_t TestMsgId = CFE_SB_ValueToMsgId(GENERIC_TORQUER_CMD_MID); + CFE_MSG_FcnCode_t FcnCode; + size_t Size; + + /* a buffer large enough for any command message */ + union + { + CFE_SB_Buffer_t SBBuf; + GENERIC_TORQUER_NoArgs_cmd_t Noop; + GENERIC_TORQUER_NoArgs_cmd_t Reset; + GENERIC_TORQUER_NoArgs_cmd_t Enable; + GENERIC_TORQUER_NoArgs_cmd_t Disable; + GENERIC_TORQUER_Percent_On_cmd_t Config; + GENERIC_TORQUER_All_Percent_On_cmd_t ConfigAll; + } TestMsg; + UT_CheckEvent_t EventTest; + + memset(&TestMsg, 0, sizeof(TestMsg)); + /* + * call with each of the supported command codes + * The CFE_MSG_GetFcnCode stub allows the code to be + * set to whatever is needed. There is no return + * value here and the actual implementation of these + * commands have separate test cases, so this just + * needs to exercise the "switch" statement. + */ + + /* test dispatch of NOOP */ + FcnCode = GENERIC_TORQUER_NOOP_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_NOOP_INF_EID, NULL); + GENERIC_TORQUER_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_NOOP_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of RESET */ + FcnCode = GENERIC_TORQUER_RESET_COUNTERS_CC; + Size = sizeof(TestMsg.Reset); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_RESET_INF_EID, NULL); + GENERIC_TORQUER_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_RESET_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of ENABLE */ + FcnCode = GENERIC_TORQUER_ENABLE_CC; + Size = sizeof(TestMsg.Enable); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_ENABLE_INF_EID, NULL); + GENERIC_TORQUER_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_ENABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + + /* test dispatch of DISABLE */ + FcnCode = GENERIC_TORQUER_DISABLE_CC; + Size = sizeof(TestMsg.Disable); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_DISABLE_INF_EID, NULL); + GENERIC_TORQUER_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_DISABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test an invalid CC */ + FcnCode = 99; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_ERR_EID, NULL); + GENERIC_TORQUER_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of ENABLE */ + FcnCode = GENERIC_TORQUER_ENABLE_CC; + Size = sizeof(TestMsg.Enable); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_ENABLE_INF_EID, NULL); + GENERIC_TORQUER_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_ENABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of CONFIG */ + TestMsg.Config.Direction = 1; + TestMsg.Config.TrqNum = 1; + TestMsg.Config.PercentOn = 1; + FcnCode = GENERIC_TORQUER_CONFIG_CC; + Size = sizeof(TestMsg.Config); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, Size, false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_CONFIG_INF_EID, NULL); + CFE_MSG_Message_t msgPtr; + GENERIC_TORQUER_AppData.MsgPtr = &msgPtr; + GENERIC_TORQUER_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_CONFIG_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of DISABLE */ + FcnCode = GENERIC_TORQUER_DISABLE_CC; + Size = sizeof(TestMsg.Disable); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_DISABLE_INF_EID, NULL); + GENERIC_TORQUER_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_DISABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of ENABLE */ + FcnCode = GENERIC_TORQUER_ENABLE_CC; + Size = sizeof(TestMsg.Enable); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_ENABLE_INF_EID, NULL); + GENERIC_TORQUER_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_ENABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of CONFIG_ALL */ + TestMsg.ConfigAll.Direction_0 = 1; + TestMsg.ConfigAll.PercentOn_0 = 1; + TestMsg.ConfigAll.Direction_1 = 1; + TestMsg.ConfigAll.PercentOn_1 = 1; + TestMsg.ConfigAll.Direction_2 = 1; + TestMsg.ConfigAll.PercentOn_2 = 1; + FcnCode = GENERIC_TORQUER_CONFIG_ALL_CC; + Size = sizeof(TestMsg.ConfigAll); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, Size, false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_CONFIG_ALL_INF_EID, NULL); + GENERIC_TORQUER_AppData.MsgPtr = &msgPtr; + GENERIC_TORQUER_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_CONFIG_ALL_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of DISABLE */ + FcnCode = GENERIC_TORQUER_DISABLE_CC; + Size = sizeof(TestMsg.Disable); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_DISABLE_INF_EID, NULL); + GENERIC_TORQUER_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_DISABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + } + + void Test_GENERIC_TORQUER_ReportHousekeeping(void) + { + /* + * Test Case For: + * void GENERIC_TORQUER_ReportHousekeeping() + */ + CFE_MSG_Message_t *MsgSend; + CFE_MSG_Message_t *MsgTimestamp; + CFE_SB_MsgId_t MsgId = CFE_SB_ValueToMsgId(GENERIC_TORQUER_REQ_HK_TLM); + + /* Set message id to return so GENERIC_TORQUER_Housekeeping will be called */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); + + /* Set up to capture send message address */ + UT_SetDataBuffer(UT_KEY(CFE_SB_TransmitMsg), &MsgSend, sizeof(MsgSend), false); + + /* Set up to capture timestamp message address */ + UT_SetDataBuffer(UT_KEY(CFE_SB_TimeStampMsg), &MsgTimestamp, sizeof(MsgTimestamp), false); + + /* Call unit under test, NULL pointer confirms command access is through APIs */ + GENERIC_TORQUER_ReportHousekeeping(); + + /* Confirm message sent*/ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TransmitMsg)) == 1, "CFE_SB_TransmitMsg() called once"); + UtAssert_True(MsgSend == &GENERIC_TORQUER_AppData.HkTelemetryPkt.TlmHeader.Msg, "CFE_SB_TransmitMsg() address matches expected"); + + /* Confirm timestamp msg address */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TimeStampMsg)) == 1, "CFE_SB_TimeStampMsg() called once"); + UtAssert_True(MsgTimestamp == &GENERIC_TORQUER_AppData.HkTelemetryPkt.TlmHeader.Msg, + "CFE_SB_TimeStampMsg() address matches expected"); + } + + void Test_GENERIC_TORQUER_VerifyCmdLength(void) + { + /* + * Test Case For: + * bool GENERIC_TORQUER_VerifyCmdLength + */ + UT_CheckEvent_t EventTest; + size_t size = 1; + CFE_MSG_FcnCode_t fcncode = 2; + CFE_SB_MsgId_t msgid = CFE_SB_ValueToMsgId(GENERIC_TORQUER_CMD_MID); + + /* + * test a match case + */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_LEN_ERR_EID, NULL); + + GENERIC_TORQUER_VerifyCmdLength(NULL, size); + + /* + * Confirm that the event was NOT generated + */ + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_TORQUER_LEN_ERR_EID NOT generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* + * test a mismatch case + */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &msgid, sizeof(msgid), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &fcncode, sizeof(fcncode), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_LEN_ERR_EID, NULL); + GENERIC_TORQUER_VerifyCmdLength(NULL, size + 1); + + /* + * Confirm that the event WAS generated + */ + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_LEN_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + } + + /* + * Setup function prior to every test + */ + void Generic_torquer_UT_Setup(void) + { + UT_ResetState(0); + } + + /* + * Teardown function after every test + */ + void Generic_torquer_UT_TearDown(void) {} + + /* + * Register the test cases to execute with the unit test tool + */ + void UtTest_Setup(void) + { + ADD_TEST(TORQUER_AppMain); + ADD_TEST(GENERIC_TORQUER_AppInit); + ADD_TEST(GENERIC_TORQUER_ProcessCommandPacket); + ADD_TEST(GENERIC_TORQUER_ProcessGroundCommand); + ADD_TEST(GENERIC_TORQUER_ReportHousekeeping); + ADD_TEST(GENERIC_TORQUER_VerifyCmdLength); + } + \ No newline at end of file From 3aa02b023d912d57ac32b5cc9e1fdcbd83ef5bca Mon Sep 17 00:00:00 2001 From: dacarter22 Date: Fri, 21 Mar 2025 14:49:24 +0000 Subject: [PATCH 04/12] [nasa/nos3#450] coverage up to 93% --- .../coveragetest/coveragetest_generic_css_app.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c index 37a14fc..1c26efb 100755 --- a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c +++ b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c @@ -314,6 +314,18 @@ GENERIC_CSS_ProcessCommandPacket(); UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_HK_ERR_EID not generated (%u)", (unsigned int)EventTest.MatchCount); + + /* Request_HK message id */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); + FcnCode = GENERIC_CSS_REQ_DATA_TLM; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_HK_ERR_EID not generated (%u)", + (unsigned int)EventTest.MatchCount); } @@ -437,6 +449,7 @@ void Test_GENERIC_CSS_ReportDeviceTelemetry(void) { + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; /* * Test Case For: * void Test_GENERIC_CSS_ReportDeviceTelemetry() @@ -465,6 +478,8 @@ UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TimeStampMsg)) == 1, "CFE_SB_TimeStampMsg() called once"); UtAssert_True(MsgTimestamp == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, "CFE_SB_TimeStampMsg() address matches expected"); + + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; } void Test_GENERIC_CSS_VerifyCmdLength(void) From 383c9affedca022f6be2f119ef2308a6032d464e Mon Sep 17 00:00:00 2001 From: dacarter22 Date: Fri, 9 May 2025 12:27:40 -0400 Subject: [PATCH 05/12] [nasa/nos3#450] 98% --- fsw/cfs/unit-test/CMakeLists.txt | 1 + .../coveragetest_generic_css_app.c | 94 ++++++++++++- .../stubs/generic_css_device_stubs.c | 34 +++++ fsw/cfs/unit-test/stubs/libi2c_stubs.c | 126 ++++++++++++++++++ 4 files changed, 254 insertions(+), 1 deletion(-) create mode 100644 fsw/cfs/unit-test/stubs/generic_css_device_stubs.c create mode 100644 fsw/cfs/unit-test/stubs/libi2c_stubs.c diff --git a/fsw/cfs/unit-test/CMakeLists.txt b/fsw/cfs/unit-test/CMakeLists.txt index 787f45b..4075b17 100755 --- a/fsw/cfs/unit-test/CMakeLists.txt +++ b/fsw/cfs/unit-test/CMakeLists.txt @@ -22,6 +22,7 @@ # inclusion of source files that are normally private include_directories(${PROJECT_SOURCE_DIR}/fsw/src) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc) +include_directories(${CMAKE_CURRENT_SOURCE_DIR}/stubs) include_directories(${hwlib_MISSION_DIR}/fsw/public_inc) diff --git a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c index 1c26efb..783f5ad 100755 --- a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c +++ b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c @@ -258,6 +258,9 @@ UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 2, CFE_SB_BAD_ARGUMENT); UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_SendEvent), 1, CFE_EVS_INVALID_PARAMETER); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), -1040187384); } void Test_GENERIC_CSS_ProcessCommandPacket(void) @@ -294,7 +297,7 @@ GENERIC_CSS_ProcessCommandPacket(); UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_CMD_ERR_EID not generated (%u)", (unsigned int)EventTest.MatchCount); - + /* invalid message id */ TestMsgId = CFE_SB_INVALID_MSG_ID; UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); @@ -326,6 +329,19 @@ GENERIC_CSS_ProcessCommandPacket(); UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_HK_ERR_EID not generated (%u)", (unsigned int)EventTest.MatchCount); + + /* Request_HK message id with invalid command */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); + FcnCode = 99; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_HK_ERR_EID not generated (%u)", + (unsigned int)EventTest.MatchCount); + } @@ -402,7 +418,30 @@ GENERIC_CSS_ProcessGroundCommand(); UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ENABLE_INF_EID generated (%u)", (unsigned int)EventTest.MatchCount); + + /* test dispatch of ENABLE */ + FcnCode = GENERIC_CSS_ENABLE_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_ENABLE_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ENABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of DISABLE */ + FcnCode = GENERIC_CSS_DISABLE_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_DISABLE_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_DISABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + /* test dispatch of DISABLE */ FcnCode = GENERIC_CSS_DISABLE_CC; Size = sizeof(TestMsg.Noop); @@ -414,6 +453,57 @@ UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_DISABLE_INF_EID generated (%u)", (unsigned int)EventTest.MatchCount); } + + void Test_GENERIC_CSS_Enable(void) + { + UT_CheckEvent_t EventTest; + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_INF_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; + UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_SUCCESS); + GENERIC_CSS_Enable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device enabled (%u)", (unsigned int)EventTest.MatchCount); + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_I2C_INIT_ERR_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; + UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); + GENERIC_CSS_Enable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: i2c port initialization error (%u)", + (unsigned int)EventTest.MatchCount); + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_ERR_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); + GENERIC_CSS_Enable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device enable failed, already enabled (%u)", + (unsigned int)EventTest.MatchCount); + } + + +void Test_GENERIC_CSS_Disable(void) +{ + UT_CheckEvent_t EventTest; + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_INF_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_SUCCESS); + GENERIC_CSS_Disable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device disabled (%u)", (unsigned int)EventTest.MatchCount); + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_ERR_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); + GENERIC_CSS_Disable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: i2c port close error (%u)", (unsigned int)EventTest.MatchCount); + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_ERR_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; + UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); + GENERIC_CSS_Disable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device disable failed, already disabled (%u)", + (unsigned int)EventTest.MatchCount); +} + void Test_GENERIC_CSS_ReportHousekeeping(void) { @@ -550,5 +640,7 @@ ADD_TEST(GENERIC_CSS_ReportHousekeeping); ADD_TEST(GENERIC_CSS_ReportDeviceTelemetry); ADD_TEST(GENERIC_CSS_VerifyCmdLength); + ADD_TEST(GENERIC_CSS_Enable); + ADD_TEST(GENERIC_CSS_Disable); } \ No newline at end of file diff --git a/fsw/cfs/unit-test/stubs/generic_css_device_stubs.c b/fsw/cfs/unit-test/stubs/generic_css_device_stubs.c new file mode 100644 index 0000000..b1cadfa --- /dev/null +++ b/fsw/cfs/unit-test/stubs/generic_css_device_stubs.c @@ -0,0 +1,34 @@ +/******************************************************************************* +** File: generic_css_device.h +** +** Purpose: +** This is the header file for the GENERIC_CSS device. +** +*******************************************************************************/ +#define _GENERIC_CSS_DEVICE_H_ + +/** + * @file + * + * Auto-Generated stub implementations for functions defined in generic_css_device header + */ + +#include "generic_css_device.h" +#include "utgenstub.h" + +/* + * ---------------------------------------------------- + * Generated stub function for GENERIC_CSS_RequestData() + * ---------------------------------------------------- + */ +int32_t GENERIC_CSS_RequestData(i2c_bus_info_t *device, GENERIC_CSS_Device_Data_tlm_t *data) +{ + UT_GenStub_SetupReturnBuffer(GENERIC_CSS_RequestData, int32_t); + + UT_GenStub_AddParam(GENERIC_CSS_RequestData, i2c_bus_info_t *, device); + UT_GenStub_AddParam(GENERIC_CSS_RequestData, GENERIC_CSS_Device_Data_tlm_t *, data); + + UT_GenStub_Execute(GENERIC_CSS_RequestData, Basic, NULL); + + return UT_GenStub_GetReturnValue(GENERIC_CSS_RequestData, int32_t); +} diff --git a/fsw/cfs/unit-test/stubs/libi2c_stubs.c b/fsw/cfs/unit-test/stubs/libi2c_stubs.c new file mode 100644 index 0000000..1d86f2e --- /dev/null +++ b/fsw/cfs/unit-test/stubs/libi2c_stubs.c @@ -0,0 +1,126 @@ +/* Copyright (C) 2009 - 2018 National Aeronautics and Space Administration. All Foreign Rights are Reserved to the U.S. +Government. + +/** + * @file + * + * Auto-Generated stub implementations for functions defined in libi2c header + */ + +#include "libi2c.h" +#include "utgenstub.h" + +/* + * ---------------------------------------------------- + * Generated stub function for i2c_master_close() + * ---------------------------------------------------- + */ +int32_t i2c_master_close(i2c_bus_info_t *device) +{ + UT_GenStub_SetupReturnBuffer(i2c_master_close, int32_t); + + UT_GenStub_AddParam(i2c_master_close, i2c_bus_info_t *, device); + + UT_GenStub_Execute(i2c_master_close, Basic, NULL); + + return UT_GenStub_GetReturnValue(i2c_master_close, int32_t); +} + +/* + * ---------------------------------------------------- + * Generated stub function for i2c_master_init() + * ---------------------------------------------------- + */ +int32_t i2c_master_init(i2c_bus_info_t *device) +{ + UT_GenStub_SetupReturnBuffer(i2c_master_init, int32_t); + + UT_GenStub_AddParam(i2c_master_init, i2c_bus_info_t *, device); + + UT_GenStub_Execute(i2c_master_init, Basic, NULL); + + return UT_GenStub_GetReturnValue(i2c_master_init, int32_t); +} + +/* + * ---------------------------------------------------- + * Generated stub function for i2c_master_transaction() + * ---------------------------------------------------- + */ +int32_t i2c_master_transaction(i2c_bus_info_t *device, uint8_t addr, void *txbuf, uint8_t txlen, void *rxbuf, + uint8_t rxlen, uint16_t timeout) +{ + UT_GenStub_SetupReturnBuffer(i2c_master_transaction, int32_t); + + UT_GenStub_AddParam(i2c_master_transaction, i2c_bus_info_t *, device); + UT_GenStub_AddParam(i2c_master_transaction, uint8_t, addr); + UT_GenStub_AddParam(i2c_master_transaction, void *, txbuf); + UT_GenStub_AddParam(i2c_master_transaction, uint8_t, txlen); + UT_GenStub_AddParam(i2c_master_transaction, void *, rxbuf); + UT_GenStub_AddParam(i2c_master_transaction, uint8_t, rxlen); + UT_GenStub_AddParam(i2c_master_transaction, uint16_t, timeout); + + UT_GenStub_Execute(i2c_master_transaction, Basic, NULL); + + return UT_GenStub_GetReturnValue(i2c_master_transaction, int32_t); +} + +/* + * ---------------------------------------------------- + * Generated stub function for i2c_multiple_transaction() + * ---------------------------------------------------- + */ +int32_t i2c_multiple_transaction(i2c_bus_info_t *device, uint8_t addr, struct i2c_rdwr_ioctl_data *rdwr_data, + uint16_t timeout) +{ + UT_GenStub_SetupReturnBuffer(i2c_multiple_transaction, int32_t); + + UT_GenStub_AddParam(i2c_multiple_transaction, i2c_bus_info_t *, device); + UT_GenStub_AddParam(i2c_multiple_transaction, uint8_t, addr); + UT_GenStub_AddParam(i2c_multiple_transaction, struct i2c_rdwr_ioctl_data *, rdwr_data); + UT_GenStub_AddParam(i2c_multiple_transaction, uint16_t, timeout); + + UT_GenStub_Execute(i2c_multiple_transaction, Basic, NULL); + + return UT_GenStub_GetReturnValue(i2c_multiple_transaction, int32_t); +} + +/* + * ---------------------------------------------------- + * Generated stub function for i2c_read_transaction() + * ---------------------------------------------------- + */ +int32_t i2c_read_transaction(i2c_bus_info_t *device, uint8_t addr, void *rxbuf, uint8_t rxlen, uint8_t timeout) +{ + UT_GenStub_SetupReturnBuffer(i2c_read_transaction, int32_t); + + UT_GenStub_AddParam(i2c_read_transaction, i2c_bus_info_t *, device); + UT_GenStub_AddParam(i2c_read_transaction, uint8_t, addr); + UT_GenStub_AddParam(i2c_read_transaction, void *, rxbuf); + UT_GenStub_AddParam(i2c_read_transaction, uint8_t, rxlen); + UT_GenStub_AddParam(i2c_read_transaction, uint8_t, timeout); + + UT_GenStub_Execute(i2c_read_transaction, Basic, NULL); + + return UT_GenStub_GetReturnValue(i2c_read_transaction, int32_t); +} + +/* + * ---------------------------------------------------- + * Generated stub function for i2c_write_transaction() + * ---------------------------------------------------- + */ +int32_t i2c_write_transaction(i2c_bus_info_t *device, uint8_t addr, void *txbuf, uint8_t txlen, uint8_t timeout) +{ + UT_GenStub_SetupReturnBuffer(i2c_write_transaction, int32_t); + + UT_GenStub_AddParam(i2c_write_transaction, i2c_bus_info_t *, device); + UT_GenStub_AddParam(i2c_write_transaction, uint8_t, addr); + UT_GenStub_AddParam(i2c_write_transaction, void *, txbuf); + UT_GenStub_AddParam(i2c_write_transaction, uint8_t, txlen); + UT_GenStub_AddParam(i2c_write_transaction, uint8_t, timeout); + + UT_GenStub_Execute(i2c_write_transaction, Basic, NULL); + + return UT_GenStub_GetReturnValue(i2c_write_transaction, int32_t); +} From 17a3f5bb617f4fcb55db80c5e239c34dc6f3f110 Mon Sep 17 00:00:00 2001 From: dacarter22 Date: Mon, 12 May 2025 11:50:15 -0400 Subject: [PATCH 06/12] [nasa/nos3#450] 98% --- fsw/cfs/unit-test/CMakeLists.txt | 22 ++- .../coveragetest_generic_css_app.c | 159 +++++++++--------- .../coveragetest_generic_css_device.c | 32 ++++ .../stubs/generic_css_device_stubs.c | 17 +- fsw/cfs/unit-test/stubs/libi2c_stubs.c | 9 - 5 files changed, 127 insertions(+), 112 deletions(-) create mode 100644 fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_device.c diff --git a/fsw/cfs/unit-test/CMakeLists.txt b/fsw/cfs/unit-test/CMakeLists.txt index 4075b17..643d1c8 100755 --- a/fsw/cfs/unit-test/CMakeLists.txt +++ b/fsw/cfs/unit-test/CMakeLists.txt @@ -18,12 +18,20 @@ # code units. # + +add_cfe_coverage_stubs(generic_css-internal stubs/generic_css_device_stubs.c stubs/libi2c_stubs.c) +target_link_libraries(coverage-generic_css-internal-stubs ut_core_api_stubs ut_assert) +target_include_directories(coverage-generic_css-internal-stubs PUBLIC $) + + + # Use the UT assert public API, and allow direct # inclusion of source files that are normally private include_directories(${PROJECT_SOURCE_DIR}/fsw/src) include_directories(${CMAKE_CURRENT_SOURCE_DIR}/inc) -include_directories(${CMAKE_CURRENT_SOURCE_DIR}/stubs) include_directories(${hwlib_MISSION_DIR}/fsw/public_inc) +include_directories(${PROJECT_SOURCE_DIR}/../../../../fsw/osal/ut_assert/inc) + # Add a coverage test executable called "generic_css-ALL" that @@ -36,14 +44,16 @@ include_directories(${hwlib_MISSION_DIR}/fsw/public_inc) add_cfe_coverage_test(generic_css ALL "coveragetest/coveragetest_generic_css_app.c" "../src/generic_css_app.c" + #"../../shared/generic_css_device.c" + #"../../../../../fsw/apps/hwlib/fsw/stubs/libi2c.c" +) +add_cfe_coverage_test(generic_css DEVICE + "coveragetest/coveragetest_generic_css_device.c" "../../shared/generic_css_device.c" - "../../../../../fsw/apps/hwlib/fsw/stubs/libi2c.c" - "../../../../../fsw/apps/hwlib/fsw/stubs/libuart.c" - + "stubs/libi2c_stubs.c" ) - # The generic_css uses library functions provided by generic_css_lib so must be linked # with the generic_css_lib stub library (this is mainly just an example of how this # can be done). #add_cfe_coverage_dependency(generic_css ALL generic_css_lib) - +add_cfe_coverage_dependency(generic_css ALL generic_css-internal) diff --git a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c index 783f5ad..f5aa04a 100755 --- a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c +++ b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c @@ -327,6 +327,19 @@ UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_HK_ERR_EID not generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* Request_HK message id */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); + FcnCode = GENERIC_CSS_REQ_DATA_TLM; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); + GENERIC_CSS_ProcessCommandPacket(); UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_HK_ERR_EID not generated (%u)", (unsigned int)EventTest.MatchCount); @@ -453,57 +466,6 @@ UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_DISABLE_INF_EID generated (%u)", (unsigned int)EventTest.MatchCount); } - - void Test_GENERIC_CSS_Enable(void) - { - UT_CheckEvent_t EventTest; - - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_INF_EID, NULL); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; - UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_SUCCESS); - GENERIC_CSS_Enable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device enabled (%u)", (unsigned int)EventTest.MatchCount); - - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_I2C_INIT_ERR_EID, NULL); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; - UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); - GENERIC_CSS_Enable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: i2c port initialization error (%u)", - (unsigned int)EventTest.MatchCount); - - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_ERR_EID, NULL); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; - UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); - GENERIC_CSS_Enable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device enable failed, already enabled (%u)", - (unsigned int)EventTest.MatchCount); - } - - -void Test_GENERIC_CSS_Disable(void) -{ - UT_CheckEvent_t EventTest; - - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_INF_EID, NULL); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; - UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_SUCCESS); - GENERIC_CSS_Disable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device disabled (%u)", (unsigned int)EventTest.MatchCount); - - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_ERR_EID, NULL); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; - UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); - GENERIC_CSS_Disable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: i2c port close error (%u)", (unsigned int)EventTest.MatchCount); - - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_ERR_EID, NULL); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; - UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); - GENERIC_CSS_Disable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device disable failed, already disabled (%u)", - (unsigned int)EventTest.MatchCount); -} - void Test_GENERIC_CSS_ReportHousekeeping(void) { @@ -537,40 +499,75 @@ void Test_GENERIC_CSS_Disable(void) "CFE_SB_TimeStampMsg() address matches expected"); } - void Test_GENERIC_CSS_ReportDeviceTelemetry(void) - { - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; - /* - * Test Case For: - * void Test_GENERIC_CSS_ReportDeviceTelemetry() - */ - CFE_MSG_Message_t *MsgSend; - CFE_MSG_Message_t *MsgTimestamp; - CFE_SB_MsgId_t MsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_DATA_TLM); - - /* Set message id to return so GENERIC_CSS_Housekeeping will be called */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); - - /* Set up to capture send message address */ - UT_SetDataBuffer(UT_KEY(CFE_SB_TransmitMsg), &MsgSend, sizeof(MsgSend), false); - - /* Set up to capture timestamp message address */ - UT_SetDataBuffer(UT_KEY(CFE_SB_TimeStampMsg), &MsgTimestamp, sizeof(MsgTimestamp), false); - - /* Call unit under test, NULL pointer confirms command access is through APIs */ - GENERIC_CSS_ReportDeviceTelemetry(); - /* Confirm message sent*/ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TransmitMsg)) == 1, "CFE_SB_TransmitMsg() called once"); - UtAssert_True(MsgSend == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, "CFE_SB_TransmitMsg() address matches expected"); +void Test_GENERIC_CSS_ReportDeviceTelemetry(void) +{ + GENERIC_CSS_ReportDeviceTelemetry(); + + UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_SUCCESS); + GENERIC_CSS_ReportDeviceTelemetry(); + + UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); + GENERIC_CSS_ReportDeviceTelemetry(); + + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; + GENERIC_CSS_ReportDeviceTelemetry(); + + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + GENERIC_CSS_ReportDeviceTelemetry(); +} + - /* Confirm timestamp msg address */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TimeStampMsg)) == 1, "CFE_SB_TimeStampMsg() called once"); - UtAssert_True(MsgTimestamp == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, - "CFE_SB_TimeStampMsg() address matches expected"); +void Test_GENERIC_CSS_Enable(void) +{ + UT_CheckEvent_t EventTest; + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_INF_EID, NULL); GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; - } + UT_SetDeferredRetcode(UT_KEY(i2c_master_init), 1, OS_SUCCESS); + GENERIC_CSS_Enable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device enabled (%u)", (unsigned int)EventTest.MatchCount); + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_I2C_INIT_ERR_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; + UT_SetDeferredRetcode(UT_KEY(i2c_master_init), 1, OS_ERROR); + GENERIC_CSS_Enable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: UART port initialization error (%u)", + (unsigned int)EventTest.MatchCount); + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_ERR_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + UT_SetDeferredRetcode(UT_KEY(i2c_master_init), 1, OS_ERROR); + GENERIC_CSS_Enable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device enable failed, already enabled (%u)", + (unsigned int)EventTest.MatchCount); +} + + +void Test_GENERIC_CSS_Disable(void) +{ + UT_CheckEvent_t EventTest; + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_INF_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + UT_SetDeferredRetcode(UT_KEY(i2c_master_close), 1, OS_SUCCESS); + GENERIC_CSS_Disable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device disabled (%u)", (unsigned int)EventTest.MatchCount); + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_I2C_CLOSE_ERR_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + UT_SetDeferredRetcode(UT_KEY(i2c_master_close), 1, OS_ERROR); + GENERIC_CSS_Disable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: UART port close error (%u)", (unsigned int)EventTest.MatchCount); + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_ERR_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; + UT_SetDeferredRetcode(UT_KEY(i2c_master_close), 1, OS_ERROR); + GENERIC_CSS_Disable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device disable failed, already disabled (%u)", + (unsigned int)EventTest.MatchCount); +} + void Test_GENERIC_CSS_VerifyCmdLength(void) { diff --git a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_device.c b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_device.c new file mode 100644 index 0000000..17a35b6 --- /dev/null +++ b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_device.c @@ -0,0 +1,32 @@ + +#include "generic_css_app_coveragetest_common.h" + +void Test_GENERIC_CSS_RequestData(void) +{ + i2c_bus_info_t device; + GENERIC_CSS_Device_Data_tlm_t data; + GENERIC_CSS_RequestData(&device, &data); +} + +void Test_GENERIC_CSS_RequestData_Hook(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context, va_list va) {} + +/* + * Setup function prior to every test + */ +void generic_css_UT_Setup(void) +{ + UT_ResetState(0); +} + +/* + * Teardown function after every test + */ +void generic_css_UT_TearDown(void) {} + +/* + * Register the test cases to execute with the unit test tool + */ +void UtTest_Setup(void) +{ + UT_SetVaHandlerFunction(UT_KEY(Test_GENERIC_CSS_RequestData), Test_GENERIC_CSS_RequestData_Hook, NULL); +} \ No newline at end of file diff --git a/fsw/cfs/unit-test/stubs/generic_css_device_stubs.c b/fsw/cfs/unit-test/stubs/generic_css_device_stubs.c index b1cadfa..eb649f3 100644 --- a/fsw/cfs/unit-test/stubs/generic_css_device_stubs.c +++ b/fsw/cfs/unit-test/stubs/generic_css_device_stubs.c @@ -1,20 +1,5 @@ -/******************************************************************************* -** File: generic_css_device.h -** -** Purpose: -** This is the header file for the GENERIC_CSS device. -** -*******************************************************************************/ -#define _GENERIC_CSS_DEVICE_H_ - -/** - * @file - * - * Auto-Generated stub implementations for functions defined in generic_css_device header - */ - -#include "generic_css_device.h" #include "utgenstub.h" +#include "generic_css_device.h" /* * ---------------------------------------------------- diff --git a/fsw/cfs/unit-test/stubs/libi2c_stubs.c b/fsw/cfs/unit-test/stubs/libi2c_stubs.c index 1d86f2e..e0edbff 100644 --- a/fsw/cfs/unit-test/stubs/libi2c_stubs.c +++ b/fsw/cfs/unit-test/stubs/libi2c_stubs.c @@ -1,12 +1,3 @@ -/* Copyright (C) 2009 - 2018 National Aeronautics and Space Administration. All Foreign Rights are Reserved to the U.S. -Government. - -/** - * @file - * - * Auto-Generated stub implementations for functions defined in libi2c header - */ - #include "libi2c.h" #include "utgenstub.h" From 168254300eeef23d6a796d12c85743f60fbd337a Mon Sep 17 00:00:00 2001 From: dacarter22 Date: Mon, 12 May 2025 11:56:26 -0400 Subject: [PATCH 07/12] [nasa/nos3#450] app at 100% --- fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c index f5aa04a..e7e3863 100755 --- a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c +++ b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c @@ -317,6 +317,8 @@ GENERIC_CSS_ProcessCommandPacket(); UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_HK_ERR_EID not generated (%u)", (unsigned int)EventTest.MatchCount); + + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; /* Request_HK message id */ TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); From 008d90e8d7fd21e2f12c0cc8eaad51c96b6acf09 Mon Sep 17 00:00:00 2001 From: dacarter22 Date: Mon, 12 May 2025 12:10:39 -0400 Subject: [PATCH 08/12] [nasa/nos3#450] device at 100% --- .../coveragetest_generic_css_device.c | 29 ++++++++++++++++--- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_device.c b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_device.c index 17a35b6..5394e50 100644 --- a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_device.c +++ b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_device.c @@ -1,10 +1,30 @@ - #include "generic_css_app_coveragetest_common.h" void Test_GENERIC_CSS_RequestData(void) { - i2c_bus_info_t device; + i2c_bus_info_t device; GENERIC_CSS_Device_Data_tlm_t data; + + /* Test basic case with minimal setup */ + GENERIC_CSS_RequestData(&device, &data); + + /* Test successful case */ + uint8_t read_data[] = { + 0x01, 0x02, /* Voltage[0] = 0x0102 */ + 0x03, 0x04, /* Voltage[1] = 0x0304 */ + 0x05, 0x06, /* Voltage[2] = 0x0506 */ + 0x07, 0x08, /* Voltage[3] = 0x0708 */ + 0x09, 0x0A, /* Voltage[4] = 0x090A */ + 0x0B, 0x0C /* Voltage[5] = 0x0B0C */ + }; + + /* Setup for successful I2C transaction */ + UT_SetDefaultReturnValue(UT_KEY(i2c_master_transaction), OS_SUCCESS); + UT_SetDataBuffer(UT_KEY(i2c_master_transaction), read_data, sizeof(read_data), false); + GENERIC_CSS_RequestData(&device, &data); + + /* Test error case */ + UT_SetDefaultReturnValue(UT_KEY(i2c_master_transaction), OS_ERROR); GENERIC_CSS_RequestData(&device, &data); } @@ -13,7 +33,7 @@ void Test_GENERIC_CSS_RequestData_Hook(void *UserObj, UT_EntryKey_t FuncKey, con /* * Setup function prior to every test */ -void generic_css_UT_Setup(void) +void Generic_css_UT_Setup(void) { UT_ResetState(0); } @@ -21,7 +41,7 @@ void generic_css_UT_Setup(void) /* * Teardown function after every test */ -void generic_css_UT_TearDown(void) {} +void Generic_css_UT_TearDown(void) {} /* * Register the test cases to execute with the unit test tool @@ -29,4 +49,5 @@ void generic_css_UT_TearDown(void) {} void UtTest_Setup(void) { UT_SetVaHandlerFunction(UT_KEY(Test_GENERIC_CSS_RequestData), Test_GENERIC_CSS_RequestData_Hook, NULL); + ADD_TEST(GENERIC_CSS_RequestData); } \ No newline at end of file From 5d0bf420893da96890814eb7c7079737ee33c876 Mon Sep 17 00:00:00 2001 From: dacarter22 Date: Mon, 12 May 2025 12:19:42 -0400 Subject: [PATCH 09/12] [nasa/nos3#450] removed extra unit test folder --- .../coveragetest/coveragetest_css_app.c | 583 ------------------ 1 file changed, 583 deletions(-) delete mode 100644 fsw/unit-test/coveragetest/coveragetest_css_app.c diff --git a/fsw/unit-test/coveragetest/coveragetest_css_app.c b/fsw/unit-test/coveragetest/coveragetest_css_app.c deleted file mode 100644 index c305e6e..0000000 --- a/fsw/unit-test/coveragetest/coveragetest_css_app.c +++ /dev/null @@ -1,583 +0,0 @@ -/* -** 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: coveragetest_generic_torquer_app.c -** -** Purpose: -** Coverage Unit Test cases for the GENERIC_TORQUER Application -** -** Notes: -** This implements various test cases to exercise all code -** paths through all functions defined in the GENERIC_TORQUER application. -** -** It is primarily focused at providing examples of the various -** stub configurations, hook functions, and wrapper calls that -** are often needed when coercing certain code paths through -** complex functions. -*/ - -/* - * Includes - */ - - #include "generic_torquer_app_coveragetest_common.h" - #include "ut_generic_torquer_app.h" - - /* to get the GENERIC_TORQUER_LIB_Function() declaration */ - - typedef struct - { - uint16 ExpectedEvent; - uint32 MatchCount; - const char *ExpectedFormat; - } UT_CheckEvent_t; - - /* - * An example hook function to check for a specific event. - */ - static int32 UT_CheckEvent_Hook(void *UserObj, int32 StubRetcode, uint32 CallCount, const UT_StubContext_t *Context, - va_list va) - { - UT_CheckEvent_t *State = UserObj; - uint16 EventId; - const char * Spec; - - /* - * The CFE_EVS_SendEvent stub passes the EventID as the - * first context argument. - */ - if (Context->ArgCount > 0) - { - EventId = UT_Hook_GetArgValueByName(Context, "EventID", uint16); - if (EventId == State->ExpectedEvent) - { - if (State->ExpectedFormat != NULL) - { - Spec = UT_Hook_GetArgValueByName(Context, "Spec", const char *); - if (Spec != NULL) - { - /* - * Example of how to validate the full argument set. - * ------------------------------------------------ - * - * If really desired one can call something like: - * - * char TestText[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH]; - * vsnprintf(TestText, sizeof(TestText), Spec, va); - * - * And then compare the output (TestText) to the expected fully-rendered string. - * - * NOTE: While this can be done, use with discretion - This isn't really - * verifying that the FSW code unit generated the correct event text, - * rather it is validating what the system snprintf() library function - * produces when passed the format string and args. - * - * This type of check has been demonstrated to make tests very fragile, - * because it is influenced by many factors outside the control of the - * test case. - * - * __This derived string is not an actual output of the unit under test__ - */ - if (strcmp(Spec, State->ExpectedFormat) == 0) - { - ++State->MatchCount; - } - } - } - else - { - ++State->MatchCount; - } - } - } - - return 0; - } - - /* - * Helper function to set up for event checking - * This attaches the hook function to CFE_EVS_SendEvent - */ - static void UT_CheckEvent_Setup(UT_CheckEvent_t *Evt, uint16 ExpectedEvent, const char *ExpectedFormat) - { - memset(Evt, 0, sizeof(*Evt)); - Evt->ExpectedEvent = ExpectedEvent; - Evt->ExpectedFormat = ExpectedFormat; - UT_SetVaHookFunction(UT_KEY(CFE_EVS_SendEvent), UT_CheckEvent_Hook, Evt); - } - - /* - ********************************************************************************** - ** TEST CASE FUNCTIONS - ********************************************************************************** - */ - - void Test_TORQUER_AppMain(void) - { - CFE_SB_MsgId_t MsgId = CFE_SB_INVALID_MSG_ID; - - /* - * Test Case For: - * void TORQUER_AppMain( void ) - */ - - UT_CheckEvent_t EventTest; - - /* - * TORQUER_AppMain does not return a value, - * but it has several internal decision points - * that need to be exercised here. - * - * First call it in "nominal" mode where all - * dependent calls should be successful by default. - */ - TORQUER_AppMain(); - - /* - * Confirm that CFE_ES_ExitApp() was called at the end of execution - */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_ExitApp)) == 1, "CFE_ES_ExitApp() called"); - - /* - * Now set up individual cases for each of the error paths. - * The first is for GENERIC_TORQUER_AppInit(). As this is in the same - * code unit, it is not a stub where the return code can be - * easily set. In order to get this to fail, an underlying - * call needs to fail, and the error gets propagated through. - * The call to CFE_EVS_Register is the first opportunity. - * Any identifiable (non-success) return code should work. - */ - UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); - - /* - * Just call the function again. It does not return - * the value, so there is nothing to test for here directly. - * However, it should show up in the coverage report that - * the GENERIC_TORQUER_AppInit() failure path was taken. - */ - TORQUER_AppMain(); - - /* - * This can validate that the internal "RunStatus" was - * set to CFE_ES_RunStatus_APP_ERROR, by querying the struct directly. - * - * It is always advisable to include the _actual_ values - * when asserting on conditions, so if/when it fails, the - * log will show what the incorrect value was. - */ - UtAssert_True(GENERIC_TORQUER_AppData.RunStatus == CFE_ES_RunStatus_APP_ERROR, - "GENERIC_TORQUER_AppData.RunStatus (%lu) == CFE_ES_RunStatus_APP_ERROR", - (unsigned long)GENERIC_TORQUER_AppData.RunStatus); - - /* - * Note that CFE_ES_RunLoop returns a boolean value, - * so in order to exercise the internal "while" loop, - * it needs to return TRUE. But this also needs to return - * FALSE in order to get out of the loop, otherwise - * it will stay there infinitely. - * - * The deferred retcode will accomplish this. - */ - UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); - - /* Set up buffer for command processing */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); - - /* - * Invoke again - */ - TORQUER_AppMain(); - - /* - * Confirm that CFE_SB_ReceiveBuffer() (inside the loop) was called - */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_ReceiveBuffer)) == 1, "CFE_SB_ReceiveBuffer() called"); - - /* - * Now also make the CFE_SB_ReceiveBuffer call fail, - * to exercise that error path. This sends an - * event which can be checked with a hook function. - */ - UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); - UT_SetDeferredRetcode(UT_KEY(CFE_SB_ReceiveBuffer), 1, CFE_SB_PIPE_RD_ERR); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_PIPE_ERR_EID, "GENERIC_TORQUER: SB Pipe Read Error = %d"); - - /* - * Invoke again - */ - TORQUER_AppMain(); - - /* - * Confirm that the event was generated - */ - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_PIPE_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - } - - void Test_GENERIC_TORQUER_AppInit(void) - { - /* - * Test Case For: - * int32 GENERIC_TORQUER_AppInit( void ) - */ - - /* nominal case should return CFE_SUCCESS */ - UT_TEST_FUNCTION_RC(GENERIC_TORQUER_AppInit(), CFE_SUCCESS); - - /* trigger a failure for each of the sub-calls, - * and confirm a write to syslog for each. - * Note that this count accumulates, because the status - * is _not_ reset between these test cases. */ - UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); - UT_TEST_FUNCTION_RC(GENERIC_TORQUER_AppInit(), CFE_EVS_INVALID_PARAMETER); - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_WriteToSysLog)) == 1, "CFE_ES_WriteToSysLog() called"); - - UT_SetDeferredRetcode(UT_KEY(CFE_SB_CreatePipe), 1, CFE_SB_BAD_ARGUMENT); - UT_TEST_FUNCTION_RC(GENERIC_TORQUER_AppInit(), CFE_SB_BAD_ARGUMENT); - - UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 1, CFE_SB_BAD_ARGUMENT); - UT_TEST_FUNCTION_RC(GENERIC_TORQUER_AppInit(), CFE_SB_BAD_ARGUMENT); - - UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 2, CFE_SB_BAD_ARGUMENT); - UT_TEST_FUNCTION_RC(GENERIC_TORQUER_AppInit(), CFE_SB_BAD_ARGUMENT); - } - - void Test_GENERIC_TORQUER_ProcessCommandPacket(void) - { - /* - * Test Case For: - * void GENERIC_TORQUER_ProcessCommandPacket - */ - /* a buffer large enough for any command message */ - union - { - CFE_SB_Buffer_t SBBuf; - GENERIC_TORQUER_NoArgs_cmd_t Noop; - } TestMsg; - CFE_SB_MsgId_t TestMsgId; - CFE_MSG_FcnCode_t FcnCode; - size_t MsgSize; - UT_CheckEvent_t EventTest; - - memset(&TestMsg, 0, sizeof(TestMsg)); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_PROCESS_CMD_ERR_EID, NULL); - - /* - * The CFE_MSG_GetMsgId() stub uses a data buffer to hold the - * message ID values to return. - */ - TestMsgId = CFE_SB_ValueToMsgId(GENERIC_TORQUER_CMD_MID); - FcnCode = GENERIC_TORQUER_NOOP_CC; - MsgSize = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); - GENERIC_TORQUER_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_TORQUER_CMD_ERR_EID not generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* invalid message id */ - TestMsgId = CFE_SB_INVALID_MSG_ID; - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - GENERIC_TORQUER_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - TestMsgId = CFE_SB_ValueToMsgId(GENERIC_TORQUER_REQ_HK_MID); - FcnCode = GENERIC_TORQUER_REQ_HK_TLM; - MsgSize = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); - GENERIC_TORQUER_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_TORQUER_CMD_ERR_EID not generated (%u)", - (unsigned int)EventTest.MatchCount); - } - - void Test_GENERIC_TORQUER_ProcessGroundCommand(void) - { - /* - * Test Case For: - * void GENERIC_TORQUER_ProcessGroundCommand - */ - CFE_SB_MsgId_t TestMsgId = CFE_SB_ValueToMsgId(GENERIC_TORQUER_CMD_MID); - CFE_MSG_FcnCode_t FcnCode; - size_t Size; - - /* a buffer large enough for any command message */ - union - { - CFE_SB_Buffer_t SBBuf; - GENERIC_TORQUER_NoArgs_cmd_t Noop; - GENERIC_TORQUER_NoArgs_cmd_t Reset; - GENERIC_TORQUER_NoArgs_cmd_t Enable; - GENERIC_TORQUER_NoArgs_cmd_t Disable; - GENERIC_TORQUER_Percent_On_cmd_t Config; - GENERIC_TORQUER_All_Percent_On_cmd_t ConfigAll; - } TestMsg; - UT_CheckEvent_t EventTest; - - memset(&TestMsg, 0, sizeof(TestMsg)); - /* - * call with each of the supported command codes - * The CFE_MSG_GetFcnCode stub allows the code to be - * set to whatever is needed. There is no return - * value here and the actual implementation of these - * commands have separate test cases, so this just - * needs to exercise the "switch" statement. - */ - - /* test dispatch of NOOP */ - FcnCode = GENERIC_TORQUER_NOOP_CC; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_NOOP_INF_EID, NULL); - GENERIC_TORQUER_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_NOOP_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of RESET */ - FcnCode = GENERIC_TORQUER_RESET_COUNTERS_CC; - Size = sizeof(TestMsg.Reset); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_RESET_INF_EID, NULL); - GENERIC_TORQUER_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_RESET_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of ENABLE */ - FcnCode = GENERIC_TORQUER_ENABLE_CC; - Size = sizeof(TestMsg.Enable); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_ENABLE_INF_EID, NULL); - GENERIC_TORQUER_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_ENABLE_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - - /* test dispatch of DISABLE */ - FcnCode = GENERIC_TORQUER_DISABLE_CC; - Size = sizeof(TestMsg.Disable); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_DISABLE_INF_EID, NULL); - GENERIC_TORQUER_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_DISABLE_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test an invalid CC */ - FcnCode = 99; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_ERR_EID, NULL); - GENERIC_TORQUER_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of ENABLE */ - FcnCode = GENERIC_TORQUER_ENABLE_CC; - Size = sizeof(TestMsg.Enable); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_ENABLE_INF_EID, NULL); - GENERIC_TORQUER_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_ENABLE_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of CONFIG */ - TestMsg.Config.Direction = 1; - TestMsg.Config.TrqNum = 1; - TestMsg.Config.PercentOn = 1; - FcnCode = GENERIC_TORQUER_CONFIG_CC; - Size = sizeof(TestMsg.Config); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, Size, false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_CONFIG_INF_EID, NULL); - CFE_MSG_Message_t msgPtr; - GENERIC_TORQUER_AppData.MsgPtr = &msgPtr; - GENERIC_TORQUER_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_CONFIG_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of DISABLE */ - FcnCode = GENERIC_TORQUER_DISABLE_CC; - Size = sizeof(TestMsg.Disable); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_DISABLE_INF_EID, NULL); - GENERIC_TORQUER_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_DISABLE_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of ENABLE */ - FcnCode = GENERIC_TORQUER_ENABLE_CC; - Size = sizeof(TestMsg.Enable); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_ENABLE_INF_EID, NULL); - GENERIC_TORQUER_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_ENABLE_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of CONFIG_ALL */ - TestMsg.ConfigAll.Direction_0 = 1; - TestMsg.ConfigAll.PercentOn_0 = 1; - TestMsg.ConfigAll.Direction_1 = 1; - TestMsg.ConfigAll.PercentOn_1 = 1; - TestMsg.ConfigAll.Direction_2 = 1; - TestMsg.ConfigAll.PercentOn_2 = 1; - FcnCode = GENERIC_TORQUER_CONFIG_ALL_CC; - Size = sizeof(TestMsg.ConfigAll); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, Size, false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_CONFIG_ALL_INF_EID, NULL); - GENERIC_TORQUER_AppData.MsgPtr = &msgPtr; - GENERIC_TORQUER_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_CONFIG_ALL_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of DISABLE */ - FcnCode = GENERIC_TORQUER_DISABLE_CC; - Size = sizeof(TestMsg.Disable); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_CMD_DISABLE_INF_EID, NULL); - GENERIC_TORQUER_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_CMD_DISABLE_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - } - - void Test_GENERIC_TORQUER_ReportHousekeeping(void) - { - /* - * Test Case For: - * void GENERIC_TORQUER_ReportHousekeeping() - */ - CFE_MSG_Message_t *MsgSend; - CFE_MSG_Message_t *MsgTimestamp; - CFE_SB_MsgId_t MsgId = CFE_SB_ValueToMsgId(GENERIC_TORQUER_REQ_HK_TLM); - - /* Set message id to return so GENERIC_TORQUER_Housekeeping will be called */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); - - /* Set up to capture send message address */ - UT_SetDataBuffer(UT_KEY(CFE_SB_TransmitMsg), &MsgSend, sizeof(MsgSend), false); - - /* Set up to capture timestamp message address */ - UT_SetDataBuffer(UT_KEY(CFE_SB_TimeStampMsg), &MsgTimestamp, sizeof(MsgTimestamp), false); - - /* Call unit under test, NULL pointer confirms command access is through APIs */ - GENERIC_TORQUER_ReportHousekeeping(); - - /* Confirm message sent*/ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TransmitMsg)) == 1, "CFE_SB_TransmitMsg() called once"); - UtAssert_True(MsgSend == &GENERIC_TORQUER_AppData.HkTelemetryPkt.TlmHeader.Msg, "CFE_SB_TransmitMsg() address matches expected"); - - /* Confirm timestamp msg address */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TimeStampMsg)) == 1, "CFE_SB_TimeStampMsg() called once"); - UtAssert_True(MsgTimestamp == &GENERIC_TORQUER_AppData.HkTelemetryPkt.TlmHeader.Msg, - "CFE_SB_TimeStampMsg() address matches expected"); - } - - void Test_GENERIC_TORQUER_VerifyCmdLength(void) - { - /* - * Test Case For: - * bool GENERIC_TORQUER_VerifyCmdLength - */ - UT_CheckEvent_t EventTest; - size_t size = 1; - CFE_MSG_FcnCode_t fcncode = 2; - CFE_SB_MsgId_t msgid = CFE_SB_ValueToMsgId(GENERIC_TORQUER_CMD_MID); - - /* - * test a match case - */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_LEN_ERR_EID, NULL); - - GENERIC_TORQUER_VerifyCmdLength(NULL, size); - - /* - * Confirm that the event was NOT generated - */ - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_TORQUER_LEN_ERR_EID NOT generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* - * test a mismatch case - */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &msgid, sizeof(msgid), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &fcncode, sizeof(fcncode), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_TORQUER_LEN_ERR_EID, NULL); - GENERIC_TORQUER_VerifyCmdLength(NULL, size + 1); - - /* - * Confirm that the event WAS generated - */ - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_TORQUER_LEN_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - } - - /* - * Setup function prior to every test - */ - void Generic_torquer_UT_Setup(void) - { - UT_ResetState(0); - } - - /* - * Teardown function after every test - */ - void Generic_torquer_UT_TearDown(void) {} - - /* - * Register the test cases to execute with the unit test tool - */ - void UtTest_Setup(void) - { - ADD_TEST(TORQUER_AppMain); - ADD_TEST(GENERIC_TORQUER_AppInit); - ADD_TEST(GENERIC_TORQUER_ProcessCommandPacket); - ADD_TEST(GENERIC_TORQUER_ProcessGroundCommand); - ADD_TEST(GENERIC_TORQUER_ReportHousekeeping); - ADD_TEST(GENERIC_TORQUER_VerifyCmdLength); - } - \ No newline at end of file From 905d1df24daf7f10c97cd0c02c14df5e698b37d6 Mon Sep 17 00:00:00 2001 From: dacarter22 Date: Mon, 12 May 2025 13:39:50 -0400 Subject: [PATCH 10/12] [nasa/nos3#450] all tests passing should fix build errors --- .../coveragetest_generic_css_app.c | 680 ++---------------- 1 file changed, 44 insertions(+), 636 deletions(-) diff --git a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c index e7e3863..e882f1d 100755 --- a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c +++ b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c @@ -1,645 +1,53 @@ -/* -** 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: coveragetest_generic_css_app.c -** -** Purpose: -** Coverage Unit Test cases for the GENERIC_CSS Application -** -** Notes: -** This implements various test cases to exercise all code -** paths through all functions defined in the GENERIC_CSS application. -** -** It is primarily focused at providing examples of the various -** stub configurations, hook functions, and wrapper calls that -** are often needed when coercing certain code paths through -** complex functions. -*/ - -/* - * Includes - */ - - #include "generic_css_app_coveragetest_common.h" - #include "ut_generic_css_app.h" - - /* to get the GENERIC_CSS_LIB_Function() declaration */ - - typedef struct - { - uint16 ExpectedEvent; - uint32 MatchCount; - const char *ExpectedFormat; - } UT_CheckEvent_t; - - /* - * An example hook function to check for a specific event. - */ - static int32 UT_CheckEvent_Hook(void *UserObj, int32 StubRetcode, uint32 CallCount, const UT_StubContext_t *Context, - va_list va) - { - UT_CheckEvent_t *State = UserObj; - uint16 EventId; - const char * Spec; - - /* - * The CFE_EVS_SendEvent stub passes the EventID as the - * first context argument. - */ - if (Context->ArgCount > 0) - { - EventId = UT_Hook_GetArgValueByName(Context, "EventID", uint16); - if (EventId == State->ExpectedEvent) - { - if (State->ExpectedFormat != NULL) - { - Spec = UT_Hook_GetArgValueByName(Context, "Spec", const char *); - if (Spec != NULL) - { - /* - * Example of how to validate the full argument set. - * ------------------------------------------------ - * - * If really desired one can call something like: - * - * char TestText[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH]; - * vsnprintf(TestText, sizeof(TestText), Spec, va); - * - * And then compare the output (TestText) to the expected fully-rendered string. - * - * NOTE: While this can be done, use with discretion - This isn't really - * verifying that the FSW code unit generated the correct event text, - * rather it is validating what the system snprintf() library function - * produces when passed the format string and args. - * - * This type of check has been demonstrated to make tests very fragile, - * because it is influenced by many factors outside the control of the - * test case. - * - * __This derived string is not an actual output of the unit under test__ - */ - if (strcmp(Spec, State->ExpectedFormat) == 0) - { - ++State->MatchCount; - } - } - } - else - { - ++State->MatchCount; - } - } - } - - return 0; - } - - /* - * Helper function to set up for event checking - * This attaches the hook function to CFE_EVS_SendEvent - */ - static void UT_CheckEvent_Setup(UT_CheckEvent_t *Evt, uint16 ExpectedEvent, const char *ExpectedFormat) - { - memset(Evt, 0, sizeof(*Evt)); - Evt->ExpectedEvent = ExpectedEvent; - Evt->ExpectedFormat = ExpectedFormat; - UT_SetVaHookFunction(UT_KEY(CFE_EVS_SendEvent), UT_CheckEvent_Hook, Evt); - } - - /* - ********************************************************************************** - ** TEST CASE FUNCTIONS - ********************************************************************************** - */ - - void Test_CSS_AppMain(void) - { - CFE_SB_MsgId_t MsgId = CFE_SB_INVALID_MSG_ID; - - /* - * Test Case For: - * void CSS_AppMain( void ) - */ - - UT_CheckEvent_t EventTest; - - /* - * CSS_AppMain does not return a value, - * but it has several internal decision points - * that need to be exercised here. - * - * First call it in "nominal" mode where all - * dependent calls should be successful by default. - */ - CSS_AppMain(); - - /* - * Confirm that CFE_ES_ExitApp() was called at the end of execution - */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_ExitApp)) == 1, "CFE_ES_ExitApp() called"); - - /* - * Now set up individual cases for each of the error paths. - * The first is for GENERIC_CSS_AppInit(). As this is in the same - * code unit, it is not a stub where the return code can be - * easily set. In order to get this to fail, an underlying - * call needs to fail, and the error gets propagated through. - * The call to CFE_EVS_Register is the first opportunity. - * Any identifiable (non-success) return code should work. - */ - UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); - - /* - * Just call the function again. It does not return - * the value, so there is nothing to test for here directly. - * However, it should show up in the coverage report that - * the GENERIC_CSS_AppInit() failure path was taken. - */ - CSS_AppMain(); - - /* - * This can validate that the internal "RunStatus" was - * set to CFE_ES_RunStatus_APP_ERROR, by querying the struct directly. - * - * It is always advisable to include the _actual_ values - * when asserting on conditions, so if/when it fails, the - * log will show what the incorrect value was. - */ - UtAssert_True(GENERIC_CSS_AppData.RunStatus == CFE_ES_RunStatus_APP_ERROR, - "GENERIC_CSS_AppData.RunStatus (%lu) == CFE_ES_RunStatus_APP_ERROR", - (unsigned long)GENERIC_CSS_AppData.RunStatus); - - /* - * Note that CFE_ES_RunLoop returns a boolean value, - * so in order to exercise the internal "while" loop, - * it needs to return TRUE. But this also needs to return - * FALSE in order to get out of the loop, otherwise - * it will stay there infinitely. - * - * The deferred retcode will accomplish this. - */ - UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); - - /* Set up buffer for command processing */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); - - /* - * Invoke again - */ - CSS_AppMain(); - - /* - * Confirm that CFE_SB_ReceiveBuffer() (inside the loop) was called - */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_ReceiveBuffer)) == 1, "CFE_SB_ReceiveBuffer() called"); - - /* - * Now also make the CFE_SB_ReceiveBuffer call fail, - * to exercise that error path. This sends an - * event which can be checked with a hook function. - */ - UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); - UT_SetDeferredRetcode(UT_KEY(CFE_SB_ReceiveBuffer), 1, CFE_SB_PIPE_RD_ERR); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PIPE_ERR_EID, "GENERIC_CSS: SB Pipe Read Error = %d"); - - /* - * Invoke again - */ - CSS_AppMain(); - - /* - * Confirm that the event was generated - */ - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_PIPE_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - } - - void Test_GENERIC_CSS_AppInit(void) - { - /* - * Test Case For: - * int32 GENERIC_CSS_AppInit( void ) - */ - - /* nominal case should return CFE_SUCCESS */ - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SUCCESS); - - /* trigger a failure for each of the sub-calls, - * and confirm a write to syslog for each. - * Note that this count accumulates, because the status - * is _not_ reset between these test cases. */ - UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_EVS_INVALID_PARAMETER); - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_WriteToSysLog)) == 1, "CFE_ES_WriteToSysLog() called"); - - UT_SetDeferredRetcode(UT_KEY(CFE_SB_CreatePipe), 1, CFE_SB_BAD_ARGUMENT); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); - - UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 1, CFE_SB_BAD_ARGUMENT); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); - - UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 2, CFE_SB_BAD_ARGUMENT); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); - - UT_SetDeferredRetcode(UT_KEY(CFE_EVS_SendEvent), 1, CFE_EVS_INVALID_PARAMETER); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), -1040187384); - } - - void Test_GENERIC_CSS_ProcessCommandPacket(void) - { - /* - * Test Case For: - * void GENERIC_CSS_ProcessCommandPacket - */ - /* a buffer large enough for any command message */ - union - { - CFE_SB_Buffer_t SBBuf; - GENERIC_CSS_NoArgs_cmd_t Noop; - } TestMsg; - CFE_SB_MsgId_t TestMsgId; - CFE_MSG_FcnCode_t FcnCode; - size_t MsgSize; - UT_CheckEvent_t EventTest; - - memset(&TestMsg, 0, sizeof(TestMsg)); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PROCESS_CMD_ERR_EID, NULL); - - /* - * The CFE_MSG_GetMsgId() stub uses a data buffer to hold the - * message ID values to return. - */ - TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); - FcnCode = GENERIC_CSS_NOOP_CC; - MsgSize = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); - GENERIC_CSS_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_CMD_ERR_EID not generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* invalid message id */ - TestMsgId = CFE_SB_INVALID_MSG_ID; - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - GENERIC_CSS_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* Request_HK message id */ - TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); - FcnCode = GENERIC_CSS_REQ_HK_TLM; - MsgSize = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); - GENERIC_CSS_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_HK_ERR_EID not generated (%u)", - (unsigned int)EventTest.MatchCount); - - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; - - /* Request_HK message id */ - TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); - FcnCode = GENERIC_CSS_REQ_DATA_TLM; - MsgSize = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); - GENERIC_CSS_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_HK_ERR_EID not generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* Request_HK message id */ - TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); - FcnCode = GENERIC_CSS_REQ_DATA_TLM; - MsgSize = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); - UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); - GENERIC_CSS_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_HK_ERR_EID not generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* Request_HK message id with invalid command */ - TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); - FcnCode = 99; - MsgSize = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); - GENERIC_CSS_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_HK_ERR_EID not generated (%u)", - (unsigned int)EventTest.MatchCount); - - - - } - - void Test_GENERIC_CSS_ProcessGroundCommand(void) - { - /* - * Test Case For: - * void GENERIC_CSS_ProcessGroundCommand - */ - CFE_SB_MsgId_t TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); - CFE_MSG_FcnCode_t FcnCode; - size_t Size; - - /* a buffer large enough for any command message */ - union - { - CFE_SB_Buffer_t SBBuf; - GENERIC_CSS_NoArgs_cmd_t Noop; - GENERIC_CSS_NoArgs_cmd_t Reset; - } TestMsg; - UT_CheckEvent_t EventTest; - - memset(&TestMsg, 0, sizeof(TestMsg)); - - /* - * call with each of the supported command codes - * The CFE_MSG_GetFcnCode stub allows the code to be - * set to whatever is needed. There is no return - * value here and the actual implementation of these - * commands have separate test cases, so this just - * needs to exercise the "switch" statement. - */ - - /* test dispatch of NOOP */ - FcnCode = GENERIC_CSS_NOOP_CC; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_NOOP_INF_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_NOOP_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of RESET */ - FcnCode = GENERIC_CSS_RESET_COUNTERS_CC; - Size = sizeof(TestMsg.Reset); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_RESET_INF_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_RESET_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test an invalid CC */ - FcnCode = 99; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_ERR_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of ENABLE */ - FcnCode = GENERIC_CSS_ENABLE_CC; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_ENABLE_INF_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ENABLE_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of ENABLE */ - FcnCode = GENERIC_CSS_ENABLE_CC; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_ENABLE_INF_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ENABLE_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - - /* test dispatch of DISABLE */ - FcnCode = GENERIC_CSS_DISABLE_CC; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_DISABLE_INF_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_DISABLE_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); +#include "generic_css_app_coveragetest_common.h" - /* test dispatch of DISABLE */ - FcnCode = GENERIC_CSS_DISABLE_CC; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_DISABLE_INF_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_DISABLE_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - } - - void Test_GENERIC_CSS_ReportHousekeeping(void) - { - /* - * Test Case For: - * void GENERIC_CSS_ReportHousekeeping() - */ - CFE_MSG_Message_t *MsgSend; - CFE_MSG_Message_t *MsgTimestamp; - CFE_SB_MsgId_t MsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_TLM); - - /* Set message id to return so GENERIC_CSS_Housekeeping will be called */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); - - /* Set up to capture send message address */ - UT_SetDataBuffer(UT_KEY(CFE_SB_TransmitMsg), &MsgSend, sizeof(MsgSend), false); - - /* Set up to capture timestamp message address */ - UT_SetDataBuffer(UT_KEY(CFE_SB_TimeStampMsg), &MsgTimestamp, sizeof(MsgTimestamp), false); - - /* Call unit under test, NULL pointer confirms command access is through APIs */ - GENERIC_CSS_ReportHousekeeping(); - - /* Confirm message sent*/ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TransmitMsg)) == 1, "CFE_SB_TransmitMsg() called once"); - UtAssert_True(MsgSend == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, "CFE_SB_TransmitMsg() address matches expected"); - - /* Confirm timestamp msg address */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TimeStampMsg)) == 1, "CFE_SB_TimeStampMsg() called once"); - UtAssert_True(MsgTimestamp == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, - "CFE_SB_TimeStampMsg() address matches expected"); - } - - -void Test_GENERIC_CSS_ReportDeviceTelemetry(void) +void Test_GENERIC_CSS_RequestData(void) { - GENERIC_CSS_ReportDeviceTelemetry(); - - UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_SUCCESS); - GENERIC_CSS_ReportDeviceTelemetry(); - - UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); - GENERIC_CSS_ReportDeviceTelemetry(); - - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; - GENERIC_CSS_ReportDeviceTelemetry(); - - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; - GENERIC_CSS_ReportDeviceTelemetry(); + i2c_bus_info_t device; + GENERIC_CSS_Device_Data_tlm_t data; + + /* Test basic case with minimal setup */ + GENERIC_CSS_RequestData(&device, &data); + + /* Test successful case */ + uint8_t read_data[] = { + 0x01, 0x02, /* Voltage[0] = 0x0102 */ + 0x03, 0x04, /* Voltage[1] = 0x0304 */ + 0x05, 0x06, /* Voltage[2] = 0x0506 */ + 0x07, 0x08, /* Voltage[3] = 0x0708 */ + 0x09, 0x0A, /* Voltage[4] = 0x090A */ + 0x0B, 0x0C /* Voltage[5] = 0x0B0C */ + }; + + /* Setup for successful I2C transaction */ + UT_SetDefaultReturnValue(UT_KEY(i2c_master_transaction), OS_SUCCESS); + UT_SetDataBuffer(UT_KEY(i2c_master_transaction), read_data, sizeof(read_data), false); + GENERIC_CSS_RequestData(&device, &data); + + /* Test error case */ + UT_SetDefaultReturnValue(UT_KEY(i2c_master_transaction), OS_ERROR); + GENERIC_CSS_RequestData(&device, &data); } - -void Test_GENERIC_CSS_Enable(void) -{ - UT_CheckEvent_t EventTest; - - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_INF_EID, NULL); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; - UT_SetDeferredRetcode(UT_KEY(i2c_master_init), 1, OS_SUCCESS); - GENERIC_CSS_Enable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device enabled (%u)", (unsigned int)EventTest.MatchCount); - - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_I2C_INIT_ERR_EID, NULL); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; - UT_SetDeferredRetcode(UT_KEY(i2c_master_init), 1, OS_ERROR); - GENERIC_CSS_Enable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: UART port initialization error (%u)", - (unsigned int)EventTest.MatchCount); +void Test_GENERIC_CSS_RequestData_Hook(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context, va_list va) {} - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_ERR_EID, NULL); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; - UT_SetDeferredRetcode(UT_KEY(i2c_master_init), 1, OS_ERROR); - GENERIC_CSS_Enable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device enable failed, already enabled (%u)", - (unsigned int)EventTest.MatchCount); +/* + * Setup function prior to every test + */ +void Generic_css_UT_Setup(void) +{ + UT_ResetState(0); } +/* + * Teardown function after every test + */ +void Generic_css_UT_TearDown(void) {} -void Test_GENERIC_CSS_Disable(void) +/* + * Register the test cases to execute with the unit test tool + */ +void UtTest_Setup(void) { - UT_CheckEvent_t EventTest; - - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_INF_EID, NULL); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; - UT_SetDeferredRetcode(UT_KEY(i2c_master_close), 1, OS_SUCCESS); - GENERIC_CSS_Disable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device disabled (%u)", (unsigned int)EventTest.MatchCount); - - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_I2C_CLOSE_ERR_EID, NULL); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; - UT_SetDeferredRetcode(UT_KEY(i2c_master_close), 1, OS_ERROR); - GENERIC_CSS_Disable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: UART port close error (%u)", (unsigned int)EventTest.MatchCount); - - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_ERR_EID, NULL); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; - UT_SetDeferredRetcode(UT_KEY(i2c_master_close), 1, OS_ERROR); - GENERIC_CSS_Disable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device disable failed, already disabled (%u)", - (unsigned int)EventTest.MatchCount); -} - - - void Test_GENERIC_CSS_VerifyCmdLength(void) - { - /* - * Test Case For: - * bool GENERIC_CSS_VerifyCmdLength - */ - - - UT_CheckEvent_t EventTest; - size_t size = 1; - CFE_MSG_FcnCode_t fcncode = 2; - CFE_SB_MsgId_t msgid = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); - - /* - * test a match case - */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); - - GENERIC_CSS_VerifyCmdLength(NULL, size); - - /* - * Confirm that the event was NOT generated - */ - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_LEN_ERR_EID NOT generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* - * test a mismatch case - */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &msgid, sizeof(msgid), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &fcncode, sizeof(fcncode), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); - GENERIC_CSS_VerifyCmdLength(NULL, size + 1); - - /* - * Confirm that the event WAS generated - */ - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_LEN_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - } - - /* - * Setup function prior to every test - */ - void Generic_css_UT_Setup(void) - { - UT_ResetState(0); - } - - /* - * Teardown function after every test - */ - void Generic_css_UT_TearDown(void) {} - - /* - * Register the test cases to execute with the unit test tool - */ - void UtTest_Setup(void) - { - ADD_TEST(CSS_AppMain); - ADD_TEST(GENERIC_CSS_AppInit); - ADD_TEST(GENERIC_CSS_ProcessCommandPacket); - ADD_TEST(GENERIC_CSS_ProcessGroundCommand); - ADD_TEST(GENERIC_CSS_ReportHousekeeping); - ADD_TEST(GENERIC_CSS_ReportDeviceTelemetry); - ADD_TEST(GENERIC_CSS_VerifyCmdLength); - ADD_TEST(GENERIC_CSS_Enable); - ADD_TEST(GENERIC_CSS_Disable); - } - \ No newline at end of file + UT_SetVaHandlerFunction(UT_KEY(Test_GENERIC_CSS_RequestData), Test_GENERIC_CSS_RequestData_Hook, NULL); + ADD_TEST(GENERIC_CSS_RequestData); +} \ No newline at end of file From 4f5139da97d90f7fd7c39b6e919cfe692aafe2ca Mon Sep 17 00:00:00 2001 From: dacarter22 Date: Mon, 12 May 2025 14:09:14 -0400 Subject: [PATCH 11/12] [nasa/nos3#450] all tests passing should fix build errors and restored app.c coverage tests --- .../coveragetest_generic_css_app.c | 657 ++++++++++++++++-- 1 file changed, 613 insertions(+), 44 deletions(-) diff --git a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c index e882f1d..7782c68 100755 --- a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c +++ b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c @@ -1,53 +1,622 @@ -#include "generic_css_app_coveragetest_common.h" - -void Test_GENERIC_CSS_RequestData(void) -{ - i2c_bus_info_t device; - GENERIC_CSS_Device_Data_tlm_t data; - - /* Test basic case with minimal setup */ - GENERIC_CSS_RequestData(&device, &data); - - /* Test successful case */ - uint8_t read_data[] = { - 0x01, 0x02, /* Voltage[0] = 0x0102 */ - 0x03, 0x04, /* Voltage[1] = 0x0304 */ - 0x05, 0x06, /* Voltage[2] = 0x0506 */ - 0x07, 0x08, /* Voltage[3] = 0x0708 */ - 0x09, 0x0A, /* Voltage[4] = 0x090A */ - 0x0B, 0x0C /* Voltage[5] = 0x0B0C */ - }; - - /* Setup for successful I2C transaction */ - UT_SetDefaultReturnValue(UT_KEY(i2c_master_transaction), OS_SUCCESS); - UT_SetDataBuffer(UT_KEY(i2c_master_transaction), read_data, sizeof(read_data), false); - GENERIC_CSS_RequestData(&device, &data); - - /* Test error case */ - UT_SetDefaultReturnValue(UT_KEY(i2c_master_transaction), OS_ERROR); - GENERIC_CSS_RequestData(&device, &data); -} +/* +** 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. +*/ -void Test_GENERIC_CSS_RequestData_Hook(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context, va_list va) {} +/* +** File: coveragetest_generic_css_app.c +** +** Purpose: +** Coverage Unit Test cases for the GENERIC_CSS Application +** +** Notes: +** This implements various test cases to exercise all code +** paths through all functions defined in the GENERIC_CSS application. +** +** It is primarily focused at providing examples of the various +** stub configurations, hook functions, and wrapper calls that +** are often needed when coercing certain code paths through +** complex functions. +*/ /* - * Setup function prior to every test + * Includes + */ + + #include "generic_css_app_coveragetest_common.h" + #include "ut_generic_css_app.h" + + /* to get the GENERIC_CSS_LIB_Function() declaration */ + + typedef struct + { + uint16 ExpectedEvent; + uint32 MatchCount; + const char *ExpectedFormat; + } UT_CheckEvent_t; + + /* + * An example hook function to check for a specific event. + */ + static int32 UT_CheckEvent_Hook(void *UserObj, int32 StubRetcode, uint32 CallCount, const UT_StubContext_t *Context, + va_list va) + { + UT_CheckEvent_t *State = UserObj; + uint16 EventId; + const char * Spec; + + /* + * The CFE_EVS_SendEvent stub passes the EventID as the + * first context argument. + */ + if (Context->ArgCount > 0) + { + EventId = UT_Hook_GetArgValueByName(Context, "EventID", uint16); + if (EventId == State->ExpectedEvent) + { + if (State->ExpectedFormat != NULL) + { + Spec = UT_Hook_GetArgValueByName(Context, "Spec", const char *); + if (Spec != NULL) + { + /* + * Example of how to validate the full argument set. + * ------------------------------------------------ + * + * If really desired one can call something like: + * + * char TestText[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH]; + * vsnprintf(TestText, sizeof(TestText), Spec, va); + * + * And then compare the output (TestText) to the expected fully-rendered string. + * + * NOTE: While this can be done, use with discretion - This isn't really + * verifying that the FSW code unit generated the correct event text, + * rather it is validating what the system snprintf() library function + * produces when passed the format string and args. + * + * This type of check has been demonstrated to make tests very fragile, + * because it is influenced by many factors outside the control of the + * test case. + * + * __This derived string is not an actual output of the unit under test__ + */ + if (strcmp(Spec, State->ExpectedFormat) == 0) + { + ++State->MatchCount; + } + } + } + else + { + ++State->MatchCount; + } + } + } + + return 0; + } + + /* + * Helper function to set up for event checking + * This attaches the hook function to CFE_EVS_SendEvent + */ + static void UT_CheckEvent_Setup(UT_CheckEvent_t *Evt, uint16 ExpectedEvent, const char *ExpectedFormat) + { + memset(Evt, 0, sizeof(*Evt)); + Evt->ExpectedEvent = ExpectedEvent; + Evt->ExpectedFormat = ExpectedFormat; + UT_SetVaHookFunction(UT_KEY(CFE_EVS_SendEvent), UT_CheckEvent_Hook, Evt); + } + + /* + ********************************************************************************** + ** TEST CASE FUNCTIONS + ********************************************************************************** */ -void Generic_css_UT_Setup(void) + + void Test_CSS_AppMain(void) + { + CFE_SB_MsgId_t MsgId = CFE_SB_INVALID_MSG_ID; + + /* + * Test Case For: + * void CSS_AppMain( void ) + */ + + UT_CheckEvent_t EventTest; + + /* + * CSS_AppMain does not return a value, + * but it has several internal decision points + * that need to be exercised here. + * + * First call it in "nominal" mode where all + * dependent calls should be successful by default. + */ + CSS_AppMain(); + + /* + * Confirm that CFE_ES_ExitApp() was called at the end of execution + */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_ExitApp)) == 1, "CFE_ES_ExitApp() called"); + + /* + * Now set up individual cases for each of the error paths. + * The first is for GENERIC_CSS_AppInit(). As this is in the same + * code unit, it is not a stub where the return code can be + * easily set. In order to get this to fail, an underlying + * call needs to fail, and the error gets propagated through. + * The call to CFE_EVS_Register is the first opportunity. + * Any identifiable (non-success) return code should work. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); + + /* + * Just call the function again. It does not return + * the value, so there is nothing to test for here directly. + * However, it should show up in the coverage report that + * the GENERIC_CSS_AppInit() failure path was taken. + */ + CSS_AppMain(); + + /* + * This can validate that the internal "RunStatus" was + * set to CFE_ES_RunStatus_APP_ERROR, by querying the struct directly. + * + * It is always advisable to include the _actual_ values + * when asserting on conditions, so if/when it fails, the + * log will show what the incorrect value was. + */ + UtAssert_True(GENERIC_CSS_AppData.RunStatus == CFE_ES_RunStatus_APP_ERROR, + "GENERIC_CSS_AppData.RunStatus (%lu) == CFE_ES_RunStatus_APP_ERROR", + (unsigned long)GENERIC_CSS_AppData.RunStatus); + + /* + * Note that CFE_ES_RunLoop returns a boolean value, + * so in order to exercise the internal "while" loop, + * it needs to return TRUE. But this also needs to return + * FALSE in order to get out of the loop, otherwise + * it will stay there infinitely. + * + * The deferred retcode will accomplish this. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); + + /* Set up buffer for command processing */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); + + /* + * Invoke again + */ + CSS_AppMain(); + + /* + * Confirm that CFE_SB_ReceiveBuffer() (inside the loop) was called + */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_ReceiveBuffer)) == 1, "CFE_SB_ReceiveBuffer() called"); + + /* + * Now also make the CFE_SB_ReceiveBuffer call fail, + * to exercise that error path. This sends an + * event which can be checked with a hook function. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); + UT_SetDeferredRetcode(UT_KEY(CFE_SB_ReceiveBuffer), 1, CFE_SB_PIPE_RD_ERR); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PIPE_ERR_EID, "GENERIC_CSS: SB Pipe Read Error = %d"); + + /* + * Invoke again + */ + CSS_AppMain(); + + /* + * Confirm that the event was generated + */ + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_PIPE_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + } + + void Test_GENERIC_CSS_AppInit(void) + { + /* + * Test Case For: + * int32 GENERIC_CSS_AppInit( void ) + */ + + /* nominal case should return CFE_SUCCESS */ + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SUCCESS); + + /* trigger a failure for each of the sub-calls, + * and confirm a write to syslog for each. + * Note that this count accumulates, because the status + * is _not_ reset between these test cases. */ + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_EVS_INVALID_PARAMETER); + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_WriteToSysLog)) == 1, "CFE_ES_WriteToSysLog() called"); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_CreatePipe), 1, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 1, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 2, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_SendEvent), 1, CFE_EVS_INVALID_PARAMETER); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), -1040187384); + } + + void Test_GENERIC_CSS_ProcessCommandPacket(void) + { + /* + * Test Case For: + * void GENERIC_CSS_ProcessCommandPacket + */ + /* a buffer large enough for any command message */ + union + { + CFE_SB_Buffer_t SBBuf; + GENERIC_CSS_NoArgs_cmd_t Noop; + } TestMsg; + CFE_SB_MsgId_t TestMsgId; + CFE_MSG_FcnCode_t FcnCode; + size_t MsgSize; + UT_CheckEvent_t EventTest; + + memset(&TestMsg, 0, sizeof(TestMsg)); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PROCESS_CMD_ERR_EID, NULL); + + /* + * The CFE_MSG_GetMsgId() stub uses a data buffer to hold the + * message ID values to return. + */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); + FcnCode = GENERIC_CSS_NOOP_CC; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_CMD_ERR_EID not generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* invalid message id */ + TestMsgId = CFE_SB_INVALID_MSG_ID; + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* Request_HK message id */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); + FcnCode = GENERIC_CSS_REQ_HK_TLM; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_HK_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + + /* Request_HK message id */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); + FcnCode = GENERIC_CSS_REQ_DATA_TLM; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_HK_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* Request_HK message id */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); + FcnCode = GENERIC_CSS_REQ_DATA_TLM; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_HK_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* Request_HK message id with invalid command */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); + FcnCode = 99; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_HK_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + + + } + + void Test_GENERIC_CSS_ProcessGroundCommand(void) + { + /* + * Test Case For: + * void GENERIC_CSS_ProcessGroundCommand + */ + CFE_SB_MsgId_t TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); + CFE_MSG_FcnCode_t FcnCode; + size_t Size; + + /* a buffer large enough for any command message */ + union + { + CFE_SB_Buffer_t SBBuf; + GENERIC_CSS_NoArgs_cmd_t Noop; + GENERIC_CSS_NoArgs_cmd_t Reset; + } TestMsg; + UT_CheckEvent_t EventTest; + + memset(&TestMsg, 0, sizeof(TestMsg)); + + /* + * call with each of the supported command codes + * The CFE_MSG_GetFcnCode stub allows the code to be + * set to whatever is needed. There is no return + * value here and the actual implementation of these + * commands have separate test cases, so this just + * needs to exercise the "switch" statement. + */ + + /* test dispatch of NOOP */ + FcnCode = GENERIC_CSS_NOOP_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_NOOP_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_NOOP_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of RESET */ + FcnCode = GENERIC_CSS_RESET_COUNTERS_CC; + Size = sizeof(TestMsg.Reset); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_RESET_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_RESET_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test an invalid CC */ + FcnCode = 99; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_ERR_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of DISABLE */ + FcnCode = GENERIC_CSS_DISABLE_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_DISABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of ENABLE */ + FcnCode = GENERIC_CSS_ENABLE_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_ENABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + } + + void Test_GENERIC_CSS_ReportHousekeeping(void) + { + /* + * Test Case For: + * void GENERIC_CSS_ReportHousekeeping() + */ + CFE_MSG_Message_t *MsgSend; + CFE_MSG_Message_t *MsgTimestamp; + CFE_SB_MsgId_t MsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_TLM); + + /* Set message id to return so GENERIC_CSS_Housekeeping will be called */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); + + /* Set up to capture send message address */ + UT_SetDataBuffer(UT_KEY(CFE_SB_TransmitMsg), &MsgSend, sizeof(MsgSend), false); + + /* Set up to capture timestamp message address */ + UT_SetDataBuffer(UT_KEY(CFE_SB_TimeStampMsg), &MsgTimestamp, sizeof(MsgTimestamp), false); + + /* Call unit under test, NULL pointer confirms command access is through APIs */ + GENERIC_CSS_ReportHousekeeping(); + + /* Confirm message sent*/ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TransmitMsg)) == 1, "CFE_SB_TransmitMsg() called once"); + UtAssert_True(MsgSend == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, "CFE_SB_TransmitMsg() address matches expected"); + + /* Confirm timestamp msg address */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TimeStampMsg)) == 1, "CFE_SB_TimeStampMsg() called once"); + UtAssert_True(MsgTimestamp == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, + "CFE_SB_TimeStampMsg() address matches expected"); + } + + +void Test_GENERIC_CSS_ReportDeviceTelemetry(void) { - UT_ResetState(0); + GENERIC_CSS_ReportDeviceTelemetry(); + + UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_SUCCESS); + GENERIC_CSS_ReportDeviceTelemetry(); + + UT_SetDeferredRetcode(UT_KEY(GENERIC_CSS_RequestData), 1, OS_ERROR); + GENERIC_CSS_ReportDeviceTelemetry(); + + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; + GENERIC_CSS_ReportDeviceTelemetry(); + + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + GENERIC_CSS_ReportDeviceTelemetry(); } -/* - * Teardown function after every test - */ -void Generic_css_UT_TearDown(void) {} + +void Test_GENERIC_CSS_Enable(void) +{ + UT_CheckEvent_t EventTest; -/* - * Register the test cases to execute with the unit test tool - */ -void UtTest_Setup(void) + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_INF_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; + UT_SetDeferredRetcode(UT_KEY(i2c_master_init), 1, OS_SUCCESS); + GENERIC_CSS_Enable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device enabled (%u)", (unsigned int)EventTest.MatchCount); + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_I2C_INIT_ERR_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; + UT_SetDeferredRetcode(UT_KEY(i2c_master_init), 1, OS_ERROR); + GENERIC_CSS_Enable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: UART port initialization error (%u)", + (unsigned int)EventTest.MatchCount); + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_ERR_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + UT_SetDeferredRetcode(UT_KEY(i2c_master_init), 1, OS_ERROR); + GENERIC_CSS_Enable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device enable failed, already enabled (%u)", + (unsigned int)EventTest.MatchCount); +} + + +void Test_GENERIC_CSS_Disable(void) { - UT_SetVaHandlerFunction(UT_KEY(Test_GENERIC_CSS_RequestData), Test_GENERIC_CSS_RequestData_Hook, NULL); - ADD_TEST(GENERIC_CSS_RequestData); -} \ No newline at end of file + UT_CheckEvent_t EventTest; + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_INF_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + UT_SetDeferredRetcode(UT_KEY(i2c_master_close), 1, OS_SUCCESS); + GENERIC_CSS_Disable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device disabled (%u)", (unsigned int)EventTest.MatchCount); + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_I2C_CLOSE_ERR_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + UT_SetDeferredRetcode(UT_KEY(i2c_master_close), 1, OS_ERROR); + GENERIC_CSS_Disable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: UART port close error (%u)", (unsigned int)EventTest.MatchCount); + + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_ERR_EID, NULL); + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; + UT_SetDeferredRetcode(UT_KEY(i2c_master_close), 1, OS_ERROR); + GENERIC_CSS_Disable(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: Device disable failed, already disabled (%u)", + (unsigned int)EventTest.MatchCount); +} + + + void Test_GENERIC_CSS_VerifyCmdLength(void) + { + /* + * Test Case For: + * bool GENERIC_CSS_VerifyCmdLength + */ + + + UT_CheckEvent_t EventTest; + size_t size = 1; + CFE_MSG_FcnCode_t fcncode = 2; + CFE_SB_MsgId_t msgid = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); + + /* + * test a match case + */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); + + GENERIC_CSS_VerifyCmdLength(NULL, size); + + /* + * Confirm that the event was NOT generated + */ + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_LEN_ERR_EID NOT generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* + * test a mismatch case + */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &msgid, sizeof(msgid), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &fcncode, sizeof(fcncode), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); + GENERIC_CSS_VerifyCmdLength(NULL, size + 1); + + /* + * Confirm that the event WAS generated + */ + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_LEN_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + } + + /* + * Setup function prior to every test + */ + void Generic_css_UT_Setup(void) + { + UT_ResetState(0); + } + + /* + * Teardown function after every test + */ + void Generic_css_UT_TearDown(void) {} + + /* + * Register the test cases to execute with the unit test tool + */ + void UtTest_Setup(void) + { + ADD_TEST(CSS_AppMain); + ADD_TEST(GENERIC_CSS_AppInit); + ADD_TEST(GENERIC_CSS_ProcessCommandPacket); + ADD_TEST(GENERIC_CSS_ProcessGroundCommand); + ADD_TEST(GENERIC_CSS_ReportHousekeeping); + ADD_TEST(GENERIC_CSS_ReportDeviceTelemetry); + ADD_TEST(GENERIC_CSS_VerifyCmdLength); + ADD_TEST(GENERIC_CSS_Enable); + ADD_TEST(GENERIC_CSS_Disable); + } + \ No newline at end of file From e4e3a472ca44ca533091842d95dd8304a9fc663f Mon Sep 17 00:00:00 2001 From: jlucas9 <6588622+jlucas9@users.noreply.github.com> Date: Thu, 22 May 2025 14:41:48 +0000 Subject: [PATCH 12/12] style: auto-format via clang-format --- .../coveragetest_generic_css_app.c | 955 +++++++++--------- .../coveragetest_generic_css_device.c | 23 +- fsw/cfs/unit-test/inc/ut_generic_css_app.h | 2 +- 3 files changed, 488 insertions(+), 492 deletions(-) mode change 100755 => 100644 fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c mode change 100755 => 100644 fsw/cfs/unit-test/inc/ut_generic_css_app.h diff --git a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c old mode 100755 new mode 100644 index 7782c68..62558b9 --- a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c +++ b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_app.c @@ -38,287 +38,287 @@ * Includes */ - #include "generic_css_app_coveragetest_common.h" - #include "ut_generic_css_app.h" - - /* to get the GENERIC_CSS_LIB_Function() declaration */ - - typedef struct - { - uint16 ExpectedEvent; - uint32 MatchCount; - const char *ExpectedFormat; - } UT_CheckEvent_t; - - /* - * An example hook function to check for a specific event. - */ - static int32 UT_CheckEvent_Hook(void *UserObj, int32 StubRetcode, uint32 CallCount, const UT_StubContext_t *Context, - va_list va) - { - UT_CheckEvent_t *State = UserObj; - uint16 EventId; - const char * Spec; - - /* - * The CFE_EVS_SendEvent stub passes the EventID as the - * first context argument. - */ - if (Context->ArgCount > 0) - { - EventId = UT_Hook_GetArgValueByName(Context, "EventID", uint16); - if (EventId == State->ExpectedEvent) - { - if (State->ExpectedFormat != NULL) - { - Spec = UT_Hook_GetArgValueByName(Context, "Spec", const char *); - if (Spec != NULL) - { - /* - * Example of how to validate the full argument set. - * ------------------------------------------------ - * - * If really desired one can call something like: - * - * char TestText[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH]; - * vsnprintf(TestText, sizeof(TestText), Spec, va); - * - * And then compare the output (TestText) to the expected fully-rendered string. - * - * NOTE: While this can be done, use with discretion - This isn't really - * verifying that the FSW code unit generated the correct event text, - * rather it is validating what the system snprintf() library function - * produces when passed the format string and args. - * - * This type of check has been demonstrated to make tests very fragile, - * because it is influenced by many factors outside the control of the - * test case. - * - * __This derived string is not an actual output of the unit under test__ - */ - if (strcmp(Spec, State->ExpectedFormat) == 0) - { - ++State->MatchCount; - } - } - } - else - { - ++State->MatchCount; - } - } - } - - return 0; - } - - /* - * Helper function to set up for event checking - * This attaches the hook function to CFE_EVS_SendEvent - */ - static void UT_CheckEvent_Setup(UT_CheckEvent_t *Evt, uint16 ExpectedEvent, const char *ExpectedFormat) - { - memset(Evt, 0, sizeof(*Evt)); - Evt->ExpectedEvent = ExpectedEvent; - Evt->ExpectedFormat = ExpectedFormat; - UT_SetVaHookFunction(UT_KEY(CFE_EVS_SendEvent), UT_CheckEvent_Hook, Evt); - } - - /* - ********************************************************************************** - ** TEST CASE FUNCTIONS - ********************************************************************************** +#include "generic_css_app_coveragetest_common.h" +#include "ut_generic_css_app.h" + +/* to get the GENERIC_CSS_LIB_Function() declaration */ + +typedef struct +{ + uint16 ExpectedEvent; + uint32 MatchCount; + const char *ExpectedFormat; +} UT_CheckEvent_t; + +/* + * An example hook function to check for a specific event. + */ +static int32 UT_CheckEvent_Hook(void *UserObj, int32 StubRetcode, uint32 CallCount, const UT_StubContext_t *Context, + va_list va) +{ + UT_CheckEvent_t *State = UserObj; + uint16 EventId; + const char *Spec; + + /* + * The CFE_EVS_SendEvent stub passes the EventID as the + * first context argument. + */ + if (Context->ArgCount > 0) + { + EventId = UT_Hook_GetArgValueByName(Context, "EventID", uint16); + if (EventId == State->ExpectedEvent) + { + if (State->ExpectedFormat != NULL) + { + Spec = UT_Hook_GetArgValueByName(Context, "Spec", const char *); + if (Spec != NULL) + { + /* + * Example of how to validate the full argument set. + * ------------------------------------------------ + * + * If really desired one can call something like: + * + * char TestText[CFE_MISSION_EVS_MAX_MESSAGE_LENGTH]; + * vsnprintf(TestText, sizeof(TestText), Spec, va); + * + * And then compare the output (TestText) to the expected fully-rendered string. + * + * NOTE: While this can be done, use with discretion - This isn't really + * verifying that the FSW code unit generated the correct event text, + * rather it is validating what the system snprintf() library function + * produces when passed the format string and args. + * + * This type of check has been demonstrated to make tests very fragile, + * because it is influenced by many factors outside the control of the + * test case. + * + * __This derived string is not an actual output of the unit under test__ + */ + if (strcmp(Spec, State->ExpectedFormat) == 0) + { + ++State->MatchCount; + } + } + } + else + { + ++State->MatchCount; + } + } + } + + return 0; +} + +/* + * Helper function to set up for event checking + * This attaches the hook function to CFE_EVS_SendEvent */ - - void Test_CSS_AppMain(void) - { - CFE_SB_MsgId_t MsgId = CFE_SB_INVALID_MSG_ID; - - /* - * Test Case For: - * void CSS_AppMain( void ) - */ - - UT_CheckEvent_t EventTest; - - /* - * CSS_AppMain does not return a value, - * but it has several internal decision points - * that need to be exercised here. - * - * First call it in "nominal" mode where all - * dependent calls should be successful by default. - */ - CSS_AppMain(); - - /* - * Confirm that CFE_ES_ExitApp() was called at the end of execution - */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_ExitApp)) == 1, "CFE_ES_ExitApp() called"); - - /* - * Now set up individual cases for each of the error paths. - * The first is for GENERIC_CSS_AppInit(). As this is in the same - * code unit, it is not a stub where the return code can be - * easily set. In order to get this to fail, an underlying - * call needs to fail, and the error gets propagated through. - * The call to CFE_EVS_Register is the first opportunity. - * Any identifiable (non-success) return code should work. - */ - UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); - - /* - * Just call the function again. It does not return - * the value, so there is nothing to test for here directly. - * However, it should show up in the coverage report that - * the GENERIC_CSS_AppInit() failure path was taken. - */ - CSS_AppMain(); - - /* - * This can validate that the internal "RunStatus" was - * set to CFE_ES_RunStatus_APP_ERROR, by querying the struct directly. - * - * It is always advisable to include the _actual_ values - * when asserting on conditions, so if/when it fails, the - * log will show what the incorrect value was. - */ - UtAssert_True(GENERIC_CSS_AppData.RunStatus == CFE_ES_RunStatus_APP_ERROR, - "GENERIC_CSS_AppData.RunStatus (%lu) == CFE_ES_RunStatus_APP_ERROR", - (unsigned long)GENERIC_CSS_AppData.RunStatus); - - /* - * Note that CFE_ES_RunLoop returns a boolean value, - * so in order to exercise the internal "while" loop, - * it needs to return TRUE. But this also needs to return - * FALSE in order to get out of the loop, otherwise - * it will stay there infinitely. - * - * The deferred retcode will accomplish this. - */ - UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); - - /* Set up buffer for command processing */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); - - /* - * Invoke again - */ - CSS_AppMain(); - - /* - * Confirm that CFE_SB_ReceiveBuffer() (inside the loop) was called - */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_ReceiveBuffer)) == 1, "CFE_SB_ReceiveBuffer() called"); - - /* - * Now also make the CFE_SB_ReceiveBuffer call fail, - * to exercise that error path. This sends an - * event which can be checked with a hook function. - */ - UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); - UT_SetDeferredRetcode(UT_KEY(CFE_SB_ReceiveBuffer), 1, CFE_SB_PIPE_RD_ERR); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PIPE_ERR_EID, "GENERIC_CSS: SB Pipe Read Error = %d"); - - /* - * Invoke again - */ - CSS_AppMain(); - - /* - * Confirm that the event was generated - */ - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_PIPE_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - } - - void Test_GENERIC_CSS_AppInit(void) - { - /* - * Test Case For: - * int32 GENERIC_CSS_AppInit( void ) - */ - - /* nominal case should return CFE_SUCCESS */ - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SUCCESS); - - /* trigger a failure for each of the sub-calls, - * and confirm a write to syslog for each. - * Note that this count accumulates, because the status - * is _not_ reset between these test cases. */ - UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_EVS_INVALID_PARAMETER); - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_WriteToSysLog)) == 1, "CFE_ES_WriteToSysLog() called"); - - UT_SetDeferredRetcode(UT_KEY(CFE_SB_CreatePipe), 1, CFE_SB_BAD_ARGUMENT); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); - - UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 1, CFE_SB_BAD_ARGUMENT); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); - - UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 2, CFE_SB_BAD_ARGUMENT); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); - - UT_SetDeferredRetcode(UT_KEY(CFE_EVS_SendEvent), 1, CFE_EVS_INVALID_PARAMETER); - UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), -1040187384); - } - - void Test_GENERIC_CSS_ProcessCommandPacket(void) - { - /* - * Test Case For: - * void GENERIC_CSS_ProcessCommandPacket - */ - /* a buffer large enough for any command message */ - union - { - CFE_SB_Buffer_t SBBuf; - GENERIC_CSS_NoArgs_cmd_t Noop; - } TestMsg; - CFE_SB_MsgId_t TestMsgId; - CFE_MSG_FcnCode_t FcnCode; - size_t MsgSize; - UT_CheckEvent_t EventTest; - - memset(&TestMsg, 0, sizeof(TestMsg)); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PROCESS_CMD_ERR_EID, NULL); - - /* - * The CFE_MSG_GetMsgId() stub uses a data buffer to hold the - * message ID values to return. - */ - TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); - FcnCode = GENERIC_CSS_NOOP_CC; - MsgSize = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); - GENERIC_CSS_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_CMD_ERR_EID not generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* invalid message id */ - TestMsgId = CFE_SB_INVALID_MSG_ID; - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - GENERIC_CSS_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* Request_HK message id */ - TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); - FcnCode = GENERIC_CSS_REQ_HK_TLM; - MsgSize = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); - GENERIC_CSS_ProcessCommandPacket(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_HK_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; +static void UT_CheckEvent_Setup(UT_CheckEvent_t *Evt, uint16 ExpectedEvent, const char *ExpectedFormat) +{ + memset(Evt, 0, sizeof(*Evt)); + Evt->ExpectedEvent = ExpectedEvent; + Evt->ExpectedFormat = ExpectedFormat; + UT_SetVaHookFunction(UT_KEY(CFE_EVS_SendEvent), UT_CheckEvent_Hook, Evt); +} + +/* +********************************************************************************** +** TEST CASE FUNCTIONS +********************************************************************************** +*/ + +void Test_CSS_AppMain(void) +{ + CFE_SB_MsgId_t MsgId = CFE_SB_INVALID_MSG_ID; + + /* + * Test Case For: + * void CSS_AppMain( void ) + */ + + UT_CheckEvent_t EventTest; + + /* + * CSS_AppMain does not return a value, + * but it has several internal decision points + * that need to be exercised here. + * + * First call it in "nominal" mode where all + * dependent calls should be successful by default. + */ + CSS_AppMain(); + + /* + * Confirm that CFE_ES_ExitApp() was called at the end of execution + */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_ExitApp)) == 1, "CFE_ES_ExitApp() called"); + + /* + * Now set up individual cases for each of the error paths. + * The first is for GENERIC_CSS_AppInit(). As this is in the same + * code unit, it is not a stub where the return code can be + * easily set. In order to get this to fail, an underlying + * call needs to fail, and the error gets propagated through. + * The call to CFE_EVS_Register is the first opportunity. + * Any identifiable (non-success) return code should work. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); + + /* + * Just call the function again. It does not return + * the value, so there is nothing to test for here directly. + * However, it should show up in the coverage report that + * the GENERIC_CSS_AppInit() failure path was taken. + */ + CSS_AppMain(); + + /* + * This can validate that the internal "RunStatus" was + * set to CFE_ES_RunStatus_APP_ERROR, by querying the struct directly. + * + * It is always advisable to include the _actual_ values + * when asserting on conditions, so if/when it fails, the + * log will show what the incorrect value was. + */ + UtAssert_True(GENERIC_CSS_AppData.RunStatus == CFE_ES_RunStatus_APP_ERROR, + "GENERIC_CSS_AppData.RunStatus (%lu) == CFE_ES_RunStatus_APP_ERROR", + (unsigned long)GENERIC_CSS_AppData.RunStatus); + + /* + * Note that CFE_ES_RunLoop returns a boolean value, + * so in order to exercise the internal "while" loop, + * it needs to return TRUE. But this also needs to return + * FALSE in order to get out of the loop, otherwise + * it will stay there infinitely. + * + * The deferred retcode will accomplish this. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); + + /* Set up buffer for command processing */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); + + /* + * Invoke again + */ + CSS_AppMain(); + + /* + * Confirm that CFE_SB_ReceiveBuffer() (inside the loop) was called + */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_ReceiveBuffer)) == 1, "CFE_SB_ReceiveBuffer() called"); + + /* + * Now also make the CFE_SB_ReceiveBuffer call fail, + * to exercise that error path. This sends an + * event which can be checked with a hook function. + */ + UT_SetDeferredRetcode(UT_KEY(CFE_ES_RunLoop), 1, true); + UT_SetDeferredRetcode(UT_KEY(CFE_SB_ReceiveBuffer), 1, CFE_SB_PIPE_RD_ERR); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PIPE_ERR_EID, "GENERIC_CSS: SB Pipe Read Error = %d"); + + /* + * Invoke again + */ + CSS_AppMain(); + + /* + * Confirm that the event was generated + */ + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_PIPE_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); +} + +void Test_GENERIC_CSS_AppInit(void) +{ + /* + * Test Case For: + * int32 GENERIC_CSS_AppInit( void ) + */ + + /* nominal case should return CFE_SUCCESS */ + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SUCCESS); + + /* trigger a failure for each of the sub-calls, + * and confirm a write to syslog for each. + * Note that this count accumulates, because the status + * is _not_ reset between these test cases. */ + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_Register), 1, CFE_EVS_INVALID_PARAMETER); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_EVS_INVALID_PARAMETER); + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_ES_WriteToSysLog)) == 1, "CFE_ES_WriteToSysLog() called"); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_CreatePipe), 1, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 1, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_SB_Subscribe), 2, CFE_SB_BAD_ARGUMENT); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), CFE_SB_BAD_ARGUMENT); + + UT_SetDeferredRetcode(UT_KEY(CFE_EVS_SendEvent), 1, CFE_EVS_INVALID_PARAMETER); + UT_TEST_FUNCTION_RC(GENERIC_CSS_AppInit(), -1040187384); +} + +void Test_GENERIC_CSS_ProcessCommandPacket(void) +{ + /* + * Test Case For: + * void GENERIC_CSS_ProcessCommandPacket + */ + /* a buffer large enough for any command message */ + union + { + CFE_SB_Buffer_t SBBuf; + GENERIC_CSS_NoArgs_cmd_t Noop; + } TestMsg; + CFE_SB_MsgId_t TestMsgId; + CFE_MSG_FcnCode_t FcnCode; + size_t MsgSize; + UT_CheckEvent_t EventTest; + + memset(&TestMsg, 0, sizeof(TestMsg)); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_PROCESS_CMD_ERR_EID, NULL); + + /* + * The CFE_MSG_GetMsgId() stub uses a data buffer to hold the + * message ID values to return. + */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); + FcnCode = GENERIC_CSS_NOOP_CC; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_CMD_ERR_EID not generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* invalid message id */ + TestMsgId = CFE_SB_INVALID_MSG_ID; + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* Request_HK message id */ + TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); + FcnCode = GENERIC_CSS_REQ_HK_TLM; + MsgSize = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &MsgSize, sizeof(MsgSize), false); + GENERIC_CSS_ProcessCommandPacket(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_HK_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; /* Request_HK message id */ TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); @@ -345,7 +345,7 @@ UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_HK_ERR_EID generated (%u)", (unsigned int)EventTest.MatchCount); - /* Request_HK message id with invalid command */ + /* Request_HK message id with invalid command */ TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_MID); FcnCode = 99; MsgSize = sizeof(TestMsg.Noop); @@ -356,129 +356,126 @@ GENERIC_CSS_ProcessCommandPacket(); UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_HK_ERR_EID generated (%u)", (unsigned int)EventTest.MatchCount); - - - - } - - void Test_GENERIC_CSS_ProcessGroundCommand(void) - { - /* - * Test Case For: - * void GENERIC_CSS_ProcessGroundCommand - */ - CFE_SB_MsgId_t TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); - CFE_MSG_FcnCode_t FcnCode; - size_t Size; - - /* a buffer large enough for any command message */ - union - { - CFE_SB_Buffer_t SBBuf; - GENERIC_CSS_NoArgs_cmd_t Noop; - GENERIC_CSS_NoArgs_cmd_t Reset; - } TestMsg; - UT_CheckEvent_t EventTest; - - memset(&TestMsg, 0, sizeof(TestMsg)); - - /* - * call with each of the supported command codes - * The CFE_MSG_GetFcnCode stub allows the code to be - * set to whatever is needed. There is no return - * value here and the actual implementation of these - * commands have separate test cases, so this just - * needs to exercise the "switch" statement. - */ - - /* test dispatch of NOOP */ - FcnCode = GENERIC_CSS_NOOP_CC; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_NOOP_INF_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_NOOP_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of RESET */ - FcnCode = GENERIC_CSS_RESET_COUNTERS_CC; - Size = sizeof(TestMsg.Reset); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_RESET_INF_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_RESET_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test an invalid CC */ - FcnCode = 99; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_ERR_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of DISABLE */ - FcnCode = GENERIC_CSS_DISABLE_CC; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_INF_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_DISABLE_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* test dispatch of ENABLE */ - FcnCode = GENERIC_CSS_ENABLE_CC; - Size = sizeof(TestMsg.Noop); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_INF_EID, NULL); - GENERIC_CSS_ProcessGroundCommand(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_ENABLE_INF_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - } - - void Test_GENERIC_CSS_ReportHousekeeping(void) - { - /* - * Test Case For: - * void GENERIC_CSS_ReportHousekeeping() - */ - CFE_MSG_Message_t *MsgSend; - CFE_MSG_Message_t *MsgTimestamp; - CFE_SB_MsgId_t MsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_TLM); - - /* Set message id to return so GENERIC_CSS_Housekeeping will be called */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); - - /* Set up to capture send message address */ - UT_SetDataBuffer(UT_KEY(CFE_SB_TransmitMsg), &MsgSend, sizeof(MsgSend), false); - - /* Set up to capture timestamp message address */ - UT_SetDataBuffer(UT_KEY(CFE_SB_TimeStampMsg), &MsgTimestamp, sizeof(MsgTimestamp), false); - - /* Call unit under test, NULL pointer confirms command access is through APIs */ - GENERIC_CSS_ReportHousekeeping(); - - /* Confirm message sent*/ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TransmitMsg)) == 1, "CFE_SB_TransmitMsg() called once"); - UtAssert_True(MsgSend == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, "CFE_SB_TransmitMsg() address matches expected"); - - /* Confirm timestamp msg address */ - UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TimeStampMsg)) == 1, "CFE_SB_TimeStampMsg() called once"); - UtAssert_True(MsgTimestamp == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, - "CFE_SB_TimeStampMsg() address matches expected"); - } - - +} + +void Test_GENERIC_CSS_ProcessGroundCommand(void) +{ + /* + * Test Case For: + * void GENERIC_CSS_ProcessGroundCommand + */ + CFE_SB_MsgId_t TestMsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); + CFE_MSG_FcnCode_t FcnCode; + size_t Size; + + /* a buffer large enough for any command message */ + union + { + CFE_SB_Buffer_t SBBuf; + GENERIC_CSS_NoArgs_cmd_t Noop; + GENERIC_CSS_NoArgs_cmd_t Reset; + } TestMsg; + UT_CheckEvent_t EventTest; + + memset(&TestMsg, 0, sizeof(TestMsg)); + + /* + * call with each of the supported command codes + * The CFE_MSG_GetFcnCode stub allows the code to be + * set to whatever is needed. There is no return + * value here and the actual implementation of these + * commands have separate test cases, so this just + * needs to exercise the "switch" statement. + */ + + /* test dispatch of NOOP */ + FcnCode = GENERIC_CSS_NOOP_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_NOOP_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_NOOP_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of RESET */ + FcnCode = GENERIC_CSS_RESET_COUNTERS_CC; + Size = sizeof(TestMsg.Reset); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_RESET_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_RESET_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test an invalid CC */ + FcnCode = 99; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_CMD_ERR_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_CMD_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of DISABLE */ + FcnCode = GENERIC_CSS_DISABLE_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_DISABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* test dispatch of ENABLE */ + FcnCode = GENERIC_CSS_ENABLE_CC; + Size = sizeof(TestMsg.Noop); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &TestMsgId, sizeof(TestMsgId), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &FcnCode, sizeof(FcnCode), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &Size, sizeof(Size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_ENABLE_INF_EID, NULL); + GENERIC_CSS_ProcessGroundCommand(); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_ENABLE_INF_EID generated (%u)", + (unsigned int)EventTest.MatchCount); +} + +void Test_GENERIC_CSS_ReportHousekeeping(void) +{ + /* + * Test Case For: + * void GENERIC_CSS_ReportHousekeeping() + */ + CFE_MSG_Message_t *MsgSend; + CFE_MSG_Message_t *MsgTimestamp; + CFE_SB_MsgId_t MsgId = CFE_SB_ValueToMsgId(GENERIC_CSS_REQ_HK_TLM); + + /* Set message id to return so GENERIC_CSS_Housekeeping will be called */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &MsgId, sizeof(MsgId), false); + + /* Set up to capture send message address */ + UT_SetDataBuffer(UT_KEY(CFE_SB_TransmitMsg), &MsgSend, sizeof(MsgSend), false); + + /* Set up to capture timestamp message address */ + UT_SetDataBuffer(UT_KEY(CFE_SB_TimeStampMsg), &MsgTimestamp, sizeof(MsgTimestamp), false); + + /* Call unit under test, NULL pointer confirms command access is through APIs */ + GENERIC_CSS_ReportHousekeeping(); + + /* Confirm message sent*/ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TransmitMsg)) == 1, "CFE_SB_TransmitMsg() called once"); + UtAssert_True(MsgSend == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, + "CFE_SB_TransmitMsg() address matches expected"); + + /* Confirm timestamp msg address */ + UtAssert_True(UT_GetStubCount(UT_KEY(CFE_SB_TimeStampMsg)) == 1, "CFE_SB_TimeStampMsg() called once"); + UtAssert_True(MsgTimestamp == &GENERIC_CSS_AppData.HkTelemetryPkt.TlmHeader.Msg, + "CFE_SB_TimeStampMsg() address matches expected"); +} + void Test_GENERIC_CSS_ReportDeviceTelemetry(void) { GENERIC_CSS_ReportDeviceTelemetry(); @@ -492,11 +489,10 @@ void Test_GENERIC_CSS_ReportDeviceTelemetry(void) GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; GENERIC_CSS_ReportDeviceTelemetry(); - GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; + GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; GENERIC_CSS_ReportDeviceTelemetry(); } - void Test_GENERIC_CSS_Enable(void) { UT_CheckEvent_t EventTest; @@ -522,7 +518,6 @@ void Test_GENERIC_CSS_Enable(void) (unsigned int)EventTest.MatchCount); } - void Test_GENERIC_CSS_Disable(void) { UT_CheckEvent_t EventTest; @@ -537,7 +532,8 @@ void Test_GENERIC_CSS_Disable(void) GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_ENABLED; UT_SetDeferredRetcode(UT_KEY(i2c_master_close), 1, OS_ERROR); GENERIC_CSS_Disable(); - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: UART port close error (%u)", (unsigned int)EventTest.MatchCount); + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS: UART port close error (%u)", + (unsigned int)EventTest.MatchCount); UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_DISABLE_ERR_EID, NULL); GENERIC_CSS_AppData.HkTelemetryPkt.DeviceEnabled = GENERIC_CSS_DEVICE_DISABLED; @@ -547,76 +543,73 @@ void Test_GENERIC_CSS_Disable(void) (unsigned int)EventTest.MatchCount); } - - void Test_GENERIC_CSS_VerifyCmdLength(void) - { - /* - * Test Case For: - * bool GENERIC_CSS_VerifyCmdLength - */ - - - UT_CheckEvent_t EventTest; - size_t size = 1; - CFE_MSG_FcnCode_t fcncode = 2; - CFE_SB_MsgId_t msgid = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); - - /* - * test a match case - */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); - - GENERIC_CSS_VerifyCmdLength(NULL, size); - - /* - * Confirm that the event was NOT generated - */ - UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_LEN_ERR_EID NOT generated (%u)", - (unsigned int)EventTest.MatchCount); - - /* - * test a mismatch case - */ - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &msgid, sizeof(msgid), false); - UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &fcncode, sizeof(fcncode), false); - UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); - GENERIC_CSS_VerifyCmdLength(NULL, size + 1); - - /* - * Confirm that the event WAS generated - */ - UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_LEN_ERR_EID generated (%u)", - (unsigned int)EventTest.MatchCount); - } - - /* - * Setup function prior to every test - */ - void Generic_css_UT_Setup(void) - { - UT_ResetState(0); - } - - /* - * Teardown function after every test - */ - void Generic_css_UT_TearDown(void) {} - - /* - * Register the test cases to execute with the unit test tool - */ - void UtTest_Setup(void) - { - ADD_TEST(CSS_AppMain); - ADD_TEST(GENERIC_CSS_AppInit); - ADD_TEST(GENERIC_CSS_ProcessCommandPacket); - ADD_TEST(GENERIC_CSS_ProcessGroundCommand); - ADD_TEST(GENERIC_CSS_ReportHousekeeping); - ADD_TEST(GENERIC_CSS_ReportDeviceTelemetry); - ADD_TEST(GENERIC_CSS_VerifyCmdLength); - ADD_TEST(GENERIC_CSS_Enable); - ADD_TEST(GENERIC_CSS_Disable); - } - \ No newline at end of file +void Test_GENERIC_CSS_VerifyCmdLength(void) +{ + /* + * Test Case For: + * bool GENERIC_CSS_VerifyCmdLength + */ + + UT_CheckEvent_t EventTest; + size_t size = 1; + CFE_MSG_FcnCode_t fcncode = 2; + CFE_SB_MsgId_t msgid = CFE_SB_ValueToMsgId(GENERIC_CSS_CMD_MID); + + /* + * test a match case + */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); + + GENERIC_CSS_VerifyCmdLength(NULL, size); + + /* + * Confirm that the event was NOT generated + */ + UtAssert_True(EventTest.MatchCount == 0, "GENERIC_CSS_LEN_ERR_EID NOT generated (%u)", + (unsigned int)EventTest.MatchCount); + + /* + * test a mismatch case + */ + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetSize), &size, sizeof(size), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetMsgId), &msgid, sizeof(msgid), false); + UT_SetDataBuffer(UT_KEY(CFE_MSG_GetFcnCode), &fcncode, sizeof(fcncode), false); + UT_CheckEvent_Setup(&EventTest, GENERIC_CSS_LEN_ERR_EID, NULL); + GENERIC_CSS_VerifyCmdLength(NULL, size + 1); + + /* + * Confirm that the event WAS generated + */ + UtAssert_True(EventTest.MatchCount == 1, "GENERIC_CSS_LEN_ERR_EID generated (%u)", + (unsigned int)EventTest.MatchCount); +} + +/* + * Setup function prior to every test + */ +void Generic_css_UT_Setup(void) +{ + UT_ResetState(0); +} + +/* + * Teardown function after every test + */ +void Generic_css_UT_TearDown(void) {} + +/* + * Register the test cases to execute with the unit test tool + */ +void UtTest_Setup(void) +{ + ADD_TEST(CSS_AppMain); + ADD_TEST(GENERIC_CSS_AppInit); + ADD_TEST(GENERIC_CSS_ProcessCommandPacket); + ADD_TEST(GENERIC_CSS_ProcessGroundCommand); + ADD_TEST(GENERIC_CSS_ReportHousekeeping); + ADD_TEST(GENERIC_CSS_ReportDeviceTelemetry); + ADD_TEST(GENERIC_CSS_VerifyCmdLength); + ADD_TEST(GENERIC_CSS_Enable); + ADD_TEST(GENERIC_CSS_Disable); +} diff --git a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_device.c b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_device.c index 5394e50..46683f1 100644 --- a/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_device.c +++ b/fsw/cfs/unit-test/coveragetest/coveragetest_generic_css_device.c @@ -2,22 +2,22 @@ void Test_GENERIC_CSS_RequestData(void) { - i2c_bus_info_t device; + i2c_bus_info_t device; GENERIC_CSS_Device_Data_tlm_t data; - + /* Test basic case with minimal setup */ GENERIC_CSS_RequestData(&device, &data); /* Test successful case */ uint8_t read_data[] = { - 0x01, 0x02, /* Voltage[0] = 0x0102 */ - 0x03, 0x04, /* Voltage[1] = 0x0304 */ - 0x05, 0x06, /* Voltage[2] = 0x0506 */ - 0x07, 0x08, /* Voltage[3] = 0x0708 */ - 0x09, 0x0A, /* Voltage[4] = 0x090A */ - 0x0B, 0x0C /* Voltage[5] = 0x0B0C */ + 0x01, 0x02, /* Voltage[0] = 0x0102 */ + 0x03, 0x04, /* Voltage[1] = 0x0304 */ + 0x05, 0x06, /* Voltage[2] = 0x0506 */ + 0x07, 0x08, /* Voltage[3] = 0x0708 */ + 0x09, 0x0A, /* Voltage[4] = 0x090A */ + 0x0B, 0x0C /* Voltage[5] = 0x0B0C */ }; - + /* Setup for successful I2C transaction */ UT_SetDefaultReturnValue(UT_KEY(i2c_master_transaction), OS_SUCCESS); UT_SetDataBuffer(UT_KEY(i2c_master_transaction), read_data, sizeof(read_data), false); @@ -28,7 +28,10 @@ void Test_GENERIC_CSS_RequestData(void) GENERIC_CSS_RequestData(&device, &data); } -void Test_GENERIC_CSS_RequestData_Hook(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context, va_list va) {} +void Test_GENERIC_CSS_RequestData_Hook(void *UserObj, UT_EntryKey_t FuncKey, const UT_StubContext_t *Context, + va_list va) +{ +} /* * Setup function prior to every test diff --git a/fsw/cfs/unit-test/inc/ut_generic_css_app.h b/fsw/cfs/unit-test/inc/ut_generic_css_app.h old mode 100755 new mode 100644 index 2540055..5c518e1 --- a/fsw/cfs/unit-test/inc/ut_generic_css_app.h +++ b/fsw/cfs/unit-test/inc/ut_generic_css_app.h @@ -46,6 +46,6 @@ /* * Allow UT access to the global "GENERIC_CSS_APP_Data" object. */ -//extern GENERIC_CSS_AppData_t GENERIC_CSS_APP_Data; +// extern GENERIC_CSS_AppData_t GENERIC_CSS_APP_Data; #endif /* UT_GENERIC_CSS_APP_H */