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_metadata_set(mock_image_ctx
, &on_finish
, "key", "value");
1704 expect_refresh_image(mock_image_ctx
, false, 0);
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_metadata_remove(mock_image_ctx
, &on_finish
, "key");
1741 expect_refresh_image(mock_image_ctx
, false, 0);
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_metadata_remove(mock_image_ctx
, &on_finish
, "key");
1779 C_SaferCond on_start_ready
;
1780 C_SaferCond on_start_safe
;
1781 when_process(mock_journal_replay
, EventEntry
{MetadataRemoveEvent(123, "key")},
1782 &on_start_ready
, &on_start_safe
);
1783 ASSERT_EQ(0, on_start_ready
.wait());
1785 C_SaferCond on_finish_ready
;
1786 C_SaferCond on_finish_safe
;
1787 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1788 &on_finish_ready
, &on_finish_safe
);
1790 wait_for_op_invoked(&on_finish
, -ENOENT
);
1791 ASSERT_EQ(0, on_start_safe
.wait());
1792 ASSERT_EQ(0, on_finish_ready
.wait());
1793 ASSERT_EQ(0, on_finish_safe
.wait());
1796 TEST_F(TestMockJournalReplay
, UnknownEvent
) {
1797 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1799 librbd::ImageCtx
*ictx
;
1800 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1802 MockReplayImageCtx
mock_image_ctx(*ictx
);
1804 MockExclusiveLock mock_exclusive_lock
;
1805 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1806 expect_accept_ops(mock_exclusive_lock
, true);
1808 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1809 expect_op_work_queue(mock_image_ctx
);
1814 ENCODE_START(1, 1, bl
);
1815 ::encode(static_cast<uint32_t>(-1), bl
);
1818 bufferlist::iterator it
= bl
.begin();
1819 C_SaferCond on_ready
;
1820 C_SaferCond on_safe
;
1821 when_process(mock_journal_replay
, &it
, &on_ready
, &on_safe
);
1823 ASSERT_EQ(0, on_safe
.wait());
1824 ASSERT_EQ(0, on_ready
.wait());
1827 TEST_F(TestMockJournalReplay
, RefreshImageBeforeOpStart
) {
1828 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1830 librbd::ImageCtx
*ictx
;
1831 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1833 MockReplayImageCtx
mock_image_ctx(*ictx
);
1835 MockExclusiveLock mock_exclusive_lock
;
1836 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1837 expect_accept_ops(mock_exclusive_lock
, true);
1839 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1840 expect_op_work_queue(mock_image_ctx
);
1843 Context
*on_finish
= nullptr;
1844 expect_refresh_image(mock_image_ctx
, true, 0);
1845 expect_resize(mock_image_ctx
, &on_finish
, 234, 123);
1847 C_SaferCond on_start_ready
;
1848 C_SaferCond on_start_safe
;
1849 when_process(mock_journal_replay
, EventEntry
{ResizeEvent(123, 234)},
1850 &on_start_ready
, &on_start_safe
);
1852 C_SaferCond on_resume
;
1853 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
1854 ASSERT_EQ(0, on_start_ready
.wait());
1856 C_SaferCond on_finish_ready
;
1857 C_SaferCond on_finish_safe
;
1858 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1859 &on_finish_ready
, &on_finish_safe
);
1861 ASSERT_EQ(0, on_resume
.wait());
1862 wait_for_op_invoked(&on_finish
, 0);
1864 ASSERT_EQ(0, on_start_safe
.wait());
1865 ASSERT_EQ(0, on_finish_ready
.wait());
1866 ASSERT_EQ(0, on_finish_safe
.wait());
1869 TEST_F(TestMockJournalReplay
, FlushEventAfterShutDown
) {
1870 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1872 librbd::ImageCtx
*ictx
;
1873 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1875 MockReplayImageCtx
mock_image_ctx(*ictx
);
1877 MockExclusiveLock mock_exclusive_lock
;
1878 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1879 expect_accept_ops(mock_exclusive_lock
, true);
1881 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1882 MockIoImageRequest mock_io_image_request
;
1883 expect_op_work_queue(mock_image_ctx
);
1885 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1887 C_SaferCond on_ready
;
1888 C_SaferCond on_safe
;
1889 when_process(mock_journal_replay
, EventEntry
{AioFlushEvent()},
1890 &on_ready
, &on_safe
);
1891 ASSERT_EQ(0, on_ready
.wait());
1892 ASSERT_EQ(-ESHUTDOWN
, on_safe
.wait());
1895 TEST_F(TestMockJournalReplay
, ModifyEventAfterShutDown
) {
1896 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1898 librbd::ImageCtx
*ictx
;
1899 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1901 MockReplayImageCtx
mock_image_ctx(*ictx
);
1903 MockExclusiveLock mock_exclusive_lock
;
1904 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1905 expect_accept_ops(mock_exclusive_lock
, true);
1907 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1908 MockIoImageRequest mock_io_image_request
;
1909 expect_op_work_queue(mock_image_ctx
);
1911 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1913 C_SaferCond on_ready
;
1914 C_SaferCond on_safe
;
1915 when_process(mock_journal_replay
,
1916 EventEntry
{AioWriteEvent(123, 456, to_bl("test"))},
1917 &on_ready
, &on_safe
);
1918 ASSERT_EQ(0, on_ready
.wait());
1919 ASSERT_EQ(-ESHUTDOWN
, on_safe
.wait());
1922 TEST_F(TestMockJournalReplay
, OpEventAfterShutDown
) {
1923 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1925 librbd::ImageCtx
*ictx
;
1926 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1928 MockReplayImageCtx
mock_image_ctx(*ictx
);
1930 MockExclusiveLock mock_exclusive_lock
;
1931 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1932 expect_accept_ops(mock_exclusive_lock
, true);
1934 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1935 MockIoImageRequest mock_io_image_request
;
1936 expect_op_work_queue(mock_image_ctx
);
1938 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1940 C_SaferCond on_ready
;
1941 C_SaferCond on_safe
;
1942 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
1943 &on_ready
, &on_safe
);
1944 ASSERT_EQ(0, on_ready
.wait());
1945 ASSERT_EQ(-ESHUTDOWN
, on_safe
.wait());
1948 TEST_F(TestMockJournalReplay
, LockLostBeforeProcess
) {
1949 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1951 librbd::ImageCtx
*ictx
;
1952 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1954 MockReplayImageCtx
mock_image_ctx(*ictx
);
1956 MockExclusiveLock mock_exclusive_lock
;
1957 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1958 expect_accept_ops(mock_exclusive_lock
, false);
1960 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1961 MockIoImageRequest mock_io_image_request
;
1962 expect_op_work_queue(mock_image_ctx
);
1965 C_SaferCond on_ready
;
1966 C_SaferCond on_safe
;
1967 when_process(mock_journal_replay
, EventEntry
{AioFlushEvent()},
1968 &on_ready
, &on_safe
);
1969 ASSERT_EQ(0, on_ready
.wait());
1970 ASSERT_EQ(-ECANCELED
, on_safe
.wait());
1972 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1975 TEST_F(TestMockJournalReplay
, LockLostBeforeExecuteOp
) {
1976 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1978 librbd::ImageCtx
*ictx
;
1979 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1981 MockReplayImageCtx
mock_image_ctx(*ictx
);
1983 MockExclusiveLock mock_exclusive_lock
;
1984 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1985 expect_accept_ops(mock_exclusive_lock
, false);
1987 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1988 expect_op_work_queue(mock_image_ctx
);
1991 EXPECT_CALL(mock_exclusive_lock
, accept_ops()).WillOnce(Return(true));
1992 EXPECT_CALL(mock_exclusive_lock
, accept_ops()).WillOnce(Return(true));
1993 expect_refresh_image(mock_image_ctx
, false, 0);
1995 C_SaferCond on_start_ready
;
1996 C_SaferCond on_start_safe
;
1997 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
1998 &on_start_ready
, &on_start_safe
);
1999 ASSERT_EQ(0, on_start_ready
.wait());
2001 C_SaferCond on_finish_ready
;
2002 C_SaferCond on_finish_safe
;
2003 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
2004 &on_finish_ready
, &on_finish_safe
);
2006 ASSERT_EQ(-ECANCELED
, on_start_safe
.wait());
2007 ASSERT_EQ(0, on_finish_ready
.wait());
2008 ASSERT_EQ(-ECANCELED
, on_finish_safe
.wait());
2011 } // namespace journal
2012 } // namespace librbd