From: Oguzhan Ozmen Date: Tue, 12 May 2026 19:31:04 +0000 (+0000) Subject: test/neocls/log trimming: reproduce log trimming can go into an infinite loop X-Git-Tag: v21.0.1~141^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=fe1a5a585a82edac88c3511348c416569cb6b134;p=ceph.git test/neocls/log trimming: reproduce log trimming can go into an infinite loop Add two tests that calls trim() loop function directly (the use_awaitable_t overloads) rather than the single-op wrapper used by existing tests. Two test cases for the marker-based overload: - trim_loop_all_entries_by_marker: writes 10 entries, trims all, verifies the loop terminates and entries are gone. - trim_loop_empty_log_by_marker: trims an empty log object, verifying the loop terminates on immediate ENODATA. Without the fix in the following commits, both tests hang indefinitely. - start a vstart cluster - run the test: [build] $ ./bin/ceph_test_neocls_log - the test introduced in this commit stalls forever: ... RUN ] neocls_log.trim_loop_all_entries_by_marker <-- stalls forever Reproduces: https://tracker.ceph.com/issues/76563 Signed-off-by: Oguzhan Ozmen --- diff --git a/src/test/cls_log/test_neocls_log.cc b/src/test/cls_log/test_neocls_log.cc index f5f4ae3fdfa0..78a2e0cfca90 100644 --- a/src/test/cls_log/test_neocls_log.cc +++ b/src/test/cls_log/test_neocls_log.cc @@ -473,6 +473,48 @@ CORO_TEST_F(neocls_log, trim_by_marker, NeoRadosTest) } } +// Test the neorados::trim() loop function (use_awaitable overloads) to verify +// it terminates. Before any fix in neorados/cls/log.h, the use_awaitable_t +// overloads had the try-catch for ENODATA inside the for(;;) loop, causing +// the loop to never exit in certain cluster configs and this CPU hogging. +CORO_TEST_F(neocls_log, trim_loop_all_entries_by_marker, NeoRadosTest) +{ + co_await create_obj(oid); + auto start_time = real_clock::now(); + + // write 10 cls_log entries into the object + co_await generate_log(rados(), oid, pool(), 10, start_time, true, + asio::use_awaitable); + + // call trim() loop function. Without a fix, this never returns + // because of where the try-catch sits relative to the for(;;) + co_await neorados::cls::log::trim( + rados(), oid, pool(), + std::string_view{neorados::cls::log::begin_marker}, + std::string_view{neorados::cls::log::end_marker}, + asio::use_awaitable); + + // Verify all entries are gone + std::vector entries{neorados::cls::log::max_list_entries}; + std::span result; + co_await list(rados(), oid, pool(), entries, &result, asio::use_awaitable); + EXPECT_EQ(0u, result.size()); +} + +CORO_TEST_F(neocls_log, trim_loop_empty_log_by_marker, NeoRadosTest) +{ + co_await create_obj(oid); + + // Trim an empty log object. With the bug, cls_log_trim returns ENODATA, + // which is caught and swallowed inside the for(;;), looping forever. + co_await neorados::cls::log::trim( + rados(), oid, pool(), + std::string_view{neorados::cls::log::begin_marker}, + std::string_view{neorados::cls::log::end_marker}, + asio::use_awaitable); +} + + #if 0 // Disable until we get rid of GCC11 TEST(neocls_log_bare, lambdata) {