1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "test/librbd/test_mock_fixture.h"
5 #include "test/librbd/test_support.h"
6 #include "test/librbd/mock/MockImageCtx.h"
7 #include "librbd/io/ImageRequest.h"
8 #include "librbd/journal/Replay.h"
9 #include "librbd/journal/Types.h"
10 #include "gmock/gmock.h"
11 #include "gtest/gtest.h"
12 #include <boost/scope_exit.hpp>
18 struct MockReplayImageCtx : public MockImageCtx {
19 MockReplayImageCtx(ImageCtx &image_ctx) : MockImageCtx(image_ctx) {
23 } // anonymous namespace
28 struct ImageRequest<MockReplayImageCtx> {
29 static ImageRequest *s_instance;
31 MOCK_METHOD4(aio_write, void(AioCompletion *c, const Extents &image_extents,
32 const bufferlist &bl, int op_flags));
33 static void aio_write(MockReplayImageCtx *ictx, AioCompletion *c,
34 Extents &&image_extents, bufferlist &&bl,
35 int op_flags, const ZTracer::Trace &parent_trace) {
36 assert(s_instance != nullptr);
37 s_instance->aio_write(c, image_extents, bl, op_flags);
40 MOCK_METHOD4(aio_discard, void(AioCompletion *c, uint64_t off, uint64_t len,
41 bool skip_partial_discard));
42 static void aio_discard(MockReplayImageCtx *ictx, AioCompletion *c,
43 uint64_t off, uint64_t len,
44 bool skip_partial_discard,
45 const ZTracer::Trace &parent_trace) {
46 assert(s_instance != nullptr);
47 s_instance->aio_discard(c, off, len, skip_partial_discard);
50 MOCK_METHOD1(aio_flush, void(AioCompletion *c));
51 static void aio_flush(MockReplayImageCtx *ictx, AioCompletion *c,
52 const ZTracer::Trace &parent_trace) {
53 assert(s_instance != nullptr);
54 s_instance->aio_flush(c);
57 MOCK_METHOD5(aio_writesame, void(AioCompletion *c, uint64_t off, uint64_t len,
58 const bufferlist &bl, int op_flags));
59 static void aio_writesame(MockReplayImageCtx *ictx, AioCompletion *c,
60 uint64_t off, uint64_t len, bufferlist &&bl,
61 int op_flags, const ZTracer::Trace &parent_trace) {
62 assert(s_instance != nullptr);
63 s_instance->aio_writesame(c, off, len, bl, op_flags);
66 MOCK_METHOD6(aio_compare_and_write, void(AioCompletion *c, const Extents &image_extents,
67 const bufferlist &cmp_bl, const bufferlist &bl,
68 uint64_t *mismatch_offset, int op_flags));
69 static void aio_compare_and_write(MockReplayImageCtx *ictx, AioCompletion *c,
70 Extents &&image_extents, bufferlist &&cmp_bl,
71 bufferlist &&bl, uint64_t *mismatch_offset,
72 int op_flags, const ZTracer::Trace &parent_trace) {
73 assert(s_instance != nullptr);
74 s_instance->aio_compare_and_write(c, image_extents, cmp_bl, bl,
75 mismatch_offset, op_flags);
83 ImageRequest<MockReplayImageCtx> *ImageRequest<MockReplayImageCtx>::s_instance = nullptr;
89 inline ImageCtx *get_image_ctx(librbd::MockReplayImageCtx *image_ctx) {
90 return image_ctx->image_ctx;
97 // template definitions
98 #include "librbd/journal/Replay.cc"
99 template class librbd::journal::Replay<librbd::MockReplayImageCtx>;
102 using ::testing::DoAll;
103 using ::testing::InSequence;
104 using ::testing::Return;
105 using ::testing::SaveArg;
106 using ::testing::StrEq;
107 using ::testing::WithArgs;
109 MATCHER_P(BufferlistEqual, str, "") {
111 return (strncmp(bl.c_str(), str, strlen(str)) == 0);
114 MATCHER_P(CStrEq, str, "") {
115 return (strncmp(arg, str, strlen(str)) == 0);
118 ACTION_P2(NotifyInvoke, lock, cond) {
119 Mutex::Locker locker(*lock);
123 ACTION_P2(CompleteAioCompletion, r, image_ctx) {
124 image_ctx->op_work_queue->queue(new FunctionContext([this, arg0](int r) {
126 arg0->init_time(image_ctx, librbd::io::AIO_TYPE_NONE);
127 arg0->set_request_count(1);
128 arg0->complete_request(r);
135 class TestMockJournalReplay : public TestMockFixture {
137 typedef io::ImageRequest<MockReplayImageCtx> MockIoImageRequest;
138 typedef Replay<MockReplayImageCtx> MockJournalReplay;
140 TestMockJournalReplay() : m_invoke_lock("m_invoke_lock") {
143 void expect_accept_ops(MockExclusiveLock &mock_exclusive_lock, bool accept) {
144 EXPECT_CALL(mock_exclusive_lock, accept_ops()).WillRepeatedly(
148 void expect_aio_discard(MockIoImageRequest &mock_io_image_request,
149 io::AioCompletion **aio_comp, uint64_t off,
150 uint64_t len, bool skip_partial_discard) {
151 EXPECT_CALL(mock_io_image_request, aio_discard(_, off, len, skip_partial_discard))
152 .WillOnce(SaveArg<0>(aio_comp));
155 void expect_aio_flush(MockIoImageRequest &mock_io_image_request,
156 io::AioCompletion **aio_comp) {
157 EXPECT_CALL(mock_io_image_request, aio_flush(_))
158 .WillOnce(SaveArg<0>(aio_comp));
161 void expect_aio_flush(MockReplayImageCtx &mock_image_ctx,
162 MockIoImageRequest &mock_io_image_request, int r) {
163 EXPECT_CALL(mock_io_image_request, aio_flush(_))
164 .WillOnce(CompleteAioCompletion(r, mock_image_ctx.image_ctx));
167 void expect_aio_write(MockIoImageRequest &mock_io_image_request,
168 io::AioCompletion **aio_comp, uint64_t off,
169 uint64_t len, const char *data) {
170 EXPECT_CALL(mock_io_image_request,
171 aio_write(_, io::Extents{{off, len}}, BufferlistEqual(data), _))
172 .WillOnce(SaveArg<0>(aio_comp));
175 void expect_aio_writesame(MockIoImageRequest &mock_io_image_request,
176 io::AioCompletion **aio_comp, uint64_t off,
177 uint64_t len, const char *data) {
178 EXPECT_CALL(mock_io_image_request,
179 aio_writesame(_, off, len, BufferlistEqual(data), _))
180 .WillOnce(SaveArg<0>(aio_comp));
183 void expect_aio_compare_and_write(MockIoImageRequest &mock_io_image_request,
184 io::AioCompletion **aio_comp, uint64_t off,
185 uint64_t len, const char *cmp_data, const char *data,
186 uint64_t *mismatch_offset) {
187 EXPECT_CALL(mock_io_image_request,
188 aio_compare_and_write(_, io::Extents{{off, len}},
189 BufferlistEqual(cmp_data), BufferlistEqual(data), mismatch_offset, _))
190 .WillOnce(SaveArg<0>(aio_comp));
193 void expect_flatten(MockReplayImageCtx &mock_image_ctx, Context **on_finish) {
194 EXPECT_CALL(*mock_image_ctx.operations, execute_flatten(_, _))
195 .WillOnce(DoAll(SaveArg<1>(on_finish),
196 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
199 void expect_rename(MockReplayImageCtx &mock_image_ctx, Context **on_finish,
200 const char *image_name) {
201 EXPECT_CALL(*mock_image_ctx.operations, execute_rename(StrEq(image_name), _))
202 .WillOnce(DoAll(SaveArg<1>(on_finish),
203 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
206 void expect_resize(MockReplayImageCtx &mock_image_ctx, Context **on_finish,
207 uint64_t size, uint64_t op_tid) {
208 EXPECT_CALL(*mock_image_ctx.operations, execute_resize(size, _, _, _, op_tid))
209 .WillOnce(DoAll(SaveArg<3>(on_finish),
210 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
213 void expect_snap_create(MockReplayImageCtx &mock_image_ctx,
214 Context **on_finish, const char *snap_name,
216 EXPECT_CALL(*mock_image_ctx.operations, execute_snap_create(_, StrEq(snap_name), _,
218 .WillOnce(DoAll(SaveArg<2>(on_finish),
219 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
222 void expect_snap_remove(MockReplayImageCtx &mock_image_ctx,
223 Context **on_finish, const char *snap_name) {
224 EXPECT_CALL(*mock_image_ctx.operations, execute_snap_remove(_, StrEq(snap_name), _))
225 .WillOnce(DoAll(SaveArg<2>(on_finish),
226 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
229 void expect_snap_rename(MockReplayImageCtx &mock_image_ctx,
230 Context **on_finish, uint64_t snap_id,
231 const char *snap_name) {
232 EXPECT_CALL(*mock_image_ctx.operations, execute_snap_rename(snap_id, StrEq(snap_name), _))
233 .WillOnce(DoAll(SaveArg<2>(on_finish),
234 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
237 void expect_snap_protect(MockReplayImageCtx &mock_image_ctx,
238 Context **on_finish, const char *snap_name) {
239 EXPECT_CALL(*mock_image_ctx.operations, execute_snap_protect(_, StrEq(snap_name), _))
240 .WillOnce(DoAll(SaveArg<2>(on_finish),
241 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
244 void expect_snap_unprotect(MockReplayImageCtx &mock_image_ctx,
245 Context **on_finish, const char *snap_name) {
246 EXPECT_CALL(*mock_image_ctx.operations, execute_snap_unprotect(_, StrEq(snap_name), _))
247 .WillOnce(DoAll(SaveArg<2>(on_finish),
248 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
251 void expect_snap_rollback(MockReplayImageCtx &mock_image_ctx,
252 Context **on_finish, const char *snap_name) {
253 EXPECT_CALL(*mock_image_ctx.operations, execute_snap_rollback(_, StrEq(snap_name), _, _))
254 .WillOnce(DoAll(SaveArg<3>(on_finish),
255 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
258 void expect_update_features(MockReplayImageCtx &mock_image_ctx, Context **on_finish,
259 uint64_t features, bool enabled, uint64_t op_tid) {
260 EXPECT_CALL(*mock_image_ctx.operations, execute_update_features(features, enabled, _, op_tid))
261 .WillOnce(DoAll(SaveArg<2>(on_finish),
262 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
265 void expect_metadata_set(MockReplayImageCtx &mock_image_ctx,
266 Context **on_finish, const char *key,
268 EXPECT_CALL(*mock_image_ctx.operations, execute_metadata_set(StrEq(key),
270 .WillOnce(DoAll(SaveArg<2>(on_finish),
271 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
274 void expect_metadata_remove(MockReplayImageCtx &mock_image_ctx,
275 Context **on_finish, const char *key) {
276 EXPECT_CALL(*mock_image_ctx.operations, execute_metadata_remove(StrEq(key), _))
277 .WillOnce(DoAll(SaveArg<1>(on_finish),
278 NotifyInvoke(&m_invoke_lock, &m_invoke_cond)));
281 void expect_refresh_image(MockReplayImageCtx &mock_image_ctx, bool required,
283 EXPECT_CALL(*mock_image_ctx.state, is_refresh_required())
284 .WillOnce(Return(required));
286 EXPECT_CALL(*mock_image_ctx.state, refresh(_))
287 .WillOnce(CompleteContext(r, mock_image_ctx.image_ctx->op_work_queue));
291 void when_process(MockJournalReplay &mock_journal_replay,
292 EventEntry &&event_entry, Context *on_ready,
295 ::encode(event_entry, bl);
297 bufferlist::iterator it = bl.begin();
298 when_process(mock_journal_replay, &it, on_ready, on_safe);
301 void when_process(MockJournalReplay &mock_journal_replay,
302 bufferlist::iterator *it, Context *on_ready,
304 EventEntry event_entry;
305 int r = mock_journal_replay.decode(it, &event_entry);
308 mock_journal_replay.process(event_entry, on_ready, on_safe);
311 void when_complete(MockReplayImageCtx &mock_image_ctx,
312 io::AioCompletion *aio_comp, int r) {
314 aio_comp->init_time(mock_image_ctx.image_ctx, librbd::io::AIO_TYPE_NONE);
315 aio_comp->set_request_count(1);
316 aio_comp->complete_request(r);
319 int when_flush(MockJournalReplay &mock_journal_replay) {
321 mock_journal_replay.flush(&ctx);
325 int when_shut_down(MockJournalReplay &mock_journal_replay, bool cancel_ops) {
327 mock_journal_replay.shut_down(cancel_ops, &ctx);
331 void when_replay_op_ready(MockJournalReplay &mock_journal_replay,
332 uint64_t op_tid, Context *on_resume) {
333 mock_journal_replay.replay_op_ready(op_tid, on_resume);
336 void wait_for_op_invoked(Context **on_finish, int r) {
338 Mutex::Locker locker(m_invoke_lock);
339 while (*on_finish == nullptr) {
340 m_invoke_cond.Wait(m_invoke_lock);
343 (*on_finish)->complete(r);
346 bufferlist to_bl(const std::string &str) {
356 TEST_F(TestMockJournalReplay, AioDiscard) {
357 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
359 librbd::ImageCtx *ictx;
360 ASSERT_EQ(0, open_image(m_image_name, &ictx));
362 MockReplayImageCtx mock_image_ctx(*ictx);
364 MockExclusiveLock mock_exclusive_lock;
365 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
366 expect_accept_ops(mock_exclusive_lock, true);
368 MockJournalReplay mock_journal_replay(mock_image_ctx);
369 MockIoImageRequest mock_io_image_request;
370 expect_op_work_queue(mock_image_ctx);
373 io::AioCompletion *aio_comp;
374 C_SaferCond on_ready;
376 expect_aio_discard(mock_io_image_request, &aio_comp, 123, 456, ictx->skip_partial_discard);
377 when_process(mock_journal_replay,
378 EventEntry{AioDiscardEvent(123, 456, ictx->skip_partial_discard)},
379 &on_ready, &on_safe);
381 when_complete(mock_image_ctx, aio_comp, 0);
382 ASSERT_EQ(0, on_ready.wait());
384 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
385 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
386 ASSERT_EQ(0, on_safe.wait());
389 TEST_F(TestMockJournalReplay, AioWrite) {
390 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
392 librbd::ImageCtx *ictx;
393 ASSERT_EQ(0, open_image(m_image_name, &ictx));
395 MockReplayImageCtx mock_image_ctx(*ictx);
397 MockExclusiveLock mock_exclusive_lock;
398 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
399 expect_accept_ops(mock_exclusive_lock, true);
401 MockJournalReplay mock_journal_replay(mock_image_ctx);
402 MockIoImageRequest mock_io_image_request;
403 expect_op_work_queue(mock_image_ctx);
406 io::AioCompletion *aio_comp;
407 C_SaferCond on_ready;
409 expect_aio_write(mock_io_image_request, &aio_comp, 123, 456, "test");
410 when_process(mock_journal_replay,
411 EventEntry{AioWriteEvent(123, 456, to_bl("test"))},
412 &on_ready, &on_safe);
414 when_complete(mock_image_ctx, aio_comp, 0);
415 ASSERT_EQ(0, on_ready.wait());
417 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
418 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
419 ASSERT_EQ(0, on_safe.wait());
422 TEST_F(TestMockJournalReplay, AioFlush) {
423 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
425 librbd::ImageCtx *ictx;
426 ASSERT_EQ(0, open_image(m_image_name, &ictx));
428 MockReplayImageCtx mock_image_ctx(*ictx);
430 MockExclusiveLock mock_exclusive_lock;
431 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
432 expect_accept_ops(mock_exclusive_lock, true);
434 MockJournalReplay mock_journal_replay(mock_image_ctx);
435 MockIoImageRequest mock_io_image_request;
436 expect_op_work_queue(mock_image_ctx);
439 io::AioCompletion *aio_comp;
440 C_SaferCond on_ready;
442 expect_aio_flush(mock_io_image_request, &aio_comp);
443 when_process(mock_journal_replay, EventEntry{AioFlushEvent()},
444 &on_ready, &on_safe);
446 when_complete(mock_image_ctx, aio_comp, 0);
447 ASSERT_EQ(0, on_safe.wait());
449 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
450 ASSERT_EQ(0, on_ready.wait());
453 TEST_F(TestMockJournalReplay, AioWriteSame) {
454 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
456 librbd::ImageCtx *ictx;
457 ASSERT_EQ(0, open_image(m_image_name, &ictx));
459 MockReplayImageCtx mock_image_ctx(*ictx);
461 MockExclusiveLock mock_exclusive_lock;
462 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
463 expect_accept_ops(mock_exclusive_lock, true);
465 MockJournalReplay mock_journal_replay(mock_image_ctx);
466 MockIoImageRequest mock_io_image_request;
467 expect_op_work_queue(mock_image_ctx);
470 io::AioCompletion *aio_comp;
471 C_SaferCond on_ready;
473 expect_aio_writesame(mock_io_image_request, &aio_comp, 123, 456, "333");
474 when_process(mock_journal_replay,
475 EventEntry{AioWriteSameEvent(123, 456, to_bl("333"))},
476 &on_ready, &on_safe);
478 when_complete(mock_image_ctx, aio_comp, 0);
479 ASSERT_EQ(0, on_ready.wait());
481 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
482 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
483 ASSERT_EQ(0, on_safe.wait());
487 TEST_F(TestMockJournalReplay, AioCompareAndWrite) {
488 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
490 librbd::ImageCtx *ictx;
491 ASSERT_EQ(0, open_image(m_image_name, &ictx));
493 MockReplayImageCtx mock_image_ctx(*ictx);
495 MockExclusiveLock mock_exclusive_lock;
496 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
497 expect_accept_ops(mock_exclusive_lock, true);
499 MockJournalReplay mock_write_journal_replay(mock_image_ctx);
500 MockJournalReplay mock_compare_and_write_journal_replay(mock_image_ctx);
501 MockJournalReplay mock_mis_compare_and_write_journal_replay(mock_image_ctx);
502 MockIoImageRequest mock_io_image_request;
503 expect_op_work_queue(mock_image_ctx);
506 io::AioCompletion *aio_comp;
507 C_SaferCond on_ready;
509 expect_aio_write(mock_io_image_request, &aio_comp, 512, 512, "test");
510 when_process(mock_write_journal_replay,
511 EventEntry{AioWriteEvent(512, 512, to_bl("test"))},
512 &on_ready, &on_safe);
514 when_complete(mock_image_ctx, aio_comp, 0);
515 ASSERT_EQ(0, on_ready.wait());
517 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
518 ASSERT_EQ(0, when_shut_down(mock_write_journal_replay, false));
519 ASSERT_EQ(0, on_safe.wait());
521 expect_aio_compare_and_write(mock_io_image_request, &aio_comp,
522 512, 512, "test", "test", nullptr);
523 when_process(mock_compare_and_write_journal_replay,
524 EventEntry{AioCompareAndWriteEvent(512, 512, to_bl("test"),
525 to_bl("test"))}, &on_ready, &on_safe);
527 when_complete(mock_image_ctx, aio_comp, 0);
528 ASSERT_EQ(0, on_ready.wait());
530 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
531 ASSERT_EQ(0, when_shut_down(mock_compare_and_write_journal_replay, false));
532 ASSERT_EQ(0, on_safe.wait());
534 expect_aio_compare_and_write(mock_io_image_request, &aio_comp,
535 512, 512, "111", "test", nullptr);
536 when_process(mock_mis_compare_and_write_journal_replay,
537 EventEntry{AioCompareAndWriteEvent(512, 512, to_bl("111"),
538 to_bl("test"))}, &on_ready, &on_safe);
540 when_complete(mock_image_ctx, aio_comp, 0);
541 ASSERT_EQ(0, on_ready.wait());
543 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
544 ASSERT_EQ(0, when_shut_down(mock_mis_compare_and_write_journal_replay, false));
545 ASSERT_EQ(0, on_safe.wait());
549 TEST_F(TestMockJournalReplay, IOError) {
550 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
552 librbd::ImageCtx *ictx;
553 ASSERT_EQ(0, open_image(m_image_name, &ictx));
555 MockReplayImageCtx mock_image_ctx(*ictx);
557 MockExclusiveLock mock_exclusive_lock;
558 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
559 expect_accept_ops(mock_exclusive_lock, true);
561 MockJournalReplay mock_journal_replay(mock_image_ctx);
562 MockIoImageRequest mock_io_image_request;
563 expect_op_work_queue(mock_image_ctx);
566 io::AioCompletion *aio_comp;
567 C_SaferCond on_ready;
569 expect_aio_discard(mock_io_image_request, &aio_comp, 123, 456, ictx->skip_partial_discard);
570 when_process(mock_journal_replay,
571 EventEntry{AioDiscardEvent(123, 456, ictx->skip_partial_discard)},
572 &on_ready, &on_safe);
574 when_complete(mock_image_ctx, aio_comp, -EINVAL);
575 ASSERT_EQ(-EINVAL, on_safe.wait());
577 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
578 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
579 ASSERT_EQ(0, on_ready.wait());
582 TEST_F(TestMockJournalReplay, SoftFlushIO) {
583 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
585 librbd::ImageCtx *ictx;
586 ASSERT_EQ(0, open_image(m_image_name, &ictx));
588 MockReplayImageCtx mock_image_ctx(*ictx);
590 MockExclusiveLock mock_exclusive_lock;
591 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
592 expect_accept_ops(mock_exclusive_lock, true);
594 MockJournalReplay mock_journal_replay(mock_image_ctx);
595 MockIoImageRequest mock_io_image_request;
596 expect_op_work_queue(mock_image_ctx);
599 const size_t io_count = 32;
600 C_SaferCond on_safes[io_count];
601 for (size_t i = 0; i < io_count; ++i) {
602 io::AioCompletion *aio_comp;
603 io::AioCompletion *flush_comp = nullptr;
604 C_SaferCond on_ready;
605 expect_aio_discard(mock_io_image_request, &aio_comp, 123, 456, ictx->skip_partial_discard);
606 if (i == io_count - 1) {
607 expect_aio_flush(mock_io_image_request, &flush_comp);
609 when_process(mock_journal_replay,
610 EventEntry{AioDiscardEvent(123, 456, ictx->skip_partial_discard)},
611 &on_ready, &on_safes[i]);
612 when_complete(mock_image_ctx, aio_comp, 0);
613 ASSERT_EQ(0, on_ready.wait());
615 if (flush_comp != nullptr) {
616 when_complete(mock_image_ctx, flush_comp, 0);
619 for (auto &on_safe : on_safes) {
620 ASSERT_EQ(0, on_safe.wait());
623 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
626 TEST_F(TestMockJournalReplay, PauseIO) {
627 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
629 librbd::ImageCtx *ictx;
630 ASSERT_EQ(0, open_image(m_image_name, &ictx));
632 MockReplayImageCtx mock_image_ctx(*ictx);
634 MockExclusiveLock mock_exclusive_lock;
635 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
636 expect_accept_ops(mock_exclusive_lock, true);
638 MockJournalReplay mock_journal_replay(mock_image_ctx);
639 MockIoImageRequest mock_io_image_request;
640 expect_op_work_queue(mock_image_ctx);
643 const size_t io_count = 64;
644 std::list<io::AioCompletion *> flush_comps;
645 C_SaferCond on_safes[io_count];
646 for (size_t i = 0; i < io_count; ++i) {
647 io::AioCompletion *aio_comp;
648 C_SaferCond on_ready;
649 expect_aio_write(mock_io_image_request, &aio_comp, 123, 456, "test");
650 if ((i + 1) % 32 == 0) {
651 flush_comps.push_back(nullptr);
652 expect_aio_flush(mock_io_image_request, &flush_comps.back());
654 when_process(mock_journal_replay,
655 EventEntry{AioWriteEvent(123, 456, to_bl("test"))},
656 &on_ready, &on_safes[i]);
657 when_complete(mock_image_ctx, aio_comp, 0);
658 if (i < io_count - 1) {
659 ASSERT_EQ(0, on_ready.wait());
661 for (auto flush_comp : flush_comps) {
662 when_complete(mock_image_ctx, flush_comp, 0);
664 ASSERT_EQ(0, on_ready.wait());
667 for (auto &on_safe : on_safes) {
668 ASSERT_EQ(0, on_safe.wait());
671 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
674 TEST_F(TestMockJournalReplay, Flush) {
675 librbd::ImageCtx *ictx;
676 ASSERT_EQ(0, open_image(m_image_name, &ictx));
678 MockReplayImageCtx mock_image_ctx(*ictx);
680 MockExclusiveLock mock_exclusive_lock;
681 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
682 expect_accept_ops(mock_exclusive_lock, true);
684 MockJournalReplay mock_journal_replay(mock_image_ctx);
685 MockIoImageRequest mock_io_image_request;
686 expect_op_work_queue(mock_image_ctx);
689 io::AioCompletion *aio_comp = nullptr;
690 C_SaferCond on_ready;
692 expect_aio_discard(mock_io_image_request, &aio_comp, 123, 456, ictx->skip_partial_discard);
693 when_process(mock_journal_replay,
694 EventEntry{AioDiscardEvent(123, 456, ictx->skip_partial_discard)},
695 &on_ready, &on_safe);
697 when_complete(mock_image_ctx, aio_comp, 0);
698 ASSERT_EQ(0, on_ready.wait());
700 expect_aio_flush(mock_image_ctx, mock_io_image_request, 0);
701 ASSERT_EQ(0, when_flush(mock_journal_replay));
702 ASSERT_EQ(0, on_safe.wait());
705 TEST_F(TestMockJournalReplay, OpFinishError) {
706 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
708 librbd::ImageCtx *ictx;
709 ASSERT_EQ(0, open_image(m_image_name, &ictx));
711 MockReplayImageCtx mock_image_ctx(*ictx);
713 MockExclusiveLock mock_exclusive_lock;
714 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
715 expect_accept_ops(mock_exclusive_lock, true);
717 MockJournalReplay mock_journal_replay(mock_image_ctx);
718 expect_op_work_queue(mock_image_ctx);
721 C_SaferCond on_start_ready;
722 C_SaferCond on_start_safe;
723 when_process(mock_journal_replay,
724 EventEntry{SnapRemoveEvent(123,
725 cls::rbd::UserSnapshotNamespace(),
729 ASSERT_EQ(0, on_start_ready.wait());
731 C_SaferCond on_finish_ready;
732 C_SaferCond on_finish_safe;
733 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, -EIO)},
734 &on_finish_ready, &on_finish_safe);
736 ASSERT_EQ(-EIO, on_start_safe.wait());
737 ASSERT_EQ(-EIO, on_finish_safe.wait());
738 ASSERT_EQ(0, on_finish_ready.wait());
741 TEST_F(TestMockJournalReplay, BlockedOpFinishError) {
742 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
744 librbd::ImageCtx *ictx;
745 ASSERT_EQ(0, open_image(m_image_name, &ictx));
747 MockReplayImageCtx mock_image_ctx(*ictx);
749 MockExclusiveLock mock_exclusive_lock;
750 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
751 expect_accept_ops(mock_exclusive_lock, true);
753 MockJournalReplay mock_journal_replay(mock_image_ctx);
754 expect_op_work_queue(mock_image_ctx);
757 Context *on_finish = nullptr;
758 expect_refresh_image(mock_image_ctx, false, 0);
759 expect_snap_create(mock_image_ctx, &on_finish, "snap", 123);
761 C_SaferCond on_start_ready;
762 C_SaferCond on_start_safe;
763 when_process(mock_journal_replay,
764 EventEntry{SnapCreateEvent(123,
765 cls::rbd::UserSnapshotNamespace(),
770 C_SaferCond on_resume;
771 when_replay_op_ready(mock_journal_replay, 123, &on_resume);
772 ASSERT_EQ(0, on_start_ready.wait());
774 C_SaferCond on_finish_ready;
775 C_SaferCond on_finish_safe;
776 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, -EBADMSG)},
777 &on_finish_ready, &on_finish_safe);
779 ASSERT_EQ(-EBADMSG, on_resume.wait());
780 wait_for_op_invoked(&on_finish, -ESTALE);
782 ASSERT_EQ(-ESTALE, on_start_safe.wait());
783 ASSERT_EQ(-ESTALE, on_finish_safe.wait());
784 ASSERT_EQ(0, on_finish_ready.wait());
787 TEST_F(TestMockJournalReplay, MissingOpFinishEvent) {
788 librbd::ImageCtx *ictx;
789 ASSERT_EQ(0, open_image(m_image_name, &ictx));
791 MockReplayImageCtx mock_image_ctx(*ictx);
793 MockExclusiveLock mock_exclusive_lock;
794 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
795 expect_accept_ops(mock_exclusive_lock, true);
797 MockJournalReplay mock_journal_replay(mock_image_ctx);
798 expect_op_work_queue(mock_image_ctx);
800 EXPECT_CALL(*mock_image_ctx.state, is_refresh_required())
801 .WillRepeatedly(Return(false));
804 Context *on_snap_create_finish = nullptr;
805 expect_snap_create(mock_image_ctx, &on_snap_create_finish, "snap", 123);
807 Context *on_snap_remove_finish = nullptr;
808 expect_snap_remove(mock_image_ctx, &on_snap_remove_finish, "snap");
810 C_SaferCond on_snap_remove_ready;
811 C_SaferCond on_snap_remove_safe;
812 when_process(mock_journal_replay,
813 EventEntry{SnapRemoveEvent(122,
814 cls::rbd::UserSnapshotNamespace(),
816 &on_snap_remove_ready,
817 &on_snap_remove_safe);
818 ASSERT_EQ(0, on_snap_remove_ready.wait());
820 C_SaferCond on_snap_create_ready;
821 C_SaferCond on_snap_create_safe;
822 when_process(mock_journal_replay,
823 EventEntry{SnapCreateEvent(123,
824 cls::rbd::UserSnapshotNamespace(),
826 &on_snap_create_ready,
827 &on_snap_create_safe);
829 C_SaferCond on_shut_down;
830 mock_journal_replay.shut_down(false, &on_shut_down);
832 wait_for_op_invoked(&on_snap_remove_finish, 0);
833 ASSERT_EQ(0, on_snap_remove_safe.wait());
835 C_SaferCond on_snap_create_resume;
836 when_replay_op_ready(mock_journal_replay, 123, &on_snap_create_resume);
837 ASSERT_EQ(0, on_snap_create_resume.wait());
839 wait_for_op_invoked(&on_snap_create_finish, 0);
840 ASSERT_EQ(0, on_snap_create_ready.wait());
841 ASSERT_EQ(0, on_snap_create_safe.wait());
843 ASSERT_EQ(0, on_shut_down.wait());
846 TEST_F(TestMockJournalReplay, MissingOpFinishEventCancelOps) {
847 librbd::ImageCtx *ictx;
848 ASSERT_EQ(0, open_image(m_image_name, &ictx));
850 MockReplayImageCtx mock_image_ctx(*ictx);
852 MockExclusiveLock mock_exclusive_lock;
853 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
854 expect_accept_ops(mock_exclusive_lock, true);
856 MockJournalReplay mock_journal_replay(mock_image_ctx);
857 expect_op_work_queue(mock_image_ctx);
860 Context *on_snap_create_finish = nullptr;
861 expect_refresh_image(mock_image_ctx, false, 0);
862 expect_snap_create(mock_image_ctx, &on_snap_create_finish, "snap", 123);
864 C_SaferCond on_snap_remove_ready;
865 C_SaferCond on_snap_remove_safe;
866 when_process(mock_journal_replay,
867 EventEntry{SnapRemoveEvent(122,
868 cls::rbd::UserSnapshotNamespace(),
870 &on_snap_remove_ready,
871 &on_snap_remove_safe);
872 ASSERT_EQ(0, on_snap_remove_ready.wait());
874 C_SaferCond on_snap_create_ready;
875 C_SaferCond on_snap_create_safe;
876 when_process(mock_journal_replay,
877 EventEntry{SnapCreateEvent(123,
878 cls::rbd::UserSnapshotNamespace(),
880 &on_snap_create_ready,
881 &on_snap_create_safe);
883 C_SaferCond on_resume;
884 when_replay_op_ready(mock_journal_replay, 123, &on_resume);
885 ASSERT_EQ(0, on_snap_create_ready.wait());
887 C_SaferCond on_shut_down;
888 mock_journal_replay.shut_down(true, &on_shut_down);
890 ASSERT_EQ(-ERESTART, on_resume.wait());
891 on_snap_create_finish->complete(-ERESTART);
892 ASSERT_EQ(-ERESTART, on_snap_create_safe.wait());
894 ASSERT_EQ(-ERESTART, on_snap_remove_safe.wait());
895 ASSERT_EQ(0, on_shut_down.wait());
898 TEST_F(TestMockJournalReplay, UnknownOpFinishEvent) {
899 librbd::ImageCtx *ictx;
900 ASSERT_EQ(0, open_image(m_image_name, &ictx));
902 MockReplayImageCtx mock_image_ctx(*ictx);
904 MockExclusiveLock mock_exclusive_lock;
905 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
906 expect_accept_ops(mock_exclusive_lock, true);
908 MockJournalReplay mock_journal_replay(mock_image_ctx);
909 expect_op_work_queue(mock_image_ctx);
912 C_SaferCond on_ready;
914 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
915 &on_ready, &on_safe);
917 ASSERT_EQ(0, on_safe.wait());
918 ASSERT_EQ(0, on_ready.wait());
921 TEST_F(TestMockJournalReplay, OpEventError) {
922 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
924 librbd::ImageCtx *ictx;
925 ASSERT_EQ(0, open_image(m_image_name, &ictx));
927 MockReplayImageCtx mock_image_ctx(*ictx);
929 MockExclusiveLock mock_exclusive_lock;
930 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
931 expect_accept_ops(mock_exclusive_lock, true);
933 MockJournalReplay mock_journal_replay(mock_image_ctx);
934 expect_op_work_queue(mock_image_ctx);
937 Context *on_finish = nullptr;
938 expect_refresh_image(mock_image_ctx, false, 0);
939 expect_snap_remove(mock_image_ctx, &on_finish, "snap");
941 C_SaferCond on_start_ready;
942 C_SaferCond on_start_safe;
943 when_process(mock_journal_replay,
944 EventEntry{SnapRemoveEvent(123,
945 cls::rbd::UserSnapshotNamespace(),
949 ASSERT_EQ(0, on_start_ready.wait());
951 C_SaferCond on_finish_ready;
952 C_SaferCond on_finish_safe;
953 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
954 &on_finish_ready, &on_finish_safe);
956 wait_for_op_invoked(&on_finish, -EINVAL);
957 ASSERT_EQ(-EINVAL, on_start_safe.wait());
958 ASSERT_EQ(0, on_finish_ready.wait());
959 ASSERT_EQ(-EINVAL, on_finish_safe.wait());
962 TEST_F(TestMockJournalReplay, SnapCreateEvent) {
963 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
965 librbd::ImageCtx *ictx;
966 ASSERT_EQ(0, open_image(m_image_name, &ictx));
968 MockReplayImageCtx mock_image_ctx(*ictx);
970 MockExclusiveLock mock_exclusive_lock;
971 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
972 expect_accept_ops(mock_exclusive_lock, true);
974 MockJournalReplay mock_journal_replay(mock_image_ctx);
975 expect_op_work_queue(mock_image_ctx);
978 Context *on_finish = nullptr;
979 expect_refresh_image(mock_image_ctx, false, 0);
980 expect_snap_create(mock_image_ctx, &on_finish, "snap", 123);
982 C_SaferCond on_start_ready;
983 C_SaferCond on_start_safe;
984 when_process(mock_journal_replay,
985 EventEntry{SnapCreateEvent(123,
986 cls::rbd::UserSnapshotNamespace(),
991 C_SaferCond on_resume;
992 when_replay_op_ready(mock_journal_replay, 123, &on_resume);
993 ASSERT_EQ(0, on_start_ready.wait());
995 C_SaferCond on_finish_ready;
996 C_SaferCond on_finish_safe;
997 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
998 &on_finish_ready, &on_finish_safe);
1000 ASSERT_EQ(0, on_resume.wait());
1001 wait_for_op_invoked(&on_finish, 0);
1003 ASSERT_EQ(0, on_start_safe.wait());
1004 ASSERT_EQ(0, on_finish_ready.wait());
1005 ASSERT_EQ(0, on_finish_safe.wait());
1008 TEST_F(TestMockJournalReplay, SnapCreateEventExists) {
1009 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1011 librbd::ImageCtx *ictx;
1012 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1014 MockReplayImageCtx mock_image_ctx(*ictx);
1016 MockExclusiveLock mock_exclusive_lock;
1017 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1018 expect_accept_ops(mock_exclusive_lock, true);
1020 MockJournalReplay mock_journal_replay(mock_image_ctx);
1021 expect_op_work_queue(mock_image_ctx);
1024 Context *on_finish = nullptr;
1025 expect_refresh_image(mock_image_ctx, false, 0);
1026 expect_snap_create(mock_image_ctx, &on_finish, "snap", 123);
1028 C_SaferCond on_start_ready;
1029 C_SaferCond on_start_safe;
1030 when_process(mock_journal_replay,
1031 EventEntry{SnapCreateEvent(123,
1032 cls::rbd::UserSnapshotNamespace(),
1037 wait_for_op_invoked(&on_finish, -EEXIST);
1038 ASSERT_EQ(0, on_start_ready.wait());
1040 C_SaferCond on_finish_ready;
1041 C_SaferCond on_finish_safe;
1042 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1043 &on_finish_ready, &on_finish_safe);
1045 ASSERT_EQ(0, on_start_safe.wait());
1046 ASSERT_EQ(0, on_finish_ready.wait());
1047 ASSERT_EQ(0, on_finish_safe.wait());
1050 TEST_F(TestMockJournalReplay, SnapRemoveEvent) {
1051 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1053 librbd::ImageCtx *ictx;
1054 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1056 MockReplayImageCtx mock_image_ctx(*ictx);
1058 MockExclusiveLock mock_exclusive_lock;
1059 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1060 expect_accept_ops(mock_exclusive_lock, true);
1062 MockJournalReplay mock_journal_replay(mock_image_ctx);
1063 expect_op_work_queue(mock_image_ctx);
1066 Context *on_finish = nullptr;
1067 expect_refresh_image(mock_image_ctx, false, 0);
1068 expect_snap_remove(mock_image_ctx, &on_finish, "snap");
1070 C_SaferCond on_start_ready;
1071 C_SaferCond on_start_safe;
1072 when_process(mock_journal_replay,
1073 EventEntry{SnapRemoveEvent(123,
1074 cls::rbd::UserSnapshotNamespace(),
1078 ASSERT_EQ(0, on_start_ready.wait());
1080 C_SaferCond on_finish_ready;
1081 C_SaferCond on_finish_safe;
1082 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1083 &on_finish_ready, &on_finish_safe);
1085 wait_for_op_invoked(&on_finish, 0);
1086 ASSERT_EQ(0, on_start_safe.wait());
1087 ASSERT_EQ(0, on_finish_ready.wait());
1088 ASSERT_EQ(0, on_finish_safe.wait());
1091 TEST_F(TestMockJournalReplay, SnapRemoveEventDNE) {
1092 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1094 librbd::ImageCtx *ictx;
1095 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1097 MockReplayImageCtx mock_image_ctx(*ictx);
1099 MockExclusiveLock mock_exclusive_lock;
1100 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1101 expect_accept_ops(mock_exclusive_lock, true);
1103 MockJournalReplay mock_journal_replay(mock_image_ctx);
1104 expect_op_work_queue(mock_image_ctx);
1107 Context *on_finish = nullptr;
1108 expect_refresh_image(mock_image_ctx, false, 0);
1109 expect_snap_remove(mock_image_ctx, &on_finish, "snap");
1111 C_SaferCond on_start_ready;
1112 C_SaferCond on_start_safe;
1113 when_process(mock_journal_replay,
1114 EventEntry{SnapRemoveEvent(123,
1115 cls::rbd::UserSnapshotNamespace(),
1119 ASSERT_EQ(0, on_start_ready.wait());
1121 C_SaferCond on_finish_ready;
1122 C_SaferCond on_finish_safe;
1123 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1124 &on_finish_ready, &on_finish_safe);
1126 wait_for_op_invoked(&on_finish, -ENOENT);
1127 ASSERT_EQ(0, on_start_safe.wait());
1128 ASSERT_EQ(0, on_finish_ready.wait());
1129 ASSERT_EQ(0, on_finish_safe.wait());
1132 TEST_F(TestMockJournalReplay, SnapRenameEvent) {
1133 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1135 librbd::ImageCtx *ictx;
1136 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1138 MockReplayImageCtx mock_image_ctx(*ictx);
1140 MockExclusiveLock mock_exclusive_lock;
1141 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1142 expect_accept_ops(mock_exclusive_lock, true);
1144 MockJournalReplay mock_journal_replay(mock_image_ctx);
1145 expect_op_work_queue(mock_image_ctx);
1148 Context *on_finish = nullptr;
1149 expect_refresh_image(mock_image_ctx, false, 0);
1150 expect_snap_rename(mock_image_ctx, &on_finish, 234, "snap");
1152 C_SaferCond on_start_ready;
1153 C_SaferCond on_start_safe;
1154 when_process(mock_journal_replay,
1155 EventEntry{SnapRenameEvent(123, 234, "snap1", "snap")},
1156 &on_start_ready, &on_start_safe);
1157 ASSERT_EQ(0, on_start_ready.wait());
1159 C_SaferCond on_finish_ready;
1160 C_SaferCond on_finish_safe;
1161 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1162 &on_finish_ready, &on_finish_safe);
1164 wait_for_op_invoked(&on_finish, 0);
1165 ASSERT_EQ(0, on_start_safe.wait());
1166 ASSERT_EQ(0, on_finish_ready.wait());
1167 ASSERT_EQ(0, on_finish_safe.wait());
1170 TEST_F(TestMockJournalReplay, SnapRenameEventExists) {
1171 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1173 librbd::ImageCtx *ictx;
1174 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1176 MockReplayImageCtx mock_image_ctx(*ictx);
1178 MockExclusiveLock mock_exclusive_lock;
1179 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1180 expect_accept_ops(mock_exclusive_lock, true);
1182 MockJournalReplay mock_journal_replay(mock_image_ctx);
1183 expect_op_work_queue(mock_image_ctx);
1186 Context *on_finish = nullptr;
1187 expect_refresh_image(mock_image_ctx, false, 0);
1188 expect_snap_rename(mock_image_ctx, &on_finish, 234, "snap");
1190 C_SaferCond on_start_ready;
1191 C_SaferCond on_start_safe;
1192 when_process(mock_journal_replay,
1193 EventEntry{SnapRenameEvent(123, 234, "snap1", "snap")},
1194 &on_start_ready, &on_start_safe);
1195 ASSERT_EQ(0, on_start_ready.wait());
1197 C_SaferCond on_finish_ready;
1198 C_SaferCond on_finish_safe;
1199 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1200 &on_finish_ready, &on_finish_safe);
1202 wait_for_op_invoked(&on_finish, -EEXIST);
1203 ASSERT_EQ(0, on_start_safe.wait());
1204 ASSERT_EQ(0, on_finish_ready.wait());
1205 ASSERT_EQ(0, on_finish_safe.wait());
1208 TEST_F(TestMockJournalReplay, SnapProtectEvent) {
1209 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1211 librbd::ImageCtx *ictx;
1212 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1214 MockReplayImageCtx mock_image_ctx(*ictx);
1216 MockExclusiveLock mock_exclusive_lock;
1217 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1218 expect_accept_ops(mock_exclusive_lock, true);
1220 MockJournalReplay mock_journal_replay(mock_image_ctx);
1221 expect_op_work_queue(mock_image_ctx);
1224 Context *on_finish = nullptr;
1225 expect_refresh_image(mock_image_ctx, false, 0);
1226 expect_snap_protect(mock_image_ctx, &on_finish, "snap");
1228 C_SaferCond on_start_ready;
1229 C_SaferCond on_start_safe;
1230 when_process(mock_journal_replay,
1231 EventEntry{SnapProtectEvent(123,
1232 cls::rbd::UserSnapshotNamespace(),
1236 ASSERT_EQ(0, on_start_ready.wait());
1238 C_SaferCond on_finish_ready;
1239 C_SaferCond on_finish_safe;
1240 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1241 &on_finish_ready, &on_finish_safe);
1243 wait_for_op_invoked(&on_finish, 0);
1244 ASSERT_EQ(0, on_start_safe.wait());
1245 ASSERT_EQ(0, on_finish_ready.wait());
1246 ASSERT_EQ(0, on_finish_safe.wait());
1249 TEST_F(TestMockJournalReplay, SnapProtectEventBusy) {
1250 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1252 librbd::ImageCtx *ictx;
1253 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1255 MockReplayImageCtx mock_image_ctx(*ictx);
1257 MockExclusiveLock mock_exclusive_lock;
1258 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1259 expect_accept_ops(mock_exclusive_lock, true);
1261 MockJournalReplay mock_journal_replay(mock_image_ctx);
1262 expect_op_work_queue(mock_image_ctx);
1265 Context *on_finish = nullptr;
1266 expect_refresh_image(mock_image_ctx, false, 0);
1267 expect_snap_protect(mock_image_ctx, &on_finish, "snap");
1269 C_SaferCond on_start_ready;
1270 C_SaferCond on_start_safe;
1271 when_process(mock_journal_replay,
1272 EventEntry{SnapProtectEvent(123,
1273 cls::rbd::UserSnapshotNamespace(),
1277 ASSERT_EQ(0, on_start_ready.wait());
1279 C_SaferCond on_finish_ready;
1280 C_SaferCond on_finish_safe;
1281 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1282 &on_finish_ready, &on_finish_safe);
1284 wait_for_op_invoked(&on_finish, -EBUSY);
1285 ASSERT_EQ(0, on_start_safe.wait());
1286 ASSERT_EQ(0, on_finish_ready.wait());
1287 ASSERT_EQ(0, on_finish_safe.wait());
1290 TEST_F(TestMockJournalReplay, SnapUnprotectEvent) {
1291 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1293 librbd::ImageCtx *ictx;
1294 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1296 MockReplayImageCtx mock_image_ctx(*ictx);
1298 MockExclusiveLock mock_exclusive_lock;
1299 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1300 expect_accept_ops(mock_exclusive_lock, true);
1302 MockJournalReplay mock_journal_replay(mock_image_ctx);
1303 expect_op_work_queue(mock_image_ctx);
1306 Context *on_finish = nullptr;
1307 expect_refresh_image(mock_image_ctx, false, 0);
1308 expect_snap_unprotect(mock_image_ctx, &on_finish, "snap");
1310 C_SaferCond on_start_ready;
1311 C_SaferCond on_start_safe;
1312 when_process(mock_journal_replay,
1313 EventEntry{SnapUnprotectEvent(123,
1314 cls::rbd::UserSnapshotNamespace(),
1318 ASSERT_EQ(0, on_start_ready.wait());
1320 C_SaferCond on_finish_ready;
1321 C_SaferCond on_finish_safe;
1322 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1323 &on_finish_ready, &on_finish_safe);
1325 wait_for_op_invoked(&on_finish, 0);
1326 ASSERT_EQ(0, on_start_safe.wait());
1327 ASSERT_EQ(0, on_finish_ready.wait());
1328 ASSERT_EQ(0, on_finish_safe.wait());
1331 TEST_F(TestMockJournalReplay, SnapUnprotectOpFinishBusy) {
1332 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1334 librbd::ImageCtx *ictx;
1335 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1337 MockReplayImageCtx mock_image_ctx(*ictx);
1339 MockExclusiveLock mock_exclusive_lock;
1340 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1341 expect_accept_ops(mock_exclusive_lock, true);
1343 MockJournalReplay mock_journal_replay(mock_image_ctx);
1344 expect_op_work_queue(mock_image_ctx);
1347 C_SaferCond on_start_ready;
1348 C_SaferCond on_start_safe;
1349 when_process(mock_journal_replay,
1350 EventEntry{SnapUnprotectEvent(123,
1351 cls::rbd::UserSnapshotNamespace(),
1355 ASSERT_EQ(0, on_start_ready.wait());
1357 // aborts the snap unprotect op if image had children
1358 C_SaferCond on_finish_ready;
1359 C_SaferCond on_finish_safe;
1360 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, -EBUSY)},
1361 &on_finish_ready, &on_finish_safe);
1363 ASSERT_EQ(0, on_start_safe.wait());
1364 ASSERT_EQ(0, on_finish_safe.wait());
1365 ASSERT_EQ(0, on_finish_ready.wait());
1368 TEST_F(TestMockJournalReplay, SnapUnprotectEventInvalid) {
1369 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1371 librbd::ImageCtx *ictx;
1372 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1374 MockReplayImageCtx mock_image_ctx(*ictx);
1376 MockExclusiveLock mock_exclusive_lock;
1377 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1378 expect_accept_ops(mock_exclusive_lock, true);
1380 MockJournalReplay mock_journal_replay(mock_image_ctx);
1381 expect_op_work_queue(mock_image_ctx);
1384 Context *on_finish = nullptr;
1385 expect_refresh_image(mock_image_ctx, false, 0);
1386 expect_snap_unprotect(mock_image_ctx, &on_finish, "snap");
1388 C_SaferCond on_start_ready;
1389 C_SaferCond on_start_safe;
1390 when_process(mock_journal_replay,
1391 EventEntry{SnapUnprotectEvent(123,
1392 cls::rbd::UserSnapshotNamespace(),
1396 ASSERT_EQ(0, on_start_ready.wait());
1398 C_SaferCond on_finish_ready;
1399 C_SaferCond on_finish_safe;
1400 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1401 &on_finish_ready, &on_finish_safe);
1403 wait_for_op_invoked(&on_finish, -EINVAL);
1404 ASSERT_EQ(0, on_start_safe.wait());
1405 ASSERT_EQ(0, on_finish_ready.wait());
1406 ASSERT_EQ(0, on_finish_safe.wait());
1409 TEST_F(TestMockJournalReplay, SnapRollbackEvent) {
1410 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1412 librbd::ImageCtx *ictx;
1413 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1415 MockReplayImageCtx mock_image_ctx(*ictx);
1417 MockExclusiveLock mock_exclusive_lock;
1418 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1419 expect_accept_ops(mock_exclusive_lock, true);
1421 MockJournalReplay mock_journal_replay(mock_image_ctx);
1422 expect_op_work_queue(mock_image_ctx);
1425 Context *on_finish = nullptr;
1426 expect_refresh_image(mock_image_ctx, false, 0);
1427 expect_snap_rollback(mock_image_ctx, &on_finish, "snap");
1429 C_SaferCond on_start_ready;
1430 C_SaferCond on_start_safe;
1431 when_process(mock_journal_replay,
1432 EventEntry{SnapRollbackEvent(123,
1433 cls::rbd::UserSnapshotNamespace(),
1437 ASSERT_EQ(0, on_start_ready.wait());
1439 C_SaferCond on_finish_ready;
1440 C_SaferCond on_finish_safe;
1441 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1442 &on_finish_ready, &on_finish_safe);
1444 wait_for_op_invoked(&on_finish, 0);
1445 ASSERT_EQ(0, on_start_safe.wait());
1446 ASSERT_EQ(0, on_finish_ready.wait());
1447 ASSERT_EQ(0, on_finish_safe.wait());
1450 TEST_F(TestMockJournalReplay, RenameEvent) {
1451 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1453 librbd::ImageCtx *ictx;
1454 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1456 MockReplayImageCtx mock_image_ctx(*ictx);
1458 MockExclusiveLock mock_exclusive_lock;
1459 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1460 expect_accept_ops(mock_exclusive_lock, true);
1462 MockJournalReplay mock_journal_replay(mock_image_ctx);
1463 expect_op_work_queue(mock_image_ctx);
1466 Context *on_finish = nullptr;
1467 expect_refresh_image(mock_image_ctx, false, 0);
1468 expect_rename(mock_image_ctx, &on_finish, "image");
1470 C_SaferCond on_start_ready;
1471 C_SaferCond on_start_safe;
1472 when_process(mock_journal_replay, EventEntry{RenameEvent(123, "image")},
1473 &on_start_ready, &on_start_safe);
1474 ASSERT_EQ(0, on_start_ready.wait());
1476 C_SaferCond on_finish_ready;
1477 C_SaferCond on_finish_safe;
1478 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1479 &on_finish_ready, &on_finish_safe);
1481 wait_for_op_invoked(&on_finish, 0);
1482 ASSERT_EQ(0, on_start_safe.wait());
1483 ASSERT_EQ(0, on_finish_ready.wait());
1484 ASSERT_EQ(0, on_finish_safe.wait());
1487 TEST_F(TestMockJournalReplay, RenameEventExists) {
1488 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1490 librbd::ImageCtx *ictx;
1491 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1493 MockReplayImageCtx mock_image_ctx(*ictx);
1495 MockExclusiveLock mock_exclusive_lock;
1496 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1497 expect_accept_ops(mock_exclusive_lock, true);
1499 MockJournalReplay mock_journal_replay(mock_image_ctx);
1500 expect_op_work_queue(mock_image_ctx);
1503 Context *on_finish = nullptr;
1504 expect_refresh_image(mock_image_ctx, false, 0);
1505 expect_rename(mock_image_ctx, &on_finish, "image");
1507 C_SaferCond on_start_ready;
1508 C_SaferCond on_start_safe;
1509 when_process(mock_journal_replay, EventEntry{RenameEvent(123, "image")},
1510 &on_start_ready, &on_start_safe);
1511 ASSERT_EQ(0, on_start_ready.wait());
1513 C_SaferCond on_finish_ready;
1514 C_SaferCond on_finish_safe;
1515 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1516 &on_finish_ready, &on_finish_safe);
1518 wait_for_op_invoked(&on_finish, -EEXIST);
1519 ASSERT_EQ(0, on_start_safe.wait());
1520 ASSERT_EQ(0, on_finish_ready.wait());
1521 ASSERT_EQ(0, on_finish_safe.wait());
1524 TEST_F(TestMockJournalReplay, ResizeEvent) {
1525 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1527 librbd::ImageCtx *ictx;
1528 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1530 MockReplayImageCtx mock_image_ctx(*ictx);
1532 MockExclusiveLock mock_exclusive_lock;
1533 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1534 expect_accept_ops(mock_exclusive_lock, true);
1536 MockJournalReplay mock_journal_replay(mock_image_ctx);
1537 expect_op_work_queue(mock_image_ctx);
1540 Context *on_finish = nullptr;
1541 expect_refresh_image(mock_image_ctx, false, 0);
1542 expect_resize(mock_image_ctx, &on_finish, 234, 123);
1544 C_SaferCond on_start_ready;
1545 C_SaferCond on_start_safe;
1546 when_process(mock_journal_replay, EventEntry{ResizeEvent(123, 234)},
1547 &on_start_ready, &on_start_safe);
1549 C_SaferCond on_resume;
1550 when_replay_op_ready(mock_journal_replay, 123, &on_resume);
1551 ASSERT_EQ(0, on_start_ready.wait());
1553 C_SaferCond on_finish_ready;
1554 C_SaferCond on_finish_safe;
1555 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1556 &on_finish_ready, &on_finish_safe);
1558 ASSERT_EQ(0, on_resume.wait());
1559 wait_for_op_invoked(&on_finish, 0);
1561 ASSERT_EQ(0, on_start_safe.wait());
1562 ASSERT_EQ(0, on_finish_ready.wait());
1563 ASSERT_EQ(0, on_finish_safe.wait());
1566 TEST_F(TestMockJournalReplay, FlattenEvent) {
1567 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1569 librbd::ImageCtx *ictx;
1570 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1572 MockReplayImageCtx mock_image_ctx(*ictx);
1574 MockExclusiveLock mock_exclusive_lock;
1575 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1576 expect_accept_ops(mock_exclusive_lock, true);
1578 MockJournalReplay mock_journal_replay(mock_image_ctx);
1579 expect_op_work_queue(mock_image_ctx);
1582 Context *on_finish = nullptr;
1583 expect_refresh_image(mock_image_ctx, false, 0);
1584 expect_flatten(mock_image_ctx, &on_finish);
1586 C_SaferCond on_start_ready;
1587 C_SaferCond on_start_safe;
1588 when_process(mock_journal_replay, EventEntry{FlattenEvent(123)},
1589 &on_start_ready, &on_start_safe);
1590 ASSERT_EQ(0, on_start_ready.wait());
1592 C_SaferCond on_finish_ready;
1593 C_SaferCond on_finish_safe;
1594 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1595 &on_finish_ready, &on_finish_safe);
1597 wait_for_op_invoked(&on_finish, 0);
1598 ASSERT_EQ(0, on_start_safe.wait());
1599 ASSERT_EQ(0, on_finish_ready.wait());
1600 ASSERT_EQ(0, on_finish_safe.wait());
1603 TEST_F(TestMockJournalReplay, FlattenEventInvalid) {
1604 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1606 librbd::ImageCtx *ictx;
1607 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1609 MockReplayImageCtx mock_image_ctx(*ictx);
1611 MockExclusiveLock mock_exclusive_lock;
1612 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1613 expect_accept_ops(mock_exclusive_lock, true);
1615 MockJournalReplay mock_journal_replay(mock_image_ctx);
1616 expect_op_work_queue(mock_image_ctx);
1619 Context *on_finish = nullptr;
1620 expect_refresh_image(mock_image_ctx, false, 0);
1621 expect_flatten(mock_image_ctx, &on_finish);
1623 C_SaferCond on_start_ready;
1624 C_SaferCond on_start_safe;
1625 when_process(mock_journal_replay, EventEntry{FlattenEvent(123)},
1626 &on_start_ready, &on_start_safe);
1627 ASSERT_EQ(0, on_start_ready.wait());
1629 C_SaferCond on_finish_ready;
1630 C_SaferCond on_finish_safe;
1631 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1632 &on_finish_ready, &on_finish_safe);
1634 wait_for_op_invoked(&on_finish, -EINVAL);
1635 ASSERT_EQ(0, on_start_safe.wait());
1636 ASSERT_EQ(0, on_finish_ready.wait());
1637 ASSERT_EQ(0, on_finish_safe.wait());
1640 TEST_F(TestMockJournalReplay, UpdateFeaturesEvent) {
1641 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1643 librbd::ImageCtx *ictx;
1644 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1646 uint64_t features = RBD_FEATURE_OBJECT_MAP | RBD_FEATURE_FAST_DIFF;
1647 bool enabled = !ictx->test_features(features);
1649 MockReplayImageCtx mock_image_ctx(*ictx);
1651 MockExclusiveLock mock_exclusive_lock;
1652 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1653 expect_accept_ops(mock_exclusive_lock, true);
1655 MockJournalReplay mock_journal_replay(mock_image_ctx);
1656 expect_op_work_queue(mock_image_ctx);
1659 Context *on_finish = nullptr;
1660 expect_refresh_image(mock_image_ctx, false, 0);
1661 expect_update_features(mock_image_ctx, &on_finish, features, enabled, 123);
1663 C_SaferCond on_start_ready;
1664 C_SaferCond on_start_safe;
1665 when_process(mock_journal_replay,
1666 EventEntry{UpdateFeaturesEvent(123, features, enabled)},
1667 &on_start_ready, &on_start_safe);
1669 C_SaferCond on_resume;
1670 when_replay_op_ready(mock_journal_replay, 123, &on_resume);
1671 ASSERT_EQ(0, on_start_ready.wait());
1673 C_SaferCond on_finish_ready;
1674 C_SaferCond on_finish_safe;
1675 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1676 &on_finish_ready, &on_finish_safe);
1678 ASSERT_EQ(0, on_resume.wait());
1679 wait_for_op_invoked(&on_finish, 0);
1681 ASSERT_EQ(0, on_start_safe.wait());
1682 ASSERT_EQ(0, on_finish_ready.wait());
1683 ASSERT_EQ(0, on_finish_safe.wait());
1686 TEST_F(TestMockJournalReplay, MetadataSetEvent) {
1687 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1689 librbd::ImageCtx *ictx;
1690 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1692 MockReplayImageCtx mock_image_ctx(*ictx);
1694 MockExclusiveLock mock_exclusive_lock;
1695 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1696 expect_accept_ops(mock_exclusive_lock, true);
1698 MockJournalReplay mock_journal_replay(mock_image_ctx);
1699 expect_op_work_queue(mock_image_ctx);
1702 Context *on_finish = nullptr;
1703 expect_refresh_image(mock_image_ctx, false, 0);
1704 expect_metadata_set(mock_image_ctx, &on_finish, "key", "value");
1706 C_SaferCond on_start_ready;
1707 C_SaferCond on_start_safe;
1708 when_process(mock_journal_replay, EventEntry{MetadataSetEvent(123, "key", "value")},
1709 &on_start_ready, &on_start_safe);
1710 ASSERT_EQ(0, on_start_ready.wait());
1712 C_SaferCond on_finish_ready;
1713 C_SaferCond on_finish_safe;
1714 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1715 &on_finish_ready, &on_finish_safe);
1717 wait_for_op_invoked(&on_finish, 0);
1718 ASSERT_EQ(0, on_start_safe.wait());
1719 ASSERT_EQ(0, on_finish_ready.wait());
1720 ASSERT_EQ(0, on_finish_safe.wait());
1723 TEST_F(TestMockJournalReplay, MetadataRemoveEvent) {
1724 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1726 librbd::ImageCtx *ictx;
1727 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1729 MockReplayImageCtx mock_image_ctx(*ictx);
1731 MockExclusiveLock mock_exclusive_lock;
1732 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1733 expect_accept_ops(mock_exclusive_lock, true);
1735 MockJournalReplay mock_journal_replay(mock_image_ctx);
1736 expect_op_work_queue(mock_image_ctx);
1739 Context *on_finish = nullptr;
1740 expect_refresh_image(mock_image_ctx, false, 0);
1741 expect_metadata_remove(mock_image_ctx, &on_finish, "key");
1743 C_SaferCond on_start_ready;
1744 C_SaferCond on_start_safe;
1745 when_process(mock_journal_replay, EventEntry{MetadataRemoveEvent(123, "key")},
1746 &on_start_ready, &on_start_safe);
1747 ASSERT_EQ(0, on_start_ready.wait());
1749 C_SaferCond on_finish_ready;
1750 C_SaferCond on_finish_safe;
1751 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1752 &on_finish_ready, &on_finish_safe);
1754 wait_for_op_invoked(&on_finish, 0);
1755 ASSERT_EQ(0, on_start_safe.wait());
1756 ASSERT_EQ(0, on_finish_ready.wait());
1757 ASSERT_EQ(0, on_finish_safe.wait());
1760 TEST_F(TestMockJournalReplay, MetadataRemoveEventDNE) {
1761 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1763 librbd::ImageCtx *ictx;
1764 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1766 MockReplayImageCtx mock_image_ctx(*ictx);
1768 MockExclusiveLock mock_exclusive_lock;
1769 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1770 expect_accept_ops(mock_exclusive_lock, true);
1772 MockJournalReplay mock_journal_replay(mock_image_ctx);
1773 expect_op_work_queue(mock_image_ctx);
1776 Context *on_finish = nullptr;
1777 expect_refresh_image(mock_image_ctx, false, 0);
1778 expect_metadata_remove(mock_image_ctx, &on_finish, "key");
1780 C_SaferCond on_start_ready;
1781 C_SaferCond on_start_safe;
1782 when_process(mock_journal_replay, EventEntry{MetadataRemoveEvent(123, "key")},
1783 &on_start_ready, &on_start_safe);
1784 ASSERT_EQ(0, on_start_ready.wait());
1786 C_SaferCond on_finish_ready;
1787 C_SaferCond on_finish_safe;
1788 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1789 &on_finish_ready, &on_finish_safe);
1791 wait_for_op_invoked(&on_finish, -ENOENT);
1792 ASSERT_EQ(0, on_start_safe.wait());
1793 ASSERT_EQ(0, on_finish_ready.wait());
1794 ASSERT_EQ(0, on_finish_safe.wait());
1797 TEST_F(TestMockJournalReplay, UnknownEvent) {
1798 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1800 librbd::ImageCtx *ictx;
1801 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1803 MockReplayImageCtx mock_image_ctx(*ictx);
1805 MockExclusiveLock mock_exclusive_lock;
1806 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1807 expect_accept_ops(mock_exclusive_lock, true);
1809 MockJournalReplay mock_journal_replay(mock_image_ctx);
1810 expect_op_work_queue(mock_image_ctx);
1815 ENCODE_START(1, 1, bl);
1816 ::encode(static_cast<uint32_t>(-1), bl);
1819 bufferlist::iterator it = bl.begin();
1820 C_SaferCond on_ready;
1821 C_SaferCond on_safe;
1822 when_process(mock_journal_replay, &it, &on_ready, &on_safe);
1824 ASSERT_EQ(0, on_safe.wait());
1825 ASSERT_EQ(0, on_ready.wait());
1828 TEST_F(TestMockJournalReplay, RefreshImageBeforeOpStart) {
1829 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1831 librbd::ImageCtx *ictx;
1832 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1834 MockReplayImageCtx mock_image_ctx(*ictx);
1836 MockExclusiveLock mock_exclusive_lock;
1837 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1838 expect_accept_ops(mock_exclusive_lock, true);
1840 MockJournalReplay mock_journal_replay(mock_image_ctx);
1841 expect_op_work_queue(mock_image_ctx);
1844 Context *on_finish = nullptr;
1845 expect_refresh_image(mock_image_ctx, true, 0);
1846 expect_resize(mock_image_ctx, &on_finish, 234, 123);
1848 C_SaferCond on_start_ready;
1849 C_SaferCond on_start_safe;
1850 when_process(mock_journal_replay, EventEntry{ResizeEvent(123, 234)},
1851 &on_start_ready, &on_start_safe);
1853 C_SaferCond on_resume;
1854 when_replay_op_ready(mock_journal_replay, 123, &on_resume);
1855 ASSERT_EQ(0, on_start_ready.wait());
1857 C_SaferCond on_finish_ready;
1858 C_SaferCond on_finish_safe;
1859 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
1860 &on_finish_ready, &on_finish_safe);
1862 ASSERT_EQ(0, on_resume.wait());
1863 wait_for_op_invoked(&on_finish, 0);
1865 ASSERT_EQ(0, on_start_safe.wait());
1866 ASSERT_EQ(0, on_finish_ready.wait());
1867 ASSERT_EQ(0, on_finish_safe.wait());
1870 TEST_F(TestMockJournalReplay, FlushEventAfterShutDown) {
1871 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1873 librbd::ImageCtx *ictx;
1874 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1876 MockReplayImageCtx mock_image_ctx(*ictx);
1878 MockExclusiveLock mock_exclusive_lock;
1879 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1880 expect_accept_ops(mock_exclusive_lock, true);
1882 MockJournalReplay mock_journal_replay(mock_image_ctx);
1883 MockIoImageRequest mock_io_image_request;
1884 expect_op_work_queue(mock_image_ctx);
1886 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
1888 C_SaferCond on_ready;
1889 C_SaferCond on_safe;
1890 when_process(mock_journal_replay, EventEntry{AioFlushEvent()},
1891 &on_ready, &on_safe);
1892 ASSERT_EQ(0, on_ready.wait());
1893 ASSERT_EQ(-ESHUTDOWN, on_safe.wait());
1896 TEST_F(TestMockJournalReplay, ModifyEventAfterShutDown) {
1897 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1899 librbd::ImageCtx *ictx;
1900 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1902 MockReplayImageCtx mock_image_ctx(*ictx);
1904 MockExclusiveLock mock_exclusive_lock;
1905 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1906 expect_accept_ops(mock_exclusive_lock, true);
1908 MockJournalReplay mock_journal_replay(mock_image_ctx);
1909 MockIoImageRequest mock_io_image_request;
1910 expect_op_work_queue(mock_image_ctx);
1912 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
1914 C_SaferCond on_ready;
1915 C_SaferCond on_safe;
1916 when_process(mock_journal_replay,
1917 EventEntry{AioWriteEvent(123, 456, to_bl("test"))},
1918 &on_ready, &on_safe);
1919 ASSERT_EQ(0, on_ready.wait());
1920 ASSERT_EQ(-ESHUTDOWN, on_safe.wait());
1923 TEST_F(TestMockJournalReplay, OpEventAfterShutDown) {
1924 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1926 librbd::ImageCtx *ictx;
1927 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1929 MockReplayImageCtx mock_image_ctx(*ictx);
1931 MockExclusiveLock mock_exclusive_lock;
1932 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1933 expect_accept_ops(mock_exclusive_lock, true);
1935 MockJournalReplay mock_journal_replay(mock_image_ctx);
1936 MockIoImageRequest mock_io_image_request;
1937 expect_op_work_queue(mock_image_ctx);
1939 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
1941 C_SaferCond on_ready;
1942 C_SaferCond on_safe;
1943 when_process(mock_journal_replay, EventEntry{RenameEvent(123, "image")},
1944 &on_ready, &on_safe);
1945 ASSERT_EQ(0, on_ready.wait());
1946 ASSERT_EQ(-ESHUTDOWN, on_safe.wait());
1949 TEST_F(TestMockJournalReplay, LockLostBeforeProcess) {
1950 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1952 librbd::ImageCtx *ictx;
1953 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1955 MockReplayImageCtx mock_image_ctx(*ictx);
1957 MockExclusiveLock mock_exclusive_lock;
1958 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1959 expect_accept_ops(mock_exclusive_lock, false);
1961 MockJournalReplay mock_journal_replay(mock_image_ctx);
1962 MockIoImageRequest mock_io_image_request;
1963 expect_op_work_queue(mock_image_ctx);
1966 C_SaferCond on_ready;
1967 C_SaferCond on_safe;
1968 when_process(mock_journal_replay, EventEntry{AioFlushEvent()},
1969 &on_ready, &on_safe);
1970 ASSERT_EQ(0, on_ready.wait());
1971 ASSERT_EQ(-ECANCELED, on_safe.wait());
1973 ASSERT_EQ(0, when_shut_down(mock_journal_replay, false));
1976 TEST_F(TestMockJournalReplay, LockLostBeforeExecuteOp) {
1977 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING);
1979 librbd::ImageCtx *ictx;
1980 ASSERT_EQ(0, open_image(m_image_name, &ictx));
1982 MockReplayImageCtx mock_image_ctx(*ictx);
1984 MockExclusiveLock mock_exclusive_lock;
1985 mock_image_ctx.exclusive_lock = &mock_exclusive_lock;
1986 expect_accept_ops(mock_exclusive_lock, false);
1988 MockJournalReplay mock_journal_replay(mock_image_ctx);
1989 expect_op_work_queue(mock_image_ctx);
1992 EXPECT_CALL(mock_exclusive_lock, accept_ops()).WillOnce(Return(true));
1993 EXPECT_CALL(mock_exclusive_lock, accept_ops()).WillOnce(Return(true));
1994 expect_refresh_image(mock_image_ctx, false, 0);
1996 C_SaferCond on_start_ready;
1997 C_SaferCond on_start_safe;
1998 when_process(mock_journal_replay, EventEntry{RenameEvent(123, "image")},
1999 &on_start_ready, &on_start_safe);
2000 ASSERT_EQ(0, on_start_ready.wait());
2002 C_SaferCond on_finish_ready;
2003 C_SaferCond on_finish_safe;
2004 when_process(mock_journal_replay, EventEntry{OpFinishEvent(123, 0)},
2005 &on_finish_ready, &on_finish_safe);
2007 ASSERT_EQ(-ECANCELED, on_start_safe.wait());
2008 ASSERT_EQ(0, on_finish_ready.wait());
2009 ASSERT_EQ(-ECANCELED, on_finish_safe.wait());
2012 } // namespace journal
2013 } // namespace librbd