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/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/PoolMetaCache.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 bool skip_mirror_enable
,
44 cls::rbd::MirrorImageMode mode
,
45 const std::string
&non_primary_global_image_id
,
46 const std::string
&primary_mirror_uuid
,
47 MockContextWQ
*op_work_queue
,
49 ceph_assert(s_instance
!= nullptr);
50 EXPECT_FALSE(non_primary_global_image_id
.empty());
51 EXPECT_FALSE(primary_mirror_uuid
.empty());
52 EXPECT_FALSE(skip_mirror_enable
);
53 s_instance
->on_finish
= on_finish
;
54 s_instance
->construct(ioctx
);
66 MOCK_METHOD0(send
, void());
67 MOCK_METHOD1(construct
, void(librados::IoCtx
&ioctx
));
70 CreateRequest
<librbd::MockTestImageCtx
>*
71 CreateRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
74 struct CloneRequest
<librbd::MockTestImageCtx
> {
75 static CloneRequest
*s_instance
;
76 Context
*on_finish
= nullptr;
78 static CloneRequest
*create(ConfigProxy
& config
, IoCtx
&p_ioctx
,
79 const std::string
&p_id
,
80 const std::string
&p_snap_name
,
81 const cls::rbd::SnapshotNamespace
& snap_ns
,
83 IoCtx
&c_ioctx
, const std::string
&c_name
,
84 const std::string
&c_id
, ImageOptions c_options
,
85 cls::rbd::MirrorImageMode mode
,
86 const std::string
&non_primary_global_image_id
,
87 const std::string
&primary_mirror_uuid
,
88 MockContextWQ
*op_work_queue
,
90 ceph_assert(s_instance
!= nullptr);
91 s_instance
->on_finish
= on_finish
;
92 s_instance
->construct();
101 s_instance
= nullptr;
104 MOCK_METHOD0(send
, void());
105 MOCK_METHOD0(construct
, void());
108 CloneRequest
<librbd::MockTestImageCtx
>*
109 CloneRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
112 } // namespace librbd
118 struct Threads
<librbd::MockTestImageCtx
> {
119 ceph::mutex
&timer_lock
;
121 ContextWQ
*work_queue
;
123 Threads(Threads
<librbd::ImageCtx
> *threads
)
124 : timer_lock(threads
->timer_lock
), timer(threads
->timer
),
125 work_queue(threads
->work_queue
) {
129 namespace image_replayer
{
132 struct CloseImageRequest
<librbd::MockTestImageCtx
> {
133 static CloseImageRequest
* s_instance
;
134 Context
*on_finish
= nullptr;
136 static CloseImageRequest
* create(librbd::MockTestImageCtx
**image_ctx
,
137 Context
*on_finish
) {
138 ceph_assert(s_instance
!= nullptr);
139 s_instance
->construct(*image_ctx
);
140 s_instance
->on_finish
= on_finish
;
144 CloseImageRequest() {
145 ceph_assert(s_instance
== nullptr);
148 ~CloseImageRequest() {
149 s_instance
= nullptr;
152 MOCK_METHOD1(construct
, void(librbd::MockTestImageCtx
*image_ctx
));
153 MOCK_METHOD0(send
, void());
157 struct OpenImageRequest
<librbd::MockTestImageCtx
> {
158 static OpenImageRequest
* s_instance
;
159 librbd::MockTestImageCtx
**image_ctx
= nullptr;
160 Context
*on_finish
= nullptr;
162 static OpenImageRequest
* create(librados::IoCtx
&io_ctx
,
163 librbd::MockTestImageCtx
**image_ctx
,
164 const std::string
&image_id
,
165 bool read_only
, Context
*on_finish
) {
166 ceph_assert(s_instance
!= nullptr);
167 s_instance
->image_ctx
= image_ctx
;
168 s_instance
->on_finish
= on_finish
;
169 s_instance
->construct(io_ctx
, image_id
);
174 ceph_assert(s_instance
== nullptr);
177 ~OpenImageRequest() {
178 s_instance
= nullptr;
181 MOCK_METHOD2(construct
, void(librados::IoCtx
&io_ctx
,
182 const std::string
&image_id
));
183 MOCK_METHOD0(send
, void());
186 CloseImageRequest
<librbd::MockTestImageCtx
>*
187 CloseImageRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
188 OpenImageRequest
<librbd::MockTestImageCtx
>*
189 OpenImageRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
191 } // namespace image_replayer
192 } // namespace mirror
195 // template definitions
196 #include "tools/rbd_mirror/image_replayer/CreateImageRequest.cc"
197 template class rbd::mirror::image_replayer::CreateImageRequest
<librbd::MockTestImageCtx
>;
201 namespace image_replayer
{
204 using ::testing::DoAll
;
205 using ::testing::InSequence
;
206 using ::testing::Invoke
;
207 using ::testing::Return
;
208 using ::testing::StrEq
;
209 using ::testing::WithArg
;
211 MATCHER_P(IsSameIoCtx
, io_ctx
, "") {
212 return &get_mock_io_ctx(arg
) == &get_mock_io_ctx(*io_ctx
);
215 class TestMockImageReplayerCreateImageRequest
: public TestMockFixture
{
217 typedef Threads
<librbd::MockTestImageCtx
> MockThreads
;
218 typedef librbd::image::CreateRequest
<librbd::MockTestImageCtx
> MockCreateRequest
;
219 typedef librbd::image::CloneRequest
<librbd::MockTestImageCtx
> MockCloneRequest
;
220 typedef CreateImageRequest
<librbd::MockTestImageCtx
> MockCreateImageRequest
;
221 typedef OpenImageRequest
<librbd::MockTestImageCtx
> MockOpenImageRequest
;
222 typedef CloseImageRequest
<librbd::MockTestImageCtx
> MockCloseImageRequest
;
224 void SetUp() override
{
225 TestMockFixture::SetUp();
228 ASSERT_EQ(0, create_image(rbd
, m_remote_io_ctx
, m_image_name
, m_image_size
));
229 ASSERT_EQ(0, open_image(m_remote_io_ctx
, m_image_name
, &m_remote_image_ctx
));
232 void snap_create(librbd::ImageCtx
*image_ctx
, const std::string
&snap_name
) {
233 ASSERT_EQ(0, image_ctx
->operations
->snap_create(cls::rbd::UserSnapshotNamespace(),
235 ASSERT_EQ(0, image_ctx
->operations
->snap_protect(cls::rbd::UserSnapshotNamespace(),
237 ASSERT_EQ(0, image_ctx
->state
->refresh());
240 int clone_image(librbd::ImageCtx
*parent_image_ctx
,
241 const std::string
&snap_name
, const std::string
&clone_name
) {
242 snap_create(parent_image_ctx
, snap_name
);
245 return librbd::clone(m_remote_io_ctx
, parent_image_ctx
->name
.c_str(),
246 snap_name
.c_str(), m_remote_io_ctx
,
247 clone_name
.c_str(), parent_image_ctx
->features
,
251 void expect_create_image(MockCreateRequest
&mock_create_request
,
252 librados::IoCtx
&ioctx
, int r
) {
253 EXPECT_CALL(mock_create_request
, construct(IsSameIoCtx(&ioctx
)));
254 EXPECT_CALL(mock_create_request
, send())
255 .WillOnce(Invoke([this, &mock_create_request
, r
]() {
256 m_threads
->work_queue
->queue(mock_create_request
.on_finish
, r
);
260 void expect_ioctx_create(librados::IoCtx
&io_ctx
) {
261 librados::MockTestMemIoCtxImpl
&io_ctx_impl
= get_mock_io_ctx(io_ctx
);
262 EXPECT_CALL(*get_mock_io_ctx(io_ctx
).get_mock_rados_client(), create_ioctx(_
, _
))
263 .WillOnce(DoAll(GetReference(&io_ctx_impl
),
264 Return(&get_mock_io_ctx(io_ctx
))));
267 void expect_get_parent_global_image_id(librados::IoCtx
&io_ctx
,
268 const std::string
&global_id
, int r
) {
269 cls::rbd::MirrorImage mirror_image
;
270 mirror_image
.global_image_id
= global_id
;
273 encode(mirror_image
, bl
);
275 EXPECT_CALL(get_mock_io_ctx(io_ctx
),
276 exec(RBD_MIRRORING
, _
, StrEq("rbd"), StrEq("mirror_image_get"), _
, _
, _
))
277 .WillOnce(DoAll(WithArg
<5>(Invoke([bl
](bufferlist
*out_bl
) {
283 void expect_mirror_image_get_image_id(librados::IoCtx
&io_ctx
,
284 const std::string
&image_id
, int r
) {
286 encode(image_id
, bl
);
288 EXPECT_CALL(get_mock_io_ctx(io_ctx
),
289 exec(RBD_MIRRORING
, _
, StrEq("rbd"), StrEq("mirror_image_get_image_id"), _
, _
, _
))
290 .WillOnce(DoAll(WithArg
<5>(Invoke([bl
](bufferlist
*out_bl
) {
296 void expect_open_image(MockOpenImageRequest
&mock_open_image_request
,
297 librados::IoCtx
&io_ctx
, const std::string
&image_id
,
298 librbd::MockTestImageCtx
&mock_image_ctx
, int r
) {
299 EXPECT_CALL(mock_open_image_request
, construct(IsSameIoCtx(&io_ctx
), image_id
));
300 EXPECT_CALL(mock_open_image_request
, send())
301 .WillOnce(Invoke([this, &mock_open_image_request
, &mock_image_ctx
, r
]() {
302 *mock_open_image_request
.image_ctx
= &mock_image_ctx
;
303 m_threads
->work_queue
->queue(mock_open_image_request
.on_finish
, r
);
307 void expect_test_op_features(librbd::MockTestImageCtx
& mock_image_ctx
,
309 EXPECT_CALL(mock_image_ctx
,
310 test_op_features(RBD_OPERATION_FEATURE_CLONE_CHILD
))
311 .WillOnce(Return(enabled
));
314 void expect_clone_image(MockCloneRequest
&mock_clone_request
,
316 EXPECT_CALL(mock_clone_request
, construct());
317 EXPECT_CALL(mock_clone_request
, send())
318 .WillOnce(Invoke([this, &mock_clone_request
, r
]() {
319 m_threads
->work_queue
->queue(mock_clone_request
.on_finish
, r
);
323 void expect_close_image(MockCloseImageRequest
&mock_close_image_request
,
324 librbd::MockTestImageCtx
&mock_image_ctx
, int r
) {
325 EXPECT_CALL(mock_close_image_request
, construct(&mock_image_ctx
));
326 EXPECT_CALL(mock_close_image_request
, send())
327 .WillOnce(Invoke([this, &mock_close_image_request
, r
]() {
328 m_threads
->work_queue
->queue(mock_close_image_request
.on_finish
, r
);
332 MockCreateImageRequest
*create_request(MockThreads
* mock_threads
,
333 const std::string
&global_image_id
,
334 const std::string
&remote_mirror_uuid
,
335 const std::string
&local_image_name
,
336 const std::string
&local_image_id
,
337 librbd::MockTestImageCtx
&mock_remote_image_ctx
,
338 Context
*on_finish
) {
339 return new MockCreateImageRequest(mock_threads
, m_local_io_ctx
,
340 global_image_id
, remote_mirror_uuid
,
341 local_image_name
, local_image_id
,
342 &mock_remote_image_ctx
,
344 cls::rbd::MIRROR_IMAGE_MODE_JOURNAL
,
348 PoolMetaCache m_pool_meta_cache
{g_ceph_context
};
349 librbd::ImageCtx
*m_remote_image_ctx
;
352 TEST_F(TestMockImageReplayerCreateImageRequest
, Create
) {
353 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
354 MockCreateRequest mock_create_request
;
357 expect_create_image(mock_create_request
, m_local_io_ctx
, 0);
360 MockThreads
mock_threads(m_threads
);
361 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
362 "remote uuid", "image name",
364 mock_remote_image_ctx
, &ctx
);
366 ASSERT_EQ(0, ctx
.wait());
369 TEST_F(TestMockImageReplayerCreateImageRequest
, CreateError
) {
370 librbd::MockTestImageCtx
mock_remote_image_ctx(*m_remote_image_ctx
);
371 MockCreateRequest mock_create_request
;
374 expect_create_image(mock_create_request
, m_local_io_ctx
, -EINVAL
);
377 MockThreads
mock_threads(m_threads
);
378 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
379 "remote uuid", "image name",
381 mock_remote_image_ctx
, &ctx
);
383 ASSERT_EQ(-EINVAL
, ctx
.wait());
386 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneGetGlobalImageIdError
) {
387 std::string clone_image_name
= get_temp_image_name();
388 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
390 librbd::ImageCtx
*remote_clone_image_ctx
;
391 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
392 &remote_clone_image_ctx
));
394 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
397 expect_ioctx_create(m_remote_io_ctx
);
398 expect_ioctx_create(m_local_io_ctx
);
399 expect_get_parent_global_image_id(m_remote_io_ctx
, "global uuid", -ENOENT
);
402 MockThreads
mock_threads(m_threads
);
403 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
404 "remote uuid", "image name",
406 mock_remote_clone_image_ctx
,
409 ASSERT_EQ(-ENOENT
, ctx
.wait());
412 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneGetLocalParentImageIdError
) {
413 std::string clone_image_name
= get_temp_image_name();
414 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
416 librbd::ImageCtx
*remote_clone_image_ctx
;
417 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
418 &remote_clone_image_ctx
));
420 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
423 expect_ioctx_create(m_remote_io_ctx
);
424 expect_ioctx_create(m_local_io_ctx
);
425 expect_get_parent_global_image_id(m_remote_io_ctx
, "global uuid", 0);
426 expect_mirror_image_get_image_id(m_local_io_ctx
, "local parent id", -ENOENT
);
429 MockThreads
mock_threads(m_threads
);
430 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
431 "remote uuid", "image name",
433 mock_remote_clone_image_ctx
,
436 ASSERT_EQ(-ENOENT
, ctx
.wait());
439 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneOpenRemoteParentError
) {
440 std::string clone_image_name
= get_temp_image_name();
441 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
443 librbd::ImageCtx
*remote_clone_image_ctx
;
444 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
445 &remote_clone_image_ctx
));
447 librbd::MockTestImageCtx
mock_remote_parent_image_ctx(*m_remote_image_ctx
);
448 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
449 MockOpenImageRequest mock_open_image_request
;
452 expect_ioctx_create(m_remote_io_ctx
);
453 expect_ioctx_create(m_local_io_ctx
);
454 expect_get_parent_global_image_id(m_remote_io_ctx
, "global uuid", 0);
455 expect_mirror_image_get_image_id(m_local_io_ctx
, "local parent id", 0);
457 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
458 m_remote_image_ctx
->id
, mock_remote_parent_image_ctx
,
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(-ENOENT
, ctx
.wait());
472 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneParentImageSyncing
) {
474 librbd::ImageCtx
*local_image_ctx
;
475 ASSERT_EQ(0, create_image(rbd
, m_local_io_ctx
, m_image_name
, m_image_size
));
476 ASSERT_EQ(0, open_image(m_local_io_ctx
, m_image_name
, &local_image_ctx
));
477 snap_create(local_image_ctx
, "snap");
478 snap_create(m_remote_image_ctx
, ".rbd-mirror.local parent uuid.1234");
480 std::string clone_image_name
= get_temp_image_name();
481 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
483 librbd::ImageCtx
*remote_clone_image_ctx
;
484 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
485 &remote_clone_image_ctx
));
487 m_pool_meta_cache
.set_local_pool_meta(
488 m_local_io_ctx
.get_id(), {"local parent uuid"});
490 librbd::MockTestImageCtx
mock_remote_parent_image_ctx(*m_remote_image_ctx
);
491 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
492 MockOpenImageRequest mock_open_image_request
;
493 MockCloseImageRequest mock_close_image_request
;
496 expect_ioctx_create(m_remote_io_ctx
);
497 expect_ioctx_create(m_local_io_ctx
);
498 expect_get_parent_global_image_id(m_remote_io_ctx
, "global uuid", 0);
499 expect_mirror_image_get_image_id(m_local_io_ctx
, "local parent id", 0);
501 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
502 m_remote_image_ctx
->id
, mock_remote_parent_image_ctx
, 0);
503 expect_close_image(mock_close_image_request
, mock_remote_parent_image_ctx
, 0);
506 MockThreads
mock_threads(m_threads
);
507 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
508 "remote uuid", "image name",
510 mock_remote_clone_image_ctx
,
513 ASSERT_EQ(-ENOENT
, ctx
.wait());
516 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneError
) {
518 librbd::ImageCtx
*local_image_ctx
;
519 ASSERT_EQ(0, create_image(rbd
, m_local_io_ctx
, m_image_name
, m_image_size
));
520 ASSERT_EQ(0, open_image(m_local_io_ctx
, m_image_name
, &local_image_ctx
));
521 snap_create(local_image_ctx
, "snap");
523 std::string clone_image_name
= get_temp_image_name();
524 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
526 librbd::ImageCtx
*remote_clone_image_ctx
;
527 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
528 &remote_clone_image_ctx
));
530 m_pool_meta_cache
.set_local_pool_meta(
531 m_local_io_ctx
.get_id(), {"local parent uuid"});
533 librbd::MockTestImageCtx
mock_remote_parent_image_ctx(*m_remote_image_ctx
);
534 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
535 MockCloneRequest mock_clone_request
;
536 MockOpenImageRequest mock_open_image_request
;
537 MockCloseImageRequest mock_close_image_request
;
540 expect_ioctx_create(m_remote_io_ctx
);
541 expect_ioctx_create(m_local_io_ctx
);
542 expect_get_parent_global_image_id(m_remote_io_ctx
, "global uuid", 0);
543 expect_mirror_image_get_image_id(m_local_io_ctx
, "local parent id", 0);
545 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
546 m_remote_image_ctx
->id
, mock_remote_parent_image_ctx
, 0);
547 expect_test_op_features(mock_remote_clone_image_ctx
, false);
548 expect_clone_image(mock_clone_request
, -EINVAL
);
549 expect_close_image(mock_close_image_request
, mock_remote_parent_image_ctx
, 0);
552 MockThreads
mock_threads(m_threads
);
553 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
554 "remote uuid", "image name",
556 mock_remote_clone_image_ctx
,
559 ASSERT_EQ(-EINVAL
, ctx
.wait());
562 TEST_F(TestMockImageReplayerCreateImageRequest
, CloneRemoteParentCloseError
) {
564 librbd::ImageCtx
*local_image_ctx
;
565 ASSERT_EQ(0, create_image(rbd
, m_local_io_ctx
, m_image_name
, m_image_size
));
566 ASSERT_EQ(0, open_image(m_local_io_ctx
, m_image_name
, &local_image_ctx
));
567 snap_create(local_image_ctx
, "snap");
569 std::string clone_image_name
= get_temp_image_name();
570 ASSERT_EQ(0, clone_image(m_remote_image_ctx
, "snap", clone_image_name
));
572 librbd::ImageCtx
*remote_clone_image_ctx
;
573 ASSERT_EQ(0, open_image(m_remote_io_ctx
, clone_image_name
,
574 &remote_clone_image_ctx
));
576 m_pool_meta_cache
.set_local_pool_meta(
577 m_local_io_ctx
.get_id(), {"local parent uuid"});
579 librbd::MockTestImageCtx
mock_remote_parent_image_ctx(*m_remote_image_ctx
);
580 librbd::MockTestImageCtx
mock_remote_clone_image_ctx(*remote_clone_image_ctx
);
581 MockCloneRequest mock_clone_request
;
582 MockOpenImageRequest mock_open_image_request
;
583 MockCloseImageRequest mock_close_image_request
;
586 expect_ioctx_create(m_remote_io_ctx
);
587 expect_ioctx_create(m_local_io_ctx
);
588 expect_get_parent_global_image_id(m_remote_io_ctx
, "global uuid", 0);
589 expect_mirror_image_get_image_id(m_local_io_ctx
, "local parent id", 0);
591 expect_open_image(mock_open_image_request
, m_remote_io_ctx
,
592 m_remote_image_ctx
->id
, mock_remote_parent_image_ctx
, 0);
593 expect_test_op_features(mock_remote_clone_image_ctx
, false);
594 expect_clone_image(mock_clone_request
, 0);
595 expect_close_image(mock_close_image_request
, mock_remote_parent_image_ctx
,
599 MockThreads
mock_threads(m_threads
);
600 MockCreateImageRequest
*request
= create_request(&mock_threads
, "global uuid",
601 "remote uuid", "image name",
603 mock_remote_clone_image_ctx
,
606 ASSERT_EQ(0, ctx
.wait());
609 } // namespace image_replayer
610 } // namespace mirror