Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #1281, remove testrunner and convert testcase to app #1292

Merged
merged 3 commits into from
Apr 22, 2021
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmake/mission_defaults.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,6 @@ set(psp_SEARCH_PATH ".")
# If ENABLE_UNIT_TEST is enabled, then include the cfe_assert library in
# all targets. This can still be overridden in targets.cmake.
if (ENABLE_UNIT_TESTS)
list(APPEND MISSION_GLOBAL_APPLIST cfe_assert cfe_testrunner cfe_testcase)
list(APPEND MISSION_GLOBAL_APPLIST cfe_assert cfe_testcase)
endif (ENABLE_UNIT_TESTS)

11 changes: 6 additions & 5 deletions cmake/sample_defs/cpu1_cfe_es_startup.scr
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
CFE_LIB, sample_lib, SAMPLE_LIB_Init, SAMPLE_LIB, 0, 0, 0x0, 0;
CFE_APP, sample_app, SAMPLE_APP_Main, SAMPLE_APP, 50, 16384, 0x0, 0;
CFE_APP, ci_lab, CI_Lab_AppMain, CI_LAB_APP, 60, 16384, 0x0, 0;
CFE_APP, to_lab, TO_Lab_AppMain, TO_LAB_APP, 70, 16384, 0x0, 0;
CFE_APP, sch_lab, SCH_Lab_AppMain, SCH_LAB_APP, 80, 16384, 0x0, 0;
CFE_LIB, cfe_assert, CFE_Assert_LibInit, ASSERT_LIB, 0, 0, 0x0, 0;
CFE_LIB, sample_lib, SAMPLE_LIB_Init, SAMPLE_LIB, 0, 0, 0x0, 0;
CFE_APP, sample_app, SAMPLE_APP_Main, SAMPLE_APP, 50, 16384, 0x0, 0;
CFE_APP, ci_lab, CI_Lab_AppMain, CI_LAB_APP, 60, 16384, 0x0, 0;
CFE_APP, to_lab, TO_Lab_AppMain, TO_LAB_APP, 70, 16384, 0x0, 0;
CFE_APP, sch_lab, SCH_Lab_AppMain, SCH_LAB_APP, 80, 16384, 0x0, 0;
!
! Startup script fields:
! 1. Object Type -- CFE_APP for an Application, or CFE_LIB for a library.
Expand Down
1 change: 1 addition & 0 deletions modules/cfe_assert/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ project(CFE_ASSERT C)
add_cfe_app(cfe_assert
src/cfe_assert_io.c
src/cfe_assert_init.c
src/cfe_assert_runner.c
$<TARGET_OBJECTS:ut_assert_pic>
)

Expand Down
33 changes: 30 additions & 3 deletions modules/cfe_assert/inc/cfe_assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
** Includes
*************************************************************************/
#include "common_types.h"
#include "cfe_es_api_typedefs.h"

/************************************************************************
** Type Definitions
Expand All @@ -50,19 +51,45 @@ typedef void (*CFE_Assert_StatusCallback_t)(uint8 MessageType, const char *Prefi
*************************************************************************/

/************************************************************************/
/** \brief Application Entry Point Function
/** \brief Library Init Function
**
** \par Description
** This function should be specified in the cfe_es_startup.scr file
** as part of starting this application.
** as part of loading this library.
**
** \par Assumptions, External Events, and Notes:
** None
**
** \return #CFE_SUCCESS if successful, or error code
**
*************************************************************************/
int32 CFE_Assert_LibInit(CFE_ES_LibId_t LibId);

/************************************************************************/
/** \brief Start Test
**
** \par Description
**
** \par Assumptions, External Events, and Notes:
** Must be followed by a call to CFE_Assert_ExecuteTest()
**
** \return None
**
*************************************************************************/
int32 CFE_Assert_RegisterTest(const char *TestName);

