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 explicit 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
, ImageArea area
,
35 bufferlist
&& bl
, int op_flags
,
36 const ZTracer::Trace
&parent_trace
) {
37 ceph_assert(s_instance
!= nullptr);
38 s_instance
->aio_write(c
, image_extents
, bl
, op_flags
);
41 MOCK_METHOD3(aio_discard
, void(AioCompletion
*c
, const Extents
& image_extents
,
42 uint32_t discard_granularity_bytes
));
43 static void aio_discard(MockReplayImageCtx
*ictx
, AioCompletion
*c
,
44 Extents
&& image_extents
, ImageArea area
,
45 uint32_t discard_granularity_bytes
,
46 const ZTracer::Trace
&parent_trace
) {
47 ceph_assert(s_instance
!= nullptr);
48 s_instance
->aio_discard(c
, image_extents
, discard_granularity_bytes
);
51 MOCK_METHOD1(aio_flush
, void(AioCompletion
*c
));
52 static void aio_flush(MockReplayImageCtx
*ictx
, AioCompletion
*c
,
53 FlushSource
, const ZTracer::Trace
&parent_trace
) {
54 ceph_assert(s_instance
!= nullptr);
55 s_instance
->aio_flush(c
);
58 MOCK_METHOD4(aio_writesame
, void(AioCompletion
*c
,
59 const Extents
& image_extents
,
62 static void aio_writesame(MockReplayImageCtx
*ictx
, AioCompletion
*c
,
63 Extents
&& image_extents
, ImageArea area
,
64 bufferlist
&& bl
, int op_flags
,
65 const ZTracer::Trace
&parent_trace
) {
66 ceph_assert(s_instance
!= nullptr);
67 s_instance
->aio_writesame(c
, image_extents
, bl
, op_flags
);
70 MOCK_METHOD6(aio_compare_and_write
, void(AioCompletion
*c
, const Extents
&image_extents
,
71 const bufferlist
&cmp_bl
, const bufferlist
&bl
,
72 uint64_t *mismatch_offset
,
74 static void aio_compare_and_write(MockReplayImageCtx
*ictx
, AioCompletion
*c
,
75 Extents
&& image_extents
, ImageArea area
,
76 bufferlist
&& cmp_bl
, bufferlist
&& bl
,
77 uint64_t* mismatch_offset
, int op_flags
,
78 const ZTracer::Trace
&parent_trace
) {
79 ceph_assert(s_instance
!= nullptr);
80 s_instance
->aio_compare_and_write(c
, image_extents
, cmp_bl
, bl
,
81 mismatch_offset
, op_flags
);
89 ImageRequest
<MockReplayImageCtx
> *ImageRequest
<MockReplayImageCtx
>::s_instance
= nullptr;
95 inline ImageCtx
*get_image_ctx(librbd::MockReplayImageCtx
*image_ctx
) {
96 return image_ctx
->image_ctx
;
101 } // namespace librbd
103 // template definitions
104 #include "librbd/journal/Replay.cc"
105 template class librbd::journal::Replay
<librbd::MockReplayImageCtx
>;
108 using ::testing::DoAll
;
109 using ::testing::InSequence
;
110 using ::testing::Return
;
111 using ::testing::SaveArg
;
112 using ::testing::StrEq
;
113 using ::testing::WithArgs
;
115 MATCHER_P(BufferlistEqual
, str
, "") {
117 return (strncmp(bl
.c_str(), str
, strlen(str
)) == 0);
120 MATCHER_P(CStrEq
, str
, "") {
121 return (strncmp(arg
, str
, strlen(str
)) == 0);
124 ACTION_P2(NotifyInvoke
, lock
, cond
) {
125 std::lock_guard locker
{*lock
};
129 ACTION_P2(CompleteAioCompletion
, r
, image_ctx
) {
130 image_ctx
->op_work_queue
->queue(new LambdaContext([this, arg0
](int r
) {
132 arg0
->init_time(image_ctx
, librbd::io::AIO_TYPE_NONE
);
133 arg0
->set_request_count(1);
134 arg0
->complete_request(r
);
141 class TestMockJournalReplay
: public TestMockFixture
{
143 typedef io::ImageRequest
<MockReplayImageCtx
> MockIoImageRequest
;
144 typedef Replay
<MockReplayImageCtx
> MockJournalReplay
;
146 TestMockJournalReplay() = default;
148 void expect_accept_ops(MockExclusiveLock
&mock_exclusive_lock
, bool accept
) {
149 EXPECT_CALL(mock_exclusive_lock
, accept_ops()).WillRepeatedly(
153 void expect_aio_discard(MockIoImageRequest
&mock_io_image_request
,
154 io::AioCompletion
**aio_comp
, uint64_t off
,
155 uint64_t len
, uint32_t discard_granularity_bytes
) {
156 EXPECT_CALL(mock_io_image_request
, aio_discard(_
, io::Extents
{{off
, len
}},
157 discard_granularity_bytes
))
158 .WillOnce(SaveArg
<0>(aio_comp
));
161 void expect_aio_flush(MockIoImageRequest
&mock_io_image_request
,
162 io::AioCompletion
**aio_comp
) {
163 EXPECT_CALL(mock_io_image_request
, aio_flush(_
))
164 .WillOnce(SaveArg
<0>(aio_comp
));
167 void expect_aio_flush(MockReplayImageCtx
&mock_image_ctx
,
168 MockIoImageRequest
&mock_io_image_request
, int r
) {
169 EXPECT_CALL(mock_io_image_request
, aio_flush(_
))
170 .WillOnce(CompleteAioCompletion(r
, mock_image_ctx
.image_ctx
));
173 void expect_aio_write(MockIoImageRequest
&mock_io_image_request
,
174 io::AioCompletion
**aio_comp
, uint64_t off
,
175 uint64_t len
, const char *data
) {
176 EXPECT_CALL(mock_io_image_request
,
177 aio_write(_
, io::Extents
{{off
, len
}}, BufferlistEqual(data
), _
))
178 .WillOnce(SaveArg
<0>(aio_comp
));
181 void expect_aio_writesame(MockIoImageRequest
&mock_io_image_request
,
182 io::AioCompletion
**aio_comp
, uint64_t off
,
183 uint64_t len
, const char *data
) {
184 EXPECT_CALL(mock_io_image_request
,
185 aio_writesame(_
, io::Extents
{{off
, len
}},
186 BufferlistEqual(data
), _
))
187 .WillOnce(SaveArg
<0>(aio_comp
));
190 void expect_aio_compare_and_write(MockIoImageRequest
&mock_io_image_request
,
191 io::AioCompletion
**aio_comp
, uint64_t off
,
192 uint64_t len
, const char *cmp_data
,
194 uint64_t *mismatch_offset
) {
195 EXPECT_CALL(mock_io_image_request
,
196 aio_compare_and_write(_
, io::Extents
{{off
, len
}},
197 BufferlistEqual(cmp_data
),
198 BufferlistEqual(data
),
200 .WillOnce(SaveArg
<0>(aio_comp
));
203 void expect_flatten(MockReplayImageCtx
&mock_image_ctx
, Context
**on_finish
) {
204 EXPECT_CALL(*mock_image_ctx
.operations
, execute_flatten(_
, _
))
205 .WillOnce(DoAll(SaveArg
<1>(on_finish
),
206 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
209 void expect_rename(MockReplayImageCtx
&mock_image_ctx
, Context
**on_finish
,
210 const char *image_name
) {
211 EXPECT_CALL(*mock_image_ctx
.operations
, execute_rename(StrEq(image_name
), _
))
212 .WillOnce(DoAll(SaveArg
<1>(on_finish
),
213 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
216 void expect_resize(MockReplayImageCtx
&mock_image_ctx
, Context
**on_finish
,
217 uint64_t size
, uint64_t op_tid
) {
218 EXPECT_CALL(*mock_image_ctx
.operations
, execute_resize(size
, _
, _
, _
, op_tid
))
219 .WillOnce(DoAll(SaveArg
<3>(on_finish
),
220 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
223 void expect_snap_create(MockReplayImageCtx
&mock_image_ctx
,
224 Context
**on_finish
, const char *snap_name
,
226 EXPECT_CALL(*mock_image_ctx
.operations
,
227 execute_snap_create(_
, StrEq(snap_name
), _
, op_tid
,
228 SNAP_CREATE_FLAG_SKIP_NOTIFY_QUIESCE
, _
))
229 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
230 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
233 void expect_snap_remove(MockReplayImageCtx
&mock_image_ctx
,
234 Context
**on_finish
, const char *snap_name
) {
235 EXPECT_CALL(*mock_image_ctx
.operations
, execute_snap_remove(_
, StrEq(snap_name
), _
))
236 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
237 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
240 void expect_snap_rename(MockReplayImageCtx
&mock_image_ctx
,
241 Context
**on_finish
, uint64_t snap_id
,
242 const char *snap_name
) {
243 EXPECT_CALL(*mock_image_ctx
.operations
, execute_snap_rename(snap_id
, StrEq(snap_name
), _
))
244 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
245 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
248 void expect_snap_protect(MockReplayImageCtx
&mock_image_ctx
,
249 Context
**on_finish
, const char *snap_name
) {
250 EXPECT_CALL(*mock_image_ctx
.operations
, execute_snap_protect(_
, StrEq(snap_name
), _
))
251 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
252 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
255 void expect_snap_unprotect(MockReplayImageCtx
&mock_image_ctx
,
256 Context
**on_finish
, const char *snap_name
) {
257 EXPECT_CALL(*mock_image_ctx
.operations
, execute_snap_unprotect(_
, StrEq(snap_name
), _
))
258 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
259 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
262 void expect_snap_rollback(MockReplayImageCtx
&mock_image_ctx
,
263 Context
**on_finish
, const char *snap_name
) {
264 EXPECT_CALL(*mock_image_ctx
.operations
, execute_snap_rollback(_
, StrEq(snap_name
), _
, _
))
265 .WillOnce(DoAll(SaveArg
<3>(on_finish
),
266 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
269 void expect_update_features(MockReplayImageCtx
&mock_image_ctx
, Context
**on_finish
,
270 uint64_t features
, bool enabled
, uint64_t op_tid
) {
271 EXPECT_CALL(*mock_image_ctx
.operations
, execute_update_features(features
, enabled
, _
, op_tid
))
272 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
273 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
276 void expect_metadata_set(MockReplayImageCtx
&mock_image_ctx
,
277 Context
**on_finish
, const char *key
,
279 EXPECT_CALL(*mock_image_ctx
.operations
, execute_metadata_set(StrEq(key
),
281 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
282 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
285 void expect_metadata_remove(MockReplayImageCtx
&mock_image_ctx
,
286 Context
**on_finish
, const char *key
) {
287 EXPECT_CALL(*mock_image_ctx
.operations
, execute_metadata_remove(StrEq(key
), _
))
288 .WillOnce(DoAll(SaveArg
<1>(on_finish
),
289 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
292 void expect_refresh_image(MockReplayImageCtx
&mock_image_ctx
, bool required
,
294 EXPECT_CALL(*mock_image_ctx
.state
, is_refresh_required())
295 .WillOnce(Return(required
));
297 EXPECT_CALL(*mock_image_ctx
.state
, refresh(_
))
298 .WillOnce(CompleteContext(r
, mock_image_ctx
.image_ctx
->op_work_queue
));
302 void when_process(MockJournalReplay
&mock_journal_replay
,
303 EventEntry
&&event_entry
, Context
*on_ready
,
306 encode(event_entry
, bl
);
308 auto it
= bl
.cbegin();
309 when_process(mock_journal_replay
, &it
, on_ready
, on_safe
);
312 void when_process(MockJournalReplay
&mock_journal_replay
,
313 bufferlist::const_iterator
*it
, Context
*on_ready
,
315 EventEntry event_entry
;
316 int r
= mock_journal_replay
.decode(it
, &event_entry
);
319 mock_journal_replay
.process(event_entry
, on_ready
, on_safe
);
322 void when_complete(MockReplayImageCtx
&mock_image_ctx
,
323 io::AioCompletion
*aio_comp
, int r
) {
325 aio_comp
->init_time(mock_image_ctx
.image_ctx
, librbd::io::AIO_TYPE_NONE
);
326 aio_comp
->set_request_count(1);
327 aio_comp
->complete_request(r
);
330 int when_flush(MockJournalReplay
&mock_journal_replay
) {
332 mock_journal_replay
.flush(&ctx
);
336 int when_shut_down(MockJournalReplay
&mock_journal_replay
, bool cancel_ops
) {
338 mock_journal_replay
.shut_down(cancel_ops
, &ctx
);
342 void when_replay_op_ready(MockJournalReplay
&mock_journal_replay
,
343 uint64_t op_tid
, Context
*on_resume
) {
344 mock_journal_replay
.replay_op_ready(op_tid
, on_resume
);
347 void wait_for_op_invoked(Context
**on_finish
, int r
) {
349 std::unique_lock locker
{m_invoke_lock
};
350 m_invoke_cond
.wait(locker
, [on_finish
] { return *on_finish
!= nullptr; });
352 (*on_finish
)->complete(r
);
355 bufferlist
to_bl(const std::string
&str
) {
361 ceph::mutex m_invoke_lock
= ceph::make_mutex("m_invoke_lock");
362 ceph::condition_variable m_invoke_cond
;
365 TEST_F(TestMockJournalReplay
, AioDiscard
) {
366 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
368 librbd::ImageCtx
*ictx
;
369 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
371 MockReplayImageCtx
mock_image_ctx(*ictx
);
373 MockExclusiveLock mock_exclusive_lock
;
374 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
375 expect_accept_ops(mock_exclusive_lock
, true);
377 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
378 MockIoImageRequest mock_io_image_request
;
379 expect_op_work_queue(mock_image_ctx
);
382 io::AioCompletion
*aio_comp
;
383 C_SaferCond on_ready
;
385 expect_aio_discard(mock_io_image_request
, &aio_comp
, 123, 456,
386 ictx
->discard_granularity_bytes
);
387 when_process(mock_journal_replay
,
388 EventEntry
{AioDiscardEvent(123, 456,
389 ictx
->discard_granularity_bytes
)},
390 &on_ready
, &on_safe
);
392 when_complete(mock_image_ctx
, aio_comp
, 0);
393 ASSERT_EQ(0, on_ready
.wait());
395 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
396 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
397 ASSERT_EQ(0, on_safe
.wait());
400 TEST_F(TestMockJournalReplay
, AioWrite
) {
401 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
403 librbd::ImageCtx
*ictx
;
404 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
406 MockReplayImageCtx
mock_image_ctx(*ictx
);
408 MockExclusiveLock mock_exclusive_lock
;
409 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
410 expect_accept_ops(mock_exclusive_lock
, true);
412 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
413 MockIoImageRequest mock_io_image_request
;
414 expect_op_work_queue(mock_image_ctx
);
417 io::AioCompletion
*aio_comp
;
418 C_SaferCond on_ready
;
420 expect_aio_write(mock_io_image_request
, &aio_comp
, 123, 456, "test");
421 when_process(mock_journal_replay
,
422 EventEntry
{AioWriteEvent(123, 456, to_bl("test"))},
423 &on_ready
, &on_safe
);
425 when_complete(mock_image_ctx
, aio_comp
, 0);
426 ASSERT_EQ(0, on_ready
.wait());
428 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
429 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
430 ASSERT_EQ(0, on_safe
.wait());
433 TEST_F(TestMockJournalReplay
, AioFlush
) {
434 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
436 librbd::ImageCtx
*ictx
;
437 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
439 MockReplayImageCtx
mock_image_ctx(*ictx
);
441 MockExclusiveLock mock_exclusive_lock
;
442 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
443 expect_accept_ops(mock_exclusive_lock
, true);
445 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
446 MockIoImageRequest mock_io_image_request
;
447 expect_op_work_queue(mock_image_ctx
);
450 io::AioCompletion
*aio_comp
;
451 C_SaferCond on_ready
;
453 expect_aio_flush(mock_io_image_request
, &aio_comp
);
454 when_process(mock_journal_replay
, EventEntry
{AioFlushEvent()},
455 &on_ready
, &on_safe
);
457 when_complete(mock_image_ctx
, aio_comp
, 0);
458 ASSERT_EQ(0, on_safe
.wait());
460 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
461 ASSERT_EQ(0, on_ready
.wait());
464 TEST_F(TestMockJournalReplay
, AioWriteSame
) {
465 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
467 librbd::ImageCtx
*ictx
;
468 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
470 MockReplayImageCtx
mock_image_ctx(*ictx
);
472 MockExclusiveLock mock_exclusive_lock
;
473 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
474 expect_accept_ops(mock_exclusive_lock
, true);
476 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
477 MockIoImageRequest mock_io_image_request
;
478 expect_op_work_queue(mock_image_ctx
);
481 io::AioCompletion
*aio_comp
;
482 C_SaferCond on_ready
;
484 expect_aio_writesame(mock_io_image_request
, &aio_comp
, 123, 456, "333");
485 when_process(mock_journal_replay
,
486 EventEntry
{AioWriteSameEvent(123, 456, to_bl("333"))},
487 &on_ready
, &on_safe
);
489 when_complete(mock_image_ctx
, aio_comp
, 0);
490 ASSERT_EQ(0, on_ready
.wait());
492 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
493 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
494 ASSERT_EQ(0, on_safe
.wait());
498 TEST_F(TestMockJournalReplay
, AioCompareAndWrite
) {
499 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
501 librbd::ImageCtx
*ictx
;
502 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
504 MockReplayImageCtx
mock_image_ctx(*ictx
);
506 MockExclusiveLock mock_exclusive_lock
;
507 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
508 expect_accept_ops(mock_exclusive_lock
, true);
510 MockJournalReplay
mock_write_journal_replay(mock_image_ctx
);
511 MockJournalReplay
mock_compare_and_write_journal_replay(mock_image_ctx
);
512 MockJournalReplay
mock_mis_compare_and_write_journal_replay(mock_image_ctx
);
513 MockIoImageRequest mock_io_image_request
;
514 expect_op_work_queue(mock_image_ctx
);
517 io::AioCompletion
*aio_comp
;
518 C_SaferCond on_ready
;
520 expect_aio_write(mock_io_image_request
, &aio_comp
, 512, 512, "test");
521 when_process(mock_write_journal_replay
,
522 EventEntry
{AioWriteEvent(512, 512, to_bl("test"))},
523 &on_ready
, &on_safe
);
525 when_complete(mock_image_ctx
, aio_comp
, 0);
526 ASSERT_EQ(0, on_ready
.wait());
528 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
529 ASSERT_EQ(0, when_shut_down(mock_write_journal_replay
, false));
530 ASSERT_EQ(0, on_safe
.wait());
532 expect_aio_compare_and_write(mock_io_image_request
, &aio_comp
,
533 512, 512, "test", "test", nullptr);
534 when_process(mock_compare_and_write_journal_replay
,
535 EventEntry
{AioCompareAndWriteEvent(512, 512, to_bl("test"),
536 to_bl("test"))}, &on_ready
, &on_safe
);
538 when_complete(mock_image_ctx
, aio_comp
, 0);
539 ASSERT_EQ(0, on_ready
.wait());
541 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
542 ASSERT_EQ(0, when_shut_down(mock_compare_and_write_journal_replay
, false));
543 ASSERT_EQ(0, on_safe
.wait());
545 expect_aio_compare_and_write(mock_io_image_request
, &aio_comp
,
546 512, 512, "111", "test", nullptr);
547 when_process(mock_mis_compare_and_write_journal_replay
,
548 EventEntry
{AioCompareAndWriteEvent(512, 512, to_bl("111"),
549 to_bl("test"))}, &on_ready
, &on_safe
);
551 when_complete(mock_image_ctx
, aio_comp
, 0);
552 ASSERT_EQ(0, on_ready
.wait());
554 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
555 ASSERT_EQ(0, when_shut_down(mock_mis_compare_and_write_journal_replay
, false));
556 ASSERT_EQ(0, on_safe
.wait());
560 TEST_F(TestMockJournalReplay
, IOError
) {
561 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
563 librbd::ImageCtx
*ictx
;
564 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
566 MockReplayImageCtx
mock_image_ctx(*ictx
);
568 MockExclusiveLock mock_exclusive_lock
;
569 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
570 expect_accept_ops(mock_exclusive_lock
, true);
572 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
573 MockIoImageRequest mock_io_image_request
;
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,
581 ictx
->discard_granularity_bytes
);
582 when_process(mock_journal_replay
,
583 EventEntry
{AioDiscardEvent(123, 456,
584 ictx
->discard_granularity_bytes
)},
585 &on_ready
, &on_safe
);
587 when_complete(mock_image_ctx
, aio_comp
, -EINVAL
);
588 ASSERT_EQ(-EINVAL
, on_safe
.wait());
590 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
591 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
592 ASSERT_EQ(0, on_ready
.wait());
595 TEST_F(TestMockJournalReplay
, SoftFlushIO
) {
596 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
598 librbd::ImageCtx
*ictx
;
599 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
601 MockReplayImageCtx
mock_image_ctx(*ictx
);
603 MockExclusiveLock mock_exclusive_lock
;
604 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
605 expect_accept_ops(mock_exclusive_lock
, true);
607 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
608 MockIoImageRequest mock_io_image_request
;
609 expect_op_work_queue(mock_image_ctx
);
612 const size_t io_count
= 32;
613 C_SaferCond on_safes
[io_count
];
614 for (size_t i
= 0; i
< io_count
; ++i
) {
615 io::AioCompletion
*aio_comp
;
616 io::AioCompletion
*flush_comp
= nullptr;
617 C_SaferCond on_ready
;
618 expect_aio_discard(mock_io_image_request
, &aio_comp
, 123, 456,
619 ictx
->discard_granularity_bytes
);
620 if (i
== io_count
- 1) {
621 expect_aio_flush(mock_io_image_request
, &flush_comp
);
623 when_process(mock_journal_replay
,
624 EventEntry
{AioDiscardEvent(123, 456,
625 ictx
->discard_granularity_bytes
)},
626 &on_ready
, &on_safes
[i
]);
627 when_complete(mock_image_ctx
, aio_comp
, 0);
628 ASSERT_EQ(0, on_ready
.wait());
630 if (flush_comp
!= nullptr) {
631 when_complete(mock_image_ctx
, flush_comp
, 0);
634 for (auto &on_safe
: on_safes
) {
635 ASSERT_EQ(0, on_safe
.wait());
638 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
641 TEST_F(TestMockJournalReplay
, PauseIO
) {
642 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
644 librbd::ImageCtx
*ictx
;
645 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
647 MockReplayImageCtx
mock_image_ctx(*ictx
);
649 MockExclusiveLock mock_exclusive_lock
;
650 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
651 expect_accept_ops(mock_exclusive_lock
, true);
653 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
654 MockIoImageRequest mock_io_image_request
;
655 expect_op_work_queue(mock_image_ctx
);
658 const size_t io_count
= 64;
659 std::list
<io::AioCompletion
*> flush_comps
;
660 C_SaferCond on_safes
[io_count
];
661 for (size_t i
= 0; i
< io_count
; ++i
) {
662 io::AioCompletion
*aio_comp
;
663 C_SaferCond on_ready
;
664 expect_aio_write(mock_io_image_request
, &aio_comp
, 123, 456, "test");
665 if ((i
+ 1) % 32 == 0) {
666 flush_comps
.push_back(nullptr);
667 expect_aio_flush(mock_io_image_request
, &flush_comps
.back());
669 when_process(mock_journal_replay
,
670 EventEntry
{AioWriteEvent(123, 456, to_bl("test"))},
671 &on_ready
, &on_safes
[i
]);
672 when_complete(mock_image_ctx
, aio_comp
, 0);
673 if (i
< io_count
- 1) {
674 ASSERT_EQ(0, on_ready
.wait());
676 for (auto flush_comp
: flush_comps
) {
677 when_complete(mock_image_ctx
, flush_comp
, 0);
679 ASSERT_EQ(0, on_ready
.wait());
682 for (auto &on_safe
: on_safes
) {
683 ASSERT_EQ(0, on_safe
.wait());
686 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
689 TEST_F(TestMockJournalReplay
, Flush
) {
690 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
692 librbd::ImageCtx
*ictx
;
693 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
695 MockReplayImageCtx
mock_image_ctx(*ictx
);
697 MockExclusiveLock mock_exclusive_lock
;
698 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
699 expect_accept_ops(mock_exclusive_lock
, true);
701 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
702 MockIoImageRequest mock_io_image_request
;
703 expect_op_work_queue(mock_image_ctx
);
706 io::AioCompletion
*aio_comp
= nullptr;
707 C_SaferCond on_ready
;
709 expect_aio_discard(mock_io_image_request
, &aio_comp
, 123, 456,
710 ictx
->discard_granularity_bytes
);
711 when_process(mock_journal_replay
,
712 EventEntry
{AioDiscardEvent(123, 456,
713 ictx
->discard_granularity_bytes
)},
714 &on_ready
, &on_safe
);
716 when_complete(mock_image_ctx
, aio_comp
, 0);
717 ASSERT_EQ(0, on_ready
.wait());
719 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
720 ASSERT_EQ(0, when_flush(mock_journal_replay
));
721 ASSERT_EQ(0, on_safe
.wait());
724 TEST_F(TestMockJournalReplay
, OpFinishError
) {
725 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
727 librbd::ImageCtx
*ictx
;
728 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
730 MockReplayImageCtx
mock_image_ctx(*ictx
);
732 MockExclusiveLock mock_exclusive_lock
;
733 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
734 expect_accept_ops(mock_exclusive_lock
, true);
736 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
737 expect_op_work_queue(mock_image_ctx
);
740 C_SaferCond on_start_ready
;
741 C_SaferCond on_start_safe
;
742 when_process(mock_journal_replay
,
743 EventEntry
{SnapRemoveEvent(123,
744 cls::rbd::UserSnapshotNamespace(),
748 ASSERT_EQ(0, on_start_ready
.wait());
750 C_SaferCond on_finish_ready
;
751 C_SaferCond on_finish_safe
;
752 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, -EIO
)},
753 &on_finish_ready
, &on_finish_safe
);
755 ASSERT_EQ(-EIO
, on_start_safe
.wait());
756 ASSERT_EQ(-EIO
, on_finish_safe
.wait());
757 ASSERT_EQ(0, on_finish_ready
.wait());
760 TEST_F(TestMockJournalReplay
, BlockedOpFinishError
) {
761 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
763 librbd::ImageCtx
*ictx
;
764 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
766 MockReplayImageCtx
mock_image_ctx(*ictx
);
768 MockExclusiveLock mock_exclusive_lock
;
769 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
770 expect_accept_ops(mock_exclusive_lock
, true);
772 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
773 expect_op_work_queue(mock_image_ctx
);
776 Context
*on_finish
= nullptr;
777 expect_refresh_image(mock_image_ctx
, false, 0);
778 expect_snap_create(mock_image_ctx
, &on_finish
, "snap", 123);
780 C_SaferCond on_start_ready
;
781 C_SaferCond on_start_safe
;
782 when_process(mock_journal_replay
,
783 EventEntry
{SnapCreateEvent(123,
784 cls::rbd::UserSnapshotNamespace(),
789 C_SaferCond on_resume
;
790 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
791 ASSERT_EQ(0, on_start_ready
.wait());
793 C_SaferCond on_finish_ready
;
794 C_SaferCond on_finish_safe
;
795 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, -EBADMSG
)},
796 &on_finish_ready
, &on_finish_safe
);
798 ASSERT_EQ(-EBADMSG
, on_resume
.wait());
799 wait_for_op_invoked(&on_finish
, -ESTALE
);
801 ASSERT_EQ(-ESTALE
, on_start_safe
.wait());
802 ASSERT_EQ(-ESTALE
, on_finish_safe
.wait());
803 ASSERT_EQ(0, on_finish_ready
.wait());
806 TEST_F(TestMockJournalReplay
, MissingOpFinishEvent
) {
807 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
809 librbd::ImageCtx
*ictx
;
810 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
812 MockReplayImageCtx
mock_image_ctx(*ictx
);
814 MockExclusiveLock mock_exclusive_lock
;
815 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
816 expect_accept_ops(mock_exclusive_lock
, true);
818 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
819 expect_op_work_queue(mock_image_ctx
);
821 EXPECT_CALL(*mock_image_ctx
.state
, is_refresh_required())
822 .WillRepeatedly(Return(false));
825 Context
*on_snap_create_finish
= nullptr;
826 expect_snap_create(mock_image_ctx
, &on_snap_create_finish
, "snap", 123);
828 Context
*on_snap_remove_finish
= nullptr;
829 expect_snap_remove(mock_image_ctx
, &on_snap_remove_finish
, "snap");
831 C_SaferCond on_snap_remove_ready
;
832 C_SaferCond on_snap_remove_safe
;
833 when_process(mock_journal_replay
,
834 EventEntry
{SnapRemoveEvent(122,
835 cls::rbd::UserSnapshotNamespace(),
837 &on_snap_remove_ready
,
838 &on_snap_remove_safe
);
839 ictx
->op_work_queue
->drain();
840 ASSERT_EQ(0, on_snap_remove_ready
.wait());
842 C_SaferCond on_snap_create_ready
;
843 C_SaferCond on_snap_create_safe
;
844 when_process(mock_journal_replay
,
845 EventEntry
{SnapCreateEvent(123,
846 cls::rbd::UserSnapshotNamespace(),
848 &on_snap_create_ready
,
849 &on_snap_create_safe
);
850 ictx
->op_work_queue
->drain();
852 C_SaferCond on_shut_down
;
853 mock_journal_replay
.shut_down(false, &on_shut_down
);
855 wait_for_op_invoked(&on_snap_remove_finish
, 0);
856 ASSERT_EQ(0, on_snap_remove_safe
.wait());
858 C_SaferCond on_snap_create_resume
;
859 when_replay_op_ready(mock_journal_replay
, 123, &on_snap_create_resume
);
860 ASSERT_EQ(0, on_snap_create_resume
.wait());
862 wait_for_op_invoked(&on_snap_create_finish
, 0);
863 ASSERT_EQ(0, on_snap_create_ready
.wait());
864 ASSERT_EQ(0, on_snap_create_safe
.wait());
866 ASSERT_EQ(0, on_shut_down
.wait());
869 TEST_F(TestMockJournalReplay
, MissingOpFinishEventCancelOps
) {
870 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
872 librbd::ImageCtx
*ictx
;
873 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
875 MockReplayImageCtx
mock_image_ctx(*ictx
);
877 MockExclusiveLock mock_exclusive_lock
;
878 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
879 expect_accept_ops(mock_exclusive_lock
, true);
881 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
882 expect_op_work_queue(mock_image_ctx
);
885 Context
*on_snap_create_finish
= nullptr;
886 expect_refresh_image(mock_image_ctx
, false, 0);
887 expect_snap_create(mock_image_ctx
, &on_snap_create_finish
, "snap", 123);
889 C_SaferCond on_snap_remove_ready
;
890 C_SaferCond on_snap_remove_safe
;
891 when_process(mock_journal_replay
,
892 EventEntry
{SnapRemoveEvent(122,
893 cls::rbd::UserSnapshotNamespace(),
895 &on_snap_remove_ready
,
896 &on_snap_remove_safe
);
897 ictx
->op_work_queue
->drain();
898 ASSERT_EQ(0, on_snap_remove_ready
.wait());
900 C_SaferCond on_snap_create_ready
;
901 C_SaferCond on_snap_create_safe
;
902 when_process(mock_journal_replay
,
903 EventEntry
{SnapCreateEvent(123,
904 cls::rbd::UserSnapshotNamespace(),
906 &on_snap_create_ready
,
907 &on_snap_create_safe
);
908 ictx
->op_work_queue
->drain();
910 C_SaferCond on_resume
;
911 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
912 ASSERT_EQ(0, on_snap_create_ready
.wait());
914 C_SaferCond on_shut_down
;
915 mock_journal_replay
.shut_down(true, &on_shut_down
);
917 ASSERT_EQ(-ERESTART
, on_resume
.wait());
918 on_snap_create_finish
->complete(-ERESTART
);
919 ASSERT_EQ(-ERESTART
, on_snap_create_safe
.wait());
921 ASSERT_EQ(-ERESTART
, on_snap_remove_safe
.wait());
922 ASSERT_EQ(0, on_shut_down
.wait());
925 TEST_F(TestMockJournalReplay
, UnknownOpFinishEvent
) {
926 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
928 librbd::ImageCtx
*ictx
;
929 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
931 MockReplayImageCtx
mock_image_ctx(*ictx
);
933 MockExclusiveLock mock_exclusive_lock
;
934 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
935 expect_accept_ops(mock_exclusive_lock
, true);
937 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
938 expect_op_work_queue(mock_image_ctx
);
941 C_SaferCond on_ready
;
943 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
944 &on_ready
, &on_safe
);
946 ASSERT_EQ(0, on_safe
.wait());
947 ASSERT_EQ(0, on_ready
.wait());
950 TEST_F(TestMockJournalReplay
, OpEventError
) {
951 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
953 librbd::ImageCtx
*ictx
;
954 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
956 MockReplayImageCtx
mock_image_ctx(*ictx
);
958 MockExclusiveLock mock_exclusive_lock
;
959 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
960 expect_accept_ops(mock_exclusive_lock
, true);
962 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
963 expect_op_work_queue(mock_image_ctx
);
966 Context
*on_finish
= nullptr;
967 expect_refresh_image(mock_image_ctx
, false, 0);
968 expect_snap_remove(mock_image_ctx
, &on_finish
, "snap");
970 C_SaferCond on_start_ready
;
971 C_SaferCond on_start_safe
;
972 when_process(mock_journal_replay
,
973 EventEntry
{SnapRemoveEvent(123,
974 cls::rbd::UserSnapshotNamespace(),
978 ASSERT_EQ(0, on_start_ready
.wait());
980 C_SaferCond on_finish_ready
;
981 C_SaferCond on_finish_safe
;
982 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
983 &on_finish_ready
, &on_finish_safe
);
985 wait_for_op_invoked(&on_finish
, -EINVAL
);
986 ASSERT_EQ(-EINVAL
, on_start_safe
.wait());
987 ASSERT_EQ(0, on_finish_ready
.wait());
988 ASSERT_EQ(-EINVAL
, on_finish_safe
.wait());
991 TEST_F(TestMockJournalReplay
, SnapCreateEvent
) {
992 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
994 librbd::ImageCtx
*ictx
;
995 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
997 MockReplayImageCtx
mock_image_ctx(*ictx
);
999 MockExclusiveLock mock_exclusive_lock
;
1000 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1001 expect_accept_ops(mock_exclusive_lock
, true);
1003 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1004 expect_op_work_queue(mock_image_ctx
);
1007 Context
*on_finish
= nullptr;
1008 expect_refresh_image(mock_image_ctx
, false, 0);
1009 expect_snap_create(mock_image_ctx
, &on_finish
, "snap", 123);
1011 C_SaferCond on_start_ready
;
1012 C_SaferCond on_start_safe
;
1013 when_process(mock_journal_replay
,
1014 EventEntry
{SnapCreateEvent(123,
1015 cls::rbd::UserSnapshotNamespace(),
1020 C_SaferCond on_resume
;
1021 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
1022 ASSERT_EQ(0, on_start_ready
.wait());
1024 C_SaferCond on_finish_ready
;
1025 C_SaferCond on_finish_safe
;
1026 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1027 &on_finish_ready
, &on_finish_safe
);
1029 ASSERT_EQ(0, on_resume
.wait());
1030 wait_for_op_invoked(&on_finish
, 0);
1032 ASSERT_EQ(0, on_start_safe
.wait());
1033 ASSERT_EQ(0, on_finish_ready
.wait());
1034 ASSERT_EQ(0, on_finish_safe
.wait());
1037 TEST_F(TestMockJournalReplay
, SnapCreateEventExists
) {
1038 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1040 librbd::ImageCtx
*ictx
;
1041 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1043 MockReplayImageCtx
mock_image_ctx(*ictx
);
1045 MockExclusiveLock mock_exclusive_lock
;
1046 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1047 expect_accept_ops(mock_exclusive_lock
, true);
1049 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1050 expect_op_work_queue(mock_image_ctx
);
1053 Context
*on_finish
= nullptr;
1054 expect_refresh_image(mock_image_ctx
, false, 0);
1055 expect_snap_create(mock_image_ctx
, &on_finish
, "snap", 123);
1057 C_SaferCond on_start_ready
;
1058 C_SaferCond on_start_safe
;
1059 when_process(mock_journal_replay
,
1060 EventEntry
{SnapCreateEvent(123,
1061 cls::rbd::UserSnapshotNamespace(),
1066 wait_for_op_invoked(&on_finish
, -EEXIST
);
1067 ASSERT_EQ(0, on_start_ready
.wait());
1069 C_SaferCond on_finish_ready
;
1070 C_SaferCond on_finish_safe
;
1071 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1072 &on_finish_ready
, &on_finish_safe
);
1074 ASSERT_EQ(0, on_start_safe
.wait());
1075 ASSERT_EQ(0, on_finish_ready
.wait());
1076 ASSERT_EQ(0, on_finish_safe
.wait());
1079 TEST_F(TestMockJournalReplay
, SnapRemoveEvent
) {
1080 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1082 librbd::ImageCtx
*ictx
;
1083 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1085 MockReplayImageCtx
mock_image_ctx(*ictx
);
1087 MockExclusiveLock mock_exclusive_lock
;
1088 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1089 expect_accept_ops(mock_exclusive_lock
, true);
1091 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1092 expect_op_work_queue(mock_image_ctx
);
1095 Context
*on_finish
= nullptr;
1096 expect_refresh_image(mock_image_ctx
, false, 0);
1097 expect_snap_remove(mock_image_ctx
, &on_finish
, "snap");
1099 C_SaferCond on_start_ready
;
1100 C_SaferCond on_start_safe
;
1101 when_process(mock_journal_replay
,
1102 EventEntry
{SnapRemoveEvent(123,
1103 cls::rbd::UserSnapshotNamespace(),
1107 ASSERT_EQ(0, on_start_ready
.wait());
1109 C_SaferCond on_finish_ready
;
1110 C_SaferCond on_finish_safe
;
1111 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1112 &on_finish_ready
, &on_finish_safe
);
1114 wait_for_op_invoked(&on_finish
, 0);
1115 ASSERT_EQ(0, on_start_safe
.wait());
1116 ASSERT_EQ(0, on_finish_ready
.wait());
1117 ASSERT_EQ(0, on_finish_safe
.wait());
1120 TEST_F(TestMockJournalReplay
, SnapRemoveEventDNE
) {
1121 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1123 librbd::ImageCtx
*ictx
;
1124 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1126 MockReplayImageCtx
mock_image_ctx(*ictx
);
1128 MockExclusiveLock mock_exclusive_lock
;
1129 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1130 expect_accept_ops(mock_exclusive_lock
, true);
1132 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1133 expect_op_work_queue(mock_image_ctx
);
1136 Context
*on_finish
= nullptr;
1137 expect_refresh_image(mock_image_ctx
, false, 0);
1138 expect_snap_remove(mock_image_ctx
, &on_finish
, "snap");
1140 C_SaferCond on_start_ready
;
1141 C_SaferCond on_start_safe
;
1142 when_process(mock_journal_replay
,
1143 EventEntry
{SnapRemoveEvent(123,
1144 cls::rbd::UserSnapshotNamespace(),
1148 ASSERT_EQ(0, on_start_ready
.wait());
1150 C_SaferCond on_finish_ready
;
1151 C_SaferCond on_finish_safe
;
1152 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1153 &on_finish_ready
, &on_finish_safe
);
1155 wait_for_op_invoked(&on_finish
, -ENOENT
);
1156 ASSERT_EQ(0, on_start_safe
.wait());
1157 ASSERT_EQ(0, on_finish_ready
.wait());
1158 ASSERT_EQ(0, on_finish_safe
.wait());
1161 TEST_F(TestMockJournalReplay
, SnapRenameEvent
) {
1162 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1164 librbd::ImageCtx
*ictx
;
1165 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1167 MockReplayImageCtx
mock_image_ctx(*ictx
);
1169 MockExclusiveLock mock_exclusive_lock
;
1170 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1171 expect_accept_ops(mock_exclusive_lock
, true);
1173 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1174 expect_op_work_queue(mock_image_ctx
);
1177 Context
*on_finish
= nullptr;
1178 expect_refresh_image(mock_image_ctx
, false, 0);
1179 expect_snap_rename(mock_image_ctx
, &on_finish
, 234, "snap");
1181 C_SaferCond on_start_ready
;
1182 C_SaferCond on_start_safe
;
1183 when_process(mock_journal_replay
,
1184 EventEntry
{SnapRenameEvent(123, 234, "snap1", "snap")},
1185 &on_start_ready
, &on_start_safe
);
1186 ASSERT_EQ(0, on_start_ready
.wait());
1188 C_SaferCond on_finish_ready
;
1189 C_SaferCond on_finish_safe
;
1190 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1191 &on_finish_ready
, &on_finish_safe
);
1193 wait_for_op_invoked(&on_finish
, 0);
1194 ASSERT_EQ(0, on_start_safe
.wait());
1195 ASSERT_EQ(0, on_finish_ready
.wait());
1196 ASSERT_EQ(0, on_finish_safe
.wait());
1199 TEST_F(TestMockJournalReplay
, SnapRenameEventExists
) {
1200 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1202 librbd::ImageCtx
*ictx
;
1203 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1205 MockReplayImageCtx
mock_image_ctx(*ictx
);
1207 MockExclusiveLock mock_exclusive_lock
;
1208 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1209 expect_accept_ops(mock_exclusive_lock
, true);
1211 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1212 expect_op_work_queue(mock_image_ctx
);
1215 Context
*on_finish
= nullptr;
1216 expect_refresh_image(mock_image_ctx
, false, 0);
1217 expect_snap_rename(mock_image_ctx
, &on_finish
, 234, "snap");
1219 C_SaferCond on_start_ready
;
1220 C_SaferCond on_start_safe
;
1221 when_process(mock_journal_replay
,
1222 EventEntry
{SnapRenameEvent(123, 234, "snap1", "snap")},
1223 &on_start_ready
, &on_start_safe
);
1224 ASSERT_EQ(0, on_start_ready
.wait());
1226 C_SaferCond on_finish_ready
;
1227 C_SaferCond on_finish_safe
;
1228 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1229 &on_finish_ready
, &on_finish_safe
);
1231 wait_for_op_invoked(&on_finish
, -EEXIST
);
1232 ASSERT_EQ(0, on_start_safe
.wait());
1233 ASSERT_EQ(0, on_finish_ready
.wait());
1234 ASSERT_EQ(0, on_finish_safe
.wait());
1237 TEST_F(TestMockJournalReplay
, SnapProtectEvent
) {
1238 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1240 librbd::ImageCtx
*ictx
;
1241 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1243 MockReplayImageCtx
mock_image_ctx(*ictx
);
1245 MockExclusiveLock mock_exclusive_lock
;
1246 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1247 expect_accept_ops(mock_exclusive_lock
, true);
1249 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1250 expect_op_work_queue(mock_image_ctx
);
1253 Context
*on_finish
= nullptr;
1254 expect_refresh_image(mock_image_ctx
, false, 0);
1255 expect_snap_protect(mock_image_ctx
, &on_finish
, "snap");
1257 C_SaferCond on_start_ready
;
1258 C_SaferCond on_start_safe
;
1259 when_process(mock_journal_replay
,
1260 EventEntry
{SnapProtectEvent(123,
1261 cls::rbd::UserSnapshotNamespace(),
1265 ASSERT_EQ(0, on_start_ready
.wait());
1267 C_SaferCond on_finish_ready
;
1268 C_SaferCond on_finish_safe
;
1269 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1270 &on_finish_ready
, &on_finish_safe
);
1272 wait_for_op_invoked(&on_finish
, 0);
1273 ASSERT_EQ(0, on_start_safe
.wait());
1274 ASSERT_EQ(0, on_finish_ready
.wait());
1275 ASSERT_EQ(0, on_finish_safe
.wait());
1278 TEST_F(TestMockJournalReplay
, SnapProtectEventBusy
) {
1279 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1281 librbd::ImageCtx
*ictx
;
1282 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1284 MockReplayImageCtx
mock_image_ctx(*ictx
);
1286 MockExclusiveLock mock_exclusive_lock
;
1287 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1288 expect_accept_ops(mock_exclusive_lock
, true);
1290 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1291 expect_op_work_queue(mock_image_ctx
);
1294 Context
*on_finish
= nullptr;
1295 expect_refresh_image(mock_image_ctx
, false, 0);
1296 expect_snap_protect(mock_image_ctx
, &on_finish
, "snap");
1298 C_SaferCond on_start_ready
;
1299 C_SaferCond on_start_safe
;
1300 when_process(mock_journal_replay
,
1301 EventEntry
{SnapProtectEvent(123,
1302 cls::rbd::UserSnapshotNamespace(),
1306 ASSERT_EQ(0, on_start_ready
.wait());
1308 C_SaferCond on_finish_ready
;
1309 C_SaferCond on_finish_safe
;
1310 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1311 &on_finish_ready
, &on_finish_safe
);
1313 wait_for_op_invoked(&on_finish
, -EBUSY
);
1314 ASSERT_EQ(0, on_start_safe
.wait());
1315 ASSERT_EQ(0, on_finish_ready
.wait());
1316 ASSERT_EQ(0, on_finish_safe
.wait());
1319 TEST_F(TestMockJournalReplay
, SnapUnprotectEvent
) {
1320 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1322 librbd::ImageCtx
*ictx
;
1323 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1325 MockReplayImageCtx
mock_image_ctx(*ictx
);
1327 MockExclusiveLock mock_exclusive_lock
;
1328 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1329 expect_accept_ops(mock_exclusive_lock
, true);
1331 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1332 expect_op_work_queue(mock_image_ctx
);
1335 Context
*on_finish
= nullptr;
1336 expect_refresh_image(mock_image_ctx
, false, 0);
1337 expect_snap_unprotect(mock_image_ctx
, &on_finish
, "snap");
1339 C_SaferCond on_start_ready
;
1340 C_SaferCond on_start_safe
;
1341 when_process(mock_journal_replay
,
1342 EventEntry
{SnapUnprotectEvent(123,
1343 cls::rbd::UserSnapshotNamespace(),
1347 ASSERT_EQ(0, on_start_ready
.wait());
1349 C_SaferCond on_finish_ready
;
1350 C_SaferCond on_finish_safe
;
1351 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1352 &on_finish_ready
, &on_finish_safe
);
1354 wait_for_op_invoked(&on_finish
, 0);
1355 ASSERT_EQ(0, on_start_safe
.wait());
1356 ASSERT_EQ(0, on_finish_ready
.wait());
1357 ASSERT_EQ(0, on_finish_safe
.wait());
1360 TEST_F(TestMockJournalReplay
, SnapUnprotectOpFinishBusy
) {
1361 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1363 librbd::ImageCtx
*ictx
;
1364 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1366 MockReplayImageCtx
mock_image_ctx(*ictx
);
1368 MockExclusiveLock mock_exclusive_lock
;
1369 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1370 expect_accept_ops(mock_exclusive_lock
, true);
1372 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1373 expect_op_work_queue(mock_image_ctx
);
1376 C_SaferCond on_start_ready
;
1377 C_SaferCond on_start_safe
;
1378 when_process(mock_journal_replay
,
1379 EventEntry
{SnapUnprotectEvent(123,
1380 cls::rbd::UserSnapshotNamespace(),
1384 ASSERT_EQ(0, on_start_ready
.wait());
1386 // aborts the snap unprotect op if image had children
1387 C_SaferCond on_finish_ready
;
1388 C_SaferCond on_finish_safe
;
1389 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, -EBUSY
)},
1390 &on_finish_ready
, &on_finish_safe
);
1392 ASSERT_EQ(0, on_start_safe
.wait());
1393 ASSERT_EQ(0, on_finish_safe
.wait());
1394 ASSERT_EQ(0, on_finish_ready
.wait());
1397 TEST_F(TestMockJournalReplay
, SnapUnprotectEventInvalid
) {
1398 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1400 librbd::ImageCtx
*ictx
;
1401 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1403 MockReplayImageCtx
mock_image_ctx(*ictx
);
1405 MockExclusiveLock mock_exclusive_lock
;
1406 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1407 expect_accept_ops(mock_exclusive_lock
, true);
1409 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1410 expect_op_work_queue(mock_image_ctx
);
1413 Context
*on_finish
= nullptr;
1414 expect_refresh_image(mock_image_ctx
, false, 0);
1415 expect_snap_unprotect(mock_image_ctx
, &on_finish
, "snap");
1417 C_SaferCond on_start_ready
;
1418 C_SaferCond on_start_safe
;
1419 when_process(mock_journal_replay
,
1420 EventEntry
{SnapUnprotectEvent(123,
1421 cls::rbd::UserSnapshotNamespace(),
1425 ASSERT_EQ(0, on_start_ready
.wait());
1427 C_SaferCond on_finish_ready
;
1428 C_SaferCond on_finish_safe
;
1429 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1430 &on_finish_ready
, &on_finish_safe
);
1432 wait_for_op_invoked(&on_finish
, -EINVAL
);
1433 ASSERT_EQ(0, on_start_safe
.wait());
1434 ASSERT_EQ(0, on_finish_ready
.wait());
1435 ASSERT_EQ(0, on_finish_safe
.wait());
1438 TEST_F(TestMockJournalReplay
, SnapRollbackEvent
) {
1439 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1441 librbd::ImageCtx
*ictx
;
1442 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1444 MockReplayImageCtx
mock_image_ctx(*ictx
);
1446 MockExclusiveLock mock_exclusive_lock
;
1447 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1448 expect_accept_ops(mock_exclusive_lock
, true);
1450 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1451 expect_op_work_queue(mock_image_ctx
);
1454 Context
*on_finish
= nullptr;
1455 expect_refresh_image(mock_image_ctx
, false, 0);
1456 expect_snap_rollback(mock_image_ctx
, &on_finish
, "snap");
1458 C_SaferCond on_start_ready
;
1459 C_SaferCond on_start_safe
;
1460 when_process(mock_journal_replay
,
1461 EventEntry
{SnapRollbackEvent(123,
1462 cls::rbd::UserSnapshotNamespace(),
1466 ASSERT_EQ(0, on_start_ready
.wait());
1468 C_SaferCond on_finish_ready
;
1469 C_SaferCond on_finish_safe
;
1470 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1471 &on_finish_ready
, &on_finish_safe
);
1473 wait_for_op_invoked(&on_finish
, 0);
1474 ASSERT_EQ(0, on_start_safe
.wait());
1475 ASSERT_EQ(0, on_finish_ready
.wait());
1476 ASSERT_EQ(0, on_finish_safe
.wait());
1479 TEST_F(TestMockJournalReplay
, RenameEvent
) {
1480 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1482 librbd::ImageCtx
*ictx
;
1483 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1485 MockReplayImageCtx
mock_image_ctx(*ictx
);
1487 MockExclusiveLock mock_exclusive_lock
;
1488 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1489 expect_accept_ops(mock_exclusive_lock
, true);
1491 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1492 expect_op_work_queue(mock_image_ctx
);
1495 Context
*on_finish
= nullptr;
1496 expect_refresh_image(mock_image_ctx
, false, 0);
1497 expect_rename(mock_image_ctx
, &on_finish
, "image");
1499 C_SaferCond on_start_ready
;
1500 C_SaferCond on_start_safe
;
1501 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
1502 &on_start_ready
, &on_start_safe
);
1503 ASSERT_EQ(0, on_start_ready
.wait());
1505 C_SaferCond on_finish_ready
;
1506 C_SaferCond on_finish_safe
;
1507 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1508 &on_finish_ready
, &on_finish_safe
);
1510 wait_for_op_invoked(&on_finish
, 0);
1511 ASSERT_EQ(0, on_start_safe
.wait());
1512 ASSERT_EQ(0, on_finish_ready
.wait());
1513 ASSERT_EQ(0, on_finish_safe
.wait());
1516 TEST_F(TestMockJournalReplay
, RenameEventExists
) {
1517 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1519 librbd::ImageCtx
*ictx
;
1520 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1522 MockReplayImageCtx
mock_image_ctx(*ictx
);
1524 MockExclusiveLock mock_exclusive_lock
;
1525 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1526 expect_accept_ops(mock_exclusive_lock
, true);
1528 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1529 expect_op_work_queue(mock_image_ctx
);
1532 Context
*on_finish
= nullptr;
1533 expect_refresh_image(mock_image_ctx
, false, 0);
1534 expect_rename(mock_image_ctx
, &on_finish
, "image");
1536 C_SaferCond on_start_ready
;
1537 C_SaferCond on_start_safe
;
1538 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
1539 &on_start_ready
, &on_start_safe
);
1540 ASSERT_EQ(0, on_start_ready
.wait());
1542 C_SaferCond on_finish_ready
;
1543 C_SaferCond on_finish_safe
;
1544 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1545 &on_finish_ready
, &on_finish_safe
);
1547 wait_for_op_invoked(&on_finish
, -EEXIST
);
1548 ASSERT_EQ(0, on_start_safe
.wait());
1549 ASSERT_EQ(0, on_finish_ready
.wait());
1550 ASSERT_EQ(0, on_finish_safe
.wait());
1553 TEST_F(TestMockJournalReplay
, ResizeEvent
) {
1554 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1556 librbd::ImageCtx
*ictx
;
1557 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1559 MockReplayImageCtx
mock_image_ctx(*ictx
);
1561 MockExclusiveLock mock_exclusive_lock
;
1562 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1563 expect_accept_ops(mock_exclusive_lock
, true);
1565 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1566 expect_op_work_queue(mock_image_ctx
);
1569 Context
*on_finish
= nullptr;
1570 expect_refresh_image(mock_image_ctx
, false, 0);
1571 expect_resize(mock_image_ctx
, &on_finish
, 234, 123);
1573 C_SaferCond on_start_ready
;
1574 C_SaferCond on_start_safe
;
1575 when_process(mock_journal_replay
, EventEntry
{ResizeEvent(123, 234)},
1576 &on_start_ready
, &on_start_safe
);
1578 C_SaferCond on_resume
;
1579 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
1580 ASSERT_EQ(0, on_start_ready
.wait());
1582 C_SaferCond on_finish_ready
;
1583 C_SaferCond on_finish_safe
;
1584 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1585 &on_finish_ready
, &on_finish_safe
);
1587 ASSERT_EQ(0, on_resume
.wait());
1588 wait_for_op_invoked(&on_finish
, 0);
1590 ASSERT_EQ(0, on_start_safe
.wait());
1591 ASSERT_EQ(0, on_finish_ready
.wait());
1592 ASSERT_EQ(0, on_finish_safe
.wait());
1595 TEST_F(TestMockJournalReplay
, FlattenEvent
) {
1596 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1598 librbd::ImageCtx
*ictx
;
1599 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1601 MockReplayImageCtx
mock_image_ctx(*ictx
);
1603 MockExclusiveLock mock_exclusive_lock
;
1604 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1605 expect_accept_ops(mock_exclusive_lock
, true);
1607 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1608 expect_op_work_queue(mock_image_ctx
);
1611 Context
*on_finish
= nullptr;
1612 expect_refresh_image(mock_image_ctx
, false, 0);
1613 expect_flatten(mock_image_ctx
, &on_finish
);
1615 C_SaferCond on_start_ready
;
1616 C_SaferCond on_start_safe
;
1617 when_process(mock_journal_replay
, EventEntry
{FlattenEvent(123)},
1618 &on_start_ready
, &on_start_safe
);
1619 ASSERT_EQ(0, on_start_ready
.wait());
1621 C_SaferCond on_finish_ready
;
1622 C_SaferCond on_finish_safe
;
1623 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1624 &on_finish_ready
, &on_finish_safe
);
1626 wait_for_op_invoked(&on_finish
, 0);
1627 ASSERT_EQ(0, on_start_safe
.wait());
1628 ASSERT_EQ(0, on_finish_ready
.wait());
1629 ASSERT_EQ(0, on_finish_safe
.wait());
1632 TEST_F(TestMockJournalReplay
, FlattenEventInvalid
) {
1633 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1635 librbd::ImageCtx
*ictx
;
1636 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1638 MockReplayImageCtx
mock_image_ctx(*ictx
);
1640 MockExclusiveLock mock_exclusive_lock
;
1641 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1642 expect_accept_ops(mock_exclusive_lock
, true);
1644 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1645 expect_op_work_queue(mock_image_ctx
);
1648 Context
*on_finish
= nullptr;
1649 expect_refresh_image(mock_image_ctx
, false, 0);
1650 expect_flatten(mock_image_ctx
, &on_finish
);
1652 C_SaferCond on_start_ready
;
1653 C_SaferCond on_start_safe
;
1654 when_process(mock_journal_replay
, EventEntry
{FlattenEvent(123)},
1655 &on_start_ready
, &on_start_safe
);
1656 ASSERT_EQ(0, on_start_ready
.wait());
1658 C_SaferCond on_finish_ready
;
1659 C_SaferCond on_finish_safe
;
1660 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1661 &on_finish_ready
, &on_finish_safe
);
1663 wait_for_op_invoked(&on_finish
, -EINVAL
);
1664 ASSERT_EQ(0, on_start_safe
.wait());
1665 ASSERT_EQ(0, on_finish_ready
.wait());
1666 ASSERT_EQ(0, on_finish_safe
.wait());
1669 TEST_F(TestMockJournalReplay
, UpdateFeaturesEvent
) {
1670 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1672 librbd::ImageCtx
*ictx
;
1673 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1675 uint64_t features
= RBD_FEATURE_OBJECT_MAP
| RBD_FEATURE_FAST_DIFF
;
1676 bool enabled
= !ictx
->test_features(features
);
1678 MockReplayImageCtx
mock_image_ctx(*ictx
);
1680 MockExclusiveLock mock_exclusive_lock
;
1681 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1682 expect_accept_ops(mock_exclusive_lock
, true);
1684 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1685 expect_op_work_queue(mock_image_ctx
);
1688 Context
*on_finish
= nullptr;
1689 expect_refresh_image(mock_image_ctx
, false, 0);
1690 expect_update_features(mock_image_ctx
, &on_finish
, features
, enabled
, 123);
1692 C_SaferCond on_start_ready
;
1693 C_SaferCond on_start_safe
;
1694 when_process(mock_journal_replay
,
1695 EventEntry
{UpdateFeaturesEvent(123, features
, enabled
)},
1696 &on_start_ready
, &on_start_safe
);
1698 C_SaferCond on_resume
;
1699 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
1700 ASSERT_EQ(0, on_start_ready
.wait());
1702 C_SaferCond on_finish_ready
;
1703 C_SaferCond on_finish_safe
;
1704 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1705 &on_finish_ready
, &on_finish_safe
);
1707 ASSERT_EQ(0, on_resume
.wait());
1708 wait_for_op_invoked(&on_finish
, 0);
1710 ASSERT_EQ(0, on_start_safe
.wait());
1711 ASSERT_EQ(0, on_finish_ready
.wait());
1712 ASSERT_EQ(0, on_finish_safe
.wait());
1715 TEST_F(TestMockJournalReplay
, MetadataSetEvent
) {
1716 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1718 librbd::ImageCtx
*ictx
;
1719 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1721 MockReplayImageCtx
mock_image_ctx(*ictx
);
1723 MockExclusiveLock mock_exclusive_lock
;
1724 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1725 expect_accept_ops(mock_exclusive_lock
, true);
1727 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1728 expect_op_work_queue(mock_image_ctx
);
1731 Context
*on_finish
= nullptr;
1732 expect_metadata_set(mock_image_ctx
, &on_finish
, "key", "value");
1733 expect_refresh_image(mock_image_ctx
, false, 0);
1735 C_SaferCond on_start_ready
;
1736 C_SaferCond on_start_safe
;
1737 when_process(mock_journal_replay
, EventEntry
{MetadataSetEvent(123, "key", "value")},
1738 &on_start_ready
, &on_start_safe
);
1739 ASSERT_EQ(0, on_start_ready
.wait());
1741 C_SaferCond on_finish_ready
;
1742 C_SaferCond on_finish_safe
;
1743 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1744 &on_finish_ready
, &on_finish_safe
);
1746 wait_for_op_invoked(&on_finish
, 0);
1747 ASSERT_EQ(0, on_start_safe
.wait());
1748 ASSERT_EQ(0, on_finish_ready
.wait());
1749 ASSERT_EQ(0, on_finish_safe
.wait());
1752 TEST_F(TestMockJournalReplay
, MetadataRemoveEvent
) {
1753 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1755 librbd::ImageCtx
*ictx
;
1756 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1758 MockReplayImageCtx
mock_image_ctx(*ictx
);
1760 MockExclusiveLock mock_exclusive_lock
;
1761 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1762 expect_accept_ops(mock_exclusive_lock
, true);
1764 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1765 expect_op_work_queue(mock_image_ctx
);
1768 Context
*on_finish
= nullptr;
1769 expect_metadata_remove(mock_image_ctx
, &on_finish
, "key");
1770 expect_refresh_image(mock_image_ctx
, false, 0);
1772 C_SaferCond on_start_ready
;
1773 C_SaferCond on_start_safe
;
1774 when_process(mock_journal_replay
, EventEntry
{MetadataRemoveEvent(123, "key")},
1775 &on_start_ready
, &on_start_safe
);
1776 ASSERT_EQ(0, on_start_ready
.wait());
1778 C_SaferCond on_finish_ready
;
1779 C_SaferCond on_finish_safe
;
1780 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1781 &on_finish_ready
, &on_finish_safe
);
1783 wait_for_op_invoked(&on_finish
, 0);
1784 ASSERT_EQ(0, on_start_safe
.wait());
1785 ASSERT_EQ(0, on_finish_ready
.wait());
1786 ASSERT_EQ(0, on_finish_safe
.wait());
1789 TEST_F(TestMockJournalReplay
, MetadataRemoveEventDNE
) {
1790 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1792 librbd::ImageCtx
*ictx
;
1793 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1795 MockReplayImageCtx
mock_image_ctx(*ictx
);
1797 MockExclusiveLock mock_exclusive_lock
;
1798 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1799 expect_accept_ops(mock_exclusive_lock
, true);
1801 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1802 expect_op_work_queue(mock_image_ctx
);
1805 Context
*on_finish
= nullptr;
1806 expect_metadata_remove(mock_image_ctx
, &on_finish
, "key");
1808 C_SaferCond on_start_ready
;
1809 C_SaferCond on_start_safe
;
1810 when_process(mock_journal_replay
, EventEntry
{MetadataRemoveEvent(123, "key")},
1811 &on_start_ready
, &on_start_safe
);
1812 ASSERT_EQ(0, on_start_ready
.wait());
1814 C_SaferCond on_finish_ready
;
1815 C_SaferCond on_finish_safe
;
1816 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1817 &on_finish_ready
, &on_finish_safe
);
1819 wait_for_op_invoked(&on_finish
, -ENOENT
);
1820 ASSERT_EQ(0, on_start_safe
.wait());
1821 ASSERT_EQ(0, on_finish_ready
.wait());
1822 ASSERT_EQ(0, on_finish_safe
.wait());
1825 TEST_F(TestMockJournalReplay
, UnknownEvent
) {
1826 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1828 librbd::ImageCtx
*ictx
;
1829 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1831 MockReplayImageCtx
mock_image_ctx(*ictx
);
1833 MockExclusiveLock mock_exclusive_lock
;
1834 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1835 expect_accept_ops(mock_exclusive_lock
, true);
1837 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1838 expect_op_work_queue(mock_image_ctx
);
1843 ENCODE_START(1, 1, bl
);
1844 encode(static_cast<uint32_t>(-1), bl
);
1847 auto it
= bl
.cbegin();
1848 C_SaferCond on_ready
;
1849 C_SaferCond on_safe
;
1850 when_process(mock_journal_replay
, &it
, &on_ready
, &on_safe
);
1852 ASSERT_EQ(0, on_safe
.wait());
1853 ASSERT_EQ(0, on_ready
.wait());
1856 TEST_F(TestMockJournalReplay
, RefreshImageBeforeOpStart
) {
1857 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1859 librbd::ImageCtx
*ictx
;
1860 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1862 MockReplayImageCtx
mock_image_ctx(*ictx
);
1864 MockExclusiveLock mock_exclusive_lock
;
1865 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1866 expect_accept_ops(mock_exclusive_lock
, true);
1868 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1869 expect_op_work_queue(mock_image_ctx
);
1872 Context
*on_finish
= nullptr;
1873 expect_refresh_image(mock_image_ctx
, true, 0);
1874 expect_resize(mock_image_ctx
, &on_finish
, 234, 123);
1876 C_SaferCond on_start_ready
;
1877 C_SaferCond on_start_safe
;
1878 when_process(mock_journal_replay
, EventEntry
{ResizeEvent(123, 234)},
1879 &on_start_ready
, &on_start_safe
);
1881 C_SaferCond on_resume
;
1882 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
1883 ASSERT_EQ(0, on_start_ready
.wait());
1885 C_SaferCond on_finish_ready
;
1886 C_SaferCond on_finish_safe
;
1887 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1888 &on_finish_ready
, &on_finish_safe
);
1890 ASSERT_EQ(0, on_resume
.wait());
1891 wait_for_op_invoked(&on_finish
, 0);
1893 ASSERT_EQ(0, on_start_safe
.wait());
1894 ASSERT_EQ(0, on_finish_ready
.wait());
1895 ASSERT_EQ(0, on_finish_safe
.wait());
1898 TEST_F(TestMockJournalReplay
, FlushEventAfterShutDown
) {
1899 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1901 librbd::ImageCtx
*ictx
;
1902 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1904 MockReplayImageCtx
mock_image_ctx(*ictx
);
1906 MockExclusiveLock mock_exclusive_lock
;
1907 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1908 expect_accept_ops(mock_exclusive_lock
, true);
1910 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1911 MockIoImageRequest mock_io_image_request
;
1912 expect_op_work_queue(mock_image_ctx
);
1914 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1916 C_SaferCond on_ready
;
1917 C_SaferCond on_safe
;
1918 when_process(mock_journal_replay
, EventEntry
{AioFlushEvent()},
1919 &on_ready
, &on_safe
);
1920 ASSERT_EQ(0, on_ready
.wait());
1921 ASSERT_EQ(-ESHUTDOWN
, on_safe
.wait());
1924 TEST_F(TestMockJournalReplay
, ModifyEventAfterShutDown
) {
1925 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1927 librbd::ImageCtx
*ictx
;
1928 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1930 MockReplayImageCtx
mock_image_ctx(*ictx
);
1932 MockExclusiveLock mock_exclusive_lock
;
1933 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1934 expect_accept_ops(mock_exclusive_lock
, true);
1936 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1937 MockIoImageRequest mock_io_image_request
;
1938 expect_op_work_queue(mock_image_ctx
);
1940 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1942 C_SaferCond on_ready
;
1943 C_SaferCond on_safe
;
1944 when_process(mock_journal_replay
,
1945 EventEntry
{AioWriteEvent(123, 456, to_bl("test"))},
1946 &on_ready
, &on_safe
);
1947 ASSERT_EQ(0, on_ready
.wait());
1948 ASSERT_EQ(-ESHUTDOWN
, on_safe
.wait());
1951 TEST_F(TestMockJournalReplay
, OpEventAfterShutDown
) {
1952 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1954 librbd::ImageCtx
*ictx
;
1955 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1957 MockReplayImageCtx
mock_image_ctx(*ictx
);
1959 MockExclusiveLock mock_exclusive_lock
;
1960 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1961 expect_accept_ops(mock_exclusive_lock
, true);
1963 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1964 MockIoImageRequest mock_io_image_request
;
1965 expect_op_work_queue(mock_image_ctx
);
1967 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1969 C_SaferCond on_ready
;
1970 C_SaferCond on_safe
;
1971 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
1972 &on_ready
, &on_safe
);
1973 ASSERT_EQ(0, on_ready
.wait());
1974 ASSERT_EQ(-ESHUTDOWN
, on_safe
.wait());
1977 TEST_F(TestMockJournalReplay
, LockLostBeforeProcess
) {
1978 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1980 librbd::ImageCtx
*ictx
;
1981 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1983 MockReplayImageCtx
mock_image_ctx(*ictx
);
1985 MockExclusiveLock mock_exclusive_lock
;
1986 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1987 expect_accept_ops(mock_exclusive_lock
, false);
1989 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1990 MockIoImageRequest mock_io_image_request
;
1991 expect_op_work_queue(mock_image_ctx
);
1994 C_SaferCond on_ready
;
1995 C_SaferCond on_safe
;
1996 when_process(mock_journal_replay
, EventEntry
{AioFlushEvent()},
1997 &on_ready
, &on_safe
);
1998 ASSERT_EQ(0, on_ready
.wait());
1999 ASSERT_EQ(-ECANCELED
, on_safe
.wait());
2001 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
2004 TEST_F(TestMockJournalReplay
, LockLostBeforeExecuteOp
) {
2005 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
2007 librbd::ImageCtx
*ictx
;
2008 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
2010 MockReplayImageCtx
mock_image_ctx(*ictx
);
2012 MockExclusiveLock mock_exclusive_lock
;
2013 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
2014 expect_accept_ops(mock_exclusive_lock
, false);
2016 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
2017 expect_op_work_queue(mock_image_ctx
);
2020 EXPECT_CALL(mock_exclusive_lock
, accept_ops()).WillOnce(Return(true));
2021 EXPECT_CALL(mock_exclusive_lock
, accept_ops()).WillOnce(Return(true));
2022 expect_refresh_image(mock_image_ctx
, false, 0);
2024 C_SaferCond on_start_ready
;
2025 C_SaferCond on_start_safe
;
2026 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
2027 &on_start_ready
, &on_start_safe
);
2028 ASSERT_EQ(0, on_start_ready
.wait());
2030 C_SaferCond on_finish_ready
;
2031 C_SaferCond on_finish_safe
;
2032 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
2033 &on_finish_ready
, &on_finish_safe
);
2035 ASSERT_EQ(-ECANCELED
, on_start_safe
.wait());
2036 ASSERT_EQ(0, on_finish_ready
.wait());
2037 ASSERT_EQ(-ECANCELED
, on_finish_safe
.wait());
2040 } // namespace journal
2041 } // namespace librbd