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
);
71 ImageRequest
<MockReplayImageCtx
> *ImageRequest
<MockReplayImageCtx
>::s_instance
= nullptr;
77 inline ImageCtx
*get_image_ctx(librbd::MockReplayImageCtx
*image_ctx
) {
78 return image_ctx
->image_ctx
;
85 // template definitions
86 #include "librbd/journal/Replay.cc"
87 template class librbd::journal::Replay
<librbd::MockReplayImageCtx
>;
90 using ::testing::DoAll
;
91 using ::testing::InSequence
;
92 using ::testing::Return
;
93 using ::testing::SaveArg
;
94 using ::testing::StrEq
;
95 using ::testing::WithArgs
;
97 MATCHER_P(BufferlistEqual
, str
, "") {
99 return (strncmp(bl
.c_str(), str
, strlen(str
)) == 0);
102 MATCHER_P(CStrEq
, str
, "") {
103 return (strncmp(arg
, str
, strlen(str
)) == 0);
106 ACTION_P2(NotifyInvoke
, lock
, cond
) {
107 Mutex::Locker
locker(*lock
);
111 ACTION_P2(CompleteAioCompletion
, r
, image_ctx
) {
112 image_ctx
->op_work_queue
->queue(new FunctionContext([this, arg0
](int r
) {
114 arg0
->init_time(image_ctx
, librbd::io::AIO_TYPE_NONE
);
115 arg0
->set_request_count(1);
116 arg0
->complete_request(r
);
123 class TestMockJournalReplay
: public TestMockFixture
{
125 typedef io::ImageRequest
<MockReplayImageCtx
> MockIoImageRequest
;
126 typedef Replay
<MockReplayImageCtx
> MockJournalReplay
;
128 TestMockJournalReplay() : m_invoke_lock("m_invoke_lock") {
131 void expect_accept_ops(MockExclusiveLock
&mock_exclusive_lock
, bool accept
) {
132 EXPECT_CALL(mock_exclusive_lock
, accept_ops()).WillRepeatedly(
136 void expect_aio_discard(MockIoImageRequest
&mock_io_image_request
,
137 io::AioCompletion
**aio_comp
, uint64_t off
,
138 uint64_t len
, bool skip_partial_discard
) {
139 EXPECT_CALL(mock_io_image_request
, aio_discard(_
, off
, len
, skip_partial_discard
))
140 .WillOnce(SaveArg
<0>(aio_comp
));
143 void expect_aio_flush(MockIoImageRequest
&mock_io_image_request
,
144 io::AioCompletion
**aio_comp
) {
145 EXPECT_CALL(mock_io_image_request
, aio_flush(_
))
146 .WillOnce(SaveArg
<0>(aio_comp
));
149 void expect_aio_flush(MockReplayImageCtx
&mock_image_ctx
,
150 MockIoImageRequest
&mock_io_image_request
, int r
) {
151 EXPECT_CALL(mock_io_image_request
, aio_flush(_
))
152 .WillOnce(CompleteAioCompletion(r
, mock_image_ctx
.image_ctx
));
155 void expect_aio_write(MockIoImageRequest
&mock_io_image_request
,
156 io::AioCompletion
**aio_comp
, uint64_t off
,
157 uint64_t len
, const char *data
) {
158 EXPECT_CALL(mock_io_image_request
,
159 aio_write(_
, io::Extents
{{off
, len
}}, BufferlistEqual(data
), _
))
160 .WillOnce(SaveArg
<0>(aio_comp
));
163 void expect_aio_writesame(MockIoImageRequest
&mock_io_image_request
,
164 io::AioCompletion
**aio_comp
, uint64_t off
,
165 uint64_t len
, const char *data
) {
166 EXPECT_CALL(mock_io_image_request
,
167 aio_writesame(_
, off
, len
, BufferlistEqual(data
), _
))
168 .WillOnce(SaveArg
<0>(aio_comp
));
171 void expect_flatten(MockReplayImageCtx
&mock_image_ctx
, Context
**on_finish
) {
172 EXPECT_CALL(*mock_image_ctx
.operations
, execute_flatten(_
, _
))
173 .WillOnce(DoAll(SaveArg
<1>(on_finish
),
174 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
177 void expect_rename(MockReplayImageCtx
&mock_image_ctx
, Context
**on_finish
,
178 const char *image_name
) {
179 EXPECT_CALL(*mock_image_ctx
.operations
, execute_rename(StrEq(image_name
), _
))
180 .WillOnce(DoAll(SaveArg
<1>(on_finish
),
181 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
184 void expect_resize(MockReplayImageCtx
&mock_image_ctx
, Context
**on_finish
,
185 uint64_t size
, uint64_t op_tid
) {
186 EXPECT_CALL(*mock_image_ctx
.operations
, execute_resize(size
, _
, _
, _
, op_tid
))
187 .WillOnce(DoAll(SaveArg
<3>(on_finish
),
188 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
191 void expect_snap_create(MockReplayImageCtx
&mock_image_ctx
,
192 Context
**on_finish
, const char *snap_name
,
194 EXPECT_CALL(*mock_image_ctx
.operations
, execute_snap_create(_
, StrEq(snap_name
), _
,
196 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
197 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
200 void expect_snap_remove(MockReplayImageCtx
&mock_image_ctx
,
201 Context
**on_finish
, const char *snap_name
) {
202 EXPECT_CALL(*mock_image_ctx
.operations
, execute_snap_remove(_
, StrEq(snap_name
), _
))
203 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
204 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
207 void expect_snap_rename(MockReplayImageCtx
&mock_image_ctx
,
208 Context
**on_finish
, uint64_t snap_id
,
209 const char *snap_name
) {
210 EXPECT_CALL(*mock_image_ctx
.operations
, execute_snap_rename(snap_id
, StrEq(snap_name
), _
))
211 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
212 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
215 void expect_snap_protect(MockReplayImageCtx
&mock_image_ctx
,
216 Context
**on_finish
, const char *snap_name
) {
217 EXPECT_CALL(*mock_image_ctx
.operations
, execute_snap_protect(_
, StrEq(snap_name
), _
))
218 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
219 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
222 void expect_snap_unprotect(MockReplayImageCtx
&mock_image_ctx
,
223 Context
**on_finish
, const char *snap_name
) {
224 EXPECT_CALL(*mock_image_ctx
.operations
, execute_snap_unprotect(_
, StrEq(snap_name
), _
))
225 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
226 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
229 void expect_snap_rollback(MockReplayImageCtx
&mock_image_ctx
,
230 Context
**on_finish
, const char *snap_name
) {
231 EXPECT_CALL(*mock_image_ctx
.operations
, execute_snap_rollback(_
, StrEq(snap_name
), _
, _
))
232 .WillOnce(DoAll(SaveArg
<3>(on_finish
),
233 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
236 void expect_update_features(MockReplayImageCtx
&mock_image_ctx
, Context
**on_finish
,
237 uint64_t features
, bool enabled
, uint64_t op_tid
) {
238 EXPECT_CALL(*mock_image_ctx
.operations
, execute_update_features(features
, enabled
, _
, op_tid
))
239 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
240 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
243 void expect_metadata_set(MockReplayImageCtx
&mock_image_ctx
,
244 Context
**on_finish
, const char *key
,
246 EXPECT_CALL(*mock_image_ctx
.operations
, execute_metadata_set(StrEq(key
),
248 .WillOnce(DoAll(SaveArg
<2>(on_finish
),
249 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
252 void expect_metadata_remove(MockReplayImageCtx
&mock_image_ctx
,
253 Context
**on_finish
, const char *key
) {
254 EXPECT_CALL(*mock_image_ctx
.operations
, execute_metadata_remove(StrEq(key
), _
))
255 .WillOnce(DoAll(SaveArg
<1>(on_finish
),
256 NotifyInvoke(&m_invoke_lock
, &m_invoke_cond
)));
259 void expect_refresh_image(MockReplayImageCtx
&mock_image_ctx
, bool required
,
261 EXPECT_CALL(*mock_image_ctx
.state
, is_refresh_required())
262 .WillOnce(Return(required
));
264 EXPECT_CALL(*mock_image_ctx
.state
, refresh(_
))
265 .WillOnce(CompleteContext(r
, mock_image_ctx
.image_ctx
->op_work_queue
));
269 void when_process(MockJournalReplay
&mock_journal_replay
,
270 EventEntry
&&event_entry
, Context
*on_ready
,
273 ::encode(event_entry
, bl
);
275 bufferlist::iterator it
= bl
.begin();
276 when_process(mock_journal_replay
, &it
, on_ready
, on_safe
);
279 void when_process(MockJournalReplay
&mock_journal_replay
,
280 bufferlist::iterator
*it
, Context
*on_ready
,
282 EventEntry event_entry
;
283 int r
= mock_journal_replay
.decode(it
, &event_entry
);
286 mock_journal_replay
.process(event_entry
, on_ready
, on_safe
);
289 void when_complete(MockReplayImageCtx
&mock_image_ctx
,
290 io::AioCompletion
*aio_comp
, int r
) {
292 aio_comp
->init_time(mock_image_ctx
.image_ctx
, librbd::io::AIO_TYPE_NONE
);
293 aio_comp
->set_request_count(1);
294 aio_comp
->complete_request(r
);
297 int when_flush(MockJournalReplay
&mock_journal_replay
) {
299 mock_journal_replay
.flush(&ctx
);
303 int when_shut_down(MockJournalReplay
&mock_journal_replay
, bool cancel_ops
) {
305 mock_journal_replay
.shut_down(cancel_ops
, &ctx
);
309 void when_replay_op_ready(MockJournalReplay
&mock_journal_replay
,
310 uint64_t op_tid
, Context
*on_resume
) {
311 mock_journal_replay
.replay_op_ready(op_tid
, on_resume
);
314 void wait_for_op_invoked(Context
**on_finish
, int r
) {
316 Mutex::Locker
locker(m_invoke_lock
);
317 while (*on_finish
== nullptr) {
318 m_invoke_cond
.Wait(m_invoke_lock
);
321 (*on_finish
)->complete(r
);
324 bufferlist
to_bl(const std::string
&str
) {
334 TEST_F(TestMockJournalReplay
, AioDiscard
) {
335 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
337 librbd::ImageCtx
*ictx
;
338 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
340 MockReplayImageCtx
mock_image_ctx(*ictx
);
342 MockExclusiveLock mock_exclusive_lock
;
343 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
344 expect_accept_ops(mock_exclusive_lock
, true);
346 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
347 MockIoImageRequest mock_io_image_request
;
348 expect_op_work_queue(mock_image_ctx
);
351 io::AioCompletion
*aio_comp
;
352 C_SaferCond on_ready
;
354 expect_aio_discard(mock_io_image_request
, &aio_comp
, 123, 456, ictx
->skip_partial_discard
);
355 when_process(mock_journal_replay
,
356 EventEntry
{AioDiscardEvent(123, 456, ictx
->skip_partial_discard
)},
357 &on_ready
, &on_safe
);
359 when_complete(mock_image_ctx
, aio_comp
, 0);
360 ASSERT_EQ(0, on_ready
.wait());
362 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
363 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
364 ASSERT_EQ(0, on_safe
.wait());
367 TEST_F(TestMockJournalReplay
, AioWrite
) {
368 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
370 librbd::ImageCtx
*ictx
;
371 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
373 MockReplayImageCtx
mock_image_ctx(*ictx
);
375 MockExclusiveLock mock_exclusive_lock
;
376 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
377 expect_accept_ops(mock_exclusive_lock
, true);
379 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
380 MockIoImageRequest mock_io_image_request
;
381 expect_op_work_queue(mock_image_ctx
);
384 io::AioCompletion
*aio_comp
;
385 C_SaferCond on_ready
;
387 expect_aio_write(mock_io_image_request
, &aio_comp
, 123, 456, "test");
388 when_process(mock_journal_replay
,
389 EventEntry
{AioWriteEvent(123, 456, to_bl("test"))},
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
, AioFlush
) {
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_flush(mock_io_image_request
, &aio_comp
);
421 when_process(mock_journal_replay
, EventEntry
{AioFlushEvent()},
422 &on_ready
, &on_safe
);
424 when_complete(mock_image_ctx
, aio_comp
, 0);
425 ASSERT_EQ(0, on_safe
.wait());
427 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
428 ASSERT_EQ(0, on_ready
.wait());
431 TEST_F(TestMockJournalReplay
, AioWriteSame
) {
432 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
434 librbd::ImageCtx
*ictx
;
435 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
437 MockReplayImageCtx
mock_image_ctx(*ictx
);
439 MockExclusiveLock mock_exclusive_lock
;
440 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
441 expect_accept_ops(mock_exclusive_lock
, true);
443 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
444 MockIoImageRequest mock_io_image_request
;
445 expect_op_work_queue(mock_image_ctx
);
448 io::AioCompletion
*aio_comp
;
449 C_SaferCond on_ready
;
451 expect_aio_writesame(mock_io_image_request
, &aio_comp
, 123, 456, "333");
452 when_process(mock_journal_replay
,
453 EventEntry
{AioWriteSameEvent(123, 456, to_bl("333"))},
454 &on_ready
, &on_safe
);
456 when_complete(mock_image_ctx
, aio_comp
, 0);
457 ASSERT_EQ(0, on_ready
.wait());
459 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
460 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
461 ASSERT_EQ(0, on_safe
.wait());
464 TEST_F(TestMockJournalReplay
, IOError
) {
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_discard(mock_io_image_request
, &aio_comp
, 123, 456, ictx
->skip_partial_discard
);
485 when_process(mock_journal_replay
,
486 EventEntry
{AioDiscardEvent(123, 456, ictx
->skip_partial_discard
)},
487 &on_ready
, &on_safe
);
489 when_complete(mock_image_ctx
, aio_comp
, -EINVAL
);
490 ASSERT_EQ(-EINVAL
, on_safe
.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_ready
.wait());
497 TEST_F(TestMockJournalReplay
, SoftFlushIO
) {
498 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
500 librbd::ImageCtx
*ictx
;
501 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
503 MockReplayImageCtx
mock_image_ctx(*ictx
);
505 MockExclusiveLock mock_exclusive_lock
;
506 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
507 expect_accept_ops(mock_exclusive_lock
, true);
509 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
510 MockIoImageRequest mock_io_image_request
;
511 expect_op_work_queue(mock_image_ctx
);
514 const size_t io_count
= 32;
515 C_SaferCond on_safes
[io_count
];
516 for (size_t i
= 0; i
< io_count
; ++i
) {
517 io::AioCompletion
*aio_comp
;
518 io::AioCompletion
*flush_comp
= nullptr;
519 C_SaferCond on_ready
;
520 expect_aio_discard(mock_io_image_request
, &aio_comp
, 123, 456, ictx
->skip_partial_discard
);
521 if (i
== io_count
- 1) {
522 expect_aio_flush(mock_io_image_request
, &flush_comp
);
524 when_process(mock_journal_replay
,
525 EventEntry
{AioDiscardEvent(123, 456, ictx
->skip_partial_discard
)},
526 &on_ready
, &on_safes
[i
]);
527 when_complete(mock_image_ctx
, aio_comp
, 0);
528 ASSERT_EQ(0, on_ready
.wait());
530 if (flush_comp
!= nullptr) {
531 when_complete(mock_image_ctx
, flush_comp
, 0);
534 for (auto &on_safe
: on_safes
) {
535 ASSERT_EQ(0, on_safe
.wait());
538 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
541 TEST_F(TestMockJournalReplay
, PauseIO
) {
542 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
544 librbd::ImageCtx
*ictx
;
545 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
547 MockReplayImageCtx
mock_image_ctx(*ictx
);
549 MockExclusiveLock mock_exclusive_lock
;
550 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
551 expect_accept_ops(mock_exclusive_lock
, true);
553 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
554 MockIoImageRequest mock_io_image_request
;
555 expect_op_work_queue(mock_image_ctx
);
558 const size_t io_count
= 64;
559 std::list
<io::AioCompletion
*> flush_comps
;
560 C_SaferCond on_safes
[io_count
];
561 for (size_t i
= 0; i
< io_count
; ++i
) {
562 io::AioCompletion
*aio_comp
;
563 C_SaferCond on_ready
;
564 expect_aio_write(mock_io_image_request
, &aio_comp
, 123, 456, "test");
565 if ((i
+ 1) % 32 == 0) {
566 flush_comps
.push_back(nullptr);
567 expect_aio_flush(mock_io_image_request
, &flush_comps
.back());
569 when_process(mock_journal_replay
,
570 EventEntry
{AioWriteEvent(123, 456, to_bl("test"))},
571 &on_ready
, &on_safes
[i
]);
572 when_complete(mock_image_ctx
, aio_comp
, 0);
573 if (i
< io_count
- 1) {
574 ASSERT_EQ(0, on_ready
.wait());
576 for (auto flush_comp
: flush_comps
) {
577 when_complete(mock_image_ctx
, flush_comp
, 0);
579 ASSERT_EQ(0, on_ready
.wait());
582 for (auto &on_safe
: on_safes
) {
583 ASSERT_EQ(0, on_safe
.wait());
586 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
589 TEST_F(TestMockJournalReplay
, Flush
) {
590 librbd::ImageCtx
*ictx
;
591 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
593 MockReplayImageCtx
mock_image_ctx(*ictx
);
595 MockExclusiveLock mock_exclusive_lock
;
596 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
597 expect_accept_ops(mock_exclusive_lock
, true);
599 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
600 MockIoImageRequest mock_io_image_request
;
601 expect_op_work_queue(mock_image_ctx
);
604 io::AioCompletion
*aio_comp
= nullptr;
605 C_SaferCond on_ready
;
607 expect_aio_discard(mock_io_image_request
, &aio_comp
, 123, 456, ictx
->skip_partial_discard
);
608 when_process(mock_journal_replay
,
609 EventEntry
{AioDiscardEvent(123, 456, ictx
->skip_partial_discard
)},
610 &on_ready
, &on_safe
);
612 when_complete(mock_image_ctx
, aio_comp
, 0);
613 ASSERT_EQ(0, on_ready
.wait());
615 expect_aio_flush(mock_image_ctx
, mock_io_image_request
, 0);
616 ASSERT_EQ(0, when_flush(mock_journal_replay
));
617 ASSERT_EQ(0, on_safe
.wait());
620 TEST_F(TestMockJournalReplay
, OpFinishError
) {
621 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
623 librbd::ImageCtx
*ictx
;
624 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
626 MockReplayImageCtx
mock_image_ctx(*ictx
);
628 MockExclusiveLock mock_exclusive_lock
;
629 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
630 expect_accept_ops(mock_exclusive_lock
, true);
632 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
633 expect_op_work_queue(mock_image_ctx
);
636 C_SaferCond on_start_ready
;
637 C_SaferCond on_start_safe
;
638 when_process(mock_journal_replay
,
639 EventEntry
{SnapRemoveEvent(123,
640 cls::rbd::UserSnapshotNamespace(),
644 ASSERT_EQ(0, on_start_ready
.wait());
646 C_SaferCond on_finish_ready
;
647 C_SaferCond on_finish_safe
;
648 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, -EIO
)},
649 &on_finish_ready
, &on_finish_safe
);
651 ASSERT_EQ(-EIO
, on_start_safe
.wait());
652 ASSERT_EQ(-EIO
, on_finish_safe
.wait());
653 ASSERT_EQ(0, on_finish_ready
.wait());
656 TEST_F(TestMockJournalReplay
, BlockedOpFinishError
) {
657 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
659 librbd::ImageCtx
*ictx
;
660 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
662 MockReplayImageCtx
mock_image_ctx(*ictx
);
664 MockExclusiveLock mock_exclusive_lock
;
665 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
666 expect_accept_ops(mock_exclusive_lock
, true);
668 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
669 expect_op_work_queue(mock_image_ctx
);
672 Context
*on_finish
= nullptr;
673 expect_refresh_image(mock_image_ctx
, false, 0);
674 expect_snap_create(mock_image_ctx
, &on_finish
, "snap", 123);
676 C_SaferCond on_start_ready
;
677 C_SaferCond on_start_safe
;
678 when_process(mock_journal_replay
,
679 EventEntry
{SnapCreateEvent(123,
680 cls::rbd::UserSnapshotNamespace(),
685 C_SaferCond on_resume
;
686 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
687 ASSERT_EQ(0, on_start_ready
.wait());
689 C_SaferCond on_finish_ready
;
690 C_SaferCond on_finish_safe
;
691 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, -EBADMSG
)},
692 &on_finish_ready
, &on_finish_safe
);
694 ASSERT_EQ(-EBADMSG
, on_resume
.wait());
695 wait_for_op_invoked(&on_finish
, -ESTALE
);
697 ASSERT_EQ(-ESTALE
, on_start_safe
.wait());
698 ASSERT_EQ(-ESTALE
, on_finish_safe
.wait());
699 ASSERT_EQ(0, on_finish_ready
.wait());
702 TEST_F(TestMockJournalReplay
, MissingOpFinishEvent
) {
703 librbd::ImageCtx
*ictx
;
704 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
706 MockReplayImageCtx
mock_image_ctx(*ictx
);
708 MockExclusiveLock mock_exclusive_lock
;
709 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
710 expect_accept_ops(mock_exclusive_lock
, true);
712 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
713 expect_op_work_queue(mock_image_ctx
);
715 EXPECT_CALL(*mock_image_ctx
.state
, is_refresh_required())
716 .WillRepeatedly(Return(false));
719 Context
*on_snap_create_finish
= nullptr;
720 expect_snap_create(mock_image_ctx
, &on_snap_create_finish
, "snap", 123);
722 Context
*on_snap_remove_finish
= nullptr;
723 expect_snap_remove(mock_image_ctx
, &on_snap_remove_finish
, "snap");
725 C_SaferCond on_snap_remove_ready
;
726 C_SaferCond on_snap_remove_safe
;
727 when_process(mock_journal_replay
,
728 EventEntry
{SnapRemoveEvent(122,
729 cls::rbd::UserSnapshotNamespace(),
731 &on_snap_remove_ready
,
732 &on_snap_remove_safe
);
733 ASSERT_EQ(0, on_snap_remove_ready
.wait());
735 C_SaferCond on_snap_create_ready
;
736 C_SaferCond on_snap_create_safe
;
737 when_process(mock_journal_replay
,
738 EventEntry
{SnapCreateEvent(123,
739 cls::rbd::UserSnapshotNamespace(),
741 &on_snap_create_ready
,
742 &on_snap_create_safe
);
744 C_SaferCond on_shut_down
;
745 mock_journal_replay
.shut_down(false, &on_shut_down
);
747 wait_for_op_invoked(&on_snap_remove_finish
, 0);
748 ASSERT_EQ(0, on_snap_remove_safe
.wait());
750 C_SaferCond on_snap_create_resume
;
751 when_replay_op_ready(mock_journal_replay
, 123, &on_snap_create_resume
);
752 ASSERT_EQ(0, on_snap_create_resume
.wait());
754 wait_for_op_invoked(&on_snap_create_finish
, 0);
755 ASSERT_EQ(0, on_snap_create_ready
.wait());
756 ASSERT_EQ(0, on_snap_create_safe
.wait());
758 ASSERT_EQ(0, on_shut_down
.wait());
761 TEST_F(TestMockJournalReplay
, MissingOpFinishEventCancelOps
) {
762 librbd::ImageCtx
*ictx
;
763 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
765 MockReplayImageCtx
mock_image_ctx(*ictx
);
767 MockExclusiveLock mock_exclusive_lock
;
768 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
769 expect_accept_ops(mock_exclusive_lock
, true);
771 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
772 expect_op_work_queue(mock_image_ctx
);
775 Context
*on_snap_create_finish
= nullptr;
776 expect_refresh_image(mock_image_ctx
, false, 0);
777 expect_snap_create(mock_image_ctx
, &on_snap_create_finish
, "snap", 123);
779 C_SaferCond on_snap_remove_ready
;
780 C_SaferCond on_snap_remove_safe
;
781 when_process(mock_journal_replay
,
782 EventEntry
{SnapRemoveEvent(122,
783 cls::rbd::UserSnapshotNamespace(),
785 &on_snap_remove_ready
,
786 &on_snap_remove_safe
);
787 ASSERT_EQ(0, on_snap_remove_ready
.wait());
789 C_SaferCond on_snap_create_ready
;
790 C_SaferCond on_snap_create_safe
;
791 when_process(mock_journal_replay
,
792 EventEntry
{SnapCreateEvent(123,
793 cls::rbd::UserSnapshotNamespace(),
795 &on_snap_create_ready
,
796 &on_snap_create_safe
);
798 C_SaferCond on_resume
;
799 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
800 ASSERT_EQ(0, on_snap_create_ready
.wait());
802 C_SaferCond on_shut_down
;
803 mock_journal_replay
.shut_down(true, &on_shut_down
);
805 ASSERT_EQ(-ERESTART
, on_resume
.wait());
806 on_snap_create_finish
->complete(-ERESTART
);
807 ASSERT_EQ(-ERESTART
, on_snap_create_safe
.wait());
809 ASSERT_EQ(-ERESTART
, on_snap_remove_safe
.wait());
810 ASSERT_EQ(0, on_shut_down
.wait());
813 TEST_F(TestMockJournalReplay
, UnknownOpFinishEvent
) {
814 librbd::ImageCtx
*ictx
;
815 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
817 MockReplayImageCtx
mock_image_ctx(*ictx
);
819 MockExclusiveLock mock_exclusive_lock
;
820 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
821 expect_accept_ops(mock_exclusive_lock
, true);
823 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
824 expect_op_work_queue(mock_image_ctx
);
827 C_SaferCond on_ready
;
829 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
830 &on_ready
, &on_safe
);
832 ASSERT_EQ(0, on_safe
.wait());
833 ASSERT_EQ(0, on_ready
.wait());
836 TEST_F(TestMockJournalReplay
, OpEventError
) {
837 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
839 librbd::ImageCtx
*ictx
;
840 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
842 MockReplayImageCtx
mock_image_ctx(*ictx
);
844 MockExclusiveLock mock_exclusive_lock
;
845 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
846 expect_accept_ops(mock_exclusive_lock
, true);
848 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
849 expect_op_work_queue(mock_image_ctx
);
852 Context
*on_finish
= nullptr;
853 expect_refresh_image(mock_image_ctx
, false, 0);
854 expect_snap_remove(mock_image_ctx
, &on_finish
, "snap");
856 C_SaferCond on_start_ready
;
857 C_SaferCond on_start_safe
;
858 when_process(mock_journal_replay
,
859 EventEntry
{SnapRemoveEvent(123,
860 cls::rbd::UserSnapshotNamespace(),
864 ASSERT_EQ(0, on_start_ready
.wait());
866 C_SaferCond on_finish_ready
;
867 C_SaferCond on_finish_safe
;
868 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
869 &on_finish_ready
, &on_finish_safe
);
871 wait_for_op_invoked(&on_finish
, -EINVAL
);
872 ASSERT_EQ(-EINVAL
, on_start_safe
.wait());
873 ASSERT_EQ(0, on_finish_ready
.wait());
874 ASSERT_EQ(-EINVAL
, on_finish_safe
.wait());
877 TEST_F(TestMockJournalReplay
, SnapCreateEvent
) {
878 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
880 librbd::ImageCtx
*ictx
;
881 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
883 MockReplayImageCtx
mock_image_ctx(*ictx
);
885 MockExclusiveLock mock_exclusive_lock
;
886 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
887 expect_accept_ops(mock_exclusive_lock
, true);
889 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
890 expect_op_work_queue(mock_image_ctx
);
893 Context
*on_finish
= nullptr;
894 expect_refresh_image(mock_image_ctx
, false, 0);
895 expect_snap_create(mock_image_ctx
, &on_finish
, "snap", 123);
897 C_SaferCond on_start_ready
;
898 C_SaferCond on_start_safe
;
899 when_process(mock_journal_replay
,
900 EventEntry
{SnapCreateEvent(123,
901 cls::rbd::UserSnapshotNamespace(),
906 C_SaferCond on_resume
;
907 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
908 ASSERT_EQ(0, on_start_ready
.wait());
910 C_SaferCond on_finish_ready
;
911 C_SaferCond on_finish_safe
;
912 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
913 &on_finish_ready
, &on_finish_safe
);
915 ASSERT_EQ(0, on_resume
.wait());
916 wait_for_op_invoked(&on_finish
, 0);
918 ASSERT_EQ(0, on_start_safe
.wait());
919 ASSERT_EQ(0, on_finish_ready
.wait());
920 ASSERT_EQ(0, on_finish_safe
.wait());
923 TEST_F(TestMockJournalReplay
, SnapCreateEventExists
) {
924 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
926 librbd::ImageCtx
*ictx
;
927 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
929 MockReplayImageCtx
mock_image_ctx(*ictx
);
931 MockExclusiveLock mock_exclusive_lock
;
932 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
933 expect_accept_ops(mock_exclusive_lock
, true);
935 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
936 expect_op_work_queue(mock_image_ctx
);
939 Context
*on_finish
= nullptr;
940 expect_refresh_image(mock_image_ctx
, false, 0);
941 expect_snap_create(mock_image_ctx
, &on_finish
, "snap", 123);
943 C_SaferCond on_start_ready
;
944 C_SaferCond on_start_safe
;
945 when_process(mock_journal_replay
,
946 EventEntry
{SnapCreateEvent(123,
947 cls::rbd::UserSnapshotNamespace(),
952 wait_for_op_invoked(&on_finish
, -EEXIST
);
953 ASSERT_EQ(0, on_start_ready
.wait());
955 C_SaferCond on_finish_ready
;
956 C_SaferCond on_finish_safe
;
957 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
958 &on_finish_ready
, &on_finish_safe
);
960 ASSERT_EQ(0, on_start_safe
.wait());
961 ASSERT_EQ(0, on_finish_ready
.wait());
962 ASSERT_EQ(0, on_finish_safe
.wait());
965 TEST_F(TestMockJournalReplay
, SnapRemoveEvent
) {
966 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
968 librbd::ImageCtx
*ictx
;
969 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
971 MockReplayImageCtx
mock_image_ctx(*ictx
);
973 MockExclusiveLock mock_exclusive_lock
;
974 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
975 expect_accept_ops(mock_exclusive_lock
, true);
977 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
978 expect_op_work_queue(mock_image_ctx
);
981 Context
*on_finish
= nullptr;
982 expect_refresh_image(mock_image_ctx
, false, 0);
983 expect_snap_remove(mock_image_ctx
, &on_finish
, "snap");
985 C_SaferCond on_start_ready
;
986 C_SaferCond on_start_safe
;
987 when_process(mock_journal_replay
,
988 EventEntry
{SnapRemoveEvent(123,
989 cls::rbd::UserSnapshotNamespace(),
993 ASSERT_EQ(0, on_start_ready
.wait());
995 C_SaferCond on_finish_ready
;
996 C_SaferCond on_finish_safe
;
997 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
998 &on_finish_ready
, &on_finish_safe
);
1000 wait_for_op_invoked(&on_finish
, 0);
1001 ASSERT_EQ(0, on_start_safe
.wait());
1002 ASSERT_EQ(0, on_finish_ready
.wait());
1003 ASSERT_EQ(0, on_finish_safe
.wait());
1006 TEST_F(TestMockJournalReplay
, SnapRemoveEventDNE
) {
1007 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1009 librbd::ImageCtx
*ictx
;
1010 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1012 MockReplayImageCtx
mock_image_ctx(*ictx
);
1014 MockExclusiveLock mock_exclusive_lock
;
1015 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1016 expect_accept_ops(mock_exclusive_lock
, true);
1018 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1019 expect_op_work_queue(mock_image_ctx
);
1022 Context
*on_finish
= nullptr;
1023 expect_refresh_image(mock_image_ctx
, false, 0);
1024 expect_snap_remove(mock_image_ctx
, &on_finish
, "snap");
1026 C_SaferCond on_start_ready
;
1027 C_SaferCond on_start_safe
;
1028 when_process(mock_journal_replay
,
1029 EventEntry
{SnapRemoveEvent(123,
1030 cls::rbd::UserSnapshotNamespace(),
1034 ASSERT_EQ(0, on_start_ready
.wait());
1036 C_SaferCond on_finish_ready
;
1037 C_SaferCond on_finish_safe
;
1038 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1039 &on_finish_ready
, &on_finish_safe
);
1041 wait_for_op_invoked(&on_finish
, -ENOENT
);
1042 ASSERT_EQ(0, on_start_safe
.wait());
1043 ASSERT_EQ(0, on_finish_ready
.wait());
1044 ASSERT_EQ(0, on_finish_safe
.wait());
1047 TEST_F(TestMockJournalReplay
, SnapRenameEvent
) {
1048 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1050 librbd::ImageCtx
*ictx
;
1051 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1053 MockReplayImageCtx
mock_image_ctx(*ictx
);
1055 MockExclusiveLock mock_exclusive_lock
;
1056 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1057 expect_accept_ops(mock_exclusive_lock
, true);
1059 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1060 expect_op_work_queue(mock_image_ctx
);
1063 Context
*on_finish
= nullptr;
1064 expect_refresh_image(mock_image_ctx
, false, 0);
1065 expect_snap_rename(mock_image_ctx
, &on_finish
, 234, "snap");
1067 C_SaferCond on_start_ready
;
1068 C_SaferCond on_start_safe
;
1069 when_process(mock_journal_replay
,
1070 EventEntry
{SnapRenameEvent(123, 234, "snap1", "snap")},
1071 &on_start_ready
, &on_start_safe
);
1072 ASSERT_EQ(0, on_start_ready
.wait());
1074 C_SaferCond on_finish_ready
;
1075 C_SaferCond on_finish_safe
;
1076 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1077 &on_finish_ready
, &on_finish_safe
);
1079 wait_for_op_invoked(&on_finish
, 0);
1080 ASSERT_EQ(0, on_start_safe
.wait());
1081 ASSERT_EQ(0, on_finish_ready
.wait());
1082 ASSERT_EQ(0, on_finish_safe
.wait());
1085 TEST_F(TestMockJournalReplay
, SnapRenameEventExists
) {
1086 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1088 librbd::ImageCtx
*ictx
;
1089 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1091 MockReplayImageCtx
mock_image_ctx(*ictx
);
1093 MockExclusiveLock mock_exclusive_lock
;
1094 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1095 expect_accept_ops(mock_exclusive_lock
, true);
1097 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1098 expect_op_work_queue(mock_image_ctx
);
1101 Context
*on_finish
= nullptr;
1102 expect_refresh_image(mock_image_ctx
, false, 0);
1103 expect_snap_rename(mock_image_ctx
, &on_finish
, 234, "snap");
1105 C_SaferCond on_start_ready
;
1106 C_SaferCond on_start_safe
;
1107 when_process(mock_journal_replay
,
1108 EventEntry
{SnapRenameEvent(123, 234, "snap1", "snap")},
1109 &on_start_ready
, &on_start_safe
);
1110 ASSERT_EQ(0, on_start_ready
.wait());
1112 C_SaferCond on_finish_ready
;
1113 C_SaferCond on_finish_safe
;
1114 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1115 &on_finish_ready
, &on_finish_safe
);
1117 wait_for_op_invoked(&on_finish
, -EEXIST
);
1118 ASSERT_EQ(0, on_start_safe
.wait());
1119 ASSERT_EQ(0, on_finish_ready
.wait());
1120 ASSERT_EQ(0, on_finish_safe
.wait());
1123 TEST_F(TestMockJournalReplay
, SnapProtectEvent
) {
1124 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1126 librbd::ImageCtx
*ictx
;
1127 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1129 MockReplayImageCtx
mock_image_ctx(*ictx
);
1131 MockExclusiveLock mock_exclusive_lock
;
1132 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1133 expect_accept_ops(mock_exclusive_lock
, true);
1135 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1136 expect_op_work_queue(mock_image_ctx
);
1139 Context
*on_finish
= nullptr;
1140 expect_refresh_image(mock_image_ctx
, false, 0);
1141 expect_snap_protect(mock_image_ctx
, &on_finish
, "snap");
1143 C_SaferCond on_start_ready
;
1144 C_SaferCond on_start_safe
;
1145 when_process(mock_journal_replay
,
1146 EventEntry
{SnapProtectEvent(123,
1147 cls::rbd::UserSnapshotNamespace(),
1151 ASSERT_EQ(0, on_start_ready
.wait());
1153 C_SaferCond on_finish_ready
;
1154 C_SaferCond on_finish_safe
;
1155 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1156 &on_finish_ready
, &on_finish_safe
);
1158 wait_for_op_invoked(&on_finish
, 0);
1159 ASSERT_EQ(0, on_start_safe
.wait());
1160 ASSERT_EQ(0, on_finish_ready
.wait());
1161 ASSERT_EQ(0, on_finish_safe
.wait());
1164 TEST_F(TestMockJournalReplay
, SnapProtectEventBusy
) {
1165 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1167 librbd::ImageCtx
*ictx
;
1168 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1170 MockReplayImageCtx
mock_image_ctx(*ictx
);
1172 MockExclusiveLock mock_exclusive_lock
;
1173 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1174 expect_accept_ops(mock_exclusive_lock
, true);
1176 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1177 expect_op_work_queue(mock_image_ctx
);
1180 Context
*on_finish
= nullptr;
1181 expect_refresh_image(mock_image_ctx
, false, 0);
1182 expect_snap_protect(mock_image_ctx
, &on_finish
, "snap");
1184 C_SaferCond on_start_ready
;
1185 C_SaferCond on_start_safe
;
1186 when_process(mock_journal_replay
,
1187 EventEntry
{SnapProtectEvent(123,
1188 cls::rbd::UserSnapshotNamespace(),
1192 ASSERT_EQ(0, on_start_ready
.wait());
1194 C_SaferCond on_finish_ready
;
1195 C_SaferCond on_finish_safe
;
1196 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1197 &on_finish_ready
, &on_finish_safe
);
1199 wait_for_op_invoked(&on_finish
, -EBUSY
);
1200 ASSERT_EQ(0, on_start_safe
.wait());
1201 ASSERT_EQ(0, on_finish_ready
.wait());
1202 ASSERT_EQ(0, on_finish_safe
.wait());
1205 TEST_F(TestMockJournalReplay
, SnapUnprotectEvent
) {
1206 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1208 librbd::ImageCtx
*ictx
;
1209 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1211 MockReplayImageCtx
mock_image_ctx(*ictx
);
1213 MockExclusiveLock mock_exclusive_lock
;
1214 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1215 expect_accept_ops(mock_exclusive_lock
, true);
1217 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1218 expect_op_work_queue(mock_image_ctx
);
1221 Context
*on_finish
= nullptr;
1222 expect_refresh_image(mock_image_ctx
, false, 0);
1223 expect_snap_unprotect(mock_image_ctx
, &on_finish
, "snap");
1225 C_SaferCond on_start_ready
;
1226 C_SaferCond on_start_safe
;
1227 when_process(mock_journal_replay
,
1228 EventEntry
{SnapUnprotectEvent(123,
1229 cls::rbd::UserSnapshotNamespace(),
1233 ASSERT_EQ(0, on_start_ready
.wait());
1235 C_SaferCond on_finish_ready
;
1236 C_SaferCond on_finish_safe
;
1237 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1238 &on_finish_ready
, &on_finish_safe
);
1240 wait_for_op_invoked(&on_finish
, 0);
1241 ASSERT_EQ(0, on_start_safe
.wait());
1242 ASSERT_EQ(0, on_finish_ready
.wait());
1243 ASSERT_EQ(0, on_finish_safe
.wait());
1246 TEST_F(TestMockJournalReplay
, SnapUnprotectOpFinishBusy
) {
1247 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1249 librbd::ImageCtx
*ictx
;
1250 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1252 MockReplayImageCtx
mock_image_ctx(*ictx
);
1254 MockExclusiveLock mock_exclusive_lock
;
1255 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1256 expect_accept_ops(mock_exclusive_lock
, true);
1258 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1259 expect_op_work_queue(mock_image_ctx
);
1262 C_SaferCond on_start_ready
;
1263 C_SaferCond on_start_safe
;
1264 when_process(mock_journal_replay
,
1265 EventEntry
{SnapUnprotectEvent(123,
1266 cls::rbd::UserSnapshotNamespace(),
1270 ASSERT_EQ(0, on_start_ready
.wait());
1272 // aborts the snap unprotect op if image had children
1273 C_SaferCond on_finish_ready
;
1274 C_SaferCond on_finish_safe
;
1275 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, -EBUSY
)},
1276 &on_finish_ready
, &on_finish_safe
);
1278 ASSERT_EQ(0, on_start_safe
.wait());
1279 ASSERT_EQ(0, on_finish_safe
.wait());
1280 ASSERT_EQ(0, on_finish_ready
.wait());
1283 TEST_F(TestMockJournalReplay
, SnapUnprotectEventInvalid
) {
1284 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1286 librbd::ImageCtx
*ictx
;
1287 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1289 MockReplayImageCtx
mock_image_ctx(*ictx
);
1291 MockExclusiveLock mock_exclusive_lock
;
1292 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1293 expect_accept_ops(mock_exclusive_lock
, true);
1295 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1296 expect_op_work_queue(mock_image_ctx
);
1299 Context
*on_finish
= nullptr;
1300 expect_refresh_image(mock_image_ctx
, false, 0);
1301 expect_snap_unprotect(mock_image_ctx
, &on_finish
, "snap");
1303 C_SaferCond on_start_ready
;
1304 C_SaferCond on_start_safe
;
1305 when_process(mock_journal_replay
,
1306 EventEntry
{SnapUnprotectEvent(123,
1307 cls::rbd::UserSnapshotNamespace(),
1311 ASSERT_EQ(0, on_start_ready
.wait());
1313 C_SaferCond on_finish_ready
;
1314 C_SaferCond on_finish_safe
;
1315 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1316 &on_finish_ready
, &on_finish_safe
);
1318 wait_for_op_invoked(&on_finish
, -EINVAL
);
1319 ASSERT_EQ(0, on_start_safe
.wait());
1320 ASSERT_EQ(0, on_finish_ready
.wait());
1321 ASSERT_EQ(0, on_finish_safe
.wait());
1324 TEST_F(TestMockJournalReplay
, SnapRollbackEvent
) {
1325 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1327 librbd::ImageCtx
*ictx
;
1328 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1330 MockReplayImageCtx
mock_image_ctx(*ictx
);
1332 MockExclusiveLock mock_exclusive_lock
;
1333 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1334 expect_accept_ops(mock_exclusive_lock
, true);
1336 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1337 expect_op_work_queue(mock_image_ctx
);
1340 Context
*on_finish
= nullptr;
1341 expect_refresh_image(mock_image_ctx
, false, 0);
1342 expect_snap_rollback(mock_image_ctx
, &on_finish
, "snap");
1344 C_SaferCond on_start_ready
;
1345 C_SaferCond on_start_safe
;
1346 when_process(mock_journal_replay
,
1347 EventEntry
{SnapRollbackEvent(123,
1348 cls::rbd::UserSnapshotNamespace(),
1352 ASSERT_EQ(0, on_start_ready
.wait());
1354 C_SaferCond on_finish_ready
;
1355 C_SaferCond on_finish_safe
;
1356 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1357 &on_finish_ready
, &on_finish_safe
);
1359 wait_for_op_invoked(&on_finish
, 0);
1360 ASSERT_EQ(0, on_start_safe
.wait());
1361 ASSERT_EQ(0, on_finish_ready
.wait());
1362 ASSERT_EQ(0, on_finish_safe
.wait());
1365 TEST_F(TestMockJournalReplay
, RenameEvent
) {
1366 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1368 librbd::ImageCtx
*ictx
;
1369 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1371 MockReplayImageCtx
mock_image_ctx(*ictx
);
1373 MockExclusiveLock mock_exclusive_lock
;
1374 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1375 expect_accept_ops(mock_exclusive_lock
, true);
1377 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1378 expect_op_work_queue(mock_image_ctx
);
1381 Context
*on_finish
= nullptr;
1382 expect_refresh_image(mock_image_ctx
, false, 0);
1383 expect_rename(mock_image_ctx
, &on_finish
, "image");
1385 C_SaferCond on_start_ready
;
1386 C_SaferCond on_start_safe
;
1387 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
1388 &on_start_ready
, &on_start_safe
);
1389 ASSERT_EQ(0, on_start_ready
.wait());
1391 C_SaferCond on_finish_ready
;
1392 C_SaferCond on_finish_safe
;
1393 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1394 &on_finish_ready
, &on_finish_safe
);
1396 wait_for_op_invoked(&on_finish
, 0);
1397 ASSERT_EQ(0, on_start_safe
.wait());
1398 ASSERT_EQ(0, on_finish_ready
.wait());
1399 ASSERT_EQ(0, on_finish_safe
.wait());
1402 TEST_F(TestMockJournalReplay
, RenameEventExists
) {
1403 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1405 librbd::ImageCtx
*ictx
;
1406 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1408 MockReplayImageCtx
mock_image_ctx(*ictx
);
1410 MockExclusiveLock mock_exclusive_lock
;
1411 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1412 expect_accept_ops(mock_exclusive_lock
, true);
1414 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1415 expect_op_work_queue(mock_image_ctx
);
1418 Context
*on_finish
= nullptr;
1419 expect_refresh_image(mock_image_ctx
, false, 0);
1420 expect_rename(mock_image_ctx
, &on_finish
, "image");
1422 C_SaferCond on_start_ready
;
1423 C_SaferCond on_start_safe
;
1424 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
1425 &on_start_ready
, &on_start_safe
);
1426 ASSERT_EQ(0, on_start_ready
.wait());
1428 C_SaferCond on_finish_ready
;
1429 C_SaferCond on_finish_safe
;
1430 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1431 &on_finish_ready
, &on_finish_safe
);
1433 wait_for_op_invoked(&on_finish
, -EEXIST
);
1434 ASSERT_EQ(0, on_start_safe
.wait());
1435 ASSERT_EQ(0, on_finish_ready
.wait());
1436 ASSERT_EQ(0, on_finish_safe
.wait());
1439 TEST_F(TestMockJournalReplay
, ResizeEvent
) {
1440 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1442 librbd::ImageCtx
*ictx
;
1443 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1445 MockReplayImageCtx
mock_image_ctx(*ictx
);
1447 MockExclusiveLock mock_exclusive_lock
;
1448 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1449 expect_accept_ops(mock_exclusive_lock
, true);
1451 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1452 expect_op_work_queue(mock_image_ctx
);
1455 Context
*on_finish
= nullptr;
1456 expect_refresh_image(mock_image_ctx
, false, 0);
1457 expect_resize(mock_image_ctx
, &on_finish
, 234, 123);
1459 C_SaferCond on_start_ready
;
1460 C_SaferCond on_start_safe
;
1461 when_process(mock_journal_replay
, EventEntry
{ResizeEvent(123, 234)},
1462 &on_start_ready
, &on_start_safe
);
1464 C_SaferCond on_resume
;
1465 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
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 ASSERT_EQ(0, on_resume
.wait());
1474 wait_for_op_invoked(&on_finish
, 0);
1476 ASSERT_EQ(0, on_start_safe
.wait());
1477 ASSERT_EQ(0, on_finish_ready
.wait());
1478 ASSERT_EQ(0, on_finish_safe
.wait());
1481 TEST_F(TestMockJournalReplay
, FlattenEvent
) {
1482 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1484 librbd::ImageCtx
*ictx
;
1485 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1487 MockReplayImageCtx
mock_image_ctx(*ictx
);
1489 MockExclusiveLock mock_exclusive_lock
;
1490 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1491 expect_accept_ops(mock_exclusive_lock
, true);
1493 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1494 expect_op_work_queue(mock_image_ctx
);
1497 Context
*on_finish
= nullptr;
1498 expect_refresh_image(mock_image_ctx
, false, 0);
1499 expect_flatten(mock_image_ctx
, &on_finish
);
1501 C_SaferCond on_start_ready
;
1502 C_SaferCond on_start_safe
;
1503 when_process(mock_journal_replay
, EventEntry
{FlattenEvent(123)},
1504 &on_start_ready
, &on_start_safe
);
1505 ASSERT_EQ(0, on_start_ready
.wait());
1507 C_SaferCond on_finish_ready
;
1508 C_SaferCond on_finish_safe
;
1509 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1510 &on_finish_ready
, &on_finish_safe
);
1512 wait_for_op_invoked(&on_finish
, 0);
1513 ASSERT_EQ(0, on_start_safe
.wait());
1514 ASSERT_EQ(0, on_finish_ready
.wait());
1515 ASSERT_EQ(0, on_finish_safe
.wait());
1518 TEST_F(TestMockJournalReplay
, FlattenEventInvalid
) {
1519 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1521 librbd::ImageCtx
*ictx
;
1522 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1524 MockReplayImageCtx
mock_image_ctx(*ictx
);
1526 MockExclusiveLock mock_exclusive_lock
;
1527 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1528 expect_accept_ops(mock_exclusive_lock
, true);
1530 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1531 expect_op_work_queue(mock_image_ctx
);
1534 Context
*on_finish
= nullptr;
1535 expect_refresh_image(mock_image_ctx
, false, 0);
1536 expect_flatten(mock_image_ctx
, &on_finish
);
1538 C_SaferCond on_start_ready
;
1539 C_SaferCond on_start_safe
;
1540 when_process(mock_journal_replay
, EventEntry
{FlattenEvent(123)},
1541 &on_start_ready
, &on_start_safe
);
1542 ASSERT_EQ(0, on_start_ready
.wait());
1544 C_SaferCond on_finish_ready
;
1545 C_SaferCond on_finish_safe
;
1546 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1547 &on_finish_ready
, &on_finish_safe
);
1549 wait_for_op_invoked(&on_finish
, -EINVAL
);
1550 ASSERT_EQ(0, on_start_safe
.wait());
1551 ASSERT_EQ(0, on_finish_ready
.wait());
1552 ASSERT_EQ(0, on_finish_safe
.wait());
1555 TEST_F(TestMockJournalReplay
, UpdateFeaturesEvent
) {
1556 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1558 librbd::ImageCtx
*ictx
;
1559 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1561 uint64_t features
= RBD_FEATURE_OBJECT_MAP
| RBD_FEATURE_FAST_DIFF
;
1562 bool enabled
= !ictx
->test_features(features
);
1564 MockReplayImageCtx
mock_image_ctx(*ictx
);
1566 MockExclusiveLock mock_exclusive_lock
;
1567 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1568 expect_accept_ops(mock_exclusive_lock
, true);
1570 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1571 expect_op_work_queue(mock_image_ctx
);
1574 Context
*on_finish
= nullptr;
1575 expect_refresh_image(mock_image_ctx
, false, 0);
1576 expect_update_features(mock_image_ctx
, &on_finish
, features
, enabled
, 123);
1578 C_SaferCond on_start_ready
;
1579 C_SaferCond on_start_safe
;
1580 when_process(mock_journal_replay
,
1581 EventEntry
{UpdateFeaturesEvent(123, features
, enabled
)},
1582 &on_start_ready
, &on_start_safe
);
1584 C_SaferCond on_resume
;
1585 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
1586 ASSERT_EQ(0, on_start_ready
.wait());
1588 C_SaferCond on_finish_ready
;
1589 C_SaferCond on_finish_safe
;
1590 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1591 &on_finish_ready
, &on_finish_safe
);
1593 ASSERT_EQ(0, on_resume
.wait());
1594 wait_for_op_invoked(&on_finish
, 0);
1596 ASSERT_EQ(0, on_start_safe
.wait());
1597 ASSERT_EQ(0, on_finish_ready
.wait());
1598 ASSERT_EQ(0, on_finish_safe
.wait());
1601 TEST_F(TestMockJournalReplay
, MetadataSetEvent
) {
1602 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1604 librbd::ImageCtx
*ictx
;
1605 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1607 MockReplayImageCtx
mock_image_ctx(*ictx
);
1609 MockExclusiveLock mock_exclusive_lock
;
1610 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1611 expect_accept_ops(mock_exclusive_lock
, true);
1613 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1614 expect_op_work_queue(mock_image_ctx
);
1617 Context
*on_finish
= nullptr;
1618 expect_refresh_image(mock_image_ctx
, false, 0);
1619 expect_metadata_set(mock_image_ctx
, &on_finish
, "key", "value");
1621 C_SaferCond on_start_ready
;
1622 C_SaferCond on_start_safe
;
1623 when_process(mock_journal_replay
, EventEntry
{MetadataSetEvent(123, "key", "value")},
1624 &on_start_ready
, &on_start_safe
);
1625 ASSERT_EQ(0, on_start_ready
.wait());
1627 C_SaferCond on_finish_ready
;
1628 C_SaferCond on_finish_safe
;
1629 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1630 &on_finish_ready
, &on_finish_safe
);
1632 wait_for_op_invoked(&on_finish
, 0);
1633 ASSERT_EQ(0, on_start_safe
.wait());
1634 ASSERT_EQ(0, on_finish_ready
.wait());
1635 ASSERT_EQ(0, on_finish_safe
.wait());
1638 TEST_F(TestMockJournalReplay
, MetadataRemoveEvent
) {
1639 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1641 librbd::ImageCtx
*ictx
;
1642 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1644 MockReplayImageCtx
mock_image_ctx(*ictx
);
1646 MockExclusiveLock mock_exclusive_lock
;
1647 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1648 expect_accept_ops(mock_exclusive_lock
, true);
1650 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1651 expect_op_work_queue(mock_image_ctx
);
1654 Context
*on_finish
= nullptr;
1655 expect_refresh_image(mock_image_ctx
, false, 0);
1656 expect_metadata_remove(mock_image_ctx
, &on_finish
, "key");
1658 C_SaferCond on_start_ready
;
1659 C_SaferCond on_start_safe
;
1660 when_process(mock_journal_replay
, EventEntry
{MetadataRemoveEvent(123, "key")},
1661 &on_start_ready
, &on_start_safe
);
1662 ASSERT_EQ(0, on_start_ready
.wait());
1664 C_SaferCond on_finish_ready
;
1665 C_SaferCond on_finish_safe
;
1666 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1667 &on_finish_ready
, &on_finish_safe
);
1669 wait_for_op_invoked(&on_finish
, 0);
1670 ASSERT_EQ(0, on_start_safe
.wait());
1671 ASSERT_EQ(0, on_finish_ready
.wait());
1672 ASSERT_EQ(0, on_finish_safe
.wait());
1675 TEST_F(TestMockJournalReplay
, MetadataRemoveEventDNE
) {
1676 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1678 librbd::ImageCtx
*ictx
;
1679 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1681 MockReplayImageCtx
mock_image_ctx(*ictx
);
1683 MockExclusiveLock mock_exclusive_lock
;
1684 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1685 expect_accept_ops(mock_exclusive_lock
, true);
1687 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1688 expect_op_work_queue(mock_image_ctx
);
1691 Context
*on_finish
= nullptr;
1692 expect_refresh_image(mock_image_ctx
, false, 0);
1693 expect_metadata_remove(mock_image_ctx
, &on_finish
, "key");
1695 C_SaferCond on_start_ready
;
1696 C_SaferCond on_start_safe
;
1697 when_process(mock_journal_replay
, EventEntry
{MetadataRemoveEvent(123, "key")},
1698 &on_start_ready
, &on_start_safe
);
1699 ASSERT_EQ(0, on_start_ready
.wait());
1701 C_SaferCond on_finish_ready
;
1702 C_SaferCond on_finish_safe
;
1703 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1704 &on_finish_ready
, &on_finish_safe
);
1706 wait_for_op_invoked(&on_finish
, -ENOENT
);
1707 ASSERT_EQ(0, on_start_safe
.wait());
1708 ASSERT_EQ(0, on_finish_ready
.wait());
1709 ASSERT_EQ(0, on_finish_safe
.wait());
1712 TEST_F(TestMockJournalReplay
, UnknownEvent
) {
1713 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1715 librbd::ImageCtx
*ictx
;
1716 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1718 MockReplayImageCtx
mock_image_ctx(*ictx
);
1720 MockExclusiveLock mock_exclusive_lock
;
1721 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1722 expect_accept_ops(mock_exclusive_lock
, true);
1724 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1725 expect_op_work_queue(mock_image_ctx
);
1730 ENCODE_START(1, 1, bl
);
1731 ::encode(static_cast<uint32_t>(-1), bl
);
1734 bufferlist::iterator it
= bl
.begin();
1735 C_SaferCond on_ready
;
1736 C_SaferCond on_safe
;
1737 when_process(mock_journal_replay
, &it
, &on_ready
, &on_safe
);
1739 ASSERT_EQ(0, on_safe
.wait());
1740 ASSERT_EQ(0, on_ready
.wait());
1743 TEST_F(TestMockJournalReplay
, RefreshImageBeforeOpStart
) {
1744 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1746 librbd::ImageCtx
*ictx
;
1747 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1749 MockReplayImageCtx
mock_image_ctx(*ictx
);
1751 MockExclusiveLock mock_exclusive_lock
;
1752 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1753 expect_accept_ops(mock_exclusive_lock
, true);
1755 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1756 expect_op_work_queue(mock_image_ctx
);
1759 Context
*on_finish
= nullptr;
1760 expect_refresh_image(mock_image_ctx
, true, 0);
1761 expect_resize(mock_image_ctx
, &on_finish
, 234, 123);
1763 C_SaferCond on_start_ready
;
1764 C_SaferCond on_start_safe
;
1765 when_process(mock_journal_replay
, EventEntry
{ResizeEvent(123, 234)},
1766 &on_start_ready
, &on_start_safe
);
1768 C_SaferCond on_resume
;
1769 when_replay_op_ready(mock_journal_replay
, 123, &on_resume
);
1770 ASSERT_EQ(0, on_start_ready
.wait());
1772 C_SaferCond on_finish_ready
;
1773 C_SaferCond on_finish_safe
;
1774 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1775 &on_finish_ready
, &on_finish_safe
);
1777 ASSERT_EQ(0, on_resume
.wait());
1778 wait_for_op_invoked(&on_finish
, 0);
1780 ASSERT_EQ(0, on_start_safe
.wait());
1781 ASSERT_EQ(0, on_finish_ready
.wait());
1782 ASSERT_EQ(0, on_finish_safe
.wait());
1785 TEST_F(TestMockJournalReplay
, FlushEventAfterShutDown
) {
1786 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1788 librbd::ImageCtx
*ictx
;
1789 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1791 MockReplayImageCtx
mock_image_ctx(*ictx
);
1793 MockExclusiveLock mock_exclusive_lock
;
1794 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1795 expect_accept_ops(mock_exclusive_lock
, true);
1797 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1798 MockIoImageRequest mock_io_image_request
;
1799 expect_op_work_queue(mock_image_ctx
);
1801 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1803 C_SaferCond on_ready
;
1804 C_SaferCond on_safe
;
1805 when_process(mock_journal_replay
, EventEntry
{AioFlushEvent()},
1806 &on_ready
, &on_safe
);
1807 ASSERT_EQ(0, on_ready
.wait());
1808 ASSERT_EQ(-ESHUTDOWN
, on_safe
.wait());
1811 TEST_F(TestMockJournalReplay
, ModifyEventAfterShutDown
) {
1812 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1814 librbd::ImageCtx
*ictx
;
1815 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1817 MockReplayImageCtx
mock_image_ctx(*ictx
);
1819 MockExclusiveLock mock_exclusive_lock
;
1820 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1821 expect_accept_ops(mock_exclusive_lock
, true);
1823 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1824 MockIoImageRequest mock_io_image_request
;
1825 expect_op_work_queue(mock_image_ctx
);
1827 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1829 C_SaferCond on_ready
;
1830 C_SaferCond on_safe
;
1831 when_process(mock_journal_replay
,
1832 EventEntry
{AioWriteEvent(123, 456, to_bl("test"))},
1833 &on_ready
, &on_safe
);
1834 ASSERT_EQ(0, on_ready
.wait());
1835 ASSERT_EQ(-ESHUTDOWN
, on_safe
.wait());
1838 TEST_F(TestMockJournalReplay
, OpEventAfterShutDown
) {
1839 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1841 librbd::ImageCtx
*ictx
;
1842 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1844 MockReplayImageCtx
mock_image_ctx(*ictx
);
1846 MockExclusiveLock mock_exclusive_lock
;
1847 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1848 expect_accept_ops(mock_exclusive_lock
, true);
1850 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1851 MockIoImageRequest mock_io_image_request
;
1852 expect_op_work_queue(mock_image_ctx
);
1854 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1856 C_SaferCond on_ready
;
1857 C_SaferCond on_safe
;
1858 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
1859 &on_ready
, &on_safe
);
1860 ASSERT_EQ(0, on_ready
.wait());
1861 ASSERT_EQ(-ESHUTDOWN
, on_safe
.wait());
1864 TEST_F(TestMockJournalReplay
, LockLostBeforeProcess
) {
1865 REQUIRE_FEATURE(RBD_FEATURE_JOURNALING
);
1867 librbd::ImageCtx
*ictx
;
1868 ASSERT_EQ(0, open_image(m_image_name
, &ictx
));
1870 MockReplayImageCtx
mock_image_ctx(*ictx
);
1872 MockExclusiveLock mock_exclusive_lock
;
1873 mock_image_ctx
.exclusive_lock
= &mock_exclusive_lock
;
1874 expect_accept_ops(mock_exclusive_lock
, false);
1876 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1877 MockIoImageRequest mock_io_image_request
;
1878 expect_op_work_queue(mock_image_ctx
);
1881 C_SaferCond on_ready
;
1882 C_SaferCond on_safe
;
1883 when_process(mock_journal_replay
, EventEntry
{AioFlushEvent()},
1884 &on_ready
, &on_safe
);
1885 ASSERT_EQ(0, on_ready
.wait());
1886 ASSERT_EQ(-ECANCELED
, on_safe
.wait());
1888 ASSERT_EQ(0, when_shut_down(mock_journal_replay
, false));
1891 TEST_F(TestMockJournalReplay
, LockLostBeforeExecuteOp
) {
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
, false);
1903 MockJournalReplay
mock_journal_replay(mock_image_ctx
);
1904 expect_op_work_queue(mock_image_ctx
);
1907 EXPECT_CALL(mock_exclusive_lock
, accept_ops()).WillOnce(Return(true));
1908 EXPECT_CALL(mock_exclusive_lock
, accept_ops()).WillOnce(Return(true));
1909 expect_refresh_image(mock_image_ctx
, false, 0);
1911 C_SaferCond on_start_ready
;
1912 C_SaferCond on_start_safe
;
1913 when_process(mock_journal_replay
, EventEntry
{RenameEvent(123, "image")},
1914 &on_start_ready
, &on_start_safe
);
1915 ASSERT_EQ(0, on_start_ready
.wait());
1917 C_SaferCond on_finish_ready
;
1918 C_SaferCond on_finish_safe
;
1919 when_process(mock_journal_replay
, EventEntry
{OpFinishEvent(123, 0)},
1920 &on_finish_ready
, &on_finish_safe
);
1922 ASSERT_EQ(-ECANCELED
, on_start_safe
.wait());
1923 ASSERT_EQ(0, on_finish_ready
.wait());
1924 ASSERT_EQ(-ECANCELED
, on_finish_safe
.wait());
1927 } // namespace journal
1928 } // namespace librbd