diff --git a/quill/test/unit_tests/CMakeLists.txt b/quill/test/unit_tests/CMakeLists.txt index 47a2c4c6..3a4d24fd 100644 --- a/quill/test/unit_tests/CMakeLists.txt +++ b/quill/test/unit_tests/CMakeLists.txt @@ -63,6 +63,11 @@ quill_add_test(TEST_TransitEventBuffer TransitEventBufferTest.cpp) quill_add_test(TEST_UnboundedQueue.cpp UnboundedQueueTest.cpp) quill_add_test(TEST_Utility UtilityTest.cpp) +if (NOT QUILL_SANITIZE_THREAD) + # clang++12 thread sanitizer throws exception for unknown reason in the CI + quill_add_test(TEST_UnboundedQueueLimit.cpp UnboundedQueueLimitTest.cpp) +endif () + if (NOT QUILL_USE_VALGRIND) quill_add_test(TEST_RdtscClock RdtscClockTest.cpp) endif () diff --git a/quill/test/unit_tests/UnboundedQueueLimitTest.cpp b/quill/test/unit_tests/UnboundedQueueLimitTest.cpp new file mode 100644 index 00000000..0e19a0d1 --- /dev/null +++ b/quill/test/unit_tests/UnboundedQueueLimitTest.cpp @@ -0,0 +1,66 @@ +#include "doctest/doctest.h" + +#include "quill/core/UnboundedSPSCQueue.h" +#include +#include +#include + +TEST_SUITE_BEGIN("UnboundedQueue"); + +using namespace quill::detail; + +TEST_CASE("unbounded_queue_max_limit") +{ + UnboundedSPSCQueue buffer{1024}; + + constexpr uint64_t half_gb = 500u * 1024u * 1024u; + constexpr uint64_t two_gb = 2u * 1024u * 1024u * 1024u - 1; + constexpr uint64_t three_gb = 3u * 1024u * 1024u * 1024u; + + auto* write_buffer_a = buffer.prepare_write(half_gb, quill::QueueType::UnboundedUnlimited); + REQUIRE(write_buffer_a); + buffer.finish_write(half_gb); + buffer.commit_write(); + + auto* write_buffer_b = buffer.prepare_write(two_gb, quill::QueueType::UnboundedUnlimited); + REQUIRE(write_buffer_b); + buffer.finish_write(two_gb); + buffer.commit_write(); + + // Buffer is filled with two GB here, we can try to reserve more to allocate another queue + auto* write_buffer_c = buffer.prepare_write(two_gb, quill::QueueType::UnboundedBlocking); + REQUIRE_FALSE(write_buffer_c); + + write_buffer_c = buffer.prepare_write(two_gb, quill::QueueType::UnboundedDropping); + REQUIRE_FALSE(write_buffer_c); + + // Buffer is filled with two GB here, we can try to reserve more to allocate another queue + // for the UnboundedLimit queue + write_buffer_c = buffer.prepare_write(two_gb, quill::QueueType::UnboundedUnlimited); + REQUIRE(write_buffer_c); + buffer.finish_write(two_gb); + buffer.commit_write(); + + // Try to allocate over 2GB + REQUIRE_THROWS_AS(QUILL_MAYBE_UNUSED auto* write_buffer_z = + buffer.prepare_write(three_gb, quill::QueueType::UnboundedUnlimited), + quill::QuillError); + + auto read_result_a = buffer.prepare_read(); + REQUIRE(read_result_a.read_pos); + buffer.finish_read(half_gb); + buffer.commit_read(); + + auto read_result_b = buffer.prepare_read(); + REQUIRE(read_result_b.read_pos); + buffer.finish_read(two_gb); + buffer.commit_read(); + + auto read_result_c = buffer.prepare_read(); + REQUIRE(read_result_c.read_pos); + buffer.finish_read(two_gb); + buffer.commit_read(); + + REQUIRE(buffer.empty()); +} +TEST_SUITE_END(); \ No newline at end of file diff --git a/quill/test/unit_tests/UnboundedQueueTest.cpp b/quill/test/unit_tests/UnboundedQueueTest.cpp index c9413de9..0b2cbffa 100644 --- a/quill/test/unit_tests/UnboundedQueueTest.cpp +++ b/quill/test/unit_tests/UnboundedQueueTest.cpp @@ -65,58 +65,4 @@ TEST_CASE("unbounded_queue_read_write_multithreaded_plain_ints") REQUIRE(buffer.empty()); } -TEST_CASE("unbounded_queue_max_limit") -{ - UnboundedSPSCQueue buffer{1024}; - - constexpr uint64_t half_gb = 500u * 1024u * 1024u; - constexpr uint64_t two_gb = 2u * 1024u * 1024u * 1024u - 1; - constexpr uint64_t three_gb = 3u * 1024u * 1024u * 1024u; - - auto* write_buffer_a = buffer.prepare_write(half_gb, quill::QueueType::UnboundedUnlimited); - REQUIRE(write_buffer_a); - buffer.finish_write(half_gb); - buffer.commit_write(); - - auto* write_buffer_b = buffer.prepare_write(two_gb, quill::QueueType::UnboundedUnlimited); - REQUIRE(write_buffer_b); - buffer.finish_write(two_gb); - buffer.commit_write(); - - // Buffer is filled with two GB here, we can try to reserve more to allocate another queue - auto* write_buffer_c = buffer.prepare_write(two_gb, quill::QueueType::UnboundedBlocking); - REQUIRE_FALSE(write_buffer_c); - - write_buffer_c = buffer.prepare_write(two_gb, quill::QueueType::UnboundedDropping); - REQUIRE_FALSE(write_buffer_c); - - // Buffer is filled with two GB here, we can try to reserve more to allocate another queue - // for the UnboundedLimit queue - write_buffer_c = buffer.prepare_write(two_gb, quill::QueueType::UnboundedUnlimited); - REQUIRE(write_buffer_c); - buffer.finish_write(two_gb); - buffer.commit_write(); - - // Try to allocate over 2GB - REQUIRE_THROWS_AS(QUILL_MAYBE_UNUSED auto* write_buffer_z = - buffer.prepare_write(three_gb, quill::QueueType::UnboundedUnlimited), - quill::QuillError); - - auto read_result_a = buffer.prepare_read(); - REQUIRE(read_result_a.read_pos); - buffer.finish_read(half_gb); - buffer.commit_read(); - - auto read_result_b = buffer.prepare_read(); - REQUIRE(read_result_b.read_pos); - buffer.finish_read(two_gb); - buffer.commit_read(); - - auto read_result_c = buffer.prepare_read(); - REQUIRE(read_result_c.read_pos); - buffer.finish_read(two_gb); - buffer.commit_read(); - - REQUIRE(buffer.empty()); -} TEST_SUITE_END(); \ No newline at end of file