/************************************************************************/
/** \brief Execute Test and Exit
**
** \par Description
**
** \par Assumptions, External Events, and Notes:
** None
**
** \return None
**
*************************************************************************/
void CFE_Assert_AppMain(void);
void CFE_Assert_ExecuteTest(void);

/************************************************************************/
/** \brief Register a test status callback
Expand Down
13 changes: 12 additions & 1 deletion modules/cfe_assert/src/cfe_assert_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,11 +47,22 @@ void CFE_Assert_RegisterCallback(CFE_Assert_StatusCallback_t Callback)
/*
* Initialization Function for this library
*/
int32 CFE_Assert_LibInit(uint32 LibId)
int32 CFE_Assert_LibInit(CFE_ES_LibId_t LibId)
{
int32 status;

memset(&CFE_Assert_Global, 0, sizeof(CFE_Assert_Global));

UtTest_EarlyInit();
UT_BSP_Setup();

status = OS_MutSemCreate(&CFE_Assert_Global.AccessMutex, "CFE_Assert", 0);
if (status != OS_SUCCESS)
{
CFE_ES_WriteToSysLog("%s(): OS_MutSemCreate failed, rc=%d\n", __func__, (int)status);
return CFE_STATUS_EXTERNAL_RESOURCE_FAIL;
}

/*
* Start a test case for all startup logic.
*
Expand Down
2 changes: 0 additions & 2 deletions modules/cfe_assert/src/cfe_assert_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,4 @@ void UT_BSP_EndTest(const UtAssert_TestCounter_t *TestCounters)

CFE_ES_WriteToSysLog("TEST COMPLETE: %u tests Segment(s) executed\n\n",
(unsigned int)TestCounters->TestSegmentCount);

OS_TaskExit();
}
54 changes: 54 additions & 0 deletions modules/cfe_assert/src/cfe_assert_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,73 @@
*************************************************************************/
#include "common_types.h"
#include "cfe_assert.h"
#include "cfe_mission_cfg.h"

/**
* State of the CFE assert library.
*
* Note that typically tests need to be deferred until the CFE system
* reaches "operational" state. CFE assert has its own internal state
* that needs to be managed as well.
*/
typedef enum
{
CFE_Assert_State_INIT, /**< Initial state prior to CFE_Assert_LibInit() */
CFE_Assert_State_STARTUP, /**< cFE starting: successful CFE_Assert_LibInit(), but no tests run yet. */
CFE_Assert_State_ACTIVE /**< cFE operational: Normal test applications are allowed to run */
} CFE_Assert_State_Enum_t;

/************************************************************************
** Type Definitions
*************************************************************************/

typedef struct
{
CFE_Assert_State_Enum_t LibState;

/**
* Verbosity of default (syslog) output
*
* This controls the type(s) of assert messages that will be written to syslog.
* This only applies for default syslog output. Use of a status callback
* function overrides this.
*/
uint32 CurrVerbosity;

/**
* Function to invoke to report test status
*/
CFE_Assert_StatusCallback_t StatusCallback;

/**
* Mutex to control access to UtAssert structures.
*
* The UtAssert library is designed for single-threaded testing. To use it
* in a multi-threaded environment like CFE, it requires synchronization between
* apps, such that only one test app registers/runs tests at a time.
*/
osal_id_t AccessMutex;

/**
* AppID of the current UtAssert resource owner.
*
* Only one test application may use UtAssert facilities at a given time.
* This records the AppID of the current owner. It is set when AccessMutex
* is first acquired, and cleared once the tests have executed and the
* resource becomes available to another app.
*/
CFE_ES_AppId_t OwnerAppId;

/**
* Name of current test set being prepared/executed.
*
* This is set when the AccessMutex is first acquired, and cleared when
* the mutex is released. It is a free-form string to indicate the owner,
* and may or may not match the app name (i.e. test apps may implement
* more than one test set).
*/
char CurrentTestName[CFE_MISSION_MAX_API_LEN];

} CFE_Assert_Global_t;

extern CFE_Assert_Global_t CFE_Assert_Global;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,7 @@

#include "cfe.h"

#include "cfe_testrunner.h"
#include "cfe_assert.h"
#include "cfe_assert_priv.h"

#include "uttest.h"
#include "utbsp.h"
Expand All @@ -55,7 +54,7 @@
*
* The value is in milliseconds.
*/
#define CFE_TESTRUNNER_START_DELAY 4000
#define CFE_TESTRUNNER_START_DELAY 1000

/*
* This uses the message type as the event ID, because these are already
Expand All @@ -70,7 +69,7 @@ static CFE_EVS_BinFilter_t CFE_TR_EventFilters[] = {
{UTASSERT_CASETYPE_DEBUG, CFE_EVS_NO_FILTER},
};

void CFE_TR_StatusReport(uint8 MessageType, const char *Prefix, const char *OutputMessage)
void CFE_Assert_StatusReport(uint8 MessageType, const char *Prefix, const char *OutputMessage)
{
uint16 EventType;

Expand Down Expand Up @@ -101,68 +100,123 @@ void CFE_TR_StatusReport(uint8 MessageType, const char *Prefix, const char *Outp
CFE_EVS_SendEvent(MessageType, EventType, "[%5s] %s", Prefix, OutputMessage);
}

/*
* Entry point for this application
*/
void CFE_TR_AppMain(void)
int32 CFE_Assert_RegisterTest(const char *TestName)
{
int32 rc;
uint32 RunStatus;
int32 rc;
char SetupSegmentName[64];

rc = CFE_EVS_Register(CFE_TR_EventFilters, sizeof(CFE_TR_EventFilters) / sizeof(CFE_EVS_BinFilter_t),
CFE_EVS_EventFilter_BINARY);
if (rc != CFE_SUCCESS)
{
CFE_ES_WriteToSysLog("Error from CFE_EVS_Register: %08lx\n", (unsigned long)rc);
return;
return rc;
}

/*
* Delay until the system reaches "operational" state -- this is when all libs have initialized
* and all apps have reached their RunLoop.
*
* If already operational then this should return immediately. This may be the case if/when
* test apps are started via ES command.
*/
rc = CFE_ES_WaitForSystemState(CFE_ES_SystemState_OPERATIONAL, CFE_TESTRUNNER_MAX_STARTUP_WAIT);
if (rc != CFE_SUCCESS)
{
CFE_ES_WriteToSysLog("Error while waiting for OPERATIONAL state: %08lx\n", (unsigned long)rc);
return;
return rc;
}

/*
* Startup Phase has ended.
* Acquire the mutex. This is needed because UtAssert and its data structures are not thread-safe.
* Only one test app should use UtAssert facilities at a given time.
*/
UtAssert_EndTest();
rc = OS_MutSemTake(CFE_Assert_Global.AccessMutex);
if (rc != CFE_SUCCESS)
{
CFE_ES_WriteToSysLog("%s(): Error from OS_MutSemTake(): %d\n", __func__, (int)rc);
return CFE_STATUS_EXTERNAL_RESOURCE_FAIL;
}

/*
* Use the local status report function for the remainder of tests
* After acquiring mutex, record the fact that this app now "owns" the assert functions
*/
CFE_Assert_RegisterCallback(CFE_TR_StatusReport);
rc = CFE_ES_GetAppID(&CFE_Assert_Global.OwnerAppId);
if (rc != CFE_SUCCESS)
{
CFE_ES_WriteToSysLog("%s(): Error from CFE_ES_GetAppId(): %08x\n", __func__, (unsigned int)rc);
OS_MutSemGive(CFE_Assert_Global.AccessMutex);
return rc;
}

/*
* Note - in a normal app this would be a while loop,
* but is just an "if" right now as it only runs once.
*
* A future enhancement to this app might be to create an SB pipe
* and execute tests based on the receipt of a command to do so.
*
* For now, it just works in a one-shot mode to run tests that were
* registered during startup, then it self-exits.
* This means the system is operational and at least one app needs to run tests.
* Update library state accordingly. The first test app that gets to this point
* will handle this.
*/
RunStatus = CFE_ES_RunStatus_APP_RUN;
if (CFE_ES_RunLoop(&RunStatus))
if (CFE_Assert_Global.LibState != CFE_Assert_State_ACTIVE)
{
UtAssert_EndTest();
CFE_Assert_Global.LibState = CFE_Assert_State_ACTIVE;

OS_TaskDelay(CFE_TESTRUNNER_START_DELAY);
}

/*
* This resets the underlying UtAssert test list to a clean slate
*
* NOTE: this is not the ideal API here; UtAssert was originally designed to
* run one set of tests and then exit. In this environment it might be used
* repeatedly by different apps. The "EarlyInit" will wipe and reset the
* internal global, which works, but is heavy handed and doesn't account for
* the possibility that tests have been added without running.
*/
UtTest_EarlyInit();

strncpy(CFE_Assert_Global.CurrentTestName, TestName, sizeof(CFE_Assert_Global.CurrentTestName) - 1);
CFE_Assert_Global.CurrentTestName[sizeof(CFE_Assert_Global.CurrentTestName) - 1] = 0;

/* Use the local status report function for the remainder of tests */
CFE_Assert_RegisterCallback(CFE_Assert_StatusReport);

/* Start a test group in case UtAssert is used during setup phase */
snprintf(SetupSegmentName, sizeof(SetupSegmentName), "%s TEST SETUP", TestName);
UtAssert_BeginTest(SetupSegmentName);

return CFE_SUCCESS;
}

/*
* Run all registered test cases.
*/
UtTest_Run();
void CFE_Assert_ExecuteTest(void)
{
int32 rc;
CFE_ES_AppId_t AppId;

/*
* Exit the main task.
*/
RunStatus = CFE_ES_RunStatus_APP_EXIT;
/*
* Sanity check - This should only be called from the same app after CFE_Assert_RegisterTest()
*/
rc = CFE_ES_GetAppID(&AppId);
if (rc != CFE_SUCCESS || !CFE_RESOURCEID_TEST_EQUAL(AppId, CFE_Assert_Global.OwnerAppId))
{
CFE_ES_WriteToSysLog("%s(): Invalid calling context, CFE_ES_GetAppId() rc=%08x AppId=%lx, OwnerAppId=%lx\n",
__func__, (unsigned int)rc, CFE_RESOURCEID_TO_ULONG(AppId),
CFE_RESOURCEID_TO_ULONG(CFE_Assert_Global.OwnerAppId));
return;
}

CFE_ES_ExitApp(RunStatus);
UtAssert_EndTest();

OS_TaskDelay(CFE_TESTRUNNER_START_DELAY);

/* Run all registered test cases. */
UtTest_Run();

/* unregister the callback and unset the appid */
CFE_Assert_RegisterCallback(NULL);

/* Release the access mutex so the next test program can run */
rc = OS_MutSemGive(CFE_Assert_Global.AccessMutex);
if (rc != CFE_SUCCESS)
{
CFE_ES_WriteToSysLog("%s(): Error from OS_MutSemGive(): %d\n", __func__, (int)rc);
}
}
8 changes: 4 additions & 4 deletions modules/cfe_testcase/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
include_directories("${CFE_ASSERT_SOURCE_DIR}/inc")
include_directories("${UT_ASSERT_SOURCE_DIR}/inc")

# Filenames based on doxygen groups.
# Filenames based on doxygen groups.
# Create the app module
add_cfe_app(cfe_testcase
src/cfe_test.c
src/es_info_test.c
)

# register the dependency on cfe_assert
add_cfe_app_dependency(cfe_testcase cfe_assert)
Loading