]>
Commit | Line | Data |
---|---|---|
d2e6a577 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" | |
9f95a23c | 7 | #include "librbd/mirror/GetInfoRequest.h" |
b32b8144 | 8 | #include "tools/rbd_mirror/Threads.h" |
d2e6a577 FG |
9 | #include "tools/rbd_mirror/image_replayer/GetMirrorImageIdRequest.h" |
10 | #include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.h" | |
9f95a23c TL |
11 | #include "tools/rbd_mirror/image_replayer/StateBuilder.h" |
12 | #include "tools/rbd_mirror/image_replayer/journal/StateBuilder.h" | |
13 | #include "tools/rbd_mirror/image_replayer/snapshot/StateBuilder.h" | |
b32b8144 | 14 | #include "test/journal/mock/MockJournaler.h" |
d2e6a577 FG |
15 | #include "test/librados_test_stub/MockTestMemIoCtxImpl.h" |
16 | #include "test/librbd/mock/MockImageCtx.h" | |
17 | ||
18 | namespace librbd { | |
19 | ||
20 | namespace { | |
21 | ||
22 | struct MockTestImageCtx : public librbd::MockImageCtx { | |
23 | MockTestImageCtx(librbd::ImageCtx &image_ctx) | |
24 | : librbd::MockImageCtx(image_ctx) { | |
25 | } | |
26 | }; | |
27 | ||
28 | } // anonymous namespace | |
b32b8144 FG |
29 | |
30 | namespace journal { | |
31 | ||
32 | template <> | |
33 | struct TypeTraits<MockTestImageCtx> { | |
34 | typedef ::journal::MockJournalerProxy Journaler; | |
35 | }; | |
36 | ||
37 | } // namespace journal | |
9f95a23c TL |
38 | |
39 | namespace mirror { | |
40 | ||
41 | template<> | |
42 | struct GetInfoRequest<librbd::MockTestImageCtx> { | |
43 | static GetInfoRequest* s_instance; | |
44 | cls::rbd::MirrorImage *mirror_image; | |
45 | PromotionState *promotion_state; | |
46 | std::string *primary_mirror_uuid; | |
47 | Context *on_finish = nullptr; | |
48 | ||
49 | static GetInfoRequest* create(librados::IoCtx& io_ctx, | |
50 | ContextWQ* context_wq, | |
51 | const std::string& image_id, | |
52 | cls::rbd::MirrorImage *mirror_image, | |
53 | PromotionState *promotion_state, | |
54 | std::string* primary_mirror_uuid, | |
55 | Context *on_finish) { | |
56 | ceph_assert(s_instance != nullptr); | |
57 | s_instance->mirror_image = mirror_image; | |
58 | s_instance->promotion_state = promotion_state; | |
59 | s_instance->primary_mirror_uuid = primary_mirror_uuid; | |
60 | s_instance->on_finish = on_finish; | |
61 | return s_instance; | |
62 | } | |
63 | ||
64 | GetInfoRequest() { | |
65 | ceph_assert(s_instance == nullptr); | |
66 | s_instance = this; | |
67 | } | |
68 | ~GetInfoRequest() { | |
69 | s_instance = nullptr; | |
70 | } | |
71 | ||
72 | MOCK_METHOD0(send, void()); | |
73 | }; | |
74 | ||
75 | GetInfoRequest<librbd::MockTestImageCtx>* GetInfoRequest<librbd::MockTestImageCtx>::s_instance = nullptr; | |
76 | ||
77 | } // namespace mirror | |
d2e6a577 FG |
78 | } // namespace librbd |
79 | ||
80 | namespace rbd { | |
81 | namespace mirror { | |
b32b8144 FG |
82 | |
83 | template <> | |
84 | struct Threads<librbd::MockTestImageCtx> { | |
9f95a23c | 85 | ceph::mutex &timer_lock; |
b32b8144 FG |
86 | SafeTimer *timer; |
87 | ContextWQ *work_queue; | |
88 | ||
89 | Threads(Threads<librbd::ImageCtx> *threads) | |
90 | : timer_lock(threads->timer_lock), timer(threads->timer), | |
91 | work_queue(threads->work_queue) { | |
92 | } | |
93 | }; | |
94 | ||
d2e6a577 FG |
95 | namespace image_replayer { |
96 | ||
97 | template <> | |
98 | struct GetMirrorImageIdRequest<librbd::MockTestImageCtx> { | |
99 | static GetMirrorImageIdRequest* s_instance; | |
100 | std::string* image_id = nullptr; | |
101 | Context* on_finish = nullptr; | |
102 | ||
103 | static GetMirrorImageIdRequest* create(librados::IoCtx& io_ctx, | |
104 | const std::string& global_image_id, | |
105 | std::string* image_id, | |
106 | Context* on_finish) { | |
11fdf7f2 | 107 | ceph_assert(s_instance != nullptr); |
d2e6a577 FG |
108 | s_instance->image_id = image_id; |
109 | s_instance->on_finish = on_finish; | |
110 | return s_instance; | |
111 | } | |
112 | ||
113 | GetMirrorImageIdRequest() { | |
114 | s_instance = this; | |
115 | } | |
116 | ||
117 | MOCK_METHOD0(send, void()); | |
118 | }; | |
119 | ||
9f95a23c TL |
120 | template<> |
121 | struct StateBuilder<librbd::MockTestImageCtx> { | |
122 | std::string local_image_id; | |
123 | librbd::mirror::PromotionState local_promotion_state = | |
124 | librbd::mirror::PROMOTION_STATE_NON_PRIMARY; | |
125 | std::string remote_image_id; | |
126 | std::string remote_mirror_uuid; | |
127 | librbd::mirror::PromotionState remote_promotion_state; | |
128 | ||
129 | virtual ~StateBuilder() {} | |
130 | ||
131 | MOCK_CONST_METHOD0(get_mirror_image_mode, cls::rbd::MirrorImageMode()); | |
132 | }; | |
133 | ||
d2e6a577 FG |
134 | GetMirrorImageIdRequest<librbd::MockTestImageCtx>* GetMirrorImageIdRequest<librbd::MockTestImageCtx>::s_instance = nullptr; |
135 | ||
9f95a23c TL |
136 | namespace journal { |
137 | ||
138 | template<> | |
139 | struct StateBuilder<librbd::MockTestImageCtx> | |
140 | : public image_replayer::StateBuilder<librbd::MockTestImageCtx> { | |
141 | static StateBuilder* s_instance; | |
142 | ||
143 | cls::rbd::MirrorImageMode mirror_image_mode = | |
144 | cls::rbd::MIRROR_IMAGE_MODE_JOURNAL; | |
145 | ||
146 | ::journal::MockJournalerProxy* remote_journaler = nullptr; | |
147 | cls::journal::ClientState remote_client_state; | |
148 | librbd::journal::MirrorPeerClientMeta remote_client_meta; | |
149 | ||
150 | static StateBuilder* create(const std::string&) { | |
151 | ceph_assert(s_instance != nullptr); | |
152 | return s_instance; | |
153 | } | |
154 | ||
155 | StateBuilder() { | |
156 | s_instance = this; | |
157 | } | |
158 | }; | |
159 | ||
160 | StateBuilder<librbd::MockTestImageCtx>* StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr; | |
161 | ||
162 | } // namespace journal | |
163 | ||
164 | namespace snapshot { | |
165 | ||
166 | template<> | |
167 | struct StateBuilder<librbd::MockTestImageCtx> | |
168 | : public image_replayer::StateBuilder<librbd::MockTestImageCtx> { | |
169 | static StateBuilder* s_instance; | |
170 | ||
171 | cls::rbd::MirrorImageMode mirror_image_mode = | |
172 | cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT; | |
173 | ||
174 | std::string remote_mirror_peer_uuid; | |
175 | ||
176 | static StateBuilder* create(const std::string&) { | |
177 | ceph_assert(s_instance != nullptr); | |
178 | return s_instance; | |
179 | } | |
180 | ||
181 | StateBuilder() { | |
182 | s_instance = this; | |
183 | } | |
184 | }; | |
185 | ||
186 | StateBuilder<librbd::MockTestImageCtx>* StateBuilder<librbd::MockTestImageCtx>::s_instance = nullptr; | |
187 | ||
188 | } // namespace snapshot | |
d2e6a577 FG |
189 | } // namespace image_replayer |
190 | } // namespace mirror | |
191 | } // namespace rbd | |
192 | ||
193 | // template definitions | |
194 | #include "tools/rbd_mirror/image_replayer/PrepareRemoteImageRequest.cc" | |
195 | ||
196 | namespace rbd { | |
197 | namespace mirror { | |
198 | namespace image_replayer { | |
199 | ||
200 | using ::testing::_; | |
201 | using ::testing::DoAll; | |
202 | using ::testing::InSequence; | |
203 | using ::testing::Invoke; | |
204 | using ::testing::Return; | |
205 | using ::testing::StrEq; | |
206 | using ::testing::WithArg; | |
207 | ||
208 | class TestMockImageReplayerPrepareRemoteImageRequest : public TestMockFixture { | |
209 | public: | |
b32b8144 | 210 | typedef Threads<librbd::MockTestImageCtx> MockThreads; |
d2e6a577 FG |
211 | typedef PrepareRemoteImageRequest<librbd::MockTestImageCtx> MockPrepareRemoteImageRequest; |
212 | typedef GetMirrorImageIdRequest<librbd::MockTestImageCtx> MockGetMirrorImageIdRequest; | |
9f95a23c TL |
213 | typedef StateBuilder<librbd::MockTestImageCtx> MockStateBuilder; |
214 | typedef journal::StateBuilder<librbd::MockTestImageCtx> MockJournalStateBuilder; | |
215 | typedef snapshot::StateBuilder<librbd::MockTestImageCtx> MockSnapshotStateBuilder; | |
216 | typedef librbd::mirror::GetInfoRequest<librbd::MockTestImageCtx> MockGetMirrorInfoRequest; | |
217 | ||
218 | void expect_get_mirror_image_mode(MockStateBuilder& mock_state_builder, | |
219 | cls::rbd::MirrorImageMode mirror_image_mode) { | |
220 | EXPECT_CALL(mock_state_builder, get_mirror_image_mode()) | |
221 | .WillOnce(Return(mirror_image_mode)); | |
222 | } | |
d2e6a577 FG |
223 | |
224 | void expect_get_mirror_image_id(MockGetMirrorImageIdRequest& mock_get_mirror_image_id_request, | |
225 | const std::string& image_id, int r) { | |
226 | EXPECT_CALL(mock_get_mirror_image_id_request, send()) | |
227 | .WillOnce(Invoke([&mock_get_mirror_image_id_request, image_id, r]() { | |
228 | *mock_get_mirror_image_id_request.image_id = image_id; | |
229 | mock_get_mirror_image_id_request.on_finish->complete(r); | |
230 | })); | |
231 | } | |
232 | ||
9f95a23c TL |
233 | void expect_get_mirror_info( |
234 | MockGetMirrorInfoRequest &mock_get_mirror_info_request, | |
235 | const cls::rbd::MirrorImage &mirror_image, | |
236 | librbd::mirror::PromotionState promotion_state, | |
237 | const std::string& primary_mirror_uuid, int r) { | |
238 | EXPECT_CALL(mock_get_mirror_info_request, send()) | |
239 | .WillOnce(Invoke([this, &mock_get_mirror_info_request, mirror_image, | |
240 | promotion_state, primary_mirror_uuid, r]() { | |
241 | *mock_get_mirror_info_request.mirror_image = mirror_image; | |
242 | *mock_get_mirror_info_request.promotion_state = promotion_state; | |
243 | *mock_get_mirror_info_request.primary_mirror_uuid = | |
244 | primary_mirror_uuid; | |
245 | m_threads->work_queue->queue( | |
246 | mock_get_mirror_info_request.on_finish, r); | |
247 | })); | |
d2e6a577 | 248 | } |
b32b8144 FG |
249 | |
250 | void expect_journaler_get_client(::journal::MockJournaler &mock_journaler, | |
251 | const std::string &client_id, | |
252 | cls::journal::Client &client, int r) { | |
253 | EXPECT_CALL(mock_journaler, get_client(StrEq(client_id), _, _)) | |
254 | .WillOnce(DoAll(WithArg<1>(Invoke([client](cls::journal::Client *out_client) { | |
255 | *out_client = client; | |
256 | })), | |
257 | WithArg<2>(Invoke([this, r](Context *on_finish) { | |
258 | m_threads->work_queue->queue(on_finish, r); | |
259 | })))); | |
260 | } | |
261 | ||
262 | void expect_journaler_register_client(::journal::MockJournaler &mock_journaler, | |
263 | const librbd::journal::ClientData &client_data, | |
264 | int r) { | |
265 | bufferlist bl; | |
11fdf7f2 | 266 | encode(client_data, bl); |
b32b8144 FG |
267 | |
268 | EXPECT_CALL(mock_journaler, register_client(ContentsEqual(bl), _)) | |
269 | .WillOnce(WithArg<1>(Invoke([this, r](Context *on_finish) { | |
270 | m_threads->work_queue->queue(on_finish, r); | |
271 | }))); | |
272 | } | |
d2e6a577 FG |
273 | }; |
274 | ||
9f95a23c TL |
275 | TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessJournal) { |
276 | ::journal::MockJournaler mock_remote_journaler; | |
b32b8144 FG |
277 | MockThreads mock_threads(m_threads); |
278 | ||
d2e6a577 | 279 | InSequence seq; |
d2e6a577 FG |
280 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
281 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, | |
282 | "remote image id", 0); | |
283 | ||
9f95a23c TL |
284 | MockGetMirrorInfoRequest mock_get_mirror_info_request; |
285 | expect_get_mirror_info(mock_get_mirror_info_request, | |
286 | {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL, | |
287 | "global image id", | |
288 | cls::rbd::MIRROR_IMAGE_STATE_ENABLED}, | |
289 | librbd::mirror::PROMOTION_STATE_PRIMARY, | |
290 | "remote mirror uuid", 0); | |
291 | ||
b32b8144 FG |
292 | EXPECT_CALL(mock_remote_journaler, construct()); |
293 | ||
294 | librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta; | |
295 | mirror_peer_client_meta.image_id = "local image id"; | |
296 | mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_SYNCING; | |
297 | librbd::journal::ClientData client_data{mirror_peer_client_meta}; | |
298 | cls::journal::Client client; | |
299 | client.state = cls::journal::CLIENT_STATE_DISCONNECTED; | |
11fdf7f2 | 300 | encode(client_data, client.data); |
b32b8144 FG |
301 | expect_journaler_get_client(mock_remote_journaler, "local mirror uuid", |
302 | client, 0); | |
303 | ||
9f95a23c TL |
304 | MockJournalStateBuilder mock_journal_state_builder; |
305 | MockStateBuilder* mock_state_builder = nullptr; | |
306 | C_SaferCond ctx; | |
307 | auto req = MockPrepareRemoteImageRequest::create(&mock_threads, | |
308 | m_local_io_ctx, | |
309 | m_remote_io_ctx, | |
310 | "global image id", | |
311 | "local mirror uuid", | |
312 | {"remote mirror uuid", ""}, | |
313 | nullptr, | |
314 | &mock_state_builder, | |
315 | &ctx); | |
316 | req->send(); | |
317 | ||
318 | ASSERT_EQ(0, ctx.wait()); | |
319 | ASSERT_TRUE(mock_state_builder != nullptr); | |
320 | ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_JOURNAL, | |
321 | mock_journal_state_builder.mirror_image_mode); | |
322 | ASSERT_EQ(std::string("remote mirror uuid"), | |
323 | mock_journal_state_builder.remote_mirror_uuid); | |
324 | ASSERT_EQ(std::string("remote image id"), | |
325 | mock_journal_state_builder.remote_image_id); | |
326 | ASSERT_EQ(librbd::mirror::PROMOTION_STATE_PRIMARY, | |
327 | mock_journal_state_builder.remote_promotion_state); | |
328 | ASSERT_TRUE(mock_journal_state_builder.remote_journaler != nullptr); | |
329 | ASSERT_EQ(cls::journal::CLIENT_STATE_DISCONNECTED, | |
330 | mock_journal_state_builder.remote_client_state); | |
331 | } | |
332 | ||
333 | TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessSnapshot) { | |
334 | ::journal::MockJournaler mock_remote_journaler; | |
335 | MockThreads mock_threads(m_threads); | |
336 | ||
337 | InSequence seq; | |
338 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; | |
339 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, | |
340 | "remote image id", 0); | |
341 | ||
342 | MockGetMirrorInfoRequest mock_get_mirror_info_request; | |
343 | expect_get_mirror_info(mock_get_mirror_info_request, | |
344 | {cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT, | |
345 | "global image id", | |
346 | cls::rbd::MIRROR_IMAGE_STATE_ENABLED}, | |
347 | librbd::mirror::PROMOTION_STATE_PRIMARY, | |
348 | "remote mirror uuid", 0); | |
349 | ||
350 | MockSnapshotStateBuilder mock_snapshot_state_builder; | |
351 | MockStateBuilder* mock_state_builder = nullptr; | |
d2e6a577 | 352 | C_SaferCond ctx; |
b32b8144 | 353 | auto req = MockPrepareRemoteImageRequest::create(&mock_threads, |
9f95a23c | 354 | m_local_io_ctx, |
b32b8144 | 355 | m_remote_io_ctx, |
d2e6a577 | 356 | "global image id", |
b32b8144 | 357 | "local mirror uuid", |
9f95a23c TL |
358 | {"remote mirror uuid", |
359 | "remote mirror peer uuid"}, | |
360 | nullptr, | |
361 | &mock_state_builder, | |
d2e6a577 FG |
362 | &ctx); |
363 | req->send(); | |
364 | ||
365 | ASSERT_EQ(0, ctx.wait()); | |
9f95a23c TL |
366 | ASSERT_TRUE(mock_state_builder != nullptr); |
367 | ASSERT_EQ(cls::rbd::MIRROR_IMAGE_MODE_SNAPSHOT, | |
368 | mock_snapshot_state_builder.mirror_image_mode); | |
369 | ASSERT_EQ(std::string("remote mirror uuid"), | |
370 | mock_snapshot_state_builder.remote_mirror_uuid); | |
371 | ASSERT_EQ(std::string("remote mirror peer uuid"), | |
372 | mock_snapshot_state_builder.remote_mirror_peer_uuid); | |
373 | ASSERT_EQ(std::string("remote image id"), | |
374 | mock_snapshot_state_builder.remote_image_id); | |
375 | ASSERT_EQ(librbd::mirror::PROMOTION_STATE_PRIMARY, | |
376 | mock_snapshot_state_builder.remote_promotion_state); | |
b32b8144 FG |
377 | } |
378 | ||
379 | TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, SuccessNotRegistered) { | |
9f95a23c | 380 | ::journal::MockJournaler mock_remote_journaler; |
b32b8144 FG |
381 | MockThreads mock_threads(m_threads); |
382 | ||
383 | InSequence seq; | |
b32b8144 FG |
384 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
385 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, | |
386 | "remote image id", 0); | |
387 | ||
9f95a23c TL |
388 | MockGetMirrorInfoRequest mock_get_mirror_info_request; |
389 | expect_get_mirror_info(mock_get_mirror_info_request, | |
390 | {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL, | |
391 | "global image id", | |
392 | cls::rbd::MIRROR_IMAGE_STATE_ENABLED}, | |
393 | librbd::mirror::PROMOTION_STATE_PRIMARY, | |
394 | "remote mirror uuid", 0); | |
395 | ||
396 | MockJournalStateBuilder mock_journal_state_builder; | |
397 | expect_get_mirror_image_mode(mock_journal_state_builder, | |
398 | cls::rbd::MIRROR_IMAGE_MODE_JOURNAL); | |
399 | ||
b32b8144 FG |
400 | EXPECT_CALL(mock_remote_journaler, construct()); |
401 | ||
402 | cls::journal::Client client; | |
403 | expect_journaler_get_client(mock_remote_journaler, "local mirror uuid", | |
404 | client, -ENOENT); | |
405 | ||
406 | librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta; | |
407 | mirror_peer_client_meta.image_id = "local image id"; | |
408 | mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; | |
409 | librbd::journal::ClientData client_data{mirror_peer_client_meta}; | |
410 | expect_journaler_register_client(mock_remote_journaler, client_data, 0); | |
411 | ||
9f95a23c TL |
412 | mock_journal_state_builder.local_image_id = "local image id"; |
413 | MockStateBuilder* mock_state_builder = &mock_journal_state_builder; | |
b32b8144 FG |
414 | C_SaferCond ctx; |
415 | auto req = MockPrepareRemoteImageRequest::create(&mock_threads, | |
9f95a23c | 416 | m_local_io_ctx, |
b32b8144 FG |
417 | m_remote_io_ctx, |
418 | "global image id", | |
419 | "local mirror uuid", | |
9f95a23c TL |
420 | {"remote mirror uuid", ""}, |
421 | nullptr, | |
422 | &mock_state_builder, | |
b32b8144 FG |
423 | &ctx); |
424 | req->send(); | |
425 | ||
426 | ASSERT_EQ(0, ctx.wait()); | |
9f95a23c TL |
427 | ASSERT_TRUE(mock_state_builder != nullptr); |
428 | ASSERT_EQ(std::string("remote image id"), | |
429 | mock_journal_state_builder.remote_image_id); | |
430 | ASSERT_EQ(librbd::mirror::PROMOTION_STATE_PRIMARY, | |
431 | mock_journal_state_builder.remote_promotion_state); | |
432 | ASSERT_TRUE(mock_journal_state_builder.remote_journaler != nullptr); | |
433 | ASSERT_EQ(cls::journal::CLIENT_STATE_CONNECTED, | |
434 | mock_journal_state_builder.remote_client_state); | |
d2e6a577 FG |
435 | } |
436 | ||
9f95a23c TL |
437 | TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, MirrorImageIdError) { |
438 | ::journal::MockJournaler mock_remote_journaler; | |
b32b8144 FG |
439 | MockThreads mock_threads(m_threads); |
440 | ||
d2e6a577 | 441 | InSequence seq; |
9f95a23c TL |
442 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
443 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, "", -EINVAL); | |
d2e6a577 | 444 | |
9f95a23c TL |
445 | MockJournalStateBuilder mock_journal_state_builder; |
446 | MockStateBuilder* mock_state_builder = &mock_journal_state_builder; | |
d2e6a577 | 447 | C_SaferCond ctx; |
b32b8144 | 448 | auto req = MockPrepareRemoteImageRequest::create(&mock_threads, |
9f95a23c | 449 | m_local_io_ctx, |
b32b8144 | 450 | m_remote_io_ctx, |
d2e6a577 | 451 | "global image id", |
b32b8144 | 452 | "local mirror uuid", |
9f95a23c TL |
453 | {"remote mirror uuid", ""}, |
454 | nullptr, | |
455 | &mock_state_builder, | |
d2e6a577 FG |
456 | &ctx); |
457 | req->send(); | |
458 | ||
459 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
9f95a23c | 460 | ASSERT_TRUE(mock_journal_state_builder.remote_journaler == nullptr); |
d2e6a577 FG |
461 | } |
462 | ||
9f95a23c TL |
463 | TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, GetMirrorInfoError) { |
464 | ::journal::MockJournaler mock_remote_journaler; | |
b32b8144 FG |
465 | MockThreads mock_threads(m_threads); |
466 | ||
d2e6a577 | 467 | InSequence seq; |
d2e6a577 | 468 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
9f95a23c TL |
469 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, |
470 | "remote image id", 0); | |
d2e6a577 | 471 | |
9f95a23c TL |
472 | MockGetMirrorInfoRequest mock_get_mirror_info_request; |
473 | expect_get_mirror_info(mock_get_mirror_info_request, | |
474 | {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL, | |
475 | "global image id", | |
476 | cls::rbd::MIRROR_IMAGE_STATE_ENABLED}, | |
477 | librbd::mirror::PROMOTION_STATE_PRIMARY, | |
478 | "remote mirror uuid", -EINVAL); | |
479 | ||
480 | MockJournalStateBuilder mock_journal_state_builder; | |
481 | MockStateBuilder* mock_state_builder = nullptr; | |
d2e6a577 | 482 | C_SaferCond ctx; |
b32b8144 | 483 | auto req = MockPrepareRemoteImageRequest::create(&mock_threads, |
9f95a23c | 484 | m_local_io_ctx, |
b32b8144 | 485 | m_remote_io_ctx, |
d2e6a577 | 486 | "global image id", |
b32b8144 | 487 | "local mirror uuid", |
9f95a23c TL |
488 | {"remote mirror uuid", ""}, |
489 | nullptr, | |
490 | &mock_state_builder, | |
d2e6a577 FG |
491 | &ctx); |
492 | req->send(); | |
493 | ||
494 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
9f95a23c | 495 | ASSERT_TRUE(mock_state_builder == nullptr); |
b32b8144 FG |
496 | } |
497 | ||
498 | TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, GetClientError) { | |
9f95a23c | 499 | ::journal::MockJournaler mock_remote_journaler; |
b32b8144 FG |
500 | MockThreads mock_threads(m_threads); |
501 | ||
502 | InSequence seq; | |
b32b8144 FG |
503 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
504 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, | |
505 | "remote image id", 0); | |
506 | ||
9f95a23c TL |
507 | MockGetMirrorInfoRequest mock_get_mirror_info_request; |
508 | expect_get_mirror_info(mock_get_mirror_info_request, | |
509 | {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL, | |
510 | "global image id", | |
511 | cls::rbd::MIRROR_IMAGE_STATE_ENABLED}, | |
512 | librbd::mirror::PROMOTION_STATE_PRIMARY, | |
513 | "remote mirror uuid", 0); | |
514 | ||
b32b8144 FG |
515 | EXPECT_CALL(mock_remote_journaler, construct()); |
516 | ||
517 | cls::journal::Client client; | |
518 | expect_journaler_get_client(mock_remote_journaler, "local mirror uuid", | |
519 | client, -EINVAL); | |
520 | ||
9f95a23c TL |
521 | MockJournalStateBuilder mock_journal_state_builder; |
522 | MockStateBuilder* mock_state_builder = nullptr; | |
b32b8144 FG |
523 | C_SaferCond ctx; |
524 | auto req = MockPrepareRemoteImageRequest::create(&mock_threads, | |
9f95a23c | 525 | m_local_io_ctx, |
b32b8144 FG |
526 | m_remote_io_ctx, |
527 | "global image id", | |
528 | "local mirror uuid", | |
9f95a23c TL |
529 | {"remote mirror uuid", ""}, |
530 | nullptr, | |
531 | &mock_state_builder, | |
b32b8144 FG |
532 | &ctx); |
533 | req->send(); | |
534 | ||
535 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
9f95a23c | 536 | ASSERT_TRUE(mock_state_builder == nullptr); |
b32b8144 FG |
537 | } |
538 | ||
539 | TEST_F(TestMockImageReplayerPrepareRemoteImageRequest, RegisterClientError) { | |
9f95a23c | 540 | ::journal::MockJournaler mock_remote_journaler; |
b32b8144 FG |
541 | MockThreads mock_threads(m_threads); |
542 | ||
543 | InSequence seq; | |
b32b8144 FG |
544 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
545 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, | |
546 | "remote image id", 0); | |
547 | ||
9f95a23c TL |
548 | MockGetMirrorInfoRequest mock_get_mirror_info_request; |
549 | expect_get_mirror_info(mock_get_mirror_info_request, | |
550 | {cls::rbd::MIRROR_IMAGE_MODE_JOURNAL, | |
551 | "global image id", | |
552 | cls::rbd::MIRROR_IMAGE_STATE_ENABLED}, | |
553 | librbd::mirror::PROMOTION_STATE_PRIMARY, | |
554 | "remote mirror uuid", 0); | |
555 | ||
556 | MockJournalStateBuilder mock_journal_state_builder; | |
557 | expect_get_mirror_image_mode(mock_journal_state_builder, | |
558 | cls::rbd::MIRROR_IMAGE_MODE_JOURNAL); | |
559 | ||
b32b8144 FG |
560 | EXPECT_CALL(mock_remote_journaler, construct()); |
561 | ||
562 | cls::journal::Client client; | |
563 | expect_journaler_get_client(mock_remote_journaler, "local mirror uuid", | |
564 | client, -ENOENT); | |
565 | ||
566 | librbd::journal::MirrorPeerClientMeta mirror_peer_client_meta; | |
567 | mirror_peer_client_meta.image_id = "local image id"; | |
568 | mirror_peer_client_meta.state = librbd::journal::MIRROR_PEER_STATE_REPLAYING; | |
569 | librbd::journal::ClientData client_data{mirror_peer_client_meta}; | |
570 | expect_journaler_register_client(mock_remote_journaler, client_data, -EINVAL); | |
571 | ||
9f95a23c TL |
572 | mock_journal_state_builder.local_image_id = "local image id"; |
573 | MockStateBuilder* mock_state_builder = &mock_journal_state_builder; | |
b32b8144 FG |
574 | C_SaferCond ctx; |
575 | auto req = MockPrepareRemoteImageRequest::create(&mock_threads, | |
9f95a23c | 576 | m_local_io_ctx, |
b32b8144 FG |
577 | m_remote_io_ctx, |
578 | "global image id", | |
579 | "local mirror uuid", | |
9f95a23c TL |
580 | {"remote mirror uuid", ""}, |
581 | nullptr, | |
582 | &mock_state_builder, | |
b32b8144 FG |
583 | &ctx); |
584 | req->send(); | |
585 | ||
586 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
d2e6a577 FG |
587 | } |
588 | ||
589 | } // namespace image_replayer | |
590 | } // namespace mirror | |
591 | } // namespace rbd |