Skip to content

Commit

Permalink
common: core_log_default_function UT implementation
Browse files Browse the repository at this point in the history
Signed-off-by: Tomasz Gromadzki <tomasz.gromadzki@intel.com>
  • Loading branch information
grom72 committed Feb 29, 2024
1 parent 1fad527 commit 8d087a3
Show file tree
Hide file tree
Showing 2 changed files with 226 additions and 72 deletions.
16 changes: 14 additions & 2 deletions src/test/core_log_default_function/TESTS.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,20 @@ def run(self, ctx):


class TEST0(CORE_LOG):
test_case = 'test_1'
test_case = 'testDefaultFunction'


class TEST1(CORE_LOG):
test_case = 'test_CORE_LOG_TRESHOLD'
test_case = 'testDefaultFunctionBadFileInfo'


class TEST2(CORE_LOG):
test_case = 'testDefaultFunctionShortFileName'


class TEST3(CORE_LOG):
test_case = 'testDefaultFunctionNoFileName'


class TEST4(CORE_LOG):
test_case = 'testDefaultFunctionBadTimestamp'
282 changes: 212 additions & 70 deletions src/test/core_log_default_function/core_log_default_function.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,125 +15,266 @@

#define NO_ARGS_CONSUMED 0

// #define CORE_LOG_UT_MAX_BUFF_SIZE 4096
#define MESSAGE "Test message"
#define TIMESTAMP "DUMMY TIMESTAMP"
#define FILE_NAME "dummy.c"
#define FILE_NAME_W_PATH "dummy_path/dummy_path/" FILE_NAME
#define FILE_NAME_ERROR "[file info error]: "
#define FUNCTION_NAME "dummy_func()"

static const char log_level_names[CORE_LOG_LEVEL_MAX][9] = {
[CORE_LOG_LEVEL_HARK] = "*HARK* ",
[CORE_LOG_LEVEL_FATAL] = "*FATAL* ",
[CORE_LOG_LEVEL_ERROR] = "*ERROR* ",
[CORE_LOG_LEVEL_WARNING] = "*WARN* ",
[CORE_LOG_LEVEL_NOTICE] = "*NOTE* ",
[CORE_LOG_LEVEL_INFO] = "*INFO* ",
[CORE_LOG_LEVEL_DEBUG] = "*DEBUG* ",
};

static const int log_level_syslog_severity[] = {
[CORE_LOG_LEVEL_HARK] = LOG_NOTICE,
[CORE_LOG_LEVEL_FATAL] = LOG_CRIT,
[CORE_LOG_LEVEL_ERROR] = LOG_ERR,
[CORE_LOG_LEVEL_WARNING] = LOG_WARNING,
[CORE_LOG_LEVEL_NOTICE] = LOG_NOTICE,
[CORE_LOG_LEVEL_INFO] = LOG_INFO,
[CORE_LOG_LEVEL_DEBUG] = LOG_DEBUG,
};

static struct {
char *ret;
}Strchr_context;

FUNC_MOCK(strrchr, char *, const char *__s, int __c)
FUNC_MOCK_RUN_DEFAULT {
UT_ASSERTeq(__c, '/');
return Strchr_context.ret;
}
FUNC_MOCK_END

static struct {
const char *file_name;
int line_no;
const char *function_name;
char *file_info_buffer;
int forceError;
}Snprintf_context;

