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 expect_writeback_cache_enabled(MockReplayImageCtx
&mock_image_ctx
,
293 EXPECT_CALL(mock_image_ctx
, is_writeback_cache_enabled())
294 .WillRepeatedly(Return(enabled
));
297 void when_process(MockJournalReplay
&mock_journal_replay
,
298 EventEntry
&&event_entry
, Context
*on_ready
,
301 ::encode(event_entry
, bl
);
303 bufferlist::iterator it
= bl
.begin();
304 when_process(mock_journal_replay
, &it
, on_ready
, on_safe
);
307 void when_process(MockJournalReplay
&mock_journal_replay
,
308 bufferlist::iterator
*it
, Context
*on_ready
,
310 EventEntry event_entry
;
311 int r
= mock_journal_replay
.decode(it
, &event_entry
);
314 mock_journal_replay
.process(event_entry
, on_ready
, on_safe
);
317 void when_complete(MockReplayImageCtx
&mock_image_ctx
,
318 io::AioCompletion
*aio_comp
, int r
) {
320 aio_comp
->init_time(mock_image_ctx
.image_ctx
, librbd::io::AIO_TYPE_NONE
);
321 aio_comp
->set_request_count(1);
322 aio_comp
->complete_request(r
);
325 int when_flush(MockJournalReplay
&mock_journal_replay
) {
327 mock_journal_replay
.flush(&ctx
);
331 int when_shut_down(MockJournalReplay
&mock_journal_replay
, bool cancel_ops
) {
333 mock_journal_replay
.shut_down(cancel_ops
, &ctx
);
337 void when_replay_op_ready(MockJournalReplay
&mock_journal_replay
,
338 uint64_t op_tid
, Context
*on_resume
) {
339 mock_journal_replay
.replay_op_ready(op_tid
, on_resume
);
342 void wait_for_op_invoked(Context
**on_finish
, int r
) {
344 Mutex::Locker
locker(m_invoke_lock
);
345 while (*on_finish
== nullptr) {
346 m_invoke_cond
.Wait(m_invoke_lock
);
349 (*on_finish
)->complete(r
);
352 bufferlist
to_bl(const std::string
&str
) {
362 TEST_F(TestMockJournalReplay
, AioDiscard
) {
363 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
365 librbd::ImageCtx
*ictx
;
366 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
368 MockReplayImageCtx
mock_image_ctx(*ictx
);
370 MockExclusiveLock mock_exclusive_lock
;
371 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
372 expect_accept_ops(mock_exclusive_lock
, true);
374 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
375 MockIoImageRequest mock_io_image_request
;
376 expect_writeback_cache_enabled(mock_image_ctx
, true);
377 expect_op_work_queue(mock_image_ctx
);
380 io::AioCompletion
*aio_comp
;
381 C_SaferCond on_ready
;
383 expect_aio_discard(mock_io_image_request
, &aio_comp
, 123, 456, ictx
->skip_partial_discard
);
384 when_process(mock_journal_replay
,
385 EventEntry
{AioDiscardEvent(123, 456, ictx
->skip_partial_discard
)},
386 &on_ready
, &on_safe
);
388 when_complete(mock_image_ctx
, aio_comp
, 0);
389 ASSERT_EQ(0, on_ready
.wait());
391 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
392 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
393 ASSERT_EQ(0, on_safe
.wait());
396 TEST_F(TestMockJournalReplay
, AioWrite
) {
397 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
399 librbd::ImageCtx
*ictx
;
400 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
402 MockReplayImageCtx
mock_image_ctx(*ictx
);
404 MockExclusiveLock mock_exclusive_lock
;
405 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
406 expect_accept_ops(mock_exclusive_lock
, true);
408 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
409 MockIoImageRequest mock_io_image_request
;
410 expect_writeback_cache_enabled(mock_image_ctx
, true);
411 expect_op_work_queue(mock_image_ctx
);
414 io::AioCompletion
*aio_comp
;
415 C_SaferCond on_ready
;
417 expect_aio_write(mock_io_image_request
, &aio_comp
, 123, 456, "test");
418 when_process(mock_journal_replay
,
419 EventEntry
{AioWriteEvent(123, 456, to_bl("test"))},
420 &on_ready
, &on_safe
);
422 when_complete(mock_image_ctx
, aio_comp
, 0);
423 ASSERT_EQ(0, on_ready
.wait());
425 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
426 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
427 ASSERT_EQ(0, on_safe
.wait());
430 TEST_F(TestMockJournalReplay
, AioFlush
) {
431 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
433 librbd::ImageCtx
*ictx
;
434 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
436 MockReplayImageCtx
mock_image_ctx(*ictx
);
438 MockExclusiveLock mock_exclusive_lock
;
439 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
440 expect_accept_ops(mock_exclusive_lock
, true);
442 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
443 MockIoImageRequest mock_io_image_request
;
444 expect_op_work_queue(mock_image_ctx
);
447 io::AioCompletion
*aio_comp
;
448 C_SaferCond on_ready
;
450 expect_aio_flush(mock_io_image_request
, &aio_comp
);
451 when_process(mock_journal_replay
, EventEntry
{AioFlushEvent()},
452 &on_ready
, &on_safe
);
454 when_complete(mock_image_ctx
, aio_comp
, 0);
455 ASSERT_EQ(0, on_safe
.wait());
457 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
458 ASSERT_EQ(0, on_ready
.wait());
461 TEST_F(TestMockJournalReplay
, AioWriteSame
) {
462 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
464 librbd::ImageCtx
*ictx
;
465 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
467 MockReplayImageCtx
mock_image_ctx(*ictx
);
469 MockExclusiveLock mock_exclusive_lock
;
470 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
471 expect_accept_ops(mock_exclusive_lock
, true);
473 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
474 MockIoImageRequest mock_io_image_request
;
475 expect_writeback_cache_enabled(mock_image_ctx
, true);
476 expect_op_work_queue(mock_image_ctx
);
479 io::AioCompletion
*aio_comp
;
480 C_SaferCond on_ready
;
482 expect_aio_writesame(mock_io_image_request
, &aio_comp
, 123, 456, "333");
483 when_process(mock_journal_replay
,
484 EventEntry
{AioWriteSameEvent(123, 456, to_bl("333"))},
485 &on_ready
, &on_safe
);
487 when_complete(mock_image_ctx
, aio_comp
, 0);
488 ASSERT_EQ(0, on_ready
.wait());
490 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
491 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
492 ASSERT_EQ(0, on_safe
.wait());
496 TEST_F(TestMockJournalReplay
, AioCompareAndWrite
) {
497 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
499 librbd::ImageCtx
*ictx
;
500 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
502 MockReplayImageCtx
mock_image_ctx(*ictx
);
504 MockExclusiveLock mock_exclusive_lock
;
505 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
506 expect_accept_ops(mock_exclusive_lock
, true);
508 MockJournalReplay
mock_write_journal_replay(mock_image_ctx
);
509 MockJournalReplay
mock_compare_and_write_journal_replay(mock_image_ctx
);
510 MockJournalReplay
mock_mis_compare_and_write_journal_replay(mock_image_ctx
);
511 MockIoImageRequest mock_io_image_request
;
512 expect_writeback_cache_enabled(mock_image_ctx
, true);
513 expect_op_work_queue(mock_image_ctx
);
516 io::AioCompletion
*aio_comp
;
517 C_SaferCond on_ready
;
519 expect_aio_write(mock_io_image_request
, &aio_comp
, 512, 512, "test");
520 when_process(mock_write_journal_replay
,
521 EventEntry
{AioWriteEvent(512, 512, to_bl("test"))},
522 &on_ready
, &on_safe
);
524 when_complete(mock_image_ctx
, aio_comp
, 0);
525 ASSERT_EQ(0, on_ready
.wait());
527 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
528 ASSERT_EQ(0, when_shut_down(mock_write_journal_replay
, false));
529 ASSERT_EQ(0, on_safe
.wait());
531 expect_aio_compare_and_write(mock_io_image_request
, &aio_comp
,
532 512, 512, "test", "test", nullptr);
533 when_process(mock_compare_and_write_journal_replay
,
534 EventEntry
{AioCompareAndWriteEvent(512, 512, to_bl("test"),
535 to_bl("test"))}, &on_ready
, &on_safe
);
537 when_complete(mock_image_ctx
, aio_comp
, 0);
538 ASSERT_EQ(0, on_ready
.wait());
540 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
541 ASSERT_EQ(0, when_shut_down(mock_compare_and_write_journal_replay
, false));
542 ASSERT_EQ(0, on_safe
.wait());
544 expect_aio_compare_and_write(mock_io_image_request
, &aio_comp
,
545 512, 512, "111", "test", nullptr);
546 when_process(mock_mis_compare_and_write_journal_replay
,
547 EventEntry
{AioCompareAndWriteEvent(512, 512, to_bl("111"),
548 to_bl("test"))}, &on_ready
, &on_safe
);
550 when_complete(mock_image_ctx
, aio_comp
, 0);
551 ASSERT_EQ(0, on_ready
.wait());
553 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
554 ASSERT_EQ(0, when_shut_down(mock_mis_compare_and_write_journal_replay
, false));
555 ASSERT_EQ(0, on_safe
.wait());
559 TEST_F(TestMockJournalReplay
, IOError
) {
560 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
562 librbd::ImageCtx
*ictx
;
563 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
565 MockReplayImageCtx
mock_image_ctx(*ictx
);
567 MockExclusiveLock mock_exclusive_lock
;
568 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
569 expect_accept_ops(mock_exclusive_lock
, true);
571 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
572 MockIoImageRequest mock_io_image_request
;
573 expect_writeback_cache_enabled(mock_image_ctx
, true);
574 expect_op_work_queue(mock_image_ctx
);
577 io::AioCompletion
*aio_comp
;
578 C_SaferCond on_ready
;
580 expect_aio_discard(mock_io_image_request
, &aio_comp
, 123, 456, ictx
->skip_partial_discard
);
581 when_process(mock_journal_replay
,
582 EventEntry
{AioDiscardEvent(123, 456, ictx
->skip_partial_discard
)},
583 &on_ready
, &on_safe
);
585 when_complete(mock_image_ctx
, aio_comp
, -EINVAL
);
586 ASSERT_EQ(-EINVAL
, on_safe
.wait());
588 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
589 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
590 ASSERT_EQ(0, on_ready
.wait());
593 TEST_F(TestMockJournalReplay
, SoftFlushIO
) {
594 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
596 librbd::ImageCtx
*ictx
;
597 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
599 MockReplayImageCtx
mock_image_ctx(*ictx
);
601 MockExclusiveLock mock_exclusive_lock
;
602 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
603 expect_accept_ops(mock_exclusive_lock
, true);
605 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
606 MockIoImageRequest mock_io_image_request
;
607 expect_writeback_cache_enabled(mock_image_ctx
, true);
608 expect_op_work_queue(mock_image_ctx
);
611 const size_t io_count
= 32;
612 C_SaferCond on_safes
[io_count
];
613 for (size_t i
= 0; i
< io_count
; ++i
) {
614 io::AioCompletion
*aio_comp
;
615 io::AioCompletion
*flush_comp
= nullptr;
616 C_SaferCond on_ready
;
617 expect_aio_discard(mock_io_image_request
, &aio_comp
, 123, 456, ictx
->skip_partial_discard
);
618 if (i
== io_count
- 1) {
619 expect_aio_flush(mock_io_image_request
, &flush_comp
);
621 when_process(mock_journal_replay
,
622 EventEntry
{AioDiscardEvent(123, 456, ictx
->skip_partial_discard
)},
623 &on_ready
, &on_safes
[i
]);
624 when_complete(mock_image_ctx
, aio_comp
, 0);
625 ASSERT_EQ(0, on_ready
.wait());
627 if (flush_comp
!= nullptr) {
628 when_complete(mock_image_ctx
, flush_comp
, 0);
631 for (auto &on_safe
: on_safes
) {
632 ASSERT_EQ(0, on_safe
.wait());
635 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
638 TEST_F(TestMockJournalReplay
, PauseIO
) {
639 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
641 librbd::ImageCtx
*ictx
;
642 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
644 MockReplayImageCtx
mock_image_ctx(*ictx
);
646 MockExclusiveLock mock_exclusive_lock
;
647 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
648 expect_accept_ops(mock_exclusive_lock
, true);
650 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
651 MockIoImageRequest mock_io_image_request
;
652 expect_writeback_cache_enabled(mock_image_ctx
, true);
653 expect_op_work_queue(mock_image_ctx
);
656 const size_t io_count
= 64;
657 std::list
<io::AioCompletion
*> flush_comps
;
658 C_SaferCond on_safes
[io_count
];
659 for (size_t i
= 0; i
< io_count
; ++i
) {
660 io::AioCompletion
*aio_comp
;
661 C_SaferCond on_ready
;
662 expect_aio_write(mock_io_image_request
, &aio_comp
, 123, 456, "test");
663 if ((i
+ 1) % 32 == 0) {
664 flush_comps
.push_back(nullptr);
665 expect_aio_flush(mock_io_image_request
, &flush_comps
.back());
667 when_process(mock_journal_replay
,
668 EventEntry
{AioWriteEvent(123, 456, to_bl("test"))},
669 &on_ready
, &on_safes
[i
]);
670 when_complete(mock_image_ctx
, aio_comp
, 0);
671 if (i
< io_count
- 1) {
672 ASSERT_EQ(0, on_ready
.wait());
674 for (auto flush_comp
: flush_comps
) {
675 when_complete(mock_image_ctx
, flush_comp
, 0);
677 ASSERT_EQ(0, on_ready
.wait());
680 for (auto &on_safe
: on_safes
) {
681 ASSERT_EQ(0, on_safe
.wait());
684 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
687 TEST_F(TestMockJournalReplay
, Flush
) {
688 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
690 librbd::ImageCtx
*ictx
;
691 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
693 MockReplayImageCtx
mock_image_ctx(*ictx
);
695 MockExclusiveLock mock_exclusive_lock
;
696 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
697 expect_accept_ops(mock_exclusive_lock
, true);
699 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
700 MockIoImageRequest mock_io_image_request
;
701 expect_writeback_cache_enabled(mock_image_ctx
, true);
702 expect_op_work_queue(mock_image_ctx
);
705 io::AioCompletion
*aio_comp
= nullptr;
706 C_SaferCond on_ready
;
708 expect_aio_discard(mock_io_image_request
, &aio_comp
, 123, 456, ictx
->skip_partial_discard
);
709 when_process(mock_journal_replay
,
710 EventEntry
{AioDiscardEvent(123, 456, ictx
->skip_partial_discard
)},
711 &on_ready
, &on_safe
);
713 when_complete(mock_image_ctx
, aio_comp
, 0);
714 ASSERT_EQ(0, on_ready
.wait());
716 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
717 ASSERT_EQ(0, when_flush(mock_journal_replay
));
718 ASSERT_EQ(0, on_safe
.wait());
721 TEST_F(TestMockJournalReplay
, OpFinishError
) {
722 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
724 librbd::ImageCtx
*ictx
;
725 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
727 MockReplayImageCtx
mock_image_ctx(*ictx
);
729 MockExclusiveLock mock_exclusive_lock
;
730 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
731 expect_accept_ops(mock_exclusive_lock
, true);
733 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
734 expect_op_work_queue(mock_image_ctx
);
737 C_SaferCond on_start_ready
;
738 C_SaferCond on_start_safe
;
739 when_process(mock_journal_replay
,
740 EventEntry
{SnapRemoveEvent(123,
741 cls::rbd::UserSnapshotNamespace(),
745 ASSERT_EQ(0, on_start_ready
.wait());
747 C_SaferCond on_finish_ready
;
748 C_SaferCond on_finish_safe
;
749 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, -EIO
)},
750 &on_finish_ready
, &on_finish_safe
);
752 ASSERT_EQ(-EIO
, on_start_safe
.wait());
753 ASSERT_EQ(-EIO
, on_finish_safe
.wait());
754 ASSERT_EQ(0, on_finish_ready
.wait());
757 TEST_F(TestMockJournalReplay
, BlockedOpFinishError
) {
758 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
760 librbd::ImageCtx
*ictx
;
761 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
763 MockReplayImageCtx
mock_image_ctx(*ictx
);
765 MockExclusiveLock mock_exclusive_lock
;
766 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
767 expect_accept_ops(mock_exclusive_lock
, true);
769 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
770 expect_op_work_queue(mock_image_ctx
);
773 Context
*on_finish
= nullptr;
774 expect_refresh_image(mock_image_ctx
, false, 0);
775 expect_snap_create(mock_image_ctx
, &on_finish
, "snap", 123);
777 C_SaferCond on_start_ready
;
778 C_SaferCond on_start_safe
;
779 when_process(mock_journal_replay
,
780 EventEntry
{SnapCreateEvent(123,
781 cls::rbd::UserSnapshotNamespace(),
786 C_SaferCond on_resume
;
787 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
788 ASSERT_EQ(0, on_start_ready
.wait());
790 C_SaferCond on_finish_ready
;
791 C_SaferCond on_finish_safe
;
792 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, -EBADMSG
)},
793 &on_finish_ready
, &on_finish_safe
);
795 ASSERT_EQ(-EBADMSG
, on_resume
.wait());
796 wait_for_op_invoked(&on_finish
, -ESTALE
);
798 ASSERT_EQ(-ESTALE
, on_start_safe
.wait());
799 ASSERT_EQ(-ESTALE
, on_finish_safe
.wait());
800 ASSERT_EQ(0, on_finish_ready
.wait());
803 TEST_F(TestMockJournalReplay
, MissingOpFinishEvent
) {
804 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
806 librbd::ImageCtx
*ictx
;
807 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
809 MockReplayImageCtx
mock_image_ctx(*ictx
);
811 MockExclusiveLock mock_exclusive_lock
;
812 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
813 expect_accept_ops(mock_exclusive_lock
, true);
815 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
816 expect_op_work_queue(mock_image_ctx
);
818 EXPECT_CALL(*mock_image_ctx
.state
, is_refresh_required())
819 .WillRepeatedly(Return(false));
822 Context
*on_snap_create_finish
= nullptr;
823 expect_snap_create(mock_image_ctx
, &on_snap_create_finish
, "snap", 123);
825 Context
*on_snap_remove_finish
= nullptr;
826 expect_snap_remove(mock_image_ctx
, &on_snap_remove_finish
, "snap");
828 C_SaferCond on_snap_remove_ready
;
829 C_SaferCond on_snap_remove_safe
;
830 when_process(mock_journal_replay
,
831 EventEntry
{SnapRemoveEvent(122,
832 cls::rbd::UserSnapshotNamespace(),
834 &on_snap_remove_ready
,
835 &on_snap_remove_safe
);
836 ASSERT_EQ(0, on_snap_remove_ready
.wait());
838 C_SaferCond on_snap_create_ready
;
839 C_SaferCond on_snap_create_safe
;
840 when_process(mock_journal_replay
,
841 EventEntry
{SnapCreateEvent(123,
842 cls::rbd::UserSnapshotNamespace(),
844 &on_snap_create_ready
,
845 &on_snap_create_safe
);
847 C_SaferCond on_shut_down
;
848 mock_journal_replay
.shut_down(false, &on_shut_down
);
850 wait_for_op_invoked(&on_snap_remove_finish
, 0);
851 ASSERT_EQ(0, on_snap_remove_safe
.wait());
853 C_SaferCond on_snap_create_resume
;
854 when_replay_op_ready(mock_journal_replay
, 123, &on_snap_create_resume
);
855 ASSERT_EQ(0, on_snap_create_resume
.wait());
857 wait_for_op_invoked(&on_snap_create_finish
, 0);
858 ASSERT_EQ(0, on_snap_create_ready
.wait());
859 ASSERT_EQ(0, on_snap_create_safe
.wait());
861 ASSERT_EQ(0, on_shut_down
.wait());
864 TEST_F(TestMockJournalReplay
, MissingOpFinishEventCancelOps
) {
865 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
867 librbd::ImageCtx
*ictx
;
868 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
870 MockReplayImageCtx
mock_image_ctx(*ictx
);
872 MockExclusiveLock mock_exclusive_lock
;
873 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
874 expect_accept_ops(mock_exclusive_lock
, true);
876 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
877 expect_op_work_queue(mock_image_ctx
);
880 Context
*on_snap_create_finish
= nullptr;
881 expect_refresh_image(mock_image_ctx
, false, 0);
882 expect_snap_create(mock_image_ctx
, &on_snap_create_finish
, "snap", 123);
884 C_SaferCond on_snap_remove_ready
;
885 C_SaferCond on_snap_remove_safe
;
886 when_process(mock_journal_replay
,
887 EventEntry
{SnapRemoveEvent(122,
888 cls::rbd::UserSnapshotNamespace(),
890 &on_snap_remove_ready
,
891 &on_snap_remove_safe
);
892 ASSERT_EQ(0, on_snap_remove_ready
.wait());
894 C_SaferCond on_snap_create_ready
;
895 C_SaferCond on_snap_create_safe
;
896 when_process(mock_journal_replay
,
897 EventEntry
{SnapCreateEvent(123,
898 cls::rbd::UserSnapshotNamespace(),
900 &on_snap_create_ready
,
901 &on_snap_create_safe
);
903 C_SaferCond on_resume
;
904 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
905 ASSERT_EQ(0, on_snap_create_ready
.wait());
907 C_SaferCond on_shut_down
;
908 mock_journal_replay
.shut_down(true, &on_shut_down
);
910 ASSERT_EQ(-ERESTART
, on_resume
.wait());
911 on_snap_create_finish
->complete(-ERESTART
);
912 ASSERT_EQ(-ERESTART
, on_snap_create_safe
.wait());
914 ASSERT_EQ(-ERESTART
, on_snap_remove_safe
.wait());
915 ASSERT_EQ(0, on_shut_down
.wait());
918 TEST_F(TestMockJournalReplay
, UnknownOpFinishEvent
) {
919 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
921 librbd::ImageCtx
*ictx
;
922 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
924 MockReplayImageCtx
mock_image_ctx(*ictx
);
926 MockExclusiveLock mock_exclusive_lock
;
927 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
928 expect_accept_ops(mock_exclusive_lock
, true);
930 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
931 expect_op_work_queue(mock_image_ctx
);
934 C_SaferCond on_ready
;
936 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
937 &on_ready
, &on_safe
);
939 ASSERT_EQ(0, on_safe
.wait());
940 ASSERT_EQ(0, on_ready
.wait());
943 TEST_F(TestMockJournalReplay
, OpEventError
) {
944 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
946 librbd::ImageCtx
*ictx
;
947 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
949 MockReplayImageCtx
mock_image_ctx(*ictx
);
951 MockExclusiveLock mock_exclusive_lock
;
952 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
953 expect_accept_ops(mock_exclusive_lock
, true);
955 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
956 expect_op_work_queue(mock_image_ctx
);
959 Context
*on_finish
= nullptr;
960 expect_refresh_image(mock_image_ctx
, false, 0);
961 expect_snap_remove(mock_image_ctx
, &on_finish
, "snap");
963 C_SaferCond on_start_ready
;
964 C_SaferCond on_start_safe
;
965 when_process(mock_journal_replay
,
966 EventEntry
{SnapRemoveEvent(123,
967 cls::rbd::UserSnapshotNamespace(),
971 ASSERT_EQ(0, on_start_ready
.wait());
973 C_SaferCond on_finish_ready
;
974 C_SaferCond on_finish_safe
;
975 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
976 &on_finish_ready
, &on_finish_safe
);
978 wait_for_op_invoked(&on_finish
, -EINVAL
);
979 ASSERT_EQ(-EINVAL
, on_start_safe
.wait());
980 ASSERT_EQ(0, on_finish_ready
.wait());
981 ASSERT_EQ(-EINVAL
, on_finish_safe
.wait());
984 TEST_F(TestMockJournalReplay
, SnapCreateEvent
) {
985 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
987 librbd::ImageCtx
*ictx
;
988 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
990 MockReplayImageCtx
mock_image_ctx(*ictx
);
992 MockExclusiveLock mock_exclusive_lock
;
993 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
994 expect_accept_ops(mock_exclusive_lock
, true);
996 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
997 expect_op_work_queue(mock_image_ctx
);
1000 Context
*on_finish
= nullptr;
1001 expect_refresh_image(mock_image_ctx
, false, 0);
1002 expect_snap_create(mock_image_ctx
, &on_finish
, "snap", 123);
1004 C_SaferCond on_start_ready
;
1005 C_SaferCond on_start_safe
;
1006 when_process(mock_journal_replay
,
1007 EventEntry
{SnapCreateEvent(123,
1008 cls::rbd::UserSnapshotNamespace(),
1013 C_SaferCond on_resume
;
1014 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
1015 ASSERT_EQ(0, on_start_ready
.wait());
1017 C_SaferCond on_finish_ready
;
1018 C_SaferCond on_finish_safe
;
1019 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1020 &on_finish_ready
, &on_finish_safe
);
1022 ASSERT_EQ(0, on_resume
.wait());
1023 wait_for_op_invoked(&on_finish
, 0);
1025 ASSERT_EQ(0, on_start_safe
.wait());
1026 ASSERT_EQ(0, on_finish_ready
.wait());
1027 ASSERT_EQ(0, on_finish_safe
.wait());
1030 TEST_F(TestMockJournalReplay
, SnapCreateEventExists
) {
1031 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1033 librbd::ImageCtx
*ictx
;
1034 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1036 MockReplayImageCtx
mock_image_ctx(*ictx
);
1038 MockExclusiveLock mock_exclusive_lock
;
1039 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1040 expect_accept_ops(mock_exclusive_lock
, true);
1042 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1043 expect_op_work_queue(mock_image_ctx
);
1046 Context
*on_finish
= nullptr;
1047 expect_refresh_image(mock_image_ctx
, false, 0);
1048 expect_snap_create(mock_image_ctx
, &on_finish
, "snap", 123);
1050 C_SaferCond on_start_ready
;
1051 C_SaferCond on_start_safe
;
1052 when_process(mock_journal_replay
,
1053 EventEntry
{SnapCreateEvent(123,
1054 cls::rbd::UserSnapshotNamespace(),
1059 wait_for_op_invoked(&on_finish
, -EEXIST
);
1060 ASSERT_EQ(0, on_start_ready
.wait());
1062 C_SaferCond on_finish_ready
;
1063 C_SaferCond on_finish_safe
;
1064 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1065 &on_finish_ready
, &on_finish_safe
);
1067 ASSERT_EQ(0, on_start_safe
.wait());
1068 ASSERT_EQ(0, on_finish_ready
.wait());
1069 ASSERT_EQ(0, on_finish_safe
.wait());
1072 TEST_F(TestMockJournalReplay
, SnapRemoveEvent
) {
1073 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1075 librbd::ImageCtx
*ictx
;
1076 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1078 MockReplayImageCtx
mock_image_ctx(*ictx
);
1080 MockExclusiveLock mock_exclusive_lock
;
1081 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1082 expect_accept_ops(mock_exclusive_lock
, true);
1084 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1085 expect_op_work_queue(mock_image_ctx
);
1088 Context
*on_finish
= nullptr;
1089 expect_refresh_image(mock_image_ctx
, false, 0);
1090 expect_snap_remove(mock_image_ctx
, &on_finish
, "snap");
1092 C_SaferCond on_start_ready
;
1093 C_SaferCond on_start_safe
;
1094 when_process(mock_journal_replay
,
1095 EventEntry
{SnapRemoveEvent(123,
1096 cls::rbd::UserSnapshotNamespace(),
1100 ASSERT_EQ(0, on_start_ready
.wait());
1102 C_SaferCond on_finish_ready
;
1103 C_SaferCond on_finish_safe
;
1104 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1105 &on_finish_ready
, &on_finish_safe
);
1107 wait_for_op_invoked(&on_finish
, 0);
1108 ASSERT_EQ(0, on_start_safe
.wait());
1109 ASSERT_EQ(0, on_finish_ready
.wait());
1110 ASSERT_EQ(0, on_finish_safe
.wait());
1113 TEST_F(TestMockJournalReplay
, SnapRemoveEventDNE
) {
1114 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1116 librbd::ImageCtx
*ictx
;
1117 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1119 MockReplayImageCtx
mock_image_ctx(*ictx
);
1121 MockExclusiveLock mock_exclusive_lock
;
1122 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1123 expect_accept_ops(mock_exclusive_lock
, true);
1125 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1126 expect_op_work_queue(mock_image_ctx
);
1129 Context
*on_finish
= nullptr;
1130 expect_refresh_image(mock_image_ctx
, false, 0);
1131 expect_snap_remove(mock_image_ctx
, &on_finish
, "snap");
1133 C_SaferCond on_start_ready
;
1134 C_SaferCond on_start_safe
;
1135 when_process(mock_journal_replay
,
1136 EventEntry
{SnapRemoveEvent(123,
1137 cls::rbd::UserSnapshotNamespace(),
1141 ASSERT_EQ(0, on_start_ready
.wait());
1143 C_SaferCond on_finish_ready
;
1144 C_SaferCond on_finish_safe
;
1145 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1146 &on_finish_ready
, &on_finish_safe
);
1148 wait_for_op_invoked(&on_finish
, -ENOENT
);
1149 ASSERT_EQ(0, on_start_safe
.wait());
1150 ASSERT_EQ(0, on_finish_ready
.wait());
1151 ASSERT_EQ(0, on_finish_safe
.wait());
1154 TEST_F(TestMockJournalReplay
, SnapRenameEvent
) {
1155 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1157 librbd::ImageCtx
*ictx
;
1158 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1160 MockReplayImageCtx
mock_image_ctx(*ictx
);
1162 MockExclusiveLock mock_exclusive_lock
;
1163 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1164 expect_accept_ops(mock_exclusive_lock
, true);
1166 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1167 expect_op_work_queue(mock_image_ctx
);
1170 Context
*on_finish
= nullptr;
1171 expect_refresh_image(mock_image_ctx
, false, 0);
1172 expect_snap_rename(mock_image_ctx
, &on_finish
, 234, "snap");
1174 C_SaferCond on_start_ready
;
1175 C_SaferCond on_start_safe
;
1176 when_process(mock_journal_replay
,
1177 EventEntry
{SnapRenameEvent(123, 234, "snap1", "snap")},
1178 &on_start_ready
, &on_start_safe
);
1179 ASSERT_EQ(0, on_start_ready
.wait());
1181 C_SaferCond on_finish_ready
;
1182 C_SaferCond on_finish_safe
;
1183 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1184 &on_finish_ready
, &on_finish_safe
);
1186 wait_for_op_invoked(&on_finish
, 0);
1187 ASSERT_EQ(0, on_start_safe
.wait());
1188 ASSERT_EQ(0, on_finish_ready
.wait());
1189 ASSERT_EQ(0, on_finish_safe
.wait());
1192 TEST_F(TestMockJournalReplay
, SnapRenameEventExists
) {
1193 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1195 librbd::ImageCtx
*ictx
;
1196 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1198 MockReplayImageCtx
mock_image_ctx(*ictx
);
1200 MockExclusiveLock mock_exclusive_lock
;
1201 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1202 expect_accept_ops(mock_exclusive_lock
, true);
1204 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1205 expect_op_work_queue(mock_image_ctx
);
1208 Context
*on_finish
= nullptr;
1209 expect_refresh_image(mock_image_ctx
, false, 0);
1210 expect_snap_rename(mock_image_ctx
, &on_finish
, 234, "snap");
1212 C_SaferCond on_start_ready
;
1213 C_SaferCond on_start_safe
;
1214 when_process(mock_journal_replay
,
1215 EventEntry
{SnapRenameEvent(123, 234, "snap1", "snap")},
1216 &on_start_ready
, &on_start_safe
);
1217 ASSERT_EQ(0, on_start_ready
.wait());
1219 C_SaferCond on_finish_ready
;
1220 C_SaferCond on_finish_safe
;
1221 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1222 &on_finish_ready
, &on_finish_safe
);
1224 wait_for_op_invoked(&on_finish
, -EEXIST
);
1225 ASSERT_EQ(0, on_start_safe
.wait());
1226 ASSERT_EQ(0, on_finish_ready
.wait());
1227 ASSERT_EQ(0, on_finish_safe
.wait());
1230 TEST_F(TestMockJournalReplay
, SnapProtectEvent
) {
1231 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1233 librbd::ImageCtx
*ictx
;
1234 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1236 MockReplayImageCtx
mock_image_ctx(*ictx
);
1238 MockExclusiveLock mock_exclusive_lock
;
1239 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1240 expect_accept_ops(mock_exclusive_lock
, true);
1242 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1243 expect_op_work_queue(mock_image_ctx
);
1246 Context
*on_finish
= nullptr;
1247 expect_refresh_image(mock_image_ctx
, false, 0);
1248 expect_snap_protect(mock_image_ctx
, &on_finish
, "snap");
1250 C_SaferCond on_start_ready
;
1251 C_SaferCond on_start_safe
;
1252 when_process(mock_journal_replay
,
1253 EventEntry
{SnapProtectEvent(123,
1254 cls::rbd::UserSnapshotNamespace(),
1258 ASSERT_EQ(0, on_start_ready
.wait());
1260 C_SaferCond on_finish_ready
;
1261 C_SaferCond on_finish_safe
;
1262 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1263 &on_finish_ready
, &on_finish_safe
);
1265 wait_for_op_invoked(&on_finish
, 0);
1266 ASSERT_EQ(0, on_start_safe
.wait());
1267 ASSERT_EQ(0, on_finish_ready
.wait());
1268 ASSERT_EQ(0, on_finish_safe
.wait());
1271 TEST_F(TestMockJournalReplay
, SnapProtectEventBusy
) {
1272 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1274 librbd::ImageCtx
*ictx
;
1275 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1277 MockReplayImageCtx
mock_image_ctx(*ictx
);
1279 MockExclusiveLock mock_exclusive_lock
;
1280 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1281 expect_accept_ops(mock_exclusive_lock
, true);
1283 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1284 expect_op_work_queue(mock_image_ctx
);
1287 Context
*on_finish
= nullptr;
1288 expect_refresh_image(mock_image_ctx
, false, 0);
1289 expect_snap_protect(mock_image_ctx
, &on_finish
, "snap");
1291 C_SaferCond on_start_ready
;
1292 C_SaferCond on_start_safe
;
1293 when_process(mock_journal_replay
,
1294 EventEntry
{SnapProtectEvent(123,
1295 cls::rbd::UserSnapshotNamespace(),
1299 ASSERT_EQ(0, on_start_ready
.wait());
1301 C_SaferCond on_finish_ready
;
1302 C_SaferCond on_finish_safe
;
1303 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1304 &on_finish_ready
, &on_finish_safe
);
1306 wait_for_op_invoked(&on_finish
, -EBUSY
);
1307 ASSERT_EQ(0, on_start_safe
.wait());
1308 ASSERT_EQ(0, on_finish_ready
.wait());
1309 ASSERT_EQ(0, on_finish_safe
.wait());
1312 TEST_F(TestMockJournalReplay
, SnapUnprotectEvent
) {
1313 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1315 librbd::ImageCtx
*ictx
;
1316 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1318 MockReplayImageCtx
mock_image_ctx(*ictx
);
1320 MockExclusiveLock mock_exclusive_lock
;
1321 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1322 expect_accept_ops(mock_exclusive_lock
, true);
1324 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1325 expect_op_work_queue(mock_image_ctx
);
1328 Context
*on_finish
= nullptr;
1329 expect_refresh_image(mock_image_ctx
, false, 0);
1330 expect_snap_unprotect(mock_image_ctx
, &on_finish
, "snap");
1332 C_SaferCond on_start_ready
;
1333 C_SaferCond on_start_safe
;
1334 when_process(mock_journal_replay
,
1335 EventEntry
{SnapUnprotectEvent(123,
1336 cls::rbd::UserSnapshotNamespace(),
1340 ASSERT_EQ(0, on_start_ready
.wait());
1342 C_SaferCond on_finish_ready
;
1343 C_SaferCond on_finish_safe
;
1344 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1345 &on_finish_ready
, &on_finish_safe
);
1347 wait_for_op_invoked(&on_finish
, 0);
1348 ASSERT_EQ(0, on_start_safe
.wait());
1349 ASSERT_EQ(0, on_finish_ready
.wait());
1350 ASSERT_EQ(0, on_finish_safe
.wait());
1353 TEST_F(TestMockJournalReplay
, SnapUnprotectOpFinishBusy
) {
1354 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1356 librbd::ImageCtx
*ictx
;
1357 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1359 MockReplayImageCtx
mock_image_ctx(*ictx
);
1361 MockExclusiveLock mock_exclusive_lock
;
1362 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1363 expect_accept_ops(mock_exclusive_lock
, true);
1365 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1366 expect_op_work_queue(mock_image_ctx
);
1369 C_SaferCond on_start_ready
;
1370 C_SaferCond on_start_safe
;
1371 when_process(mock_journal_replay
,
1372 EventEntry
{SnapUnprotectEvent(123,
1373 cls::rbd::UserSnapshotNamespace(),
1377 ASSERT_EQ(0, on_start_ready
.wait());
1379 // aborts the snap unprotect op if image had children
1380 C_SaferCond on_finish_ready
;
1381 C_SaferCond on_finish_safe
;
1382 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, -EBUSY
)},
1383 &on_finish_ready
, &on_finish_safe
);
1385 ASSERT_EQ(0, on_start_safe
.wait());
1386 ASSERT_EQ(0, on_finish_safe
.wait());
1387 ASSERT_EQ(0, on_finish_ready
.wait());
1390 TEST_F(TestMockJournalReplay
, SnapUnprotectEventInvalid
) {
1391 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1393 librbd::ImageCtx
*ictx
;
1394 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1396 MockReplayImageCtx
mock_image_ctx(*ictx
);
1398 MockExclusiveLock mock_exclusive_lock
;
1399 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1400 expect_accept_ops(mock_exclusive_lock
, true);
1402 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1403 expect_op_work_queue(mock_image_ctx
);
1406 Context
*on_finish
= nullptr;
1407 expect_refresh_image(mock_image_ctx
, false, 0);
1408 expect_snap_unprotect(mock_image_ctx
, &on_finish
, "snap");
1410 C_SaferCond on_start_ready
;
1411 C_SaferCond on_start_safe
;
1412 when_process(mock_journal_replay
,
1413 EventEntry
{SnapUnprotectEvent(123,
1414 cls::rbd::UserSnapshotNamespace(),
1418 ASSERT_EQ(0, on_start_ready
.wait());
1420 C_SaferCond on_finish_ready
;
1421 C_SaferCond on_finish_safe
;
1422 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1423 &on_finish_ready
, &on_finish_safe
);
1425 wait_for_op_invoked(&on_finish
, -EINVAL
);
1426 ASSERT_EQ(0, on_start_safe
.wait());
1427 ASSERT_EQ(0, on_finish_ready
.wait());
1428 ASSERT_EQ(0, on_finish_safe
.wait());
1431 TEST_F(TestMockJournalReplay
, SnapRollbackEvent
) {
1432 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1434 librbd::ImageCtx
*ictx
;
1435 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1437 MockReplayImageCtx
mock_image_ctx(*ictx
);
1439 MockExclusiveLock mock_exclusive_lock
;
1440 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1441 expect_accept_ops(mock_exclusive_lock
, true);
1443 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1444 expect_op_work_queue(mock_image_ctx
);
1447 Context
*on_finish
= nullptr;
1448 expect_refresh_image(mock_image_ctx
, false, 0);
1449 expect_snap_rollback(mock_image_ctx
, &on_finish
, "snap");
1451 C_SaferCond on_start_ready
;
1452 C_SaferCond on_start_safe
;
1453 when_process(mock_journal_replay
,
1454 EventEntry
{SnapRollbackEvent(123,
1455 cls::rbd::UserSnapshotNamespace(),
1459 ASSERT_EQ(0, on_start_ready
.wait());
1461 C_SaferCond on_finish_ready
;
1462 C_SaferCond on_finish_safe
;
1463 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1464 &on_finish_ready
, &on_finish_safe
);
1466 wait_for_op_invoked(&on_finish
, 0);
1467 ASSERT_EQ(0, on_start_safe
.wait());
1468 ASSERT_EQ(0, on_finish_ready
.wait());
1469 ASSERT_EQ(0, on_finish_safe
.wait());
1472 TEST_F(TestMockJournalReplay
, RenameEvent
) {
1473 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1475 librbd::ImageCtx
*ictx
;
1476 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1478 MockReplayImageCtx
mock_image_ctx(*ictx
);
1480 MockExclusiveLock mock_exclusive_lock
;
1481 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1482 expect_accept_ops(mock_exclusive_lock
, true);
1484 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1485 expect_op_work_queue(mock_image_ctx
);
1488 Context
*on_finish
= nullptr;
1489 expect_refresh_image(mock_image_ctx
, false, 0);
1490 expect_rename(mock_image_ctx
, &on_finish
, "image");
1492 C_SaferCond on_start_ready
;
1493 C_SaferCond on_start_safe
;
1494 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
1495 &on_start_ready
, &on_start_safe
);
1496 ASSERT_EQ(0, on_start_ready
.wait());
1498 C_SaferCond on_finish_ready
;
1499 C_SaferCond on_finish_safe
;
1500 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1501 &on_finish_ready
, &on_finish_safe
);
1503 wait_for_op_invoked(&on_finish
, 0);
1504 ASSERT_EQ(0, on_start_safe
.wait());
1505 ASSERT_EQ(0, on_finish_ready
.wait());
1506 ASSERT_EQ(0, on_finish_safe
.wait());
1509 TEST_F(TestMockJournalReplay
, RenameEventExists
) {
1510 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1512 librbd::ImageCtx
*ictx
;
1513 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1515 MockReplayImageCtx
mock_image_ctx(*ictx
);
1517 MockExclusiveLock mock_exclusive_lock
;
1518 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1519 expect_accept_ops(mock_exclusive_lock
, true);
1521 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1522 expect_op_work_queue(mock_image_ctx
);
1525 Context
*on_finish
= nullptr;
1526 expect_refresh_image(mock_image_ctx
, false, 0);
1527 expect_rename(mock_image_ctx
, &on_finish
, "image");
1529 C_SaferCond on_start_ready
;
1530 C_SaferCond on_start_safe
;
1531 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
1532 &on_start_ready
, &on_start_safe
);
1533 ASSERT_EQ(0, on_start_ready
.wait());
1535 C_SaferCond on_finish_ready
;
1536 C_SaferCond on_finish_safe
;
1537 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1538 &on_finish_ready
, &on_finish_safe
);
1540 wait_for_op_invoked(&on_finish
, -EEXIST
);
1541 ASSERT_EQ(0, on_start_safe
.wait());
1542 ASSERT_EQ(0, on_finish_ready
.wait());
1543 ASSERT_EQ(0, on_finish_safe
.wait());
1546 TEST_F(TestMockJournalReplay
, ResizeEvent
) {
1547 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1549 librbd::ImageCtx
*ictx
;
1550 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1552 MockReplayImageCtx
mock_image_ctx(*ictx
);
1554 MockExclusiveLock mock_exclusive_lock
;
1555 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1556 expect_accept_ops(mock_exclusive_lock
, true);
1558 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1559 expect_op_work_queue(mock_image_ctx
);
1562 Context
*on_finish
= nullptr;
1563 expect_refresh_image(mock_image_ctx
, false, 0);
1564 expect_resize(mock_image_ctx
, &on_finish
, 234, 123);
1566 C_SaferCond on_start_ready
;
1567 C_SaferCond on_start_safe
;
1568 when_process(mock_journal_replay
, EventEntry
{ResizeEvent(123, 234)},
1569 &on_start_ready
, &on_start_safe
);
1571 C_SaferCond on_resume
;
1572 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
1573 ASSERT_EQ(0, on_start_ready
.wait());
1575 C_SaferCond on_finish_ready
;
1576 C_SaferCond on_finish_safe
;
1577 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1578 &on_finish_ready
, &on_finish_safe
);
1580 ASSERT_EQ(0, on_resume
.wait());
1581 wait_for_op_invoked(&on_finish
, 0);
1583 ASSERT_EQ(0, on_start_safe
.wait());
1584 ASSERT_EQ(0, on_finish_ready
.wait());
1585 ASSERT_EQ(0, on_finish_safe
.wait());
1588 TEST_F(TestMockJournalReplay
, FlattenEvent
) {
1589 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1591 librbd::ImageCtx
*ictx
;
1592 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1594 MockReplayImageCtx
mock_image_ctx(*ictx
);
1596 MockExclusiveLock mock_exclusive_lock
;
1597 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1598 expect_accept_ops(mock_exclusive_lock
, true);
1600 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1601 expect_op_work_queue(mock_image_ctx
);
1604 Context
*on_finish
= nullptr;
1605 expect_refresh_image(mock_image_ctx
, false, 0);
1606 expect_flatten(mock_image_ctx
, &on_finish
);
1608 C_SaferCond on_start_ready
;
1609 C_SaferCond on_start_safe
;
1610 when_process(mock_journal_replay
, EventEntry
{FlattenEvent(123)},
1611 &on_start_ready
, &on_start_safe
);
1612 ASSERT_EQ(0, on_start_ready
.wait());
1614 C_SaferCond on_finish_ready
;
1615 C_SaferCond on_finish_safe
;
1616 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1617 &on_finish_ready
, &on_finish_safe
);
1619 wait_for_op_invoked(&on_finish
, 0);
1620 ASSERT_EQ(0, on_start_safe
.wait());
1621 ASSERT_EQ(0, on_finish_ready
.wait());
1622 ASSERT_EQ(0, on_finish_safe
.wait());
1625 TEST_F(TestMockJournalReplay
, FlattenEventInvalid
) {
1626 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1628 librbd::ImageCtx
*ictx
;
1629 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1631 MockReplayImageCtx
mock_image_ctx(*ictx
);
1633 MockExclusiveLock mock_exclusive_lock
;
1634 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1635 expect_accept_ops(mock_exclusive_lock
, true);
1637 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1638 expect_op_work_queue(mock_image_ctx
);
1641 Context
*on_finish
= nullptr;
1642 expect_refresh_image(mock_image_ctx
, false, 0);
1643 expect_flatten(mock_image_ctx
, &on_finish
);
1645 C_SaferCond on_start_ready
;
1646 C_SaferCond on_start_safe
;
1647 when_process(mock_journal_replay
, EventEntry
{FlattenEvent(123)},
1648 &on_start_ready
, &on_start_safe
);
1649 ASSERT_EQ(0, on_start_ready
.wait());
1651 C_SaferCond on_finish_ready
;
1652 C_SaferCond on_finish_safe
;
1653 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1654 &on_finish_ready
, &on_finish_safe
);
1656 wait_for_op_invoked(&on_finish
, -EINVAL
);
1657 ASSERT_EQ(0, on_start_safe
.wait());
1658 ASSERT_EQ(0, on_finish_ready
.wait());
1659 ASSERT_EQ(0, on_finish_safe
.wait());
1662 TEST_F(TestMockJournalReplay
, UpdateFeaturesEvent
) {
1663 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1665 librbd::ImageCtx
*ictx
;
1666 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1668 uint64_t features
= RBD_FEATURE_OBJECT_MAP
| RBD_FEATURE_FAST_DIFF
;
1669 bool enabled
= !ictx
->test_features(features
);
1671 MockReplayImageCtx
mock_image_ctx(*ictx
);
1673 MockExclusiveLock mock_exclusive_lock
;
1674 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1675 expect_accept_ops(mock_exclusive_lock
, true);
1677 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1678 expect_op_work_queue(mock_image_ctx
);
1681 Context
*on_finish
= nullptr;
1682 expect_refresh_image(mock_image_ctx
, false, 0);
1683 expect_update_features(mock_image_ctx
, &on_finish
, features
, enabled
, 123);
1685 C_SaferCond on_start_ready
;
1686 C_SaferCond on_start_safe
;
1687 when_process(mock_journal_replay
,
1688 EventEntry
{UpdateFeaturesEvent(123, features
, enabled
)},
1689 &on_start_ready
, &on_start_safe
);
1691 C_SaferCond on_resume
;
1692 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
1693 ASSERT_EQ(0, on_start_ready
.wait());
1695 C_SaferCond on_finish_ready
;
1696 C_SaferCond on_finish_safe
;
1697 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1698 &on_finish_ready
, &on_finish_safe
);
1700 ASSERT_EQ(0, on_resume
.wait());
1701 wait_for_op_invoked(&on_finish
, 0);
1703 ASSERT_EQ(0, on_start_safe
.wait());
1704 ASSERT_EQ(0, on_finish_ready
.wait());
1705 ASSERT_EQ(0, on_finish_safe
.wait());
1708 TEST_F(TestMockJournalReplay
, MetadataSetEvent
) {
1709 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1711 librbd::ImageCtx
*ictx
;
1712 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1714 MockReplayImageCtx
mock_image_ctx(*ictx
);
1716 MockExclusiveLock mock_exclusive_lock
;
1717 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1718 expect_accept_ops(mock_exclusive_lock
, true);
1720 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1721 expect_op_work_queue(mock_image_ctx
);
1724 Context
*on_finish
= nullptr;
1725 expect_metadata_set(mock_image_ctx
, &on_finish
, "key", "value");
1726 expect_refresh_image(mock_image_ctx
, false, 0);
1728 C_SaferCond on_start_ready
;
1729 C_SaferCond on_start_safe
;
1730 when_process(mock_journal_replay
, EventEntry
{MetadataSetEvent(123, "key", "value")},
1731 &on_start_ready
, &on_start_safe
);
1732 ASSERT_EQ(0, on_start_ready
.wait());
1734 C_SaferCond on_finish_ready
;
1735 C_SaferCond on_finish_safe
;
1736 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1737 &on_finish_ready
, &on_finish_safe
);
1739 wait_for_op_invoked(&on_finish
, 0);
1740 ASSERT_EQ(0, on_start_safe
.wait());
1741 ASSERT_EQ(0, on_finish_ready
.wait());
1742 ASSERT_EQ(0, on_finish_safe
.wait());
1745 TEST_F(TestMockJournalReplay
, MetadataRemoveEvent
) {
1746 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1748 librbd::ImageCtx
*ictx
;
1749 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1751 MockReplayImageCtx
mock_image_ctx(*ictx
);
1753 MockExclusiveLock mock_exclusive_lock
;
1754 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1755 expect_accept_ops(mock_exclusive_lock
, true);
1757 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1758 expect_op_work_queue(mock_image_ctx
);
1761 Context
*on_finish
= nullptr;
1762 expect_metadata_remove(mock_image_ctx
, &on_finish
, "key");
1763 expect_refresh_image(mock_image_ctx
, false, 0);
1765 C_SaferCond on_start_ready
;
1766 C_SaferCond on_start_safe
;
1767 when_process(mock_journal_replay
, EventEntry
{MetadataRemoveEvent(123, "key")},
1768 &on_start_ready
, &on_start_safe
);
1769 ASSERT_EQ(0, on_start_ready
.wait());
1771 C_SaferCond on_finish_ready
;
1772 C_SaferCond on_finish_safe
;
1773 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1774 &on_finish_ready
, &on_finish_safe
);
1776 wait_for_op_invoked(&on_finish
, 0);
1777 ASSERT_EQ(0, on_start_safe
.wait());
1778 ASSERT_EQ(0, on_finish_ready
.wait());
1779 ASSERT_EQ(0, on_finish_safe
.wait());
1782 TEST_F(TestMockJournalReplay
, MetadataRemoveEventDNE
) {
1783 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1785 librbd::ImageCtx
*ictx
;
1786 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1788 MockReplayImageCtx
mock_image_ctx(*ictx
);
1790 MockExclusiveLock mock_exclusive_lock
;
1791 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1792 expect_accept_ops(mock_exclusive_lock
, true);
1794 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1795 expect_op_work_queue(mock_image_ctx
);
1798 Context
*on_finish
= nullptr;
1799 expect_metadata_remove(mock_image_ctx
, &on_finish
, "key");
1801 C_SaferCond on_start_ready
;
1802 C_SaferCond on_start_safe
;
1803 when_process(mock_journal_replay
, EventEntry
{MetadataRemoveEvent(123, "key")},
1804 &on_start_ready
, &on_start_safe
);
1805 ASSERT_EQ(0, on_start_ready
.wait());
1807 C_SaferCond on_finish_ready
;
1808 C_SaferCond on_finish_safe
;
1809 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1810 &on_finish_ready
, &on_finish_safe
);
1812 wait_for_op_invoked(&on_finish
, -ENOENT
);
1813 ASSERT_EQ(0, on_start_safe
.wait());
1814 ASSERT_EQ(0, on_finish_ready
.wait());
1815 ASSERT_EQ(0, on_finish_safe
.wait());
1818 TEST_F(TestMockJournalReplay
, UnknownEvent
) {
1819 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1821 librbd::ImageCtx
*ictx
;
1822 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1824 MockReplayImageCtx
mock_image_ctx(*ictx
);
1826 MockExclusiveLock mock_exclusive_lock
;
1827 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1828 expect_accept_ops(mock_exclusive_lock
, true);
1830 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1831 expect_op_work_queue(mock_image_ctx
);
1836 ENCODE_START(1, 1, bl
);
1837 ::encode(static_cast<uint32_t>(-1), bl
);
1840 bufferlist::iterator it
= bl
.begin();
1841 C_SaferCond on_ready
;
1842 C_SaferCond on_safe
;
1843 when_process(mock_journal_replay
, &it
, &on_ready
, &on_safe
);
1845 ASSERT_EQ(0, on_safe
.wait());
1846 ASSERT_EQ(0, on_ready
.wait());
1849 TEST_F(TestMockJournalReplay
, RefreshImageBeforeOpStart
) {
1850 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1852 librbd::ImageCtx
*ictx
;
1853 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1855 MockReplayImageCtx
mock_image_ctx(*ictx
);
1857 MockExclusiveLock mock_exclusive_lock
;
1858 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1859 expect_accept_ops(mock_exclusive_lock
, true);
1861 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1862 expect_op_work_queue(mock_image_ctx
);
1865 Context
*on_finish
= nullptr;
1866 expect_refresh_image(mock_image_ctx
, true, 0);
1867 expect_resize(mock_image_ctx
, &on_finish
, 234, 123);
1869 C_SaferCond on_start_ready
;
1870 C_SaferCond on_start_safe
;
1871 when_process(mock_journal_replay
, EventEntry
{ResizeEvent(123, 234)},
1872 &on_start_ready
, &on_start_safe
);
1874 C_SaferCond on_resume
;
1875 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
1876 ASSERT_EQ(0, on_start_ready
.wait());
1878 C_SaferCond on_finish_ready
;
1879 C_SaferCond on_finish_safe
;
1880 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1881 &on_finish_ready
, &on_finish_safe
);
1883 ASSERT_EQ(0, on_resume
.wait());
1884 wait_for_op_invoked(&on_finish
, 0);
1886 ASSERT_EQ(0, on_start_safe
.wait());
1887 ASSERT_EQ(0, on_finish_ready
.wait());
1888 ASSERT_EQ(0, on_finish_safe
.wait());
1891 TEST_F(TestMockJournalReplay
, FlushEventAfterShutDown
) {
1892 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1894 librbd::ImageCtx
*ictx
;
1895 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1897 MockReplayImageCtx
mock_image_ctx(*ictx
);
1899 MockExclusiveLock mock_exclusive_lock
;
1900 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1901 expect_accept_ops(mock_exclusive_lock
, true);
1903 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1904 MockIoImageRequest mock_io_image_request
;
1905 expect_op_work_queue(mock_image_ctx
);
1907 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1909 C_SaferCond on_ready
;
1910 C_SaferCond on_safe
;
1911 when_process(mock_journal_replay
, EventEntry
{AioFlushEvent()},
1912 &on_ready
, &on_safe
);
1913 ASSERT_EQ(0, on_ready
.wait());
1914 ASSERT_EQ(-ESHUTDOWN
, on_safe
.wait());
1917 TEST_F(TestMockJournalReplay
, ModifyEventAfterShutDown
) {
1918 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1920 librbd::ImageCtx
*ictx
;
1921 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1923 MockReplayImageCtx
mock_image_ctx(*ictx
);
1925 MockExclusiveLock mock_exclusive_lock
;
1926 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1927 expect_accept_ops(mock_exclusive_lock
, true);
1929 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1930 MockIoImageRequest mock_io_image_request
;
1931 expect_op_work_queue(mock_image_ctx
);
1933 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1935 C_SaferCond on_ready
;
1936 C_SaferCond on_safe
;
1937 when_process(mock_journal_replay
,
1938 EventEntry
{AioWriteEvent(123, 456, to_bl("test"))},
1939 &on_ready
, &on_safe
);
1940 ASSERT_EQ(0, on_ready
.wait());
1941 ASSERT_EQ(-ESHUTDOWN
, on_safe
.wait());
1944 TEST_F(TestMockJournalReplay
, OpEventAfterShutDown
) {
1945 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1947 librbd::ImageCtx
*ictx
;
1948 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1950 MockReplayImageCtx
mock_image_ctx(*ictx
);
1952 MockExclusiveLock mock_exclusive_lock
;
1953 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1954 expect_accept_ops(mock_exclusive_lock
, true);
1956 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1957 MockIoImageRequest mock_io_image_request
;
1958 expect_op_work_queue(mock_image_ctx
);
1960 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1962 C_SaferCond on_ready
;
1963 C_SaferCond on_safe
;
1964 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
1965 &on_ready
, &on_safe
);
1966 ASSERT_EQ(0, on_ready
.wait());
1967 ASSERT_EQ(-ESHUTDOWN
, on_safe
.wait());
1970 TEST_F(TestMockJournalReplay
, LockLostBeforeProcess
) {
1971 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1973 librbd::ImageCtx
*ictx
;
1974 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1976 MockReplayImageCtx
mock_image_ctx(*ictx
);
1978 MockExclusiveLock mock_exclusive_lock
;
1979 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1980 expect_accept_ops(mock_exclusive_lock
, false);
1982 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1983 MockIoImageRequest mock_io_image_request
;
1984 expect_op_work_queue(mock_image_ctx
);
1987 C_SaferCond on_ready
;
1988 C_SaferCond on_safe
;
1989 when_process(mock_journal_replay
, EventEntry
{AioFlushEvent()},
1990 &on_ready
, &on_safe
);
1991 ASSERT_EQ(0, on_ready
.wait());
1992 ASSERT_EQ(-ECANCELED
, on_safe
.wait());
1994 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1997 TEST_F(TestMockJournalReplay
, LockLostBeforeExecuteOp
) {
1998 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
2000 librbd::ImageCtx
*ictx
;
2001 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
2003 MockReplayImageCtx
mock_image_ctx(*ictx
);
2005 MockExclusiveLock mock_exclusive_lock
;
2006 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
2007 expect_accept_ops(mock_exclusive_lock
, false);
2009 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
2010 expect_op_work_queue(mock_image_ctx
);
2013 EXPECT_CALL(mock_exclusive_lock
, accept_ops()).WillOnce(Return(true));
2014 EXPECT_CALL(mock_exclusive_lock
, accept_ops()).WillOnce(Return(true));
2015 expect_refresh_image(mock_image_ctx
, false, 0);
2017 C_SaferCond on_start_ready
;
2018 C_SaferCond on_start_safe
;
2019 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
2020 &on_start_ready
, &on_start_safe
);
2021 ASSERT_EQ(0, on_start_ready
.wait());
2023 C_SaferCond on_finish_ready
;
2024 C_SaferCond on_finish_safe
;
2025 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
2026 &on_finish_ready
, &on_finish_safe
);
2028 ASSERT_EQ(-ECANCELED
, on_start_safe
.wait());
2029 ASSERT_EQ(0, on_finish_ready
.wait());
2030 ASSERT_EQ(-ECANCELED
, on_finish_safe
.wait());
2033 TEST_F(TestMockJournalReplay
, WritebackCacheDisabled
) {
2034 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
2036 librbd::ImageCtx
*ictx
;
2037 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
2039 MockReplayImageCtx
mock_image_ctx(*ictx
);
2041 MockExclusiveLock mock_exclusive_lock
;
2042 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
2043 expect_accept_ops(mock_exclusive_lock
, true);
2045 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
2046 MockIoImageRequest mock_io_image_request
;
2047 expect_writeback_cache_enabled(mock_image_ctx
, false);
2048 expect_op_work_queue(mock_image_ctx
);
2051 io::AioCompletion
*aio_comp
;
2052 C_SaferCond on_ready
;
2053 C_SaferCond on_safe
;
2054 expect_aio_discard(mock_io_image_request
, &aio_comp
, 123, 456, false);
2055 when_process(mock_journal_replay
,
2056 EventEntry
{AioDiscardEvent(123, 456, false)},
2057 &on_ready
, &on_safe
);
2059 when_complete(mock_image_ctx
, aio_comp
, 0);
2060 ASSERT_EQ(0, on_ready
.wait());
2061 ASSERT_EQ(0, on_safe
.wait());
2062 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
2065 } // namespace journal
2066 } // namespace librbd