]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc
d8d7ed2da5615c174682682adbfe4a5dd4a473fd
[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, PrepareRemoteImageDNELocalLinked) {
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, -ENOENT);
652 expect_is_local_primary(mock_state_builder, false);
653 expect_is_linked(mock_state_builder, true);
654
655 C_SaferCond ctx;
656 MockThreads mock_threads(m_threads);
657 MockInstanceWatcher mock_instance_watcher;
658 MockBootstrapRequest *request = create_request(
659 &mock_threads, &mock_instance_watcher, "global image id",
660 "local mirror uuid", &ctx);
661 request->send();
662 ASSERT_EQ(-ENOLINK, ctx.wait());
663 }
664
665 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareRemoteImageDNELocalLinkedCanceled) {
666 InSequence seq;
667
668 // prepare local image
669 MockPrepareLocalImageRequest mock_prepare_local_image_request;
670 MockStateBuilder mock_state_builder;
671 expect_send(mock_prepare_local_image_request, mock_state_builder,
672 m_local_image_ctx->id, m_local_image_ctx->name, 0);
673
674 // prepare remote image
675 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
676 expect_send(mock_prepare_remote_image_request, mock_state_builder,
677 "remote mirror uuid", m_remote_image_ctx->id, -ENOENT);
678 expect_is_local_primary(mock_state_builder, false);
679 expect_is_linked(mock_state_builder, true);
680
681 C_SaferCond ctx;
682 MockThreads mock_threads(m_threads);
683 MockInstanceWatcher mock_instance_watcher;
684 MockBootstrapRequest *request = create_request(
685 &mock_threads, &mock_instance_watcher, "global image id",
686 "local mirror uuid", &ctx);
687 request->cancel();
688 request->send();
689 ASSERT_EQ(-ENOLINK, ctx.wait());
690 }
691
692 TEST_F(TestMockImageReplayerBootstrapRequest, OpenLocalImageError) {
693 InSequence seq;
694
695 // prepare local image
696 MockPrepareLocalImageRequest mock_prepare_local_image_request;
697 MockStateBuilder mock_state_builder;
698 expect_send(mock_prepare_local_image_request, mock_state_builder,
699 m_local_image_ctx->id, m_local_image_ctx->name, 0);
700
701 // prepare remote image
702 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
703 expect_send(mock_prepare_remote_image_request, mock_state_builder,
704 "remote mirror uuid", m_remote_image_ctx->id, 0);
705 expect_is_local_primary(mock_state_builder, false);
706 expect_is_remote_primary(mock_state_builder, true);
707
708 // open the remote image
709 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
710 MockOpenImageRequest mock_open_image_request;
711 expect_open_image(mock_open_image_request, m_remote_io_ctx,
712 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
713
714 // open the local image
715 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
716 MockOpenLocalImageRequest mock_open_local_image_request;
717 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
718 mock_local_image_ctx.id, &mock_local_image_ctx,
719 -EINVAL);
720
721 // close remote image
722 expect_replay_requires_remote_image(mock_state_builder, false);
723 expect_close_remote_image(mock_state_builder, 0);
724
725 C_SaferCond ctx;
726 MockThreads mock_threads(m_threads);
727 MockInstanceWatcher mock_instance_watcher;
728 MockBootstrapRequest *request = create_request(
729 &mock_threads, &mock_instance_watcher, "global image id",
730 "local mirror uuid", &ctx);
731 request->send();
732 ASSERT_EQ(-EINVAL, ctx.wait());
733 }
734
735 TEST_F(TestMockImageReplayerBootstrapRequest, OpenLocalImageDNE) {
736 InSequence seq;
737
738 // prepare local image
739 MockPrepareLocalImageRequest mock_prepare_local_image_request;
740 MockStateBuilder mock_state_builder;
741 expect_send(mock_prepare_local_image_request, mock_state_builder,
742 m_local_image_ctx->id, m_local_image_ctx->name, 0);
743
744 // prepare remote image
745 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
746 expect_send(mock_prepare_remote_image_request, mock_state_builder,
747 "remote mirror uuid", m_remote_image_ctx->id, 0);
748 expect_is_local_primary(mock_state_builder, false);
749 expect_is_remote_primary(mock_state_builder, true);
750
751 // open the remote image
752 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
753 MockOpenImageRequest mock_open_image_request;
754 expect_open_image(mock_open_image_request, m_remote_io_ctx,
755 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
756
757 // open the local image
758 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
759 MockOpenLocalImageRequest mock_open_local_image_request;
760 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
761 mock_local_image_ctx.id, &mock_local_image_ctx,
762 -ENOENT);
763
764 // create local image
765 expect_create_local_image(mock_state_builder, "local image id", 0);
766
767 // re-open the local image
768 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
769 "local image id", &mock_local_image_ctx, 0);
770
771 // prepare replay
772 expect_prepare_replay(mock_state_builder, false, false, 0);
773 expect_is_disconnected(mock_state_builder, false);
774
775 // close remote image
776 expect_replay_requires_remote_image(mock_state_builder, false);
777 expect_close_remote_image(mock_state_builder, 0);
778
779 C_SaferCond ctx;
780 MockThreads mock_threads(m_threads);
781 MockInstanceWatcher mock_instance_watcher;
782 MockBootstrapRequest *request = create_request(
783 &mock_threads, &mock_instance_watcher, "global image id",
784 "local mirror uuid", &ctx);
785 request->send();
786 ASSERT_EQ(0, ctx.wait());
787 }
788
789 TEST_F(TestMockImageReplayerBootstrapRequest, OpenLocalImagePrimary) {
790 InSequence seq;
791
792 // prepare local image
793 MockPrepareLocalImageRequest mock_prepare_local_image_request;
794 MockStateBuilder mock_state_builder;
795 expect_send(mock_prepare_local_image_request, mock_state_builder,
796 m_local_image_ctx->id, m_local_image_ctx->name, 0);
797
798 // prepare remote image
799 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
800 expect_send(mock_prepare_remote_image_request, mock_state_builder,
801 "remote mirror uuid", m_remote_image_ctx->id, 0);
802 expect_is_local_primary(mock_state_builder, false);
803 expect_is_remote_primary(mock_state_builder, true);
804
805 // open the remote image
806 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
807 MockOpenImageRequest mock_open_image_request;
808 expect_open_image(mock_open_image_request, m_remote_io_ctx,
809 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
810
811 // open the local image
812 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
813 MockOpenLocalImageRequest mock_open_local_image_request;
814 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
815 mock_local_image_ctx.id, &mock_local_image_ctx,
816 -EREMOTEIO);
817
818 // close remote image
819 expect_replay_requires_remote_image(mock_state_builder, false);
820 expect_close_remote_image(mock_state_builder, 0);
821
822 C_SaferCond ctx;
823 MockThreads mock_threads(m_threads);
824 MockInstanceWatcher mock_instance_watcher;
825 MockBootstrapRequest *request = create_request(
826 &mock_threads, &mock_instance_watcher, "global image id",
827 "local mirror uuid", &ctx);
828 request->send();
829 ASSERT_EQ(-EREMOTEIO, ctx.wait());
830 }
831
832 TEST_F(TestMockImageReplayerBootstrapRequest, CreateLocalImageError) {
833 InSequence seq;
834
835 // prepare local image
836 MockPrepareLocalImageRequest mock_prepare_local_image_request;
837 MockStateBuilder mock_state_builder;
838 expect_send(mock_prepare_local_image_request, mock_state_builder, "", "",
839 -ENOENT);
840
841 // prepare remote image
842 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
843 expect_send(mock_prepare_remote_image_request, mock_state_builder,
844 "remote mirror uuid", m_remote_image_ctx->id, 0);
845 expect_is_local_primary(mock_state_builder, false);
846 expect_is_remote_primary(mock_state_builder, true);
847
848 // open the remote image
849 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
850 MockOpenImageRequest mock_open_image_request;
851 expect_open_image(mock_open_image_request, m_remote_io_ctx,
852 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
853
854 // create local image
855 expect_create_local_image(mock_state_builder, "local image id", -EINVAL);
856
857 // close remote image
858 expect_replay_requires_remote_image(mock_state_builder, false);
859 expect_close_remote_image(mock_state_builder, 0);
860
861 C_SaferCond ctx;
862 MockThreads mock_threads(m_threads);
863 MockInstanceWatcher mock_instance_watcher;
864 MockBootstrapRequest *request = create_request(
865 &mock_threads, &mock_instance_watcher, "global image id",
866 "local mirror uuid", &ctx);
867 request->send();
868 ASSERT_EQ(-EINVAL, ctx.wait());
869 }
870
871 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplayError) {
872 InSequence seq;
873
874 // prepare local image
875 MockPrepareLocalImageRequest mock_prepare_local_image_request;
876 MockStateBuilder mock_state_builder;
877 expect_send(mock_prepare_local_image_request, mock_state_builder,
878 m_local_image_ctx->id, m_local_image_ctx->name, 0);
879
880 // prepare remote image
881 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
882 expect_send(mock_prepare_remote_image_request, mock_state_builder,
883 "remote mirror uuid", m_remote_image_ctx->id, 0);
884 expect_is_local_primary(mock_state_builder, false);
885 expect_is_remote_primary(mock_state_builder, true);
886
887 // open the remote image
888 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
889 MockOpenImageRequest mock_open_image_request;
890 expect_open_image(mock_open_image_request, m_remote_io_ctx,
891 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
892
893 // open the local image
894 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
895 MockOpenLocalImageRequest mock_open_local_image_request;
896 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
897 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
898
899 // prepare replay
900 expect_prepare_replay(mock_state_builder, false, false, -EINVAL);
901
902 // close remote image
903 expect_replay_requires_remote_image(mock_state_builder, false);
904 expect_close_remote_image(mock_state_builder, 0);
905
906 C_SaferCond ctx;
907 MockThreads mock_threads(m_threads);
908 MockInstanceWatcher mock_instance_watcher;
909 MockBootstrapRequest *request = create_request(
910 &mock_threads, &mock_instance_watcher, "global image id",
911 "local mirror uuid", &ctx);
912 request->send();
913 ASSERT_EQ(-EINVAL, ctx.wait());
914 }
915
916 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplayResyncRequested) {
917 InSequence seq;
918
919 // prepare local image
920 MockPrepareLocalImageRequest mock_prepare_local_image_request;
921 MockStateBuilder mock_state_builder;
922 expect_send(mock_prepare_local_image_request, mock_state_builder,
923 m_local_image_ctx->id, m_local_image_ctx->name, 0);
924
925 // prepare remote image
926 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
927 expect_send(mock_prepare_remote_image_request, mock_state_builder,
928 "remote mirror uuid", m_remote_image_ctx->id, 0);
929 expect_is_local_primary(mock_state_builder, false);
930 expect_is_remote_primary(mock_state_builder, true);
931
932 // open the remote image
933 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
934 MockOpenImageRequest mock_open_image_request;
935 expect_open_image(mock_open_image_request, m_remote_io_ctx,
936 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
937
938 // open the local image
939 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
940 MockOpenLocalImageRequest mock_open_local_image_request;
941 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
942 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
943
944 // prepare replay
945 expect_prepare_replay(mock_state_builder, true, false, 0);
946
947 // close remote image
948 expect_replay_requires_remote_image(mock_state_builder, false);
949 expect_close_remote_image(mock_state_builder, 0);
950
951 C_SaferCond ctx;
952 MockThreads mock_threads(m_threads);
953 MockInstanceWatcher mock_instance_watcher;
954 MockBootstrapRequest *request = create_request(
955 &mock_threads, &mock_instance_watcher, "global image id",
956 "local mirror uuid", &ctx);
957 request->send();
958 ASSERT_EQ(0, ctx.wait());
959 ASSERT_TRUE(m_do_resync);
960 }
961
962 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplaySyncing) {
963 InSequence seq;
964
965 // prepare local image
966 MockPrepareLocalImageRequest mock_prepare_local_image_request;
967 MockStateBuilder mock_state_builder;
968 expect_send(mock_prepare_local_image_request, mock_state_builder,
969 m_local_image_ctx->id, m_local_image_ctx->name, 0);
970
971 // prepare remote image
972 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
973 expect_send(mock_prepare_remote_image_request, mock_state_builder,
974 "remote mirror uuid", m_remote_image_ctx->id, 0);
975 expect_is_local_primary(mock_state_builder, false);
976 expect_is_remote_primary(mock_state_builder, true);
977
978 // open the remote image
979 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
980 MockOpenImageRequest mock_open_image_request;
981 expect_open_image(mock_open_image_request, m_remote_io_ctx,
982 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
983
984 // open the local image
985 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
986 MockOpenLocalImageRequest mock_open_local_image_request;
987 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
988 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
989
990 // prepare replay
991 expect_prepare_replay(mock_state_builder, false, true, 0);
992 expect_is_disconnected(mock_state_builder, false);
993
994 // image sync
995 MockImageSync mock_image_sync;
996 expect_image_sync(mock_image_sync, 0);
997
998 // close remote image
999 expect_replay_requires_remote_image(mock_state_builder, false);
1000 expect_close_remote_image(mock_state_builder, 0);
1001
1002 C_SaferCond ctx;
1003 MockThreads mock_threads(m_threads);
1004 MockInstanceWatcher mock_instance_watcher;
1005 MockBootstrapRequest *request = create_request(
1006 &mock_threads, &mock_instance_watcher, "global image id",
1007 "local mirror uuid", &ctx);
1008 request->send();
1009 ASSERT_EQ(0, ctx.wait());
1010 }
1011
1012 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplayDisconnected) {
1013 InSequence seq;
1014
1015 // prepare local image
1016 MockPrepareLocalImageRequest mock_prepare_local_image_request;
1017 MockStateBuilder mock_state_builder;
1018 expect_send(mock_prepare_local_image_request, mock_state_builder,
1019 m_local_image_ctx->id, m_local_image_ctx->name, 0);
1020
1021 // prepare remote image
1022 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
1023 expect_send(mock_prepare_remote_image_request, mock_state_builder,
1024 "remote mirror uuid", m_remote_image_ctx->id, 0);
1025 expect_is_local_primary(mock_state_builder, false);
1026 expect_is_remote_primary(mock_state_builder, true);
1027
1028 // open the remote image
1029 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
1030 MockOpenImageRequest mock_open_image_request;
1031 expect_open_image(mock_open_image_request, m_remote_io_ctx,
1032 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
1033
1034 // open the local image
1035 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
1036 MockOpenLocalImageRequest mock_open_local_image_request;
1037 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
1038 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
1039
1040 // prepare replay
1041 expect_prepare_replay(mock_state_builder, false, false, 0);
1042 expect_is_disconnected(mock_state_builder, true);
1043
1044 // close remote image
1045 expect_replay_requires_remote_image(mock_state_builder, false);
1046 expect_close_remote_image(mock_state_builder, 0);
1047
1048 C_SaferCond ctx;
1049 MockThreads mock_threads(m_threads);
1050 MockInstanceWatcher mock_instance_watcher;
1051 MockBootstrapRequest *request = create_request(
1052 &mock_threads, &mock_instance_watcher, "global image id",
1053 "local mirror uuid", &ctx);
1054 request->send();
1055 ASSERT_EQ(0, ctx.wait());
1056 }
1057
1058 TEST_F(TestMockImageReplayerBootstrapRequest, ImageSyncError) {
1059 InSequence seq;
1060
1061 // prepare local image
1062 MockPrepareLocalImageRequest mock_prepare_local_image_request;
1063 MockStateBuilder mock_state_builder;
1064 expect_send(mock_prepare_local_image_request, mock_state_builder,
1065 m_local_image_ctx->id, m_local_image_ctx->name, 0);
1066
1067 // prepare remote image
1068 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
1069 expect_send(mock_prepare_remote_image_request, mock_state_builder,
1070 "remote mirror uuid", m_remote_image_ctx->id, 0);
1071 expect_is_local_primary(mock_state_builder, false);
1072 expect_is_remote_primary(mock_state_builder, true);
1073
1074 // open the remote image
1075 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
1076 MockOpenImageRequest mock_open_image_request;
1077 expect_open_image(mock_open_image_request, m_remote_io_ctx,
1078 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
1079
1080 // open the local image
1081 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
1082 MockOpenLocalImageRequest mock_open_local_image_request;
1083 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
1084 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
1085
1086 // prepare replay
1087 expect_prepare_replay(mock_state_builder, false, true, 0);
1088 expect_is_disconnected(mock_state_builder, false);
1089
1090 // image sync
1091 MockImageSync mock_image_sync;
1092 expect_image_sync(mock_image_sync, -EINVAL);
1093
1094 // close remote image
1095 expect_replay_requires_remote_image(mock_state_builder, false);
1096 expect_close_remote_image(mock_state_builder, 0);
1097
1098 C_SaferCond ctx;
1099 MockThreads mock_threads(m_threads);
1100 MockInstanceWatcher mock_instance_watcher;
1101 MockBootstrapRequest *request = create_request(
1102 &mock_threads, &mock_instance_watcher, "global image id",
1103 "local mirror uuid", &ctx);
1104 request->send();
1105 ASSERT_EQ(-EINVAL, ctx.wait());
1106 }
1107
1108 TEST_F(TestMockImageReplayerBootstrapRequest, ImageSyncCanceled) {
1109 InSequence seq;
1110
1111 // prepare local image
1112 MockPrepareLocalImageRequest mock_prepare_local_image_request;
1113 MockStateBuilder mock_state_builder;
1114 expect_send(mock_prepare_local_image_request, mock_state_builder,
1115 m_local_image_ctx->id, m_local_image_ctx->name, 0);
1116
1117 // prepare remote image
1118 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
1119 expect_send(mock_prepare_remote_image_request, mock_state_builder,
1120 "remote mirror uuid", m_remote_image_ctx->id, 0);
1121 expect_is_local_primary(mock_state_builder, false);
1122 expect_is_remote_primary(mock_state_builder, true);
1123
1124 // open the remote image
1125 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
1126 MockOpenImageRequest mock_open_image_request;
1127 expect_open_image(mock_open_image_request, m_remote_io_ctx,
1128 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
1129
1130 // open the local image
1131 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
1132 MockOpenLocalImageRequest mock_open_local_image_request;
1133 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
1134 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
1135
1136 // prepare replay
1137 expect_prepare_replay(mock_state_builder, false, true, 0);
1138 expect_is_disconnected(mock_state_builder, false);
1139
1140 // close remote image
1141 expect_replay_requires_remote_image(mock_state_builder, false);
1142 expect_close_remote_image(mock_state_builder, 0);
1143
1144 C_SaferCond ctx;
1145 MockThreads mock_threads(m_threads);
1146 MockInstanceWatcher mock_instance_watcher;
1147 MockBootstrapRequest *request = create_request(
1148 &mock_threads, &mock_instance_watcher, "global image id",
1149 "local mirror uuid", &ctx);
1150 request->cancel();
1151 request->send();
1152 ASSERT_EQ(-ECANCELED, ctx.wait());
1153 }
1154
1155 TEST_F(TestMockImageReplayerBootstrapRequest, CloseRemoteImageError) {
1156 InSequence seq;
1157
1158 // prepare local image
1159 MockPrepareLocalImageRequest mock_prepare_local_image_request;
1160 MockStateBuilder mock_state_builder;
1161 expect_send(mock_prepare_local_image_request, mock_state_builder,
1162 m_local_image_ctx->id, m_local_image_ctx->name, 0);
1163
1164 // prepare remote image
1165 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
1166 expect_send(mock_prepare_remote_image_request, mock_state_builder,
1167 "remote mirror uuid", m_remote_image_ctx->id, 0);
1168 expect_is_local_primary(mock_state_builder, false);
1169 expect_is_remote_primary(mock_state_builder, true);
1170
1171 // open the remote image
1172 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
1173 MockOpenImageRequest mock_open_image_request;
1174 expect_open_image(mock_open_image_request, m_remote_io_ctx,
1175 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
1176
1177 // open the local image
1178 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
1179 MockOpenLocalImageRequest mock_open_local_image_request;
1180 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
1181 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
1182
1183 // prepare replay
1184 expect_prepare_replay(mock_state_builder, false, false, 0);
1185 expect_is_disconnected(mock_state_builder, false);
1186
1187 // attempt to close remote image
1188 expect_replay_requires_remote_image(mock_state_builder, false);
1189 expect_close_remote_image(mock_state_builder, -EINVAL);
1190
1191 C_SaferCond ctx;
1192 MockThreads mock_threads(m_threads);
1193 MockInstanceWatcher mock_instance_watcher;
1194 MockBootstrapRequest *request = create_request(
1195 &mock_threads, &mock_instance_watcher, "global image id",
1196 "local mirror uuid", &ctx);
1197 request->send();
1198 ASSERT_EQ(0, ctx.wait());
1199 }
1200
1201 TEST_F(TestMockImageReplayerBootstrapRequest, ReplayRequiresRemoteImage) {
1202 InSequence seq;
1203
1204 // prepare local image
1205 MockPrepareLocalImageRequest mock_prepare_local_image_request;
1206 MockStateBuilder mock_state_builder;
1207 expect_send(mock_prepare_local_image_request, mock_state_builder,
1208 m_local_image_ctx->id, m_local_image_ctx->name, 0);
1209
1210 // prepare remote image
1211 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
1212 expect_send(mock_prepare_remote_image_request, mock_state_builder,
1213 "remote mirror uuid", m_remote_image_ctx->id, 0);
1214 expect_is_local_primary(mock_state_builder, false);
1215 expect_is_remote_primary(mock_state_builder, true);
1216
1217 // open the remote image
1218 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
1219 MockOpenImageRequest mock_open_image_request;
1220 expect_open_image(mock_open_image_request, m_remote_io_ctx,
1221 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
1222
1223 // open the local image
1224 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
1225 MockOpenLocalImageRequest mock_open_local_image_request;
1226 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
1227 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
1228
1229 // prepare replay
1230 expect_prepare_replay(mock_state_builder, false, false, 0);
1231 expect_is_disconnected(mock_state_builder, false);
1232
1233 // remote image is left open
1234 expect_replay_requires_remote_image(mock_state_builder, true);
1235
1236 C_SaferCond ctx;
1237 MockThreads mock_threads(m_threads);
1238 MockInstanceWatcher mock_instance_watcher;
1239 MockBootstrapRequest *request = create_request(
1240 &mock_threads, &mock_instance_watcher, "global image id",
1241 "local mirror uuid", &ctx);
1242 request->send();
1243 ASSERT_EQ(0, ctx.wait());
1244 }
1245
1246 } // namespace image_replayer
1247 } // namespace mirror
1248 } // namespace rbd