]>
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 | ||
90 | void expect_mirror_image_get(librados::IoCtx &io_ctx, | |
91 | cls::rbd::MirrorImageState state, | |
92 | const std::string &global_id, int r) { | |
93 | cls::rbd::MirrorImage mirror_image; | |
94 | mirror_image.state = state; | |
95 | mirror_image.global_image_id = global_id; | |
96 | ||
97 | bufferlist bl; | |
98 | ::encode(mirror_image, bl); | |
99 | ||
100 | EXPECT_CALL(get_mock_io_ctx(io_ctx), | |
101 | exec(RBD_MIRRORING, _, StrEq("rbd"), StrEq("mirror_image_get"), _, _, _)) | |
102 | .WillOnce(DoAll(WithArg<5>(Invoke([bl](bufferlist *out_bl) { | |
103 | *out_bl = bl; | |
104 | })), | |
105 | Return(r))); | |
106 | } | |
107 | ||
108 | void expect_get_tag_owner(librbd::MockJournal &mock_journal, | |
109 | const std::string &local_image_id, | |
110 | const std::string &tag_owner, int r) { | |
111 | EXPECT_CALL(mock_journal, get_tag_owner(local_image_id, _, _, _)) | |
112 | .WillOnce(WithArgs<1, 3>(Invoke([tag_owner, r](std::string *owner, Context *on_finish) { | |
113 | *owner = tag_owner; | |
114 | on_finish->complete(r); | |
115 | }))); | |
116 | } | |
117 | ||
118 | }; | |
119 | ||
120 | TEST_F(TestMockImageReplayerPrepareLocalImageRequest, Success) { | |
121 | InSequence seq; | |
d2e6a577 FG |
122 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
123 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, "local image id", | |
124 | 0); | |
7c673cae FG |
125 | expect_mirror_image_get(m_local_io_ctx, cls::rbd::MIRROR_IMAGE_STATE_ENABLED, |
126 | "global image id", 0); | |
127 | ||
128 | librbd::MockJournal mock_journal; | |
129 | expect_get_tag_owner(mock_journal, "local image id", "remote mirror uuid", 0); | |
130 | ||
131 | std::string local_image_id; | |
132 | std::string tag_owner; | |
133 | C_SaferCond ctx; | |
134 | auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx, | |
135 | "global image id", | |
136 | &local_image_id, | |
137 | &tag_owner, | |
138 | m_threads->work_queue, | |
139 | &ctx); | |
140 | req->send(); | |
141 | ||
142 | ASSERT_EQ(0, ctx.wait()); | |
143 | ASSERT_EQ(std::string("local image id"), local_image_id); | |
144 | ASSERT_EQ(std::string("remote mirror uuid"), tag_owner); | |
145 | } | |
146 | ||
7c673cae FG |
147 | TEST_F(TestMockImageReplayerPrepareLocalImageRequest, MirrorImageIdError) { |
148 | InSequence seq; | |
d2e6a577 FG |
149 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
150 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, "", -EINVAL); | |
7c673cae FG |
151 | |
152 | std::string local_image_id; | |
153 | std::string tag_owner; | |
154 | C_SaferCond ctx; | |
155 | auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx, | |
156 | "global image id", | |
157 | &local_image_id, | |
158 | &tag_owner, | |
159 | m_threads->work_queue, | |
160 | &ctx); | |
161 | req->send(); | |
162 | ||
163 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
164 | } | |
165 | ||
166 | TEST_F(TestMockImageReplayerPrepareLocalImageRequest, MirrorImageError) { | |
167 | InSequence seq; | |
d2e6a577 FG |
168 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
169 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, "local image id", | |
170 | 0); | |
7c673cae FG |
171 | expect_mirror_image_get(m_local_io_ctx, cls::rbd::MIRROR_IMAGE_STATE_DISABLED, |
172 | "", -EINVAL); | |
173 | ||
174 | std::string local_image_id; | |
175 | std::string tag_owner; | |
176 | C_SaferCond ctx; | |
177 | auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx, | |
178 | "global image id", | |
179 | &local_image_id, | |
180 | &tag_owner, | |
181 | m_threads->work_queue, | |
182 | &ctx); | |
183 | req->send(); | |
184 | ||
185 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
186 | } | |
187 | ||
188 | TEST_F(TestMockImageReplayerPrepareLocalImageRequest, TagOwnerError) { | |
189 | InSequence seq; | |
d2e6a577 FG |
190 | MockGetMirrorImageIdRequest mock_get_mirror_image_id_request; |
191 | expect_get_mirror_image_id(mock_get_mirror_image_id_request, "local image id", | |
192 | 0); | |
7c673cae FG |
193 | expect_mirror_image_get(m_local_io_ctx, cls::rbd::MIRROR_IMAGE_STATE_ENABLED, |
194 | "global image id", 0); | |
195 | ||
196 | librbd::MockJournal mock_journal; | |
197 | expect_get_tag_owner(mock_journal, "local image id", "remote mirror uuid", | |
198 | -ENOENT); | |
199 | ||
200 | std::string local_image_id; | |
201 | std::string tag_owner; | |
202 | C_SaferCond ctx; | |
203 | auto req = MockPrepareLocalImageRequest::create(m_local_io_ctx, | |
204 | "global image id", | |
205 | &local_image_id, | |
206 | &tag_owner, | |
207 | m_threads->work_queue, | |
208 | &ctx); | |
209 | req->send(); | |
210 | ||
211 | ASSERT_EQ(-ENOENT, ctx.wait()); | |
212 | } | |
213 | ||
214 | } // namespace image_replayer | |
215 | } // namespace mirror | |
216 | } // namespace rbd |