]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rbd_mirror/image_replayer/test_mock_PrepareRemoteImageRequest.cc
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / test / rbd_mirror / image_replayer / test_mock_PrepareRemoteImageRequest.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "test/rbd_mirror/test_mock_fixture.h"
5 #include "cls/rbd/cls_rbd_types.h"
6 #include "librbd/journal/TypeTraits.h"
7 #include "librbd/mirror/GetInfoRequest.h"
8 #include "tools/rbd_mirror/Threads.h"
9 #include "tools/rbd_mirror/image_replayer/GetMirrorImageIdRequest.h"
10 #include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h"
11 #include "tools/rbd_mirror/image_replayer/StateBuilder.h"
12 #include "tools/rbd_mirror/image_replayer/journal/StateBuilder.h"
13 #include "tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h"
14 #include "test/journal/mock/MockJournaler.h"
15 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
16 #include "test/librbd/mock/MockImageCtx.h"
17
18 namespace librbd {
19
20 namespace {
21
22 struct MockTestImageCtx : public librbd::MockImageCtx {
23 MockTestImageCtx(librbd::ImageCtx &image_ctx)
24 : librbd::MockImageCtx(image_ctx) {
25 }
26 };
27
28 } // anonymous namespace
29
30 namespace journal {
31
32 template <>
33 struct TypeTraits<MockTestImageCtx> {
34 typedef ::journal::MockJournalerProxy Journaler;
35 };
36
37 } // namespace journal
38
39 namespace mirror {
40
41 template<>
42 struct GetInfoRequest<librbd::MockTestImageCtx> {
43 static GetInfoRequest* s_instance;
44 cls::rbd::MirrorImage *mirror_image;
45 PromotionState *promotion_state;
46 std::string *primary_mirror_uuid;
47 Context *on_finish = nullptr;
48
49 static GetInfoRequest* create(librados::IoCtx& io_ctx,
50 librbd::asio::ContextWQ* context_wq,
51 const std::string& image_id,
52 cls::rbd::MirrorImage *mirror_image,
53 PromotionState *promotion_state,
54 std::string* primary_mirror_uuid,
55 Context *on_finish) {
56 ceph_assert(s_instance != nullptr);
57 s_instance->mirror_image = mirror_image;
58 s_instance->promotion_state = promotion_state;
59 s_instance->primary_mirror_uuid = primary_mirror_uuid;
60 s_instance->on_finish = on_finish;
61 return s_instance;
62 }
63
64 GetInfoRequest() {
65 ceph_assert(s_instance == nullptr);
66 s_instance = this;
67 }
68 ~GetInfoRequest() {
69 s_instance = nullptr;
70 }
71
72 MOCK_METHOD0(send, void());
73 };
74
75 GetInfoRequest<librbd::MockTestImageCtx>* GetInfoRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
76
77 } // namespace mirror
78 } // namespace librbd
79
80 namespace rbd {
81 namespace mirror {
82
83 template <>
84 struct Threads<librbd::MockTestImageCtx> {
85 ceph::mutex &timer_lock;
86 SafeTimer *timer;
87 librbd::asio::ContextWQ *work_queue;
88
89 Threads(Threads<librbd::ImageCtx> *threads)
90 : timer_lock(threads->timer_lock), timer(threads->timer),
91 work_queue(threads->work_queue) {
92 }
93 };
94
95 namespace image_replayer {
96
97 template <>
98 struct GetMirrorImageIdRequest<librbd::MockTestImageCtx> {
99 static GetMirrorImageIdRequest* s_instance;
100 std::string* image_id = nullptr;
101 Context* on_finish = nullptr;
102
103 static GetMirrorImageIdRequest* create(librados::IoCtx& io_ctx,
104 const std::string& global_image_id,
105 std::string* image_id,
106 Context* on_finish) {
107 ceph_assert(s_instance != nullptr);
108 s_instance->image_id = image_id;
109 s_instance->on_finish = on_finish;
110 return s_instance;
111 }
112
113 GetMirrorImageIdRequest() {
114 s_instance = this;
115 }
116
117 MOCK_METHOD0(send, void());
118 };
119
120 template<>
121 struct StateBuilder<librbd::MockTestImageCtx> {
122 std::string local_image_id;
123 librbd::mirror::PromotionState local_promotion_state =
124 librbd::mirror::PROMOTION_STATE_NON_PRIMARY;
125 std::string remote_image_id;
126 std::string remote_mirror_uuid;
127 librbd::mirror::PromotionState remote_promotion_state;
128
129 virtual ~StateBuilder() {}
130
131 MOCK_CONST_METHOD0(get_mirror_image_mode, cls::rbd::MirrorImageMode());
132 };
133
134 GetMirrorImageIdRequest<librbd::MockTestImageCtx>* GetMirrorImageIdRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
135
136 namespace journal {
137
138 template<>
139 struct StateBuilder<librbd::MockTestImageCtx>
140 : public image_replayer::StateBuilder<librbd::MockTestImageCtx> {
141 static StateBuilder* s_instance;
142
143 cls::rbd::MirrorImageMode mirror_image_mode =
144 cls::rbd::MIRROR_IMAGE_MODE_JOURNAL;
145
146 ::journal::MockJournalerProxy* remote_journaler = nullptr;
147 cls::journal::ClientState remote_client_state;
148 librbd::journal::MirrorPeerClientMeta remote_client_meta;
149
150 static StateBuilder* create(const std::string&) {
151 ceph_assert(s_instance != nullptr);
152 return s_instance;
153 }
154
155 StateBuilder() {
156 s_instance = this;
157 }
158 };
159
160 StateBuilder<librbd::MockTestImageCtx>* StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr;
161
162 } // namespace journal
163
164 namespace snapshot {
165
166 template<>
167 struct StateBuilder<librbd::MockTestImageCtx>
168 : public image_replayer::StateBuilder<librbd::MockTestImageCtx> {
169 static StateBuilder* s_instance;
170
171 cls::rbd::MirrorImageMode mirror_image_mode =
172 cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT;
173
174 std::string remote_mirror_peer_uuid;
175
176 static StateBuilder* create(const std::string&) {
177 ceph_assert(s_instance != nullptr);
178 return s_instance;
179 }
180
181 StateBuilder() {
182 s_instance = this;
183 }
184 };
185
186 StateBuilder<librbd::MockTestImageCtx>* StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr;
187
188 } // namespace snapshot
189 } // namespace image_replayer
190 } // namespace mirror
191 } // namespace rbd
192
193 // template definitions
194 #include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.cc"
195
196 namespace rbd {
197 namespace mirror {
198 namespace image_replayer {
199
200 using ::testing::_;
201 using ::testing::DoAll;
202 using ::testing::InSequence;
203 using ::testing::Invoke;
204 using ::testing::Return;
205 using ::testing::StrEq;
206 using ::testing::WithArg;
207
208 class TestMockImageReplayerPrepareRemoteImageRequest : public TestMockFixture {
209 public:
210 typedef Threads<librbd::MockTestImageCtx> MockThreads;
211 typedef PrepareRemoteImageRequest<librbd::MockTestImageCtx> MockPrepareRemoteImageRequest;
212 typedef GetMirrorImageIdRequest<librbd::MockTestImageCtx> MockGetMirrorImageIdRequest;
213 typedef StateBuilder<librbd::MockTestImageCtx> MockStateBuilder;
214 typedef journal::StateBuilder<librbd::MockTestImageCtx> MockJournalStateBuilder;
215 typedef snapshot::StateBuilder<librbd::MockTestImageCtx> MockSnapshotStateBuilder;
216 typedef librbd::mirror::GetInfoRequest<librbd::MockTestImageCtx> MockGetMirrorInfoRequest;
217
218 void expect_get_mirror_image_mode(MockStateBuilder& mock_state_builder,
219 cls::rbd::MirrorImageMode mirror_image_mode) {
220 EXPECT_CALL(mock_state_builder, get_mirror_image_mode())
221 .WillOnce(Return(mirror_image_mode));
222 }
223
224 void expect_get_mirror_image_id(MockGetMirrorImageIdRequest& mock_get_mirror_image_id_request,
225 const std::string& image_id, int r) {
226 EXPECT_CALL(mock_get_mirror_image_id_request, send())
227 .WillOnce(Invoke([&mock_get_mirror_image_id_request, image_id, r]() {
228 *mock_get_mirror_image_id_request.image_id = image_id;
229 mock_get_mirror_image_id_request.on_finish->complete(r);
230 }));
231 }
232
233 void expect_get_mirror_info(
234 MockGetMirrorInfoRequest &mock_get_mirror_info_request,
235 const cls::rbd::MirrorImage &mirror_image,
236 librbd::mirror::PromotionState promotion_state,
237 const std::string& primary_mirror_uuid, int r) {
238 EXPECT_CALL(mock_get_mirror_info_request, send())
239 .WillOnce(Invoke([this, &mock_get_mirror_info_request, mirror_image,
240 promotion_state, primary_mirror_uuid, r]() {
241 *mock_get_mirror_info_request.mirror_image = mirror_image;
242 *mock_get_mirror_info_request.promotion_state = promotion_state;
243 *mock_get_mirror_info_request.primary_mirror_uuid =
244 primary_mirror_uuid;
245 m_threads->work_queue->queue(
246 mock_get_mirror_info_request.on_finish, r);
247 }));
248 }
249
250 void expect_journaler_get_client(::journal::MockJournaler &mock_journaler,
251 const std::string &client_id,
252 cls::journal::Client &client, int r) {
253 EXPECT_CALL(mock_journaler, get_client(StrEq(client_id), _, _))
254 .WillOnce(DoAll(WithArg<1>(Invoke([client](cls::journal::Client *out_client) {
255 *out_client = client;
256 })),
257 WithArg<2>(Invoke([this, r](Context *on_finish) {
258 m_threads->work_queue->queue(on_finish, r);
259 }))));
260 }
261
262 void expect_journaler_register_client(::journal::MockJournaler &mock_journaler,
263 const librbd::journal::ClientData &client_data,
264 int r) {
265 bufferlist bl;
266 encode(client_data, bl);
267
268 EXPECT_CALL(mock_journaler, register_client(ContentsEqual(bl), _))
269 .WillOnce(WithArg<1>(Invoke([this, r](Context *on_finish) {
270 m_threads->work_queue->queue(on_finish, r);
271 })));
272 }
273 };
274
275 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessJournal) {
276 ::journal::MockJournaler mock_remote_journaler;
277 MockThreads mock_threads(m_threads);
278
279 InSequence seq;
280 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
281 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
282 "remote image id", 0);
283
284 MockGetMirrorInfoRequest mock_get_mirror_info_request;
285 expect_get_mirror_info(mock_get_mirror_info_request,
286 {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
287 "global image id",
288 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
289 librbd::mirror::PROMOTION_STATE_PRIMARY,
290 "remote mirror uuid", 0);
291
292 EXPECT_CALL(mock_remote_journaler, construct());
293
294 librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
295 mirror_peer_client_meta.image_id = "local image id";
296 mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING;
297 librbd::journal::ClientData client_data{mirror_peer_client_meta};
298 cls::journal::Client client;
299 client.state = cls::journal::CLIENT_STATE_DISCONNECTED;
300 encode(client_data, client.data);
301 expect_journaler_get_client(mock_remote_journaler, "local mirror uuid",
302 client, 0);
303
304 MockJournalStateBuilder mock_journal_state_builder;
305 MockStateBuilder* mock_state_builder = nullptr;
306 C_SaferCond ctx;
307 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
308 m_local_io_ctx,
309 m_remote_io_ctx,
310 "global image id",
311 "local mirror uuid",
312 {"remote mirror uuid", ""},
313 nullptr,
314 &mock_state_builder,
315 &ctx);
316 req->send();
317
318 ASSERT_EQ(0, ctx.wait());
319 ASSERT_TRUE(mock_state_builder != nullptr);
320 ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
321 mock_journal_state_builder.mirror_image_mode);
322 ASSERT_EQ(std::string("remote mirror uuid"),
323 mock_journal_state_builder.remote_mirror_uuid);
324 ASSERT_EQ(std::string("remote image id"),
325 mock_journal_state_builder.remote_image_id);
326 ASSERT_EQ(librbd::mirror::PROMOTION_STATE_PRIMARY,
327 mock_journal_state_builder.remote_promotion_state);
328 ASSERT_TRUE(mock_journal_state_builder.remote_journaler != nullptr);
329 ASSERT_EQ(cls::journal::CLIENT_STATE_DISCONNECTED,
330 mock_journal_state_builder.remote_client_state);
331 }
332
333 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessSnapshot) {
334 MockThreads mock_threads(m_threads);
335
336 InSequence seq;
337 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
338 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
339 "remote image id", 0);
340
341 MockGetMirrorInfoRequest mock_get_mirror_info_request;
342 expect_get_mirror_info(mock_get_mirror_info_request,
343 {cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
344 "global image id",
345 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
346 librbd::mirror::PROMOTION_STATE_PRIMARY,
347 "remote mirror uuid", 0);
348
349 MockSnapshotStateBuilder mock_snapshot_state_builder;
350 MockStateBuilder* mock_state_builder = nullptr;
351 C_SaferCond ctx;
352 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
353 m_local_io_ctx,
354 m_remote_io_ctx,
355 "global image id",
356 "local mirror uuid",
357 {"remote mirror uuid",
358 "remote mirror peer uuid"},
359 nullptr,
360 &mock_state_builder,
361 &ctx);
362 req->send();
363
364 ASSERT_EQ(0, ctx.wait());
365 ASSERT_TRUE(mock_state_builder != nullptr);
366 ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
367 mock_snapshot_state_builder.mirror_image_mode);
368 ASSERT_EQ(std::string("remote mirror uuid"),
369 mock_snapshot_state_builder.remote_mirror_uuid);
370 ASSERT_EQ(std::string("remote mirror peer uuid"),
371 mock_snapshot_state_builder.remote_mirror_peer_uuid);
372 ASSERT_EQ(std::string("remote image id"),
373 mock_snapshot_state_builder.remote_image_id);
374 ASSERT_EQ(librbd::mirror::PROMOTION_STATE_PRIMARY,
375 mock_snapshot_state_builder.remote_promotion_state);
376 }
377
378 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessNotRegistered) {
379 ::journal::MockJournaler mock_remote_journaler;
380 MockThreads mock_threads(m_threads);
381
382 InSequence seq;
383 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
384 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
385 "remote image id", 0);
386
387 MockGetMirrorInfoRequest mock_get_mirror_info_request;
388 expect_get_mirror_info(mock_get_mirror_info_request,
389 {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
390 "global image id",
391 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
392 librbd::mirror::PROMOTION_STATE_PRIMARY,
393 "remote mirror uuid", 0);
394
395 MockJournalStateBuilder mock_journal_state_builder;
396 expect_get_mirror_image_mode(mock_journal_state_builder,
397 cls::rbd::MIRROR_IMAGE_MODE_JOURNAL);
398
399 EXPECT_CALL(mock_remote_journaler, construct());
400
401 cls::journal::Client client;
402 expect_journaler_get_client(mock_remote_journaler, "local mirror uuid",
403 client, -ENOENT);
404
405 librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
406 mirror_peer_client_meta.image_id = "local image id";
407 mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
408 librbd::journal::ClientData client_data{mirror_peer_client_meta};
409 expect_journaler_register_client(mock_remote_journaler, client_data, 0);
410
411 mock_journal_state_builder.local_image_id = "local image id";
412 MockStateBuilder* mock_state_builder = &mock_journal_state_builder;
413 C_SaferCond ctx;
414 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
415 m_local_io_ctx,
416 m_remote_io_ctx,
417 "global image id",
418 "local mirror uuid",
419 {"remote mirror uuid", ""},
420 nullptr,
421 &mock_state_builder,
422 &ctx);
423 req->send();
424
425 ASSERT_EQ(0, ctx.wait());
426 ASSERT_TRUE(mock_state_builder != nullptr);
427 ASSERT_EQ(std::string("remote image id"),
428 mock_journal_state_builder.remote_image_id);
429 ASSERT_EQ(librbd::mirror::PROMOTION_STATE_PRIMARY,
430 mock_journal_state_builder.remote_promotion_state);
431 ASSERT_TRUE(mock_journal_state_builder.remote_journaler != nullptr);
432 ASSERT_EQ(cls::journal::CLIENT_STATE_CONNECTED,
433 mock_journal_state_builder.remote_client_state);
434 }
435
436 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, GetMirrorImageIdError) {
437 MockThreads mock_threads(m_threads);
438
439 InSequence seq;
440 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
441 expect_get_mirror_image_id(mock_get_mirror_image_id_request, "", -EINVAL);
442
443 MockJournalStateBuilder mock_journal_state_builder;
444 MockStateBuilder* mock_state_builder = &mock_journal_state_builder;
445 C_SaferCond ctx;
446 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
447 m_local_io_ctx,
448 m_remote_io_ctx,
449 "global image id",
450 "local mirror uuid",
451 {"remote mirror uuid", ""},
452 nullptr,
453 &mock_state_builder,
454 &ctx);
455 req->send();
456
457 ASSERT_EQ(-EINVAL, ctx.wait());
458 ASSERT_TRUE(mock_journal_state_builder.remote_journaler == nullptr);
459 }
460
461 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, GetMirrorInfoError) {
462 MockThreads mock_threads(m_threads);
463
464 InSequence seq;
465 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
466 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
467 "remote image id", 0);
468
469 MockGetMirrorInfoRequest mock_get_mirror_info_request;
470 expect_get_mirror_info(mock_get_mirror_info_request,
471 {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
472 "global image id",
473 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
474 librbd::mirror::PROMOTION_STATE_PRIMARY,
475 "remote mirror uuid", -EINVAL);
476
477 MockJournalStateBuilder mock_journal_state_builder;
478 MockStateBuilder* mock_state_builder = nullptr;
479 C_SaferCond ctx;
480 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
481 m_local_io_ctx,
482 m_remote_io_ctx,
483 "global image id",
484 "local mirror uuid",
485 {"remote mirror uuid", ""},
486 nullptr,
487 &mock_state_builder,
488 &ctx);
489 req->send();
490
491 ASSERT_EQ(-EINVAL, ctx.wait());
492 ASSERT_TRUE(mock_state_builder == nullptr);
493 }
494
495 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, GetClientError) {
496 ::journal::MockJournaler mock_remote_journaler;
497 MockThreads mock_threads(m_threads);
498
499 InSequence seq;
500 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
501 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
502 "remote image id", 0);
503
504 MockGetMirrorInfoRequest mock_get_mirror_info_request;
505 expect_get_mirror_info(mock_get_mirror_info_request,
506 {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
507 "global image id",
508 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
509 librbd::mirror::PROMOTION_STATE_PRIMARY,
510 "remote mirror uuid", 0);
511
512 EXPECT_CALL(mock_remote_journaler, construct());
513
514 cls::journal::Client client;
515 expect_journaler_get_client(mock_remote_journaler, "local mirror uuid",
516 client, -EINVAL);
517
518 MockJournalStateBuilder mock_journal_state_builder;
519 MockStateBuilder* mock_state_builder = nullptr;
520 C_SaferCond ctx;
521 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
522 m_local_io_ctx,
523 m_remote_io_ctx,
524 "global image id",
525 "local mirror uuid",
526 {"remote mirror uuid", ""},
527 nullptr,
528 &mock_state_builder,
529 &ctx);
530 req->send();
531
532 ASSERT_EQ(-EINVAL, ctx.wait());
533 ASSERT_TRUE(mock_state_builder == nullptr);
534 }
535
536 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, RegisterClientError) {
537 ::journal::MockJournaler mock_remote_journaler;
538 MockThreads mock_threads(m_threads);
539
540 InSequence seq;
541 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
542 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
543 "remote image id", 0);
544
545 MockGetMirrorInfoRequest mock_get_mirror_info_request;
546 expect_get_mirror_info(mock_get_mirror_info_request,
547 {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
548 "global image id",
549 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
550 librbd::mirror::PROMOTION_STATE_PRIMARY,
551 "remote mirror uuid", 0);
552
553 MockJournalStateBuilder mock_journal_state_builder;
554 expect_get_mirror_image_mode(mock_journal_state_builder,
555 cls::rbd::MIRROR_IMAGE_MODE_JOURNAL);
556
557 EXPECT_CALL(mock_remote_journaler, construct());
558
559 cls::journal::Client client;
560 expect_journaler_get_client(mock_remote_journaler, "local mirror uuid",
561 client, -ENOENT);
562
563 librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
564 mirror_peer_client_meta.image_id = "local image id";
565 mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
566 librbd::journal::ClientData client_data{mirror_peer_client_meta};
567 expect_journaler_register_client(mock_remote_journaler, client_data, -EINVAL);
568
569 mock_journal_state_builder.local_image_id = "local image id";
570 MockStateBuilder* mock_state_builder = &mock_journal_state_builder;
571 C_SaferCond ctx;
572 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
573 m_local_io_ctx,
574 m_remote_io_ctx,
575 "global image id",
576 "local mirror uuid",
577 {"remote mirror uuid", ""},
578 nullptr,
579 &mock_state_builder,
580 &ctx);
581 req->send();
582
583 ASSERT_EQ(-EINVAL, ctx.wait());
584 }
585
586 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, MirrorImageIdDNEJournal) {
587 MockThreads mock_threads(m_threads);
588
589 InSequence seq;
590 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
591 expect_get_mirror_image_id(mock_get_mirror_image_id_request, "", -ENOENT);
592
593 MockJournalStateBuilder mock_journal_state_builder;
594 MockStateBuilder* mock_state_builder = &mock_journal_state_builder;
595 C_SaferCond ctx;
596 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
597 m_local_io_ctx,
598 m_remote_io_ctx,
599 "global image id",
600 "local mirror uuid",
601 {"remote mirror uuid", ""},
602 nullptr,
603 &mock_state_builder,
604 &ctx);
605 req->send();
606
607 ASSERT_EQ(-ENOENT, ctx.wait());
608 ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
609 mock_journal_state_builder.mirror_image_mode);
610 ASSERT_EQ("remote mirror uuid",
611 mock_journal_state_builder.remote_mirror_uuid);
612 ASSERT_EQ("", mock_journal_state_builder.remote_image_id);
613 }
614
615 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, MirrorImageIdDNESnapshot) {
616 MockThreads mock_threads(m_threads);
617
618 InSequence seq;
619 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
620 expect_get_mirror_image_id(mock_get_mirror_image_id_request, "", -ENOENT);
621
622 MockSnapshotStateBuilder mock_snapshot_state_builder;
623 MockStateBuilder* mock_state_builder = &mock_snapshot_state_builder;
624 C_SaferCond ctx;
625 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
626 m_local_io_ctx,
627 m_remote_io_ctx,
628 "global image id",
629 "local mirror uuid",
630 {"remote mirror uuid",
631 "remote mirror peer uuid"},
632 nullptr,
633 &mock_state_builder,
634 &ctx);
635 req->send();
636
637 ASSERT_EQ(-ENOENT, ctx.wait());
638 ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
639 mock_snapshot_state_builder.mirror_image_mode);
640 ASSERT_EQ("remote mirror uuid",
641 mock_snapshot_state_builder.remote_mirror_uuid);
642 ASSERT_EQ("remote mirror peer uuid",
643 mock_snapshot_state_builder.remote_mirror_peer_uuid);
644 ASSERT_EQ("", mock_snapshot_state_builder.remote_image_id);
645 }
646
647 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, MirrorInfoDNEJournal) {
648 MockThreads mock_threads(m_threads);
649
650 InSequence seq;
651 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
652 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
653 "remote image id", 0);
654
655 MockGetMirrorInfoRequest mock_get_mirror_info_request;
656 expect_get_mirror_info(mock_get_mirror_info_request,
657 {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
658 "global image id",
659 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
660 librbd::mirror::PROMOTION_STATE_PRIMARY,
661 "remote mirror uuid", -ENOENT);
662
663 MockJournalStateBuilder mock_journal_state_builder;
664 MockStateBuilder* mock_state_builder = &mock_journal_state_builder;
665 C_SaferCond ctx;
666 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
667 m_local_io_ctx,
668 m_remote_io_ctx,
669 "global image id",
670 "local mirror uuid",
671 {"remote mirror uuid", ""},
672 nullptr,
673 &mock_state_builder,
674 &ctx);
675 req->send();
676
677 ASSERT_EQ(-ENOENT, ctx.wait());
678 ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
679 mock_journal_state_builder.mirror_image_mode);
680 ASSERT_EQ("remote mirror uuid",
681 mock_journal_state_builder.remote_mirror_uuid);
682 ASSERT_EQ("", mock_journal_state_builder.remote_image_id);
683 }
684
685 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, MirrorInfoDNESnapshot) {
686 MockThreads mock_threads(m_threads);
687
688 InSequence seq;
689 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
690 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
691 "remote image id", 0);
692
693 MockGetMirrorInfoRequest mock_get_mirror_info_request;
694 expect_get_mirror_info(mock_get_mirror_info_request,
695 {cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
696 "global image id",
697 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
698 librbd::mirror::PROMOTION_STATE_PRIMARY,
699 "remote mirror uuid", -ENOENT);
700
701 MockSnapshotStateBuilder mock_snapshot_state_builder;
702 MockStateBuilder* mock_state_builder = &mock_snapshot_state_builder;
703 C_SaferCond ctx;
704 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
705 m_local_io_ctx,
706 m_remote_io_ctx,
707 "global image id",
708 "local mirror uuid",
709 {"remote mirror uuid",
710 "remote mirror peer uuid"},
711 nullptr,
712 &mock_state_builder,
713 &ctx);
714 req->send();
715
716 ASSERT_EQ(-ENOENT, ctx.wait());
717 ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
718 mock_snapshot_state_builder.mirror_image_mode);
719 ASSERT_EQ("remote mirror uuid",
720 mock_snapshot_state_builder.remote_mirror_uuid);
721 ASSERT_EQ("remote mirror peer uuid",
722 mock_snapshot_state_builder.remote_mirror_peer_uuid);
723 ASSERT_EQ("", mock_snapshot_state_builder.remote_image_id);
724 }
725
726 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, MirrorInfoDisablingJournal) {
727 MockThreads mock_threads(m_threads);
728
729 InSequence seq;
730 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
731 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
732 "remote image id", 0);
733
734 MockGetMirrorInfoRequest mock_get_mirror_info_request;
735 expect_get_mirror_info(mock_get_mirror_info_request,
736 {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
737 "global image id",
738 cls::rbd::MIRROR_IMAGE_STATE_DISABLING},
739 librbd::mirror::PROMOTION_STATE_PRIMARY,
740 "remote mirror uuid", 0);
741
742 MockJournalStateBuilder mock_journal_state_builder;
743 expect_get_mirror_image_mode(mock_journal_state_builder,
744 cls::rbd::MIRROR_IMAGE_MODE_JOURNAL);
745 MockStateBuilder* mock_state_builder = &mock_journal_state_builder;
746 C_SaferCond ctx;
747 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
748 m_local_io_ctx,
749 m_remote_io_ctx,
750 "global image id",
751 "local mirror uuid",
752 {"remote mirror uuid", ""},
753 nullptr,
754 &mock_state_builder,
755 &ctx);
756 req->send();
757
758 ASSERT_EQ(-ENOENT, ctx.wait());
759 ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
760 mock_journal_state_builder.mirror_image_mode);
761 ASSERT_EQ("remote mirror uuid",
762 mock_journal_state_builder.remote_mirror_uuid);
763 ASSERT_EQ("", mock_journal_state_builder.remote_image_id);
764 }
765
766 TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, MirrorInfoDisablingSnapshot) {
767 MockThreads mock_threads(m_threads);
768
769 InSequence seq;
770 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
771 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
772 "remote image id", 0);
773
774 MockGetMirrorInfoRequest mock_get_mirror_info_request;
775 expect_get_mirror_info(mock_get_mirror_info_request,
776 {cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
777 "global image id",
778 cls::rbd::MIRROR_IMAGE_STATE_DISABLING},
779 librbd::mirror::PROMOTION_STATE_PRIMARY,
780 "remote mirror uuid", 0);
781
782 MockSnapshotStateBuilder mock_snapshot_state_builder;
783 expect_get_mirror_image_mode(mock_snapshot_state_builder,
784 cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT);
785 MockStateBuilder* mock_state_builder = &mock_snapshot_state_builder;
786 C_SaferCond ctx;
787 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
788 m_local_io_ctx,
789 m_remote_io_ctx,
790 "global image id",
791 "local mirror uuid",
792 {"remote mirror uuid",
793 "remote mirror peer uuid"},
794 nullptr,
795 &mock_state_builder,
796 &ctx);
797 req->send();
798
799 ASSERT_EQ(-ENOENT, ctx.wait());
800 ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
801 mock_snapshot_state_builder.mirror_image_mode);
802 ASSERT_EQ("remote mirror uuid",
803 mock_snapshot_state_builder.remote_mirror_uuid);
804 ASSERT_EQ("remote mirror peer uuid",
805 mock_snapshot_state_builder.remote_mirror_peer_uuid);
806 ASSERT_EQ("", mock_snapshot_state_builder.remote_image_id);
807 }
808
809 } // namespace image_replayer
810 } // namespace mirror
811 } // namespace rbd