]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/rbd_mirror/image_replayer/test_mock_CreateImageRequest.cc
update sources to v12.1.3
[ceph.git] / ceph / src / test / rbd_mirror / image_replayer / test_mock_CreateImageRequest.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#include "test/rbd_mirror/test_mock_fixture.h"
5#include "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
19namespace librbd {
20
21namespace {
22
23struct MockTestImageCtx : public librbd::MockImageCtx {
24 MockTestImageCtx(librbd::ImageCtx &image_ctx)
25 : librbd::MockImageCtx(image_ctx) {
26 }
27};
28
29} // anonymous namespace
30
31namespace image {
32
33template<>
34struct 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
67CreateRequest<librbd::MockTestImageCtx>*
68 CreateRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
69
70template<>
71struct 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
99CloneRequest<librbd::MockTestImageCtx>*
100 CloneRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
101
102} // namespace image
103} // namespace librbd
104
105namespace rbd {
106namespace mirror {
107namespace image_replayer {
108
109template<>
110struct 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
134template<>
135struct 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
164CloseImageRequest<librbd::MockTestImageCtx>*
165 CloseImageRequest<librbd::MockTestImageCtx>::s_instance = nullptr;
166OpenImageRequest<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"
175template class rbd::mirror::image_replayer::CreateImageRequest<librbd::MockTestImageCtx>;
176
177namespace rbd {
178namespace mirror {
179namespace image_replayer {
180
181using ::testing::_;
182using ::testing::DoAll;
183using ::testing::InSequence;
184using ::testing::Invoke;
185using ::testing::Return;
186using ::testing::StrEq;
187using ::testing::WithArg;
188
189MATCHER_P(IsSameIoCtx, io_ctx, "") {
190 return &get_mock_io_ctx(arg) == &get_mock_io_ctx(*io_ctx);
191}
192
193class TestMockImageReplayerCreateImageRequest : public TestMockFixture {
194public:
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,
d2e6a577 316 const std::string &local_image_id,
7c673cae 317 librbd::MockTestImageCtx &mock_remote_image_ctx,
7c673cae
FG
318 Context *on_finish) {
319 return new MockCreateImageRequest(m_local_io_ctx, m_threads->work_queue,
320 global_image_id, remote_mirror_uuid,
d2e6a577
FG
321 local_image_name, local_image_id,
322 &mock_remote_image_ctx, on_finish);
7c673cae
FG
323 }
324
325 librbd::ImageCtx *m_remote_image_ctx;
326};
327
328TEST_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;
7c673cae 336 MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
d2e6a577
FG
337 "image name", "101241a7c4c9",
338 mock_remote_image_ctx, &ctx);
7c673cae
FG
339 request->send();
340 ASSERT_EQ(0, ctx.wait());
7c673cae
FG
341}
342
343TEST_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;
7c673cae 351 MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
d2e6a577
FG
352 "image name", "101241a7c4c9",
353 mock_remote_image_ctx, &ctx);
7c673cae
FG
354 request->send();
355 ASSERT_EQ(-EINVAL, ctx.wait());
356}
357
358TEST_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;
7c673cae 394 MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
d2e6a577 395 "image name", "101241a7c4c9",
7c673cae 396 mock_remote_clone_image_ctx,
d2e6a577 397 &ctx);
7c673cae
FG
398 request->send();
399 ASSERT_EQ(0, ctx.wait());
7c673cae
FG
400}
401
402TEST_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;
7c673cae 419 MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
d2e6a577 420 "image name", "101241a7c4c9",
7c673cae 421 mock_remote_clone_image_ctx,
d2e6a577 422 &ctx);
7c673cae
FG
423 request->send();
424 ASSERT_EQ(-ENOENT, ctx.wait());
425}
426
427TEST_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;
7c673cae 445 MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
d2e6a577 446 "image name", "101241a7c4c9",
7c673cae 447 mock_remote_clone_image_ctx,
d2e6a577 448 &ctx);
7c673cae
FG
449 request->send();
450 ASSERT_EQ(-ENOENT, ctx.wait());
451}
452
453TEST_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;
7c673cae 476 MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
d2e6a577 477 "image name", "101241a7c4c9",
7c673cae 478 mock_remote_clone_image_ctx,
d2e6a577 479 &ctx);
7c673cae
FG
480 request->send();
481 ASSERT_EQ(-ENOENT, ctx.wait());
482}
483
484TEST_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;
7c673cae 517 MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
d2e6a577 518 "image name", "101241a7c4c9",
7c673cae 519 mock_remote_clone_image_ctx,
d2e6a577 520 &ctx);
7c673cae
FG
521 request->send();
522 ASSERT_EQ(-ENOENT, ctx.wait());
523}
524
525TEST_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;
7c673cae 560 MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
d2e6a577 561 "image name", "101241a7c4c9",
7c673cae 562 mock_remote_clone_image_ctx,
d2e6a577 563 &ctx);
7c673cae
FG
564 request->send();
565 ASSERT_EQ(-ENOENT, ctx.wait());
566}
567
568TEST_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;
7c673cae 604 MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
d2e6a577 605 "image name", "101241a7c4c9",
7c673cae 606 mock_remote_clone_image_ctx,
d2e6a577 607 &ctx);
7c673cae
FG
608 request->send();
609 ASSERT_EQ(-EINVAL, ctx.wait());
610}
611
612TEST_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;
7c673cae 648 MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
d2e6a577 649 "image name", "101241a7c4c9",
7c673cae 650 mock_remote_clone_image_ctx,
d2e6a577 651 &ctx);
7c673cae
FG
652 request->send();
653 ASSERT_EQ(0, ctx.wait());
7c673cae
FG
654}
655
656TEST_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;
7c673cae 692 MockCreateImageRequest *request = create_request("global uuid", "remote uuid",
d2e6a577 693 "image name", "101241a7c4c9",
7c673cae 694 mock_remote_clone_image_ctx,
d2e6a577 695 &ctx);
7c673cae
FG
696 request->send();
697 ASSERT_EQ(0, ctx.wait());
7c673cae
FG
698}
699
700} // namespace image_replayer
701} // namespace mirror
702} // namespace rbd