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 "cls/rbd/cls_rbd_types.h"
6 #include "librbd/journal/TypeTraits.h"
7 #include "tools/rbd_mirror/image_replayer/GetMirrorImageIdRequest.h"
8 #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.h"
9 #include "test/journal/mock/MockJournaler.h"
10 #include "test/librados_test_stub/MockTestMemIoCtxImpl.h"
11 #include "test/librbd/mock/MockImageCtx.h"
12 #include "test/librbd/mock/MockJournal.h"
18 struct MockTestImageCtx
: public librbd::MockImageCtx
{
19 MockTestImageCtx(librbd::ImageCtx
&image_ctx
)
20 : librbd::MockImageCtx(image_ctx
) {
24 } // anonymous namespace
29 namespace image_replayer
{
32 struct GetMirrorImageIdRequest
<librbd::MockTestImageCtx
> {
33 static GetMirrorImageIdRequest
* s_instance
;
34 std::string
* image_id
= nullptr;
35 Context
* on_finish
= nullptr;
37 static GetMirrorImageIdRequest
* create(librados::IoCtx
& io_ctx
,
38 const std::string
& global_image_id
,
39 std::string
* image_id
,
41 assert(s_instance
!= nullptr);
42 s_instance
->image_id
= image_id
;
43 s_instance
->on_finish
= on_finish
;
47 GetMirrorImageIdRequest() {
51 MOCK_METHOD0(send
, void());
54 GetMirrorImageIdRequest
<librbd::MockTestImageCtx
>* GetMirrorImageIdRequest
<librbd::MockTestImageCtx
>::s_instance
= nullptr;
56 } // namespace image_replayer
60 // template definitions
61 #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc"
65 namespace image_replayer
{
68 using ::testing::DoAll
;
69 using ::testing::InSequence
;
70 using ::testing::Invoke
;
71 using ::testing::Return
;
72 using ::testing::StrEq
;
73 using ::testing::WithArg
;
74 using ::testing::WithArgs
;
76 class TestMockImageReplayerPrepareLocalImageRequest
: public TestMockFixture
{
78 typedef PrepareLocalImageRequest
<librbd::MockTestImageCtx
> MockPrepareLocalImageRequest
;
79 typedef GetMirrorImageIdRequest
<librbd::MockTestImageCtx
> MockGetMirrorImageIdRequest
;
81 void expect_get_mirror_image_id(MockGetMirrorImageIdRequest
& mock_get_mirror_image_id_request
,
82 const std::string
& image_id
, int r
) {
83 EXPECT_CALL(mock_get_mirror_image_id_request
, send())
84 .WillOnce(Invoke([&mock_get_mirror_image_id_request
, image_id
, r
]() {
85 *mock_get_mirror_image_id_request
.image_id
= image_id
;
86 mock_get_mirror_image_id_request
.on_finish
->complete(r
);
90 void expect_dir_get_name(librados::IoCtx
&io_ctx
,
91 const std::string
&image_name
, int r
) {
93 encode(image_name
, bl
);
95 EXPECT_CALL(get_mock_io_ctx(io_ctx
),
96 exec(RBD_DIRECTORY
, _
, StrEq("rbd"), StrEq("dir_get_name"), _
, _
, _
))
97 .WillOnce(DoAll(WithArg
<5>(Invoke([bl
](bufferlist
*out_bl
) {
103 void expect_mirror_image_get(librados::IoCtx
&io_ctx
,
104 cls::rbd::MirrorImageState state
,
105 const std::string
&global_id
, int r
) {
106 cls::rbd::MirrorImage mirror_image
;
107 mirror_image
.state
= state
;
108 mirror_image
.global_image_id
= global_id
;
111 ::encode(mirror_image
, bl
);
113 EXPECT_CALL(get_mock_io_ctx(io_ctx
),
114 exec(RBD_MIRRORING
, _
, StrEq("rbd"), StrEq("mirror_image_get"), _
, _
, _
))
115 .WillOnce(DoAll(WithArg
<5>(Invoke([bl
](bufferlist
*out_bl
) {
121 void expect_get_tag_owner(librbd::MockJournal
&mock_journal
,
122 const std::string
&local_image_id
,
123 const std::string
&tag_owner
, int r
) {
124 EXPECT_CALL(mock_journal
, get_tag_owner(local_image_id
, _
, _
, _
))
125 .WillOnce(WithArgs
<1, 3>(Invoke([tag_owner
, r
](std::string
*owner
, Context
*on_finish
) {
127 on_finish
->complete(r
);
133 TEST_F(TestMockImageReplayerPrepareLocalImageRequest
, Success
) {
135 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request
;
136 expect_get_mirror_image_id(mock_get_mirror_image_id_request
, "local image id",
138 expect_dir_get_name(m_local_io_ctx
, "local image name", 0);
139 expect_mirror_image_get(m_local_io_ctx
, cls::rbd::MIRROR_IMAGE_STATE_ENABLED
,
140 "global image id", 0);
142 librbd::MockJournal mock_journal
;
143 expect_get_tag_owner(mock_journal
, "local image id", "remote mirror uuid", 0);
145 std::string local_image_id
;
146 std::string local_image_name
;
147 std::string tag_owner
;
149 auto req
= MockPrepareLocalImageRequest::create(m_local_io_ctx
,
154 m_threads
->work_queue
,
158 ASSERT_EQ(0, ctx
.wait());
159 ASSERT_EQ(std::string("local image id"), local_image_id
);
160 ASSERT_EQ(std::string("local image name"), local_image_name
);
161 ASSERT_EQ(std::string("remote mirror uuid"), tag_owner
);
164 TEST_F(TestMockImageReplayerPrepareLocalImageRequest
, MirrorImageIdError
) {
166 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request
;
167 expect_get_mirror_image_id(mock_get_mirror_image_id_request
, "", -EINVAL
);
169 std::string local_image_id
;
170 std::string local_image_name
;
171 std::string tag_owner
;
173 auto req
= MockPrepareLocalImageRequest::create(m_local_io_ctx
,
178 m_threads
->work_queue
,
182 ASSERT_EQ(-EINVAL
, ctx
.wait());
185 TEST_F(TestMockImageReplayerPrepareLocalImageRequest
, DirGetNameError
) {
187 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request
;
188 expect_get_mirror_image_id(mock_get_mirror_image_id_request
, "local image id",
190 expect_dir_get_name(m_local_io_ctx
, "", -ENOENT
);
192 std::string local_image_id
;
193 std::string local_image_name
;
194 std::string tag_owner
;
196 auto req
= MockPrepareLocalImageRequest::create(m_local_io_ctx
,
201 m_threads
->work_queue
,
205 ASSERT_EQ(-ENOENT
, ctx
.wait());
208 TEST_F(TestMockImageReplayerPrepareLocalImageRequest
, MirrorImageError
) {
210 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request
;
211 expect_get_mirror_image_id(mock_get_mirror_image_id_request
, "local image id",
213 expect_dir_get_name(m_local_io_ctx
, "local image name", 0);
214 expect_mirror_image_get(m_local_io_ctx
, cls::rbd::MIRROR_IMAGE_STATE_DISABLED
,
217 std::string local_image_id
;
218 std::string local_image_name
;
219 std::string tag_owner
;
221 auto req
= MockPrepareLocalImageRequest::create(m_local_io_ctx
,
226 m_threads
->work_queue
,
230 ASSERT_EQ(-EINVAL
, ctx
.wait());
233 TEST_F(TestMockImageReplayerPrepareLocalImageRequest
, TagOwnerError
) {
235 MockGetMirrorImageIdRequest mock_get_mirror_image_id_request
;
236 expect_get_mirror_image_id(mock_get_mirror_image_id_request
, "local image id",
238 expect_dir_get_name(m_local_io_ctx
, "local image name", 0);
239 expect_mirror_image_get(m_local_io_ctx
, cls::rbd::MIRROR_IMAGE_STATE_ENABLED
,
240 "global image id", 0);
242 librbd::MockJournal mock_journal
;
243 expect_get_tag_owner(mock_journal
, "local image id", "remote mirror uuid",
246 std::string local_image_id
;
247 std::string local_image_name
;
248 std::string tag_owner
;
250 auto req
= MockPrepareLocalImageRequest::create(m_local_io_ctx
,
255 m_threads
->work_queue
,
259 ASSERT_EQ(-ENOENT
, ctx
.wait());
262 } // namespace image_replayer
263 } // namespace mirror