Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / test / rbd_mirror / image_replayer / test_mock_CreateImageRequest.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 "include/rbd/librbd.hpp"
6 #include "librbd/ImageState.h"
7 #include "librbd/Operations.h"
8 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
9 #include "test/librados_test_stub/MockTestMemRadosClient.h"
10 #include "test/librbd/mock/MockImageCtx.h"
11 #include "tools/rbd_mirror/image_replayer/CreateImageRequest.h"
12 #include "tools/rbd_mirror/image_replayer/CloseImageRequest.h"
13 #include "tools/rbd_mirror/image_replayer/OpenImageRequest.h"
14 #include "tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h"
15 #include "librbd/image/CreateRequest.h"
16 #include "librbd/image/CloneRequest.h"
17 #include "tools/rbd_mirror/Threads.h"
18
19 namespace librbd {
20
21 namespace {
22
23 struct MockTestImageCtx : public librbd::MockImageCtx {
24   MockTestImageCtx(librbd::ImageCtx &image_ctx)
25     : librbd::MockImageCtx(image_ctx) {
26   }
27 };
28
29 } // anonymous namespace
30
31 namespace image {
32
33 template<>
34 struct CreateRequest<librbd::MockTestImageCtx> {
35   static CreateRequest *s_instance;
36   Context *on_finish = nullptr;
37
38   static CreateRequest *create(IoCtx &ioctx, const std::string &imgname,
39                                const std::string &imageid, uint64_t size,
40                                const librbd::ImageOptions &image_options,
41                                const std::string &non_primary_global_image_id,
42                                const std::string &primary_mirror_uuid,
43                                bool skip_mirror_enable,
44                                MockContextWQ *op_work_queue,
45                                Context *on_finish) {
46     assert(s_instance != nullptr);
47     EXPECT_FALSE(non_primary_global_image_id.empty());
48     EXPECT_FALSE(primary_mirror_uuid.empty());
49     EXPECT_FALSE(skip_mirror_enable);
50     s_instance->on_finish = on_finish;
51     s_instance->construct(ioctx);
52     return s_instance;
53   }
54
55   CreateRequest() {
56     s_instance = this;
57   }
58
59   ~CreateRequest() {
60     s_instance = nullptr;
61   }
62
63   MOCK_METHOD0(send, void());
64   MOCK_METHOD1(construct, void(librados::IoCtx &ioctx));
65 };
66
67 CreateRequest<librbd::MockTestImageCtx>*
68   CreateRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
69
70 template<>
71 struct CloneRequest<librbd::MockTestImageCtx> {
72   static CloneRequest *s_instance;
73   Context *on_finish = nullptr;
74
75   static CloneRequest *create(librbd::MockTestImageCtx *p_imctx,
76                               IoCtx &c_ioctx, const std::string &c_name,
77                               const std::string &c_id, ImageOptions c_options,
78                               const std::string &non_primary_global_image_id,
79                               const std::string &primary_mirror_uuid,
80                               MockContextWQ *op_work_queue, Context *on_finish) {
81     assert(s_instance != nullptr);
82     s_instance->on_finish = on_finish;
83     s_instance->construct(p_imctx);
84     return s_instance;
85   }
86
87   CloneRequest() {
88     s_instance = this;
89   }
90
91   ~CloneRequest() {
92     s_instance = nullptr;
93   }
94
95   MOCK_METHOD0(send, void());
96   MOCK_METHOD1(construct, void(librbd::MockTestImageCtx *p_imctx));
97 };
98
99 CloneRequest<librbd::MockTestImageCtx>*
100   CloneRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
101
102 } // namespace image
103 } // namespace librbd
104
105 namespace rbd {
106 namespace mirror {
107 namespace image_replayer {
108
109 template<>
110 struct CloseImageRequest<librbd::MockTestImageCtx> {
111   static CloseImageRequest* s_instance;
112   Context *on_finish = nullptr;
113
114   static CloseImageRequest* create(librbd::MockTestImageCtx **image_ctx,
115                                    Context *on_finish) {
116     assert(s_instance != nullptr);
117     s_instance->construct(*image_ctx);
118     s_instance->on_finish = on_finish;
119     return s_instance;
120   }
121
122   CloseImageRequest() {
123     assert(s_instance == nullptr);
124     s_instance = this;
125   }
126   ~CloseImageRequest() {
127     s_instance = nullptr;
128   }
129
130   MOCK_METHOD1(construct, void(librbd::MockTestImageCtx *image_ctx));
131   MOCK_METHOD0(send, void());
132 };
133
134 template<>
135 struct OpenImageRequest<librbd::MockTestImageCtx> {
136   static OpenImageRequest* s_instance;
137   librbd::MockTestImageCtx **image_ctx = nullptr;
138   Context *on_finish = nullptr;
139
140   static OpenImageRequest* create(librados::IoCtx &io_ctx,
141                                   librbd::MockTestImageCtx **image_ctx,
142                                   const std::string &image_id,
143                                   bool read_only, Context *on_finish) {
144     assert(s_instance != nullptr);
145     s_instance->image_ctx = image_ctx;
146     s_instance->on_finish = on_finish;
147     s_instance->construct(io_ctx, image_id);
148     return s_instance;
149   }
150
151   OpenImageRequest() {
152     assert(s_instance == nullptr);
153     s_instance = this;
154   }
155   ~OpenImageRequest() {
156     s_instance = nullptr;
157   }
158
159   MOCK_METHOD2(construct, void(librados::IoCtx &io_ctx,
160                                const std::string &image_id));
161   MOCK_METHOD0(send, void());
162 };
163
164 CloseImageRequest<librbd::MockTestImageCtx>*
165   CloseImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
166 OpenImageRequest<librbd::MockTestImageCtx>*
167   OpenImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
168
169 } // namespace image_replayer
170 } // namespace mirror
171 } // namespace rbd
172
173 // template definitions
174 #include "tools/rbd_mirror/image_replayer/CreateImageRequest.cc"
175 template class rbd::mirror::image_replayer::CreateImageRequest<librbd::MockTestImageCtx>;
176
177 namespace rbd {
178 namespace mirror {
179 namespace image_replayer {
180
181 using ::testing::_;
182 using ::testing::DoAll;
183 using ::testing::InSequence;
184 using ::testing::Invoke;
185 using ::testing::Return;
186 using ::testing::StrEq;
187 using ::testing::WithArg;
188
189 MATCHER_P(IsSameIoCtx, io_ctx, "") {
190   return &get_mock_io_ctx(arg) == &get_mock_io_ctx(*io_ctx);
191 }
192
193 class TestMockImageReplayerCreateImageRequest : public TestMockFixture {
194 public:
195   typedef librbd::image::CreateRequest<librbd::MockTestImageCtx> MockCreateRequest;
196   typedef librbd::image::CloneRequest<librbd::MockTestImageCtx> MockCloneRequest;
197   typedef CreateImageRequest<librbd::MockTestImageCtx> MockCreateImageRequest;
198   typedef OpenImageRequest<librbd::MockTestImageCtx> MockOpenImageRequest;
199   typedef CloseImageRequest<librbd::MockTestImageCtx> MockCloseImageRequest;
200
201   void SetUp() override {
202     TestMockFixture::SetUp();
203
204     librbd::RBD rbd;
205     ASSERT_EQ(0, create_image(rbd, m_remote_io_ctx, m_image_name, m_image_size));
206     ASSERT_EQ(0, open_image(m_remote_io_ctx, m_image_name, &m_remote_image_ctx));
207   }
208
209   int clone_image(librbd::ImageCtx *parent_image_ctx,
210                   const std::string &snap_name, const std::string &clone_name) {
211     {
212       librbd::ImageCtx *ictx = new librbd::ImageCtx(parent_image_ctx->name,
213                                                     "", "", m_remote_io_ctx,
214                                                     false);
215       ictx->state->open(false);
216       EXPECT_EQ(0, ictx->operations->snap_create(cls::rbd::UserSnapshotNamespace(),
217                                                  snap_name.c_str()));
218       EXPECT_EQ(0, ictx->operations->snap_protect(cls::rbd::UserSnapshotNamespace(),
219                                                   snap_name.c_str()));
220       ictx->state->close();
221     }
222
223     EXPECT_EQ(0, parent_image_ctx->state->refresh());
224
225     int order = 0;
226     return librbd::clone(m_remote_io_ctx, parent_image_ctx->name.c_str(),
227                          snap_name.c_str(), m_remote_io_ctx,
228                          clone_name.c_str(), parent_image_ctx->features,
229                          &order, 0, 0);
230   }
231
232   void expect_create_image(MockCreateRequest &mock_create_request,
233                            librados::IoCtx &ioctx, int r) {
234     EXPECT_CALL(mock_create_request, construct(IsSameIoCtx(&ioctx)));
235     EXPECT_CALL(mock_create_request, send())
236       .WillOnce(Invoke([this, &mock_create_request, r]() {
237             m_threads->work_queue->queue(mock_create_request.on_finish, r);
238           }));
239   }
240
241   void expect_ioctx_create(librados::IoCtx &io_ctx) {
242     EXPECT_CALL(*get_mock_io_ctx(io_ctx).get_mock_rados_client(), create_ioctx(_, _))
243       .WillOnce(Return(&get_mock_io_ctx(io_ctx)));
244   }
245
246   void expect_get_parent_global_image_id(librados::IoCtx &io_ctx,
247                                          const std::string &global_id, int r) {
248     cls::rbd::MirrorImage mirror_image;
249     mirror_image.global_image_id = global_id;
250
251     bufferlist bl;
252     ::encode(mirror_image, bl);
253
254     EXPECT_CALL(get_mock_io_ctx(io_ctx),
255                 exec(RBD_MIRRORING, _, StrEq("rbd"), StrEq("mirror_image_get"), _, _, _))
256       .WillOnce(DoAll(WithArg<5>(Invoke([bl](bufferlist *out_bl) {
257                                           *out_bl = bl;
258                                         })),
259                       Return(r)));
260   }
261
262   void expect_mirror_image_get_image_id(librados::IoCtx &io_ctx,
263                                         const std::string &image_id, int r) {
264     bufferlist bl;
265     ::encode(image_id, bl);
266
267     EXPECT_CALL(get_mock_io_ctx(io_ctx),
268                 exec(RBD_MIRRORING, _, StrEq("rbd"), StrEq("mirror_image_get_image_id"), _, _, _))
269       .WillOnce(DoAll(WithArg<5>(Invoke([bl](bufferlist *out_bl) {
270                                           *out_bl = bl;
271                                         })),
272                       Return(r)));
273   }
274
275   void expect_open_image(MockOpenImageRequest &mock_open_image_request,
276                          librados::IoCtx &io_ctx, const std::string &image_id,
277                          librbd::MockTestImageCtx &mock_image_ctx, int r) {
278     EXPECT_CALL(mock_open_image_request, construct(IsSameIoCtx(&io_ctx), image_id));
279     EXPECT_CALL(mock_open_image_request, send())
280       .WillOnce(Invoke([this, &mock_open_image_request, &mock_image_ctx, r]() {
281           *mock_open_image_request.image_ctx = &mock_image_ctx;
282           m_threads->work_queue->queue(mock_open_image_request.on_finish, r);
283         }));
284   }
285
286   void expect_snap_set(librbd::MockTestImageCtx &mock_image_ctx,
287                        const std::string &snap_name, int r) {
288     EXPECT_CALL(*mock_image_ctx.state, snap_set(_, StrEq(snap_name), _))
289       .WillOnce(WithArg<2>(Invoke([this, r](Context *on_finish) {
290           m_threads->work_queue->queue(on_finish, r);
291         })));
292   }
293
294   void expect_clone_image(MockCloneRequest &mock_clone_request,
295                           librbd::MockTestImageCtx &mock_parent_imctx,
296                           int r) {
297     EXPECT_CALL(mock_clone_request, construct(&mock_parent_imctx));
298     EXPECT_CALL(mock_clone_request, send())
299       .WillOnce(Invoke([this, &mock_clone_request, r]() {
300             m_threads->work_queue->queue(mock_clone_request.on_finish, r);
301           }));
302   }
303
304   void expect_close_image(MockCloseImageRequest &mock_close_image_request,
305                           librbd::MockTestImageCtx &mock_image_ctx, int r) {
306     EXPECT_CALL(mock_close_image_request, construct(&mock_image_ctx));
307     EXPECT_CALL(mock_close_image_request, send())
308       .WillOnce(Invoke([this, &mock_close_image_request, r]() {
309           m_threads->work_queue->queue(mock_close_image_request.on_finish, r);
310         }));
311   }
312
313   MockCreateImageRequest *create_request(const std::string &global_image_id,
314                                          const std::string &remote_mirror_uuid,
315                                          const std::string &local_image_name,
316                                          const std::string &local_image_id,
317                                          librbd::MockTestImageCtx &mock_remote_image_ctx,
318                                          Context *on_finish) {
319     return new MockCreateImageRequest(m_local_io_ctx, m_threads->work_queue,
320                                       global_image_id, remote_mirror_uuid,
321                                       local_image_name, local_image_id,
322                                       &mock_remote_image_ctx, on_finish);
323   }
324
325   librbd::ImageCtx *m_remote_image_ctx;
326 };
327
328 TEST_F(TestMockImageReplayerCreateImageRequest, Create) {
329   librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
330   MockCreateRequest mock_create_request;
331
332   InSequence seq;
333   expect_create_image(mock_create_request, m_local_io_ctx, 0);
334
335   C_SaferCond ctx;
336   MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
337                                                    "image name", "101241a7c4c9",
338                                                    mock_remote_image_ctx, &ctx);
339   request->send();
340   ASSERT_EQ(0, ctx.wait());
341 }
342
343 TEST_F(TestMockImageReplayerCreateImageRequest, CreateError) {
344   librbd::MockTestImageCtx mock_remote_image_ctx(*m_remote_image_ctx);
345   MockCreateRequest mock_create_request;
346
347   InSequence seq;
348   expect_create_image(mock_create_request, m_local_io_ctx, -EINVAL);
349
350   C_SaferCond ctx;
351   MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
352                                                    "image name", "101241a7c4c9",
353                                                    mock_remote_image_ctx, &ctx);
354   request->send();
355   ASSERT_EQ(-EINVAL, ctx.wait());
356 }
357
358 TEST_F(TestMockImageReplayerCreateImageRequest, Clone) {
359   librbd::RBD rbd;
360   librbd::ImageCtx *local_image_ctx;
361   ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
362   ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &local_image_ctx));
363
364   std::string clone_image_name = get_temp_image_name();
365   ASSERT_EQ(0, clone_image(m_remote_image_ctx, "snap", clone_image_name));
366
367   librbd::ImageCtx *remote_clone_image_ctx;
368   ASSERT_EQ(0, open_image(m_remote_io_ctx, clone_image_name,
369                &remote_clone_image_ctx));
370
371   librbd::MockTestImageCtx mock_remote_parent_image_ctx(*m_remote_image_ctx);
372   librbd::MockTestImageCtx mock_local_parent_image_ctx(*local_image_ctx);
373   librbd::MockTestImageCtx mock_remote_clone_image_ctx(*remote_clone_image_ctx);
374   MockCloneRequest mock_clone_request;
375   MockOpenImageRequest mock_open_image_request;
376   MockCloseImageRequest mock_close_image_request;
377
378   InSequence seq;
379   expect_ioctx_create(m_remote_io_ctx);
380   expect_ioctx_create(m_local_io_ctx);
381   expect_get_parent_global_image_id(m_remote_io_ctx, "global uuid", 0);
382   expect_mirror_image_get_image_id(m_local_io_ctx, "local parent id", 0);
383
384   expect_open_image(mock_open_image_request, m_remote_io_ctx,
385                     m_remote_image_ctx->id, mock_remote_parent_image_ctx, 0);
386   expect_open_image(mock_open_image_request, m_local_io_ctx,
387                     "local parent id", mock_local_parent_image_ctx, 0);
388   expect_snap_set(mock_local_parent_image_ctx, "snap", 0);
389   expect_clone_image(mock_clone_request, mock_local_parent_image_ctx, 0);
390   expect_close_image(mock_close_image_request, mock_local_parent_image_ctx, 0);
391   expect_close_image(mock_close_image_request, mock_remote_parent_image_ctx, 0);
392
393   C_SaferCond ctx;
394   MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
395                                                    "image name", "101241a7c4c9",
396                                                    mock_remote_clone_image_ctx,
397                                                    &ctx);
398   request->send();
399   ASSERT_EQ(0, ctx.wait());
400 }
401
402 TEST_F(TestMockImageReplayerCreateImageRequest, CloneGetGlobalImageIdError) {
403   std::string clone_image_name = get_temp_image_name();
404   ASSERT_EQ(0, clone_image(m_remote_image_ctx, "snap", clone_image_name));
405
406   librbd::ImageCtx *remote_clone_image_ctx;
407   ASSERT_EQ(0, open_image(m_remote_io_ctx, clone_image_name,
408                &remote_clone_image_ctx));
409
410   librbd::MockTestImageCtx mock_remote_clone_image_ctx(*remote_clone_image_ctx);
411   MockCloneRequest mock_clone_request;
412
413   InSequence seq;
414   expect_ioctx_create(m_remote_io_ctx);
415   expect_ioctx_create(m_local_io_ctx);
416   expect_get_parent_global_image_id(m_remote_io_ctx, "global uuid", -ENOENT);
417
418   C_SaferCond ctx;
419   MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
420                                                    "image name", "101241a7c4c9",
421                                                    mock_remote_clone_image_ctx,
422                                                    &ctx);
423   request->send();
424   ASSERT_EQ(-ENOENT, ctx.wait());
425 }
426
427 TEST_F(TestMockImageReplayerCreateImageRequest, CloneGetLocalParentImageIdError) {
428   std::string clone_image_name = get_temp_image_name();
429   ASSERT_EQ(0, clone_image(m_remote_image_ctx, "snap", clone_image_name));
430
431   librbd::ImageCtx *remote_clone_image_ctx;
432   ASSERT_EQ(0, open_image(m_remote_io_ctx, clone_image_name,
433                &remote_clone_image_ctx));
434
435   librbd::MockTestImageCtx mock_remote_clone_image_ctx(*remote_clone_image_ctx);
436   MockCloneRequest mock_clone_request;
437
438   InSequence seq;
439   expect_ioctx_create(m_remote_io_ctx);
440   expect_ioctx_create(m_local_io_ctx);
441   expect_get_parent_global_image_id(m_remote_io_ctx, "global uuid", 0);
442   expect_mirror_image_get_image_id(m_local_io_ctx, "local parent id", -ENOENT);
443
444   C_SaferCond ctx;
445   MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
446                                                    "image name", "101241a7c4c9",
447                                                    mock_remote_clone_image_ctx,
448                                                    &ctx);
449   request->send();
450   ASSERT_EQ(-ENOENT, ctx.wait());
451 }
452
453 TEST_F(TestMockImageReplayerCreateImageRequest, CloneOpenRemoteParentError) {
454   std::string clone_image_name = get_temp_image_name();
455   ASSERT_EQ(0, clone_image(m_remote_image_ctx, "snap", clone_image_name));
456
457   librbd::ImageCtx *remote_clone_image_ctx;
458   ASSERT_EQ(0, open_image(m_remote_io_ctx, clone_image_name,
459                &remote_clone_image_ctx));
460
461   librbd::MockTestImageCtx mock_remote_parent_image_ctx(*m_remote_image_ctx);
462   librbd::MockTestImageCtx mock_remote_clone_image_ctx(*remote_clone_image_ctx);
463   MockCloneRequest mock_clone_request;
464   MockOpenImageRequest mock_open_image_request;
465
466   InSequence seq;
467   expect_ioctx_create(m_remote_io_ctx);
468   expect_ioctx_create(m_local_io_ctx);
469   expect_get_parent_global_image_id(m_remote_io_ctx, "global uuid", 0);
470   expect_mirror_image_get_image_id(m_local_io_ctx, "local parent id", 0);
471
472   expect_open_image(mock_open_image_request, m_remote_io_ctx,
473                     m_remote_image_ctx->id, mock_remote_parent_image_ctx, -ENOENT);
474
475   C_SaferCond ctx;
476   MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
477                                                    "image name", "101241a7c4c9",
478                                                    mock_remote_clone_image_ctx,
479                                                    &ctx);
480   request->send();
481   ASSERT_EQ(-ENOENT, ctx.wait());
482 }
483
484 TEST_F(TestMockImageReplayerCreateImageRequest, CloneOpenLocalParentError) {
485   librbd::RBD rbd;
486   librbd::ImageCtx *local_image_ctx;
487   ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
488   ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &local_image_ctx));
489
490   std::string clone_image_name = get_temp_image_name();
491   ASSERT_EQ(0, clone_image(m_remote_image_ctx, "snap", clone_image_name));
492
493   librbd::ImageCtx *remote_clone_image_ctx;
494   ASSERT_EQ(0, open_image(m_remote_io_ctx, clone_image_name,
495                &remote_clone_image_ctx));
496
497   librbd::MockTestImageCtx mock_remote_parent_image_ctx(*m_remote_image_ctx);
498   librbd::MockTestImageCtx mock_local_parent_image_ctx(*local_image_ctx);
499   librbd::MockTestImageCtx mock_remote_clone_image_ctx(*remote_clone_image_ctx);
500   MockCloneRequest mock_clone_request;
501   MockOpenImageRequest mock_open_image_request;
502   MockCloseImageRequest mock_close_image_request;
503
504   InSequence seq;
505   expect_ioctx_create(m_remote_io_ctx);
506   expect_ioctx_create(m_local_io_ctx);
507   expect_get_parent_global_image_id(m_remote_io_ctx, "global uuid", 0);
508   expect_mirror_image_get_image_id(m_local_io_ctx, "local parent id", 0);
509
510   expect_open_image(mock_open_image_request, m_remote_io_ctx,
511                     m_remote_image_ctx->id, mock_remote_parent_image_ctx, 0);
512   expect_open_image(mock_open_image_request, m_local_io_ctx,
513                     "local parent id", mock_local_parent_image_ctx, -ENOENT);
514   expect_close_image(mock_close_image_request, mock_remote_parent_image_ctx, 0);
515
516   C_SaferCond ctx;
517   MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
518                                                    "image name", "101241a7c4c9",
519                                                    mock_remote_clone_image_ctx,
520                                                    &ctx);
521   request->send();
522   ASSERT_EQ(-ENOENT, ctx.wait());
523 }
524
525 TEST_F(TestMockImageReplayerCreateImageRequest, CloneSnapSetError) {
526   librbd::RBD rbd;
527   librbd::ImageCtx *local_image_ctx;
528   ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
529   ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &local_image_ctx));
530
531   std::string clone_image_name = get_temp_image_name();
532   ASSERT_EQ(0, clone_image(m_remote_image_ctx, "snap", clone_image_name));
533
534   librbd::ImageCtx *remote_clone_image_ctx;
535   ASSERT_EQ(0, open_image(m_remote_io_ctx, clone_image_name,
536                &remote_clone_image_ctx));
537
538   librbd::MockTestImageCtx mock_remote_parent_image_ctx(*m_remote_image_ctx);
539   librbd::MockTestImageCtx mock_local_parent_image_ctx(*local_image_ctx);
540   librbd::MockTestImageCtx mock_remote_clone_image_ctx(*remote_clone_image_ctx);
541   MockCloneRequest mock_clone_request;
542   MockOpenImageRequest mock_open_image_request;
543   MockCloseImageRequest mock_close_image_request;
544
545   InSequence seq;
546   expect_ioctx_create(m_remote_io_ctx);
547   expect_ioctx_create(m_local_io_ctx);
548   expect_get_parent_global_image_id(m_remote_io_ctx, "global uuid", 0);
549   expect_mirror_image_get_image_id(m_local_io_ctx, "local parent id", 0);
550
551   expect_open_image(mock_open_image_request, m_remote_io_ctx,
552                     m_remote_image_ctx->id, mock_remote_parent_image_ctx, 0);
553   expect_open_image(mock_open_image_request, m_local_io_ctx,
554                     "local parent id", mock_local_parent_image_ctx, 0);
555   expect_snap_set(mock_local_parent_image_ctx, "snap", -ENOENT);
556   expect_close_image(mock_close_image_request, mock_local_parent_image_ctx, 0);
557   expect_close_image(mock_close_image_request, mock_remote_parent_image_ctx, 0);
558
559   C_SaferCond ctx;
560   MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
561                                                    "image name", "101241a7c4c9",
562                                                    mock_remote_clone_image_ctx,
563                                                    &ctx);
564   request->send();
565   ASSERT_EQ(-ENOENT, ctx.wait());
566 }
567
568 TEST_F(TestMockImageReplayerCreateImageRequest, CloneError) {
569   librbd::RBD rbd;
570   librbd::ImageCtx *local_image_ctx;
571   ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
572   ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &local_image_ctx));
573
574   std::string clone_image_name = get_temp_image_name();
575   ASSERT_EQ(0, clone_image(m_remote_image_ctx, "snap", clone_image_name));
576
577   librbd::ImageCtx *remote_clone_image_ctx;
578   ASSERT_EQ(0, open_image(m_remote_io_ctx, clone_image_name,
579                &remote_clone_image_ctx));
580
581   librbd::MockTestImageCtx mock_remote_parent_image_ctx(*m_remote_image_ctx);
582   librbd::MockTestImageCtx mock_local_parent_image_ctx(*local_image_ctx);
583   librbd::MockTestImageCtx mock_remote_clone_image_ctx(*remote_clone_image_ctx);
584   MockCloneRequest mock_clone_request;
585   MockOpenImageRequest mock_open_image_request;
586   MockCloseImageRequest mock_close_image_request;
587
588   InSequence seq;
589   expect_ioctx_create(m_remote_io_ctx);
590   expect_ioctx_create(m_local_io_ctx);
591   expect_get_parent_global_image_id(m_remote_io_ctx, "global uuid", 0);
592   expect_mirror_image_get_image_id(m_local_io_ctx, "local parent id", 0);
593
594   expect_open_image(mock_open_image_request, m_remote_io_ctx,
595                     m_remote_image_ctx->id, mock_remote_parent_image_ctx, 0);
596   expect_open_image(mock_open_image_request, m_local_io_ctx,
597                     "local parent id", mock_local_parent_image_ctx, 0);
598   expect_snap_set(mock_local_parent_image_ctx, "snap", 0);
599   expect_clone_image(mock_clone_request, mock_local_parent_image_ctx, -EINVAL);
600   expect_close_image(mock_close_image_request, mock_local_parent_image_ctx, 0);
601   expect_close_image(mock_close_image_request, mock_remote_parent_image_ctx, 0);
602
603   C_SaferCond ctx;
604   MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
605                                                    "image name", "101241a7c4c9",
606                                                    mock_remote_clone_image_ctx,
607                                                    &ctx);
608   request->send();
609   ASSERT_EQ(-EINVAL, ctx.wait());
610 }
611
612 TEST_F(TestMockImageReplayerCreateImageRequest, CloneLocalParentCloseError) {
613   librbd::RBD rbd;
614   librbd::ImageCtx *local_image_ctx;
615   ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
616   ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &local_image_ctx));
617
618   std::string clone_image_name = get_temp_image_name();
619   ASSERT_EQ(0, clone_image(m_remote_image_ctx, "snap", clone_image_name));
620
621   librbd::ImageCtx *remote_clone_image_ctx;
622   ASSERT_EQ(0, open_image(m_remote_io_ctx, clone_image_name,
623                &remote_clone_image_ctx));
624
625   librbd::MockTestImageCtx mock_remote_parent_image_ctx(*m_remote_image_ctx);
626   librbd::MockTestImageCtx mock_local_parent_image_ctx(*local_image_ctx);
627   librbd::MockTestImageCtx mock_remote_clone_image_ctx(*remote_clone_image_ctx);
628   MockCloneRequest mock_clone_request;
629   MockOpenImageRequest mock_open_image_request;
630   MockCloseImageRequest mock_close_image_request;
631
632   InSequence seq;
633   expect_ioctx_create(m_remote_io_ctx);
634   expect_ioctx_create(m_local_io_ctx);
635   expect_get_parent_global_image_id(m_remote_io_ctx, "global uuid", 0);
636   expect_mirror_image_get_image_id(m_local_io_ctx, "local parent id", 0);
637
638   expect_open_image(mock_open_image_request, m_remote_io_ctx,
639                     m_remote_image_ctx->id, mock_remote_parent_image_ctx, 0);
640   expect_open_image(mock_open_image_request, m_local_io_ctx,
641                     "local parent id", mock_local_parent_image_ctx, 0);
642   expect_snap_set(mock_local_parent_image_ctx, "snap", 0);
643   expect_clone_image(mock_clone_request, mock_local_parent_image_ctx, 0);
644   expect_close_image(mock_close_image_request, mock_local_parent_image_ctx, -EINVAL);
645   expect_close_image(mock_close_image_request, mock_remote_parent_image_ctx, 0);
646
647   C_SaferCond ctx;
648   MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
649                                                    "image name", "101241a7c4c9",
650                                                    mock_remote_clone_image_ctx,
651                                                    &ctx);
652   request->send();
653   ASSERT_EQ(0, ctx.wait());
654 }
655
656 TEST_F(TestMockImageReplayerCreateImageRequest, CloneRemoteParentCloseError) {
657   librbd::RBD rbd;
658   librbd::ImageCtx *local_image_ctx;
659   ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size));
660   ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &local_image_ctx));
661
662   std::string clone_image_name = get_temp_image_name();
663   ASSERT_EQ(0, clone_image(m_remote_image_ctx, "snap", clone_image_name));
664
665   librbd::ImageCtx *remote_clone_image_ctx;
666   ASSERT_EQ(0, open_image(m_remote_io_ctx, clone_image_name,
667                &remote_clone_image_ctx));
668
669   librbd::MockTestImageCtx mock_remote_parent_image_ctx(*m_remote_image_ctx);
670   librbd::MockTestImageCtx mock_local_parent_image_ctx(*local_image_ctx);
671   librbd::MockTestImageCtx mock_remote_clone_image_ctx(*remote_clone_image_ctx);
672   MockCloneRequest mock_clone_request;
673   MockOpenImageRequest mock_open_image_request;
674   MockCloseImageRequest mock_close_image_request;
675
676   InSequence seq;
677   expect_ioctx_create(m_remote_io_ctx);
678   expect_ioctx_create(m_local_io_ctx);
679   expect_get_parent_global_image_id(m_remote_io_ctx, "global uuid", 0);
680   expect_mirror_image_get_image_id(m_local_io_ctx, "local parent id", 0);
681
682   expect_open_image(mock_open_image_request, m_remote_io_ctx,
683                     m_remote_image_ctx->id, mock_remote_parent_image_ctx, 0);
684   expect_open_image(mock_open_image_request, m_local_io_ctx,
685                     "local parent id", mock_local_parent_image_ctx, 0);
686   expect_snap_set(mock_local_parent_image_ctx, "snap", 0);
687   expect_clone_image(mock_clone_request, mock_local_parent_image_ctx, 0);
688   expect_close_image(mock_close_image_request, mock_local_parent_image_ctx, 0);
689   expect_close_image(mock_close_image_request, mock_remote_parent_image_ctx, -EINVAL);
690
691   C_SaferCond ctx;
692   MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
693                                                    "image name", "101241a7c4c9",
694                                                    mock_remote_clone_image_ctx,
695                                                    &ctx);
696   request->send();
697   ASSERT_EQ(0, ctx.wait());
698 }
699
700 } // namespace image_replayer
701 } // namespace mirror
702 } // namespace rbd