]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc
8a66cecaed9b90d39dbb69f0965a004c4ce1fc50
[ceph.git] / ceph / src / test / rbd_mirror / image_replayer / test_mock_BootstrapRequest.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 "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"
19
20 namespace librbd {
21
22 namespace {
23
24 struct MockTestImageCtx : public librbd::MockImageCtx {
25 MockTestImageCtx(librbd::ImageCtx &image_ctx)
26 : librbd::MockImageCtx(image_ctx) {
27 }
28 };
29
30 } // anonymous namespace
31 } // namespace librbd
32
33 namespace rbd {
34 namespace mirror {
35
36 class ProgressContext;
37
38 template <>
39 struct Threads<librbd::MockTestImageCtx> {
40 ceph::mutex &timer_lock;
41 SafeTimer *timer;
42 librbd::asio::ContextWQ *work_queue;
43
44 Threads(Threads<librbd::ImageCtx> *threads)
45 : timer_lock(threads->timer_lock), timer(threads->timer),
46 work_queue(threads->work_queue) {
47 }
48 };
49
50 template<>
51 struct ImageSync<librbd::MockTestImageCtx> {
52 static ImageSync* s_instance;
53 Context *on_finish = nullptr;
54
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;
65 return s_instance;
66 }
67
68 ImageSync() {
69 ceph_assert(s_instance == nullptr);
70 s_instance = this;
71 }
72 ~ImageSync() {
73 s_instance = nullptr;
74 }
75
76 MOCK_METHOD0(get, void());
77 MOCK_METHOD0(put, void());
78 MOCK_METHOD0(send, void());
79 MOCK_METHOD0(cancel, void());
80 };
81
82 ImageSync<librbd::MockTestImageCtx>*
83 ImageSync<librbd::MockTestImageCtx>::s_instance = nullptr;
84
85 template<>
86 struct InstanceWatcher<librbd::MockTestImageCtx> {
87 };
88
89 namespace image_replayer {
90
91 template<>
92 struct OpenImageRequest<librbd::MockTestImageCtx> {
93 static OpenImageRequest* s_instance;
94 librbd::MockTestImageCtx **image_ctx = nullptr;
95 Context *on_finish = nullptr;
96
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);
105 return s_instance;
106 }
107
108 OpenImageRequest() {
109 ceph_assert(s_instance == nullptr);
110 s_instance = this;
111 }
112 ~OpenImageRequest() {
113 s_instance = nullptr;
114 }
115
116 MOCK_METHOD2(construct, void(librados::IoCtx &io_ctx,
117 const std::string &image_id));
118 MOCK_METHOD0(send, void());
119 };
120
121 template<>
122 struct OpenLocalImageRequest<librbd::MockTestImageCtx> {
123 static OpenLocalImageRequest* s_instance;
124 librbd::MockTestImageCtx **image_ctx = nullptr;
125 Context *on_finish = nullptr;
126
127 static OpenLocalImageRequest* create(librados::IoCtx &local_io_ctx,
128 librbd::MockTestImageCtx **local_image_ctx,
129 const std::string &local_image_id,
130 librbd::asio::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);
136 return s_instance;
137 }
138
139 OpenLocalImageRequest() {
140 ceph_assert(s_instance == nullptr);
141 s_instance = this;
142 }
143 ~OpenLocalImageRequest() {
144 s_instance = nullptr;
145 }
146
147 MOCK_METHOD2(construct, void(librados::IoCtx &io_ctx,
148 const std::string &image_id));
149 MOCK_METHOD0(send, void());
150 };
151
152 template<>
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;
158
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 librbd::asio::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;
169 return s_instance;
170 }
171
172 PrepareLocalImageRequest() {
173 s_instance = this;
174 }
175
176 MOCK_METHOD0(send, void());
177 };
178
179 template<>
180 struct PrepareRemoteImageRequest<librbd::MockTestImageCtx> {
181 static PrepareRemoteImageRequest* s_instance;
182 StateBuilder<librbd::MockTestImageCtx>** state_builder = nullptr;
183 Context *on_finish = nullptr;
184
185 static PrepareRemoteImageRequest* create(Threads<librbd::MockTestImageCtx> *threads,
186 librados::IoCtx &,
187 librados::IoCtx &,
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;
197 return s_instance;
198 }
199
200 PrepareRemoteImageRequest() {
201 s_instance = this;
202 }
203
204 MOCK_METHOD0(send, void());
205 };
206
207 template<>
208 struct StateBuilder<librbd::MockTestImageCtx> {
209 static StateBuilder* s_instance;
210
211 image_sync::MockSyncPointHandler mock_sync_point_handler;
212 MockBaseRequest mock_base_request;
213
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;
219
220 static StateBuilder* create(const std::string&) {
221 ceph_assert(s_instance != nullptr);
222 return s_instance;
223 }
224
225 image_sync::MockSyncPointHandler* create_sync_point_handler() {
226 return &mock_sync_point_handler;
227 }
228
229 StateBuilder() {
230 s_instance = this;
231 }
232
233 MOCK_CONST_METHOD0(is_disconnected, bool());
234 MOCK_CONST_METHOD0(is_local_primary, bool());
235 MOCK_CONST_METHOD0(is_remote_primary, bool());
236 MOCK_CONST_METHOD0(is_linked, bool());
237
238 MOCK_CONST_METHOD0(replay_requires_remote_image, bool());
239 MOCK_METHOD1(close_remote_image, void(Context*));
240
241 MOCK_METHOD6(create_local_image_request,
242 BaseRequest*(Threads<librbd::MockTestImageCtx>*,
243 librados::IoCtx&,
244 const std::string&,
245 PoolMetaCache*,
246 ProgressContext*,
247 Context*));
248 MOCK_METHOD5(create_prepare_replay_request,
249 BaseRequest*(const std::string&,
250 ProgressContext*,
251 bool*, bool*, Context*));
252
253 void destroy_sync_point_handler() {
254 }
255 void destroy() {
256 }
257 };
258
259 OpenImageRequest<librbd::MockTestImageCtx>*
260 OpenImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
261 OpenLocalImageRequest<librbd::MockTestImageCtx>*
262 OpenLocalImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
263 PrepareLocalImageRequest<librbd::MockTestImageCtx>*
264 PrepareLocalImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
265 PrepareRemoteImageRequest<librbd::MockTestImageCtx>*
266 PrepareRemoteImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
267 StateBuilder<librbd::MockTestImageCtx>*
268 StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr;
269
270 } // namespace image_replayer
271 } // namespace mirror
272 } // namespace rbd
273
274 // template definitions
275 #include "tools/rbd_mirror/image_replayer/BootstrapRequest.cc"
276
277 namespace rbd {
278 namespace mirror {
279 namespace image_replayer {
280
281 using ::testing::_;
282 using ::testing::DoAll;
283 using ::testing::InSequence;
284 using ::testing::Invoke;
285 using ::testing::Return;
286 using ::testing::SetArgPointee;
287 using ::testing::StrEq;
288 using ::testing::WithArg;
289 using ::testing::WithArgs;
290
291 MATCHER_P(IsSameIoCtx, io_ctx, "") {
292 return &get_mock_io_ctx(arg) == &get_mock_io_ctx(*io_ctx);
293 }
294
295 class TestMockImageReplayerBootstrapRequest : public TestMockFixture {
296 public:
297 typedef Threads<librbd::MockTestImageCtx> MockThreads;
298 typedef BootstrapRequest<librbd::MockTestImageCtx> MockBootstrapRequest;
299 typedef ImageSync<librbd::MockTestImageCtx> MockImageSync;
300 typedef InstanceWatcher<librbd::MockTestImageCtx> MockInstanceWatcher;
301 typedef OpenImageRequest<librbd::MockTestImageCtx> MockOpenImageRequest;
302 typedef OpenLocalImageRequest<librbd::MockTestImageCtx> MockOpenLocalImageRequest;
303 typedef PrepareLocalImageRequest<librbd::MockTestImageCtx> MockPrepareLocalImageRequest;
304 typedef PrepareRemoteImageRequest<librbd::MockTestImageCtx> MockPrepareRemoteImageRequest;
305 typedef StateBuilder<librbd::MockTestImageCtx> MockStateBuilder;
306 typedef std::list<cls::journal::Tag> Tags;
307
308 void SetUp() override {
309 TestMockFixture::SetUp();
310
311 librbd::RBD rbd;
312 ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size));
313 ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
314
315 ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
316 ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &m_local_image_ctx));
317 }
318
319 void expect_send(MockPrepareLocalImageRequest &mock_request,
320 MockStateBuilder& mock_state_builder,
321 const std::string& local_image_id,
322 const std::string& local_image_name, int r) {
323 EXPECT_CALL(mock_request, send())
324 .WillOnce(Invoke([&mock_request, &mock_state_builder, local_image_id,
325 local_image_name, r]() {
326 if (r == 0) {
327 *mock_request.state_builder = &mock_state_builder;
328 mock_state_builder.local_image_id = local_image_id;
329 *mock_request.local_image_name = local_image_name;
330 }
331 mock_request.on_finish->complete(r);
332 }));
333 }
334
335 void expect_send(MockPrepareRemoteImageRequest& mock_request,
336 MockStateBuilder& mock_state_builder,
337 const std::string& remote_mirror_uuid,
338 const std::string& remote_image_id,
339 int r) {
340 EXPECT_CALL(mock_request, send())
341 .WillOnce(Invoke([&mock_request, &mock_state_builder, remote_mirror_uuid,
342 remote_image_id, r]() {
343 if (r >= 0) {
344 *mock_request.state_builder = &mock_state_builder;
345 mock_state_builder.remote_image_id = remote_image_id;
346 }
347
348 mock_state_builder.remote_mirror_uuid = remote_mirror_uuid;
349 mock_request.on_finish->complete(r);
350 }));
351 }
352
353 void expect_is_local_primary(MockStateBuilder& mock_state_builder,
354 bool is_primary) {
355 EXPECT_CALL(mock_state_builder, is_local_primary())
356 .WillOnce(Return(is_primary));
357 }
358
359 void expect_is_remote_primary(MockStateBuilder& mock_state_builder,
360 bool is_primary) {
361 EXPECT_CALL(mock_state_builder, is_remote_primary())
362 .WillOnce(Return(is_primary));
363 }
364
365 void expect_is_linked(MockStateBuilder& mock_state_builder, bool is_linked) {
366 EXPECT_CALL(mock_state_builder, is_linked())
367 .WillOnce(Return(is_linked));
368 }
369
370 void expect_is_disconnected(MockStateBuilder& mock_state_builder,
371 bool is_disconnected) {
372 EXPECT_CALL(mock_state_builder, is_disconnected())
373 .WillOnce(Return(is_disconnected));
374 }
375
376 void expect_replay_requires_remote_image(MockStateBuilder& mock_state_builder,
377 bool requires_image) {
378 EXPECT_CALL(mock_state_builder, replay_requires_remote_image())
379 .WillOnce(Return(requires_image));
380 }
381
382 void expect_open_image(MockOpenImageRequest &mock_open_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_image_request,
386 construct(IsSameIoCtx(&io_ctx), image_id));
387 EXPECT_CALL(mock_open_image_request, send())
388 .WillOnce(Invoke([this, &mock_open_image_request, &mock_image_ctx, r]() {
389 *mock_open_image_request.image_ctx = &mock_image_ctx;
390 m_threads->work_queue->queue(mock_open_image_request.on_finish, r);
391 }));
392 }
393
394 void expect_open_local_image(MockOpenLocalImageRequest &mock_open_local_image_request,
395 librados::IoCtx &io_ctx, const std::string &image_id,
396 librbd::MockTestImageCtx *mock_image_ctx, int r) {
397 EXPECT_CALL(mock_open_local_image_request,
398 construct(IsSameIoCtx(&io_ctx), image_id));
399 EXPECT_CALL(mock_open_local_image_request, send())
400 .WillOnce(Invoke([this, &mock_open_local_image_request, mock_image_ctx, r]() {
401 if (r >= 0) {
402 *mock_open_local_image_request.image_ctx = mock_image_ctx;
403 }
404 m_threads->work_queue->queue(mock_open_local_image_request.on_finish,
405 r);
406 }));
407 }
408
409 void expect_close_remote_image(
410 MockStateBuilder& mock_state_builder, int r) {
411 EXPECT_CALL(mock_state_builder, close_remote_image(_))
412 .WillOnce(Invoke([&mock_state_builder, r]
413 (Context* on_finish) {
414 mock_state_builder.remote_image_ctx = nullptr;
415 on_finish->complete(r);
416 }));
417 }
418
419 void expect_create_local_image(MockStateBuilder& mock_state_builder,
420 const std::string& local_image_id, int r) {
421 EXPECT_CALL(mock_state_builder,
422 create_local_image_request(_, _, _, _, _, _))
423 .WillOnce(WithArg<5>(
424 Invoke([&mock_state_builder, local_image_id, r](Context* ctx) {
425 if (r >= 0) {
426 mock_state_builder.local_image_id = local_image_id;
427 }
428 mock_state_builder.mock_base_request.on_finish = ctx;
429 return &mock_state_builder.mock_base_request;
430 })));
431 EXPECT_CALL(mock_state_builder.mock_base_request, send())
432 .WillOnce(Invoke([this, &mock_state_builder, r]() {
433 m_threads->work_queue->queue(
434 mock_state_builder.mock_base_request.on_finish, r);
435 }));
436 }
437
438 void expect_prepare_replay(MockStateBuilder& mock_state_builder,
439 bool resync_requested, bool syncing, int r) {
440 EXPECT_CALL(mock_state_builder,
441 create_prepare_replay_request(_, _, _, _, _))
442 .WillOnce(WithArgs<2, 3, 4>(
443 Invoke([&mock_state_builder, resync_requested, syncing, r]
444 (bool* resync, bool* sync, Context* ctx) {
445 if (r >= 0) {
446 *resync = resync_requested;
447 *sync = syncing;
448 }
449 mock_state_builder.mock_base_request.on_finish = ctx;
450 return &mock_state_builder.mock_base_request;
451 })));
452 EXPECT_CALL(mock_state_builder.mock_base_request, send())
453 .WillOnce(Invoke([this, &mock_state_builder, r]() {
454 m_threads->work_queue->queue(
455 mock_state_builder.mock_base_request.on_finish, r);
456 }));
457 }
458
459 void expect_image_sync(MockImageSync &mock_image_sync, int r) {
460 EXPECT_CALL(mock_image_sync, get());
461 EXPECT_CALL(mock_image_sync, send())
462 .WillOnce(Invoke([this, &mock_image_sync, r]() {
463 m_threads->work_queue->queue(mock_image_sync.on_finish, r);
464 }));
465 EXPECT_CALL(mock_image_sync, put());
466 }
467
468 MockBootstrapRequest *create_request(MockThreads* mock_threads,
469 MockInstanceWatcher *mock_instance_watcher,
470 const std::string &global_image_id,
471 const std::string &local_mirror_uuid,
472 Context *on_finish) {
473 return new MockBootstrapRequest(mock_threads,
474 m_local_io_ctx,
475 m_remote_io_ctx,
476 mock_instance_watcher,
477 global_image_id,
478 local_mirror_uuid,
479 {"remote mirror uuid",
480 "remote mirror peer uuid"},
481 nullptr, nullptr, nullptr,
482 &m_mock_state_builder,
483 &m_do_resync, on_finish);
484 }
485
486 librbd::ImageCtx *m_remote_image_ctx;
487 librbd::ImageCtx *m_local_image_ctx = nullptr;
488
489 MockStateBuilder* m_mock_state_builder = nullptr;
490 bool m_do_resync = false;
491 };
492
493 TEST_F(TestMockImageReplayerBootstrapRequest, Success) {
494 InSequence seq;
495
496 // prepare local image
497 MockStateBuilder mock_state_builder;
498 MockPrepareLocalImageRequest mock_prepare_local_image_request;
499 expect_send(mock_prepare_local_image_request, mock_state_builder,
500 m_local_image_ctx->id, m_local_image_ctx->name, 0);
501
502 // prepare remote image
503 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
504 expect_send(mock_prepare_remote_image_request, mock_state_builder,
505 "remote mirror uuid", m_remote_image_ctx->id, 0);
506 expect_is_local_primary(mock_state_builder, false);
507 expect_is_remote_primary(mock_state_builder, true);
508
509 // open the remote image
510 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
511 MockOpenImageRequest mock_open_image_request;
512 expect_open_image(mock_open_image_request, m_remote_io_ctx,
513 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
514
515 // open the local image
516 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
517 MockOpenLocalImageRequest mock_open_local_image_request;
518 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
519 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
520
521 // prepare replay
522 expect_prepare_replay(mock_state_builder, false, false, 0);
523 expect_is_disconnected(mock_state_builder, false);
524
525 // close remote image
526 expect_replay_requires_remote_image(mock_state_builder, false);
527 expect_close_remote_image(mock_state_builder, 0);
528
529 C_SaferCond ctx;
530 MockThreads mock_threads(m_threads);
531 MockInstanceWatcher mock_instance_watcher;
532 MockBootstrapRequest *request = create_request(
533 &mock_threads, &mock_instance_watcher, "global image id",
534 "local mirror uuid", &ctx);
535 request->send();
536 ASSERT_EQ(0, ctx.wait());
537 }
538
539 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareRemoteImageNotPrimaryLocalDNE) {
540 InSequence seq;
541
542 // prepare local image
543 MockStateBuilder mock_state_builder;
544 MockPrepareLocalImageRequest mock_prepare_local_image_request;
545 expect_send(mock_prepare_local_image_request, mock_state_builder,
546 m_local_image_ctx->id, m_local_image_ctx->name, -ENOENT);
547
548 // prepare remote image
549 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
550 expect_send(mock_prepare_remote_image_request, mock_state_builder,
551 "remote mirror uuid", m_remote_image_ctx->id, 0);
552 expect_is_local_primary(mock_state_builder, false);
553 expect_is_remote_primary(mock_state_builder, false);
554
555 C_SaferCond ctx;
556 MockThreads mock_threads(m_threads);
557 MockInstanceWatcher mock_instance_watcher;
558 MockBootstrapRequest *request = create_request(
559 &mock_threads, &mock_instance_watcher, "global image id",
560 "local mirror uuid", &ctx);
561 request->send();
562 ASSERT_EQ(-EREMOTEIO, ctx.wait());
563 }
564
565 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareRemoteImageNotPrimaryLocalUnlinked) {
566 InSequence seq;
567
568 // prepare local image
569 MockStateBuilder mock_state_builder;
570 MockPrepareLocalImageRequest mock_prepare_local_image_request;
571 expect_send(mock_prepare_local_image_request, mock_state_builder,
572 m_local_image_ctx->id, m_local_image_ctx->name, 0);
573
574 // prepare remote image
575 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
576 expect_send(mock_prepare_remote_image_request, mock_state_builder,
577 "remote mirror uuid", m_remote_image_ctx->id, 0);
578 expect_is_local_primary(mock_state_builder, false);
579 expect_is_remote_primary(mock_state_builder, false);
580 expect_is_linked(mock_state_builder, false);
581
582 C_SaferCond ctx;
583 MockThreads mock_threads(m_threads);
584 MockInstanceWatcher mock_instance_watcher;
585 MockBootstrapRequest *request = create_request(
586 &mock_threads, &mock_instance_watcher, "global image id",
587 "local mirror uuid", &ctx);
588 request->send();
589 ASSERT_EQ(-EREMOTEIO, ctx.wait());
590 }
591
592 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareRemoteImageNotPrimaryLocalLinked) {
593 InSequence seq;
594
595 // prepare local image
596 MockStateBuilder mock_state_builder;
597 MockPrepareLocalImageRequest mock_prepare_local_image_request;
598 expect_send(mock_prepare_local_image_request, mock_state_builder,
599 m_local_image_ctx->id, m_local_image_ctx->name, 0);
600
601 // prepare remote image
602 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
603 expect_send(mock_prepare_remote_image_request, mock_state_builder,
604 "remote mirror uuid", m_remote_image_ctx->id, 0);
605 expect_is_local_primary(mock_state_builder, false);
606 expect_is_remote_primary(mock_state_builder, false);
607 expect_is_linked(mock_state_builder, true);
608
609 // open the remote image
610 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
611 MockOpenImageRequest mock_open_image_request;
612 expect_open_image(mock_open_image_request, m_remote_io_ctx,
613 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
614
615 // open the local image
616 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
617 MockOpenLocalImageRequest mock_open_local_image_request;
618 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
619 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
620
621 // prepare replay
622 expect_prepare_replay(mock_state_builder, false, false, 0);
623 expect_is_disconnected(mock_state_builder, false);
624
625 // close remote image
626 expect_replay_requires_remote_image(mock_state_builder, false);
627 expect_close_remote_image(mock_state_builder, 0);
628
629 C_SaferCond ctx;
630 MockThreads mock_threads(m_threads);
631 MockInstanceWatcher mock_instance_watcher;
632 MockBootstrapRequest *request = create_request(
633 &mock_threads, &mock_instance_watcher, "global image id",
634 "local mirror uuid", &ctx);
635 request->send();
636 ASSERT_EQ(0, ctx.wait());
637 }
638
639 TEST_F(TestMockImageReplayerBootstrapRequest, OpenLocalImageError) {
640 InSequence seq;
641
642 // prepare local image
643 MockPrepareLocalImageRequest mock_prepare_local_image_request;
644 MockStateBuilder mock_state_builder;
645 expect_send(mock_prepare_local_image_request, mock_state_builder,
646 m_local_image_ctx->id, m_local_image_ctx->name, 0);
647
648 // prepare remote image
649 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
650 expect_send(mock_prepare_remote_image_request, mock_state_builder,
651 "remote mirror uuid", m_remote_image_ctx->id, 0);
652 expect_is_local_primary(mock_state_builder, false);
653 expect_is_remote_primary(mock_state_builder, true);
654
655 // open the remote image
656 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
657 MockOpenImageRequest mock_open_image_request;
658 expect_open_image(mock_open_image_request, m_remote_io_ctx,
659 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
660
661 // open the local image
662 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
663 MockOpenLocalImageRequest mock_open_local_image_request;
664 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
665 mock_local_image_ctx.id, &mock_local_image_ctx,
666 -EINVAL);
667
668 // close remote image
669 expect_replay_requires_remote_image(mock_state_builder, false);
670 expect_close_remote_image(mock_state_builder, 0);
671
672 C_SaferCond ctx;
673 MockThreads mock_threads(m_threads);
674 MockInstanceWatcher mock_instance_watcher;
675 MockBootstrapRequest *request = create_request(
676 &mock_threads, &mock_instance_watcher, "global image id",
677 "local mirror uuid", &ctx);
678 request->send();
679 ASSERT_EQ(-EINVAL, ctx.wait());
680 }
681
682 TEST_F(TestMockImageReplayerBootstrapRequest, OpenLocalImageDNE) {
683 InSequence seq;
684
685 // prepare local image
686 MockPrepareLocalImageRequest mock_prepare_local_image_request;
687 MockStateBuilder mock_state_builder;
688 expect_send(mock_prepare_local_image_request, mock_state_builder,
689 m_local_image_ctx->id, m_local_image_ctx->name, 0);
690
691 // prepare remote image
692 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
693 expect_send(mock_prepare_remote_image_request, mock_state_builder,
694 "remote mirror uuid", m_remote_image_ctx->id, 0);
695 expect_is_local_primary(mock_state_builder, false);
696 expect_is_remote_primary(mock_state_builder, true);
697
698 // open the remote image
699 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
700 MockOpenImageRequest mock_open_image_request;
701 expect_open_image(mock_open_image_request, m_remote_io_ctx,
702 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
703
704 // open the local image
705 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
706 MockOpenLocalImageRequest mock_open_local_image_request;
707 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
708 mock_local_image_ctx.id, &mock_local_image_ctx,
709 -ENOENT);
710
711 // create local image
712 expect_create_local_image(mock_state_builder, "local image id", 0);
713
714 // re-open the local image
715 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
716 "local image id", &mock_local_image_ctx, 0);
717
718 // prepare replay
719 expect_prepare_replay(mock_state_builder, false, false, 0);
720 expect_is_disconnected(mock_state_builder, false);
721
722 // close remote image
723 expect_replay_requires_remote_image(mock_state_builder, false);
724 expect_close_remote_image(mock_state_builder, 0);
725
726 C_SaferCond ctx;
727 MockThreads mock_threads(m_threads);
728 MockInstanceWatcher mock_instance_watcher;
729 MockBootstrapRequest *request = create_request(
730 &mock_threads, &mock_instance_watcher, "global image id",
731 "local mirror uuid", &ctx);
732 request->send();
733 ASSERT_EQ(0, ctx.wait());
734 }
735
736 TEST_F(TestMockImageReplayerBootstrapRequest, OpenLocalImagePrimary) {
737 InSequence seq;
738
739 // prepare local image
740 MockPrepareLocalImageRequest mock_prepare_local_image_request;
741 MockStateBuilder mock_state_builder;
742 expect_send(mock_prepare_local_image_request, mock_state_builder,
743 m_local_image_ctx->id, m_local_image_ctx->name, 0);
744
745 // prepare remote image
746 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
747 expect_send(mock_prepare_remote_image_request, mock_state_builder,
748 "remote mirror uuid", m_remote_image_ctx->id, 0);
749 expect_is_local_primary(mock_state_builder, false);
750 expect_is_remote_primary(mock_state_builder, true);
751
752 // open the remote image
753 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
754 MockOpenImageRequest mock_open_image_request;
755 expect_open_image(mock_open_image_request, m_remote_io_ctx,
756 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
757
758 // open the local image
759 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
760 MockOpenLocalImageRequest mock_open_local_image_request;
761 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
762 mock_local_image_ctx.id, &mock_local_image_ctx,
763 -EREMOTEIO);
764
765 // close remote image
766 expect_replay_requires_remote_image(mock_state_builder, false);
767 expect_close_remote_image(mock_state_builder, 0);
768
769 C_SaferCond ctx;
770 MockThreads mock_threads(m_threads);
771 MockInstanceWatcher mock_instance_watcher;
772 MockBootstrapRequest *request = create_request(
773 &mock_threads, &mock_instance_watcher, "global image id",
774 "local mirror uuid", &ctx);
775 request->send();
776 ASSERT_EQ(-EREMOTEIO, ctx.wait());
777 }
778
779 TEST_F(TestMockImageReplayerBootstrapRequest, CreateLocalImageError) {
780 InSequence seq;
781
782 // prepare local image
783 MockPrepareLocalImageRequest mock_prepare_local_image_request;
784 MockStateBuilder mock_state_builder;
785 expect_send(mock_prepare_local_image_request, mock_state_builder, "", "",
786 -ENOENT);
787
788 // prepare remote image
789 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
790 expect_send(mock_prepare_remote_image_request, mock_state_builder,
791 "remote mirror uuid", m_remote_image_ctx->id, 0);
792 expect_is_local_primary(mock_state_builder, false);
793 expect_is_remote_primary(mock_state_builder, true);
794
795 // open the remote image
796 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
797 MockOpenImageRequest mock_open_image_request;
798 expect_open_image(mock_open_image_request, m_remote_io_ctx,
799 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
800
801 // create local image
802 expect_create_local_image(mock_state_builder, "local image id", -EINVAL);
803
804 // close remote image
805 expect_replay_requires_remote_image(mock_state_builder, false);
806 expect_close_remote_image(mock_state_builder, 0);
807
808 C_SaferCond ctx;
809 MockThreads mock_threads(m_threads);
810 MockInstanceWatcher mock_instance_watcher;
811 MockBootstrapRequest *request = create_request(
812 &mock_threads, &mock_instance_watcher, "global image id",
813 "local mirror uuid", &ctx);
814 request->send();
815 ASSERT_EQ(-EINVAL, ctx.wait());
816 }
817
818 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplayError) {
819 InSequence seq;
820
821 // prepare local image
822 MockPrepareLocalImageRequest mock_prepare_local_image_request;
823 MockStateBuilder mock_state_builder;
824 expect_send(mock_prepare_local_image_request, mock_state_builder,
825 m_local_image_ctx->id, m_local_image_ctx->name, 0);
826
827 // prepare remote image
828 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
829 expect_send(mock_prepare_remote_image_request, mock_state_builder,
830 "remote mirror uuid", m_remote_image_ctx->id, 0);
831 expect_is_local_primary(mock_state_builder, false);
832 expect_is_remote_primary(mock_state_builder, true);
833
834 // open the remote image
835 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
836 MockOpenImageRequest mock_open_image_request;
837 expect_open_image(mock_open_image_request, m_remote_io_ctx,
838 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
839
840 // open the local image
841 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
842 MockOpenLocalImageRequest mock_open_local_image_request;
843 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
844 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
845
846 // prepare replay
847 expect_prepare_replay(mock_state_builder, false, false, -EINVAL);
848
849 // close remote image
850 expect_replay_requires_remote_image(mock_state_builder, false);
851 expect_close_remote_image(mock_state_builder, 0);
852
853 C_SaferCond ctx;
854 MockThreads mock_threads(m_threads);
855 MockInstanceWatcher mock_instance_watcher;
856 MockBootstrapRequest *request = create_request(
857 &mock_threads, &mock_instance_watcher, "global image id",
858 "local mirror uuid", &ctx);
859 request->send();
860 ASSERT_EQ(-EINVAL, ctx.wait());
861 }
862
863 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplayResyncRequested) {
864 InSequence seq;
865
866 // prepare local image
867 MockPrepareLocalImageRequest mock_prepare_local_image_request;
868 MockStateBuilder mock_state_builder;
869 expect_send(mock_prepare_local_image_request, mock_state_builder,
870 m_local_image_ctx->id, m_local_image_ctx->name, 0);
871
872 // prepare remote image
873 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
874 expect_send(mock_prepare_remote_image_request, mock_state_builder,
875 "remote mirror uuid", m_remote_image_ctx->id, 0);
876 expect_is_local_primary(mock_state_builder, false);
877 expect_is_remote_primary(mock_state_builder, true);
878
879 // open the remote image
880 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
881 MockOpenImageRequest mock_open_image_request;
882 expect_open_image(mock_open_image_request, m_remote_io_ctx,
883 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
884
885 // open the local image
886 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
887 MockOpenLocalImageRequest mock_open_local_image_request;
888 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
889 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
890
891 // prepare replay
892 expect_prepare_replay(mock_state_builder, true, false, 0);
893
894 // close remote image
895 expect_replay_requires_remote_image(mock_state_builder, false);
896 expect_close_remote_image(mock_state_builder, 0);
897
898 C_SaferCond ctx;
899 MockThreads mock_threads(m_threads);
900 MockInstanceWatcher mock_instance_watcher;
901 MockBootstrapRequest *request = create_request(
902 &mock_threads, &mock_instance_watcher, "global image id",
903 "local mirror uuid", &ctx);
904 request->send();
905 ASSERT_EQ(0, ctx.wait());
906 ASSERT_TRUE(m_do_resync);
907 }
908
909 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplaySyncing) {
910 InSequence seq;
911
912 // prepare local image
913 MockPrepareLocalImageRequest mock_prepare_local_image_request;
914 MockStateBuilder mock_state_builder;
915 expect_send(mock_prepare_local_image_request, mock_state_builder,
916 m_local_image_ctx->id, m_local_image_ctx->name, 0);
917
918 // prepare remote image
919 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
920 expect_send(mock_prepare_remote_image_request, mock_state_builder,
921 "remote mirror uuid", m_remote_image_ctx->id, 0);
922 expect_is_local_primary(mock_state_builder, false);
923 expect_is_remote_primary(mock_state_builder, true);
924
925 // open the remote image
926 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
927 MockOpenImageRequest mock_open_image_request;
928 expect_open_image(mock_open_image_request, m_remote_io_ctx,
929 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
930
931 // open the local image
932 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
933 MockOpenLocalImageRequest mock_open_local_image_request;
934 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
935 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
936
937 // prepare replay
938 expect_prepare_replay(mock_state_builder, false, true, 0);
939 expect_is_disconnected(mock_state_builder, false);
940
941 // image sync
942 MockImageSync mock_image_sync;
943 expect_image_sync(mock_image_sync, 0);
944
945 // close remote image
946 expect_replay_requires_remote_image(mock_state_builder, false);
947 expect_close_remote_image(mock_state_builder, 0);
948
949 C_SaferCond ctx;
950 MockThreads mock_threads(m_threads);
951 MockInstanceWatcher mock_instance_watcher;
952 MockBootstrapRequest *request = create_request(
953 &mock_threads, &mock_instance_watcher, "global image id",
954 "local mirror uuid", &ctx);
955 request->send();
956 ASSERT_EQ(0, ctx.wait());
957 }
958
959 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplayDisconnected) {
960 InSequence seq;
961
962 // prepare local image
963 MockPrepareLocalImageRequest mock_prepare_local_image_request;
964 MockStateBuilder mock_state_builder;
965 expect_send(mock_prepare_local_image_request, mock_state_builder,
966 m_local_image_ctx->id, m_local_image_ctx->name, 0);
967
968 // prepare remote image
969 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
970 expect_send(mock_prepare_remote_image_request, mock_state_builder,
971 "remote mirror uuid", m_remote_image_ctx->id, 0);
972 expect_is_local_primary(mock_state_builder, false);
973 expect_is_remote_primary(mock_state_builder, true);
974
975 // open the remote image
976 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
977 MockOpenImageRequest mock_open_image_request;
978 expect_open_image(mock_open_image_request, m_remote_io_ctx,
979 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
980
981 // open the local image
982 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
983 MockOpenLocalImageRequest mock_open_local_image_request;
984 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
985 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
986
987 // prepare replay
988 expect_prepare_replay(mock_state_builder, false, false, 0);
989 expect_is_disconnected(mock_state_builder, true);
990
991 // close remote image
992 expect_replay_requires_remote_image(mock_state_builder, false);
993 expect_close_remote_image(mock_state_builder, 0);
994
995 C_SaferCond ctx;
996 MockThreads mock_threads(m_threads);
997 MockInstanceWatcher mock_instance_watcher;
998 MockBootstrapRequest *request = create_request(
999 &mock_threads, &mock_instance_watcher, "global image id",
1000 "local mirror uuid", &ctx);
1001 request->send();
1002 ASSERT_EQ(0, ctx.wait());
1003 }
1004
1005 TEST_F(TestMockImageReplayerBootstrapRequest, ImageSyncError) {
1006 InSequence seq;
1007
1008 // prepare local image
1009 MockPrepareLocalImageRequest mock_prepare_local_image_request;
1010 MockStateBuilder mock_state_builder;
1011 expect_send(mock_prepare_local_image_request, mock_state_builder,
1012 m_local_image_ctx->id, m_local_image_ctx->name, 0);
1013
1014 // prepare remote image
1015 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
1016 expect_send(mock_prepare_remote_image_request, mock_state_builder,
1017 "remote mirror uuid", m_remote_image_ctx->id, 0);
1018 expect_is_local_primary(mock_state_builder, false);
1019 expect_is_remote_primary(mock_state_builder, true);
1020
1021 // open the remote image
1022 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
1023 MockOpenImageRequest mock_open_image_request;
1024 expect_open_image(mock_open_image_request, m_remote_io_ctx,
1025 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
1026
1027 // open the local image
1028 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
1029 MockOpenLocalImageRequest mock_open_local_image_request;
1030 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
1031 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
1032
1033 // prepare replay
1034 expect_prepare_replay(mock_state_builder, false, true, 0);
1035 expect_is_disconnected(mock_state_builder, false);
1036
1037 // image sync
1038 MockImageSync mock_image_sync;
1039 expect_image_sync(mock_image_sync, -EINVAL);
1040
1041 // close remote image
1042 expect_replay_requires_remote_image(mock_state_builder, false);
1043 expect_close_remote_image(mock_state_builder, 0);
1044
1045 C_SaferCond ctx;
1046 MockThreads mock_threads(m_threads);
1047 MockInstanceWatcher mock_instance_watcher;
1048 MockBootstrapRequest *request = create_request(
1049 &mock_threads, &mock_instance_watcher, "global image id",
1050 "local mirror uuid", &ctx);
1051 request->send();
1052 ASSERT_EQ(-EINVAL, ctx.wait());
1053 }
1054
1055 TEST_F(TestMockImageReplayerBootstrapRequest, ImageSyncCanceled) {
1056 InSequence seq;
1057
1058 // prepare local image
1059 MockPrepareLocalImageRequest mock_prepare_local_image_request;
1060 MockStateBuilder mock_state_builder;
1061 expect_send(mock_prepare_local_image_request, mock_state_builder,
1062 m_local_image_ctx->id, m_local_image_ctx->name, 0);
1063
1064 // prepare remote image
1065 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
1066 expect_send(mock_prepare_remote_image_request, mock_state_builder,
1067 "remote mirror uuid", m_remote_image_ctx->id, 0);
1068 expect_is_local_primary(mock_state_builder, false);
1069 expect_is_remote_primary(mock_state_builder, true);
1070
1071 // open the remote image
1072 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
1073 MockOpenImageRequest mock_open_image_request;
1074 expect_open_image(mock_open_image_request, m_remote_io_ctx,
1075 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
1076
1077 // open the local image
1078 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
1079 MockOpenLocalImageRequest mock_open_local_image_request;
1080 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
1081 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
1082
1083 // prepare replay
1084 expect_prepare_replay(mock_state_builder, false, true, 0);
1085 expect_is_disconnected(mock_state_builder, false);
1086
1087 // close remote image
1088 expect_replay_requires_remote_image(mock_state_builder, false);
1089 expect_close_remote_image(mock_state_builder, 0);
1090
1091 C_SaferCond ctx;
1092 MockThreads mock_threads(m_threads);
1093 MockInstanceWatcher mock_instance_watcher;
1094 MockBootstrapRequest *request = create_request(
1095 &mock_threads, &mock_instance_watcher, "global image id",
1096 "local mirror uuid", &ctx);
1097 request->cancel();
1098 request->send();
1099 ASSERT_EQ(-ECANCELED, ctx.wait());
1100 }
1101
1102 TEST_F(TestMockImageReplayerBootstrapRequest, CloseRemoteImageError) {
1103 InSequence seq;
1104
1105 // prepare local image
1106 MockPrepareLocalImageRequest mock_prepare_local_image_request;
1107 MockStateBuilder mock_state_builder;
1108 expect_send(mock_prepare_local_image_request, mock_state_builder,
1109 m_local_image_ctx->id, m_local_image_ctx->name, 0);
1110
1111 // prepare remote image
1112 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
1113 expect_send(mock_prepare_remote_image_request, mock_state_builder,
1114 "remote mirror uuid", m_remote_image_ctx->id, 0);
1115 expect_is_local_primary(mock_state_builder, false);
1116 expect_is_remote_primary(mock_state_builder, true);
1117
1118 // open the remote image
1119 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
1120 MockOpenImageRequest mock_open_image_request;
1121 expect_open_image(mock_open_image_request, m_remote_io_ctx,
1122 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
1123
1124 // open the local image
1125 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
1126 MockOpenLocalImageRequest mock_open_local_image_request;
1127 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
1128 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
1129
1130 // prepare replay
1131 expect_prepare_replay(mock_state_builder, false, false, 0);
1132 expect_is_disconnected(mock_state_builder, false);
1133
1134 // attempt to close remote image
1135 expect_replay_requires_remote_image(mock_state_builder, false);
1136 expect_close_remote_image(mock_state_builder, -EINVAL);
1137
1138 C_SaferCond ctx;
1139 MockThreads mock_threads(m_threads);
1140 MockInstanceWatcher mock_instance_watcher;
1141 MockBootstrapRequest *request = create_request(
1142 &mock_threads, &mock_instance_watcher, "global image id",
1143 "local mirror uuid", &ctx);
1144 request->send();
1145 ASSERT_EQ(0, ctx.wait());
1146 }
1147
1148 TEST_F(TestMockImageReplayerBootstrapRequest, ReplayRequiresRemoteImage) {
1149 InSequence seq;
1150
1151 // prepare local image
1152 MockPrepareLocalImageRequest mock_prepare_local_image_request;
1153 MockStateBuilder mock_state_builder;
1154 expect_send(mock_prepare_local_image_request, mock_state_builder,
1155 m_local_image_ctx->id, m_local_image_ctx->name, 0);
1156
1157 // prepare remote image
1158 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
1159 expect_send(mock_prepare_remote_image_request, mock_state_builder,
1160 "remote mirror uuid", m_remote_image_ctx->id, 0);
1161 expect_is_local_primary(mock_state_builder, false);
1162 expect_is_remote_primary(mock_state_builder, true);
1163
1164 // open the remote image
1165 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
1166 MockOpenImageRequest mock_open_image_request;
1167 expect_open_image(mock_open_image_request, m_remote_io_ctx,
1168 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
1169
1170 // open the local image
1171 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
1172 MockOpenLocalImageRequest mock_open_local_image_request;
1173 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
1174 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
1175
1176 // prepare replay
1177 expect_prepare_replay(mock_state_builder, false, false, 0);
1178 expect_is_disconnected(mock_state_builder, false);
1179
1180 // remote image is left open
1181 expect_replay_requires_remote_image(mock_state_builder, true);
1182
1183 C_SaferCond ctx;
1184 MockThreads mock_threads(m_threads);
1185 MockInstanceWatcher mock_instance_watcher;
1186 MockBootstrapRequest *request = create_request(
1187 &mock_threads, &mock_instance_watcher, "global image id",
1188 "local mirror uuid", &ctx);
1189 request->send();
1190 ASSERT_EQ(0, ctx.wait());
1191 }
1192
1193 } // namespace image_replayer
1194 } // namespace mirror
1195 } // namespace rbd