* This file is part of the MindStudio project.
* Copyright (c) 2025 Huawei Technologies Co.,Ltd.
*
* MindStudio is licensed under Mulan PSL v2.
* You can use this software according to the terms and conditions of the Mulan PSL v2.
* You may obtain a copy of Mulan PSL v2 at:
*
* http://license.coscl.org.cn/MulanPSL2
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
* See the Mulan PSL v2 for more details.
* -------------------------------------------------------------------------
*/
#include <gtest/gtest.h>
#include <gtest/internal/gtest-port.h>
#include <thread>
#include "securec.h"
#define private public
#include "utility/log.h"
#undef private
using namespace Utility;
bool FindStr(const std::string &fileName, const char* str)
{
FILE *fp = fopen(fileName.c_str(), "r");
char buffer[256];
if (fgets(buffer, sizeof(buffer), fp) != nullptr && strstr(buffer, str) != nullptr) {
fclose(fp);
return true;
}
fclose(fp);
return false;
}
TEST(Log, log_debug_with_default_log_level_warn_expect_not_output)
{
Log &logger = Log::GetLog();
logger.fp_ = fopen("output.txt", "w");
const char* testLog = "test log debug";
LOG_DEBUG(testLog);
logger.fp_ = nullptr;
EXPECT_FALSE(FindStr("output.txt", testLog));
}
TEST(Log, log_warn_expect_output_warn_log)
{
Log &logger = Log::GetLog();
logger.fp_ = fopen("output.txt", "w");
const char* testLog = "test log warn";
Utility::SetLogLevel(MemScope::LogLv::WARN);
LOG_WARN(testLog);
logger.fp_ = nullptr;
EXPECT_TRUE(FindStr("output.txt", testLog));
EXPECT_TRUE(FindStr("output.txt", "[WARN]"));
}
TEST(Log, log_error_expect_output_erro_log)
{
Log &logger = Log::GetLog();
logger.fp_ = fopen("output.txt", "w");
const char* testLog = "test log error";
Utility::SetLogLevel(MemScope::LogLv::ERROR);
LOG_ERROR(testLog);
logger.fp_ = nullptr;
EXPECT_TRUE(FindStr("output.txt", testLog));
EXPECT_TRUE(FindStr("output.txt", "[ERROR]"));
}
TEST(Log, log_info_expect_output_info_log)
{
Log &logger = Log::GetLog();
logger.fp_ = fopen("output.txt", "w");
const char* testLog = "test log info";
Utility::SetLogLevel(MemScope::LogLv::INFO);
LOG_INFO(testLog);
logger.fp_ = nullptr;
EXPECT_TRUE(FindStr("output.txt", testLog));
EXPECT_TRUE(FindStr("output.txt", "[INFO]"));
}
TEST(Log, log_nullptr_expect_no_output)
{
Log &logger = Log::GetLog();
logger.fp_ = nullptr;
logger.Printf("Test message", MemScope::LogLv::INFO, "test.cpp", 74);
EXPECT_FALSE(FindStr("output.txt", "message"));
}
TEST(Log, log_level_different_threashold_expect_success)
{
Log &logger = Log::GetLog();
logger.fp_ = fopen("output.txt", "w");
logger.SetLogLevel(MemScope::LogLv::INFO);
logger.Printf("Debug message", MemScope::LogLv::DEBUG, "test.cpp", 84);
logger.Printf("Info message", MemScope::LogLv::INFO, "test.cpp", 85);
logger.Printf("Warning message", MemScope::LogLv::WARN, "test.cpp", 86);
logger.Printf("Error message", MemScope::LogLv::ERROR, "test.cpp", 87);
logger.fp_ = nullptr;
EXPECT_TRUE(FindStr("output.txt", "message"));
}
TEST(Log, log_size_exceed_max_expect_warn_and_double_size)
{
Log &logger = Log::GetLog();
FILE* originalFp = logger.fp_;
int64_t originalMaxSize = logger.maxLogSize_;
std::string originalLogPath = logger.logFilePath_;
logger.maxLogSize_ = 100;
std::string testLogPath = "./size_exceed_log.txt";
logger.fp_ = fopen(testLogPath.c_str(), "w");
strcpy_s(logger.logFilePath_, sizeof(logger.logFilePath_), testLogPath.c_str());
std::string largeLog(90, 'a');
LOG_WARN(largeLog.c_str());
LOG_WARN(largeLog.c_str());
EXPECT_TRUE(FileExists(testLogPath));
EXPECT_EQ(logger.maxLogSize_, 200);
fclose(logger.fp_);
remove(testLogPath.c_str());
logger.fp_ = originalFp;
logger.maxLogSize_ = originalMaxSize;
strcpy_s(logger.logFilePath_, sizeof(logger.logFilePath_), originalLogPath.c_str());
}
TEST(Log, log_with_params_expect_formatted_output)
{
Log &logger = Log::GetLog();
logger.fp_ = fopen("output.txt", "w");
Utility::SetLogLevel(MemScope::LogLv::INFO);
int intParam = 123;
std::string strParam = "test_param";
double doubleParam = 3.14;
LOG_INFO("int: %d, string: %s, double: %.2f", intParam, strParam.c_str(), doubleParam);
logger.fp_ = nullptr;
EXPECT_TRUE(FindStr("output.txt", "int: 123"));
EXPECT_TRUE(FindStr("output.txt", "string: test_param"));
EXPECT_TRUE(FindStr("output.txt", "double: 3.14"));
}
TEST(Log, log_level_debug_expect_all_log_output)
{
Log &logger = Log::GetLog();
logger.fp_ = fopen("output.txt", "w");
Utility::SetLogLevel(MemScope::LogLv::DEBUG);
LOG_DEBUG("debug log");
LOG_INFO("info log");
LOG_WARN("warn log");
LOG_ERROR("error log");
logger.fp_ = nullptr;
EXPECT_TRUE(FindStr("output.txt", "debug log"));
EXPECT_FALSE(FindStr("output.txt", "info log"));
EXPECT_FALSE(FindStr("output.txt", "warn log"));
EXPECT_FALSE(FindStr("output.txt", "error log"));
}
TEST(Log, log_level_error_expect_only_error_output)
{
Log &logger = Log::GetLog();
logger.fp_ = fopen("output.txt", "w");
Utility::SetLogLevel(MemScope::LogLv::ERROR);
LOG_DEBUG("debug log");
LOG_INFO("info log");
LOG_WARN("warn log");
LOG_ERROR("error log");
logger.fp_ = nullptr;
EXPECT_FALSE(FindStr("output.txt", "debug log"));
EXPECT_FALSE(FindStr("output.txt", "info log"));
EXPECT_FALSE(FindStr("output.txt", "warn log"));
EXPECT_TRUE(FindStr("output.txt", "error log"));
}
TEST(Log, multi_thread_log_expect_no_crash)
{
Log &logger = Log::GetLog();
logger.fp_ = fopen("multi_thread_log.txt", "w");
Utility::SetLogLevel(MemScope::LogLv::INFO);
auto logFunc = []() {
for (int i = 0; i < 100; ++i) {
LOG_INFO("thread log: %d", i);
}
};
std::thread threads[10];
for (int i = 0; i < 10; ++i) {
threads[i] = std::thread(logFunc);
}
for (int i = 0; i < 10; ++i) {
threads[i].join();
}
logger.fp_ = nullptr;
EXPECT_TRUE(FileExists("multi_thread_log.txt"));
EXPECT_TRUE(FindStr("multi_thread_log.txt", "thread log"));
remove("multi_thread_log.txt");
}
TEST(Log, log_empty_file_expect_success)
{
Log &logger = Log::GetLog();
logger.fp_ = fopen("empty_file_log.txt", "w");
Utility::SetLogLevel(MemScope::LogLv::DEBUG);
LOG_DEBUG("empty file first log");
logger.fp_ = nullptr;
EXPECT_TRUE(FindStr("empty_file_log.txt", "first log"));
remove("empty_file_log.txt");
}