Make max log level for log_sink_callback configurable (#193)

This commit is contained in:
Matt Durak 2024-03-06 10:02:19 -08:00 коммит произвёл GitHub
Родитель f2c796fea2
Коммит dc0fa12c29
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: B5690EEEBB952194
5 изменённых файлов: 324 добавлений и 65 удалений

Просмотреть файл

@ -9,6 +9,7 @@ Note that this assumes the other logging system cares about only the level and t
```c
typedef void (*LOG_SINK_CALLBACK_LOG)(void* context, LOG_LEVEL log_level, const char* message);
int log_sink_callback_set_callback(LOG_SINK_CALLBACK_LOG log_callback, void* context);
void log_sink_callback_set_max_level(LOG_LEVEL log_level);
extern const LOG_SINK_IF log_sink_callback;
```
@ -49,6 +50,16 @@ int log_sink_callback_set_callback(LOG_SINK_CALLBACK_LOG log_callback, void* con
**SRS_LOG_SINK_CALLBACK_42_005: [** `log_sink_callback_set_callback` shall return 0. **]**
### log_sink_callback_set_max_level
```c
void log_sink_callback_set_max_level(LOG_LEVEL log_level);
```
`log_sink_callback_set_max_level` sets the maximum log level that will be passed to the callback. Log messages with a level higher than this (more verbose) will be dropped. This avoids additional string processing on the log messages that will be dropped. This function is not thread-safe. If called during normal operation to change the log level, some threads may continue to log messages at the old level for some time.
**SRS_LOG_SINK_CALLBACK_42_019: [** `log_sink_callback_set_max_level` shall store `log_level` so that it is used by all future calls to `log_sink_callback.log`. **]**
### log_sink_callback.log
The signature of `log_sink_callback.log` is:
@ -61,6 +72,8 @@ typedef void (*LOG_SINK_LOG_FUNC)(LOG_LEVEL log_level, LOG_CONTEXT_HANDLE log_co
**SRS_LOG_SINK_CALLBACK_42_006: [** If `message_format` is `NULL`, `log_sink_callback.log` shall call the `log_callback` with an error message and return. **]**
**SRS_LOG_SINK_CALLBACK_42_020: [** If `log_level` is greater than the maximum level set by `log_sink_callback_set_max_level`, then `log_sink_callback.log` shall return without calling the `log_callback`. **]**
**SRS_LOG_SINK_CALLBACK_42_007: [** `log_sink_callback.log` shall obtain the time by calling `time`. **]**
**SRS_LOG_SINK_CALLBACK_42_008: [** `log_sink_callback.log` shall write the time to string by calling `ctime`. **]**

Просмотреть файл

@ -12,6 +12,7 @@ extern "C" {
typedef void (*LOG_SINK_CALLBACK_LOG)(void* context, LOG_LEVEL log_level, const char* message);
int log_sink_callback_set_callback(LOG_SINK_CALLBACK_LOG log_callback, void* context);
void log_sink_callback_set_max_level(LOG_LEVEL log_level);
extern const LOG_SINK_IF log_sink_callback;

Просмотреть файл

@ -31,7 +31,7 @@ void log_sink_callback_noop_callback(void* context, LOG_LEVEL log_level, const c
static LOG_SINK_CALLBACK_LOG log_sink_callback_callback = log_sink_callback_noop_callback;
static void* log_sink_callback_context = NULL;
static LOG_LEVEL log_sink_callback_max_level = LOG_LEVEL_VERBOSE;
static int log_sink_callback_init(void)
{
@ -64,6 +64,12 @@ int log_sink_callback_set_callback(LOG_SINK_CALLBACK_LOG log_callback, void* con
return result;
}
void log_sink_callback_set_max_level(LOG_LEVEL log_level)
{
/*Codes_SRS_LOG_SINK_CALLBACK_42_019: [ log_sink_callback_set_max_level shall store log_level so that it is used by all future calls to log_sink_callback.log. ]*/
log_sink_callback_max_level = log_level;
}
static void log_sink_callback_log(LOG_LEVEL log_level, LOG_CONTEXT_HANDLE log_context, const char* file, const char* func, int line, const char* message_format, va_list args)
{
@ -74,89 +80,96 @@ static void log_sink_callback_log(LOG_LEVEL log_level, LOG_CONTEXT_HANDLE log_co
}
else
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_016: [ log_sink_callback.log shall include at most LOG_MAX_MESSAGE_LENGTH characters including the null terminator in the callback argument (the rest of the context shall be truncated). ]*/
char temp[LOG_MAX_MESSAGE_LENGTH];
char* buffer = temp;
size_t buffer_size = sizeof(temp);
/* Codes_SRS_LOG_SINK_CALLBACK_42_007: [ log_sink_callback.log shall obtain the time by calling time. ]*/
time_t t = time(NULL);
/* Codes_SRS_LOG_SINK_CALLBACK_42_008: [ log_sink_callback.log shall write the time to string by calling ctime. ]*/
/* Codes_SRS_LOG_SINK_CALLBACK_42_010: [ If the call to time fails then log_sink_callback.log shall format the time as NULL. ]*/
char* ctime_result = (t == (time_t)-1) ? NULL : ctime(&t);
/* Codes_SRS_LOG_SINK_CALLBACK_42_009: [ log_sink_callback.log shall create a line in the format: Time: {formatted time} File:{file}:{line} Func:{func} {optional context information} {formatted message}. ]*/
int snprintf_result = snprintf(buffer, buffer_size, "Time:%.24s File:%s:%d Func:%s",
/* Codes_SRS_LOG_SINK_CALLBACK_42_011: [ If the call to ctime fails then log_sink_callback.log shall format the time as NULL. ]*/
MU_P_OR_NULL(ctime_result),
MU_P_OR_NULL(file),
line,
MU_P_OR_NULL(func));
if (snprintf_result < 0)
if (log_level > log_sink_callback_max_level)
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_017: [ If any encoding error occurs during formatting of the line (i.e. if any printf class functions fails), log_sink_callback.log shall call the log_callback with Error formatting log line and return. ]*/
log_sink_callback_callback(log_sink_callback_context, LOG_LEVEL_CRITICAL, error_string);
/* Codes_SRS_LOG_SINK_CALLBACK_42_020: [ If log_level is greater than the maximum level set by log_sink_callback_set_max_level, then log_sink_callback.log shall return without calling the log_callback. ]*/
}
else
{
bool error = false;
/* Codes_SRS_LOG_SINK_CALLBACK_42_016: [ log_sink_callback.log shall include at most LOG_MAX_MESSAGE_LENGTH characters including the null terminator in the callback argument (the rest of the context shall be truncated). ]*/
char temp[LOG_MAX_MESSAGE_LENGTH];
char* buffer = temp;
size_t buffer_size = sizeof(temp);
snprintf_result = MIN(snprintf_result, (int)buffer_size);
buffer += snprintf_result;
buffer_size -= snprintf_result;
/* Codes_SRS_LOG_SINK_CALLBACK_42_007: [ log_sink_callback.log shall obtain the time by calling time. ]*/
time_t t = time(NULL);
/* Codes_SRS_LOG_SINK_CALLBACK_42_008: [ log_sink_callback.log shall write the time to string by calling ctime. ]*/
/* Codes_SRS_LOG_SINK_CALLBACK_42_010: [ If the call to time fails then log_sink_callback.log shall format the time as NULL. ]*/
char* ctime_result = (t == (time_t)-1) ? NULL : ctime(&t);
/* Codes_SRS_LOG_SINK_CALLBACK_42_012: [ If log_context is non-NULL: ]*/
if (log_context != NULL)
/* Codes_SRS_LOG_SINK_CALLBACK_42_009: [ log_sink_callback.log shall create a line in the format: Time: {formatted time} File:{file}:{line} Func:{func} {optional context information} {formatted message}. ]*/
int snprintf_result = snprintf(buffer, buffer_size, "Time:%.24s File:%s:%d Func:%s",
/* Codes_SRS_LOG_SINK_CALLBACK_42_011: [ If the call to ctime fails then log_sink_callback.log shall format the time as NULL. ]*/
MU_P_OR_NULL(ctime_result),
MU_P_OR_NULL(file),
line,
MU_P_OR_NULL(func));
if (snprintf_result < 0)
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_013: [ log_sink_callback.log shall call log_context_get_property_value_pair_count to obtain the count of properties. ]*/
size_t property_value_pair_count = log_context_get_property_value_pair_count(log_context);
/* Codes_SRS_LOG_SINK_CALLBACK_42_014: [ log_sink_callback.log shall call log_context_get_property_value_pairs to obtain the properties. ]*/
const LOG_CONTEXT_PROPERTY_VALUE_PAIR* property_value_pairs = log_context_get_property_value_pairs(log_context);
/* Codes_SRS_LOG_SINK_CALLBACK_42_015: [ log_sink_callback.log shall call log_context_property_to_string to write the properties to the string buffer. ]*/
int log_n_properties_result = log_context_property_to_string(buffer, buffer_size, property_value_pairs, property_value_pair_count); // lgtm[cpp/unguardednullreturndereference] Tests and code review ensure that NULL access cannot happen
if (log_n_properties_result < 0)
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_017: [ If any encoding error occurs during formatting of the line (i.e. if any printf class functions fails), log_sink_callback.log shall call the log_callback with Error formatting log line and return. ]*/
error = true;
}
else
{
log_n_properties_result = MIN(log_n_properties_result, (int)buffer_size);
buffer += log_n_properties_result;
buffer_size -= log_n_properties_result;
}
/* Codes_SRS_LOG_SINK_CALLBACK_42_017: [ If any encoding error occurs during formatting of the line (i.e. if any printf class functions fails), log_sink_callback.log shall call the log_callback with Error formatting log line and return. ]*/
log_sink_callback_callback(log_sink_callback_context, LOG_LEVEL_CRITICAL, error_string);
}
if (!error)
else
{
if (buffer_size > 1)
{
*buffer = ' ';
buffer++;
buffer_size--;
bool error = false;
int vsnprintf_result = vsnprintf(buffer, buffer_size, message_format, args);
if (vsnprintf_result < 0)
snprintf_result = MIN(snprintf_result, (int)buffer_size);
buffer += snprintf_result;
buffer_size -= snprintf_result;
/* Codes_SRS_LOG_SINK_CALLBACK_42_012: [ If log_context is non-NULL: ]*/
if (log_context != NULL)
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_013: [ log_sink_callback.log shall call log_context_get_property_value_pair_count to obtain the count of properties. ]*/
size_t property_value_pair_count = log_context_get_property_value_pair_count(log_context);
/* Codes_SRS_LOG_SINK_CALLBACK_42_014: [ log_sink_callback.log shall call log_context_get_property_value_pairs to obtain the properties. ]*/
const LOG_CONTEXT_PROPERTY_VALUE_PAIR* property_value_pairs = log_context_get_property_value_pairs(log_context);
/* Codes_SRS_LOG_SINK_CALLBACK_42_015: [ log_sink_callback.log shall call log_context_property_to_string to write the properties to the string buffer. ]*/
int log_n_properties_result = log_context_property_to_string(buffer, buffer_size, property_value_pairs, property_value_pair_count); // lgtm[cpp/unguardednullreturndereference] Tests and code review ensure that NULL access cannot happen
if (log_n_properties_result < 0)
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_017: [ If any encoding error occurs during formatting of the line (i.e. if any printf class functions fails), log_sink_callback.log shall call the log_callback with Error formatting log line and return. ]*/
error = true;
}
else
{
// all ok
log_n_properties_result = MIN(log_n_properties_result, (int)buffer_size);
buffer += log_n_properties_result;
buffer_size -= log_n_properties_result;
}
}
}
if (error)
{
log_sink_callback_callback(log_sink_callback_context, LOG_LEVEL_CRITICAL, error_string);
}
else
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_018: [ log_sink_callback.log shall call log_callback with its context, log_level, and the formatted message. ]*/
log_sink_callback_callback(log_sink_callback_context, log_level, temp);
if (!error)
{
if (buffer_size > 1)
{
*buffer = ' ';
buffer++;
buffer_size--;
int vsnprintf_result = vsnprintf(buffer, buffer_size, message_format, args);
if (vsnprintf_result < 0)
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_017: [ If any encoding error occurs during formatting of the line (i.e. if any printf class functions fails), log_sink_callback.log shall call the log_callback with Error formatting log line and return. ]*/
error = true;
}
else
{
// all ok
}
}
}
if (error)
{
log_sink_callback_callback(log_sink_callback_context, LOG_LEVEL_CRITICAL, error_string);
}
else
{
/* Codes_SRS_LOG_SINK_CALLBACK_42_018: [ log_sink_callback.log shall call log_callback with its context, log_level, and the formatted message. ]*/
log_sink_callback_callback(log_sink_callback_context, log_level, temp);
}
}
}
}

