1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "cls/journal/cls_journal_types.h"
5 #include "librbd/journal/Replay.h"
6 #include "librbd/journal/Types.h"
7 #include "tools/rbd_mirror/ImageDeleter.h"
8 #include "tools/rbd_mirror/ImageReplayer.h"
9 #include "tools/rbd_mirror/InstanceWatcher.h"
10 #include "tools/rbd_mirror/Threads.h"
11 #include "tools/rbd_mirror/image_replayer/BootstrapRequest.h"
12 #include "tools/rbd_mirror/image_replayer/CloseImageRequest.h"
13 #include "tools/rbd_mirror/image_replayer/EventPreprocessor.h"
14 #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.h"
15 #include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h"
16 #include "test/rbd_mirror/test_mock_fixture.h"
17 #include "test/journal/mock/MockJournaler.h"
18 #include "test/librbd/mock/MockImageCtx.h"
19 #include "test/librbd/mock/MockJournal.h"
20 #include "test/rbd_mirror/mock/MockContextWQ.h"
21 #include "test/rbd_mirror/mock/MockSafeTimer.h"
27 struct MockTestJournal
;
29 struct MockTestImageCtx
: public MockImageCtx
{
30 MockTestImageCtx(librbd::ImageCtx
&image_ctx
)
31 : librbd::MockImageCtx(image_ctx
) {
33 MockTestJournal
*journal
= nullptr;
36 struct MockTestJournal
: public MockJournal
{
37 MOCK_METHOD2(start_external_replay
, void(journal::Replay
<MockTestImageCtx
> **,
39 MOCK_METHOD0(stop_external_replay
, void());
42 } // anonymous namespace
47 struct Replay
<MockTestImageCtx
> {
48 MOCK_METHOD2(decode
, int(bufferlist::iterator
*, EventEntry
*));
49 MOCK_METHOD3(process
, void(const EventEntry
&, Context
*, Context
*));
50 MOCK_METHOD1(flush
, void(Context
*));
51 MOCK_METHOD2(shut_down
, void(bool, Context
*));
55 struct TypeTraits
<MockTestImageCtx
> {
56 typedef ::journal::MockJournalerProxy Journaler
;
57 typedef ::journal::MockReplayEntryProxy ReplayEntry
;
60 struct MirrorPeerClientMeta
;
62 } // namespace journal
69 struct Threads
<librbd::MockTestImageCtx
> {
73 MockContextWQ
*work_queue
;
75 Threads(Threads
<librbd::ImageCtx
> *threads
)
76 : timer(new MockSafeTimer()),
77 timer_lock(threads
->timer_lock
),
78 work_queue(new MockContextWQ()) {
87 struct ImageDeleter
<librbd::MockTestImageCtx
> {
88 MOCK_METHOD4(schedule_image_delete
, void(RadosRef
, int64_t,
89 const std::string
&, bool));
90 MOCK_METHOD4(wait_for_scheduled_deletion
,
91 void(int64_t, const std::string
&, Context
*, bool));
92 MOCK_METHOD2(cancel_waiter
, void(int64_t, const std::string
&));
96 class InstanceWatcher
<librbd::MockTestImageCtx
> {
99 namespace image_replayer
{
102 using ::testing::AtLeast
;
103 using ::testing::DoAll
;
104 using ::testing::InSequence
;
105 using ::testing::Invoke
;
106 using ::testing::MatcherCast
;
107 using ::testing::Return
;
108 using ::testing::ReturnArg
;
109 using ::testing::SetArgPointee
;
110 using ::testing::WithArg
;
113 struct PrepareLocalImageRequest
<librbd::MockTestImageCtx
> {
114 static PrepareLocalImageRequest
* s_instance
;
115 std::string
*local_image_id
= nullptr;
116 std::string
*local_image_name
= nullptr;
117 std::string
*tag_owner
= nullptr;
118 Context
*on_finish
= nullptr;
120 static PrepareLocalImageRequest
* create(librados::IoCtx
&,
121 const std::string
&global_image_id
,
122 std::string
*local_image_id
,
123 std::string
*local_image_name
,
124 std::string
*tag_owner
,
125 MockContextWQ
*work_queue
,
126 Context
*on_finish
) {
127 assert(s_instance
!= nullptr);
128 s_instance
->local_image_id
= local_image_id
;
129 s_instance
->local_image_name
= local_image_name
;
130 s_instance
->tag_owner
= tag_owner
;
131 s_instance
->on_finish
= on_finish
;
135 PrepareLocalImageRequest() {
139 MOCK_METHOD0(send
, void());
143 struct PrepareRemoteImageRequest
<librbd::MockTestImageCtx
> {
144 static PrepareRemoteImageRequest
* s_instance
;
145 std::string
*remote_mirror_uuid
= nullptr;
146 std::string
*remote_image_id
= nullptr;
147 cls::journal::ClientState
*client_state
;
148 ::journal::MockJournalerProxy
**remote_journaler
= nullptr;
149 librbd::journal::MirrorPeerClientMeta
*client_meta
= nullptr;
150 Context
*on_finish
= nullptr;
152 static PrepareRemoteImageRequest
* create(Threads
<librbd::MockTestImageCtx
> *threads
,
154 const std::string
&global_image_id
,
155 const std::string
&local_mirror_uuid
,
156 const std::string
&local_image_id
,
157 std::string
*remote_mirror_uuid
,
158 std::string
*remote_image_id
,
159 ::journal::MockJournalerProxy
**remote_journaler
,
160 cls::journal::ClientState
*client_state
,
161 librbd::journal::MirrorPeerClientMeta
*client_meta
,
162 Context
*on_finish
) {
163 assert(s_instance
!= nullptr);
164 s_instance
->remote_mirror_uuid
= remote_mirror_uuid
;
165 s_instance
->remote_image_id
= remote_image_id
;
166 s_instance
->remote_journaler
= remote_journaler
;
167 s_instance
->client_state
= client_state
;
168 s_instance
->client_meta
= client_meta
;
169 s_instance
->on_finish
= on_finish
;
173 PrepareRemoteImageRequest() {
177 MOCK_METHOD0(send
, void());
181 struct BootstrapRequest
<librbd::MockTestImageCtx
> {
182 static BootstrapRequest
* s_instance
;
183 librbd::MockTestImageCtx
**image_ctx
= nullptr;
184 Context
*on_finish
= nullptr;
185 bool *do_resync
= nullptr;
187 static BootstrapRequest
* create(
188 librados::IoCtx
&local_io_ctx
, librados::IoCtx
&remote_io_ctx
,
189 rbd::mirror::InstanceWatcher
<librbd::MockTestImageCtx
> *instance_watcher
,
190 librbd::MockTestImageCtx
**local_image_ctx
,
191 const std::string
&local_image_name
, const std::string
&remote_image_id
,
192 const std::string
&global_image_id
, MockContextWQ
*work_queue
,
193 MockSafeTimer
*timer
, Mutex
*timer_lock
,
194 const std::string
&local_mirror_uuid
,
195 const std::string
&remote_mirror_uuid
,
196 ::journal::MockJournalerProxy
*journaler
,
197 cls::journal::ClientState
*client_state
,
198 librbd::journal::MirrorPeerClientMeta
*client_meta
,
199 Context
*on_finish
, bool *do_resync
,
200 rbd::mirror::ProgressContext
*progress_ctx
= nullptr) {
201 assert(s_instance
!= nullptr);
202 s_instance
->image_ctx
= local_image_ctx
;
203 s_instance
->on_finish
= on_finish
;
204 s_instance
->do_resync
= do_resync
;
209 assert(s_instance
== nullptr);
213 ~BootstrapRequest() {
214 assert(s_instance
== this);
215 s_instance
= nullptr;
224 inline bool is_syncing() const {
228 MOCK_METHOD0(send
, void());
229 MOCK_METHOD0(cancel
, void());
233 struct CloseImageRequest
<librbd::MockTestImageCtx
> {
234 static CloseImageRequest
* s_instance
;
235 librbd::MockTestImageCtx
**image_ctx
= nullptr;
236 Context
*on_finish
= nullptr;
238 static CloseImageRequest
* create(librbd::MockTestImageCtx
**image_ctx
,
239 Context
*on_finish
) {
240 assert(s_instance
!= nullptr);
241 s_instance
->image_ctx
= image_ctx
;
242 s_instance
->on_finish
= on_finish
;
246 CloseImageRequest() {
247 assert(s_instance
== nullptr);
251 ~CloseImageRequest() {
252 assert(s_instance
== this);
253 s_instance
= nullptr;
256 MOCK_METHOD0(send
, void());
260 struct EventPreprocessor
<librbd::MockTestImageCtx
> {
261 static EventPreprocessor
*s_instance
;
263 static EventPreprocessor
*create(librbd::MockTestImageCtx
&local_image_ctx
,
264 ::journal::MockJournalerProxy
&remote_journaler
,
265 const std::string
&local_mirror_uuid
,
266 librbd::journal::MirrorPeerClientMeta
*client_meta
,
267 MockContextWQ
*work_queue
) {
268 assert(s_instance
!= nullptr);
272 static void destroy(EventPreprocessor
* processor
) {
275 EventPreprocessor() {
276 assert(s_instance
== nullptr);
280 ~EventPreprocessor() {
281 assert(s_instance
== this);
282 s_instance
= nullptr;
285 MOCK_METHOD1(is_required
, bool(const librbd::journal::EventEntry
&));
286 MOCK_METHOD2(preprocess
, void(librbd::journal::EventEntry
*, Context
*));
290 struct ReplayStatusFormatter
<librbd::MockTestImageCtx
> {
291 static ReplayStatusFormatter
* s_instance
;
293 static ReplayStatusFormatter
* create(::journal::MockJournalerProxy
*journaler
,
294 const std::string
&mirror_uuid
) {
295 assert(s_instance
!= nullptr);
299 static void destroy(ReplayStatusFormatter
* formatter
) {
302 ReplayStatusFormatter() {
303 assert(s_instance
== nullptr);
307 ~ReplayStatusFormatter() {
308 assert(s_instance
== this);
309 s_instance
= nullptr;
312 MOCK_METHOD2(get_or_send_update
, bool(std::string
*description
, Context
*on_finish
));
315 BootstrapRequest
<librbd::MockTestImageCtx
>* BootstrapRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
316 CloseImageRequest
<librbd::MockTestImageCtx
>* CloseImageRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
317 EventPreprocessor
<librbd::MockTestImageCtx
>* EventPreprocessor
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
318 PrepareLocalImageRequest
<librbd::MockTestImageCtx
>* PrepareLocalImageRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
319 PrepareRemoteImageRequest
<librbd::MockTestImageCtx
>* PrepareRemoteImageRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
320 ReplayStatusFormatter
<librbd::MockTestImageCtx
>* ReplayStatusFormatter
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
322 } // namespace image_replayer
323 } // namespace mirror
326 // template definitions
327 #include "tools/rbd_mirror/ImageReplayer.cc"
332 class TestMockImageReplayer
: public TestMockFixture
{
334 typedef Threads
<librbd::MockTestImageCtx
> MockThreads
;
335 typedef ImageDeleter
<librbd::MockTestImageCtx
> MockImageDeleter
;
336 typedef BootstrapRequest
<librbd::MockTestImageCtx
> MockBootstrapRequest
;
337 typedef CloseImageRequest
<librbd::MockTestImageCtx
> MockCloseImageRequest
;
338 typedef EventPreprocessor
<librbd::MockTestImageCtx
> MockEventPreprocessor
;
339 typedef PrepareLocalImageRequest
<librbd::MockTestImageCtx
> MockPrepareLocalImageRequest
;
340 typedef PrepareRemoteImageRequest
<librbd::MockTestImageCtx
> MockPrepareRemoteImageRequest
;
341 typedef ReplayStatusFormatter
<librbd::MockTestImageCtx
> MockReplayStatusFormatter
;
342 typedef librbd::journal::Replay
<librbd::MockTestImageCtx
> MockReplay
;
343 typedef ImageReplayer
<librbd::MockTestImageCtx
> MockImageReplayer
;
344 typedef InstanceWatcher
<librbd::MockTestImageCtx
> MockInstanceWatcher
;
346 void SetUp() override
{
347 TestMockFixture::SetUp();
350 ASSERT_EQ(0, create_image(rbd
, m_remote_io_ctx
, m_image_name
, m_image_size
));
351 ASSERT_EQ(0, open_image(m_remote_io_ctx
, m_image_name
, &m_remote_image_ctx
));
354 void TearDown() override
{
355 delete m_image_replayer
;
357 TestMockFixture::TearDown();
360 void create_local_image() {
362 ASSERT_EQ(0, create_image(rbd
, m_local_io_ctx
, m_image_name
, m_image_size
));
363 ASSERT_EQ(0, open_image(m_local_io_ctx
, m_image_name
, &m_local_image_ctx
));
366 void expect_work_queue_repeatedly(MockThreads
&mock_threads
) {
367 EXPECT_CALL(*mock_threads
.work_queue
, queue(_
, _
))
368 .WillRepeatedly(Invoke([this](Context
*ctx
, int r
) {
369 m_threads
->work_queue
->queue(ctx
, r
);
373 void expect_add_event_after_repeatedly(MockThreads
&mock_threads
) {
374 EXPECT_CALL(*mock_threads
.timer
, add_event_after(_
, _
))
376 DoAll(Invoke([this](double seconds
, Context
*ctx
) {
377 m_threads
->timer
->add_event_after(seconds
, ctx
);
380 EXPECT_CALL(*mock_threads
.timer
, cancel_event(_
))
382 Invoke([this](Context
*ctx
) {
383 return m_threads
->timer
->cancel_event(ctx
);
387 void expect_wait_for_scheduled_deletion(MockImageDeleter
& mock_image_deleter
,
388 const std::string
& global_image_id
,
390 EXPECT_CALL(mock_image_deleter
,
391 wait_for_scheduled_deletion(_
, global_image_id
, _
, false))
392 .WillOnce(WithArg
<2>(Invoke([this, r
](Context
*ctx
) {
393 m_threads
->work_queue
->queue(ctx
, r
);
397 void expect_cancel_waiter(MockImageDeleter
& mock_image_deleter
) {
398 EXPECT_CALL(mock_image_deleter
, cancel_waiter(m_local_io_ctx
.get_id(),
402 void expect_schedule_image_delete(MockImageDeleter
& mock_image_deleter
,
403 const std::string
& global_image_id
,
404 bool ignore_orphan
) {
405 EXPECT_CALL(mock_image_deleter
,
406 schedule_image_delete(_
, _
, global_image_id
, ignore_orphan
));
409 bufferlist
encode_tag_data(const librbd::journal::TagData
&tag_data
) {
411 ::encode(tag_data
, bl
);
415 void expect_get_or_send_update(
416 MockReplayStatusFormatter
&mock_replay_status_formatter
) {
417 EXPECT_CALL(mock_replay_status_formatter
, get_or_send_update(_
, _
))
418 .WillRepeatedly(DoAll(WithArg
<1>(CompleteContext(-EEXIST
)),
422 void expect_send(MockPrepareLocalImageRequest
&mock_request
,
423 const std::string
&local_image_id
,
424 const std::string
&local_image_name
,
425 const std::string
&tag_owner
,
427 EXPECT_CALL(mock_request
, send())
428 .WillOnce(Invoke([&mock_request
, local_image_id
, local_image_name
, tag_owner
, r
]() {
430 *mock_request
.local_image_id
= local_image_id
;
431 *mock_request
.local_image_name
= local_image_name
;
432 *mock_request
.tag_owner
= tag_owner
;
434 mock_request
.on_finish
->complete(r
);
438 void expect_send(MockPrepareRemoteImageRequest
& mock_request
,
439 const std::string
& mirror_uuid
, const std::string
& image_id
,
441 EXPECT_CALL(mock_request
, send())
442 .WillOnce(Invoke([&mock_request
, image_id
, mirror_uuid
, r
]() {
444 *mock_request
.remote_journaler
= new ::journal::MockJournalerProxy();
447 *mock_request
.remote_mirror_uuid
= mirror_uuid
;
448 *mock_request
.remote_image_id
= image_id
;
449 mock_request
.on_finish
->complete(r
);
453 void expect_send(MockBootstrapRequest
&mock_bootstrap_request
,
454 librbd::MockTestImageCtx
&mock_local_image_ctx
,
455 bool do_resync
, int r
) {
456 EXPECT_CALL(mock_bootstrap_request
, send())
457 .WillOnce(Invoke([&mock_bootstrap_request
, &mock_local_image_ctx
,
460 *mock_bootstrap_request
.image_ctx
= &mock_local_image_ctx
;
461 *mock_bootstrap_request
.do_resync
= do_resync
;
463 mock_bootstrap_request
.on_finish
->complete(r
);
467 void expect_start_external_replay(librbd::MockTestJournal
&mock_journal
,
468 MockReplay
*mock_replay
, int r
) {
469 EXPECT_CALL(mock_journal
, start_external_replay(_
, _
))
470 .WillOnce(DoAll(SetArgPointee
<0>(mock_replay
),
471 WithArg
<1>(CompleteContext(r
))));
474 void expect_init(::journal::MockJournaler
&mock_journaler
, int r
) {
475 EXPECT_CALL(mock_journaler
, init(_
))
476 .WillOnce(CompleteContext(r
));
479 void expect_get_cached_client(::journal::MockJournaler
&mock_journaler
,
481 librbd::journal::ImageClientMeta image_client_meta
;
482 image_client_meta
.tag_class
= 0;
484 librbd::journal::ClientData client_data
;
485 client_data
.client_meta
= image_client_meta
;
487 cls::journal::Client client
;
488 ::encode(client_data
, client
.data
);
490 EXPECT_CALL(mock_journaler
, get_cached_client("local_mirror_uuid", _
))
491 .WillOnce(DoAll(SetArgPointee
<1>(client
),
495 void expect_stop_replay(::journal::MockJournaler
&mock_journaler
, int r
) {
496 EXPECT_CALL(mock_journaler
, stop_replay(_
))
497 .WillOnce(CompleteContext(r
));
500 void expect_flush(MockReplay
&mock_replay
, int r
) {
501 EXPECT_CALL(mock_replay
, flush(_
)).WillOnce(CompleteContext(r
));
504 void expect_shut_down(MockReplay
&mock_replay
, bool cancel_ops
, int r
) {
505 EXPECT_CALL(mock_replay
, shut_down(cancel_ops
, _
))
506 .WillOnce(WithArg
<1>(CompleteContext(r
)));
509 void expect_shut_down(journal::MockJournaler
&mock_journaler
, int r
) {
510 EXPECT_CALL(mock_journaler
, shut_down(_
))
511 .WillOnce(CompleteContext(r
));
514 void expect_send(MockCloseImageRequest
&mock_close_image_request
, int r
) {
515 EXPECT_CALL(mock_close_image_request
, send())
516 .WillOnce(Invoke([&mock_close_image_request
, r
]() {
517 *mock_close_image_request
.image_ctx
= nullptr;
518 mock_close_image_request
.on_finish
->complete(r
);
522 void expect_get_commit_tid_in_debug(
523 ::journal::MockReplayEntry
&mock_replay_entry
) {
524 // It is used in debug messages and depends on debug level
525 EXPECT_CALL(mock_replay_entry
, get_commit_tid())
527 .WillRepeatedly(Return(0));
530 void expect_committed(::journal::MockJournaler
&mock_journaler
, int times
) {
531 EXPECT_CALL(mock_journaler
, committed(
532 MatcherCast
<const ::journal::MockReplayEntryProxy
&>(_
)))
536 void expect_try_pop_front(::journal::MockJournaler
&mock_journaler
,
537 uint64_t replay_tag_tid
, bool entries_available
) {
538 EXPECT_CALL(mock_journaler
, try_pop_front(_
, _
))
539 .WillOnce(DoAll(SetArgPointee
<0>(::journal::MockReplayEntryProxy()),
540 SetArgPointee
<1>(replay_tag_tid
),
541 Return(entries_available
)));
544 void expect_try_pop_front_return_no_entries(
545 ::journal::MockJournaler
&mock_journaler
, Context
*on_finish
) {
546 EXPECT_CALL(mock_journaler
, try_pop_front(_
, _
))
547 .WillOnce(DoAll(Invoke([on_finish
](::journal::MockReplayEntryProxy
*e
,
549 on_finish
->complete(0);
554 void expect_get_tag(::journal::MockJournaler
&mock_journaler
,
555 const cls::journal::Tag
&tag
, int r
) {
556 EXPECT_CALL(mock_journaler
, get_tag(_
, _
, _
))
557 .WillOnce(DoAll(SetArgPointee
<1>(tag
),
558 WithArg
<2>(CompleteContext(r
))));
561 void expect_allocate_tag(librbd::MockTestJournal
&mock_journal
, int r
) {
562 EXPECT_CALL(mock_journal
, allocate_tag(_
, _
, _
))
563 .WillOnce(WithArg
<2>(CompleteContext(r
)));
566 void expect_preprocess(MockEventPreprocessor
&mock_event_preprocessor
,
567 bool required
, int r
) {
568 EXPECT_CALL(mock_event_preprocessor
, is_required(_
))
569 .WillOnce(Return(required
));
571 EXPECT_CALL(mock_event_preprocessor
, preprocess(_
, _
))
572 .WillOnce(WithArg
<1>(CompleteContext(r
)));
576 void expect_process(MockReplay
&mock_replay
,
577 int on_ready_r
, int on_commit_r
) {
578 EXPECT_CALL(mock_replay
, process(_
, _
, _
))
579 .WillOnce(DoAll(WithArg
<1>(CompleteContext(on_ready_r
)),
580 WithArg
<2>(CompleteContext(on_commit_r
))));
583 void create_image_replayer(MockThreads
&mock_threads
,
584 MockImageDeleter
&mock_image_deleter
) {
585 m_image_replayer
= new MockImageReplayer(
586 &mock_threads
, &mock_image_deleter
, &m_instance_watcher
,
587 rbd::mirror::RadosRef(new librados::Rados(m_local_io_ctx
)),
588 "local_mirror_uuid", m_local_io_ctx
.get_id(), "global image id");
589 m_image_replayer
->add_peer("peer_uuid", m_remote_io_ctx
);
592 librbd::ImageCtx
*m_remote_image_ctx
;
593 librbd::ImageCtx
*m_local_image_ctx
= nullptr;
594 MockInstanceWatcher m_instance_watcher
;
595 MockImageReplayer
*m_image_replayer
= nullptr;
598 TEST_F(TestMockImageReplayer
, StartStop
) {
601 create_local_image();
602 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
604 librbd::MockTestJournal mock_local_journal
;
605 mock_local_image_ctx
.journal
= &mock_local_journal
;
607 journal::MockJournaler mock_remote_journaler
;
608 MockThreads
mock_threads(m_threads
);
609 expect_work_queue_repeatedly(mock_threads
);
610 expect_add_event_after_repeatedly(mock_threads
);
612 MockImageDeleter mock_image_deleter
;
613 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
614 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
615 MockBootstrapRequest mock_bootstrap_request
;
616 MockReplay mock_local_replay
;
617 MockEventPreprocessor mock_event_preprocessor
;
618 MockReplayStatusFormatter mock_replay_status_formatter
;
620 expect_get_or_send_update(mock_replay_status_formatter
);
623 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
624 expect_send(mock_prepare_local_image_request
, mock_local_image_ctx
.id
,
625 mock_local_image_ctx
.name
, "remote mirror uuid", 0);
626 expect_send(mock_prepare_remote_image_request
, "remote mirror uuid",
627 m_remote_image_ctx
->id
, 0);
628 EXPECT_CALL(mock_remote_journaler
, construct());
629 expect_send(mock_bootstrap_request
, mock_local_image_ctx
, false, 0);
631 EXPECT_CALL(mock_local_journal
, add_listener(_
));
633 expect_init(mock_remote_journaler
, 0);
635 EXPECT_CALL(mock_remote_journaler
, add_listener(_
));
636 expect_get_cached_client(mock_remote_journaler
, 0);
638 expect_start_external_replay(mock_local_journal
, &mock_local_replay
, 0);
640 EXPECT_CALL(mock_remote_journaler
, start_live_replay(_
, _
));
642 create_image_replayer(mock_threads
, mock_image_deleter
);
644 C_SaferCond start_ctx
;
645 m_image_replayer
->start(&start_ctx
);
646 ASSERT_EQ(0, start_ctx
.wait());
647 ASSERT_EQ(image_replayer::HEALTH_STATE_OK
,
648 m_image_replayer
->get_health_state());
652 MockCloseImageRequest mock_close_local_image_request
;
654 expect_cancel_waiter(mock_image_deleter
);
655 expect_shut_down(mock_local_replay
, true, 0);
656 EXPECT_CALL(mock_local_journal
, remove_listener(_
));
657 EXPECT_CALL(mock_local_journal
, stop_external_replay());
658 expect_send(mock_close_local_image_request
, 0);
660 expect_stop_replay(mock_remote_journaler
, 0);
661 EXPECT_CALL(mock_remote_journaler
, remove_listener(_
));
662 expect_shut_down(mock_remote_journaler
, 0);
664 C_SaferCond stop_ctx
;
665 m_image_replayer
->stop(&stop_ctx
);
666 ASSERT_EQ(0, stop_ctx
.wait());
667 ASSERT_EQ(image_replayer::HEALTH_STATE_OK
,
668 m_image_replayer
->get_health_state());
671 TEST_F(TestMockImageReplayer
, LocalImagePrimary
) {
672 create_local_image();
673 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
675 journal::MockJournaler mock_remote_journaler
;
676 MockThreads
mock_threads(m_threads
);
677 expect_work_queue_repeatedly(mock_threads
);
678 expect_add_event_after_repeatedly(mock_threads
);
680 MockImageDeleter mock_image_deleter
;
681 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
682 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
683 MockReplayStatusFormatter mock_replay_status_formatter
;
685 expect_get_or_send_update(mock_replay_status_formatter
);
688 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
689 expect_send(mock_prepare_local_image_request
, mock_local_image_ctx
.id
,
690 mock_local_image_ctx
.name
, "", 0);
691 expect_send(mock_prepare_remote_image_request
, "remote mirror uuid",
692 "remote image id", 0);
693 EXPECT_CALL(mock_remote_journaler
, construct());
694 EXPECT_CALL(mock_remote_journaler
, remove_listener(_
));
695 expect_shut_down(mock_remote_journaler
, 0);
697 create_image_replayer(mock_threads
, mock_image_deleter
);
699 C_SaferCond start_ctx
;
700 m_image_replayer
->start(&start_ctx
);
701 ASSERT_EQ(0, start_ctx
.wait());
704 TEST_F(TestMockImageReplayer
, LocalImageDNE
) {
705 create_local_image();
706 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
708 journal::MockJournaler mock_remote_journaler
;
709 MockThreads
mock_threads(m_threads
);
710 expect_work_queue_repeatedly(mock_threads
);
711 expect_add_event_after_repeatedly(mock_threads
);
713 MockImageDeleter mock_image_deleter
;
714 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
715 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
716 MockBootstrapRequest mock_bootstrap_request
;
717 MockReplayStatusFormatter mock_replay_status_formatter
;
719 expect_get_or_send_update(mock_replay_status_formatter
);
722 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
723 expect_send(mock_prepare_local_image_request
, "", "", "", -ENOENT
);
724 expect_send(mock_prepare_remote_image_request
, "remote mirror uuid",
725 m_remote_image_ctx
->id
, 0);
726 EXPECT_CALL(mock_remote_journaler
, construct());
727 expect_send(mock_bootstrap_request
, mock_local_image_ctx
, false, -EREMOTEIO
);
729 EXPECT_CALL(mock_remote_journaler
, remove_listener(_
));
730 expect_shut_down(mock_remote_journaler
, 0);
732 create_image_replayer(mock_threads
, mock_image_deleter
);
734 C_SaferCond start_ctx
;
735 m_image_replayer
->start(&start_ctx
);
736 ASSERT_EQ(-EREMOTEIO
, start_ctx
.wait());
739 TEST_F(TestMockImageReplayer
, PrepareLocalImageError
) {
740 create_local_image();
741 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
743 MockThreads
mock_threads(m_threads
);
744 expect_work_queue_repeatedly(mock_threads
);
745 expect_add_event_after_repeatedly(mock_threads
);
747 MockImageDeleter mock_image_deleter
;
748 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
749 MockReplayStatusFormatter mock_replay_status_formatter
;
751 expect_get_or_send_update(mock_replay_status_formatter
);
754 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
755 expect_send(mock_prepare_local_image_request
, mock_local_image_ctx
.id
,
756 mock_local_image_ctx
.name
, "remote mirror uuid", -EINVAL
);
758 create_image_replayer(mock_threads
, mock_image_deleter
);
760 C_SaferCond start_ctx
;
761 m_image_replayer
->start(&start_ctx
);
762 ASSERT_EQ(-EINVAL
, start_ctx
.wait());
765 TEST_F(TestMockImageReplayer
, GetRemoteImageIdDNE
) {
766 create_local_image();
767 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
769 MockThreads
mock_threads(m_threads
);
770 expect_work_queue_repeatedly(mock_threads
);
771 expect_add_event_after_repeatedly(mock_threads
);
773 MockImageDeleter mock_image_deleter
;
774 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
775 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
776 MockReplayStatusFormatter mock_replay_status_formatter
;
778 expect_get_or_send_update(mock_replay_status_formatter
);
781 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
782 expect_send(mock_prepare_local_image_request
, mock_local_image_ctx
.id
,
783 mock_local_image_ctx
.name
, "remote mirror uuid", 0);
784 expect_send(mock_prepare_remote_image_request
, "remote mirror uuid",
786 expect_schedule_image_delete(mock_image_deleter
, "global image id", false);
788 create_image_replayer(mock_threads
, mock_image_deleter
);
790 C_SaferCond start_ctx
;
791 m_image_replayer
->start(&start_ctx
);
792 ASSERT_EQ(0, start_ctx
.wait());
795 TEST_F(TestMockImageReplayer
, GetRemoteImageIdNonLinkedDNE
) {
796 create_local_image();
797 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
799 MockThreads
mock_threads(m_threads
);
800 expect_work_queue_repeatedly(mock_threads
);
801 expect_add_event_after_repeatedly(mock_threads
);
803 MockImageDeleter mock_image_deleter
;
804 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
805 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
806 MockReplayStatusFormatter mock_replay_status_formatter
;
808 expect_get_or_send_update(mock_replay_status_formatter
);
811 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
812 expect_send(mock_prepare_local_image_request
, mock_local_image_ctx
.id
,
813 mock_local_image_ctx
.name
, "some other mirror uuid", 0);
814 expect_send(mock_prepare_remote_image_request
, "remote mirror uuid",
817 create_image_replayer(mock_threads
, mock_image_deleter
);
819 C_SaferCond start_ctx
;
820 m_image_replayer
->start(&start_ctx
);
821 ASSERT_EQ(-ENOENT
, start_ctx
.wait());
824 TEST_F(TestMockImageReplayer
, GetRemoteImageIdError
) {
825 create_local_image();
826 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
828 MockThreads
mock_threads(m_threads
);
829 expect_work_queue_repeatedly(mock_threads
);
830 expect_add_event_after_repeatedly(mock_threads
);
832 MockImageDeleter mock_image_deleter
;
833 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
834 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
835 MockReplayStatusFormatter mock_replay_status_formatter
;
837 expect_get_or_send_update(mock_replay_status_formatter
);
840 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
841 expect_send(mock_prepare_local_image_request
, mock_local_image_ctx
.id
,
842 mock_local_image_ctx
.name
, "remote mirror uuid", 0);
843 expect_send(mock_prepare_remote_image_request
, "remote mirror uuid",
844 m_remote_image_ctx
->id
, -EINVAL
);
846 create_image_replayer(mock_threads
, mock_image_deleter
);
848 C_SaferCond start_ctx
;
849 m_image_replayer
->start(&start_ctx
);
850 ASSERT_EQ(-EINVAL
, start_ctx
.wait());
853 TEST_F(TestMockImageReplayer
, BootstrapError
) {
855 create_local_image();
856 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
858 journal::MockJournaler mock_remote_journaler
;
859 MockThreads
mock_threads(m_threads
);
860 expect_work_queue_repeatedly(mock_threads
);
861 expect_add_event_after_repeatedly(mock_threads
);
863 MockImageDeleter mock_image_deleter
;
864 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
865 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
866 MockBootstrapRequest mock_bootstrap_request
;
867 MockReplayStatusFormatter mock_replay_status_formatter
;
869 expect_get_or_send_update(mock_replay_status_formatter
);
872 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
873 expect_send(mock_prepare_local_image_request
, mock_local_image_ctx
.id
,
874 mock_local_image_ctx
.name
, "remote mirror uuid", 0);
875 expect_send(mock_prepare_remote_image_request
, "remote mirror uuid",
876 m_remote_image_ctx
->id
, 0);
877 EXPECT_CALL(mock_remote_journaler
, construct());
878 expect_send(mock_bootstrap_request
, mock_local_image_ctx
, false, -EINVAL
);
880 EXPECT_CALL(mock_remote_journaler
, remove_listener(_
));
881 expect_shut_down(mock_remote_journaler
, 0);
883 create_image_replayer(mock_threads
, mock_image_deleter
);
885 C_SaferCond start_ctx
;
886 m_image_replayer
->start(&start_ctx
);
887 ASSERT_EQ(-EINVAL
, start_ctx
.wait());
890 TEST_F(TestMockImageReplayer
, StartExternalReplayError
) {
893 create_local_image();
894 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
896 librbd::MockTestJournal mock_local_journal
;
897 mock_local_image_ctx
.journal
= &mock_local_journal
;
899 journal::MockJournaler mock_remote_journaler
;
900 MockThreads
mock_threads(m_threads
);
901 expect_work_queue_repeatedly(mock_threads
);
902 expect_add_event_after_repeatedly(mock_threads
);
904 MockImageDeleter mock_image_deleter
;
905 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
906 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
907 MockBootstrapRequest mock_bootstrap_request
;
908 MockReplay mock_local_replay
;
909 MockEventPreprocessor mock_event_preprocessor
;
910 MockReplayStatusFormatter mock_replay_status_formatter
;
912 expect_get_or_send_update(mock_replay_status_formatter
);
915 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
916 expect_send(mock_prepare_local_image_request
, mock_local_image_ctx
.id
,
917 mock_local_image_ctx
.name
, "remote mirror uuid", 0);
918 expect_send(mock_prepare_remote_image_request
, "remote mirror uuid",
919 m_remote_image_ctx
->id
, 0);
920 EXPECT_CALL(mock_remote_journaler
, construct());
921 expect_send(mock_bootstrap_request
, mock_local_image_ctx
, false, 0);
923 EXPECT_CALL(mock_local_journal
, add_listener(_
));
925 expect_init(mock_remote_journaler
, 0);
927 EXPECT_CALL(mock_remote_journaler
, add_listener(_
));
928 expect_get_cached_client(mock_remote_journaler
, 0);
930 expect_start_external_replay(mock_local_journal
, nullptr, -EINVAL
);
932 MockCloseImageRequest mock_close_local_image_request
;
933 EXPECT_CALL(mock_local_journal
, remove_listener(_
));
934 expect_send(mock_close_local_image_request
, 0);
936 EXPECT_CALL(mock_remote_journaler
, remove_listener(_
));
937 expect_shut_down(mock_remote_journaler
, 0);
939 create_image_replayer(mock_threads
, mock_image_deleter
);
941 C_SaferCond start_ctx
;
942 m_image_replayer
->start(&start_ctx
);
943 ASSERT_EQ(-EINVAL
, start_ctx
.wait());
944 ASSERT_EQ(image_replayer::HEALTH_STATE_ERROR
,
945 m_image_replayer
->get_health_state());
948 TEST_F(TestMockImageReplayer
, StopError
) {
951 create_local_image();
952 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
954 librbd::MockTestJournal mock_local_journal
;
955 mock_local_image_ctx
.journal
= &mock_local_journal
;
957 journal::MockJournaler mock_remote_journaler
;
958 MockThreads
mock_threads(m_threads
);
959 expect_work_queue_repeatedly(mock_threads
);
960 expect_add_event_after_repeatedly(mock_threads
);
962 MockImageDeleter mock_image_deleter
;
963 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
964 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
965 MockBootstrapRequest mock_bootstrap_request
;
966 MockReplay mock_local_replay
;
967 MockEventPreprocessor mock_event_preprocessor
;
968 MockReplayStatusFormatter mock_replay_status_formatter
;
970 expect_get_or_send_update(mock_replay_status_formatter
);
973 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
974 expect_send(mock_prepare_local_image_request
, mock_local_image_ctx
.id
,
975 mock_local_image_ctx
.name
, "remote mirror uuid", 0);
976 expect_send(mock_prepare_remote_image_request
, "remote mirror uuid",
977 m_remote_image_ctx
->id
, 0);
978 EXPECT_CALL(mock_remote_journaler
, construct());
979 expect_send(mock_bootstrap_request
, mock_local_image_ctx
, false, 0);
981 EXPECT_CALL(mock_local_journal
, add_listener(_
));
983 expect_init(mock_remote_journaler
, 0);
985 EXPECT_CALL(mock_remote_journaler
, add_listener(_
));
986 expect_get_cached_client(mock_remote_journaler
, 0);
988 expect_start_external_replay(mock_local_journal
, &mock_local_replay
, 0);
990 EXPECT_CALL(mock_remote_journaler
, start_live_replay(_
, _
));
992 create_image_replayer(mock_threads
, mock_image_deleter
);
994 C_SaferCond start_ctx
;
995 m_image_replayer
->start(&start_ctx
);
996 ASSERT_EQ(0, start_ctx
.wait());
998 // STOP (errors are ignored)
1000 MockCloseImageRequest mock_close_local_image_request
;
1002 expect_cancel_waiter(mock_image_deleter
);
1003 expect_shut_down(mock_local_replay
, true, -EINVAL
);
1004 EXPECT_CALL(mock_local_journal
, remove_listener(_
));
1005 EXPECT_CALL(mock_local_journal
, stop_external_replay());
1006 expect_send(mock_close_local_image_request
, -EINVAL
);
1008 expect_stop_replay(mock_remote_journaler
, -EINVAL
);
1009 EXPECT_CALL(mock_remote_journaler
, remove_listener(_
));
1010 expect_shut_down(mock_remote_journaler
, -EINVAL
);
1012 C_SaferCond stop_ctx
;
1013 m_image_replayer
->stop(&stop_ctx
);
1014 ASSERT_EQ(0, stop_ctx
.wait());
1017 TEST_F(TestMockImageReplayer
, Replay
) {
1020 create_local_image();
1021 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
1023 librbd::MockTestJournal mock_local_journal
;
1024 mock_local_image_ctx
.journal
= &mock_local_journal
;
1026 journal::MockJournaler mock_remote_journaler
;
1027 MockThreads
mock_threads(m_threads
);
1028 expect_work_queue_repeatedly(mock_threads
);
1029 expect_add_event_after_repeatedly(mock_threads
);
1031 MockImageDeleter mock_image_deleter
;
1032 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
1033 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
1034 MockBootstrapRequest mock_bootstrap_request
;
1035 MockReplay mock_local_replay
;
1036 MockEventPreprocessor mock_event_preprocessor
;
1037 MockReplayStatusFormatter mock_replay_status_formatter
;
1038 ::journal::MockReplayEntry mock_replay_entry
;
1040 expect_get_or_send_update(mock_replay_status_formatter
);
1041 expect_get_commit_tid_in_debug(mock_replay_entry
);
1042 expect_committed(mock_remote_journaler
, 2);
1045 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
1046 expect_send(mock_prepare_local_image_request
, mock_local_image_ctx
.id
,
1047 mock_local_image_ctx
.name
, "remote mirror uuid", 0);
1048 expect_send(mock_prepare_remote_image_request
, "remote mirror uuid",
1049 m_remote_image_ctx
->id
, 0);
1050 EXPECT_CALL(mock_remote_journaler
, construct());
1051 expect_send(mock_bootstrap_request
, mock_local_image_ctx
, false, 0);
1053 EXPECT_CALL(mock_local_journal
, add_listener(_
));
1055 expect_init(mock_remote_journaler
, 0);
1057 EXPECT_CALL(mock_remote_journaler
, add_listener(_
));
1058 expect_get_cached_client(mock_remote_journaler
, 0);
1060 expect_start_external_replay(mock_local_journal
, &mock_local_replay
, 0);
1062 EXPECT_CALL(mock_remote_journaler
, start_live_replay(_
, _
));
1064 create_image_replayer(mock_threads
, mock_image_deleter
);
1066 C_SaferCond start_ctx
;
1067 m_image_replayer
->start(&start_ctx
);
1068 ASSERT_EQ(0, start_ctx
.wait());
1072 cls::journal::Tag tag
=
1073 {1, 0, encode_tag_data({librbd::Journal
<>::LOCAL_MIRROR_UUID
,
1074 librbd::Journal
<>::LOCAL_MIRROR_UUID
,
1077 expect_try_pop_front(mock_remote_journaler
, tag
.tid
, true);
1080 expect_shut_down(mock_local_replay
, false, 0);
1081 EXPECT_CALL(mock_local_journal
, stop_external_replay());
1082 expect_start_external_replay(mock_local_journal
, &mock_local_replay
, 0);
1083 expect_get_tag(mock_remote_journaler
, tag
, 0);
1084 expect_allocate_tag(mock_local_journal
, 0);
1087 EXPECT_CALL(mock_replay_entry
, get_data());
1088 EXPECT_CALL(mock_local_replay
, decode(_
, _
))
1089 .WillOnce(Return(0));
1090 expect_preprocess(mock_event_preprocessor
, false, 0);
1091 expect_process(mock_local_replay
, 0, 0);
1093 // the next event with preprocess
1094 expect_try_pop_front(mock_remote_journaler
, tag
.tid
, true);
1095 EXPECT_CALL(mock_replay_entry
, get_data());
1096 EXPECT_CALL(mock_local_replay
, decode(_
, _
))
1097 .WillOnce(Return(0));
1098 expect_preprocess(mock_event_preprocessor
, true, 0);
1099 expect_process(mock_local_replay
, 0, 0);
1101 // attempt to process the next event
1102 C_SaferCond replay_ctx
;
1103 expect_try_pop_front_return_no_entries(mock_remote_journaler
, &replay_ctx
);
1106 m_image_replayer
->handle_replay_ready();
1107 ASSERT_EQ(0, replay_ctx
.wait());
1111 MockCloseImageRequest mock_close_local_image_request
;
1112 expect_cancel_waiter(mock_image_deleter
);
1113 expect_shut_down(mock_local_replay
, true, 0);
1114 EXPECT_CALL(mock_local_journal
, remove_listener(_
));
1115 EXPECT_CALL(mock_local_journal
, stop_external_replay());
1116 expect_send(mock_close_local_image_request
, 0);
1118 expect_stop_replay(mock_remote_journaler
, 0);
1119 EXPECT_CALL(mock_remote_journaler
, remove_listener(_
));
1120 expect_shut_down(mock_remote_journaler
, 0);
1122 C_SaferCond stop_ctx
;
1123 m_image_replayer
->stop(&stop_ctx
);
1124 ASSERT_EQ(0, stop_ctx
.wait());
1127 TEST_F(TestMockImageReplayer
, DecodeError
) {
1130 create_local_image();
1131 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
1133 librbd::MockTestJournal mock_local_journal
;
1134 mock_local_image_ctx
.journal
= &mock_local_journal
;
1136 journal::MockJournaler mock_remote_journaler
;
1137 MockThreads
mock_threads(m_threads
);
1138 expect_work_queue_repeatedly(mock_threads
);
1139 expect_add_event_after_repeatedly(mock_threads
);
1141 MockImageDeleter mock_image_deleter
;
1142 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
1143 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
1144 MockBootstrapRequest mock_bootstrap_request
;
1145 MockReplay mock_local_replay
;
1146 MockEventPreprocessor mock_event_preprocessor
;
1147 MockReplayStatusFormatter mock_replay_status_formatter
;
1148 ::journal::MockReplayEntry mock_replay_entry
;
1150 expect_get_or_send_update(mock_replay_status_formatter
);
1151 expect_get_commit_tid_in_debug(mock_replay_entry
);
1154 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
1155 expect_send(mock_prepare_local_image_request
, mock_local_image_ctx
.id
,
1156 mock_local_image_ctx
.name
, "remote mirror uuid", 0);
1157 expect_send(mock_prepare_remote_image_request
, "remote mirror uuid",
1158 m_remote_image_ctx
->id
, 0);
1159 EXPECT_CALL(mock_remote_journaler
, construct());
1160 expect_send(mock_bootstrap_request
, mock_local_image_ctx
, false, 0);
1162 EXPECT_CALL(mock_local_journal
, add_listener(_
));
1164 expect_init(mock_remote_journaler
, 0);
1166 EXPECT_CALL(mock_remote_journaler
, add_listener(_
));
1167 expect_get_cached_client(mock_remote_journaler
, 0);
1169 expect_start_external_replay(mock_local_journal
, &mock_local_replay
, 0);
1171 EXPECT_CALL(mock_remote_journaler
, start_live_replay(_
, _
));
1173 create_image_replayer(mock_threads
, mock_image_deleter
);
1175 C_SaferCond start_ctx
;
1176 m_image_replayer
->start(&start_ctx
);
1177 ASSERT_EQ(0, start_ctx
.wait());
1181 cls::journal::Tag tag
=
1182 {1, 0, encode_tag_data({librbd::Journal
<>::LOCAL_MIRROR_UUID
,
1183 librbd::Journal
<>::LOCAL_MIRROR_UUID
,
1186 expect_try_pop_front(mock_remote_journaler
, tag
.tid
, true);
1189 expect_shut_down(mock_local_replay
, false, 0);
1190 EXPECT_CALL(mock_local_journal
, stop_external_replay());
1191 expect_start_external_replay(mock_local_journal
, &mock_local_replay
, 0);
1192 expect_get_tag(mock_remote_journaler
, tag
, 0);
1193 expect_allocate_tag(mock_local_journal
, 0);
1196 EXPECT_CALL(mock_replay_entry
, get_data());
1197 EXPECT_CALL(mock_local_replay
, decode(_
, _
))
1198 .WillOnce(Return(-EINVAL
));
1201 expect_shut_down(mock_local_replay
, true, 0);
1202 EXPECT_CALL(mock_local_journal
, remove_listener(_
));
1203 EXPECT_CALL(mock_local_journal
, stop_external_replay());
1205 MockCloseImageRequest mock_close_local_image_request
;
1206 C_SaferCond close_ctx
;
1207 EXPECT_CALL(mock_close_local_image_request
, send())
1208 .WillOnce(Invoke([&mock_close_local_image_request
, &close_ctx
]() {
1209 *mock_close_local_image_request
.image_ctx
= nullptr;
1210 mock_close_local_image_request
.on_finish
->complete(0);
1211 close_ctx
.complete(0);
1214 expect_stop_replay(mock_remote_journaler
, 0);
1215 EXPECT_CALL(mock_remote_journaler
, remove_listener(_
));
1216 expect_shut_down(mock_remote_journaler
, 0);
1219 m_image_replayer
->handle_replay_ready();
1220 ASSERT_EQ(0, close_ctx
.wait());
1222 while (!m_image_replayer
->is_stopped()) {
1227 TEST_F(TestMockImageReplayer
, DelayedReplay
) {
1231 create_local_image();
1232 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
1234 librbd::MockTestJournal mock_local_journal
;
1235 mock_local_image_ctx
.journal
= &mock_local_journal
;
1237 journal::MockJournaler mock_remote_journaler
;
1238 MockThreads
mock_threads(m_threads
);
1239 expect_work_queue_repeatedly(mock_threads
);
1240 expect_add_event_after_repeatedly(mock_threads
);
1242 MockImageDeleter mock_image_deleter
;
1243 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
1244 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
1245 MockBootstrapRequest mock_bootstrap_request
;
1246 MockReplay mock_local_replay
;
1247 MockEventPreprocessor mock_event_preprocessor
;
1248 MockReplayStatusFormatter mock_replay_status_formatter
;
1249 ::journal::MockReplayEntry mock_replay_entry
;
1251 expect_get_or_send_update(mock_replay_status_formatter
);
1252 expect_get_commit_tid_in_debug(mock_replay_entry
);
1253 expect_committed(mock_remote_journaler
, 1);
1256 expect_wait_for_scheduled_deletion(mock_image_deleter
, "global image id", 0);
1257 expect_send(mock_prepare_local_image_request
, mock_local_image_ctx
.id
,
1258 mock_local_image_ctx
.name
, "remote mirror uuid", 0);
1259 expect_send(mock_prepare_remote_image_request
, "remote mirror uuid",
1260 m_remote_image_ctx
->id
, 0);
1261 EXPECT_CALL(mock_remote_journaler
, construct());
1262 expect_send(mock_bootstrap_request
, mock_local_image_ctx
, false, 0);
1264 EXPECT_CALL(mock_local_journal
, add_listener(_
));
1266 expect_init(mock_remote_journaler
, 0);
1268 EXPECT_CALL(mock_remote_journaler
, add_listener(_
));
1269 expect_get_cached_client(mock_remote_journaler
, 0);
1271 expect_start_external_replay(mock_local_journal
, &mock_local_replay
, 0);
1273 EXPECT_CALL(mock_remote_journaler
, start_live_replay(_
, _
));
1275 create_image_replayer(mock_threads
, mock_image_deleter
);
1277 C_SaferCond start_ctx
;
1278 m_image_replayer
->start(&start_ctx
);
1279 ASSERT_EQ(0, start_ctx
.wait());
1283 cls::journal::Tag tag
=
1284 {1, 0, encode_tag_data({librbd::Journal
<>::LOCAL_MIRROR_UUID
,
1285 librbd::Journal
<>::LOCAL_MIRROR_UUID
,
1288 expect_try_pop_front(mock_remote_journaler
, tag
.tid
, true);
1291 expect_shut_down(mock_local_replay
, false, 0);
1292 EXPECT_CALL(mock_local_journal
, stop_external_replay());
1293 expect_start_external_replay(mock_local_journal
, &mock_local_replay
, 0);
1294 expect_get_tag(mock_remote_journaler
, tag
, 0);
1295 expect_allocate_tag(mock_local_journal
, 0);
1297 // process with delay
1298 EXPECT_CALL(mock_replay_entry
, get_data());
1299 librbd::journal::EventEntry
event_entry(
1300 librbd::journal::AioDiscardEvent(123, 345, false), ceph_clock_now());
1301 EXPECT_CALL(mock_local_replay
, decode(_
, _
))
1302 .WillOnce(DoAll(SetArgPointee
<1>(event_entry
),
1304 expect_preprocess(mock_event_preprocessor
, false, 0);
1305 expect_process(mock_local_replay
, 0, 0);
1307 // attempt to process the next event
1308 C_SaferCond replay_ctx
;
1309 expect_try_pop_front_return_no_entries(mock_remote_journaler
, &replay_ctx
);
1312 mock_local_image_ctx
.mirroring_replay_delay
= 2;
1313 m_image_replayer
->handle_replay_ready();
1314 ASSERT_EQ(0, replay_ctx
.wait());
1316 // add a pending (delayed) entry before stop
1317 expect_try_pop_front(mock_remote_journaler
, tag
.tid
, true);
1318 EXPECT_CALL(mock_replay_entry
, get_data());
1319 C_SaferCond decode_ctx
;
1320 EXPECT_CALL(mock_local_replay
, decode(_
, _
))
1321 .WillOnce(DoAll(Invoke([&decode_ctx
](bufferlist::iterator
* it
,
1322 librbd::journal::EventEntry
*e
) {
1323 decode_ctx
.complete(0);
1327 mock_local_image_ctx
.mirroring_replay_delay
= 10;
1328 m_image_replayer
->handle_replay_ready();
1329 ASSERT_EQ(0, decode_ctx
.wait());
1333 MockCloseImageRequest mock_close_local_image_request
;
1335 expect_cancel_waiter(mock_image_deleter
);
1336 expect_shut_down(mock_local_replay
, true, 0);
1337 EXPECT_CALL(mock_local_journal
, remove_listener(_
));
1338 EXPECT_CALL(mock_local_journal
, stop_external_replay());
1339 expect_send(mock_close_local_image_request
, 0);
1341 expect_stop_replay(mock_remote_journaler
, 0);
1342 EXPECT_CALL(mock_remote_journaler
, remove_listener(_
));
1343 expect_shut_down(mock_remote_journaler
, 0);
1345 C_SaferCond stop_ctx
;
1346 m_image_replayer
->stop(&stop_ctx
);
1347 ASSERT_EQ(0, stop_ctx
.wait());
1351 } // namespace mirror