Skip to content

Commit

Permalink
Partial nasa#596, UtAssert macros for ES test
Browse files Browse the repository at this point in the history
Update ES coverage test to use preferred macros.

Adds dedicated assert macros for checking fixed-length
string buffers, and for checking memory offsets.

Also adds an improved implemention of the syslog/printf check
which filters out newlines (keeps log more parseable).
  • Loading branch information
jphickey committed Jun 22, 2021
1 parent 99f481d commit 800f501
Show file tree
Hide file tree
Showing 3 changed files with 907 additions and 1,249 deletions.
83 changes: 77 additions & 6 deletions modules/core_private/ut-stubs/inc/ut_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -648,6 +648,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 @@ -860,9 +898,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 +913,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 +963,39 @@ 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 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 */
129 changes: 129 additions & 0 deletions modules/core_private/ut-stubs/src/ut_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -826,3 +826,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 800f501

Please sign in to comment.