]>
Commit | Line | Data |
---|---|---|
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 "cls/rbd/cls_rbd_types.h" | |
6 | #include "librbd/journal/TypeTraits.h" | |
d2e6a577 | 7 | #include "tools/rbd_mirror/image_replayer/GetMirrorImageIdRequest.h" |
7c673cae FG |
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" | |
13 | ||
14 | namespace librbd { | |
15 | ||
16 | namespace { | |
17 | ||
18 | struct MockTestImageCtx : public librbd::MockImageCtx { | |
19 | MockTestImageCtx(librbd::ImageCtx &image_ctx) | |
20 | : librbd::MockImageCtx(image_ctx) { | |
21 | } | |
22 | }; | |
23 | ||
24 | } // anonymous namespace | |
25 | } // namespace librbd | |
26 | ||
d2e6a577 FG |
27 | namespace rbd { |
28 | namespace mirror { | |
29 | namespace image_replayer { | |
30 | ||
31 | template <> | |
32 | struct GetMirrorImageIdRequest<librbd::MockTestImageCtx> { | |
33 | static GetMirrorImageIdRequest* s_instance; | |
34 | std::string* image_id = nullptr; | |
35 | Context* on_finish = nullptr; | |
36 | ||
37 | static GetMirrorImageIdRequest* create(librados::IoCtx& io_ctx, | |
38 | const std::string& global_image_id, | |
39 | std::string* image_id, | |
40 | Context* on_finish) { | |
41 | assert(s_instance != nullptr); | |
42 | s_instance->image_id = image_id; | |
43 | s_instance->on_finish = on_finish; | |
44 | return s_instance; | |
45 | } | |
46 | ||
47 | GetMirrorImageIdRequest() { | |
48 | s_instance = this; | |
49 | } | |
50 | ||
51 | MOCK_METHOD0(send, void()); | |
52 | }; | |
53 | ||
54 | GetMirrorImageIdRequest<librbd::MockTestImageCtx>* GetMirrorImageIdRequest<librbd::MockTestImageCtx>::s_instance = nullptr; | |
55 | ||
56 | } // namespace image_replayer | |
57 | } // namespace mirror | |
58 | } // namespace rbd | |
59 | ||
7c673cae FG |
60 | // template definitions |
61 | #include "tools/rbd_mirror/image_replayer/PrepareLocalImageRequest.cc" | |
62 | ||
63 | namespace rbd { | |
64 | namespace mirror { | |
65 | namespace image_replayer { | |
66 | ||
67 | using ::testing::_; | |
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; | |
75 | ||
76 | class TestMockImageReplayerPrepareLocalImageRequest : public TestMockFixture { | |
77 | public: | |
78 | typedef PrepareLocalImageRequest<librbd::MockTestImageCtx> MockPrepareLocalImageRequest; | |
d2e6a577 FG |
79 | typedef GetMirrorImageIdRequest<librbd::MockTestImageCtx> MockGetMirrorImageIdRequest; |
80 | ||
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); | |
87 | })); | |
7c673cae FG |
88 | } |
89 | ||
28e407b8 AA |
90 | void expect_dir_get_name(librados::IoCtx &io_ctx, |
91 | const std::string &image_name, int r) { | |
92 | bufferlist bl; | |
93 | encode(image_name, bl); | |
94 | ||
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) { | |
98 | *out_bl = bl; | |
99 | })), | |
100 | Return(r))); | |
101 | } | |
102 | ||
7c673cae FG |
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; | |
109 | ||
110 | bufferlist bl; | |
111 | ::encode(mirror_image, bl); | |
112 | ||
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) { | |
116 | *out_bl = bl; | |
117 | })), | |
118 | Return(r))); | |
119 | } | |
120 | ||
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) { | |
126 | *owner = tag_owner; | |
127 | on_finish->complete(r); | |
128 | }))); | |
129 | } | |
130 | ||
131 | }; | |
132 | ||
133 | TEST_F(TestMockImageReplayerPrepareLocalImageRequest, Success) { | |
134 | InSequence seq; | |
d2e6a577 FG |
135 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
136 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, "local image id", | |
137 | 0); | |
28e407b8 | 138 | expect_dir_get_name(m_local_io_ctx, "local image name", 0); |
7c673cae FG |
139 | expect_mirror_image_get(m_local_io_ctx, cls::rbd::MIRROR_IMAGE_STATE_ENABLED, |
140 | "global image id", 0); | |
141 | ||
142 | librbd::MockJournal mock_journal; | |
143 | expect_get_tag_owner(mock_journal, "local image id", "remote mirror uuid", 0); | |
144 | ||
145 | std::string local_image_id; | |
28e407b8 | 146 | std::string local_image_name; |
7c673cae FG |
147 | std::string tag_owner; |
148 | C_SaferCond ctx; | |
149 | auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx, | |
150 | "global image id", | |
151 | &local_image_id, | |
28e407b8 | 152 | &local_image_name, |
7c673cae FG |
153 | &tag_owner, |
154 | m_threads->work_queue, | |
155 | &ctx); | |
156 | req->send(); | |
157 | ||
158 | ASSERT_EQ(0, ctx.wait()); | |
159 | ASSERT_EQ(std::string("local image id"), local_image_id); | |
28e407b8 | 160 | ASSERT_EQ(std::string("local image name"), local_image_name); |
7c673cae FG |
161 | ASSERT_EQ(std::string("remote mirror uuid"), tag_owner); |
162 | } | |
163 | ||
7c673cae FG |
164 | TEST_F(TestMockImageReplayerPrepareLocalImageRequest, MirrorImageIdError) { |
165 | InSequence seq; | |
d2e6a577 FG |
166 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
167 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, "", -EINVAL); | |
7c673cae FG |
168 | |
169 | std::string local_image_id; | |
28e407b8 | 170 | std::string local_image_name; |
7c673cae FG |
171 | std::string tag_owner; |
172 | C_SaferCond ctx; | |
173 | auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx, | |
174 | "global image id", | |
175 | &local_image_id, | |
28e407b8 | 176 | &local_image_name, |
7c673cae FG |
177 | &tag_owner, |
178 | m_threads->work_queue, | |
179 | &ctx); | |
180 | req->send(); | |
181 | ||
182 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
183 | } | |
184 | ||
28e407b8 AA |
185 | TEST_F(TestMockImageReplayerPrepareLocalImageRequest, DirGetNameError) { |
186 | InSequence seq; | |
187 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; | |
188 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, "local image id", | |
189 | 0); | |
190 | expect_dir_get_name(m_local_io_ctx, "", -ENOENT); | |
191 | ||
192 | std::string local_image_id; | |
193 | std::string local_image_name; | |
194 | std::string tag_owner; | |
195 | C_SaferCond ctx; | |
196 | auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx, | |
197 | "global image id", | |
198 | &local_image_id, | |
199 | &local_image_name, | |
200 | &tag_owner, | |
201 | m_threads->work_queue, | |
202 | &ctx); | |
203 | req->send(); | |
204 | ||
205 | ASSERT_EQ(-ENOENT, ctx.wait()); | |
206 | } | |
207 | ||
7c673cae FG |
208 | TEST_F(TestMockImageReplayerPrepareLocalImageRequest, MirrorImageError) { |
209 | InSequence seq; | |
d2e6a577 FG |
210 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
211 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, "local image id", | |
212 | 0); | |
28e407b8 | 213 | expect_dir_get_name(m_local_io_ctx, "local image name", 0); |
7c673cae FG |
214 | expect_mirror_image_get(m_local_io_ctx, cls::rbd::MIRROR_IMAGE_STATE_DISABLED, |
215 | "", -EINVAL); | |
216 | ||
217 | std::string local_image_id; | |
28e407b8 | 218 | std::string local_image_name; |
7c673cae FG |
219 | std::string tag_owner; |
220 | C_SaferCond ctx; | |
221 | auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx, | |
222 | "global image id", | |
223 | &local_image_id, | |
28e407b8 | 224 | &local_image_name, |
7c673cae FG |
225 | &tag_owner, |
226 | m_threads->work_queue, | |
227 | &ctx); | |
228 | req->send(); | |
229 | ||
230 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
231 | } | |
232 | ||
233 | TEST_F(TestMockImageReplayerPrepareLocalImageRequest, TagOwnerError) { | |
234 | InSequence seq; | |
d2e6a577 FG |
235 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
236 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, "local image id", | |
237 | 0); | |
28e407b8 | 238 | expect_dir_get_name(m_local_io_ctx, "local image name", 0); |
7c673cae FG |
239 | expect_mirror_image_get(m_local_io_ctx, cls::rbd::MIRROR_IMAGE_STATE_ENABLED, |
240 | "global image id", 0); | |
241 | ||
242 | librbd::MockJournal mock_journal; | |
243 | expect_get_tag_owner(mock_journal, "local image id", "remote mirror uuid", | |
244 | -ENOENT); | |
245 | ||
246 | std::string local_image_id; | |
28e407b8 | 247 | std::string local_image_name; |
7c673cae FG |
248 | std::string tag_owner; |
249 | C_SaferCond ctx; | |
250 | auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx, | |
251 | "global image id", | |
252 | &local_image_id, | |
28e407b8 | 253 | &local_image_name, |
7c673cae FG |
254 | &tag_owner, |
255 | m_threads->work_queue, | |
256 | &ctx); | |
257 | req->send(); | |
258 | ||
259 | ASSERT_EQ(-ENOENT, ctx.wait()); | |
260 | } | |
261 | ||
262 | } // namespace image_replayer | |
263 | } // namespace mirror | |
264 | } // namespace rbd |