]>
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 "librbd/journal/Types.h" | |
6 | #include "librbd/journal/TypeTraits.h" | |
7 | #include "tools/rbd_mirror/image_replayer/EventPreprocessor.h" | |
8 | #include "tools/rbd_mirror/Threads.h" | |
9 | #include "test/journal/mock/MockJournaler.h" | |
10 | #include "test/librbd/mock/MockImageCtx.h" | |
11 | ||
12 | namespace librbd { | |
13 | ||
14 | namespace { | |
15 | ||
16 | struct MockTestImageCtx : public librbd::MockImageCtx { | |
11fdf7f2 | 17 | explicit MockTestImageCtx(librbd::ImageCtx &image_ctx) |
7c673cae FG |
18 | : librbd::MockImageCtx(image_ctx) { |
19 | } | |
20 | }; | |
21 | ||
22 | } // anonymous namespace | |
23 | ||
24 | namespace journal { | |
25 | ||
26 | template <> | |
27 | struct TypeTraits<librbd::MockTestImageCtx> { | |
28 | typedef ::journal::MockJournaler Journaler; | |
29 | }; | |
30 | ||
31 | } // namespace journal | |
32 | } // namespace librbd | |
33 | ||
34 | // template definitions | |
35 | #include "tools/rbd_mirror/image_replayer/EventPreprocessor.cc" | |
36 | template class rbd::mirror::image_replayer::EventPreprocessor<librbd::MockTestImageCtx>; | |
37 | ||
38 | namespace rbd { | |
39 | namespace mirror { | |
40 | namespace image_replayer { | |
41 | ||
42 | using testing::_; | |
43 | using testing::WithArg; | |
44 | ||
45 | class TestMockImageReplayerEventPreprocessor : public TestMockFixture { | |
46 | public: | |
47 | typedef EventPreprocessor<librbd::MockTestImageCtx> MockEventPreprocessor; | |
48 | ||
49 | void SetUp() override { | |
50 | TestMockFixture::SetUp(); | |
51 | ||
52 | librbd::RBD rbd; | |
53 | ASSERT_EQ(0, create_image(rbd, m_local_io_ctx, m_image_name, m_image_size)); | |
54 | ASSERT_EQ(0, open_image(m_local_io_ctx, m_image_name, &m_local_image_ctx)); | |
55 | } | |
56 | ||
57 | void expect_image_refresh(librbd::MockTestImageCtx &mock_remote_image_ctx, int r) { | |
58 | EXPECT_CALL(*mock_remote_image_ctx.state, refresh(_)) | |
59 | .WillOnce(CompleteContext(r)); | |
60 | } | |
61 | ||
62 | void expect_update_client(journal::MockJournaler &mock_journaler, int r) { | |
63 | EXPECT_CALL(mock_journaler, update_client(_, _)) | |
64 | .WillOnce(WithArg<1>(CompleteContext(r))); | |
65 | } | |
66 | ||
67 | librbd::ImageCtx *m_local_image_ctx; | |
68 | librbd::journal::MirrorPeerClientMeta m_client_meta; | |
69 | ||
70 | }; | |
71 | ||
72 | TEST_F(TestMockImageReplayerEventPreprocessor, IsNotRequired) { | |
73 | librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); | |
74 | ::journal::MockJournaler mock_remote_journaler; | |
75 | ||
76 | MockEventPreprocessor event_preprocessor(mock_local_image_ctx, | |
77 | mock_remote_journaler, | |
78 | "local mirror uuid", | |
79 | &m_client_meta, | |
80 | m_threads->work_queue); | |
81 | ||
82 | librbd::journal::EventEntry event_entry{librbd::journal::RenameEvent{}}; | |
83 | ASSERT_FALSE(event_preprocessor.is_required(event_entry)); | |
84 | } | |
85 | ||
86 | TEST_F(TestMockImageReplayerEventPreprocessor, IsRequiredSnapMapPrune) { | |
87 | librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); | |
88 | ::journal::MockJournaler mock_remote_journaler; | |
89 | ||
90 | m_client_meta.snap_seqs = {{1, 2}, {3, 4}}; | |
91 | MockEventPreprocessor event_preprocessor(mock_local_image_ctx, | |
92 | mock_remote_journaler, | |
93 | "local mirror uuid", | |
94 | &m_client_meta, | |
95 | m_threads->work_queue); | |
96 | ||
97 | librbd::journal::EventEntry event_entry{librbd::journal::RenameEvent{}}; | |
98 | ASSERT_TRUE(event_preprocessor.is_required(event_entry)); | |
99 | } | |
100 | ||
101 | TEST_F(TestMockImageReplayerEventPreprocessor, IsRequiredSnapRename) { | |
102 | librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); | |
103 | ::journal::MockJournaler mock_remote_journaler; | |
104 | ||
105 | MockEventPreprocessor event_preprocessor(mock_local_image_ctx, | |
106 | mock_remote_journaler, | |
107 | "local mirror uuid", | |
108 | &m_client_meta, | |
109 | m_threads->work_queue); | |
110 | ||
111 | librbd::journal::EventEntry event_entry{librbd::journal::SnapRenameEvent{}}; | |
112 | ASSERT_TRUE(event_preprocessor.is_required(event_entry)); | |
113 | } | |
114 | ||
115 | TEST_F(TestMockImageReplayerEventPreprocessor, PreprocessSnapMapPrune) { | |
116 | librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); | |
117 | ::journal::MockJournaler mock_remote_journaler; | |
118 | ||
119 | expect_image_refresh(mock_local_image_ctx, 0); | |
120 | expect_update_client(mock_remote_journaler, 0); | |
121 | ||
122 | mock_local_image_ctx.snap_info = { | |
123 | {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}}; | |
124 | m_client_meta.snap_seqs = {{1, 2}, {3, 4}, {5, 6}}; | |
125 | MockEventPreprocessor event_preprocessor(mock_local_image_ctx, | |
126 | mock_remote_journaler, | |
127 | "local mirror uuid", | |
128 | &m_client_meta, | |
129 | m_threads->work_queue); | |
130 | ||
131 | librbd::journal::EventEntry event_entry{librbd::journal::RenameEvent{}}; | |
132 | C_SaferCond ctx; | |
133 | event_preprocessor.preprocess(&event_entry, &ctx); | |
134 | ASSERT_EQ(0, ctx.wait()); | |
135 | ||
11fdf7f2 | 136 | librbd::SnapSeqs expected_snap_seqs = {{5, 6}}; |
7c673cae FG |
137 | ASSERT_EQ(expected_snap_seqs, m_client_meta.snap_seqs); |
138 | } | |
139 | ||
140 | TEST_F(TestMockImageReplayerEventPreprocessor, PreprocessSnapRename) { | |
141 | librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); | |
142 | ::journal::MockJournaler mock_remote_journaler; | |
143 | ||
144 | expect_image_refresh(mock_local_image_ctx, 0); | |
145 | expect_update_client(mock_remote_journaler, 0); | |
146 | ||
147 | mock_local_image_ctx.snap_ids = {{{cls::rbd::UserSnapshotNamespace(), "snap"}, 6}}; | |
148 | mock_local_image_ctx.snap_info = { | |
149 | {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}}; | |
150 | MockEventPreprocessor event_preprocessor(mock_local_image_ctx, | |
151 | mock_remote_journaler, | |
152 | "local mirror uuid", | |
153 | &m_client_meta, | |
154 | m_threads->work_queue); | |
155 | ||
156 | librbd::journal::EventEntry event_entry{ | |
157 | librbd::journal::SnapRenameEvent{0, 5, "snap", "new_snap"}}; | |
158 | C_SaferCond ctx; | |
159 | event_preprocessor.preprocess(&event_entry, &ctx); | |
160 | ASSERT_EQ(0, ctx.wait()); | |
161 | ||
11fdf7f2 | 162 | librbd::SnapSeqs expected_snap_seqs = {{5, 6}}; |
7c673cae FG |
163 | ASSERT_EQ(expected_snap_seqs, m_client_meta.snap_seqs); |
164 | ||
165 | librbd::journal::SnapRenameEvent *event = | |
166 | boost::get<librbd::journal::SnapRenameEvent>(&event_entry.event); | |
167 | ASSERT_EQ(6U, event->snap_id); | |
168 | } | |
169 | ||
170 | TEST_F(TestMockImageReplayerEventPreprocessor, PreprocessSnapRenameMissing) { | |
171 | librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); | |
172 | ::journal::MockJournaler mock_remote_journaler; | |
173 | ||
174 | expect_image_refresh(mock_local_image_ctx, 0); | |
175 | ||
176 | MockEventPreprocessor event_preprocessor(mock_local_image_ctx, | |
177 | mock_remote_journaler, | |
178 | "local mirror uuid", | |
179 | &m_client_meta, | |
180 | m_threads->work_queue); | |
181 | ||
182 | librbd::journal::EventEntry event_entry{ | |
183 | librbd::journal::SnapRenameEvent{0, 5, "snap", "new_snap"}}; | |
184 | C_SaferCond ctx; | |
185 | event_preprocessor.preprocess(&event_entry, &ctx); | |
186 | ASSERT_EQ(-ENOENT, ctx.wait()); | |
187 | ||
188 | librbd::journal::SnapRenameEvent *event = | |
189 | boost::get<librbd::journal::SnapRenameEvent>(&event_entry.event); | |
190 | ASSERT_EQ(CEPH_NOSNAP, event->snap_id); | |
191 | } | |
192 | ||
193 | TEST_F(TestMockImageReplayerEventPreprocessor, PreprocessSnapRenameKnown) { | |
194 | librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); | |
195 | ::journal::MockJournaler mock_remote_journaler; | |
196 | ||
197 | expect_image_refresh(mock_local_image_ctx, 0); | |
198 | ||
199 | mock_local_image_ctx.snap_info = { | |
200 | {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}}; | |
201 | m_client_meta.snap_seqs = {{5, 6}}; | |
202 | MockEventPreprocessor event_preprocessor(mock_local_image_ctx, | |
203 | mock_remote_journaler, | |
204 | "local mirror uuid", | |
205 | &m_client_meta, | |
206 | m_threads->work_queue); | |
207 | ||
208 | librbd::journal::EventEntry event_entry{ | |
209 | librbd::journal::SnapRenameEvent{0, 5, "snap", "new_snap"}}; | |
210 | C_SaferCond ctx; | |
211 | event_preprocessor.preprocess(&event_entry, &ctx); | |
212 | ASSERT_EQ(0, ctx.wait()); | |
213 | ||
11fdf7f2 | 214 | librbd::SnapSeqs expected_snap_seqs = {{5, 6}}; |
7c673cae FG |
215 | ASSERT_EQ(expected_snap_seqs, m_client_meta.snap_seqs); |
216 | ||
217 | librbd::journal::SnapRenameEvent *event = | |
218 | boost::get<librbd::journal::SnapRenameEvent>(&event_entry.event); | |
219 | ASSERT_EQ(6U, event->snap_id); | |
220 | } | |
221 | ||
222 | TEST_F(TestMockImageReplayerEventPreprocessor, PreprocessRefreshError) { | |
223 | librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); | |
224 | ::journal::MockJournaler mock_remote_journaler; | |
225 | ||
226 | expect_image_refresh(mock_local_image_ctx, -EINVAL); | |
227 | ||
228 | MockEventPreprocessor event_preprocessor(mock_local_image_ctx, | |
229 | mock_remote_journaler, | |
230 | "local mirror uuid", | |
231 | &m_client_meta, | |
232 | m_threads->work_queue); | |
233 | ||
234 | librbd::journal::EventEntry event_entry{librbd::journal::RenameEvent{}}; | |
235 | C_SaferCond ctx; | |
236 | event_preprocessor.preprocess(&event_entry, &ctx); | |
237 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
238 | } | |
239 | ||
240 | TEST_F(TestMockImageReplayerEventPreprocessor, PreprocessClientUpdateError) { | |
241 | librbd::MockTestImageCtx mock_local_image_ctx(*m_local_image_ctx); | |
242 | ::journal::MockJournaler mock_remote_journaler; | |
243 | ||
244 | expect_image_refresh(mock_local_image_ctx, 0); | |
245 | expect_update_client(mock_remote_journaler, -EINVAL); | |
246 | ||
247 | mock_local_image_ctx.snap_ids = {{{cls::rbd::UserSnapshotNamespace(), "snap"}, 6}}; | |
248 | mock_local_image_ctx.snap_info = { | |
249 | {6, librbd::SnapInfo{"snap", cls::rbd::UserSnapshotNamespace(), 0U, {}, 0U, 0U, utime_t()}}}; | |
250 | MockEventPreprocessor event_preprocessor(mock_local_image_ctx, | |
251 | mock_remote_journaler, | |
252 | "local mirror uuid", | |
253 | &m_client_meta, | |
254 | m_threads->work_queue); | |
255 | ||
256 | librbd::journal::EventEntry event_entry{ | |
257 | librbd::journal::SnapRenameEvent{0, 5, "snap", "new_snap"}}; | |
258 | C_SaferCond ctx; | |
259 | event_preprocessor.preprocess(&event_entry, &ctx); | |
260 | ASSERT_EQ(-EINVAL, ctx.wait()); | |
261 | } | |
262 | ||
263 | } // namespace image_replayer | |
264 | } // namespace mirror | |
265 | } // namespace rbd |