]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rbd_mirror/image_map/test_Policy.cc
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / test / rbd_mirror / image_map / test_Policy.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "include/Context.h"
5 #include "test/rbd_mirror/test_fixture.h"
6 #include "tools/rbd_mirror/image_map/Types.h"
7 #include "tools/rbd_mirror/image_map/SimplePolicy.h"
8 #include "include/stringify.h"
9 #include "common/Thread.h"
10
11 void register_test_image_policy() {
12 }
13
14 namespace rbd {
15 namespace mirror {
16 namespace image_map {
17
18 class TestImageMapPolicy : public TestFixture {
19 public:
20 void SetUp() override {
21 TestFixture::SetUp();
22
23 EXPECT_EQ(0, _rados->conf_set("rbd_mirror_image_policy_migration_throttle",
24 "0"));
25
26 CephContext *cct = reinterpret_cast<CephContext *>(m_local_io_ctx.cct());
27 std::string policy_type = cct->_conf.get_val<string>("rbd_mirror_image_policy_type");
28
29 if (policy_type == "none" || policy_type == "simple") {
30 m_policy = image_map::SimplePolicy::create(m_local_io_ctx);
31 } else {
32 ceph_abort();
33 }
34
35 m_policy->init({});
36 }
37
38 void TearDown() override {
39 TestFixture::TearDown();
40 delete m_policy;
41 }
42
43 void map_image(const std::string &global_image_id) {
44 ASSERT_TRUE(m_policy->add_image(global_image_id));
45
46 ASSERT_EQ(ACTION_TYPE_MAP_UPDATE, m_policy->start_action(global_image_id));
47 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
48
49 ASSERT_EQ(ACTION_TYPE_ACQUIRE, m_policy->start_action(global_image_id));
50 ASSERT_FALSE(m_policy->finish_action(global_image_id, 0));
51 }
52
53 void unmap_image(const std::string &global_image_id) {
54 ASSERT_TRUE(m_policy->remove_image(global_image_id));
55
56 ASSERT_EQ(ACTION_TYPE_RELEASE, m_policy->start_action(global_image_id));
57 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
58
59 ASSERT_EQ(ACTION_TYPE_MAP_REMOVE, m_policy->start_action(global_image_id));
60 ASSERT_FALSE(m_policy->finish_action(global_image_id, 0));
61 }
62
63 void shuffle_image(const std::string &global_image_id) {
64 ASSERT_EQ(ACTION_TYPE_RELEASE, m_policy->start_action(global_image_id));
65 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
66
67 ASSERT_EQ(ACTION_TYPE_MAP_UPDATE, m_policy->start_action(global_image_id));
68 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
69
70 ASSERT_EQ(ACTION_TYPE_ACQUIRE, m_policy->start_action(global_image_id));
71 ASSERT_FALSE(m_policy->finish_action(global_image_id, 0));
72 }
73
74 Policy *m_policy;
75 };
76
77 TEST_F(TestImageMapPolicy, NegativeLookup) {
78 const std::string global_image_id = "global id 1";
79
80 LookupInfo info = m_policy->lookup(global_image_id);
81 ASSERT_TRUE(info.instance_id == UNMAPPED_INSTANCE_ID);
82 }
83
84 TEST_F(TestImageMapPolicy, Init) {
85 const std::string global_image_id = "global id 1";
86
87 m_policy->init({{global_image_id, {"9876", {}, {}}}});
88
89 ASSERT_EQ(ACTION_TYPE_ACQUIRE, m_policy->start_action(global_image_id));
90 ASSERT_FALSE(m_policy->finish_action(global_image_id, 0));
91 }
92
93 TEST_F(TestImageMapPolicy, MapImage) {
94 const std::string global_image_id = "global id 1";
95
96 map_image(global_image_id);
97
98 LookupInfo info = m_policy->lookup(global_image_id);
99 ASSERT_TRUE(info.instance_id != UNMAPPED_INSTANCE_ID);
100 }
101
102 TEST_F(TestImageMapPolicy, UnmapImage) {
103 const std::string global_image_id = "global id 1";
104
105 // map image
106 map_image(global_image_id);
107
108 LookupInfo info = m_policy->lookup(global_image_id);
109 ASSERT_TRUE(info.instance_id != UNMAPPED_INSTANCE_ID);
110
111 // unmap image
112 unmap_image(global_image_id);
113
114 info = m_policy->lookup(global_image_id);
115 ASSERT_TRUE(info.instance_id == UNMAPPED_INSTANCE_ID);
116 }
117
118 TEST_F(TestImageMapPolicy, ShuffleImageAddInstance) {
119 std::set<std::string> global_image_ids {
120 "global id 1", "global id 2", "global id 3", "global id 4", "global id 5", "global id 6"
121 };
122
123 for (auto const &global_image_id : global_image_ids) {
124 // map image
125 map_image(global_image_id);
126
127 LookupInfo info = m_policy->lookup(global_image_id);
128 ASSERT_TRUE(info.instance_id != UNMAPPED_INSTANCE_ID);
129 }
130
131 std::set<std::string> shuffle_global_image_ids;
132 m_policy->add_instances({"9876"}, &shuffle_global_image_ids);
133
134 for (auto const &global_image_id : shuffle_global_image_ids) {
135 shuffle_image(global_image_id);
136
137 LookupInfo info = m_policy->lookup(global_image_id);
138 ASSERT_TRUE(info.instance_id != UNMAPPED_INSTANCE_ID);
139 }
140 }
141
142 TEST_F(TestImageMapPolicy, ShuffleImageRemoveInstance) {
143 std::set<std::string> global_image_ids {
144 "global id 1", "global id 2", "global id 3", "global id 4", "global id 5"
145 };
146
147 std::set<std::string> shuffle_global_image_ids;
148 m_policy->add_instances({stringify(m_local_io_ctx.get_instance_id())},
149 &shuffle_global_image_ids);
150 for (auto const &global_image_id : global_image_ids) {
151 // map image
152 map_image(global_image_id);
153
154 LookupInfo info = m_policy->lookup(global_image_id);
155 ASSERT_TRUE(info.instance_id != UNMAPPED_INSTANCE_ID);
156 }
157
158 m_policy->add_instances({"9876"}, &shuffle_global_image_ids);
159
160 for (auto const &global_image_id : shuffle_global_image_ids) {
161 shuffle_image(global_image_id);
162
163 LookupInfo info = m_policy->lookup(global_image_id);
164 ASSERT_TRUE(info.instance_id != UNMAPPED_INSTANCE_ID);
165 }
166
167 // record which of the images got migrated to the new instance
168 std::set<std::string> remapped_global_image_ids;
169 for (auto const &global_image_id: shuffle_global_image_ids) {
170 LookupInfo info = m_policy->lookup(global_image_id);
171 if (info.instance_id == "9876") {
172 remapped_global_image_ids.emplace(global_image_id);
173 }
174 }
175
176 shuffle_global_image_ids.clear();
177 m_policy->remove_instances({"9876"}, &shuffle_global_image_ids);
178
179 ASSERT_TRUE(shuffle_global_image_ids == remapped_global_image_ids);
180
181 for (auto const &global_image_id : shuffle_global_image_ids) {
182 shuffle_image(global_image_id);
183
184 LookupInfo info = m_policy->lookup(global_image_id);
185 ASSERT_TRUE(info.instance_id != UNMAPPED_INSTANCE_ID);
186 }
187 }
188
189 TEST_F(TestImageMapPolicy, RetryMapUpdate) {
190 const std::string global_image_id = "global id 1";
191
192 ASSERT_TRUE(m_policy->add_image(global_image_id));
193
194 ASSERT_EQ(ACTION_TYPE_MAP_UPDATE, m_policy->start_action(global_image_id));
195 // on-disk map update failed
196 ASSERT_TRUE(m_policy->finish_action(global_image_id, -EIO));
197
198 ASSERT_EQ(ACTION_TYPE_MAP_UPDATE, m_policy->start_action(global_image_id));
199 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
200
201 ASSERT_EQ(ACTION_TYPE_ACQUIRE, m_policy->start_action(global_image_id));
202 ASSERT_FALSE(m_policy->finish_action(global_image_id, 0));
203
204 LookupInfo info = m_policy->lookup(global_image_id);
205 ASSERT_TRUE(info.instance_id != UNMAPPED_INSTANCE_ID);
206 }
207
208 TEST_F(TestImageMapPolicy, MapFailureAndUnmap) {
209 const std::string global_image_id = "global id 1";
210
211 ASSERT_TRUE(m_policy->add_image(global_image_id));
212
213 ASSERT_EQ(ACTION_TYPE_MAP_UPDATE, m_policy->start_action(global_image_id));
214 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
215
216 ASSERT_EQ(ACTION_TYPE_ACQUIRE, m_policy->start_action(global_image_id));
217
218 std::set<std::string> shuffle_global_image_ids;
219 m_policy->add_instances({"9876"}, &shuffle_global_image_ids);
220 ASSERT_TRUE(shuffle_global_image_ids.empty());
221
222 m_policy->remove_instances({stringify(m_local_io_ctx.get_instance_id())},
223 &shuffle_global_image_ids);
224 ASSERT_TRUE(shuffle_global_image_ids.empty());
225
226 ASSERT_TRUE(m_policy->finish_action(global_image_id, -EBLOCKLISTED));
227
228 ASSERT_EQ(ACTION_TYPE_RELEASE, m_policy->start_action(global_image_id));
229 ASSERT_TRUE(m_policy->finish_action(global_image_id, -ENOENT));
230
231 ASSERT_EQ(ACTION_TYPE_MAP_UPDATE, m_policy->start_action(global_image_id));
232 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
233
234 ASSERT_EQ(ACTION_TYPE_ACQUIRE, m_policy->start_action(global_image_id));
235 ASSERT_FALSE(m_policy->finish_action(global_image_id, 0));
236
237 ASSERT_TRUE(m_policy->remove_image(global_image_id));
238
239 ASSERT_EQ(ACTION_TYPE_RELEASE, m_policy->start_action(global_image_id));
240 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
241
242 ASSERT_EQ(ACTION_TYPE_MAP_REMOVE, m_policy->start_action(global_image_id));
243 ASSERT_FALSE(m_policy->finish_action(global_image_id, 0));
244 }
245
246 TEST_F(TestImageMapPolicy, ReshuffleWithMapFailure) {
247 std::set<std::string> global_image_ids {
248 "global id 1", "global id 2", "global id 3", "global id 4", "global id 5",
249 "global id 6"
250 };
251
252 std::set<std::string> shuffle_global_image_ids;
253 m_policy->add_instances({stringify(m_local_io_ctx.get_instance_id())},
254 &shuffle_global_image_ids);
255 for (auto const &global_image_id : global_image_ids) {
256 // map image
257 map_image(global_image_id);
258
259 LookupInfo info = m_policy->lookup(global_image_id);
260 ASSERT_TRUE(info.instance_id != UNMAPPED_INSTANCE_ID);
261 }
262
263 m_policy->add_instances({"9876"}, &shuffle_global_image_ids);
264 ASSERT_FALSE(shuffle_global_image_ids.empty());
265
266 const std::string global_image_id = *(shuffle_global_image_ids.begin());
267 shuffle_global_image_ids.clear();
268
269 ASSERT_EQ(ACTION_TYPE_RELEASE, m_policy->start_action(global_image_id));
270 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
271
272 ASSERT_EQ(ACTION_TYPE_MAP_UPDATE, m_policy->start_action(global_image_id));
273 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
274
275 ASSERT_EQ(ACTION_TYPE_ACQUIRE, m_policy->start_action(global_image_id));
276
277 // peer unavailable
278 m_policy->remove_instances({"9876"}, &shuffle_global_image_ids);
279 ASSERT_TRUE(shuffle_global_image_ids.empty());
280
281 ASSERT_TRUE(m_policy->finish_action(global_image_id, -EBLOCKLISTED));
282
283 ASSERT_EQ(ACTION_TYPE_RELEASE, m_policy->start_action(global_image_id));
284 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
285
286 ASSERT_EQ(ACTION_TYPE_MAP_UPDATE, m_policy->start_action(global_image_id));
287 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
288
289 ASSERT_EQ(ACTION_TYPE_ACQUIRE, m_policy->start_action(global_image_id));
290 ASSERT_FALSE(m_policy->finish_action(global_image_id, 0));
291 }
292
293 TEST_F(TestImageMapPolicy, ShuffleFailureAndRemove) {
294 std::set<std::string> global_image_ids {
295 "global id 1", "global id 2", "global id 3", "global id 4", "global id 5",
296 "global id 6"
297 };
298
299 std::set<std::string> shuffle_global_image_ids;
300 m_policy->add_instances({stringify(m_local_io_ctx.get_instance_id())},
301 &shuffle_global_image_ids);
302 for (auto const &global_image_id : global_image_ids) {
303 // map image
304 map_image(global_image_id);
305
306 LookupInfo info = m_policy->lookup(global_image_id);
307 ASSERT_TRUE(info.instance_id != UNMAPPED_INSTANCE_ID);
308 }
309
310 m_policy->add_instances({"9876"}, &shuffle_global_image_ids);
311 ASSERT_FALSE(shuffle_global_image_ids.empty());
312
313 std::string global_image_id = *(shuffle_global_image_ids.begin());
314 shuffle_global_image_ids.clear();
315
316 ASSERT_EQ(ACTION_TYPE_RELEASE, m_policy->start_action(global_image_id));
317 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
318
319 ASSERT_EQ(ACTION_TYPE_MAP_UPDATE, m_policy->start_action(global_image_id));
320 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
321
322 ASSERT_EQ(ACTION_TYPE_ACQUIRE, m_policy->start_action(global_image_id));
323
324 // peer unavailable
325 m_policy->remove_instances({"9876"}, &shuffle_global_image_ids);
326 ASSERT_TRUE(shuffle_global_image_ids.empty());
327
328 ASSERT_TRUE(m_policy->finish_action(global_image_id, -EBLOCKLISTED));
329
330 ASSERT_EQ(ACTION_TYPE_RELEASE, m_policy->start_action(global_image_id));
331 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
332
333 ASSERT_EQ(ACTION_TYPE_MAP_UPDATE, m_policy->start_action(global_image_id));
334 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
335
336 ASSERT_EQ(ACTION_TYPE_ACQUIRE, m_policy->start_action(global_image_id));
337 ASSERT_FALSE(m_policy->finish_action(global_image_id, 0));
338
339 ASSERT_TRUE(m_policy->remove_image(global_image_id));
340
341 ASSERT_EQ(ACTION_TYPE_RELEASE, m_policy->start_action(global_image_id));
342 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
343
344 ASSERT_EQ(ACTION_TYPE_MAP_REMOVE, m_policy->start_action(global_image_id));
345 ASSERT_FALSE(m_policy->finish_action(global_image_id, 0));
346
347 LookupInfo info = m_policy->lookup(global_image_id);
348 ASSERT_TRUE(info.instance_id == UNMAPPED_INSTANCE_ID);
349 }
350
351 TEST_F(TestImageMapPolicy, InitialInstanceUpdate) {
352 const std::string global_image_id = "global id 1";
353
354 m_policy->init({{global_image_id, {"9876", {}, {}}}});
355
356 ASSERT_EQ(ACTION_TYPE_ACQUIRE, m_policy->start_action(global_image_id));
357
358 auto instance_id = stringify(m_local_io_ctx.get_instance_id());
359 std::set<std::string> shuffle_global_image_ids;
360 m_policy->add_instances({instance_id}, &shuffle_global_image_ids);
361
362 ASSERT_EQ(0U, shuffle_global_image_ids.size());
363 ASSERT_TRUE(m_policy->finish_action(global_image_id, -ENOENT));
364
365 ASSERT_EQ(ACTION_TYPE_RELEASE, m_policy->start_action(global_image_id));
366 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
367
368 ASSERT_EQ(ACTION_TYPE_MAP_UPDATE, m_policy->start_action(global_image_id));
369 ASSERT_TRUE(m_policy->finish_action(global_image_id, 0));
370
371 ASSERT_EQ(ACTION_TYPE_ACQUIRE, m_policy->start_action(global_image_id));
372 ASSERT_FALSE(m_policy->finish_action(global_image_id, 0));
373 }
374
375 } // namespace image_map
376 } // namespace mirror
377 } // namespace rbd