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 #1625, add test log file #1633

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
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
36 changes: 36 additions & 0 deletions modules/cfe_assert/inc/cfe_assert.h
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,40 @@ void CFE_Assert_ExecuteTest(void);
*/
void CFE_Assert_RegisterCallback(CFE_Assert_StatusCallback_t Callback);

/************************************************************************/
/** \brief Start a test log file
*
* \par Description
* Sets the name of a file which will store the results of all tests
* The output is saved to the log file in addition to the normal callback
* function provided in CFE_Assert_RegisterCallback().
*
* \par Assumptions, External Events, and Notes:
* Only the test outputs are saved to this log file, thereby providing
* a file that can be checked by a script. During test operation, the
* file is first created with a "tmp" extension, and then will be renamed
* to the name given here once the test is complete.
*
* \param[in] Filename Name of log file to write
*
* \return CFE Status code
* \retval #CFE_SUCCESS if file was opened successfully
*
*/
int32 CFE_Assert_OpenLogFile(const char *Filename);

/************************************************************************/
/** \brief Complete a test log file
*
* \par Description
* Closes the test log file that was previously opened via CFE_Assert_OpenLogFile
*
* \par Assumptions, External Events, and Notes:
* This should be called once test cases have completed
*
* \return None
*
*/
void CFE_Assert_CloseLogFile(void);

#endif /* CFE_ASSERT_H */
60 changes: 60 additions & 0 deletions modules/cfe_assert/src/cfe_assert_init.c
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,66 @@ void CFE_Assert_RegisterCallback(CFE_Assert_StatusCallback_t Callback)
CFE_Assert_Global.StatusCallback = Callback;
}

/*
* Opens a log file to "tee" the test output to
*/
int32 CFE_Assert_OpenLogFile(const char *Filename)
{
int32 Status;
char * Ext;
size_t NameLen;

strncpy(CFE_Assert_Global.LogFileFinal, Filename, sizeof(CFE_Assert_Global.LogFileFinal) - 1);
CFE_Assert_Global.LogFileFinal[sizeof(CFE_Assert_Global.LogFileFinal) - 1] = 0;

strncpy(CFE_Assert_Global.LogFileTemp, Filename, sizeof(CFE_Assert_Global.LogFileTemp) - 1);
CFE_Assert_Global.LogFileTemp[sizeof(CFE_Assert_Global.LogFileTemp) - 1] = 0;

Ext = strrchr(CFE_Assert_Global.LogFileTemp, '.');
if (Ext == NULL)
{
NameLen = strlen(CFE_Assert_Global.LogFileTemp);
}
else
{
NameLen = Ext - CFE_Assert_Global.LogFileTemp;
}

/* Use a ".tmp" file while actively writing, will rename at the end */
if (NameLen > (sizeof(CFE_Assert_Global.LogFileTemp) - 5))
{
NameLen = sizeof(CFE_Assert_Global.LogFileTemp) - 5;
}
strcpy(&CFE_Assert_Global.LogFileTemp[NameLen], ".tmp");

Status = OS_OpenCreate(&CFE_Assert_Global.LogFileDesc, CFE_Assert_Global.LogFileTemp,
OS_FILE_FLAG_CREATE | OS_FILE_FLAG_TRUNCATE, OS_WRITE_ONLY);
if (Status != OS_SUCCESS)
{
CFE_ES_WriteToSysLog("%s: Failed to open %s, rc=%d\n", __func__, CFE_Assert_Global.LogFileTemp, (int)Status);
return CFE_STATUS_EXTERNAL_RESOURCE_FAIL;
}

return CFE_SUCCESS;
}

/*
* Closes the log file
* This also renames the intermediate log file to its final name
*/
void CFE_Assert_CloseLogFile(void)
{
if (OS_ObjectIdDefined(CFE_Assert_Global.LogFileDesc))
{
OS_close(CFE_Assert_Global.LogFileDesc);
OS_rename(CFE_Assert_Global.LogFileTemp, CFE_Assert_Global.LogFileFinal);
}

CFE_Assert_Global.LogFileDesc = OS_OBJECT_ID_UNDEFINED;
CFE_Assert_Global.LogFileTemp[0] = 0;
CFE_Assert_Global.LogFileFinal[0] = 0;
}

