Skip to content

Commit

Permalink
Merge pull request #1624 from jphickey/fix-596-ut-report-macros
Browse files Browse the repository at this point in the history
Fix nasa#596, nasa#470, scrub all UT_Report calls
  • Loading branch information
jphickey committed Jun 23, 2021
2 parents 2527452 + 442634d commit 0701923
Show file tree
Hide file tree
Showing 21 changed files with 3,114 additions and 4,395 deletions.
153 changes: 94 additions & 59 deletions modules/core_private/ut-stubs/inc/ut_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -235,43 +235,6 @@ void UT_ResetCDS(void);
/* Reset pool buffer array index */
void UT_ResetPoolBufferIndex(void);

/*****************************************************************************/
/**
** \brief Output single test's pass/fail status
**
** \par Description
** Out the results and description for a single test, and update the
** pass/fail counters.
**
** \par Assumptions, External Events, and Notes:
**
** \param[in] test Equals 0 if the test failed; non-zero if the
** test passed
**
** \param[in] fun_name Character string pointer to the name of the function
** being tested
**
** \param[in] info Character string pointer to the description of the test
**
** \returns
** This function does not return a value.
**
******************************************************************************/
void UT_Report(const char *file, uint32 line, bool test, const char *fun_name, const char *info);

/*****************************************************************************/
/**
** \brief Test pass/fail summary
**
** \par Description
** Output total number of tests passed and failed.
**
** \returns
** This function does not return a value.
**
******************************************************************************/
void UT_ReportFailures(void);

/*****************************************************************************/
/**
** \brief Send a message via the software bus
Expand Down Expand Up @@ -648,6 +611,44 @@ void UT_AddSubTest(void (*Test)(void), void (*Setup)(void), void (*Teardown)(voi
bool CFE_UtAssert_SuccessCheck_Impl(CFE_Status_t Status, UtAssert_CaseType_t CaseType, const char *File, uint32 Line,
const char *Text);

/*****************************************************************************/
/**
** \brief Helper function for message check (printf/syslog) verifications
**
** \par Description
** This helper function wraps the normal UtAssert function, intended for verifying
** CFE API calls that are expected to generate printf or syslog messages. This
** includes the actual message in the log, but scrubs it for newlines and other
** items that may affect the ability to parse the log file via a script.
**
** \par Assumptions, External Events, and Notes:
** None
**
** \returns Test pass status, returns true if status was successful, false if it failed.
**
******************************************************************************/
bool CFE_UtAssert_MessageCheck_Impl(bool Status, const char *File, uint32 Line, const char *Desc,
const char *FormatString);

/*****************************************************************************/
/**
** \brief Helper function for string buffer check verifications
**
** \par Description
** This helper function wraps the normal UtAssert function, intended for verifying
** the contents of string buffer(s). This also includes the actual message in the log,
** but scrubs it for newlines and other items that may affect the ability to parse
** the log file via a script.
**
** \par Assumptions, External Events, and Notes:
** None
**
** \returns Test pass status, returns true if status was successful, false if it failed.
**
******************************************************************************/
bool CFE_UtAssert_StringBufCheck_Impl(const char *String1, size_t String1Max, const char *String2, size_t String2Max,
const char *File, uint32 Line);

/*****************************************************************************/
/**
** \brief Helper function for generic unsigned integer value checks
Expand Down Expand Up @@ -718,22 +719,6 @@ bool CFE_UtAssert_GenericSignedCompare_Impl(int32 ActualValue, CFE_UtAssert_Comp
******************************************************************************/
#define CFE_UtAssert_SUCCESS(FN) CFE_UtAssert_SuccessCheck_Impl(FN, UTASSERT_CASETYPE_FAILURE, __FILE__, __LINE__, #FN)

