This commit is contained in:
2026-02-01 12:56:05 +01:00
parent f51adeecca
commit 0bdbcb1657
857 changed files with 0 additions and 97661 deletions

View File

@@ -0,0 +1,5 @@
idf_component_register(
SRCS "test_logger.cpp"
INCLUDE_DIRS "."
REQUIRES unity logger
)

View File

@@ -0,0 +1,292 @@
/**
* @file test_logger.cpp
* @brief Unit tests for ASF Logger
* @author Mahmoud Elmohtady
* @company Nabd solutions - ASF
* @copyright Copyright (c) 2025
*/
#include "unity.h"
#include "logger.hpp"
#include <cstring>
#include <cstdio>
// Test constants
static const char* TEST_TAG = "TEST_LOGGER";
static const uint32_t TEST_ID = 12345;
/**
* @brief Test logger initialization
*/
void test_logger_initialization()
{
// Test default configuration
asf::logger::LoggerConfig defaultConfig = asf::logger::getDefaultConfig();
TEST_ASSERT_EQUAL(asf::logger::LogLevel::INFO, defaultConfig.minLevel);
TEST_ASSERT_TRUE(defaultConfig.enableTimestamp);
TEST_ASSERT_TRUE(defaultConfig.enableColor);
TEST_ASSERT_TRUE(defaultConfig.enableId);
TEST_ASSERT_EQUAL(256, defaultConfig.maxMessageLength);
// Test custom configuration
asf::logger::LoggerConfig customConfig = {};
customConfig.minLevel = asf::logger::LogLevel::DEBUG;
customConfig.enableTimestamp = false;
customConfig.enableColor = false;
customConfig.enableId = false;
customConfig.maxMessageLength = 128;
asf::logger::initialize(customConfig);
TEST_ASSERT_EQUAL(asf::logger::LogLevel::DEBUG, asf::logger::getLogLevel());
}
/**
* @brief Test log level functionality
*/
void test_log_levels()
{
// Test setting different log levels
asf::logger::setLogLevel(asf::logger::LogLevel::VERBOSE);
TEST_ASSERT_EQUAL(asf::logger::LogLevel::VERBOSE, asf::logger::getLogLevel());
asf::logger::setLogLevel(asf::logger::LogLevel::DEBUG);
TEST_ASSERT_EQUAL(asf::logger::LogLevel::DEBUG, asf::logger::getLogLevel());
asf::logger::setLogLevel(asf::logger::LogLevel::INFO);
TEST_ASSERT_EQUAL(asf::logger::LogLevel::INFO, asf::logger::getLogLevel());
asf::logger::setLogLevel(asf::logger::LogLevel::WARNING);
TEST_ASSERT_EQUAL(asf::logger::LogLevel::WARNING, asf::logger::getLogLevel());
asf::logger::setLogLevel(asf::logger::LogLevel::ERROR);
TEST_ASSERT_EQUAL(asf::logger::LogLevel::ERROR, asf::logger::getLogLevel());
asf::logger::setLogLevel(asf::logger::LogLevel::NONE);
TEST_ASSERT_EQUAL(asf::logger::LogLevel::NONE, asf::logger::getLogLevel());
}
/**
* @brief Test log level to string conversion
*/
void test_log_level_to_string()
{
TEST_ASSERT_EQUAL_STRING("VERBOSE", asf::logger::logLevelToString(asf::logger::LogLevel::VERBOSE));
TEST_ASSERT_EQUAL_STRING("DEBUG", asf::logger::logLevelToString(asf::logger::LogLevel::DEBUG));
TEST_ASSERT_EQUAL_STRING("INFO", asf::logger::logLevelToString(asf::logger::LogLevel::INFO));
TEST_ASSERT_EQUAL_STRING("WARNING", asf::logger::logLevelToString(asf::logger::LogLevel::WARNING));
TEST_ASSERT_EQUAL_STRING("ERROR", asf::logger::logLevelToString(asf::logger::LogLevel::ERROR));
TEST_ASSERT_EQUAL_STRING("NONE", asf::logger::logLevelToString(asf::logger::LogLevel::NONE));
}
/**
* @brief Test log level to color conversion
*/
void test_log_level_to_color()
{
// Test that color codes are returned (non-empty strings)
const char* verboseColor = asf::logger::logLevelToColor(asf::logger::LogLevel::VERBOSE);
const char* debugColor = asf::logger::logLevelToColor(asf::logger::LogLevel::DEBUG);
const char* infoColor = asf::logger::logLevelToColor(asf::logger::LogLevel::INFO);
const char* warningColor = asf::logger::logLevelToColor(asf::logger::LogLevel::WARNING);
const char* errorColor = asf::logger::logLevelToColor(asf::logger::LogLevel::ERROR);
TEST_ASSERT_NOT_NULL(verboseColor);
TEST_ASSERT_NOT_NULL(debugColor);
TEST_ASSERT_NOT_NULL(infoColor);
TEST_ASSERT_NOT_NULL(warningColor);
TEST_ASSERT_NOT_NULL(errorColor);
// Test that different levels have different colors
TEST_ASSERT_NOT_EQUAL_STRING(verboseColor, debugColor);
TEST_ASSERT_NOT_EQUAL_STRING(debugColor, infoColor);
TEST_ASSERT_NOT_EQUAL_STRING(infoColor, warningColor);
TEST_ASSERT_NOT_EQUAL_STRING(warningColor, errorColor);
}
/**
* @brief Test ISO timestamp generation
*/
void test_iso_timestamp()
{
char timestampBuffer[32];
const char* timestamp = asf::logger::getIsoTimestamp(timestampBuffer, sizeof(timestampBuffer));
TEST_ASSERT_NOT_NULL(timestamp);
TEST_ASSERT_GREATER_THAN(0, strlen(timestamp));
// Check basic format (should contain 'T' and 'Z')
TEST_ASSERT_NOT_NULL(strchr(timestamp, 'T'));
TEST_ASSERT_NOT_NULL(strchr(timestamp, 'Z'));
// Test with insufficient buffer
char smallBuffer[10];
const char* smallTimestamp = asf::logger::getIsoTimestamp(smallBuffer, sizeof(smallBuffer));
TEST_ASSERT_EQUAL_STRING("", smallTimestamp);
// Test with null buffer
const char* nullTimestamp = asf::logger::getIsoTimestamp(nullptr, 32);
TEST_ASSERT_EQUAL_STRING("", nullTimestamp);
}
/**
* @brief Test configuration toggles
*/
void test_configuration_toggles()
{
// Test timestamp toggle
asf::logger::enableTimestamp(true);
// No direct way to test this without capturing output, but ensure no crash
asf::logger::enableTimestamp(false);
// No direct way to test this without capturing output, but ensure no crash
// Test color toggle
asf::logger::enableColor(true);
// No direct way to test this without capturing output, but ensure no crash
asf::logger::enableColor(false);
// No direct way to test this without capturing output, but ensure no crash
// Test ID toggle
asf::logger::enableId(true);
// No direct way to test this without capturing output, but ensure no crash
asf::logger::enableId(false);
// No direct way to test this without capturing output, but ensure no crash
}
/**
* @brief Test basic logging functions
*/
void test_basic_logging()
{
// Initialize logger with verbose level to test all functions
asf::logger::LoggerConfig config = asf::logger::getDefaultConfig();
config.minLevel = asf::logger::LogLevel::VERBOSE;
asf::logger::initialize(config);
// Test all logging functions (should not crash)
asf::logger::logVerbose(TEST_TAG, TEST_ID, "Verbose message: %d", 1);
asf::logger::logDebug(TEST_TAG, TEST_ID, "Debug message: %d", 2);
asf::logger::logInfo(TEST_TAG, TEST_ID, "Info message: %d", 3);
asf::logger::logWarning(TEST_TAG, TEST_ID, "Warning message: %d", 4);
asf::logger::logError(TEST_TAG, TEST_ID, "Error message: %d", 5);
// Test main log function
asf::logger::log(TEST_TAG, TEST_ID, asf::logger::LogLevel::INFO, "Main log function: %s", "test");
}
/**
* @brief Test logging macros
*/
void test_logging_macros()
{
// Initialize logger with verbose level
asf::logger::LoggerConfig config = asf::logger::getDefaultConfig();
config.minLevel = asf::logger::LogLevel::VERBOSE;
asf::logger::initialize(config);
// Test all macros (should not crash)
ASF_LOG_VERBOSE(TEST_TAG, TEST_ID, "Verbose macro: %d", 1);
ASF_LOG_DEBUG(TEST_TAG, TEST_ID, "Debug macro: %d", 2);
ASF_LOG_INFO(TEST_TAG, TEST_ID, "Info macro: %d", 3);
ASF_LOG_WARNING(TEST_TAG, TEST_ID, "Warning macro: %d", 4);
ASF_LOG_ERROR(TEST_TAG, TEST_ID, "Error macro: %d", 5);
// Test short form macros
ASF_LOGV(TEST_TAG, TEST_ID, "Verbose short macro: %d", 1);
ASF_LOGD(TEST_TAG, TEST_ID, "Debug short macro: %d", 2);
ASF_LOGI(TEST_TAG, TEST_ID, "Info short macro: %d", 3);
ASF_LOGW(TEST_TAG, TEST_ID, "Warning short macro: %d", 4);
ASF_LOGE(TEST_TAG, TEST_ID, "Error short macro: %d", 5);
}
/**
* @brief Test log level filtering
*/
void test_log_level_filtering()
{
// Set log level to WARNING
asf::logger::setLogLevel(asf::logger::LogLevel::WARNING);
// These should be filtered out (no crash expected)
asf::logger::logVerbose(TEST_TAG, TEST_ID, "This should be filtered");
asf::logger::logDebug(TEST_TAG, TEST_ID, "This should be filtered");
asf::logger::logInfo(TEST_TAG, TEST_ID, "This should be filtered");
// These should pass through (no crash expected)
asf::logger::logWarning(TEST_TAG, TEST_ID, "This should pass");
asf::logger::logError(TEST_TAG, TEST_ID, "This should pass");
}
/**
* @brief Test null parameter handling
*/
void test_null_parameters()
{
// Test with null tag (should not crash)
asf::logger::logInfo(nullptr, TEST_ID, "Test message");
// Test with null format (should not crash)
asf::logger::logInfo(TEST_TAG, TEST_ID, nullptr);
// Test main log function with null parameters
asf::logger::log(nullptr, TEST_ID, asf::logger::LogLevel::INFO, "Test message");
asf::logger::log(TEST_TAG, TEST_ID, asf::logger::LogLevel::INFO, nullptr);
}
/**
* @brief Test long messages
*/
void test_long_messages()
{
// Create a long message
char longMessage[512];
memset(longMessage, 'A', sizeof(longMessage) - 1);
longMessage[sizeof(longMessage) - 1] = '\0';
// Should handle long messages gracefully (truncate if necessary)
asf::logger::logInfo(TEST_TAG, TEST_ID, "Long message: %s", longMessage);
}
/**
* @brief Test performance (basic timing)
*/
void test_performance()
{
// Set to ERROR level to minimize output
asf::logger::setLogLevel(asf::logger::LogLevel::ERROR);
// Perform many log calls that should be filtered out
for (int i = 0; i < 1000; i++) {
asf::logger::logInfo(TEST_TAG, i, "Performance test message %d", i);
}
// This test mainly ensures no crashes during high-frequency logging
TEST_ASSERT_TRUE(true); // If we reach here, performance test passed
}
/**
* @brief Run all logger tests
*/
extern "C" void app_main()
{
UNITY_BEGIN();
RUN_TEST(test_logger_initialization);
RUN_TEST(test_log_levels);
RUN_TEST(test_log_level_to_string);
RUN_TEST(test_log_level_to_color);
RUN_TEST(test_iso_timestamp);
RUN_TEST(test_configuration_toggles);
RUN_TEST(test_basic_logging);
RUN_TEST(test_logging_macros);
RUN_TEST(test_log_level_filtering);
RUN_TEST(test_null_parameters);
RUN_TEST(test_long_messages);
RUN_TEST(test_performance);
UNITY_END();
}