FUNC_MOCK(snprintf, int, char *__restrict __s, size_t __maxlen,
const char *__restrict __format, ...)
/* file info */
FUNC_MOCK_RUN(0) {
/* second parameter after __format equal to -1 causes negative value return */
va_list arg;
va_start(arg, __format);
UT_ASSERTeq(strcmp("%s: %3d: %s: ", __format), 0);
strncpy(__s, "DUMMY FILE_INFO", __maxlen);
return 10;
UT_ASSERTstreq(__format, "%s: %3d: %s: ");
char *file_name = va_arg(arg, char *);
UT_ASSERTstreq(file_name, Snprintf_context.file_name);
int line_no = va_arg(arg, int);
if (line_no >= 0)
UT_ASSERTeq(line_no, Snprintf_context.line_no);
else
return -1;
char *function_name = va_arg(arg, char *);
UT_ASSERTstreq(function_name, Snprintf_context.function_name);
if (Snprintf_context.file_info_buffer)
strncpy(__s, Snprintf_context.file_info_buffer,
__maxlen);
va_end(arg);
return __maxlen;
}
/* get time prefix */
FUNC_MOCK_RUN(1) {
va_list arg;
va_start(arg, __format);
UT_ASSERTeq(strcmp("%s.%06ld ", __format), 0);
strncpy(__s, "DUMMY TIMESTAMP ", __maxlen);
va_end(arg);
}
FUNC_MOCK_RUN(2) {
va_list arg;
va_start(arg, __format);
UT_OUT("%s", __format);
// UT_ASSERTeq(strcmp("%s[%ld] %s%s%s\n", __format), 0);
return vsnprintf(__s, __maxlen, __format, arg);
va_end(arg);

UT_ASSERTstreq(__format, "%s.%06ld ");
if (Snprintf_context.forceError) {
memset(__s, 'x', __maxlen);
}
else
strncpy(__s, TIMESTAMP, __maxlen);
return __maxlen;
}
FUNC_MOCK_RUN_DEFAULT {
va_list arg;
va_start(arg, __format);
UT_OUT("%d", RCOUNTER(snprintf));
return vsnprintf(__s, __maxlen, __format, arg);
UT_OUT("sprintf - %d: %s", RCOUNTER(snprintf), __format);
UT_FATAL("Unknown sprintf");
va_end(arg);
}
FUNC_MOCK_END

static int Syslog_no_of_calls;
static char Syslog_log_level_name[9] = "";
static const char *Syslog_message;
static struct {
int no_of_calls;
int __pri;
const char *log_level_name;
char *file_info;
const char *message;
}Syslog_context;

FUNC_MOCK(syslog, void, int __pri, const char *__fmt, ...)
FUNC_MOCK_RUN_DEFAULT {
Syslog_context.no_of_calls++;
UT_ASSERTeq(__pri, Syslog_context.__pri);
UT_ASSERTeq(strcmp("%s%s%s", __fmt), 0);
va_list arg;
va_start(arg, __fmt);
UT_ASSERTeq(__pri, LOG_ERR);
UT_ASSERTeq(strcmp("%s%s%s", __fmt), 0);
char *log_level_name = va_arg(arg, char *);
UT_ASSERTeq(strncmp(Syslog_log_level_name, &log_level_name[1],
strlen(Syslog_log_level_name)), 0);
UT_ASSERTstreq(log_level_name, Syslog_context.log_level_name);
char *file_info = va_arg(arg, char *);
UT_ASSERTeq(strcmp("DUMMY FILE_INFO", file_info), 0);
if (Syslog_context.file_info)
UT_ASSERTstreq(file_info, Syslog_context.file_info);
char *message = va_arg(arg, char *);
UT_ASSERTeq(strcmp(Syslog_message, message), 0);
if (Syslog_context.message)
UT_ASSERTstreq(message, Syslog_context.message);
va_end(arg);
Syslog_no_of_calls ++;
}
FUNC_MOCK_END

#define CORE_LOG_UT_MESSAGE "Test message"
static struct {
int no_of_calls;
char *times_stamp;
} Fprintf_context;

#if 0
#define CORE_LOG_UT_MESSAGE_LONG \
"Test message long 20Test message long 40Test message long 60" \
"Test message long 80Test message long100Test message long120" \
"Test message long140Test message long160Test message long180" \
"Test message long200Test message long220Test message long240" \
"Test message long260Test message long280Test message long300"
FUNC_MOCK(fprintf, int, FILE *__restrict __stream, \
const char *__restrict __fmt, ...)
FUNC_MOCK_RUN_DEFAULT {
UT_ASSERTeq(__stream, stderr);
Fprintf_context.no_of_calls++;
if (Fprintf_context.times_stamp) {
va_list arg;
va_start(arg, __fmt);
char *times_tamp = va_arg(arg, char *);
UT_ASSERTstreq(times_tamp, Fprintf_context.times_stamp);
va_end(arg);
}
return 0;
}
FUNC_MOCK_END

