diff --git a/CMakeLists.txt b/CMakeLists.txt index 05a4ba9c..a1ba9eae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,7 +5,7 @@ project(quill) # Options #------------------------------------------------------------------------------------------------------- -option(QUILL_NO_EXCEPTIONS "Enable this option to build Quill without exception handling support." OFF) +option(QUILL_NO_EXCEPTIONS "Enable this option to build without exception handling support." OFF) option(QUILL_NO_THREAD_NAME_SUPPORT "Enable this option to disable features that require thread name retrieval, ensuring compatibility with older Windows versions (e.g., Windows Server 2012/2016) and Android." OFF) @@ -15,9 +15,11 @@ option(QUILL_DISABLE_NON_PREFIXED_MACROS "Enable this option to disable non-pref option(QUILL_BUILD_EXAMPLES "Enable this option to build and install the examples. Set this to ON to include example projects in the build process and have them installed after configuring with CMake." OFF) -option(QUILL_BUILD_TESTS "Enable this option to build the test suite for Quill." OFF) +option(QUILL_BUILD_TESTS "Enable this option to build the test suite." OFF) -option(QUILL_BUILD_BENCHMARKS "Enable this option to build the benchmark tests for Quill." OFF) +option(QUILL_ENABLE_EXTENSIVE_TESTS "Enable extensive tests that may require more resources and are not suitable for hosted CI runners." OFF) + +option(QUILL_BUILD_BENCHMARKS "Enable this option to build the benchmarks." OFF) option(QUILL_SANITIZE_ADDRESS "Enable AddressSanitizer (ASan) for memory error detection in tests." OFF) @@ -29,7 +31,7 @@ option(QUILL_USE_VALGRIND "Use Valgrind as the default memory checking tool in C option(QUILL_ENABLE_INSTALL "Enable the CMake install target when Quill is not the master project." OFF) -option(QUILL_DOCS_GEN "Generate documentation for Quill during the build process." OFF) +option(QUILL_DOCS_GEN "Generate documentation during the build process." OFF) #------------------------------------------------------------------------------------------------------- # Use newer policies if possible, up to most recent tested version of CMake. @@ -98,6 +100,11 @@ if (QUILL_BUILD_TESTS) endif () endif () +# Error out if QUILL_ENABLE_EXTENSIVE_TESTS is ON but QUILL_BUILD_TESTS is OFF +if (QUILL_ENABLE_EXTENSIVE_TESTS AND NOT QUILL_BUILD_TESTS) + message(FATAL_ERROR "QUILL_ENABLE_EXTENSIVE_TESTS requires QUILL_BUILD_TESTS to be enabled. Please enable QUILL_BUILD_TESTS.") +endif () + #------------------------------------------------------------------------------------------------------- # Log Info #------------------------------------------------------------------------------------------------------- diff --git a/test/integration_tests/CMakeLists.txt b/test/integration_tests/CMakeLists.txt index 750546e5..3fde401b 100644 --- a/test/integration_tests/CMakeLists.txt +++ b/test/integration_tests/CMakeLists.txt @@ -31,6 +31,10 @@ function(quill_add_test TEST_NAME SOURCES) # Link dependencies target_link_libraries(${TEST_NAME} quill) + if (QUILL_ENABLE_EXTENSIVE_TESTS) + target_compile_definitions(${TEST_NAME} PRIVATE QUILL_ENABLE_EXTENSIVE_TESTS) + endif () + # Do not decay cxx standard if not specified set_property(TARGET ${TEST_NAME} PROPERTY CXX_STANDARD_REQUIRED ON) @@ -111,6 +115,7 @@ quill_add_test(TEST_StringRandomLogging StringRandomLoggingTest.cpp) quill_add_test(TEST_StringRandomSmallLogging StringRandomSmallLoggingTest.cpp) quill_add_test(TEST_StringRef StringRefTest.cpp) quill_add_test(TEST_TagsLogging TagsLoggingTest.cpp) +quill_add_test(TEST_UnboundedUnlimitedQueue UnboundedUnlimitedQueueTest.cpp) quill_add_test(TEST_UserClockSource UserClockSourceTest.cpp) quill_add_test(TEST_UserDefinedTypeLogging UserDefinedTypeLoggingTest.cpp) quill_add_test(TEST_UserSink UserSinkTest.cpp) @@ -122,4 +127,4 @@ target_compile_definitions(TEST_CompileActiveLogLevel PRIVATE -DQUILL_COMPILE_AC if (WIN32) quill_add_test(TEST_WideStdTypesLogging WideStdTypesLoggingTest.cpp) quill_add_test(TEST_WideStringLogging WideStringLoggingTest.cpp) -endif () +endif () \ No newline at end of file diff --git a/test/integration_tests/StringLoggingTest.cpp b/test/integration_tests/StringLoggingTest.cpp index 05587f84..f21cf54b 100644 --- a/test/integration_tests/StringLoggingTest.cpp +++ b/test/integration_tests/StringLoggingTest.cpp @@ -139,7 +139,7 @@ TEST_CASE("string_logging") c_style_string, end_s, c_style_char_array_empty, c_style_char_array); } - // Log a big string + // Log a string for (size_t i = 0; i < number_of_messages; ++i) { std::string v{"Lorem ipsum dolor sit amet, consectetur "}; @@ -219,7 +219,7 @@ TEST_CASE("string_logging") file_contents, std::string{"LOG_INFO " + logger_name + " Logging int: 0, int: 0, string: Lorem ipsum dolor sit amet, consectetur 0, char: Lorem ipsum dolor sit amet, consectetur 0"})); REQUIRE(quill::testing::file_contains( - file_contents, std::string{"LOG_INFO " + logger_name + " Logging int: 1999, int: 19990, string: Lorem ipsum dolor sit amet, consectetur 1999, char: Lorem ipsum dolor sit amet, consectetur 1999"})); + file_contents, std::string{"LOG_INFO " + logger_name + " Logging int: 9999, int: 99990, string: Lorem ipsum dolor sit amet, consectetur 9999, char: Lorem ipsum dolor sit amet, consectetur 9999"})); testing::remove_file(filename); } \ No newline at end of file diff --git a/test/integration_tests/UnboundedUnlimitedQueueTest.cpp b/test/integration_tests/UnboundedUnlimitedQueueTest.cpp new file mode 100644 index 00000000..281998eb --- /dev/null +++ b/test/integration_tests/UnboundedUnlimitedQueueTest.cpp @@ -0,0 +1,89 @@ +#include "doctest/doctest.h" + +#include "misc/TestUtilities.h" +#include "quill/Backend.h" +#include "quill/Frontend.h" +#include "quill/LogMacros.h" +#include "quill/sinks/FileSink.h" + +#include +#include + +using namespace quill; + +// Define custom Frontend Options +struct CustomFrontendOptions +{ + static constexpr quill::QueueType queue_type = quill::QueueType::UnboundedUnlimited; + static constexpr uint32_t initial_queue_capacity = 131'072; + static constexpr uint32_t blocking_queue_retry_interval_ns = 800; + static constexpr bool huge_pages_enabled = false; +}; + +using CustomFrontend = FrontendImpl; +using CustomLogger = LoggerImpl; + +TEST_CASE("unbounded_unlimited_queue") +{ + static constexpr char const* filename = "unbounded_unlimited_queue.log"; + static std::string const logger_name = "logger"; + static constexpr size_t number_of_messages = 1000; + + // Start the logging backend thread + Backend::start(); + + auto file_sink = CustomFrontend::create_or_get_sink( + filename, + []() + { + FileSinkConfig cfg; + cfg.set_open_mode('w'); + return cfg; + }(), + FileEventNotifier{}); + + CustomLogger* logger = CustomFrontend::create_or_get_logger(logger_name, std::move(file_sink)); + + // Log a string + for (size_t i = 0; i < number_of_messages; ++i) + { + std::string v{"Lorem ipsum dolor sit amet, consectetur "}; + v += std::to_string(i); + + LOG_INFO(logger, "Logging int: {}, int: {}, string: {}, char: {}", i, i * 10, v, v.c_str()); + } + +#ifdef QUILL_ENABLE_EXTENSIVE_TESTS + // log a very large string + std::string const very_large(std::numeric_limits::max(), 'A'); + LOG_INFO(logger, "Very large string {}", very_large); +#endif + + logger->flush_log(); + Frontend::remove_logger(logger); + + // Wait until the backend thread stops for test stability + Backend::stop(); + + // Read file and check + std::vector const file_contents = quill::testing::file_contents(filename); + +#ifdef QUILL_ENABLE_EXTENSIVE_TESTS + REQUIRE_EQ(file_contents.size(), number_of_messages + 1); +#else + REQUIRE_EQ(file_contents.size(), number_of_messages); +#endif + + REQUIRE(quill::testing::file_contains( + file_contents, std::string{"LOG_INFO " + logger_name + " Logging int: 0, int: 0, string: Lorem ipsum dolor sit amet, consectetur 0, char: Lorem ipsum dolor sit amet, consectetur 0"})); + + REQUIRE(quill::testing::file_contains( + file_contents, std::string{"LOG_INFO " + logger_name + " Logging int: 999, int: 9990, string: Lorem ipsum dolor sit amet, consectetur 999, char: Lorem ipsum dolor sit amet, consectetur 999"})); + +#ifdef QUILL_ENABLE_EXTENSIVE_TESTS + REQUIRE(quill::testing::file_contains( + file_contents, std::string{"LOG_INFO " + logger_name + " Very large string"})); +#endif + + testing::remove_file(filename); +}