Просмотреть файл

@ -381,6 +381,106 @@ static void log_sink_callback_with_a_context_with_boolean_false_works(void)
LOG_CONTEXT_DESTROY(test_context);
}
static void test_case_log_sink_callback_is_called_with_max_level(LOG_LEVEL log_level, LOG_LEVEL max_log_level)
{
// arrange
log_sink_callback_set_max_level(max_log_level);
uint32_t count_before = log_callback_context.message_count;
// act
test_log_sink_callback_log(log_level, NULL, __FILE__, __FUNCTION__, __LINE__, "a");
// assert
assert_log_message_received(count_before, log_level, __FILE__, __FUNCTION__, NULL, "a");
// cleanup
log_sink_callback_set_max_level(LOG_LEVEL_VERBOSE);
}
static void test_case_log_sink_callback_is_not_called_with_max_level(LOG_LEVEL log_level, LOG_LEVEL max_log_level)
{
// arrange
log_sink_callback_set_max_level(max_log_level);
uint32_t count_before = log_callback_context.message_count;
// act
test_log_sink_callback_log(log_level, NULL, __FILE__, __FUNCTION__, __LINE__, "a");
// assert
POOR_MANS_ASSERT(log_callback_context.message_count == count_before);
// cleanup
log_sink_callback_set_max_level(LOG_LEVEL_VERBOSE);
}
static void log_sink_callback_log_calls_callback_for_all_log_levels_when_max_level_is_VERBOSE(void)
{
for (LOG_LEVEL log_level = LOG_LEVEL_CRITICAL; log_level <= LOG_LEVEL_VERBOSE; log_level++)
{
test_case_log_sink_callback_is_called_with_max_level(log_level, LOG_LEVEL_VERBOSE);
}
}
static void log_sink_callback_log_calls_callback_for_all_log_levels_INFO_and_lower_when_max_level_is_INFO(void)
{
for (LOG_LEVEL log_level = LOG_LEVEL_CRITICAL; log_level <= LOG_LEVEL_VERBOSE; log_level++)
{
if (log_level > LOG_LEVEL_INFO)
{
test_case_log_sink_callback_is_not_called_with_max_level(log_level, LOG_LEVEL_INFO);
}
else
{
test_case_log_sink_callback_is_called_with_max_level(log_level, LOG_LEVEL_INFO);
}
}
}
static void log_sink_callback_log_calls_callback_for_all_log_levels_WARNING_and_lower_when_max_level_is_WARNING(void)
{
for (LOG_LEVEL log_level = LOG_LEVEL_CRITICAL; log_level <= LOG_LEVEL_VERBOSE; log_level++)
{
if (log_level > LOG_LEVEL_WARNING)
{
test_case_log_sink_callback_is_not_called_with_max_level(log_level, LOG_LEVEL_WARNING);
}
else
{
test_case_log_sink_callback_is_called_with_max_level(log_level, LOG_LEVEL_WARNING);
}
}
}
static void log_sink_callback_log_calls_callback_for_all_log_levels_ERROR_and_lower_when_max_level_is_ERROR(void)
{
for (LOG_LEVEL log_level = LOG_LEVEL_CRITICAL; log_level <= LOG_LEVEL_VERBOSE; log_level++)
{
if (log_level > LOG_LEVEL_ERROR)
{
test_case_log_sink_callback_is_not_called_with_max_level(log_level, LOG_LEVEL_ERROR);
}
else
{
test_case_log_sink_callback_is_called_with_max_level(log_level, LOG_LEVEL_ERROR);
}
}
}
static void log_sink_callback_log_calls_callback_for_log_level_CRITICAL_when_max_level_is_CRITICAL(void)
{
for (LOG_LEVEL log_level = LOG_LEVEL_CRITICAL; log_level <= LOG_LEVEL_VERBOSE; log_level++)
{
if (log_level > LOG_LEVEL_CRITICAL)
{
test_case_log_sink_callback_is_not_called_with_max_level(log_level, LOG_LEVEL_CRITICAL);
}
else
{
test_case_log_sink_callback_is_called_with_max_level(log_level, LOG_LEVEL_CRITICAL);
}
}
}
/* very "poor man's" way of testing, as no test harness and mocking framework are available */
int main(void)
{
@ -417,6 +517,12 @@ int main(void)
log_sink_callback_with_a_context_with_boolean_true_works();
log_sink_callback_with_a_context_with_boolean_false_works();
log_sink_callback_log_calls_callback_for_all_log_levels_when_max_level_is_VERBOSE();
log_sink_callback_log_calls_callback_for_all_log_levels_INFO_and_lower_when_max_level_is_INFO();
log_sink_callback_log_calls_callback_for_all_log_levels_WARNING_and_lower_when_max_level_is_WARNING();
log_sink_callback_log_calls_callback_for_all_log_levels_ERROR_and_lower_when_max_level_is_ERROR();
log_sink_callback_log_calls_callback_for_log_level_CRITICAL_when_max_level_is_CRITICAL();
log_sink_callback.deinit();
return 0;

Просмотреть файл

@ -413,6 +413,7 @@ static void test_init(void)
log_sink_callback.init();
int result = log_sink_callback_set_callback(mock_log_callback, (void*)0x42);
POOR_MANS_ASSERT(result == 0);
log_sink_callback_set_max_level(LOG_LEVEL_VERBOSE);
}
static void setup_printf_call(void)
@ -1294,6 +1295,125 @@ static void when_printing_a_property_name_exceeds_log_line_size_it_is_truncated(
LOG_CONTEXT_DESTROY(context_1);
}
static void test_case_log_sink_callback_log_with_max_level_does_call_callback(LOG_LEVEL log_level, LOG_LEVEL max_log_level)
{
// arrange
test_init();
log_sink_callback_set_max_level(max_log_level);
setup_mocks();
setup_time_call();
setup_ctime_call();
setup_snprintf_call();
setup_vsnprintf_call();
setup_log_callback_call();
// act
int line_no = __LINE__;
test_log_sink_callback_log(log_level, NULL, __FILE__, __FUNCTION__, line_no, "test");
// assert
POOR_MANS_ASSERT(expected_call_count == actual_call_count);
POOR_MANS_ASSERT(expected_calls[0].time_call.captured__time == NULL);
POOR_MANS_ASSERT(actual_and_expected_match);
POOR_MANS_ASSERT(expected_calls[actual_call_count - 1].log_callback_call.captured_context == (void*)0x42);
POOR_MANS_ASSERT(expected_calls[actual_call_count - 1].log_callback_call.captured_log_level == log_level);
validate_log_line(expected_calls[actual_call_count - 1].log_callback_call.captured_output, "Time:%%s %%s %%d %%d:%%d:%%d %%d File:%s:%d Func:%s %%[^\r\n]", __FILE__, line_no, __FUNCTION__, "test");
}
static void test_case_log_sink_callback_log_with_max_level_does_not_call_callback(LOG_LEVEL log_level, LOG_LEVEL max_log_level)
{
// arrange
test_init();
log_sink_callback_set_max_level(max_log_level);
setup_mocks();
// act
int line_no = __LINE__;
test_log_sink_callback_log(log_level, NULL, __FILE__, __FUNCTION__, line_no, "test");
// assert
POOR_MANS_ASSERT(expected_call_count == actual_call_count);
}
/*Tests_SRS_LOG_SINK_CALLBACK_42_019: [ log_sink_callback_set_max_level shall store log_level so that it is used by all future calls to log_sink_callback.log. ]*/
/*Tests_SRS_LOG_SINK_CALLBACK_42_020: [ If log_level is greater than the maximum level set by log_sink_callback_set_max_level, then log_sink_callback.log shall return without calling the log_callback. ]*/
static void log_sink_callback_log_calls_callback_for_all_log_levels_when_max_level_is_VERBOSE(void)
{
for (LOG_LEVEL log_level = LOG_LEVEL_CRITICAL; log_level <= LOG_LEVEL_VERBOSE; log_level++)
{
test_case_log_sink_callback_log_with_max_level_does_call_callback(log_level, LOG_LEVEL_VERBOSE);
}
}
/*Tests_SRS_LOG_SINK_CALLBACK_42_019: [ log_sink_callback_set_max_level shall store log_level so that it is used by all future calls to log_sink_callback.log. ]*/
/*Tests_SRS_LOG_SINK_CALLBACK_42_020: [ If log_level is greater than the maximum level set by log_sink_callback_set_max_level, then log_sink_callback.log shall return without calling the log_callback. ]*/
static void log_sink_callback_log_calls_callback_for_all_log_levels_INFO_and_lower_when_max_level_is_INFO(void)
{
for (LOG_LEVEL log_level = LOG_LEVEL_CRITICAL; log_level <= LOG_LEVEL_VERBOSE; log_level++)
{
if (log_level > LOG_LEVEL_INFO)
{
test_case_log_sink_callback_log_with_max_level_does_not_call_callback(log_level, LOG_LEVEL_INFO);
}
else
{
test_case_log_sink_callback_log_with_max_level_does_call_callback(log_level, LOG_LEVEL_INFO);
}
}
}
/*Tests_SRS_LOG_SINK_CALLBACK_42_019: [ log_sink_callback_set_max_level shall store log_level so that it is used by all future calls to log_sink_callback.log. ]*/
/*Tests_SRS_LOG_SINK_CALLBACK_42_020: [ If log_level is greater than the maximum level set by log_sink_callback_set_max_level, then log_sink_callback.log shall return without calling the log_callback. ]*/
static void log_sink_callback_log_calls_callback_for_all_log_levels_WARNING_and_lower_when_max_level_is_WARNING(void)
{
for (LOG_LEVEL log_level = LOG_LEVEL_CRITICAL; log_level <= LOG_LEVEL_VERBOSE; log_level++)
{
if (log_level > LOG_LEVEL_WARNING)
{
test_case_log_sink_callback_log_with_max_level_does_not_call_callback(log_level, LOG_LEVEL_WARNING);
}
else
{
test_case_log_sink_callback_log_with_max_level_does_call_callback(log_level, LOG_LEVEL_WARNING);
}
}
}
/*Tests_SRS_LOG_SINK_CALLBACK_42_019: [ log_sink_callback_set_max_level shall store log_level so that it is used by all future calls to log_sink_callback.log. ]*/
/*Tests_SRS_LOG_SINK_CALLBACK_42_020: [ If log_level is greater than the maximum level set by log_sink_callback_set_max_level, then log_sink_callback.log shall return without calling the log_callback. ]*/
static void log_sink_callback_log_calls_callback_for_all_log_levels_ERROR_and_lower_when_max_level_is_ERROR(void)
{
for (LOG_LEVEL log_level = LOG_LEVEL_CRITICAL; log_level <= LOG_LEVEL_VERBOSE; log_level++)
{
if (log_level > LOG_LEVEL_ERROR)
{
test_case_log_sink_callback_log_with_max_level_does_not_call_callback(log_level, LOG_LEVEL_ERROR);
}
else
{
test_case_log_sink_callback_log_with_max_level_does_call_callback(log_level, LOG_LEVEL_ERROR);
}
}
}
/*Tests_SRS_LOG_SINK_CALLBACK_42_019: [ log_sink_callback_set_max_level shall store log_level so that it is used by all future calls to log_sink_callback.log. ]*/
/*Tests_SRS_LOG_SINK_CALLBACK_42_020: [ If log_level is greater than the maximum level set by log_sink_callback_set_max_level, then log_sink_callback.log shall return without calling the log_callback. ]*/
static void log_sink_callback_log_calls_callback_for_log_level_CRITICAL_when_max_level_is_CRITICAL(void)
{
for (LOG_LEVEL log_level = LOG_LEVEL_CRITICAL; log_level <= LOG_LEVEL_VERBOSE; log_level++)
{
if (log_level > LOG_LEVEL_CRITICAL)
{
test_case_log_sink_callback_log_with_max_level_does_not_call_callback(log_level, LOG_LEVEL_CRITICAL);
}
else
{
test_case_log_sink_callback_log_with_max_level_does_call_callback(log_level, LOG_LEVEL_CRITICAL);
}
}
}
/* very "poor man's" way of testing, as no test harness and mocking framework are available */
int main(void)
{
@ -1326,5 +1446,11 @@ int main(void)
when_printing_a_property_value_exceeds_log_line_size_it_is_truncated();
when_printing_a_property_name_exceeds_log_line_size_it_is_truncated();
log_sink_callback_log_calls_callback_for_all_log_levels_when_max_level_is_VERBOSE();
log_sink_callback_log_calls_callback_for_all_log_levels_INFO_and_lower_when_max_level_is_INFO();
log_sink_callback_log_calls_callback_for_all_log_levels_WARNING_and_lower_when_max_level_is_WARNING();
log_sink_callback_log_calls_callback_for_all_log_levels_ERROR_and_lower_when_max_level_is_ERROR();
log_sink_callback_log_calls_callback_for_log_level_CRITICAL_when_max_level_is_CRITICAL();
return 0;
}