]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rbd_mirror/image_replayer/test_mock_BootstrapRequest.cc
import 15.2.0 Octopus source
[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 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 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 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_linked, bool());
236
237 MOCK_CONST_METHOD0(replay_requires_remote_image, bool());
238 MOCK_METHOD1(close_remote_image, void(Context*));
239
240 MOCK_METHOD6(create_local_image_request,
241 BaseRequest*(Threads<librbd::MockTestImageCtx>*,
242 librados::IoCtx&,
243 const std::string&,
244 PoolMetaCache*,
245 ProgressContext*,
246 Context*));
247 MOCK_METHOD5(create_prepare_replay_request,
248 BaseRequest*(const std::string&,
249 ProgressContext*,
250 bool*, bool*, Context*));
251
252 void destroy_sync_point_handler() {
253 }
254 void destroy() {
255 }
256 };
257
258 OpenImageRequest<librbd::MockTestImageCtx>*
259 OpenImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
260 OpenLocalImageRequest<librbd::MockTestImageCtx>*
261 OpenLocalImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
262 PrepareLocalImageRequest<librbd::MockTestImageCtx>*
263 PrepareLocalImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
264 PrepareRemoteImageRequest<librbd::MockTestImageCtx>*
265 PrepareRemoteImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
266 StateBuilder<librbd::MockTestImageCtx>*
267 StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr;
268
269 } // namespace image_replayer
270 } // namespace mirror
271 } // namespace rbd
272
273 // template definitions
274 #include "tools/rbd_mirror/image_replayer/BootstrapRequest.cc"
275
276 namespace rbd {
277 namespace mirror {
278 namespace image_replayer {
279
280 using ::testing::_;
281 using ::testing::DoAll;
282 using ::testing::InSequence;
283 using ::testing::Invoke;
284 using ::testing::Return;
285 using ::testing::SetArgPointee;
286 using ::testing::StrEq;
287 using ::testing::WithArg;
288 using ::testing::WithArgs;
289
290 MATCHER_P(IsSameIoCtx, io_ctx, "") {
291 return &get_mock_io_ctx(arg) == &get_mock_io_ctx(*io_ctx);
292 }
293
294 class TestMockImageReplayerBootstrapRequest : public TestMockFixture {
295 public:
296 typedef Threads<librbd::MockTestImageCtx> MockThreads;
297 typedef BootstrapRequest<librbd::MockTestImageCtx> MockBootstrapRequest;
298 typedef ImageSync<librbd::MockTestImageCtx> MockImageSync;
299 typedef InstanceWatcher<librbd::MockTestImageCtx> MockInstanceWatcher;
300 typedef OpenImageRequest<librbd::MockTestImageCtx> MockOpenImageRequest;
301 typedef OpenLocalImageRequest<librbd::MockTestImageCtx> MockOpenLocalImageRequest;
302 typedef PrepareLocalImageRequest<librbd::MockTestImageCtx> MockPrepareLocalImageRequest;
303 typedef PrepareRemoteImageRequest<librbd::MockTestImageCtx> MockPrepareRemoteImageRequest;
304 typedef StateBuilder<librbd::MockTestImageCtx> MockStateBuilder;
305 typedef std::list<cls::journal::Tag> Tags;
306
307 void SetUp() override {
308 TestMockFixture::SetUp();
309
310 librbd::RBD rbd;
311 ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size));
312 ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
313
314 ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
315 ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &m_local_image_ctx));
316 }
317
318 void expect_send(MockPrepareLocalImageRequest &mock_request,
319 MockStateBuilder& mock_state_builder,
320 const std::string& local_image_id,
321 const std::string& local_image_name, int r) {
322 EXPECT_CALL(mock_request, send())
323 .WillOnce(Invoke([&mock_request, &mock_state_builder, local_image_id,
324 local_image_name, r]() {
325 if (r == 0) {
326 *mock_request.state_builder = &mock_state_builder;
327 mock_state_builder.local_image_id = local_image_id;
328 *mock_request.local_image_name = local_image_name;
329 }
330 mock_request.on_finish->complete(r);
331 }));
332 }
333
334 void expect_send(MockPrepareRemoteImageRequest& mock_request,
335 MockStateBuilder& mock_state_builder,
336 const std::string& remote_mirror_uuid,
337 const std::string& remote_image_id,
338 int r) {
339 EXPECT_CALL(mock_request, send())
340 .WillOnce(Invoke([&mock_request, &mock_state_builder, remote_mirror_uuid,
341 remote_image_id, r]() {
342 if (r >= 0) {
343 *mock_request.state_builder = &mock_state_builder;
344 mock_state_builder.remote_image_id = remote_image_id;
345 }
346
347 mock_state_builder.remote_mirror_uuid = remote_mirror_uuid;
348 mock_request.on_finish->complete(r);
349 }));
350 }
351
352 void expect_is_local_primary(MockStateBuilder& mock_state_builder,
353 bool is_primary) {
354 EXPECT_CALL(mock_state_builder, is_local_primary())
355 .WillOnce(Return(is_primary));
356 }
357
358 void expect_is_disconnected(MockStateBuilder& mock_state_builder,
359 bool is_disconnected) {
360 EXPECT_CALL(mock_state_builder, is_disconnected())
361 .WillOnce(Return(is_disconnected));
362 }
363
364 void expect_replay_requires_remote_image(MockStateBuilder& mock_state_builder,
365 bool requires_image) {
366 EXPECT_CALL(mock_state_builder, replay_requires_remote_image())
367 .WillOnce(Return(requires_image));
368 }
369
370 void expect_open_image(MockOpenImageRequest &mock_open_image_request,
371 librados::IoCtx &io_ctx, const std::string &image_id,
372 librbd::MockTestImageCtx &mock_image_ctx, int r) {
373 EXPECT_CALL(mock_open_image_request,
374 construct(IsSameIoCtx(&io_ctx), image_id));
375 EXPECT_CALL(mock_open_image_request, send())
376 .WillOnce(Invoke([this, &mock_open_image_request, &mock_image_ctx, r]() {
377 *mock_open_image_request.image_ctx = &mock_image_ctx;
378 m_threads->work_queue->queue(mock_open_image_request.on_finish, r);
379 }));
380 }
381
382 void expect_open_local_image(MockOpenLocalImageRequest &mock_open_local_image_request,
383 librados::IoCtx &io_ctx, const std::string &image_id,
384 librbd::MockTestImageCtx *mock_image_ctx, int r) {
385 EXPECT_CALL(mock_open_local_image_request,
386 construct(IsSameIoCtx(&io_ctx), image_id));
387 EXPECT_CALL(mock_open_local_image_request, send())
388 .WillOnce(Invoke([this, &mock_open_local_image_request, mock_image_ctx, r]() {
389 if (r >= 0) {
390 *mock_open_local_image_request.image_ctx = mock_image_ctx;
391 }
392 m_threads->work_queue->queue(mock_open_local_image_request.on_finish,
393 r);
394 }));
395 }
396
397 void expect_close_remote_image(
398 MockStateBuilder& mock_state_builder, int r) {
399 EXPECT_CALL(mock_state_builder, close_remote_image(_))
400 .WillOnce(Invoke([&mock_state_builder, r]
401 (Context* on_finish) {
402 mock_state_builder.remote_image_ctx = nullptr;
403 on_finish->complete(r);
404 }));
405 }
406
407 void expect_create_local_image(MockStateBuilder& mock_state_builder,
408 const std::string& local_image_id, int r) {
409 EXPECT_CALL(mock_state_builder,
410 create_local_image_request(_, _, _, _, _, _))
411 .WillOnce(WithArg<5>(
412 Invoke([&mock_state_builder, local_image_id, r](Context* ctx) {
413 if (r >= 0) {
414 mock_state_builder.local_image_id = local_image_id;
415 }
416 mock_state_builder.mock_base_request.on_finish = ctx;
417 return &mock_state_builder.mock_base_request;
418 })));
419 EXPECT_CALL(mock_state_builder.mock_base_request, send())
420 .WillOnce(Invoke([this, &mock_state_builder, r]() {
421 m_threads->work_queue->queue(
422 mock_state_builder.mock_base_request.on_finish, r);
423 }));
424 }
425
426 void expect_prepare_replay(MockStateBuilder& mock_state_builder,
427 bool resync_requested, bool syncing, int r) {
428 EXPECT_CALL(mock_state_builder,
429 create_prepare_replay_request(_, _, _, _, _))
430 .WillOnce(WithArgs<2, 3, 4>(
431 Invoke([&mock_state_builder, resync_requested, syncing, r]
432 (bool* resync, bool* sync, Context* ctx) {
433 if (r >= 0) {
434 *resync = resync_requested;
435 *sync = syncing;
436 }
437 mock_state_builder.mock_base_request.on_finish = ctx;
438 return &mock_state_builder.mock_base_request;
439 })));
440 EXPECT_CALL(mock_state_builder.mock_base_request, send())
441 .WillOnce(Invoke([this, &mock_state_builder, r]() {
442 m_threads->work_queue->queue(
443 mock_state_builder.mock_base_request.on_finish, r);
444 }));
445 }
446
447 void expect_image_sync(MockImageSync &mock_image_sync, int r) {
448 EXPECT_CALL(mock_image_sync, get());
449 EXPECT_CALL(mock_image_sync, send())
450 .WillOnce(Invoke([this, &mock_image_sync, r]() {
451 m_threads->work_queue->queue(mock_image_sync.on_finish, r);
452 }));
453 EXPECT_CALL(mock_image_sync, put());
454 }
455
456 MockBootstrapRequest *create_request(MockThreads* mock_threads,
457 MockInstanceWatcher *mock_instance_watcher,
458 const std::string &global_image_id,
459 const std::string &local_mirror_uuid,
460 Context *on_finish) {
461 return new MockBootstrapRequest(mock_threads,
462 m_local_io_ctx,
463 m_remote_io_ctx,
464 mock_instance_watcher,
465 global_image_id,
466 local_mirror_uuid,
467 {"remote mirror uuid",
468 "remote mirror peer uuid"},
469 nullptr, nullptr, nullptr,
470 &m_mock_state_builder,
471 &m_do_resync, on_finish);
472 }
473
474 librbd::ImageCtx *m_remote_image_ctx;
475 librbd::ImageCtx *m_local_image_ctx = nullptr;
476
477 MockStateBuilder* m_mock_state_builder = nullptr;
478 bool m_do_resync = false;
479 };
480
481 TEST_F(TestMockImageReplayerBootstrapRequest, Success) {
482 InSequence seq;
483
484 // prepare local image
485 MockStateBuilder mock_state_builder;
486 MockPrepareLocalImageRequest mock_prepare_local_image_request;
487 expect_send(mock_prepare_local_image_request, mock_state_builder,
488 m_local_image_ctx->id, m_local_image_ctx->name, 0);
489
490 // prepare remote image
491 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
492 expect_send(mock_prepare_remote_image_request, mock_state_builder,
493 "remote mirror uuid", m_remote_image_ctx->id, 0);
494 expect_is_local_primary(mock_state_builder, false);
495
496 // open the remote image
497 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
498 MockOpenImageRequest mock_open_image_request;
499 expect_open_image(mock_open_image_request, m_remote_io_ctx,
500 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
501
502 // open the local image
503 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
504 MockOpenLocalImageRequest mock_open_local_image_request;
505 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
506 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
507
508 // prepare replay
509 expect_prepare_replay(mock_state_builder, false, false, 0);
510 expect_is_disconnected(mock_state_builder, false);
511
512 // close remote image
513 expect_replay_requires_remote_image(mock_state_builder, false);
514 expect_close_remote_image(mock_state_builder, 0);
515
516 C_SaferCond ctx;
517 MockThreads mock_threads(m_threads);
518 MockInstanceWatcher mock_instance_watcher;
519 MockBootstrapRequest *request = create_request(
520 &mock_threads, &mock_instance_watcher, "global image id",
521 "local mirror uuid", &ctx);
522 request->send();
523 ASSERT_EQ(0, ctx.wait());
524 }
525
526 TEST_F(TestMockImageReplayerBootstrapRequest, OpenLocalImageError) {
527 InSequence seq;
528
529 // prepare local image
530 MockPrepareLocalImageRequest mock_prepare_local_image_request;
531 MockStateBuilder mock_state_builder;
532 expect_send(mock_prepare_local_image_request, mock_state_builder,
533 m_local_image_ctx->id, m_local_image_ctx->name, 0);
534
535 // prepare remote image
536 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
537 expect_send(mock_prepare_remote_image_request, mock_state_builder,
538 "remote mirror uuid", m_remote_image_ctx->id, 0);
539 expect_is_local_primary(mock_state_builder, false);
540
541 // open the remote image
542 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
543 MockOpenImageRequest mock_open_image_request;
544 expect_open_image(mock_open_image_request, m_remote_io_ctx,
545 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
546
547 // open the local image
548 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
549 MockOpenLocalImageRequest mock_open_local_image_request;
550 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
551 mock_local_image_ctx.id, &mock_local_image_ctx,
552 -EINVAL);
553
554 // close remote image
555 expect_replay_requires_remote_image(mock_state_builder, false);
556 expect_close_remote_image(mock_state_builder, 0);
557
558 C_SaferCond ctx;
559 MockThreads mock_threads(m_threads);
560 MockInstanceWatcher mock_instance_watcher;
561 MockBootstrapRequest *request = create_request(
562 &mock_threads, &mock_instance_watcher, "global image id",
563 "local mirror uuid", &ctx);
564 request->send();
565 ASSERT_EQ(-EINVAL, ctx.wait());
566 }
567
568 TEST_F(TestMockImageReplayerBootstrapRequest, OpenLocalImageDNE) {
569 InSequence seq;
570
571 // prepare local image
572 MockPrepareLocalImageRequest mock_prepare_local_image_request;
573 MockStateBuilder mock_state_builder;
574 expect_send(mock_prepare_local_image_request, mock_state_builder,
575 m_local_image_ctx->id, m_local_image_ctx->name, 0);
576
577 // prepare remote image
578 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
579 expect_send(mock_prepare_remote_image_request, mock_state_builder,
580 "remote mirror uuid", m_remote_image_ctx->id, 0);
581 expect_is_local_primary(mock_state_builder, false);
582
583 // open the remote image
584 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
585 MockOpenImageRequest mock_open_image_request;
586 expect_open_image(mock_open_image_request, m_remote_io_ctx,
587 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
588
589 // open the local image
590 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
591 MockOpenLocalImageRequest mock_open_local_image_request;
592 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
593 mock_local_image_ctx.id, &mock_local_image_ctx,
594 -ENOENT);
595
596 // create local image
597 expect_create_local_image(mock_state_builder, "local image id", 0);
598
599 // re-open the local image
600 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
601 "local image id", &mock_local_image_ctx, 0);
602
603 // prepare replay
604 expect_prepare_replay(mock_state_builder, false, false, 0);
605 expect_is_disconnected(mock_state_builder, false);
606
607 // close remote image
608 expect_replay_requires_remote_image(mock_state_builder, false);
609 expect_close_remote_image(mock_state_builder, 0);
610
611 C_SaferCond ctx;
612 MockThreads mock_threads(m_threads);
613 MockInstanceWatcher mock_instance_watcher;
614 MockBootstrapRequest *request = create_request(
615 &mock_threads, &mock_instance_watcher, "global image id",
616 "local mirror uuid", &ctx);
617 request->send();
618 ASSERT_EQ(0, ctx.wait());
619 }
620
621 TEST_F(TestMockImageReplayerBootstrapRequest, OpenLocalImagePrimary) {
622 InSequence seq;
623
624 // prepare local image
625 MockPrepareLocalImageRequest mock_prepare_local_image_request;
626 MockStateBuilder mock_state_builder;
627 expect_send(mock_prepare_local_image_request, mock_state_builder,
628 m_local_image_ctx->id, m_local_image_ctx->name, 0);
629
630 // prepare remote image
631 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
632 expect_send(mock_prepare_remote_image_request, mock_state_builder,
633 "remote mirror uuid", m_remote_image_ctx->id, 0);
634 expect_is_local_primary(mock_state_builder, false);
635
636 // open the remote image
637 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
638 MockOpenImageRequest mock_open_image_request;
639 expect_open_image(mock_open_image_request, m_remote_io_ctx,
640 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
641
642 // open the local image
643 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
644 MockOpenLocalImageRequest mock_open_local_image_request;
645 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
646 mock_local_image_ctx.id, &mock_local_image_ctx,
647 -EREMOTEIO);
648
649 // close remote image
650 expect_replay_requires_remote_image(mock_state_builder, false);
651 expect_close_remote_image(mock_state_builder, 0);
652
653 C_SaferCond ctx;
654 MockThreads mock_threads(m_threads);
655 MockInstanceWatcher mock_instance_watcher;
656 MockBootstrapRequest *request = create_request(
657 &mock_threads, &mock_instance_watcher, "global image id",
658 "local mirror uuid", &ctx);
659 request->send();
660 ASSERT_EQ(-EREMOTEIO, ctx.wait());
661 }
662
663 TEST_F(TestMockImageReplayerBootstrapRequest, CreateLocalImageError) {
664 InSequence seq;
665
666 // prepare local image
667 MockPrepareLocalImageRequest mock_prepare_local_image_request;
668 MockStateBuilder mock_state_builder;
669 expect_send(mock_prepare_local_image_request, mock_state_builder, "", "",
670 -ENOENT);
671
672 // prepare remote image
673 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
674 expect_send(mock_prepare_remote_image_request, mock_state_builder,
675 "remote mirror uuid", m_remote_image_ctx->id, 0);
676 expect_is_local_primary(mock_state_builder, false);
677
678 // open the remote image
679 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
680 MockOpenImageRequest mock_open_image_request;
681 expect_open_image(mock_open_image_request, m_remote_io_ctx,
682 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
683
684 // create local image
685 expect_create_local_image(mock_state_builder, "local image id", -EINVAL);
686
687 // close remote image
688 expect_replay_requires_remote_image(mock_state_builder, false);
689 expect_close_remote_image(mock_state_builder, 0);
690
691 C_SaferCond ctx;
692 MockThreads mock_threads(m_threads);
693 MockInstanceWatcher mock_instance_watcher;
694 MockBootstrapRequest *request = create_request(
695 &mock_threads, &mock_instance_watcher, "global image id",
696 "local mirror uuid", &ctx);
697 request->send();
698 ASSERT_EQ(-EINVAL, ctx.wait());
699 }
700
701 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplayError) {
702 InSequence seq;
703
704 // prepare local image
705 MockPrepareLocalImageRequest mock_prepare_local_image_request;
706 MockStateBuilder mock_state_builder;
707 expect_send(mock_prepare_local_image_request, mock_state_builder,
708 m_local_image_ctx->id, m_local_image_ctx->name, 0);
709
710 // prepare remote image
711 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
712 expect_send(mock_prepare_remote_image_request, mock_state_builder,
713 "remote mirror uuid", m_remote_image_ctx->id, 0);
714 expect_is_local_primary(mock_state_builder, false);
715
716 // open the remote image
717 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
718 MockOpenImageRequest mock_open_image_request;
719 expect_open_image(mock_open_image_request, m_remote_io_ctx,
720 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
721
722 // open the local image
723 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
724 MockOpenLocalImageRequest mock_open_local_image_request;
725 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
726 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
727
728 // prepare replay
729 expect_prepare_replay(mock_state_builder, false, false, -EINVAL);
730
731 // close remote image
732 expect_replay_requires_remote_image(mock_state_builder, false);
733 expect_close_remote_image(mock_state_builder, 0);
734
735 C_SaferCond ctx;
736 MockThreads mock_threads(m_threads);
737 MockInstanceWatcher mock_instance_watcher;
738 MockBootstrapRequest *request = create_request(
739 &mock_threads, &mock_instance_watcher, "global image id",
740 "local mirror uuid", &ctx);
741 request->send();
742 ASSERT_EQ(-EINVAL, ctx.wait());
743 }
744
745 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplayResyncRequested) {
746 InSequence seq;
747
748 // prepare local image
749 MockPrepareLocalImageRequest mock_prepare_local_image_request;
750 MockStateBuilder mock_state_builder;
751 expect_send(mock_prepare_local_image_request, mock_state_builder,
752 m_local_image_ctx->id, m_local_image_ctx->name, 0);
753
754 // prepare remote image
755 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
756 expect_send(mock_prepare_remote_image_request, mock_state_builder,
757 "remote mirror uuid", m_remote_image_ctx->id, 0);
758 expect_is_local_primary(mock_state_builder, false);
759
760 // open the remote image
761 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
762 MockOpenImageRequest mock_open_image_request;
763 expect_open_image(mock_open_image_request, m_remote_io_ctx,
764 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
765
766 // open the local image
767 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
768 MockOpenLocalImageRequest mock_open_local_image_request;
769 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
770 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
771
772 // prepare replay
773 expect_prepare_replay(mock_state_builder, true, false, 0);
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 ASSERT_TRUE(m_do_resync);
788 }
789
790 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplaySyncing) {
791 InSequence seq;
792
793 // prepare local image
794 MockPrepareLocalImageRequest mock_prepare_local_image_request;
795 MockStateBuilder mock_state_builder;
796 expect_send(mock_prepare_local_image_request, mock_state_builder,
797 m_local_image_ctx->id, m_local_image_ctx->name, 0);
798
799 // prepare remote image
800 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
801 expect_send(mock_prepare_remote_image_request, mock_state_builder,
802 "remote mirror uuid", m_remote_image_ctx->id, 0);
803 expect_is_local_primary(mock_state_builder, false);
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, 0);
816
817 // prepare replay
818 expect_prepare_replay(mock_state_builder, false, true, 0);
819 expect_is_disconnected(mock_state_builder, false);
820
821 // image sync
822 MockImageSync mock_image_sync;
823 expect_image_sync(mock_image_sync, 0);
824
825 // close remote image
826 expect_replay_requires_remote_image(mock_state_builder, false);
827 expect_close_remote_image(mock_state_builder, 0);
828
829 C_SaferCond ctx;
830 MockThreads mock_threads(m_threads);
831 MockInstanceWatcher mock_instance_watcher;
832 MockBootstrapRequest *request = create_request(
833 &mock_threads, &mock_instance_watcher, "global image id",
834 "local mirror uuid", &ctx);
835 request->send();
836 ASSERT_EQ(0, ctx.wait());
837 }
838
839 TEST_F(TestMockImageReplayerBootstrapRequest, PrepareReplayDisconnected) {
840 InSequence seq;
841
842 // prepare local image
843 MockPrepareLocalImageRequest mock_prepare_local_image_request;
844 MockStateBuilder mock_state_builder;
845 expect_send(mock_prepare_local_image_request, mock_state_builder,
846 m_local_image_ctx->id, m_local_image_ctx->name, 0);
847
848 // prepare remote image
849 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
850 expect_send(mock_prepare_remote_image_request, mock_state_builder,
851 "remote mirror uuid", m_remote_image_ctx->id, 0);
852 expect_is_local_primary(mock_state_builder, false);
853
854 // open the remote image
855 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
856 MockOpenImageRequest mock_open_image_request;
857 expect_open_image(mock_open_image_request, m_remote_io_ctx,
858 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
859
860 // open the local image
861 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
862 MockOpenLocalImageRequest mock_open_local_image_request;
863 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
864 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
865
866 // prepare replay
867 expect_prepare_replay(mock_state_builder, false, false, 0);
868 expect_is_disconnected(mock_state_builder, false);
869
870 // close remote image
871 expect_replay_requires_remote_image(mock_state_builder, false);
872 expect_close_remote_image(mock_state_builder, 0);
873
874 C_SaferCond ctx;
875 MockThreads mock_threads(m_threads);
876 MockInstanceWatcher mock_instance_watcher;
877 MockBootstrapRequest *request = create_request(
878 &mock_threads, &mock_instance_watcher, "global image id",
879 "local mirror uuid", &ctx);
880 request->send();
881 ASSERT_EQ(0, ctx.wait());
882 }
883
884 TEST_F(TestMockImageReplayerBootstrapRequest, ImageSyncError) {
885 InSequence seq;
886
887 // prepare local image
888 MockPrepareLocalImageRequest mock_prepare_local_image_request;
889 MockStateBuilder mock_state_builder;
890 expect_send(mock_prepare_local_image_request, mock_state_builder,
891 m_local_image_ctx->id, m_local_image_ctx->name, 0);
892
893 // prepare remote image
894 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
895 expect_send(mock_prepare_remote_image_request, mock_state_builder,
896 "remote mirror uuid", m_remote_image_ctx->id, 0);
897 expect_is_local_primary(mock_state_builder, false);
898
899 // open the remote image
900 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
901 MockOpenImageRequest mock_open_image_request;
902 expect_open_image(mock_open_image_request, m_remote_io_ctx,
903 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
904
905 // open the local image
906 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
907 MockOpenLocalImageRequest mock_open_local_image_request;
908 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
909 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
910
911 // prepare replay
912 expect_prepare_replay(mock_state_builder, false, true, 0);
913 expect_is_disconnected(mock_state_builder, false);
914
915 // image sync
916 MockImageSync mock_image_sync;
917 expect_image_sync(mock_image_sync, -EINVAL);
918
919 // close remote image
920 expect_replay_requires_remote_image(mock_state_builder, false);
921 expect_close_remote_image(mock_state_builder, 0);
922
923 C_SaferCond ctx;
924 MockThreads mock_threads(m_threads);
925 MockInstanceWatcher mock_instance_watcher;
926 MockBootstrapRequest *request = create_request(
927 &mock_threads, &mock_instance_watcher, "global image id",
928 "local mirror uuid", &ctx);
929 request->send();
930 ASSERT_EQ(-EINVAL, ctx.wait());
931 }
932
933 TEST_F(TestMockImageReplayerBootstrapRequest, ImageSyncCanceled) {
934 InSequence seq;
935
936 // prepare local image
937 MockPrepareLocalImageRequest mock_prepare_local_image_request;
938 MockStateBuilder mock_state_builder;
939 expect_send(mock_prepare_local_image_request, mock_state_builder,
940 m_local_image_ctx->id, m_local_image_ctx->name, 0);
941
942 // prepare remote image
943 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
944 expect_send(mock_prepare_remote_image_request, mock_state_builder,
945 "remote mirror uuid", m_remote_image_ctx->id, 0);
946 expect_is_local_primary(mock_state_builder, false);
947
948 // open the remote image
949 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
950 MockOpenImageRequest mock_open_image_request;
951 expect_open_image(mock_open_image_request, m_remote_io_ctx,
952 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
953
954 // open the local image
955 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
956 MockOpenLocalImageRequest mock_open_local_image_request;
957 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
958 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
959
960 // prepare replay
961 expect_prepare_replay(mock_state_builder, false, true, 0);
962 expect_is_disconnected(mock_state_builder, false);
963
964 // close remote image
965 expect_replay_requires_remote_image(mock_state_builder, false);
966 expect_close_remote_image(mock_state_builder, 0);
967
968 C_SaferCond ctx;
969 MockThreads mock_threads(m_threads);
970 MockInstanceWatcher mock_instance_watcher;
971 MockBootstrapRequest *request = create_request(
972 &mock_threads, &mock_instance_watcher, "global image id",
973 "local mirror uuid", &ctx);
974 request->cancel();
975 request->send();
976 ASSERT_EQ(-ECANCELED, ctx.wait());
977 }
978
979 TEST_F(TestMockImageReplayerBootstrapRequest, CloseRemoteImageError) {
980 InSequence seq;
981
982 // prepare local image
983 MockPrepareLocalImageRequest mock_prepare_local_image_request;
984 MockStateBuilder mock_state_builder;
985 expect_send(mock_prepare_local_image_request, mock_state_builder,
986 m_local_image_ctx->id, m_local_image_ctx->name, 0);
987
988 // prepare remote image
989 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
990 expect_send(mock_prepare_remote_image_request, mock_state_builder,
991 "remote mirror uuid", m_remote_image_ctx->id, 0);
992 expect_is_local_primary(mock_state_builder, false);
993
994 // open the remote image
995 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
996 MockOpenImageRequest mock_open_image_request;
997 expect_open_image(mock_open_image_request, m_remote_io_ctx,
998 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
999
1000 // open the local image
1001 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
1002 MockOpenLocalImageRequest mock_open_local_image_request;
1003 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
1004 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
1005
1006 // prepare replay
1007 expect_prepare_replay(mock_state_builder, false, false, 0);
1008 expect_is_disconnected(mock_state_builder, false);
1009
1010 // attempt to close remote image
1011 expect_replay_requires_remote_image(mock_state_builder, false);
1012 expect_close_remote_image(mock_state_builder, -EINVAL);
1013
1014 C_SaferCond ctx;
1015 MockThreads mock_threads(m_threads);
1016 MockInstanceWatcher mock_instance_watcher;
1017 MockBootstrapRequest *request = create_request(
1018 &mock_threads, &mock_instance_watcher, "global image id",
1019 "local mirror uuid", &ctx);
1020 request->send();
1021 ASSERT_EQ(0, ctx.wait());
1022 }
1023
1024 TEST_F(TestMockImageReplayerBootstrapRequest, ReplayRequiresRemoteImage) {
1025 InSequence seq;
1026
1027 // prepare local image
1028 MockPrepareLocalImageRequest mock_prepare_local_image_request;
1029 MockStateBuilder mock_state_builder;
1030 expect_send(mock_prepare_local_image_request, mock_state_builder,
1031 m_local_image_ctx->id, m_local_image_ctx->name, 0);
1032
1033 // prepare remote image
1034 MockPrepareRemoteImageRequest mock_prepare_remote_image_request;
1035 expect_send(mock_prepare_remote_image_request, mock_state_builder,
1036 "remote mirror uuid", m_remote_image_ctx->id, 0);
1037 expect_is_local_primary(mock_state_builder, false);
1038
1039 // open the remote image
1040 librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
1041 MockOpenImageRequest mock_open_image_request;
1042 expect_open_image(mock_open_image_request, m_remote_io_ctx,
1043 mock_remote_image_ctx.id, mock_remote_image_ctx, 0);
1044
1045 // open the local image
1046 librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx);
1047 MockOpenLocalImageRequest mock_open_local_image_request;
1048 expect_open_local_image(mock_open_local_image_request, m_local_io_ctx,
1049 mock_local_image_ctx.id, &mock_local_image_ctx, 0);
1050
1051 // prepare replay
1052 expect_prepare_replay(mock_state_builder, false, false, 0);
1053 expect_is_disconnected(mock_state_builder, false);
1054
1055 // remote image is left open
1056 expect_replay_requires_remote_image(mock_state_builder, true);
1057
1058 C_SaferCond ctx;
1059 MockThreads mock_threads(m_threads);
1060 MockInstanceWatcher mock_instance_watcher;
1061 MockBootstrapRequest *request = create_request(
1062 &mock_threads, &mock_instance_watcher, "global image id",
1063 "local mirror uuid", &ctx);
1064 request->send();
1065 ASSERT_EQ(0, ctx.wait());
1066 }
1067
1068 } // namespace image_replayer
1069 } // namespace mirror
1070 } // namespace rbd