Skip to content

Commit 24ec834

Browse files
committed
storage: add test_concurrent_segment_roll_and_close
To test race conditions between `segment::close()` and a segment roll, particularly one which goes through `release_appender_in_background()`.
1 parent c0d76d1 commit 24ec834

File tree

1 file changed

+39
-0
lines changed

1 file changed

+39
-0
lines changed

src/v/storage/tests/storage_e2e_fixture_test.cc

+39
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
#include "storage/tests/storage_e2e_fixture.h"
1616
#include "test_utils/fixture.h"
1717

18+
#include <seastar/core/future.hh>
1819
#include <seastar/core/io_priority_class.hh>
1920
#include <seastar/core/lowres_clock.hh>
2021

@@ -25,6 +26,16 @@
2526

2627
using namespace std::chrono_literals;
2728

29+
namespace {
30+
ss::future<> force_roll_log(storage::disk_log_impl* log) {
31+
try {
32+
co_await log->force_roll(ss::default_priority_class());
33+
} catch (...) {
34+
}
35+
}
36+
37+
} // namespace
38+
2839
FIXTURE_TEST(test_compaction_segment_ms, storage_e2e_fixture) {
2940
test_local_cfg.get("log_segment_ms_min")
3041
.set_value(std::chrono::duration_cast<std::chrono::milliseconds>(1ms));
@@ -156,3 +167,31 @@ FIXTURE_TEST(test_concurrent_log_eviction_and_append, storage_e2e_fixture) {
156167
// final round of eviction.
157168
BOOST_REQUIRE_LE(log->segment_count(), 1);
158169
}
170+
171+
FIXTURE_TEST(test_concurrent_segment_roll_and_close, storage_e2e_fixture) {
172+
const auto topic_name = model::topic("tapioca");
173+
const auto ntp = model::ntp(model::kafka_namespace, topic_name, 0);
174+
175+
cluster::topic_properties props;
176+
add_topic({model::kafka_namespace, topic_name}, 1, props).get();
177+
wait_for_leader(ntp).get();
178+
179+
auto partition = app.partition_manager.local().get(ntp);
180+
auto* log = dynamic_cast<storage::disk_log_impl*>(partition->log().get());
181+
auto seg = log->segments().back();
182+
183+
// Hold a read lock, which will force release_appender() to go through
184+
// release_appender_in_background()
185+
auto read_lock_holder = seg->read_lock().get();
186+
187+
auto roll_fut = force_roll_log(log);
188+
auto release_holder_fut = ss::sleep(100ms).then(
189+
[read_locker_holder = std::move(read_lock_holder)] {});
190+
auto remove_segment_fut = remove_segment_permanently(log, seg);
191+
192+
ss::when_all(
193+
std::move(roll_fut),
194+
std::move(remove_segment_fut),
195+
std::move(release_holder_fut))
196+
.get();
197+
}

0 commit comments

Comments
 (0)