1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
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/journal/mock/MockJournaler.h"
9 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
10 #include "test/librados_test_stub/MockTestMemRadosClient.h"
11 #include "test/librbd/mock/MockImageCtx.h"
12 #include "tools/rbd_mirror/image_replayer/CreateImageRequest.h"
13 #include "tools/rbd_mirror/image_replayer/CloseImageRequest.h"
14 #include "tools/rbd_mirror/image_replayer/OpenImageRequest.h"
15 #include "tools/rbd_mirror/image_replayer/OpenLocalImageRequest.h"
16 #include "librbd/image/CreateRequest.h"
17 #include "librbd/image/CloneRequest.h"
18 #include "tools/rbd_mirror/Threads.h"
24 struct MockTestImageCtx
: public librbd::MockImageCtx
{
25 explicit MockTestImageCtx(librbd::ImageCtx
&image_ctx
)
26 : librbd::MockImageCtx(image_ctx
) {
30 } // anonymous namespace
35 struct CreateRequest
<librbd::MockTestImageCtx
> {
36 static CreateRequest
*s_instance
;
37 Context
*on_finish
= nullptr;
39 static CreateRequest
*create(const ConfigProxy
& config
, IoCtx
&ioctx
,
40 const std::string
&imgname
,
41 const std::string
&imageid
, uint64_t size
,
42 const librbd::ImageOptions
&image_options
,
43 const std::string
&non_primary_global_image_id
,
44 const std::string
&primary_mirror_uuid
,
45 bool skip_mirror_enable
,
46 MockContextWQ
*op_work_queue
,
48 ceph_assert(s_instance
!= nullptr);
49 EXPECT_FALSE(non_primary_global_image_id
.empty());
50 EXPECT_FALSE(primary_mirror_uuid
.empty());
51 EXPECT_FALSE(skip_mirror_enable
);
52 s_instance
->on_finish
= on_finish
;
53 s_instance
->construct(ioctx
);
65 MOCK_METHOD0(send
, void());
66 MOCK_METHOD1(construct
, void(librados::IoCtx
&ioctx
));
69 CreateRequest
<librbd::MockTestImageCtx
>*
70 CreateRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
73 struct CloneRequest
<librbd::MockTestImageCtx
> {
74 static CloneRequest
*s_instance
;
75 Context
*on_finish
= nullptr;
77 static CloneRequest
*create(ConfigProxy
& config
, IoCtx
&p_ioctx
,
78 const std::string
&p_id
,
79 const std::string
&p_snap_name
,
81 IoCtx
&c_ioctx
, const std::string
&c_name
,
82 const std::string
&c_id
, ImageOptions c_options
,
83 const std::string
&non_primary_global_image_id
,
84 const std::string
&primary_mirror_uuid
,
85 MockContextWQ
*op_work_queue
,
87 ceph_assert(s_instance
!= nullptr);
88 s_instance
->on_finish
= on_finish
;
89 s_instance
->construct();
101 MOCK_METHOD0(send
, void());
102 MOCK_METHOD0(construct
, void());
105 CloneRequest
<librbd::MockTestImageCtx
>*
106 CloneRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
113 struct TypeTraits
<MockTestImageCtx
> {
114 typedef ::journal::MockJournalerProxy Journaler
;
117 } // namespace journal
118 } // namespace librbd
124 struct Threads
<librbd::MockTestImageCtx
> {
127 ContextWQ
*work_queue
;
129 Threads(Threads
<librbd::ImageCtx
> *threads
)
130 : timer_lock(threads
->timer_lock
), timer(threads
->timer
),
131 work_queue(threads
->work_queue
) {
135 namespace image_replayer
{
138 struct CloseImageRequest
<librbd::MockTestImageCtx
> {
139 static CloseImageRequest
* s_instance
;
140 Context
*on_finish
= nullptr;
142 static CloseImageRequest
* create(librbd::MockTestImageCtx
**image_ctx
,
143 Context
*on_finish
) {
144 ceph_assert(s_instance
!= nullptr);
145 s_instance
->construct(*image_ctx
);
146 s_instance
->on_finish
= on_finish
;
150 CloseImageRequest() {
151 ceph_assert(s_instance
== nullptr);
154 ~CloseImageRequest() {
155 s_instance
= nullptr;
158 MOCK_METHOD1(construct
, void(librbd::MockTestImageCtx
*image_ctx
));
159 MOCK_METHOD0(send
, void());
163 struct OpenImageRequest
<librbd::MockTestImageCtx
> {
164 static OpenImageRequest
* s_instance
;
165 librbd::MockTestImageCtx
**image_ctx
= nullptr;
166 Context
*on_finish
= nullptr;
168 static OpenImageRequest
* create(librados::IoCtx
&io_ctx
,
169 librbd::MockTestImageCtx
**image_ctx
,
170 const std::string
&image_id
,
171 bool read_only
, Context
*on_finish
) {
172 ceph_assert(s_instance
!= nullptr);
173 s_instance
->image_ctx
= image_ctx
;
174 s_instance
->on_finish
= on_finish
;
175 s_instance
->construct(io_ctx
, image_id
);
180 ceph_assert(s_instance
== nullptr);
183 ~OpenImageRequest() {
184 s_instance
= nullptr;
187 MOCK_METHOD2(construct
, void(librados::IoCtx
&io_ctx
,
188 const std::string
&image_id
));
189 MOCK_METHOD0(send
, void());
192 CloseImageRequest
<librbd::MockTestImageCtx
>*
193 CloseImageRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
194 OpenImageRequest
<librbd::MockTestImageCtx
>*
195 OpenImageRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
197 } // namespace image_replayer
198 } // namespace mirror
201 // template definitions
202 #include "tools/rbd_mirror/image_replayer/CreateImageRequest.cc"
203 template class rbd::mirror::image_replayer::CreateImageRequest
<librbd::MockTestImageCtx
>;
207 namespace image_replayer
{
210 using ::testing::DoAll
;
211 using ::testing::InSequence
;
212 using ::testing::Invoke
;
213 using ::testing::Return
;
214 using ::testing::StrEq
;
215 using ::testing::WithArg
;
217 MATCHER_P(IsSameIoCtx
, io_ctx
, "") {
218 return &get_mock_io_ctx(arg
) == &get_mock_io_ctx(*io_ctx
);
221 class TestMockImageReplayerCreateImageRequest
: public TestMockFixture
{
223 typedef Threads
<librbd::MockTestImageCtx
> MockThreads
;
224 typedef librbd::image::CreateRequest
<librbd::MockTestImageCtx
> MockCreateRequest
;
225 typedef librbd::image::CloneRequest
<librbd::MockTestImageCtx
> MockCloneRequest
;
226 typedef CreateImageRequest
<librbd::MockTestImageCtx
> MockCreateImageRequest
;
227 typedef OpenImageRequest
<librbd::MockTestImageCtx
> MockOpenImageRequest
;
228 typedef CloseImageRequest
<librbd::MockTestImageCtx
> MockCloseImageRequest
;
230 void SetUp() override
{
231 TestMockFixture::SetUp();
234 ASSERT_EQ(0, create_image(rbd
, m_remote_io_ctx
, m_image_name
, m_image_size
));
235 ASSERT_EQ(0, open_image(m_remote_io_ctx
, m_image_name
, &m_remote_image_ctx
));
238 void snap_create(librbd::ImageCtx
*image_ctx
, const std::string
&snap_name
) {
239 ASSERT_EQ(0, image_ctx
->operations
->snap_create(cls::rbd::UserSnapshotNamespace(),
241 ASSERT_EQ(0, image_ctx
->operations
->snap_protect(cls::rbd::UserSnapshotNamespace(),
243 ASSERT_EQ(0, image_ctx
->state
->refresh());
246 int clone_image(librbd::ImageCtx
*parent_image_ctx
,
247 const std::string
&snap_name
, const std::string
&clone_name
) {
248 snap_create(parent_image_ctx
, snap_name
);
251 return librbd::clone(m_remote_io_ctx
, parent_image_ctx
->name
.c_str(),
252 snap_name
.c_str(), m_remote_io_ctx
,
253 clone_name
.c_str(), parent_image_ctx
->features
,
257 void expect_create_image(MockCreateRequest
&mock_create_request
,
258 librados::IoCtx
&ioctx
, int r
) {
259 EXPECT_CALL(mock_create_request
, construct(IsSameIoCtx(&ioctx
)));
260 EXPECT_CALL(mock_create_request
, send())
261 .WillOnce(Invoke([this, &mock_create_request
, r
]() {
262 m_threads
->work_queue
->queue(mock_create_request
.on_finish
, r
);
266 void expect_ioctx_create(librados::IoCtx
&io_ctx
) {
267 librados::MockTestMemIoCtxImpl
&io_ctx_impl
= get_mock_io_ctx(io_ctx
);
268 EXPECT_CALL(*get_mock_io_ctx(io_ctx
).get_mock_rados_client(), create_ioctx(_
, _
))
269 .WillOnce(DoAll(GetReference(&io_ctx_impl
),
270 Return(&get_mock_io_ctx(io_ctx
))));
273 void expect_get_parent_global_image_id(librados::IoCtx
&io_ctx
,
274 const std::string
&global_id
, int r
) {
275 cls::rbd::MirrorImage mirror_image
;
276 mirror_image
.global_image_id
= global_id
;
279 encode(mirror_image
, bl
);
281 EXPECT_CALL(get_mock_io_ctx(io_ctx
),
282 exec(RBD_MIRRORING
, _
, StrEq("rbd"), StrEq("mirror_image_get"), _
, _
, _
))
283 .WillOnce(DoAll(WithArg
<5>(Invoke([bl
](bufferlist
*out_bl
) {
289 void expect_mirror_image_get_image_id(librados::IoCtx
&io_ctx
,
290 const std::string
&image_id
, int r
) {
292 encode(image_id
, bl
);
294 EXPECT_CALL(get_mock_io_ctx(io_ctx
),
295 exec(RBD_MIRRORING
, _
, StrEq("rbd"), StrEq("mirror_image_get_image_id"), _
, _
, _
))
296 .WillOnce(DoAll(WithArg
<5>(Invoke([bl
](bufferlist
*out_bl
) {
302 void expect_open_image(MockOpenImageRequest
&mock_open_image_request
,
303 librados::IoCtx
&io_ctx
, const std::string
&image_id
,
304 librbd::MockTestImageCtx
&mock_image_ctx
, int r
) {
305 EXPECT_CALL(mock_open_image_request
, construct(IsSameIoCtx(&io_ctx
), image_id
));
306 EXPECT_CALL(mock_open_image_request
, send())
307 .WillOnce(Invoke([this, &mock_open_image_request
, &mock_image_ctx
, r
]() {
308 *mock_open_image_request
.image_ctx
= &mock_image_ctx
;
309 m_threads
->work_queue
->queue(mock_open_image_request
.on_finish
, r
);
313 void expect_test_op_features(librbd::MockTestImageCtx
& mock_image_ctx
,
315 EXPECT_CALL(mock_image_ctx
,
316 test_op_features(RBD_OPERATION_FEATURE_CLONE_CHILD
))
317 .WillOnce(Return(enabled
));
320 void expect_clone_image(MockCloneRequest
&mock_clone_request
,
322 EXPECT_CALL(mock_clone_request
, construct());
323 EXPECT_CALL(mock_clone_request
, send())
324 .WillOnce(Invoke([this, &mock_clone_request
, r
]() {
325 m_threads
->work_queue
->queue(mock_clone_request
.on_finish
, r
);
329 void expect_close_image(MockCloseImageRequest
&mock_close_image_request
,
330 librbd::MockTestImageCtx
&mock_image_ctx
, int r
) {
331 EXPECT_CALL(mock_close_image_request
, construct(&mock_image_ctx
));
332 EXPECT_CALL(mock_close_image_request
, send())
333 .WillOnce(Invoke([this, &mock_close_image_request
, r
]() {
334 m_threads
->work_queue
->queue(mock_close_image_request
.on_finish
, r
);
338 void expect_mirror_uuid_get(librados::IoCtx
&io_ctx
,
339 const std::string
&mirror_uuid
, int r
) {
341 encode(mirror_uuid
, bl
);
343 EXPECT_CALL(get_mock_io_ctx(io_ctx
),
344 exec(RBD_MIRRORING
, _
, StrEq("rbd"), StrEq("mirror_uuid_get"), _
, _
, _
))
345 .WillOnce(DoAll(WithArg
<5>(Invoke([bl
](bufferlist
*out_bl
) {
351 void expect_journaler_get_client(journal::MockJournaler
& mock_journaler
,
352 const std::string
& client_id
,
353 librbd::journal::MirrorPeerState state
,
355 EXPECT_CALL(mock_journaler
, construct());
357 librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta
;
358 mirror_peer_client_meta
.state
= state
;
360 librbd::journal::ClientData client_data
{mirror_peer_client_meta
};
362 cls::journal::Client client
;
363 encode(client_data
, client
.data
);
365 EXPECT_CALL(mock_journaler
, get_client(StrEq(client_id
), _
, _
))
366 .WillOnce(DoAll(WithArg
<1>(Invoke([client
](cls::journal::Client
*out_client
) {
367 *out_client
= client
;
369 WithArg
<2>(Invoke([this, r
](Context
*on_finish
) {
370 m_threads
->work_queue
->queue(on_finish
, r
);
374 MockCreateImageRequest
*create_request(MockThreads
* mock_threads
,
375 const std::string
&global_image_id
,
376 const std::string
&remote_mirror_uuid
,
377 const std::string
&local_image_name
,
378 const std::string
&local_image_id
,
379 librbd::MockTestImageCtx
&mock_remote_image_ctx
,
380 Context
*on_finish
) {
381 return new MockCreateImageRequest(mock_threads
, m_local_io_ctx
,
382 global_image_id
, remote_mirror_uuid
,
383 local_image_name
, local_image_id
,
384 &mock_remote_image_ctx
, on_finish
);
387 librbd::ImageCtx
*m_remote_image_ctx
;
390 TEST_F(TestMockImageReplayerCreateImageRequest
, Create
) {
391 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
392 MockCreateRequest mock_create_request
;
395 expect_create_image(mock_create_request
, m_local_io_ctx
, 0);
398 MockThreads
mock_threads(m_threads
);
399 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
400 "remote uuid", "image name",
402 mock_remote_image_ctx
, &ctx
);
404 ASSERT_EQ(0, ctx
.wait());
407 TEST_F(TestMockImageReplayerCreateImageRequest
, CreateError
) {
408 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
409 MockCreateRequest mock_create_request
;
412 expect_create_image(mock_create_request
, m_local_io_ctx
, -EINVAL
);
415 MockThreads
mock_threads(m_threads
);
416 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
417 "remote uuid", "image name",
419 mock_remote_image_ctx
, &ctx
);
421 ASSERT_EQ(-EINVAL
, ctx
.wait());
424 TEST_F(TestMockImageReplayerCreateImageRequest
, Clone
) {
426 librbd::ImageCtx
*local_image_ctx
;
427 ASSERT_EQ(0, create_image(rbd
, m_local_io_ctx
, m_image_name
, m_image_size
));
428 ASSERT_EQ(0, open_image(m_local_io_ctx
, m_image_name
, &local_image_ctx
));
429 snap_create(local_image_ctx
, "snap");
431 std::string clone_image_name
= get_temp_image_name();
432 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
434 librbd::ImageCtx
*remote_clone_image_ctx
;
435 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
436 &remote_clone_image_ctx
));
438 librbd::MockTestImageCtx
mock_remote_parent_image_ctx(*m_remote_image_ctx
);
439 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
440 MockCloneRequest mock_clone_request
;
441 MockOpenImageRequest mock_open_image_request
;
442 MockCloseImageRequest mock_close_image_request
;
443 journal::MockJournaler mock_remote_journaler
;
446 expect_ioctx_create(m_remote_io_ctx
);
447 expect_ioctx_create(m_local_io_ctx
);
448 expect_mirror_uuid_get(m_local_io_ctx
, "local parent uuid", 0);
449 expect_journaler_get_client(
450 mock_remote_journaler
, "local parent uuid",
451 librbd::journal::MIRROR_PEER_STATE_REPLAYING
, 0);
452 expect_get_parent_global_image_id(m_remote_io_ctx
, "global uuid", 0);
453 expect_mirror_image_get_image_id(m_local_io_ctx
, "local parent id", 0);
455 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
456 m_remote_image_ctx
->id
, mock_remote_parent_image_ctx
, 0);
457 expect_test_op_features(mock_remote_clone_image_ctx
, false);
458 expect_clone_image(mock_clone_request
, 0);
459 expect_close_image(mock_close_image_request
, mock_remote_parent_image_ctx
, 0);
462 MockThreads
mock_threads(m_threads
);
463 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
464 "remote uuid", "image name",
466 mock_remote_clone_image_ctx
,
469 ASSERT_EQ(0, ctx
.wait());
472 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneParentMirrorUuidGetError
) {
473 std::string clone_image_name
= get_temp_image_name();
474 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
476 librbd::ImageCtx
*remote_clone_image_ctx
;
477 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
478 &remote_clone_image_ctx
));
480 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
483 expect_ioctx_create(m_remote_io_ctx
);
484 expect_ioctx_create(m_local_io_ctx
);
485 expect_mirror_uuid_get(m_local_io_ctx
, "local parent uuid", -EPERM
);
488 MockThreads
mock_threads(m_threads
);
489 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
490 "remote uuid", "image name",
492 mock_remote_clone_image_ctx
,
495 ASSERT_EQ(-EPERM
, ctx
.wait());
498 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneGetRemoteParentClientStateError
) {
499 std::string clone_image_name
= get_temp_image_name();
500 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
502 librbd::ImageCtx
*remote_clone_image_ctx
;
503 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
504 &remote_clone_image_ctx
));
506 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
507 journal::MockJournaler mock_remote_journaler
;
510 expect_ioctx_create(m_remote_io_ctx
);
511 expect_ioctx_create(m_local_io_ctx
);
512 expect_mirror_uuid_get(m_local_io_ctx
, "local parent uuid", 0);
513 expect_journaler_get_client(
514 mock_remote_journaler
, "local parent uuid",
515 librbd::journal::MIRROR_PEER_STATE_REPLAYING
, -EPERM
);
518 MockThreads
mock_threads(m_threads
);
519 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
520 "remote uuid", "image name",
522 mock_remote_clone_image_ctx
,
525 ASSERT_EQ(-EPERM
, ctx
.wait());
528 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneGetRemoteParentClientStateSyncing
) {
529 std::string clone_image_name
= get_temp_image_name();
530 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
532 librbd::ImageCtx
*remote_clone_image_ctx
;
533 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
534 &remote_clone_image_ctx
));
536 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
537 journal::MockJournaler mock_remote_journaler
;
540 expect_ioctx_create(m_remote_io_ctx
);
541 expect_ioctx_create(m_local_io_ctx
);
542 expect_mirror_uuid_get(m_local_io_ctx
, "local parent uuid", 0);
543 expect_journaler_get_client(
544 mock_remote_journaler
, "local parent uuid",
545 librbd::journal::MIRROR_PEER_STATE_SYNCING
, 0);
548 MockThreads
mock_threads(m_threads
);
549 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
550 "remote uuid", "image name",
552 mock_remote_clone_image_ctx
,
555 ASSERT_EQ(-ENOENT
, ctx
.wait());
558 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneGetGlobalImageIdError
) {
559 std::string clone_image_name
= get_temp_image_name();
560 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
562 librbd::ImageCtx
*remote_clone_image_ctx
;
563 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
564 &remote_clone_image_ctx
));
566 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
567 journal::MockJournaler mock_remote_journaler
;
570 expect_ioctx_create(m_remote_io_ctx
);
571 expect_ioctx_create(m_local_io_ctx
);
572 expect_mirror_uuid_get(m_local_io_ctx
, "local parent uuid", 0);
573 expect_journaler_get_client(
574 mock_remote_journaler
, "local parent uuid",
575 librbd::journal::MIRROR_PEER_STATE_REPLAYING
, 0);
576 expect_get_parent_global_image_id(m_remote_io_ctx
, "global uuid", -ENOENT
);
579 MockThreads
mock_threads(m_threads
);
580 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
581 "remote uuid", "image name",
583 mock_remote_clone_image_ctx
,
586 ASSERT_EQ(-ENOENT
, ctx
.wait());
589 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneGetLocalParentImageIdError
) {
590 std::string clone_image_name
= get_temp_image_name();
591 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
593 librbd::ImageCtx
*remote_clone_image_ctx
;
594 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
595 &remote_clone_image_ctx
));
597 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
598 journal::MockJournaler mock_remote_journaler
;
601 expect_ioctx_create(m_remote_io_ctx
);
602 expect_ioctx_create(m_local_io_ctx
);
603 expect_mirror_uuid_get(m_local_io_ctx
, "local parent uuid", 0);
604 expect_journaler_get_client(
605 mock_remote_journaler
, "local parent uuid",
606 librbd::journal::MIRROR_PEER_STATE_REPLAYING
, 0);
607 expect_get_parent_global_image_id(m_remote_io_ctx
, "global uuid", 0);
608 expect_mirror_image_get_image_id(m_local_io_ctx
, "local parent id", -ENOENT
);
611 MockThreads
mock_threads(m_threads
);
612 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
613 "remote uuid", "image name",
615 mock_remote_clone_image_ctx
,
618 ASSERT_EQ(-ENOENT
, ctx
.wait());
621 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneOpenRemoteParentError
) {
622 std::string clone_image_name
= get_temp_image_name();
623 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
625 librbd::ImageCtx
*remote_clone_image_ctx
;
626 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
627 &remote_clone_image_ctx
));
629 librbd::MockTestImageCtx
mock_remote_parent_image_ctx(*m_remote_image_ctx
);
630 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
631 MockOpenImageRequest mock_open_image_request
;
632 journal::MockJournaler mock_remote_journaler
;
635 expect_ioctx_create(m_remote_io_ctx
);
636 expect_ioctx_create(m_local_io_ctx
);
637 expect_mirror_uuid_get(m_local_io_ctx
, "local parent uuid", 0);
638 expect_journaler_get_client(
639 mock_remote_journaler
, "local parent uuid",
640 librbd::journal::MIRROR_PEER_STATE_REPLAYING
, 0);
641 expect_get_parent_global_image_id(m_remote_io_ctx
, "global uuid", 0);
642 expect_mirror_image_get_image_id(m_local_io_ctx
, "local parent id", 0);
644 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
645 m_remote_image_ctx
->id
, mock_remote_parent_image_ctx
,
649 MockThreads
mock_threads(m_threads
);
650 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
651 "remote uuid", "image name",
653 mock_remote_clone_image_ctx
,
656 ASSERT_EQ(-ENOENT
, ctx
.wait());
659 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneError
) {
661 librbd::ImageCtx
*local_image_ctx
;
662 ASSERT_EQ(0, create_image(rbd
, m_local_io_ctx
, m_image_name
, m_image_size
));
663 ASSERT_EQ(0, open_image(m_local_io_ctx
, m_image_name
, &local_image_ctx
));
664 snap_create(local_image_ctx
, "snap");
666 std::string clone_image_name
= get_temp_image_name();
667 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
669 librbd::ImageCtx
*remote_clone_image_ctx
;
670 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
671 &remote_clone_image_ctx
));
673 librbd::MockTestImageCtx
mock_remote_parent_image_ctx(*m_remote_image_ctx
);
674 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
675 MockCloneRequest mock_clone_request
;
676 MockOpenImageRequest mock_open_image_request
;
677 MockCloseImageRequest mock_close_image_request
;
678 journal::MockJournaler mock_remote_journaler
;
681 expect_ioctx_create(m_remote_io_ctx
);
682 expect_ioctx_create(m_local_io_ctx
);
683 expect_mirror_uuid_get(m_local_io_ctx
, "local parent uuid", 0);
684 expect_journaler_get_client(
685 mock_remote_journaler
, "local parent uuid",
686 librbd::journal::MIRROR_PEER_STATE_REPLAYING
, 0);
687 expect_get_parent_global_image_id(m_remote_io_ctx
, "global uuid", 0);
688 expect_mirror_image_get_image_id(m_local_io_ctx
, "local parent id", 0);
690 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
691 m_remote_image_ctx
->id
, mock_remote_parent_image_ctx
, 0);
692 expect_test_op_features(mock_remote_clone_image_ctx
, false);
693 expect_clone_image(mock_clone_request
, -EINVAL
);
694 expect_close_image(mock_close_image_request
, mock_remote_parent_image_ctx
, 0);
697 MockThreads
mock_threads(m_threads
);
698 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
699 "remote uuid", "image name",
701 mock_remote_clone_image_ctx
,
704 ASSERT_EQ(-EINVAL
, ctx
.wait());
707 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneRemoteParentCloseError
) {
709 librbd::ImageCtx
*local_image_ctx
;
710 ASSERT_EQ(0, create_image(rbd
, m_local_io_ctx
, m_image_name
, m_image_size
));
711 ASSERT_EQ(0, open_image(m_local_io_ctx
, m_image_name
, &local_image_ctx
));
712 snap_create(local_image_ctx
, "snap");
714 std::string clone_image_name
= get_temp_image_name();
715 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
717 librbd::ImageCtx
*remote_clone_image_ctx
;
718 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
719 &remote_clone_image_ctx
));
721 librbd::MockTestImageCtx
mock_remote_parent_image_ctx(*m_remote_image_ctx
);
722 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
723 MockCloneRequest mock_clone_request
;
724 MockOpenImageRequest mock_open_image_request
;
725 MockCloseImageRequest mock_close_image_request
;
726 journal::MockJournaler mock_remote_journaler
;
729 expect_ioctx_create(m_remote_io_ctx
);
730 expect_ioctx_create(m_local_io_ctx
);
731 expect_mirror_uuid_get(m_local_io_ctx
, "local parent uuid", 0);
732 expect_journaler_get_client(
733 mock_remote_journaler
, "local parent uuid",
734 librbd::journal::MIRROR_PEER_STATE_REPLAYING
, 0);
735 expect_get_parent_global_image_id(m_remote_io_ctx
, "global uuid", 0);
736 expect_mirror_image_get_image_id(m_local_io_ctx
, "local parent id", 0);
738 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
739 m_remote_image_ctx
->id
, mock_remote_parent_image_ctx
, 0);
740 expect_test_op_features(mock_remote_clone_image_ctx
, false);
741 expect_clone_image(mock_clone_request
, 0);
742 expect_close_image(mock_close_image_request
, mock_remote_parent_image_ctx
,
746 MockThreads
mock_threads(m_threads
);
747 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
748 "remote uuid", "image name",
750 mock_remote_clone_image_ctx
,
753 ASSERT_EQ(0, ctx
.wait());
756 } // namespace image_replayer
757 } // namespace mirror