output_escape() was called on every send_str/receive_str even when LOG_DEBUG_PROTO logging was disabled, allocating and scanning the whole payload for a line that log_debug_message() then discarded. Add a log_debug_enabled(flag) gate mirroring log_debug_message()'s own filter and check it before escaping. Redacted (secret) strings still log the same <redacted> marker; no observable log output changes.
163 lines
5.3 KiB
C
163 lines
5.3 KiB
C
#include "test_log.h"
|
|
#include "log.h"
|
|
#include "test_utils.h"
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
|
|
/* Test default log level: WARNING and ERROR should print, DEBUG and INFO should not.
|
|
* We can't easily capture stderr in unit tests, so we verify the functions don't crash
|
|
* and that set_log_level changes behavior. */
|
|
|
|
static void test_log_message_debug() {
|
|
set_log_level(LOG_LEVEL_WARNING);
|
|
log_message(LOG_LEVEL_DEBUG, "debug message: %d", 42);
|
|
/* crash regression test — stderr capture would need infrastructure changes */
|
|
EXPECT_TRUE(true);
|
|
}
|
|
|
|
static void test_log_message_info() {
|
|
set_log_level(LOG_LEVEL_WARNING);
|
|
log_message(LOG_LEVEL_INFO, "info message: %s", "test");
|
|
/* crash regression test — stderr capture would need infrastructure changes */
|
|
EXPECT_TRUE(true);
|
|
}
|
|
|
|
static void test_log_message_warning() {
|
|
set_log_level(LOG_LEVEL_WARNING);
|
|
log_message(LOG_LEVEL_WARNING, "warning message: %d %s", 1, "test");
|
|
/* crash regression test — stderr capture would need infrastructure changes */
|
|
EXPECT_TRUE(true);
|
|
}
|
|
|
|
static void test_log_message_error() {
|
|
set_log_level(LOG_LEVEL_WARNING);
|
|
log_message(LOG_LEVEL_ERROR, "error message: %s", "critical");
|
|
/* crash regression test — stderr capture would need infrastructure changes */
|
|
EXPECT_TRUE(true);
|
|
}
|
|
|
|
static void test_log_set_level_debug() {
|
|
set_log_level(LOG_LEVEL_DEBUG);
|
|
|
|
/* After setting to DEBUG, all levels should be shown */
|
|
log_message(LOG_LEVEL_DEBUG, "debug after set");
|
|
log_message(LOG_LEVEL_INFO, "info after set");
|
|
log_message(LOG_LEVEL_WARNING, "warning after set");
|
|
log_message(LOG_LEVEL_ERROR, "error after set");
|
|
|
|
/* crash regression test — stderr capture would need infrastructure changes */
|
|
EXPECT_TRUE(true);
|
|
}
|
|
|
|
static void test_log_set_level_info() {
|
|
set_log_level(LOG_LEVEL_INFO);
|
|
|
|
/* INFO level should show INFO, WARNING, ERROR but not DEBUG */
|
|
log_message(LOG_LEVEL_DEBUG, "debug should be filtered"); /* filtered */
|
|
log_message(LOG_LEVEL_INFO, "info should show");
|
|
log_message(LOG_LEVEL_WARNING, "warning should show");
|
|
log_message(LOG_LEVEL_ERROR, "error should show");
|
|
|
|
/* crash regression test — stderr capture would need infrastructure changes */
|
|
EXPECT_TRUE(true);
|
|
}
|
|
|
|
static void test_log_set_level_error() {
|
|
set_log_level(LOG_LEVEL_ERROR);
|
|
|
|
/* ERROR level: only ERROR should show */
|
|
log_message(LOG_LEVEL_DEBUG, "debug filtered");
|
|
log_message(LOG_LEVEL_INFO, "info filtered");
|
|
log_message(LOG_LEVEL_WARNING, "warning filtered");
|
|
log_message(LOG_LEVEL_ERROR, "error should show");
|
|
|
|
/* crash regression test — stderr capture would need infrastructure changes */
|
|
EXPECT_TRUE(true);
|
|
}
|
|
|
|
/* Test that set_log_level with default WARNING filters correctly */
|
|
static void test_log_filtering() {
|
|
/* Reset to default */
|
|
set_log_level(LOG_LEVEL_WARNING);
|
|
|
|
/* These should be filtered */
|
|
log_message(LOG_LEVEL_DEBUG, "filtered debug");
|
|
log_message(LOG_LEVEL_INFO, "filtered info");
|
|
|
|
/* These should be shown */
|
|
log_message(LOG_LEVEL_WARNING, "visible warning");
|
|
log_message(LOG_LEVEL_ERROR, "visible error");
|
|
|
|
/* crash regression test — stderr capture would need infrastructure changes */
|
|
EXPECT_TRUE(true);
|
|
}
|
|
|
|
static void test_log_stderr_mode_all() {
|
|
int pipe_fds[2];
|
|
EXPECT_EQ_INT(pipe(pipe_fds), 0);
|
|
int saved_stderr = dup(STDERR_FILENO);
|
|
EXPECT_TRUE(saved_stderr >= 0);
|
|
EXPECT_TRUE(dup2(pipe_fds[1], STDERR_FILENO) >= 0);
|
|
close(pipe_fds[1]);
|
|
|
|
set_log_level(LOG_LEVEL_WARNING);
|
|
log_set_stderr_mode(LOG_STDERR_ALL);
|
|
log_message(LOG_LEVEL_WARNING, "warning routed to stderr");
|
|
fflush(stderr);
|
|
|
|
EXPECT_TRUE(dup2(saved_stderr, STDERR_FILENO) >= 0);
|
|
close(saved_stderr);
|
|
char output[128] = {0};
|
|
ssize_t length = read(pipe_fds[0], output, sizeof(output) - 1);
|
|
close(pipe_fds[0]);
|
|
EXPECT_TRUE(length > 0);
|
|
EXPECT_TRUE(strstr(output, "warning routed to stderr") != NULL);
|
|
log_set_stderr_mode(LOG_STDERR_ERRORS);
|
|
}
|
|
|
|
/* Test that log_message handles various format strings */
|
|
static void test_log_message_formats() {
|
|
set_log_level(LOG_LEVEL_DEBUG);
|
|
|
|
log_message(LOG_LEVEL_DEBUG, "simple string");
|
|
log_message(LOG_LEVEL_INFO, "integer: %d", -1);
|
|
log_message(LOG_LEVEL_WARNING, "string: %s", "hello");
|
|
log_message(LOG_LEVEL_ERROR, "multiple: %d %s %d", 1, "two", 3);
|
|
|
|
/* crash regression test — stderr capture would need infrastructure changes */
|
|
EXPECT_TRUE(true);
|
|
}
|
|
|
|
/* log_debug_enabled is the lazy-formatting gate for log_debug_message: it must
|
|
* be true only at DEBUG level with the requested flag selected, exactly
|
|
* mirroring the filter inside log_debug_message itself. */
|
|
static void test_log_debug_enabled_matches_gate() {
|
|
set_log_level(LOG_LEVEL_WARNING);
|
|
set_log_debug_flags(LOG_DEBUG_ALL);
|
|
EXPECT_FALSE(log_debug_enabled(LOG_DEBUG_PROTO));
|
|
|
|
set_log_level(LOG_LEVEL_DEBUG);
|
|
set_log_debug_flags(LOG_DEBUG_PROTO);
|
|
EXPECT_TRUE(log_debug_enabled(LOG_DEBUG_PROTO));
|
|
EXPECT_FALSE(log_debug_enabled(LOG_DEBUG_IO));
|
|
|
|
set_log_debug_flags(0);
|
|
EXPECT_FALSE(log_debug_enabled(LOG_DEBUG_PROTO));
|
|
|
|
set_log_debug_flags(LOG_DEBUG_ALL);
|
|
}
|
|
|
|
void test_log() {
|
|
test_log_message_debug();
|
|
test_log_message_info();
|
|
test_log_message_warning();
|
|
test_log_message_error();
|
|
test_log_set_level_debug();
|
|
test_log_set_level_info();
|
|
test_log_set_level_error();
|
|
test_log_filtering();
|
|
test_log_stderr_mode_all();
|
|
test_log_message_formats();
|
|
test_log_debug_enabled_matches_gate();
|
|
}
|