1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "test/rbd_mirror/test_mock_fixture.h"
5 #include "librbd/journal/TypeTraits.h"
6 #include "tools/rbd_mirror/BaseRequest.h"
7 #include "tools/rbd_mirror/InstanceWatcher.h"
8 #include "tools/rbd_mirror/Threads.h"
9 #include "tools/rbd_mirror/image_replayer/BootstrapRequest.h"
10 #include "tools/rbd_mirror/image_replayer/OpenImageRequest.h"
11 #include "tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h"
12 #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.h"
13 #include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h"
14 #include "tools/rbd_mirror/image_replayer/StateBuilder.h"
15 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
16 #include "test/librbd/mock/MockImageCtx.h"
17 #include "test/rbd_mirror/mock/image_sync/MockSyncPointHandler.h"
18 #include "test/rbd_mirror/mock/MockBaseRequest.h"
24 struct MockTestImageCtx
: public librbd::MockImageCtx
{
25 MockTestImageCtx(librbd::ImageCtx
&image_ctx
)
26 : librbd::MockImageCtx(image_ctx
) {
30 } // anonymous namespace
36 class ProgressContext
;
39 struct Threads
<librbd::MockTestImageCtx
> {
40 ceph::mutex
&timer_lock
;
42 ContextWQ
*work_queue
;
44 Threads(Threads
<librbd::ImageCtx
> *threads
)
45 : timer_lock(threads
->timer_lock
), timer(threads
->timer
),
46 work_queue(threads
->work_queue
) {
51 struct ImageSync
<librbd::MockTestImageCtx
> {
52 static ImageSync
* s_instance
;
53 Context
*on_finish
= nullptr;
55 static ImageSync
* create(
56 Threads
<librbd::MockTestImageCtx
>* threads
,
57 librbd::MockTestImageCtx
*local_image_ctx
,
58 librbd::MockTestImageCtx
*remote_image_ctx
,
59 const std::string
&local_mirror_uuid
,
60 image_sync::SyncPointHandler
* sync_point_handler
,
61 InstanceWatcher
<librbd::MockTestImageCtx
> *instance_watcher
,
62 ProgressContext
*progress_ctx
, Context
*on_finish
) {
63 ceph_assert(s_instance
!= nullptr);
64 s_instance
->on_finish
= on_finish
;
69 ceph_assert(s_instance
== nullptr);
76 MOCK_METHOD0(get
, void());
77 MOCK_METHOD0(put
, void());
78 MOCK_METHOD0(send
, void());
79 MOCK_METHOD0(cancel
, void());
82 ImageSync
<librbd::MockTestImageCtx
>*
83 ImageSync
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
86 struct InstanceWatcher
<librbd::MockTestImageCtx
> {
89 namespace image_replayer
{
92 struct OpenImageRequest
<librbd::MockTestImageCtx
> {
93 static OpenImageRequest
* s_instance
;
94 librbd::MockTestImageCtx
**image_ctx
= nullptr;
95 Context
*on_finish
= nullptr;
97 static OpenImageRequest
* create(librados::IoCtx
&io_ctx
,
98 librbd::MockTestImageCtx
**image_ctx
,
99 const std::string
&image_id
,
100 bool read_only
, Context
*on_finish
) {
101 ceph_assert(s_instance
!= nullptr);
102 s_instance
->image_ctx
= image_ctx
;
103 s_instance
->on_finish
= on_finish
;
104 s_instance
->construct(io_ctx
, image_id
);
109 ceph_assert(s_instance
== nullptr);
112 ~OpenImageRequest() {
113 s_instance
= nullptr;
116 MOCK_METHOD2(construct
, void(librados::IoCtx
&io_ctx
,
117 const std::string
&image_id
));
118 MOCK_METHOD0(send
, void());
122 struct OpenLocalImageRequest
<librbd::MockTestImageCtx
> {
123 static OpenLocalImageRequest
* s_instance
;
124 librbd::MockTestImageCtx
**image_ctx
= nullptr;
125 Context
*on_finish
= nullptr;
127 static OpenLocalImageRequest
* create(librados::IoCtx
&local_io_ctx
,
128 librbd::MockTestImageCtx
**local_image_ctx
,
129 const std::string
&local_image_id
,
130 ContextWQ
*work_queue
,
131 Context
*on_finish
) {
132 ceph_assert(s_instance
!= nullptr);
133 s_instance
->image_ctx
= local_image_ctx
;
134 s_instance
->on_finish
= on_finish
;
135 s_instance
->construct(local_io_ctx
, local_image_id
);
139 OpenLocalImageRequest() {
140 ceph_assert(s_instance
== nullptr);
143 ~OpenLocalImageRequest() {
144 s_instance
= nullptr;
147 MOCK_METHOD2(construct
, void(librados::IoCtx
&io_ctx
,
148 const std::string
&image_id
));
149 MOCK_METHOD0(send
, void());
153 struct PrepareLocalImageRequest
<librbd::MockTestImageCtx
> {
154 static PrepareLocalImageRequest
* s_instance
;
155 std::string
*local_image_name
= nullptr;
156 StateBuilder
<librbd::MockTestImageCtx
>** state_builder
= nullptr;
157 Context
*on_finish
= nullptr;
159 static PrepareLocalImageRequest
* create(librados::IoCtx
&,
160 const std::string
&global_image_id
,
161 std::string
*local_image_name
,
162 StateBuilder
<librbd::MockTestImageCtx
>** state_builder
,
163 ContextWQ
*work_queue
,
164 Context
*on_finish
) {
165 ceph_assert(s_instance
!= nullptr);
166 s_instance
->local_image_name
= local_image_name
;
167 s_instance
->state_builder
= state_builder
;
168 s_instance
->on_finish
= on_finish
;
172 PrepareLocalImageRequest() {
176 MOCK_METHOD0(send
, void());
180 struct PrepareRemoteImageRequest
<librbd::MockTestImageCtx
> {
181 static PrepareRemoteImageRequest
* s_instance
;
182 StateBuilder
<librbd::MockTestImageCtx
>** state_builder
= nullptr;
183 Context
*on_finish
= nullptr;
185 static PrepareRemoteImageRequest
* create(Threads
<librbd::MockTestImageCtx
> *threads
,
188 const std::string
&global_image_id
,
189 const std::string
&local_mirror_uuid
,
190 const RemotePoolMeta
& remote_pool_meta
,
191 ::journal::CacheManagerHandler
*cache_manager_handler
,
192 StateBuilder
<librbd::MockTestImageCtx
>** state_builder
,
193 Context
*on_finish
) {
194 ceph_assert(s_instance
!= nullptr);
195 s_instance
->state_builder
= state_builder
;
196 s_instance
->on_finish
= on_finish
;
200 PrepareRemoteImageRequest() {
204 MOCK_METHOD0(send
, void());
208 struct StateBuilder
<librbd::MockTestImageCtx
> {
209 static StateBuilder
* s_instance
;
211 image_sync::MockSyncPointHandler mock_sync_point_handler
;
212 MockBaseRequest mock_base_request
;
214 librbd::MockTestImageCtx
* local_image_ctx
= nullptr;
215 librbd::MockTestImageCtx
* remote_image_ctx
= nullptr;
216 std::string local_image_id
;
217 std::string remote_mirror_uuid
;
218 std::string remote_image_id
;
220 static StateBuilder
* create(const std::string
&) {
221 ceph_assert(s_instance
!= nullptr);
225 image_sync::MockSyncPointHandler
* create_sync_point_handler() {
226 return &mock_sync_point_handler
;
233 MOCK_CONST_METHOD0(is_disconnected
, bool());
234 MOCK_CONST_METHOD0(is_local_primary
, bool());
235 MOCK_CONST_METHOD0(is_linked
, bool());
237 MOCK_CONST_METHOD0(replay_requires_remote_image
, bool());
238 MOCK_METHOD1(close_remote_image
, void(Context
*));
240 MOCK_METHOD6(create_local_image_request
,
241 BaseRequest
*(Threads
<librbd::MockTestImageCtx
>*,
247 MOCK_METHOD5(create_prepare_replay_request
,
248 BaseRequest
*(const std::string
&,
250 bool*, bool*, Context
*));
252 void destroy_sync_point_handler() {
258 OpenImageRequest
<librbd::MockTestImageCtx
>*
259 OpenImageRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
260 OpenLocalImageRequest
<librbd::MockTestImageCtx
>*
261 OpenLocalImageRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
262 PrepareLocalImageRequest
<librbd::MockTestImageCtx
>*
263 PrepareLocalImageRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
264 PrepareRemoteImageRequest
<librbd::MockTestImageCtx
>*
265 PrepareRemoteImageRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
266 StateBuilder
<librbd::MockTestImageCtx
>*
267 StateBuilder
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
269 } // namespace image_replayer
270 } // namespace mirror
273 // template definitions
274 #include "tools/rbd_mirror/image_replayer/BootstrapRequest.cc"
278 namespace image_replayer
{
281 using ::testing::DoAll
;
282 using ::testing::InSequence
;
283 using ::testing::Invoke
;
284 using ::testing::Return
;
285 using ::testing::SetArgPointee
;
286 using ::testing::StrEq
;
287 using ::testing::WithArg
;
288 using ::testing::WithArgs
;
290 MATCHER_P(IsSameIoCtx
, io_ctx
, "") {
291 return &get_mock_io_ctx(arg
) == &get_mock_io_ctx(*io_ctx
);
294 class TestMockImageReplayerBootstrapRequest
: public TestMockFixture
{
296 typedef Threads
<librbd::MockTestImageCtx
> MockThreads
;
297 typedef BootstrapRequest
<librbd::MockTestImageCtx
> MockBootstrapRequest
;
298 typedef ImageSync
<librbd::MockTestImageCtx
> MockImageSync
;
299 typedef InstanceWatcher
<librbd::MockTestImageCtx
> MockInstanceWatcher
;
300 typedef OpenImageRequest
<librbd::MockTestImageCtx
> MockOpenImageRequest
;
301 typedef OpenLocalImageRequest
<librbd::MockTestImageCtx
> MockOpenLocalImageRequest
;
302 typedef PrepareLocalImageRequest
<librbd::MockTestImageCtx
> MockPrepareLocalImageRequest
;
303 typedef PrepareRemoteImageRequest
<librbd::MockTestImageCtx
> MockPrepareRemoteImageRequest
;
304 typedef StateBuilder
<librbd::MockTestImageCtx
> MockStateBuilder
;
305 typedef std::list
<cls::journal::Tag
> Tags
;
307 void SetUp() override
{
308 TestMockFixture::SetUp();
311 ASSERT_EQ(0, create_image(rbd
, m_remote_io_ctx
, m_image_name
, m_image_size
));
312 ASSERT_EQ(0, open_image(m_remote_io_ctx
, m_image_name
, &m_remote_image_ctx
));
314 ASSERT_EQ(0, create_image(rbd
, m_local_io_ctx
, m_image_name
, m_image_size
));
315 ASSERT_EQ(0, open_image(m_local_io_ctx
, m_image_name
, &m_local_image_ctx
));
318 void expect_send(MockPrepareLocalImageRequest
&mock_request
,
319 MockStateBuilder
& mock_state_builder
,
320 const std::string
& local_image_id
,
321 const std::string
& local_image_name
, int r
) {
322 EXPECT_CALL(mock_request
, send())
323 .WillOnce(Invoke([&mock_request
, &mock_state_builder
, local_image_id
,
324 local_image_name
, r
]() {
326 *mock_request
.state_builder
= &mock_state_builder
;
327 mock_state_builder
.local_image_id
= local_image_id
;
328 *mock_request
.local_image_name
= local_image_name
;
330 mock_request
.on_finish
->complete(r
);
334 void expect_send(MockPrepareRemoteImageRequest
& mock_request
,
335 MockStateBuilder
& mock_state_builder
,
336 const std::string
& remote_mirror_uuid
,
337 const std::string
& remote_image_id
,
339 EXPECT_CALL(mock_request
, send())
340 .WillOnce(Invoke([&mock_request
, &mock_state_builder
, remote_mirror_uuid
,
341 remote_image_id
, r
]() {
343 *mock_request
.state_builder
= &mock_state_builder
;
344 mock_state_builder
.remote_image_id
= remote_image_id
;
347 mock_state_builder
.remote_mirror_uuid
= remote_mirror_uuid
;
348 mock_request
.on_finish
->complete(r
);
352 void expect_is_local_primary(MockStateBuilder
& mock_state_builder
,
354 EXPECT_CALL(mock_state_builder
, is_local_primary())
355 .WillOnce(Return(is_primary
));
358 void expect_is_disconnected(MockStateBuilder
& mock_state_builder
,
359 bool is_disconnected
) {
360 EXPECT_CALL(mock_state_builder
, is_disconnected())
361 .WillOnce(Return(is_disconnected
));
364 void expect_replay_requires_remote_image(MockStateBuilder
& mock_state_builder
,
365 bool requires_image
) {
366 EXPECT_CALL(mock_state_builder
, replay_requires_remote_image())
367 .WillOnce(Return(requires_image
));
370 void expect_open_image(MockOpenImageRequest
&mock_open_image_request
,
371 librados::IoCtx
&io_ctx
, const std::string
&image_id
,
372 librbd::MockTestImageCtx
&mock_image_ctx
, int r
) {
373 EXPECT_CALL(mock_open_image_request
,
374 construct(IsSameIoCtx(&io_ctx
), image_id
));
375 EXPECT_CALL(mock_open_image_request
, send())
376 .WillOnce(Invoke([this, &mock_open_image_request
, &mock_image_ctx
, r
]() {
377 *mock_open_image_request
.image_ctx
= &mock_image_ctx
;
378 m_threads
->work_queue
->queue(mock_open_image_request
.on_finish
, r
);
382 void expect_open_local_image(MockOpenLocalImageRequest
&mock_open_local_image_request
,
383 librados::IoCtx
&io_ctx
, const std::string
&image_id
,
384 librbd::MockTestImageCtx
*mock_image_ctx
, int r
) {
385 EXPECT_CALL(mock_open_local_image_request
,
386 construct(IsSameIoCtx(&io_ctx
), image_id
));
387 EXPECT_CALL(mock_open_local_image_request
, send())
388 .WillOnce(Invoke([this, &mock_open_local_image_request
, mock_image_ctx
, r
]() {
390 *mock_open_local_image_request
.image_ctx
= mock_image_ctx
;
392 m_threads
->work_queue
->queue(mock_open_local_image_request
.on_finish
,
397 void expect_close_remote_image(
398 MockStateBuilder
& mock_state_builder
, int r
) {
399 EXPECT_CALL(mock_state_builder
, close_remote_image(_
))
400 .WillOnce(Invoke([&mock_state_builder
, r
]
401 (Context
* on_finish
) {
402 mock_state_builder
.remote_image_ctx
= nullptr;
403 on_finish
->complete(r
);
407 void expect_create_local_image(MockStateBuilder
& mock_state_builder
,
408 const std::string
& local_image_id
, int r
) {
409 EXPECT_CALL(mock_state_builder
,
410 create_local_image_request(_
, _
, _
, _
, _
, _
))
411 .WillOnce(WithArg
<5>(
412 Invoke([&mock_state_builder
, local_image_id
, r
](Context
* ctx
) {
414 mock_state_builder
.local_image_id
= local_image_id
;
416 mock_state_builder
.mock_base_request
.on_finish
= ctx
;
417 return &mock_state_builder
.mock_base_request
;
419 EXPECT_CALL(mock_state_builder
.mock_base_request
, send())
420 .WillOnce(Invoke([this, &mock_state_builder
, r
]() {
421 m_threads
->work_queue
->queue(
422 mock_state_builder
.mock_base_request
.on_finish
, r
);
426 void expect_prepare_replay(MockStateBuilder
& mock_state_builder
,
427 bool resync_requested
, bool syncing
, int r
) {
428 EXPECT_CALL(mock_state_builder
,
429 create_prepare_replay_request(_
, _
, _
, _
, _
))
430 .WillOnce(WithArgs
<2, 3, 4>(
431 Invoke([&mock_state_builder
, resync_requested
, syncing
, r
]
432 (bool* resync
, bool* sync
, Context
* ctx
) {
434 *resync
= resync_requested
;
437 mock_state_builder
.mock_base_request
.on_finish
= ctx
;
438 return &mock_state_builder
.mock_base_request
;
440 EXPECT_CALL(mock_state_builder
.mock_base_request
, send())
441 .WillOnce(Invoke([this, &mock_state_builder
, r
]() {
442 m_threads
->work_queue
->queue(
443 mock_state_builder
.mock_base_request
.on_finish
, r
);
447 void expect_image_sync(MockImageSync
&mock_image_sync
, int r
) {
448 EXPECT_CALL(mock_image_sync
, get());
449 EXPECT_CALL(mock_image_sync
, send())
450 .WillOnce(Invoke([this, &mock_image_sync
, r
]() {
451 m_threads
->work_queue
->queue(mock_image_sync
.on_finish
, r
);
453 EXPECT_CALL(mock_image_sync
, put());
456 MockBootstrapRequest
*create_request(MockThreads
* mock_threads
,
457 MockInstanceWatcher
*mock_instance_watcher
,
458 const std::string
&global_image_id
,
459 const std::string
&local_mirror_uuid
,
460 Context
*on_finish
) {
461 return new MockBootstrapRequest(mock_threads
,
464 mock_instance_watcher
,
467 {"remote mirror uuid",
468 "remote mirror peer uuid"},
469 nullptr, nullptr, nullptr,
470 &m_mock_state_builder
,
471 &m_do_resync
, on_finish
);
474 librbd::ImageCtx
*m_remote_image_ctx
;
475 librbd::ImageCtx
*m_local_image_ctx
= nullptr;
477 MockStateBuilder
* m_mock_state_builder
= nullptr;
478 bool m_do_resync
= false;
481 TEST_F(TestMockImageReplayerBootstrapRequest
, Success
) {
484 // prepare local image
485 MockStateBuilder mock_state_builder
;
486 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
487 expect_send(mock_prepare_local_image_request
, mock_state_builder
,
488 m_local_image_ctx
->id
, m_local_image_ctx
->name
, 0);
490 // prepare remote image
491 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
492 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
493 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
494 expect_is_local_primary(mock_state_builder
, false);
496 // open the remote image
497 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
498 MockOpenImageRequest mock_open_image_request
;
499 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
500 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
502 // open the local image
503 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
504 MockOpenLocalImageRequest mock_open_local_image_request
;
505 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
506 mock_local_image_ctx
.id
, &mock_local_image_ctx
, 0);
509 expect_prepare_replay(mock_state_builder
, false, false, 0);
510 expect_is_disconnected(mock_state_builder
, false);
512 // close remote image
513 expect_replay_requires_remote_image(mock_state_builder
, false);
514 expect_close_remote_image(mock_state_builder
, 0);
517 MockThreads
mock_threads(m_threads
);
518 MockInstanceWatcher mock_instance_watcher
;
519 MockBootstrapRequest
*request
= create_request(
520 &mock_threads
, &mock_instance_watcher
, "global image id",
521 "local mirror uuid", &ctx
);
523 ASSERT_EQ(0, ctx
.wait());
526 TEST_F(TestMockImageReplayerBootstrapRequest
, OpenLocalImageError
) {
529 // prepare local image
530 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
531 MockStateBuilder mock_state_builder
;
532 expect_send(mock_prepare_local_image_request
, mock_state_builder
,
533 m_local_image_ctx
->id
, m_local_image_ctx
->name
, 0);
535 // prepare remote image
536 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
537 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
538 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
539 expect_is_local_primary(mock_state_builder
, false);
541 // open the remote image
542 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
543 MockOpenImageRequest mock_open_image_request
;
544 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
545 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
547 // open the local image
548 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
549 MockOpenLocalImageRequest mock_open_local_image_request
;
550 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
551 mock_local_image_ctx
.id
, &mock_local_image_ctx
,
554 // close remote image
555 expect_replay_requires_remote_image(mock_state_builder
, false);
556 expect_close_remote_image(mock_state_builder
, 0);
559 MockThreads
mock_threads(m_threads
);
560 MockInstanceWatcher mock_instance_watcher
;
561 MockBootstrapRequest
*request
= create_request(
562 &mock_threads
, &mock_instance_watcher
, "global image id",
563 "local mirror uuid", &ctx
);
565 ASSERT_EQ(-EINVAL
, ctx
.wait());
568 TEST_F(TestMockImageReplayerBootstrapRequest
, OpenLocalImageDNE
) {
571 // prepare local image
572 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
573 MockStateBuilder mock_state_builder
;
574 expect_send(mock_prepare_local_image_request
, mock_state_builder
,
575 m_local_image_ctx
->id
, m_local_image_ctx
->name
, 0);
577 // prepare remote image
578 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
579 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
580 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
581 expect_is_local_primary(mock_state_builder
, false);
583 // open the remote image
584 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
585 MockOpenImageRequest mock_open_image_request
;
586 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
587 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
589 // open the local image
590 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
591 MockOpenLocalImageRequest mock_open_local_image_request
;
592 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
593 mock_local_image_ctx
.id
, &mock_local_image_ctx
,
596 // create local image
597 expect_create_local_image(mock_state_builder
, "local image id", 0);
599 // re-open the local image
600 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
601 "local image id", &mock_local_image_ctx
, 0);
604 expect_prepare_replay(mock_state_builder
, false, false, 0);
605 expect_is_disconnected(mock_state_builder
, false);
607 // close remote image
608 expect_replay_requires_remote_image(mock_state_builder
, false);
609 expect_close_remote_image(mock_state_builder
, 0);
612 MockThreads
mock_threads(m_threads
);
613 MockInstanceWatcher mock_instance_watcher
;
614 MockBootstrapRequest
*request
= create_request(
615 &mock_threads
, &mock_instance_watcher
, "global image id",
616 "local mirror uuid", &ctx
);
618 ASSERT_EQ(0, ctx
.wait());
621 TEST_F(TestMockImageReplayerBootstrapRequest
, OpenLocalImagePrimary
) {
624 // prepare local image
625 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
626 MockStateBuilder mock_state_builder
;
627 expect_send(mock_prepare_local_image_request
, mock_state_builder
,
628 m_local_image_ctx
->id
, m_local_image_ctx
->name
, 0);
630 // prepare remote image
631 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
632 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
633 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
634 expect_is_local_primary(mock_state_builder
, false);
636 // open the remote image
637 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
638 MockOpenImageRequest mock_open_image_request
;
639 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
640 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
642 // open the local image
643 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
644 MockOpenLocalImageRequest mock_open_local_image_request
;
645 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
646 mock_local_image_ctx
.id
, &mock_local_image_ctx
,
649 // close remote image
650 expect_replay_requires_remote_image(mock_state_builder
, false);
651 expect_close_remote_image(mock_state_builder
, 0);
654 MockThreads
mock_threads(m_threads
);
655 MockInstanceWatcher mock_instance_watcher
;
656 MockBootstrapRequest
*request
= create_request(
657 &mock_threads
, &mock_instance_watcher
, "global image id",
658 "local mirror uuid", &ctx
);
660 ASSERT_EQ(-EREMOTEIO
, ctx
.wait());
663 TEST_F(TestMockImageReplayerBootstrapRequest
, CreateLocalImageError
) {
666 // prepare local image
667 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
668 MockStateBuilder mock_state_builder
;
669 expect_send(mock_prepare_local_image_request
, mock_state_builder
, "", "",
672 // prepare remote image
673 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
674 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
675 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
676 expect_is_local_primary(mock_state_builder
, false);
678 // open the remote image
679 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
680 MockOpenImageRequest mock_open_image_request
;
681 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
682 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
684 // create local image
685 expect_create_local_image(mock_state_builder
, "local image id", -EINVAL
);
687 // close remote image
688 expect_replay_requires_remote_image(mock_state_builder
, false);
689 expect_close_remote_image(mock_state_builder
, 0);
692 MockThreads
mock_threads(m_threads
);
693 MockInstanceWatcher mock_instance_watcher
;
694 MockBootstrapRequest
*request
= create_request(
695 &mock_threads
, &mock_instance_watcher
, "global image id",
696 "local mirror uuid", &ctx
);
698 ASSERT_EQ(-EINVAL
, ctx
.wait());
701 TEST_F(TestMockImageReplayerBootstrapRequest
, PrepareReplayError
) {
704 // prepare local image
705 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
706 MockStateBuilder mock_state_builder
;
707 expect_send(mock_prepare_local_image_request
, mock_state_builder
,
708 m_local_image_ctx
->id
, m_local_image_ctx
->name
, 0);
710 // prepare remote image
711 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
712 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
713 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
714 expect_is_local_primary(mock_state_builder
, false);
716 // open the remote image
717 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
718 MockOpenImageRequest mock_open_image_request
;
719 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
720 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
722 // open the local image
723 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
724 MockOpenLocalImageRequest mock_open_local_image_request
;
725 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
726 mock_local_image_ctx
.id
, &mock_local_image_ctx
, 0);
729 expect_prepare_replay(mock_state_builder
, false, false, -EINVAL
);
731 // close remote image
732 expect_replay_requires_remote_image(mock_state_builder
, false);
733 expect_close_remote_image(mock_state_builder
, 0);
736 MockThreads
mock_threads(m_threads
);
737 MockInstanceWatcher mock_instance_watcher
;
738 MockBootstrapRequest
*request
= create_request(
739 &mock_threads
, &mock_instance_watcher
, "global image id",
740 "local mirror uuid", &ctx
);
742 ASSERT_EQ(-EINVAL
, ctx
.wait());
745 TEST_F(TestMockImageReplayerBootstrapRequest
, PrepareReplayResyncRequested
) {
748 // prepare local image
749 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
750 MockStateBuilder mock_state_builder
;
751 expect_send(mock_prepare_local_image_request
, mock_state_builder
,
752 m_local_image_ctx
->id
, m_local_image_ctx
->name
, 0);
754 // prepare remote image
755 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
756 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
757 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
758 expect_is_local_primary(mock_state_builder
, false);
760 // open the remote image
761 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
762 MockOpenImageRequest mock_open_image_request
;
763 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
764 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
766 // open the local image
767 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
768 MockOpenLocalImageRequest mock_open_local_image_request
;
769 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
770 mock_local_image_ctx
.id
, &mock_local_image_ctx
, 0);
773 expect_prepare_replay(mock_state_builder
, true, false, 0);
775 // close remote image
776 expect_replay_requires_remote_image(mock_state_builder
, false);
777 expect_close_remote_image(mock_state_builder
, 0);
780 MockThreads
mock_threads(m_threads
);
781 MockInstanceWatcher mock_instance_watcher
;
782 MockBootstrapRequest
*request
= create_request(
783 &mock_threads
, &mock_instance_watcher
, "global image id",
784 "local mirror uuid", &ctx
);
786 ASSERT_EQ(0, ctx
.wait());
787 ASSERT_TRUE(m_do_resync
);
790 TEST_F(TestMockImageReplayerBootstrapRequest
, PrepareReplaySyncing
) {
793 // prepare local image
794 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
795 MockStateBuilder mock_state_builder
;
796 expect_send(mock_prepare_local_image_request
, mock_state_builder
,
797 m_local_image_ctx
->id
, m_local_image_ctx
->name
, 0);
799 // prepare remote image
800 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
801 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
802 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
803 expect_is_local_primary(mock_state_builder
, false);
805 // open the remote image
806 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
807 MockOpenImageRequest mock_open_image_request
;
808 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
809 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
811 // open the local image
812 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
813 MockOpenLocalImageRequest mock_open_local_image_request
;
814 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
815 mock_local_image_ctx
.id
, &mock_local_image_ctx
, 0);
818 expect_prepare_replay(mock_state_builder
, false, true, 0);
819 expect_is_disconnected(mock_state_builder
, false);
822 MockImageSync mock_image_sync
;
823 expect_image_sync(mock_image_sync
, 0);
825 // close remote image
826 expect_replay_requires_remote_image(mock_state_builder
, false);
827 expect_close_remote_image(mock_state_builder
, 0);
830 MockThreads
mock_threads(m_threads
);
831 MockInstanceWatcher mock_instance_watcher
;
832 MockBootstrapRequest
*request
= create_request(
833 &mock_threads
, &mock_instance_watcher
, "global image id",
834 "local mirror uuid", &ctx
);
836 ASSERT_EQ(0, ctx
.wait());
839 TEST_F(TestMockImageReplayerBootstrapRequest
, PrepareReplayDisconnected
) {
842 // prepare local image
843 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
844 MockStateBuilder mock_state_builder
;
845 expect_send(mock_prepare_local_image_request
, mock_state_builder
,
846 m_local_image_ctx
->id
, m_local_image_ctx
->name
, 0);
848 // prepare remote image
849 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
850 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
851 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
852 expect_is_local_primary(mock_state_builder
, false);
854 // open the remote image
855 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
856 MockOpenImageRequest mock_open_image_request
;
857 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
858 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
860 // open the local image
861 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
862 MockOpenLocalImageRequest mock_open_local_image_request
;
863 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
864 mock_local_image_ctx
.id
, &mock_local_image_ctx
, 0);
867 expect_prepare_replay(mock_state_builder
, false, false, 0);
868 expect_is_disconnected(mock_state_builder
, false);
870 // close remote image
871 expect_replay_requires_remote_image(mock_state_builder
, false);
872 expect_close_remote_image(mock_state_builder
, 0);
875 MockThreads
mock_threads(m_threads
);
876 MockInstanceWatcher mock_instance_watcher
;
877 MockBootstrapRequest
*request
= create_request(
878 &mock_threads
, &mock_instance_watcher
, "global image id",
879 "local mirror uuid", &ctx
);
881 ASSERT_EQ(0, ctx
.wait());
884 TEST_F(TestMockImageReplayerBootstrapRequest
, ImageSyncError
) {
887 // prepare local image
888 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
889 MockStateBuilder mock_state_builder
;
890 expect_send(mock_prepare_local_image_request
, mock_state_builder
,
891 m_local_image_ctx
->id
, m_local_image_ctx
->name
, 0);
893 // prepare remote image
894 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
895 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
896 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
897 expect_is_local_primary(mock_state_builder
, false);
899 // open the remote image
900 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
901 MockOpenImageRequest mock_open_image_request
;
902 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
903 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
905 // open the local image
906 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
907 MockOpenLocalImageRequest mock_open_local_image_request
;
908 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
909 mock_local_image_ctx
.id
, &mock_local_image_ctx
, 0);
912 expect_prepare_replay(mock_state_builder
, false, true, 0);
913 expect_is_disconnected(mock_state_builder
, false);
916 MockImageSync mock_image_sync
;
917 expect_image_sync(mock_image_sync
, -EINVAL
);
919 // close remote image
920 expect_replay_requires_remote_image(mock_state_builder
, false);
921 expect_close_remote_image(mock_state_builder
, 0);
924 MockThreads
mock_threads(m_threads
);
925 MockInstanceWatcher mock_instance_watcher
;
926 MockBootstrapRequest
*request
= create_request(
927 &mock_threads
, &mock_instance_watcher
, "global image id",
928 "local mirror uuid", &ctx
);
930 ASSERT_EQ(-EINVAL
, ctx
.wait());
933 TEST_F(TestMockImageReplayerBootstrapRequest
, ImageSyncCanceled
) {
936 // prepare local image
937 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
938 MockStateBuilder mock_state_builder
;
939 expect_send(mock_prepare_local_image_request
, mock_state_builder
,
940 m_local_image_ctx
->id
, m_local_image_ctx
->name
, 0);
942 // prepare remote image
943 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
944 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
945 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
946 expect_is_local_primary(mock_state_builder
, false);
948 // open the remote image
949 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
950 MockOpenImageRequest mock_open_image_request
;
951 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
952 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
954 // open the local image
955 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
956 MockOpenLocalImageRequest mock_open_local_image_request
;
957 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
958 mock_local_image_ctx
.id
, &mock_local_image_ctx
, 0);
961 expect_prepare_replay(mock_state_builder
, false, true, 0);
962 expect_is_disconnected(mock_state_builder
, false);
964 // close remote image
965 expect_replay_requires_remote_image(mock_state_builder
, false);
966 expect_close_remote_image(mock_state_builder
, 0);
969 MockThreads
mock_threads(m_threads
);
970 MockInstanceWatcher mock_instance_watcher
;
971 MockBootstrapRequest
*request
= create_request(
972 &mock_threads
, &mock_instance_watcher
, "global image id",
973 "local mirror uuid", &ctx
);
976 ASSERT_EQ(-ECANCELED
, ctx
.wait());
979 TEST_F(TestMockImageReplayerBootstrapRequest
, CloseRemoteImageError
) {
982 // prepare local image
983 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
984 MockStateBuilder mock_state_builder
;
985 expect_send(mock_prepare_local_image_request
, mock_state_builder
,
986 m_local_image_ctx
->id
, m_local_image_ctx
->name
, 0);
988 // prepare remote image
989 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
990 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
991 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
992 expect_is_local_primary(mock_state_builder
, false);
994 // open the remote image
995 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
996 MockOpenImageRequest mock_open_image_request
;
997 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
998 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
1000 // open the local image
1001 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
1002 MockOpenLocalImageRequest mock_open_local_image_request
;
1003 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
1004 mock_local_image_ctx
.id
, &mock_local_image_ctx
, 0);
1007 expect_prepare_replay(mock_state_builder
, false, false, 0);
1008 expect_is_disconnected(mock_state_builder
, false);
1010 // attempt to close remote image
1011 expect_replay_requires_remote_image(mock_state_builder
, false);
1012 expect_close_remote_image(mock_state_builder
, -EINVAL
);
1015 MockThreads
mock_threads(m_threads
);
1016 MockInstanceWatcher mock_instance_watcher
;
1017 MockBootstrapRequest
*request
= create_request(
1018 &mock_threads
, &mock_instance_watcher
, "global image id",
1019 "local mirror uuid", &ctx
);
1021 ASSERT_EQ(0, ctx
.wait());
1024 TEST_F(TestMockImageReplayerBootstrapRequest
, ReplayRequiresRemoteImage
) {
1027 // prepare local image
1028 MockPrepareLocalImageRequest mock_prepare_local_image_request
;
1029 MockStateBuilder mock_state_builder
;
1030 expect_send(mock_prepare_local_image_request
, mock_state_builder
,
1031 m_local_image_ctx
->id
, m_local_image_ctx
->name
, 0);
1033 // prepare remote image
1034 MockPrepareRemoteImageRequest mock_prepare_remote_image_request
;
1035 expect_send(mock_prepare_remote_image_request
, mock_state_builder
,
1036 "remote mirror uuid", m_remote_image_ctx
->id
, 0);
1037 expect_is_local_primary(mock_state_builder
, false);
1039 // open the remote image
1040 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
1041 MockOpenImageRequest mock_open_image_request
;
1042 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
1043 mock_remote_image_ctx
.id
, mock_remote_image_ctx
, 0);
1045 // open the local image
1046 librbd::MockTestImageCtx
mock_local_image_ctx(*m_local_image_ctx
);
1047 MockOpenLocalImageRequest mock_open_local_image_request
;
1048 expect_open_local_image(mock_open_local_image_request
, m_local_io_ctx
,
1049 mock_local_image_ctx
.id
, &mock_local_image_ctx
, 0);
1052 expect_prepare_replay(mock_state_builder
, false, false, 0);
1053 expect_is_disconnected(mock_state_builder
, false);
1055 // remote image is left open
1056 expect_replay_requires_remote_image(mock_state_builder
, true);
1059 MockThreads
mock_threads(m_threads
);
1060 MockInstanceWatcher mock_instance_watcher
;
1061 MockBootstrapRequest
*request
= create_request(
1062 &mock_threads
, &mock_instance_watcher
, "global image id",
1063 "local mirror uuid", &ctx
);
1065 ASSERT_EQ(0, ctx
.wait());
1068 } // namespace image_replayer
1069 } // namespace mirror