/*
* Initialization Function for this library
*/
Expand Down
13 changes: 13 additions & 0 deletions modules/cfe_assert/src/cfe_assert_io.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,14 @@ void UT_BSP_SysLogStatusReport(uint8 MessageType, const char *Prefix, const char
}
}

void UT_BSP_WriteLogFile(osal_id_t FileDesc, uint8 MessageType, const char *Prefix, const char *OutputMessage)
{
char LogFileBuffer[CFE_ASSERT_MAX_LOG_LINE_LENGTH];

snprintf(LogFileBuffer, sizeof(LogFileBuffer), "[%5s] %s\n", Prefix, OutputMessage);
OS_write(FileDesc, LogFileBuffer, strlen(LogFileBuffer));
}

void UT_BSP_DoText(uint8 MessageType, const char *OutputMessage)
{
const char * Prefix;
Expand Down Expand Up @@ -139,6 +147,11 @@ void UT_BSP_DoText(uint8 MessageType, const char *OutputMessage)

StatusCallback(MessageType, Prefix, OutputMessage);

if (OS_ObjectIdDefined(CFE_Assert_Global.LogFileDesc))
{
UT_BSP_WriteLogFile(CFE_Assert_Global.LogFileDesc, MessageType, Prefix, OutputMessage);
}

/*
* If any ABORT (major failure) message is thrown,
* then call a BSP-provided routine to stop the test and possibly dump a core
Expand Down
30 changes: 30 additions & 0 deletions modules/cfe_assert/src/cfe_assert_priv.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,17 @@
*************************************************************************/
#include "common_types.h"
#include "cfe_assert.h"
#include "osconfig.h"
#include "cfe_mission_cfg.h"

/**
* Maximum length of a single line in the test log file
*
* Note this only applies to the log file. The user callback
* may have other limitations.
*/
#define CFE_ASSERT_MAX_LOG_LINE_LENGTH 512

/**
* State of the CFE assert library.
*
Expand Down Expand Up @@ -77,6 +86,27 @@ typedef struct
*/
CFE_Assert_StatusCallback_t StatusCallback;

/**
* Name of final log file for test results
*
* The temporary file will be renamed to this at the end of testing
*/
char LogFileFinal[OS_MAX_PATH_LEN];

/**
* Name of temporary log file for test results
*
* This is the file name that is actively written during the test
*/
char LogFileTemp[OS_MAX_PATH_LEN];

/**
* Log File descriptor
*
* Should be set to OS_OBJECT_ID_UNDEFINED if no log file is open
*/
osal_id_t LogFileDesc;

/**
* Mutex to control access to UtAssert structures.
*
Expand Down
1 change: 1 addition & 0 deletions modules/cfe_assert/src/cfe_assert_runner.c
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ void CFE_Assert_ExecuteTest(void)
/* unregister the callback and unset the appid */
UT_BSP_Lock();
CFE_Assert_RegisterCallback(NULL);
CFE_Assert_CloseLogFile();
CFE_Assert_Global.OwnerAppId = CFE_ES_APPID_UNDEFINED;
UT_BSP_Unlock();
}
1 change: 1 addition & 0 deletions modules/cfe_testcase/src/cfe_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ void CFE_TestMain(void)
* state and gets ownership of the UtAssert subsystem
*/
CFE_Assert_RegisterTest("CFE API");
CFE_Assert_OpenLogFile(CFE_ASSERT_LOG_FILE_NAME);

/*
* Register test cases in UtAssert
Expand Down
9 changes: 9 additions & 0 deletions modules/cfe_testcase/src/cfe_test.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,15 @@
#include "uttest.h"
#include "utassert.h"

/**
* Name of log file to write
*
* This file captures all of the test results, independently of the
* events generated during the test run. The file can be used as part
* of scripted tests and/or capturing test artifacts.
*/
#define CFE_ASSERT_LOG_FILE_NAME "/cf/cfe_test.log"

/* Compare two Resource IDs */
#define UtAssert_ResourceID_EQ(actual, expect) \
UtAssert_True(CFE_RESOURCEID_TEST_EQUAL(actual, expect), "%s (%lu) == %s (%lu)", #actual, \
Expand Down