/*****************************************************************************/
/**
** \brief Asserts the specific status code from the function being tested.
**
** \par Description
** The core of each unit test is the execution of the function being tested.
** This function and macro should be used to test for a specific status code
** from a function (typically an error case).
**
** \par Assumptions, External Events, and Notes:
** None
**
******************************************************************************/
#define CFE_UtAssert_EQUAL(FN, EXP) \
CFE_UtAssert_GenericSignedCompare_Impl(FN, CFE_UtAssert_Compare_EQ, EXP, __FILE__, __LINE__, "", #FN, #EXP)

/*****************************************************************************/
/**
** \brief Asserts the expression/function evaluates as logically true
Expand Down Expand Up @@ -860,9 +845,8 @@ bool CFE_UtAssert_GenericSignedCompare_Impl(int32 ActualValue, CFE_UtAssert_Comp
** is potentially useful to confirm a specific code path was followed.
**
******************************************************************************/
#define CFE_UtAssert_SYSLOG(str) \
CFE_UtAssert_GenericSignedCompare_Impl(UT_SyslogIsInHistory(str), CFE_UtAssert_Compare_GT, 0, __FILE__, __LINE__, \
"Syslog generated: ", #str, "")
#define CFE_UtAssert_SYSLOG(str) \
CFE_UtAssert_MessageCheck_Impl(UT_SyslogIsInHistory(str), __FILE__, __LINE__, "Syslog generated: ", str)

/*****************************************************************************/
/**
Expand All @@ -876,9 +860,8 @@ bool CFE_UtAssert_GenericSignedCompare_Impl(int32 ActualValue, CFE_UtAssert_Comp
** is potentially useful to confirm a specific code path was followed.
**
******************************************************************************/
#define CFE_UtAssert_PRINTF(str) \
CFE_UtAssert_GenericSignedCompare_Impl(UT_PrintfIsInHistory(str), CFE_UtAssert_Compare_GT, 0, __FILE__, __LINE__, \
"Printf generated: ", #str, "")
#define CFE_UtAssert_PRINTF(str) \
CFE_UtAssert_MessageCheck_Impl(UT_PrintfIsInHistory(str), __FILE__, __LINE__, "Printf generated: ", str)

/*****************************************************************************/
/**
Expand Down Expand Up @@ -927,4 +910,56 @@ bool CFE_UtAssert_GenericSignedCompare_Impl(int32 ActualValue, CFE_UtAssert_Comp
CFE_RESOURCEID_TO_ULONG(id2), __FILE__, __LINE__, \
"Resource ID Check: ", #id1, #id2)

/*****************************************************************************/
/**
** \brief Macro to check CFE memory size/offset for equality
**
** \par Description
** A macro that checks two memory offset/size values for equality.
**
** \par Assumptions, External Events, and Notes:
** This is a simple unsigned comparison which logs the values as hexadecimal
**
******************************************************************************/
#define CFE_UtAssert_MEMOFFSET_EQ(off1, off2) \
CFE_UtAssert_GenericUnsignedCompare_Impl(off1, CFE_UtAssert_Compare_EQ, off2, __FILE__, __LINE__, \
"Offset Check: ", #off1, #off2)

/*****************************************************************************/
/**
** \brief Macro to check CFE message ID for equality
**
** \par Description
** A macro that checks two message ID values for equality.
**
** \par Assumptions, External Events, and Notes:
** The generic #UtAssert_UINT32_EQ check should not be used, as CFE_SB_MsgId_t values
** and integers may not be interchangable with strict type checking.
**
******************************************************************************/
#define CFE_UtAssert_MSGID_EQ(mid1, mid2) \
CFE_UtAssert_GenericUnsignedCompare_Impl(CFE_SB_MsgIdToValue(mid1), CFE_UtAssert_Compare_EQ, \
CFE_SB_MsgIdToValue(mid2), __FILE__, __LINE__, "MsgId Check: ", #mid1, \
#mid2)

/*****************************************************************************/
/**
** \brief Macro to check string buffers for equality
**
** \par Description
** A macro that checks two string buffers for equality. Both buffer maximum sizes are explicitly
** specified, so that strings may reside in a fixed length buffer. The function will never
** check beyond the specified length, regardless of termination.
**
** \par Assumptions, External Events, and Notes:
** The generic #UtAssert_StrCmp macro requires both arguments to be NULL terminated. This also
** includes the actual string in the log, but filters embedded newlines to keep the log clean.
**
** If the string arguments are guaranteed to be NULL terminated and/or the max size is
** not known, then the SIZE_MAX constant may be passed for the respective string.
**
******************************************************************************/
#define CFE_UtAssert_STRINGBUF_EQ(str1, size1, str2, size2) \
CFE_UtAssert_StringBufCheck_Impl(str1, size1, str2, size2, __FILE__, __LINE__)

#endif /* UT_SUPPORT_H */
137 changes: 129 additions & 8 deletions modules/core_private/ut-stubs/src/ut_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -197,14 +197,6 @@ void UT_ResetPoolBufferIndex(void)
UT_SetDataBuffer(UT_KEY(CFE_ES_GetPoolBuf), &UT_CFE_ES_MemoryPool, sizeof(UT_CFE_ES_MemoryPool), false);
}

/*
** Output single test's pass/fail status
*/
void UT_Report(const char *file, uint32 line, bool test, const char *fun_name, const char *info)
{
UtAssertEx(test, UtAssert_GetContext(), file, line, "%s - %s", fun_name, info);
}

/*
** Calls the specified "task pipe" function
**
Expand Down Expand Up @@ -826,3 +818,132 @@ bool CFE_UtAssert_GenericSignedCompare_Impl(int32 ActualValue, CFE_UtAssert_Comp
return UtAssertEx(Result, UTASSERT_CASETYPE_FAILURE, File, Line, "%s%s (%ld) %s %s (%ld)", Desc, ActualText,
(long)ActualValue, CFE_UtAssert_GetOpText(CompareType), ReferenceText, (long)ReferenceValue);
}

bool CFE_UtAssert_MessageCheck_Impl(bool Status, const char *File, uint32 Line, const char *Desc,
const char *FormatString)
{
char ScrubbedFormat[256];
const char *EndPtr;
size_t FormatLen;

/* Locate the actual end of the string, but limited to length of local buffer */
/* Reserve two extra chars for quotes */
EndPtr = memchr(FormatString, 0, sizeof(ScrubbedFormat) - 2);
if (EndPtr != NULL)
{
FormatLen = EndPtr - FormatString;
}
else
{
FormatLen = sizeof(ScrubbedFormat) - 3;
}

/* Check for a newline within that range, and if present, end the string there instead */
EndPtr = memchr(FormatString, '\n', FormatLen);
if (EndPtr != NULL)
{
FormatLen = EndPtr - FormatString;
}

/* Need to make a copy, as the input string is "const" */
ScrubbedFormat[0] = '\'';
memcpy(&ScrubbedFormat[1], FormatString, FormatLen);
ScrubbedFormat[FormatLen] = '\'';
ScrubbedFormat[FormatLen + 1] = 0;

return CFE_UtAssert_GenericSignedCompare_Impl(Status, CFE_UtAssert_Compare_GT, 0, File, Line, Desc, ScrubbedFormat,
"");
}

bool CFE_UtAssert_StringBufCheck_Impl(const char *String1, size_t String1Max, const char *String2, size_t String2Max,
const char *File, uint32 Line)
{
char ScrubbedString1[256];
char ScrubbedString2[256];
const char *EndPtr1;
const char *EndPtr2;
size_t FormatLen1;
size_t FormatLen2;
bool Result;

/* Locate the actual end of both strings */
if (String1 == NULL)
{
EndPtr1 = NULL;
}
else
{
EndPtr1 = memchr(String1, 0, String1Max);
}

if (EndPtr1 != NULL)
{
FormatLen1 = EndPtr1 - String1;
}
else
{
FormatLen1 = String1Max;
}

if (String2 == NULL)
{
EndPtr2 = NULL;
}
else
{
EndPtr2 = memchr(String2, 0, String2Max);
}

if (EndPtr2 != NULL)
{
FormatLen2 = EndPtr2 - String2;
}
else
{
FormatLen2 = String2Max;
}

if (FormatLen1 != FormatLen2)
{
/* This means the strings have different termination/length, and therefore must not be equal (content doesn't
* matter) */
Result = false;
}
else if (FormatLen1 == 0)
{
/* Two empty strings are considered equal */
Result = true;
}
else
{
/* If the effective lengths are the same, use memcmp to check content */
Result = (memcmp(String1, String2, FormatLen1) == 0);
}

/* Now make "safe" copies of the strings */
/* Check for a newline within the string, and if present, end the string there instead */
if (FormatLen1 > 0)
{
EndPtr1 = memchr(String1, '\n', FormatLen1);
if (EndPtr1 != NULL)
{
FormatLen1 = EndPtr1 - String1;
}
memcpy(ScrubbedString1, String1, FormatLen1);
}
ScrubbedString1[FormatLen1] = 0;

if (FormatLen2 > 0)
{
EndPtr2 = memchr(String2, '\n', FormatLen2);
if (EndPtr2 != NULL)
{
FormatLen2 = EndPtr2 - String2;
}
memcpy(ScrubbedString2, String2, FormatLen2);
}
ScrubbedString2[FormatLen2] = 0;

return UtAssertEx(Result, UTASSERT_CASETYPE_FAILURE, File, Line, "String: \'%s\' == \'%s\'", ScrubbedString1,
ScrubbedString2);
}
Loading

0 comments on commit 0701923

Please sign in to comment.