diff --git a/unitest/log_test.cpp b/unitest/log_test.cpp index cf47110..b8f88e6 100644 --- a/unitest/log_test.cpp +++ b/unitest/log_test.cpp @@ -15,96 +15,124 @@ See the Mulan PSL v2 for more details. */ #include "log_test.h" #include "gtest/gtest.h" - #include "common/log/log.h" +#include "common/file/file.h" // 引入文件操作工具类(miniob 已有封装) +#include +#include +#include // 用于 sleep 等待日志刷盘 using namespace common; -LogTest::LogTest() -{ - // Auto-generated constructor stub -} - -LogTest::~LogTest() -{ - // Auto-generated destructor stub -} +// 测试用日志文件路径(统一管理,避免硬编码) +const std::string TEST_LOG_FILE = "./test_logrotate.log"; +const size_t LOG_ROTATE_SIZE = 1024 * 1024; // 1MB 轮转阈值(与日志模块默认配置一致) -int LogTest::init(const std::string &logFile) -{ +LogTest::LogTest() = default; // 简化默认构造函数(使用编译器生成版本) +LogTest::~LogTest() = default; // 简化析构函数 - LoggerFactory::init_default(logFile); +/** + * @brief 初始化日志模块 + * @param log_file 日志文件路径(默认使用测试专用路径) + * @return 0 成功,非0 失败 + */ +int LogTest::init(const std::string &log_file = TEST_LOG_FILE) { + // 初始化前先清理历史测试日志(避免干扰) + FileUtil::delete_file(log_file); + FileUtil::delete_file(log_file + ".1"); // 清理轮转后的旧日志 + LoggerFactory::init_default(log_file); g_log->set_rotate_type(LOG_ROTATE_BYSIZE); - + g_log->set_rotate_size(LOG_ROTATE_SIZE); // 显式设置轮转大小(确保测试一致性) return 0; } -void *LogTest::log_loop(void *param) -{ - int index = *(int *)param; - int i = 0; - while (i < 100) { - i++; - LOG_INFO("index:%d --> %d", index, i); +/** + * @brief 日志循环输出线程函数 + * @param param 线程参数(指向 int 类型的日志标识索引) + * @return 无 + */ +void *LogTest::log_loop(void *param) { + // 空指针校验(修复内存安全隐患) + if (param == nullptr) { + LOG_ERROR("log_loop: input param is null"); + return nullptr; } - return NULL; -} - -void checkRotate() -{ - LogTest test; - - test.init(); - ASSERT_EQ(g_log->get_rotate_type(), LOG_ROTATE_BYSIZE); - - int index = 30; - test.log_loop(&index); -} - -TEST(checkRotateTest, CheckRoateTest) -{ - checkRotate(); + int thread_index = *(static_cast(param)); // 类型安全转换 + // 输出足够多日志,确保触发大小轮转(原100条可能不足1MB) + for (int i = 0; i < 10000; ++i) { + LOG_INFO("Thread-%d: log count = %d, test log rotate by size", thread_index, i); + } + return nullptr; } -void testEnableTest() -{ - LogTest test; - - test.init(); - - ASSERT_EQ(g_log->check_output(LOG_LEVEL_PANIC, __FILE__), true); - ASSERT_EQ(g_log->check_output(LOG_LEVEL_ERR, __FILE__), true); - ASSERT_EQ(g_log->check_output(LOG_LEVEL_WARN, __FILE__), true); - ASSERT_EQ(g_log->check_output(LOG_LEVEL_INFO, __FILE__), true); - ASSERT_EQ(g_log->check_output(LOG_LEVEL_DEBUG, __FILE__), false); - ASSERT_EQ(g_log->check_output(LOG_LEVEL_TRACE, __FILE__), false); - ASSERT_EQ(g_log->check_output(LOG_LEVEL_LAST, __FILE__), false); - - g_log->set_default_module(__FILE__); - - ASSERT_EQ(g_log->check_output(LOG_LEVEL_PANIC, __FILE__), true); - ASSERT_EQ(g_log->check_output(LOG_LEVEL_ERR, __FILE__), true); - ASSERT_EQ(g_log->check_output(LOG_LEVEL_WARN, __FILE__), true); - ASSERT_EQ(g_log->check_output(LOG_LEVEL_INFO, __FILE__), true); - ASSERT_EQ(g_log->check_output(LOG_LEVEL_DEBUG, __FILE__), true); - ASSERT_EQ(g_log->check_output(LOG_LEVEL_TRACE, __FILE__), true); - ASSERT_EQ(g_log->check_output(LOG_LEVEL_LAST, __FILE__), true); +/** + * @brief 测试日志按大小轮转功能 + * 验证点:1. 轮转配置生效;2. 日志文件生成;3. 达到阈值后触发轮转 + */ +TEST(LogRotateTest, RotateBySize) { + LogTest log_test; + ASSERT_EQ(log_test.init(), 0) << "日志模块初始化失败"; + + // 验证轮转配置 + ASSERT_EQ(g_log->get_rotate_type(), LOG_ROTATE_BYSIZE) << "日志轮转类型配置错误"; + ASSERT_EQ(g_log->get_rotate_size(), LOG_ROTATE_SIZE) << "日志轮转大小配置错误"; + + // 启动单线程输出日志(确保触发轮转) + int thread_index = 1; + log_test.log_loop(&thread_index); + + // 等待日志刷盘(避免异步写入导致文件未生成) + sleep(1); + + // 验证日志文件存在 + ASSERT_TRUE(FileUtil::file_exists(TEST_LOG_FILE)) << "主日志文件未生成"; + ASSERT_TRUE(FileUtil::file_exists(TEST_LOG_FILE + ".1")) << "日志未触发轮转(未生成轮转文件)"; + + // 验证轮转文件大小符合阈值(允许±10%误差) + size_t rotate_file_size = FileUtil::file_size(TEST_LOG_FILE + ".1"); + ASSERT_GE(rotate_file_size, LOG_ROTATE_SIZE * 0.9) << "轮转文件大小未达到阈值"; + ASSERT_LE(rotate_file_size, LOG_ROTATE_SIZE * 1.1) << "轮转文件大小超出阈值过多"; + + // 清理测试资源 + LoggerFactory::destroy(); + FileUtil::delete_file(TEST_LOG_FILE); + FileUtil::delete_file(TEST_LOG_FILE + ".1"); } -TEST(testEnableTest, CheckEnableTest) -{ - testEnableTest(); +/** + * @brief 测试日志级别启用/禁用功能 + * 验证点:1. 默认模块日志级别;2. 指定模块日志级别;3. 非法级别校验 + */ +TEST(LogLevelTest, CheckEnableStatus) { + LogTest log_test; + ASSERT_EQ(log_test.init(), 0) << "日志模块初始化失败"; + const char *test_module = __FILE__; + + // 验证默认模块的日志级别(默认只启用 INFO 及以上) + ASSERT_TRUE(g_log->check_output(LOG_LEVEL_PANIC, test_module)) << "PANIC 级别应默认启用"; + ASSERT_TRUE(g_log->check_output(LOG_LEVEL_ERR, test_module)) << "ERR 级别应默认启用"; + ASSERT_TRUE(g_log->check_output(LOG_LEVEL_WARN, test_module)) << "WARN 级别应默认启用"; + ASSERT_TRUE(g_log->check_output(LOG_LEVEL_INFO, test_module)) << "INFO 级别应默认启用"; + ASSERT_FALSE(g_log->check_output(LOG_LEVEL_DEBUG, test_module)) << "DEBUG 级别应默认禁用"; + ASSERT_FALSE(g_log->check_output(LOG_LEVEL_TRACE, test_module)) << "TRACE 级别应默认禁用"; + ASSERT_FALSE(g_log->check_output(LOG_LEVEL_LAST, test_module)) << "非法级别应返回禁用"; + + // 验证指定模块启用所有日志级别 + g_log->set_default_module(test_module); + ASSERT_TRUE(g_log->check_output(LOG_LEVEL_DEBUG, test_module)) << "指定模块应启用 DEBUG 级别"; + ASSERT_TRUE(g_log->check_output(LOG_LEVEL_TRACE, test_module)) << "指定模块应启用 TRACE 级别"; + + // 验证非默认模块的日志级别(仍遵循默认配置) + const char *other_module = "other_test_module"; + ASSERT_FALSE(g_log->check_output(LOG_LEVEL_DEBUG, other_module)) << "非默认模块应禁用 DEBUG 级别"; + + // 清理测试资源 + LoggerFactory::destroy(); + FileUtil::delete_file(TEST_LOG_FILE); } -int main(int argc, char **argv) -{ - - // 分析gtest程序的命令行参数 +int main(int argc, char **argv) { testing::InitGoogleTest(&argc, argv); - - // 调用RUN_ALL_TESTS()运行所有测试用例 - // main函数返回RUN_ALL_TESTS()的运行结果 return RUN_ALL_TESTS(); -} +} \ No newline at end of file