#define CORE_LOG_UT_MESSAGE_TOO_LONG CORE_LOG_UT_MESSAGE_LONG \
"Test message long 321"
#endif
/* Tsts helpers */
static void
TEST_SETUP(const char *message)
{
Syslog_context.message = message;
}

/* tests */
static void
TEST_STEP_SETUP(enum core_log_level LEVEL, const char *file_name, int line_no,
const char *function_name)
{
Syslog_context.no_of_calls = 0;
Syslog_context.__pri = log_level_syslog_severity[LEVEL];
Syslog_context.log_level_name = log_level_names[LEVEL];
FUNC_MOCK_RCOUNTER_SET(snprintf, 0);
Snprintf_context.file_name = file_name;
Snprintf_context.line_no = line_no;
Snprintf_context.function_name = function_name;
Snprintf_context.forceError = 0;
Fprintf_context.no_of_calls = 0;
Fprintf_context.times_stamp = NULL;

#define TEST_SETUP(message_to_test) \
Syslog_message = message_to_test;
}

#define TEST_STEP_SETUP(level) \
Syslog_no_of_calls = 0; \
strcpy(Syslog_log_level_name, #level)
#define TEST_STEP_CHECK(FPRINTF_CALLED) \
do { \
UT_ASSERTeq(Syslog_context.no_of_calls, 1); \
UT_ASSERTeq(Fprintf_context.no_of_calls, FPRINTF_CALLED); \
} while (0)

#define TEST_STEP_CHECK() \
UT_ASSERTeq(Syslog_no_of_calls, 1)
/* basic tests with a normal message pass through */
static int
testDefaultFunction(const struct test_case *tc, int argc, char *argv[])
{
core_log_set_threshold(CORE_LOG_THRESHOLD_AUX, CORE_LOG_LEVEL_DEBUG);
TEST_SETUP(MESSAGE);
for (enum core_log_level treshold = CORE_LOG_LEVEL_HARK;
treshold < CORE_LOG_LEVEL_MAX; treshold++) {
core_log_set_threshold(CORE_LOG_THRESHOLD_AUX, treshold);
for (enum core_log_level level = CORE_LOG_LEVEL_HARK;
level < CORE_LOG_LEVEL_MAX; level++) {

#define TEST_STEP(LEVEL, MESSAGE) \
TEST_STEP_SETUP(LEVEL); \
core_log_default_function(NULL, CORE_LOG_LEVEL_ERROR, \
"file name", 123, "function_name", MESSAGE); \
TEST_STEP_CHECK()
TEST_STEP_SETUP(level, FILE_NAME, 0, FUNCTION_NAME);
core_log_default_function(NULL, level, FILE_NAME_W_PATH,
0, FUNCTION_NAME, MESSAGE);
TEST_STEP_CHECK(level == CORE_LOG_LEVEL_HARK? 0 :
level > treshold? 0 : 1);
}
}
return NO_ARGS_CONSUMED;
}

/* basic tests with a normal message */
/* test to check that information about bad file is printed */
static int
test_1(const struct test_case *tc, int argc, char *argv[])
testDefaultFunctionBadFileInfo(const struct test_case *tc, int argc,
char *argv[])
{
TEST_SETUP(CORE_LOG_UT_MESSAGE);
TEST_STEP(ERROR, CORE_LOG_UT_MESSAGE);
core_log_set_threshold(CORE_LOG_THRESHOLD_AUX, CORE_LOG_LEVEL_DEBUG);
TEST_SETUP(MESSAGE);
TEST_STEP_SETUP(CORE_LOG_LEVEL_DEBUG, FILE_NAME_ERROR, 0,
FUNCTION_NAME);
core_log_default_function(NULL, CORE_LOG_LEVEL_DEBUG, FILE_NAME_W_PATH,
-1, FUNCTION_NAME, MESSAGE);
TEST_STEP_CHECK(1);

return NO_ARGS_CONSUMED;
}

/* test to check that core_log_to_last() works w/ every thresholds */
/* test to check that short file name (w/o path) is properly printed */
static int
test_CORE_LOG_TRESHOLD(const struct test_case *tc, int argc, char *argv[])
testDefaultFunctionShortFileName(const struct test_case *tc, int argc,
char *argv[])
{
// core_log_set_function(CORE_LOG_USE_DEFAULT_FUNCTION, NULL);
TEST_SETUP(CORE_LOG_UT_MESSAGE);
for (enum core_log_level level = CORE_LOG_LEVEL_HARK;
level < CORE_LOG_LEVEL_MAX; level ++) {
core_log_set_threshold(CORE_LOG_THRESHOLD, level);
/* must be in one line for proper __LINE__ value */
}
core_log_set_threshold(CORE_LOG_THRESHOLD_AUX, CORE_LOG_LEVEL_DEBUG);
TEST_SETUP(MESSAGE);
TEST_STEP_SETUP(CORE_LOG_LEVEL_DEBUG, FILE_NAME, 1, FUNCTION_NAME);
core_log_default_function(NULL, CORE_LOG_LEVEL_DEBUG, FILE_NAME, 1,
FUNCTION_NAME, MESSAGE);
TEST_STEP_CHECK(1);

return NO_ARGS_CONSUMED;
}

/* test to check no fileinfo when filename is NULL */
static int
testDefaultFunctionNoFileName(const struct test_case *tc, int argc,
char *argv[])
{
core_log_set_threshold(CORE_LOG_THRESHOLD_AUX, CORE_LOG_LEVEL_DEBUG);
TEST_SETUP(MESSAGE);
TEST_STEP_SETUP(CORE_LOG_LEVEL_DEBUG, "", 1, FUNCTION_NAME);
/* skip file_info snprintf() */
FUNC_MOCK_RCOUNTER_SET(snprintf, 1);
core_log_default_function(NULL, CORE_LOG_LEVEL_DEBUG, NULL, 1,
FUNCTION_NAME, MESSAGE);
TEST_STEP_CHECK(1);

return NO_ARGS_CONSUMED;
}

/* test to check timestamp error */
static int
testDefaultFunctionBadTimestamp(const struct test_case *tc, int argc,
char *argv[])
{
core_log_set_threshold(CORE_LOG_THRESHOLD_AUX, CORE_LOG_LEVEL_DEBUG);
TEST_SETUP(MESSAGE);
TEST_STEP_SETUP(CORE_LOG_LEVEL_DEBUG, FILE_NAME, 1, FUNCTION_NAME);
Snprintf_context.forceError = 1;
Fprintf_context.times_stamp = "[time error] ";
/* skip file_info snprintf() */
core_log_default_function(NULL, CORE_LOG_LEVEL_DEBUG, FILE_NAME, 1,
FUNCTION_NAME, MESSAGE);
TEST_STEP_CHECK(1);

return NO_ARGS_CONSUMED;
}

static struct test_case test_cases[] = {
TEST_CASE(test_1),
TEST_CASE(test_CORE_LOG_TRESHOLD),
TEST_CASE(testDefaultFunction),
TEST_CASE(testDefaultFunctionBadFileInfo),
TEST_CASE(testDefaultFunctionShortFileName),
TEST_CASE(testDefaultFunctionNoFileName),
TEST_CASE(testDefaultFunctionBadTimestamp),
};

/* force the test to use the default logging function */
Expand All @@ -144,7 +285,8 @@ int
main(int argc, char *argv[])
{
START(argc, argv, "core_log_default_function");

// if (__builtin_constant_p("cnd"))
// UT_ASSERT(0);
TEST_CASE_PROCESS(argc, argv, test_cases, ARRAY_SIZE(test_cases));

DONE(NULL);
Expand Down

0 comments on commit 8d087a3

Please sign in to comment.