]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/rbd_mirror/image_replayer/test_mock_PrepareRemoteImageRequest.cc
import 15.2.0 Octopus source
[ceph.git] / ceph / src / test / rbd_mirror / image_replayer / test_mock_PrepareRemoteImageRequest.cc
CommitLineData
d2e6a577
FG
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"
9f95a23c 7#include "librbd/mirror/GetInfoRequest.h"
b32b8144 8#include "tools/rbd_mirror/Threads.h"
d2e6a577
FG
9#include "tools/rbd_mirror/image_replayer/GetMirrorImageIdRequest.h"
10#include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h"
9f95a23c
TL
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"
b32b8144 14#include "test/journal/mock/MockJournaler.h"
d2e6a577
FG
15#include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
16#include "test/librbd/mock/MockImageCtx.h"
17
18namespace librbd {
19
20namespace {
21
22struct MockTestImageCtx : public librbd::MockImageCtx {
23 MockTestImageCtx(librbd::ImageCtx &image_ctx)
24 : librbd::MockImageCtx(image_ctx) {
25 }
26};
27
28} // anonymous namespace
b32b8144
FG
29
30namespace journal {
31
32template <>
33struct TypeTraits<MockTestImageCtx> {
34 typedef ::journal::MockJournalerProxy Journaler;
35};
36
37} // namespace journal
9f95a23c
TL
38
39namespace mirror {
40
41template<>
42struct 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 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
75GetInfoRequest<librbd::MockTestImageCtx>* GetInfoRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
76
77} // namespace mirror
d2e6a577
FG
78} // namespace librbd
79
80namespace rbd {
81namespace mirror {
b32b8144
FG
82
83template <>
84struct Threads<librbd::MockTestImageCtx> {
9f95a23c 85 ceph::mutex &timer_lock;
b32b8144
FG
86 SafeTimer *timer;
87 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
d2e6a577
FG
95namespace image_replayer {
96
97template <>
98struct 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) {
11fdf7f2 107 ceph_assert(s_instance != nullptr);
d2e6a577
FG
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
9f95a23c
TL
120template<>
121struct 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
d2e6a577
FG
134GetMirrorImageIdRequest<librbd::MockTestImageCtx>* GetMirrorImageIdRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
135
9f95a23c
TL
136namespace journal {
137
138template<>
139struct 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
160StateBuilder<librbd::MockTestImageCtx>* StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr;
161
162} // namespace journal
163
164namespace snapshot {
165
166template<>
167struct 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
186StateBuilder<librbd::MockTestImageCtx>* StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr;
187
188} // namespace snapshot
d2e6a577
FG
189} // namespace image_replayer
190} // namespace mirror
191} // namespace rbd
192
193// template definitions
194#include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.cc"
195
196namespace rbd {
197namespace mirror {
198namespace image_replayer {
199
200using ::testing::_;
201using ::testing::DoAll;
202using ::testing::InSequence;
203using ::testing::Invoke;
204using ::testing::Return;
205using ::testing::StrEq;
206using ::testing::WithArg;
207
208class TestMockImageReplayerPrepareRemoteImageRequest : public TestMockFixture {
209public:
b32b8144 210 typedef Threads<librbd::MockTestImageCtx> MockThreads;
d2e6a577
FG
211 typedef PrepareRemoteImageRequest<librbd::MockTestImageCtx> MockPrepareRemoteImageRequest;
212 typedef GetMirrorImageIdRequest<librbd::MockTestImageCtx> MockGetMirrorImageIdRequest;
9f95a23c
TL
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 }
d2e6a577
FG
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
9f95a23c
TL
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 }));
d2e6a577 248 }
b32b8144
FG
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;
11fdf7f2 266 encode(client_data, bl);
b32b8144
FG
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 }
d2e6a577
FG
273};
274
9f95a23c
TL
275TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessJournal) {
276 ::journal::MockJournaler mock_remote_journaler;
b32b8144
FG
277 MockThreads mock_threads(m_threads);
278
d2e6a577 279 InSequence seq;
d2e6a577
FG
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
9f95a23c
TL
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
b32b8144
FG
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;
11fdf7f2 300 encode(client_data, client.data);
b32b8144
FG
301 expect_journaler_get_client(mock_remote_journaler, "local mirror uuid",
302 client, 0);
303
9f95a23c
TL
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
333TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessSnapshot) {
334 ::journal::MockJournaler mock_remote_journaler;
335 MockThreads mock_threads(m_threads);
336
337 InSequence seq;
338 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
339 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
340 "remote image id", 0);
341
342 MockGetMirrorInfoRequest mock_get_mirror_info_request;
343 expect_get_mirror_info(mock_get_mirror_info_request,
344 {cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
345 "global image id",
346 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
347 librbd::mirror::PROMOTION_STATE_PRIMARY,
348 "remote mirror uuid", 0);
349
350 MockSnapshotStateBuilder mock_snapshot_state_builder;
351 MockStateBuilder* mock_state_builder = nullptr;
d2e6a577 352 C_SaferCond ctx;
b32b8144 353 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
9f95a23c 354 m_local_io_ctx,
b32b8144 355 m_remote_io_ctx,
d2e6a577 356 "global image id",
b32b8144 357 "local mirror uuid",
9f95a23c
TL
358 {"remote mirror uuid",
359 "remote mirror peer uuid"},
360 nullptr,
361 &mock_state_builder,
d2e6a577
FG
362 &ctx);
363 req->send();
364
365 ASSERT_EQ(0, ctx.wait());
9f95a23c
TL
366 ASSERT_TRUE(mock_state_builder != nullptr);
367 ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT,
368 mock_snapshot_state_builder.mirror_image_mode);
369 ASSERT_EQ(std::string("remote mirror uuid"),
370 mock_snapshot_state_builder.remote_mirror_uuid);
371 ASSERT_EQ(std::string("remote mirror peer uuid"),
372 mock_snapshot_state_builder.remote_mirror_peer_uuid);
373 ASSERT_EQ(std::string("remote image id"),
374 mock_snapshot_state_builder.remote_image_id);
375 ASSERT_EQ(librbd::mirror::PROMOTION_STATE_PRIMARY,
376 mock_snapshot_state_builder.remote_promotion_state);
b32b8144
FG
377}
378
379TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessNotRegistered) {
9f95a23c 380 ::journal::MockJournaler mock_remote_journaler;
b32b8144
FG
381 MockThreads mock_threads(m_threads);
382
383 InSequence seq;
b32b8144
FG
384 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
385 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
386 "remote image id", 0);
387
9f95a23c
TL
388 MockGetMirrorInfoRequest mock_get_mirror_info_request;
389 expect_get_mirror_info(mock_get_mirror_info_request,
390 {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
391 "global image id",
392 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
393 librbd::mirror::PROMOTION_STATE_PRIMARY,
394 "remote mirror uuid", 0);
395
396 MockJournalStateBuilder mock_journal_state_builder;
397 expect_get_mirror_image_mode(mock_journal_state_builder,
398 cls::rbd::MIRROR_IMAGE_MODE_JOURNAL);
399
b32b8144
FG
400 EXPECT_CALL(mock_remote_journaler, construct());
401
402 cls::journal::Client client;
403 expect_journaler_get_client(mock_remote_journaler, "local mirror uuid",
404 client, -ENOENT);
405
406 librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
407 mirror_peer_client_meta.image_id = "local image id";
408 mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
409 librbd::journal::ClientData client_data{mirror_peer_client_meta};
410 expect_journaler_register_client(mock_remote_journaler, client_data, 0);
411
9f95a23c
TL
412 mock_journal_state_builder.local_image_id = "local image id";
413 MockStateBuilder* mock_state_builder = &mock_journal_state_builder;
b32b8144
FG
414 C_SaferCond ctx;
415 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
9f95a23c 416 m_local_io_ctx,
b32b8144
FG
417 m_remote_io_ctx,
418 "global image id",
419 "local mirror uuid",
9f95a23c
TL
420 {"remote mirror uuid", ""},
421 nullptr,
422 &mock_state_builder,
b32b8144
FG
423 &ctx);
424 req->send();
425
426 ASSERT_EQ(0, ctx.wait());
9f95a23c
TL
427 ASSERT_TRUE(mock_state_builder != nullptr);
428 ASSERT_EQ(std::string("remote image id"),
429 mock_journal_state_builder.remote_image_id);
430 ASSERT_EQ(librbd::mirror::PROMOTION_STATE_PRIMARY,
431 mock_journal_state_builder.remote_promotion_state);
432 ASSERT_TRUE(mock_journal_state_builder.remote_journaler != nullptr);
433 ASSERT_EQ(cls::journal::CLIENT_STATE_CONNECTED,
434 mock_journal_state_builder.remote_client_state);
d2e6a577
FG
435}
436
9f95a23c
TL
437TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, MirrorImageIdError) {
438 ::journal::MockJournaler mock_remote_journaler;
b32b8144
FG
439 MockThreads mock_threads(m_threads);
440
d2e6a577 441 InSequence seq;
9f95a23c
TL
442 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
443 expect_get_mirror_image_id(mock_get_mirror_image_id_request, "", -EINVAL);
d2e6a577 444
9f95a23c
TL
445 MockJournalStateBuilder mock_journal_state_builder;
446 MockStateBuilder* mock_state_builder = &mock_journal_state_builder;
d2e6a577 447 C_SaferCond ctx;
b32b8144 448 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
9f95a23c 449 m_local_io_ctx,
b32b8144 450 m_remote_io_ctx,
d2e6a577 451 "global image id",
b32b8144 452 "local mirror uuid",
9f95a23c
TL
453 {"remote mirror uuid", ""},
454 nullptr,
455 &mock_state_builder,
d2e6a577
FG
456 &ctx);
457 req->send();
458
459 ASSERT_EQ(-EINVAL, ctx.wait());
9f95a23c 460 ASSERT_TRUE(mock_journal_state_builder.remote_journaler == nullptr);
d2e6a577
FG
461}
462
9f95a23c
TL
463TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, GetMirrorInfoError) {
464 ::journal::MockJournaler mock_remote_journaler;
b32b8144
FG
465 MockThreads mock_threads(m_threads);
466
d2e6a577 467 InSequence seq;
d2e6a577 468 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
9f95a23c
TL
469 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
470 "remote image id", 0);
d2e6a577 471
9f95a23c
TL
472 MockGetMirrorInfoRequest mock_get_mirror_info_request;
473 expect_get_mirror_info(mock_get_mirror_info_request,
474 {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
475 "global image id",
476 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
477 librbd::mirror::PROMOTION_STATE_PRIMARY,
478 "remote mirror uuid", -EINVAL);
479
480 MockJournalStateBuilder mock_journal_state_builder;
481 MockStateBuilder* mock_state_builder = nullptr;
d2e6a577 482 C_SaferCond ctx;
b32b8144 483 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
9f95a23c 484 m_local_io_ctx,
b32b8144 485 m_remote_io_ctx,
d2e6a577 486 "global image id",
b32b8144 487 "local mirror uuid",
9f95a23c
TL
488 {"remote mirror uuid", ""},
489 nullptr,
490 &mock_state_builder,
d2e6a577
FG
491 &ctx);
492 req->send();
493
494 ASSERT_EQ(-EINVAL, ctx.wait());
9f95a23c 495 ASSERT_TRUE(mock_state_builder == nullptr);
b32b8144
FG
496}
497
498TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, GetClientError) {
9f95a23c 499 ::journal::MockJournaler mock_remote_journaler;
b32b8144
FG
500 MockThreads mock_threads(m_threads);
501
502 InSequence seq;
b32b8144
FG
503 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
504 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
505 "remote image id", 0);
506
9f95a23c
TL
507 MockGetMirrorInfoRequest mock_get_mirror_info_request;
508 expect_get_mirror_info(mock_get_mirror_info_request,
509 {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
510 "global image id",
511 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
512 librbd::mirror::PROMOTION_STATE_PRIMARY,
513 "remote mirror uuid", 0);
514
b32b8144
FG
515 EXPECT_CALL(mock_remote_journaler, construct());
516
517 cls::journal::Client client;
518 expect_journaler_get_client(mock_remote_journaler, "local mirror uuid",
519 client, -EINVAL);
520
9f95a23c
TL
521 MockJournalStateBuilder mock_journal_state_builder;
522 MockStateBuilder* mock_state_builder = nullptr;
b32b8144
FG
523 C_SaferCond ctx;
524 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
9f95a23c 525 m_local_io_ctx,
b32b8144
FG
526 m_remote_io_ctx,
527 "global image id",
528 "local mirror uuid",
9f95a23c
TL
529 {"remote mirror uuid", ""},
530 nullptr,
531 &mock_state_builder,
b32b8144
FG
532 &ctx);
533 req->send();
534
535 ASSERT_EQ(-EINVAL, ctx.wait());
9f95a23c 536 ASSERT_TRUE(mock_state_builder == nullptr);
b32b8144
FG
537}
538
539TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, RegisterClientError) {
9f95a23c 540 ::journal::MockJournaler mock_remote_journaler;
b32b8144
FG
541 MockThreads mock_threads(m_threads);
542
543 InSequence seq;
b32b8144
FG
544 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request;
545 expect_get_mirror_image_id(mock_get_mirror_image_id_request,
546 "remote image id", 0);
547
9f95a23c
TL
548 MockGetMirrorInfoRequest mock_get_mirror_info_request;
549 expect_get_mirror_info(mock_get_mirror_info_request,
550 {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL,
551 "global image id",
552 cls::rbd::MIRROR_IMAGE_STATE_ENABLED},
553 librbd::mirror::PROMOTION_STATE_PRIMARY,
554 "remote mirror uuid", 0);
555
556 MockJournalStateBuilder mock_journal_state_builder;
557 expect_get_mirror_image_mode(mock_journal_state_builder,
558 cls::rbd::MIRROR_IMAGE_MODE_JOURNAL);
559
b32b8144
FG
560 EXPECT_CALL(mock_remote_journaler, construct());
561
562 cls::journal::Client client;
563 expect_journaler_get_client(mock_remote_journaler, "local mirror uuid",
564 client, -ENOENT);
565
566 librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta;
567 mirror_peer_client_meta.image_id = "local image id";
568 mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING;
569 librbd::journal::ClientData client_data{mirror_peer_client_meta};
570 expect_journaler_register_client(mock_remote_journaler, client_data, -EINVAL);
571
9f95a23c
TL
572 mock_journal_state_builder.local_image_id = "local image id";
573 MockStateBuilder* mock_state_builder = &mock_journal_state_builder;
b32b8144
FG
574 C_SaferCond ctx;
575 auto req = MockPrepareRemoteImageRequest::create(&mock_threads,
9f95a23c 576 m_local_io_ctx,
b32b8144
FG
577 m_remote_io_ctx,
578 "global image id",
579 "local mirror uuid",
9f95a23c
TL
580 {"remote mirror uuid", ""},
581 nullptr,
582 &mock_state_builder,
b32b8144
FG
583 &ctx);
584 req->send();
585
586 ASSERT_EQ(-EINVAL, ctx.wait());
d2e6a577
FG
587}
588
589} // namespace image_replayer
590} // namespace mirror
591} // namespace rbd