From df56f6bdc2086ab3cd9684eba333099561276c19 Mon Sep 17 00:00:00 2001 From: Calle Wilund Date: Mon, 16 Mar 2026 20:13:32 +0100 Subject: [PATCH] memtable_test::memtable_flush_period: Change sleep to use injection signal instead Fixes: SCYLLADB-942 Adds an injection signal _from_ table::seal_active_memtable to allow us to reliably wait for flushing. And does so. Closes scylladb/scylladb#29070 (cherry picked from commit 0013f22374bd659218477153e36bf91527070385) Closes scylladb/scylladb#29116 --- replica/table.cc | 4 +++- test/boost/memtable_test.cc | 28 +++++++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/replica/table.cc b/replica/table.cc index 5cbf3781ea..25bbe4f42b 100644 --- a/replica/table.cc +++ b/replica/table.cc @@ -1766,7 +1766,9 @@ table::seal_active_memtable(compaction_group& cg, flush_permit&& flush_permit) n utils::get_local_injector().inject("table_seal_active_memtable_try_flush", []() { throw std::system_error(ENOSPC, std::system_category(), "Injected error"); }); - co_return co_await this->try_flush_memtable_to_sstable(cg, old, std::move(write_permit)); + co_await this->try_flush_memtable_to_sstable(cg, old, std::move(write_permit)); + // signal a memtable was sealed + utils::get_local_injector().receive_message("table_seal_post_flush_waiters"); }); undo_stats.reset(); diff --git a/test/boost/memtable_test.cc b/test/boost/memtable_test.cc index 45f206b7ed..bb692de239 100644 --- a/test/boost/memtable_test.cc +++ b/test/boost/memtable_test.cc @@ -1004,7 +1004,20 @@ SEASTAR_TEST_CASE(memtable_flush_compresses_mutations) { }, db_config); } -SEASTAR_TEST_CASE(memtable_flush_period) { +static auto check_has_error_injection() { + return boost::unit_test::precondition([](auto){ + return +#ifdef SCYLLA_ENABLE_ERROR_INJECTION + true +#else + false +#endif + ; + }); +} + +SEASTAR_TEST_CASE(memtable_flush_period, *check_has_error_injection()) { +#ifdef SCYLLA_ENABLE_ERROR_INJECTION auto db_config = make_shared(); db_config->enable_cache.set(false); return do_with_cql_env_thread([](cql_test_env& env) { @@ -1028,6 +1041,9 @@ SEASTAR_TEST_CASE(memtable_flush_period) { t.apply(m); BOOST_REQUIRE_EQUAL(t.sstables_count(), 0); // add mutation and check there are no sstables for this table + auto& errj = utils::get_local_injector(); + errj.enable("table_seal_post_flush_waiters", true); + // change schema to set memtable flush period // we use small value in this test but it is impossible to set the period less than 60000ms using ALTER TABLE construction schema_builder b(t.schema()); @@ -1035,8 +1051,10 @@ SEASTAR_TEST_CASE(memtable_flush_period) { schema_ptr s2 = b.build(); t.set_schema(s2); - sleep(500ms).get(); // wait until memtable flush starts at least once - BOOST_REQUIRE(t.sstables_count() == 1 || t.get_stats().pending_flushes > 0); // flush started + BOOST_TEST_MESSAGE("Wait for flush"); + errj.inject("table_seal_post_flush_waiters", utils::wait_for_message(std::chrono::minutes(2))).get(); + BOOST_TEST_MESSAGE("Flush received"); + BOOST_REQUIRE(eventually_true([&] { // wait until memtable will be flushed at least once return t.sstables_count() == 1; })); @@ -1047,6 +1065,10 @@ SEASTAR_TEST_CASE(memtable_flush_period) { .produces(m) .produces_end_of_stream(); }, db_config); +#else + BOOST_TEST_MESSAGE("Skipping test as it depends on error injection. Please run in mode where it's enabled (debug,dev)"); + return make_ready_future<>(); +#endif } SEASTAR_TEST_CASE(sstable_compaction_does_not_resurrect_data) {