|
#include "test_framework.h"
|
|
#include "../src/logging.h"
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <stdio.h>
|
|
#include <sys/stat.h>
|
|
#include <errno.h>
|
|
|
|
void test_logging_debug_mode(void) {
|
|
TEST_SUITE_BEGIN("Logging Debug Mode");
|
|
|
|
logging_set_debug(0);
|
|
TEST_ASSERT_EQ(0, logging_get_debug(), "Debug mode disabled");
|
|
|
|
logging_set_debug(1);
|
|
TEST_ASSERT_EQ(1, logging_get_debug(), "Debug mode enabled");
|
|
|
|
logging_set_debug(0);
|
|
TEST_ASSERT_EQ(0, logging_get_debug(), "Debug mode disabled again");
|
|
|
|
TEST_SUITE_END();
|
|
}
|
|
|
|
void test_logging_set_file(void) {
|
|
TEST_SUITE_BEGIN("Logging Set File");
|
|
|
|
char tmp_path[] = "/tmp/test_rproxy_log_XXXXXX";
|
|
int fd = mkstemp(tmp_path);
|
|
TEST_ASSERT(fd >= 0, "Temp file created");
|
|
close(fd);
|
|
|
|
int result = logging_set_file(tmp_path);
|
|
TEST_ASSERT_EQ(0, result, "Set log file succeeds");
|
|
|
|
log_info("Test log message");
|
|
|
|
struct stat st;
|
|
stat(tmp_path, &st);
|
|
TEST_ASSERT(st.st_size > 0, "Log file has content");
|
|
|
|
logging_cleanup();
|
|
unlink(tmp_path);
|
|
|
|
TEST_SUITE_END();
|
|
}
|
|
|
|
void test_logging_set_file_null(void) {
|
|
TEST_SUITE_BEGIN("Logging Set File NULL");
|
|
|
|
int result = logging_set_file(NULL);
|
|
TEST_ASSERT_EQ(0, result, "NULL path returns to stdout");
|
|
|
|
log_info("Test message to stdout");
|
|
TEST_ASSERT(1, "Logging to stdout works");
|
|
|
|
TEST_SUITE_END();
|
|
}
|
|
|
|
void test_logging_set_file_invalid(void) {
|
|
TEST_SUITE_BEGIN("Logging Set File Invalid Path");
|
|
|
|
int result = logging_set_file("/nonexistent/directory/log.txt");
|
|
TEST_ASSERT_EQ(-1, result, "Invalid path returns -1");
|
|
|
|
TEST_SUITE_END();
|
|
}
|
|
|
|
void test_logging_log_functions(void) {
|
|
TEST_SUITE_BEGIN("Logging Log Functions");
|
|
|
|
char tmp_path[] = "/tmp/test_rproxy_log_XXXXXX";
|
|
int fd = mkstemp(tmp_path);
|
|
close(fd);
|
|
|
|
logging_set_file(tmp_path);
|
|
|
|
log_info("Info message: %d", 42);
|
|
log_error("Error message: %s", "test error");
|
|
|
|
logging_set_debug(1);
|
|
log_debug("Debug message: %s", "debug info");
|
|
logging_set_debug(0);
|
|
|
|
log_debug("This should not appear");
|
|
|
|
struct stat st;
|
|
stat(tmp_path, &st);
|
|
TEST_ASSERT(st.st_size > 0, "Log messages written");
|
|
|
|
FILE *f = fopen(tmp_path, "r");
|
|
char content[4096] = {0};
|
|
if (f) {
|
|
size_t bytes_read = fread(content, 1, sizeof(content) - 1, f);
|
|
(void)bytes_read;
|
|
fclose(f);
|
|
}
|
|
|
|
TEST_ASSERT(strstr(content, "INFO") != NULL, "INFO level present");
|
|
TEST_ASSERT(strstr(content, "ERROR") != NULL, "ERROR level present");
|
|
TEST_ASSERT(strstr(content, "DEBUG") != NULL, "DEBUG level present");
|
|
TEST_ASSERT(strstr(content, "42") != NULL, "Info param present");
|
|
TEST_ASSERT(strstr(content, "test error") != NULL, "Error param present");
|
|
|
|
logging_cleanup();
|
|
unlink(tmp_path);
|
|
|
|
TEST_SUITE_END();
|
|
}
|
|
|
|
void test_logging_cleanup(void) {
|
|
TEST_SUITE_BEGIN("Logging Cleanup");
|
|
|
|
char tmp_path[] = "/tmp/test_rproxy_log_XXXXXX";
|
|
int fd = mkstemp(tmp_path);
|
|
close(fd);
|
|
|
|
logging_set_file(tmp_path);
|
|
log_info("Before cleanup");
|
|
|
|
logging_cleanup();
|
|
|
|
log_info("After cleanup to stdout");
|
|
TEST_ASSERT(1, "Cleanup completed and logging works");
|
|
|
|
unlink(tmp_path);
|
|
|
|
TEST_SUITE_END();
|
|
}
|
|
|
|
void test_logging_multiple_files(void) {
|
|
TEST_SUITE_BEGIN("Logging Multiple File Switches");
|
|
|
|
char tmp1[] = "/tmp/test_rproxy_log1_XXXXXX";
|
|
char tmp2[] = "/tmp/test_rproxy_log2_XXXXXX";
|
|
|
|
int fd1 = mkstemp(tmp1);
|
|
int fd2 = mkstemp(tmp2);
|
|
close(fd1);
|
|
close(fd2);
|
|
|
|
logging_set_file(tmp1);
|
|
log_info("Message to file 1");
|
|
|
|
logging_set_file(tmp2);
|
|
log_info("Message to file 2");
|
|
|
|
struct stat st1, st2;
|
|
stat(tmp1, &st1);
|
|
stat(tmp2, &st2);
|
|
|
|
TEST_ASSERT(st1.st_size > 0, "First file has content");
|
|
TEST_ASSERT(st2.st_size > 0, "Second file has content");
|
|
|
|
logging_cleanup();
|
|
unlink(tmp1);
|
|
unlink(tmp2);
|
|
|
|
TEST_SUITE_END();
|
|
}
|
|
|
|
void test_logging_error_with_errno(void) {
|
|
TEST_SUITE_BEGIN("Logging Error With Errno");
|
|
|
|
char tmp_path[] = "/tmp/test_rproxy_log_XXXXXX";
|
|
int fd = mkstemp(tmp_path);
|
|
close(fd);
|
|
|
|
logging_set_file(tmp_path);
|
|
|
|
errno = ENOENT;
|
|
log_error("File not found error");
|
|
errno = 0;
|
|
|
|
log_error("Error without errno");
|
|
|
|
errno = EPERM;
|
|
log_error("Permission denied: %s", "/test/file");
|
|
errno = 0;
|
|
|
|
logging_cleanup();
|
|
|
|
FILE *f = fopen(tmp_path, "r");
|
|
char content[4096] = {0};
|
|
if (f) {
|
|
size_t bytes_read = fread(content, 1, sizeof(content) - 1, f);
|
|
(void)bytes_read;
|
|
fclose(f);
|
|
}
|
|
|
|
TEST_ASSERT(strstr(content, "File not found") != NULL, "First error logged");
|
|
TEST_ASSERT(strstr(content, "without errno") != NULL, "Second error logged");
|
|
|
|
unlink(tmp_path);
|
|
|
|
TEST_SUITE_END();
|
|
}
|
|
|
|
void test_logging_debug_disabled(void) {
|
|
TEST_SUITE_BEGIN("Logging Debug Disabled");
|
|
|
|
char tmp_path[] = "/tmp/test_rproxy_log_XXXXXX";
|
|
int fd = mkstemp(tmp_path);
|
|
close(fd);
|
|
|
|
logging_set_file(tmp_path);
|
|
logging_set_debug(0);
|
|
|
|
log_debug("This should not appear");
|
|
log_info("This should appear");
|
|
|
|
struct stat st;
|
|
stat(tmp_path, &st);
|
|
TEST_ASSERT(st.st_size > 0, "File has some content");
|
|
|
|
FILE *f = fopen(tmp_path, "r");
|
|
char content[4096] = {0};
|
|
if (f) {
|
|
size_t bytes_read = fread(content, 1, sizeof(content) - 1, f);
|
|
(void)bytes_read;
|
|
fclose(f);
|
|
}
|
|
|
|
TEST_ASSERT(strstr(content, "should appear") != NULL, "Info message present");
|
|
|
|
logging_cleanup();
|
|
unlink(tmp_path);
|
|
|
|
TEST_SUITE_END();
|
|
}
|
|
|
|
void test_logging_format_strings(void) {
|
|
TEST_SUITE_BEGIN("Logging Format Strings");
|
|
|
|
char tmp_path[] = "/tmp/test_rproxy_log_XXXXXX";
|
|
int fd = mkstemp(tmp_path);
|
|
close(fd);
|
|
|
|
logging_set_file(tmp_path);
|
|
|
|
log_info("Int: %d, String: %s, Float: %.2f", 42, "test", 3.14);
|
|
log_error("Code: %d, Msg: %s", 500, "Internal error");
|
|
|
|
logging_set_debug(1);
|
|
log_debug("Debug: %s %d", "value", 123);
|
|
logging_set_debug(0);
|
|
|
|
logging_cleanup();
|
|
|
|
FILE *f = fopen(tmp_path, "r");
|
|
char content[4096] = {0};
|
|
if (f) {
|
|
size_t bytes_read = fread(content, 1, sizeof(content) - 1, f);
|
|
(void)bytes_read;
|
|
fclose(f);
|
|
}
|
|
|
|
TEST_ASSERT(strstr(content, "42") != NULL, "Int formatted");
|
|
TEST_ASSERT(strstr(content, "test") != NULL, "String formatted");
|
|
TEST_ASSERT(strstr(content, "500") != NULL, "Error code formatted");
|
|
|
|
unlink(tmp_path);
|
|
|
|
TEST_SUITE_END();
|
|
}
|
|
|
|
void run_logging_tests(void) {
|
|
test_logging_debug_mode();
|
|
test_logging_set_file();
|
|
test_logging_set_file_null();
|
|
test_logging_set_file_invalid();
|
|
test_logging_log_functions();
|
|
test_logging_cleanup();
|
|
test_logging_multiple_files();
|
|
test_logging_error_with_errno();
|
|
test_logging_debug_disabled();
|
|
test_logging_format_strings();
|
|
}
|