]>
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 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2011 New Dream Network | |
7 | * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com> | |
8 | * | |
9 | * Author: Loic Dachary <loic@dachary.org> | |
10 | * | |
11 | * This is free software; you can redistribute it and/or | |
12 | * modify it under the terms of the GNU General Public | |
13 | * License version 2, as published by the Free Software | |
14 | * Foundation. See file COPYING. | |
15 | * | |
16 | */ | |
17 | ||
18 | #include "include/types.h" | |
19 | #include "osd/osd_types.h" | |
20 | #include "osd/OSDMap.h" | |
21 | #include "gtest/gtest.h" | |
22 | #include "include/coredumpctl.h" | |
23 | #include "common/Thread.h" | |
24 | #include "include/stringify.h" | |
25 | #include "osd/ReplicatedBackend.h" | |
7c673cae FG |
26 | #include <sstream> |
27 | ||
20effc67 TL |
28 | using namespace std; |
29 | ||
7c673cae FG |
30 | TEST(hobject, prefixes0) |
31 | { | |
32 | uint32_t mask = 0xE947FA20; | |
33 | uint32_t bits = 12; | |
34 | int64_t pool = 0; | |
35 | ||
36 | set<string> prefixes_correct; | |
37 | prefixes_correct.insert(string("0000000000000000.02A")); | |
38 | ||
39 | set<string> prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); | |
40 | ASSERT_EQ(prefixes_out, prefixes_correct); | |
41 | } | |
42 | ||
43 | TEST(hobject, prefixes1) | |
44 | { | |
45 | uint32_t mask = 0x0000000F; | |
46 | uint32_t bits = 6; | |
47 | int64_t pool = 20; | |
48 | ||
49 | set<string> prefixes_correct; | |
50 | prefixes_correct.insert(string("0000000000000014.F0")); | |
51 | prefixes_correct.insert(string("0000000000000014.F4")); | |
52 | prefixes_correct.insert(string("0000000000000014.F8")); | |
53 | prefixes_correct.insert(string("0000000000000014.FC")); | |
54 | ||
55 | set<string> prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); | |
56 | ASSERT_EQ(prefixes_out, prefixes_correct); | |
57 | } | |
58 | ||
59 | TEST(hobject, prefixes2) | |
60 | { | |
61 | uint32_t mask = 0xDEADBEAF; | |
62 | uint32_t bits = 25; | |
63 | int64_t pool = 0; | |
64 | ||
65 | set<string> prefixes_correct; | |
66 | prefixes_correct.insert(string("0000000000000000.FAEBDA0")); | |
67 | prefixes_correct.insert(string("0000000000000000.FAEBDA2")); | |
68 | prefixes_correct.insert(string("0000000000000000.FAEBDA4")); | |
69 | prefixes_correct.insert(string("0000000000000000.FAEBDA6")); | |
70 | prefixes_correct.insert(string("0000000000000000.FAEBDA8")); | |
71 | prefixes_correct.insert(string("0000000000000000.FAEBDAA")); | |
72 | prefixes_correct.insert(string("0000000000000000.FAEBDAC")); | |
73 | prefixes_correct.insert(string("0000000000000000.FAEBDAE")); | |
74 | ||
75 | set<string> prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); | |
76 | ASSERT_EQ(prefixes_out, prefixes_correct); | |
77 | } | |
78 | ||
79 | TEST(hobject, prefixes3) | |
80 | { | |
81 | uint32_t mask = 0xE947FA20; | |
82 | uint32_t bits = 32; | |
83 | int64_t pool = 0x23; | |
84 | ||
85 | set<string> prefixes_correct; | |
86 | prefixes_correct.insert(string("0000000000000023.02AF749E")); | |
87 | ||
88 | set<string> prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); | |
89 | ASSERT_EQ(prefixes_out, prefixes_correct); | |
90 | } | |
91 | ||
92 | TEST(hobject, prefixes4) | |
93 | { | |
94 | uint32_t mask = 0xE947FA20; | |
95 | uint32_t bits = 0; | |
96 | int64_t pool = 0x23; | |
97 | ||
98 | set<string> prefixes_correct; | |
99 | prefixes_correct.insert(string("0000000000000023.")); | |
100 | ||
101 | set<string> prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); | |
102 | ASSERT_EQ(prefixes_out, prefixes_correct); | |
103 | } | |
104 | ||
105 | TEST(hobject, prefixes5) | |
106 | { | |
107 | uint32_t mask = 0xDEADBEAF; | |
108 | uint32_t bits = 1; | |
109 | int64_t pool = 0x34AC5D00; | |
110 | ||
111 | set<string> prefixes_correct; | |
112 | prefixes_correct.insert(string("0000000034AC5D00.1")); | |
113 | prefixes_correct.insert(string("0000000034AC5D00.3")); | |
114 | prefixes_correct.insert(string("0000000034AC5D00.5")); | |
115 | prefixes_correct.insert(string("0000000034AC5D00.7")); | |
116 | prefixes_correct.insert(string("0000000034AC5D00.9")); | |
117 | prefixes_correct.insert(string("0000000034AC5D00.B")); | |
118 | prefixes_correct.insert(string("0000000034AC5D00.D")); | |
119 | prefixes_correct.insert(string("0000000034AC5D00.F")); | |
120 | ||
121 | set<string> prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); | |
122 | ASSERT_EQ(prefixes_out, prefixes_correct); | |
123 | } | |
124 | ||
125 | TEST(pg_interval_t, check_new_interval) | |
126 | { | |
127 | // iterate through all 4 combinations | |
128 | for (unsigned i = 0; i < 4; ++i) { | |
7c673cae FG |
129 | // |
130 | // Create a situation where osdmaps are the same so that | |
131 | // each test case can diverge from it using minimal code. | |
132 | // | |
133 | int osd_id = 1; | |
134 | epoch_t epoch = 40; | |
11fdf7f2 | 135 | std::shared_ptr<OSDMap> osdmap(new OSDMap()); |
7c673cae FG |
136 | osdmap->set_max_osd(10); |
137 | osdmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
138 | osdmap->set_epoch(epoch); | |
11fdf7f2 | 139 | std::shared_ptr<OSDMap> lastmap(new OSDMap()); |
7c673cae FG |
140 | lastmap->set_max_osd(10); |
141 | lastmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
142 | lastmap->set_epoch(epoch); | |
143 | epoch_t same_interval_since = epoch; | |
144 | epoch_t last_epoch_clean = same_interval_since; | |
145 | int64_t pool_id = 200; | |
146 | int pg_num = 4; | |
147 | __u8 min_size = 2; | |
148 | boost::scoped_ptr<IsPGRecoverablePredicate> recoverable(new ReplicatedBackend::RPCRecPred()); | |
149 | { | |
150 | OSDMap::Incremental inc(epoch + 1); | |
151 | inc.new_pools[pool_id].min_size = min_size; | |
152 | inc.new_pools[pool_id].set_pg_num(pg_num); | |
11fdf7f2 | 153 | inc.new_pools[pool_id].set_pg_num_pending(pg_num); |
7c673cae FG |
154 | inc.new_up_thru[osd_id] = epoch + 1; |
155 | osdmap->apply_incremental(inc); | |
156 | lastmap->apply_incremental(inc); | |
157 | } | |
158 | vector<int> new_acting; | |
159 | new_acting.push_back(osd_id); | |
160 | new_acting.push_back(osd_id + 1); | |
161 | vector<int> old_acting = new_acting; | |
162 | int old_primary = osd_id; | |
163 | int new_primary = osd_id; | |
164 | vector<int> new_up; | |
165 | new_up.push_back(osd_id); | |
166 | int old_up_primary = osd_id; | |
167 | int new_up_primary = osd_id; | |
168 | vector<int> old_up = new_up; | |
169 | pg_t pgid; | |
170 | pgid.set_pool(pool_id); | |
171 | ||
172 | // | |
173 | // Do nothing if there are no modifications in | |
174 | // acting, up or pool size and that the pool is not | |
175 | // being split | |
176 | // | |
177 | { | |
11fdf7f2 | 178 | PastIntervals past_intervals; |
7c673cae FG |
179 | |
180 | ASSERT_TRUE(past_intervals.empty()); | |
181 | ASSERT_FALSE(PastIntervals::check_new_interval(old_primary, | |
182 | new_primary, | |
183 | old_acting, | |
184 | new_acting, | |
185 | old_up_primary, | |
186 | new_up_primary, | |
187 | old_up, | |
188 | new_up, | |
189 | same_interval_since, | |
190 | last_epoch_clean, | |
191 | osdmap, | |
192 | lastmap, | |
193 | pgid, | |
9f95a23c | 194 | *recoverable, |
7c673cae FG |
195 | &past_intervals)); |
196 | ASSERT_TRUE(past_intervals.empty()); | |
197 | } | |
198 | ||
199 | // | |
200 | // The acting set has changed | |
201 | // | |
202 | { | |
203 | vector<int> new_acting; | |
204 | int _new_primary = osd_id + 1; | |
205 | new_acting.push_back(_new_primary); | |
206 | ||
11fdf7f2 | 207 | PastIntervals past_intervals; |
7c673cae FG |
208 | |
209 | ASSERT_TRUE(past_intervals.empty()); | |
210 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
211 | new_primary, | |
212 | old_acting, | |
213 | new_acting, | |
214 | old_up_primary, | |
215 | new_up_primary, | |
216 | old_up, | |
217 | new_up, | |
218 | same_interval_since, | |
219 | last_epoch_clean, | |
220 | osdmap, | |
221 | lastmap, | |
222 | pgid, | |
9f95a23c | 223 | *recoverable, |
7c673cae FG |
224 | &past_intervals)); |
225 | old_primary = new_primary; | |
226 | } | |
227 | ||
228 | // | |
229 | // The up set has changed | |
230 | // | |
231 | { | |
232 | vector<int> new_up; | |
233 | int _new_primary = osd_id + 1; | |
234 | new_up.push_back(_new_primary); | |
235 | ||
11fdf7f2 | 236 | PastIntervals past_intervals; |
7c673cae FG |
237 | |
238 | ASSERT_TRUE(past_intervals.empty()); | |
239 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
240 | new_primary, | |
241 | old_acting, | |
242 | new_acting, | |
243 | old_up_primary, | |
244 | new_up_primary, | |
245 | old_up, | |
246 | new_up, | |
247 | same_interval_since, | |
248 | last_epoch_clean, | |
249 | osdmap, | |
250 | lastmap, | |
251 | pgid, | |
9f95a23c | 252 | *recoverable, |
7c673cae FG |
253 | &past_intervals)); |
254 | } | |
255 | ||
256 | // | |
257 | // The up primary has changed | |
258 | // | |
259 | { | |
260 | vector<int> new_up; | |
261 | int _new_up_primary = osd_id + 1; | |
262 | ||
11fdf7f2 | 263 | PastIntervals past_intervals; |
7c673cae FG |
264 | |
265 | ASSERT_TRUE(past_intervals.empty()); | |
266 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
267 | new_primary, | |
268 | old_acting, | |
269 | new_acting, | |
270 | old_up_primary, | |
271 | _new_up_primary, | |
272 | old_up, | |
273 | new_up, | |
274 | same_interval_since, | |
275 | last_epoch_clean, | |
276 | osdmap, | |
277 | lastmap, | |
278 | pgid, | |
9f95a23c | 279 | *recoverable, |
7c673cae FG |
280 | &past_intervals)); |
281 | } | |
282 | ||
283 | // | |
284 | // PG is splitting | |
285 | // | |
286 | { | |
11fdf7f2 | 287 | std::shared_ptr<OSDMap> osdmap(new OSDMap()); |
7c673cae FG |
288 | osdmap->set_max_osd(10); |
289 | osdmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
290 | osdmap->set_epoch(epoch); | |
291 | int new_pg_num = pg_num ^ 2; | |
292 | OSDMap::Incremental inc(epoch + 1); | |
293 | inc.new_pools[pool_id].min_size = min_size; | |
294 | inc.new_pools[pool_id].set_pg_num(new_pg_num); | |
295 | osdmap->apply_incremental(inc); | |
296 | ||
11fdf7f2 | 297 | PastIntervals past_intervals; |
7c673cae FG |
298 | |
299 | ASSERT_TRUE(past_intervals.empty()); | |
300 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
301 | new_primary, | |
302 | old_acting, | |
303 | new_acting, | |
304 | old_up_primary, | |
305 | new_up_primary, | |
306 | old_up, | |
307 | new_up, | |
308 | same_interval_since, | |
309 | last_epoch_clean, | |
310 | osdmap, | |
311 | lastmap, | |
312 | pgid, | |
9f95a23c | 313 | *recoverable, |
7c673cae FG |
314 | &past_intervals)); |
315 | } | |
316 | ||
11fdf7f2 TL |
317 | // |
318 | // PG is pre-merge source | |
319 | // | |
320 | { | |
321 | std::shared_ptr<OSDMap> osdmap(new OSDMap()); | |
322 | osdmap->set_max_osd(10); | |
323 | osdmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
324 | osdmap->set_epoch(epoch); | |
325 | OSDMap::Incremental inc(epoch + 1); | |
326 | inc.new_pools[pool_id].min_size = min_size; | |
327 | inc.new_pools[pool_id].set_pg_num(pg_num); | |
328 | inc.new_pools[pool_id].set_pg_num_pending(pg_num - 1); | |
329 | osdmap->apply_incremental(inc); | |
330 | cout << "pg_num " << pg_num << std::endl; | |
331 | PastIntervals past_intervals; | |
332 | ||
333 | ASSERT_TRUE(past_intervals.empty()); | |
334 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
335 | new_primary, | |
336 | old_acting, | |
337 | new_acting, | |
338 | old_up_primary, | |
339 | new_up_primary, | |
340 | old_up, | |
341 | new_up, | |
342 | same_interval_since, | |
343 | last_epoch_clean, | |
344 | osdmap, | |
345 | lastmap, | |
346 | pg_t(pg_num - 1, pool_id), | |
9f95a23c | 347 | *recoverable, |
11fdf7f2 TL |
348 | &past_intervals)); |
349 | } | |
350 | ||
351 | // | |
352 | // PG was pre-merge source | |
353 | // | |
354 | { | |
355 | std::shared_ptr<OSDMap> osdmap(new OSDMap()); | |
356 | osdmap->set_max_osd(10); | |
357 | osdmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
358 | osdmap->set_epoch(epoch); | |
359 | OSDMap::Incremental inc(epoch + 1); | |
360 | inc.new_pools[pool_id].min_size = min_size; | |
361 | inc.new_pools[pool_id].set_pg_num(pg_num); | |
362 | inc.new_pools[pool_id].set_pg_num_pending(pg_num - 1); | |
363 | osdmap->apply_incremental(inc); | |
364 | ||
365 | cout << "pg_num " << pg_num << std::endl; | |
366 | PastIntervals past_intervals; | |
367 | ||
368 | ASSERT_TRUE(past_intervals.empty()); | |
369 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
370 | new_primary, | |
371 | old_acting, | |
372 | new_acting, | |
373 | old_up_primary, | |
374 | new_up_primary, | |
375 | old_up, | |
376 | new_up, | |
377 | same_interval_since, | |
378 | last_epoch_clean, | |
379 | lastmap, // reverse order! | |
380 | osdmap, | |
381 | pg_t(pg_num - 1, pool_id), | |
9f95a23c | 382 | *recoverable, |
11fdf7f2 TL |
383 | &past_intervals)); |
384 | } | |
385 | ||
386 | // | |
387 | // PG is merge source | |
388 | // | |
389 | { | |
390 | std::shared_ptr<OSDMap> osdmap(new OSDMap()); | |
391 | osdmap->set_max_osd(10); | |
392 | osdmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
393 | osdmap->set_epoch(epoch); | |
394 | OSDMap::Incremental inc(epoch + 1); | |
395 | inc.new_pools[pool_id].min_size = min_size; | |
396 | inc.new_pools[pool_id].set_pg_num(pg_num - 1); | |
397 | osdmap->apply_incremental(inc); | |
398 | ||
399 | PastIntervals past_intervals; | |
400 | ||
401 | ASSERT_TRUE(past_intervals.empty()); | |
402 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
403 | new_primary, | |
404 | old_acting, | |
405 | new_acting, | |
406 | old_up_primary, | |
407 | new_up_primary, | |
408 | old_up, | |
409 | new_up, | |
410 | same_interval_since, | |
411 | last_epoch_clean, | |
412 | osdmap, | |
413 | lastmap, | |
414 | pg_t(pg_num - 1, pool_id), | |
9f95a23c | 415 | *recoverable, |
11fdf7f2 TL |
416 | &past_intervals)); |
417 | } | |
418 | ||
419 | // | |
420 | // PG is pre-merge target | |
421 | // | |
422 | { | |
423 | std::shared_ptr<OSDMap> osdmap(new OSDMap()); | |
424 | osdmap->set_max_osd(10); | |
425 | osdmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
426 | osdmap->set_epoch(epoch); | |
427 | OSDMap::Incremental inc(epoch + 1); | |
428 | inc.new_pools[pool_id].min_size = min_size; | |
429 | inc.new_pools[pool_id].set_pg_num_pending(pg_num - 1); | |
430 | osdmap->apply_incremental(inc); | |
431 | ||
432 | PastIntervals past_intervals; | |
433 | ||
434 | ASSERT_TRUE(past_intervals.empty()); | |
435 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
436 | new_primary, | |
437 | old_acting, | |
438 | new_acting, | |
439 | old_up_primary, | |
440 | new_up_primary, | |
441 | old_up, | |
442 | new_up, | |
443 | same_interval_since, | |
444 | last_epoch_clean, | |
445 | osdmap, | |
446 | lastmap, | |
447 | pg_t(pg_num / 2 - 1, pool_id), | |
9f95a23c | 448 | *recoverable, |
11fdf7f2 TL |
449 | &past_intervals)); |
450 | } | |
451 | ||
452 | // | |
453 | // PG was pre-merge target | |
454 | // | |
455 | { | |
456 | std::shared_ptr<OSDMap> osdmap(new OSDMap()); | |
457 | osdmap->set_max_osd(10); | |
458 | osdmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
459 | osdmap->set_epoch(epoch); | |
460 | OSDMap::Incremental inc(epoch + 1); | |
461 | inc.new_pools[pool_id].min_size = min_size; | |
462 | inc.new_pools[pool_id].set_pg_num_pending(pg_num - 1); | |
463 | osdmap->apply_incremental(inc); | |
464 | ||
465 | PastIntervals past_intervals; | |
466 | ||
467 | ASSERT_TRUE(past_intervals.empty()); | |
468 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
469 | new_primary, | |
470 | old_acting, | |
471 | new_acting, | |
472 | old_up_primary, | |
473 | new_up_primary, | |
474 | old_up, | |
475 | new_up, | |
476 | same_interval_since, | |
477 | last_epoch_clean, | |
478 | lastmap, // reverse order! | |
479 | osdmap, | |
480 | pg_t(pg_num / 2 - 1, pool_id), | |
9f95a23c | 481 | *recoverable, |
11fdf7f2 TL |
482 | &past_intervals)); |
483 | } | |
484 | ||
485 | // | |
486 | // PG is merge target | |
487 | // | |
488 | { | |
489 | std::shared_ptr<OSDMap> osdmap(new OSDMap()); | |
490 | osdmap->set_max_osd(10); | |
491 | osdmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
492 | osdmap->set_epoch(epoch); | |
493 | OSDMap::Incremental inc(epoch + 1); | |
494 | inc.new_pools[pool_id].min_size = min_size; | |
495 | inc.new_pools[pool_id].set_pg_num(pg_num - 1); | |
496 | osdmap->apply_incremental(inc); | |
497 | ||
498 | PastIntervals past_intervals; | |
499 | ||
500 | ASSERT_TRUE(past_intervals.empty()); | |
501 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
502 | new_primary, | |
503 | old_acting, | |
504 | new_acting, | |
505 | old_up_primary, | |
506 | new_up_primary, | |
507 | old_up, | |
508 | new_up, | |
509 | same_interval_since, | |
510 | last_epoch_clean, | |
511 | osdmap, | |
512 | lastmap, | |
513 | pg_t(pg_num / 2 - 1, pool_id), | |
9f95a23c | 514 | *recoverable, |
11fdf7f2 TL |
515 | &past_intervals)); |
516 | } | |
517 | ||
7c673cae FG |
518 | // |
519 | // PG size has changed | |
520 | // | |
521 | { | |
11fdf7f2 | 522 | std::shared_ptr<OSDMap> osdmap(new OSDMap()); |
7c673cae FG |
523 | osdmap->set_max_osd(10); |
524 | osdmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
525 | osdmap->set_epoch(epoch); | |
526 | OSDMap::Incremental inc(epoch + 1); | |
527 | __u8 new_min_size = min_size + 1; | |
528 | inc.new_pools[pool_id].min_size = new_min_size; | |
529 | inc.new_pools[pool_id].set_pg_num(pg_num); | |
530 | osdmap->apply_incremental(inc); | |
531 | ||
11fdf7f2 | 532 | PastIntervals past_intervals; |
7c673cae FG |
533 | |
534 | ASSERT_TRUE(past_intervals.empty()); | |
535 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
536 | new_primary, | |
537 | old_acting, | |
538 | new_acting, | |
539 | old_up_primary, | |
540 | new_up_primary, | |
541 | old_up, | |
542 | new_up, | |
543 | same_interval_since, | |
544 | last_epoch_clean, | |
545 | osdmap, | |
546 | lastmap, | |
547 | pgid, | |
9f95a23c | 548 | *recoverable, |
7c673cae FG |
549 | &past_intervals)); |
550 | } | |
551 | ||
552 | // | |
553 | // The old acting set was empty : the previous interval could not | |
554 | // have been rw | |
555 | // | |
556 | { | |
557 | vector<int> old_acting; | |
558 | ||
11fdf7f2 | 559 | PastIntervals past_intervals; |
7c673cae FG |
560 | |
561 | ostringstream out; | |
562 | ||
563 | ASSERT_TRUE(past_intervals.empty()); | |
564 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
565 | new_primary, | |
566 | old_acting, | |
567 | new_acting, | |
568 | old_up_primary, | |
569 | new_up_primary, | |
570 | old_up, | |
571 | new_up, | |
572 | same_interval_since, | |
573 | last_epoch_clean, | |
574 | osdmap, | |
575 | lastmap, | |
576 | pgid, | |
9f95a23c | 577 | *recoverable, |
7c673cae FG |
578 | &past_intervals, |
579 | &out)); | |
580 | ASSERT_NE(string::npos, out.str().find("acting set is too small")); | |
581 | } | |
582 | ||
583 | // | |
584 | // The old acting set did not have enough osd : it could | |
585 | // not have been rw | |
586 | // | |
587 | { | |
588 | vector<int> old_acting; | |
589 | old_acting.push_back(osd_id); | |
590 | ||
591 | // | |
592 | // see http://tracker.ceph.com/issues/5780 | |
593 | // the size of the old acting set should be compared | |
594 | // with the min_size of the old osdmap | |
595 | // | |
596 | // The new osdmap is created so that it triggers the | |
597 | // bug. | |
598 | // | |
11fdf7f2 | 599 | std::shared_ptr<OSDMap> osdmap(new OSDMap()); |
7c673cae FG |
600 | osdmap->set_max_osd(10); |
601 | osdmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
602 | osdmap->set_epoch(epoch); | |
603 | OSDMap::Incremental inc(epoch + 1); | |
604 | __u8 new_min_size = old_acting.size(); | |
605 | inc.new_pools[pool_id].min_size = new_min_size; | |
606 | inc.new_pools[pool_id].set_pg_num(pg_num); | |
607 | osdmap->apply_incremental(inc); | |
608 | ||
609 | ostringstream out; | |
610 | ||
11fdf7f2 | 611 | PastIntervals past_intervals; |
7c673cae FG |
612 | |
613 | ASSERT_TRUE(past_intervals.empty()); | |
614 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
615 | new_primary, | |
616 | old_acting, | |
617 | new_acting, | |
618 | old_up_primary, | |
619 | new_up_primary, | |
620 | old_up, | |
621 | new_up, | |
622 | same_interval_since, | |
623 | last_epoch_clean, | |
624 | osdmap, | |
625 | lastmap, | |
626 | pgid, | |
9f95a23c | 627 | *recoverable, |
7c673cae FG |
628 | &past_intervals, |
629 | &out)); | |
630 | ASSERT_NE(string::npos, out.str().find("acting set is too small")); | |
631 | } | |
632 | ||
633 | // | |
634 | // The acting set changes. The old acting set primary was up during the | |
635 | // previous interval and may have been rw. | |
636 | // | |
637 | { | |
638 | vector<int> new_acting; | |
639 | new_acting.push_back(osd_id + 4); | |
640 | new_acting.push_back(osd_id + 5); | |
641 | ||
642 | ostringstream out; | |
643 | ||
11fdf7f2 | 644 | PastIntervals past_intervals; |
7c673cae FG |
645 | |
646 | ASSERT_TRUE(past_intervals.empty()); | |
647 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
648 | new_primary, | |
649 | old_acting, | |
650 | new_acting, | |
651 | old_up_primary, | |
652 | new_up_primary, | |
653 | old_up, | |
654 | new_up, | |
655 | same_interval_since, | |
656 | last_epoch_clean, | |
657 | osdmap, | |
658 | lastmap, | |
659 | pgid, | |
9f95a23c | 660 | *recoverable, |
7c673cae FG |
661 | &past_intervals, |
662 | &out)); | |
663 | ASSERT_NE(string::npos, out.str().find("includes interval")); | |
664 | } | |
665 | // | |
666 | // The acting set changes. The old acting set primary was not up | |
667 | // during the old interval but last_epoch_clean is in the | |
668 | // old interval and it may have been rw. | |
669 | // | |
670 | { | |
671 | vector<int> new_acting; | |
672 | new_acting.push_back(osd_id + 4); | |
673 | new_acting.push_back(osd_id + 5); | |
674 | ||
11fdf7f2 | 675 | std::shared_ptr<OSDMap> lastmap(new OSDMap()); |
7c673cae FG |
676 | lastmap->set_max_osd(10); |
677 | lastmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
678 | lastmap->set_epoch(epoch); | |
679 | OSDMap::Incremental inc(epoch + 1); | |
680 | inc.new_pools[pool_id].min_size = min_size; | |
681 | inc.new_pools[pool_id].set_pg_num(pg_num); | |
682 | inc.new_up_thru[osd_id] = epoch - 10; | |
683 | lastmap->apply_incremental(inc); | |
684 | ||
685 | ostringstream out; | |
686 | ||
11fdf7f2 | 687 | PastIntervals past_intervals; |
7c673cae FG |
688 | |
689 | ASSERT_TRUE(past_intervals.empty()); | |
690 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
691 | new_primary, | |
692 | old_acting, | |
693 | new_acting, | |
694 | old_up_primary, | |
695 | new_up_primary, | |
696 | old_up, | |
697 | new_up, | |
698 | same_interval_since, | |
699 | last_epoch_clean, | |
700 | osdmap, | |
701 | lastmap, | |
702 | pgid, | |
9f95a23c | 703 | *recoverable, |
7c673cae FG |
704 | &past_intervals, |
705 | &out)); | |
706 | ASSERT_NE(string::npos, out.str().find("presumed to have been rw")); | |
707 | } | |
708 | ||
709 | // | |
710 | // The acting set changes. The old acting set primary was not up | |
711 | // during the old interval and last_epoch_clean is before the | |
712 | // old interval : the previous interval could not possibly have | |
713 | // been rw. | |
714 | // | |
715 | { | |
716 | vector<int> new_acting; | |
717 | new_acting.push_back(osd_id + 4); | |
718 | new_acting.push_back(osd_id + 5); | |
719 | ||
720 | epoch_t last_epoch_clean = epoch - 10; | |
721 | ||
11fdf7f2 | 722 | std::shared_ptr<OSDMap> lastmap(new OSDMap()); |
7c673cae FG |
723 | lastmap->set_max_osd(10); |
724 | lastmap->set_state(osd_id, CEPH_OSD_EXISTS); | |
725 | lastmap->set_epoch(epoch); | |
726 | OSDMap::Incremental inc(epoch + 1); | |
727 | inc.new_pools[pool_id].min_size = min_size; | |
728 | inc.new_pools[pool_id].set_pg_num(pg_num); | |
729 | inc.new_up_thru[osd_id] = last_epoch_clean; | |
730 | lastmap->apply_incremental(inc); | |
731 | ||
732 | ostringstream out; | |
733 | ||
11fdf7f2 | 734 | PastIntervals past_intervals; |
7c673cae FG |
735 | |
736 | ASSERT_TRUE(past_intervals.empty()); | |
737 | ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, | |
738 | new_primary, | |
739 | old_acting, | |
740 | new_acting, | |
741 | old_up_primary, | |
742 | new_up_primary, | |
743 | old_up, | |
744 | new_up, | |
745 | same_interval_since, | |
746 | last_epoch_clean, | |
747 | osdmap, | |
748 | lastmap, | |
749 | pgid, | |
9f95a23c | 750 | *recoverable, |
7c673cae FG |
751 | &past_intervals, |
752 | &out)); | |
753 | ASSERT_NE(string::npos, out.str().find("does not include interval")); | |
754 | } | |
755 | } // end for, didn't want to reindent | |
756 | } | |
757 | ||
758 | TEST(pg_t, get_ancestor) | |
759 | { | |
11fdf7f2 TL |
760 | ASSERT_EQ(pg_t(0, 0), pg_t(16, 0).get_ancestor(16)); |
761 | ASSERT_EQ(pg_t(1, 0), pg_t(17, 0).get_ancestor(16)); | |
762 | ASSERT_EQ(pg_t(0, 0), pg_t(16, 0).get_ancestor(8)); | |
763 | ASSERT_EQ(pg_t(16, 0), pg_t(16, 0).get_ancestor(80)); | |
764 | ASSERT_EQ(pg_t(16, 0), pg_t(16, 0).get_ancestor(83)); | |
765 | ASSERT_EQ(pg_t(1, 0), pg_t(1321, 0).get_ancestor(123).get_ancestor(8)); | |
766 | ASSERT_EQ(pg_t(3, 0), pg_t(1323, 0).get_ancestor(123).get_ancestor(8)); | |
767 | ASSERT_EQ(pg_t(3, 0), pg_t(1323, 0).get_ancestor(8)); | |
7c673cae FG |
768 | } |
769 | ||
770 | TEST(pg_t, split) | |
771 | { | |
11fdf7f2 | 772 | pg_t pgid(0, 0); |
7c673cae FG |
773 | set<pg_t> s; |
774 | bool b; | |
775 | ||
776 | s.clear(); | |
777 | b = pgid.is_split(1, 1, &s); | |
778 | ASSERT_TRUE(!b); | |
779 | ||
780 | s.clear(); | |
781 | b = pgid.is_split(2, 4, NULL); | |
782 | ASSERT_TRUE(b); | |
783 | b = pgid.is_split(2, 4, &s); | |
784 | ASSERT_TRUE(b); | |
785 | ASSERT_EQ(1u, s.size()); | |
11fdf7f2 | 786 | ASSERT_TRUE(s.count(pg_t(2, 0))); |
7c673cae FG |
787 | |
788 | s.clear(); | |
789 | b = pgid.is_split(2, 8, &s); | |
790 | ASSERT_TRUE(b); | |
791 | ASSERT_EQ(3u, s.size()); | |
11fdf7f2 TL |
792 | ASSERT_TRUE(s.count(pg_t(2, 0))); |
793 | ASSERT_TRUE(s.count(pg_t(4, 0))); | |
794 | ASSERT_TRUE(s.count(pg_t(6, 0))); | |
7c673cae FG |
795 | |
796 | s.clear(); | |
797 | b = pgid.is_split(3, 8, &s); | |
798 | ASSERT_TRUE(b); | |
799 | ASSERT_EQ(1u, s.size()); | |
11fdf7f2 | 800 | ASSERT_TRUE(s.count(pg_t(4, 0))); |
7c673cae FG |
801 | |
802 | s.clear(); | |
803 | b = pgid.is_split(6, 8, NULL); | |
804 | ASSERT_TRUE(!b); | |
805 | b = pgid.is_split(6, 8, &s); | |
806 | ASSERT_TRUE(!b); | |
807 | ASSERT_EQ(0u, s.size()); | |
808 | ||
11fdf7f2 | 809 | pgid = pg_t(1, 0); |
7c673cae FG |
810 | |
811 | s.clear(); | |
812 | b = pgid.is_split(2, 4, &s); | |
813 | ASSERT_TRUE(b); | |
814 | ASSERT_EQ(1u, s.size()); | |
11fdf7f2 | 815 | ASSERT_TRUE(s.count(pg_t(3, 0))); |
7c673cae FG |
816 | |
817 | s.clear(); | |
818 | b = pgid.is_split(2, 6, &s); | |
819 | ASSERT_TRUE(b); | |
820 | ASSERT_EQ(2u, s.size()); | |
11fdf7f2 TL |
821 | ASSERT_TRUE(s.count(pg_t(3, 0))); |
822 | ASSERT_TRUE(s.count(pg_t(5, 0))); | |
7c673cae FG |
823 | |
824 | s.clear(); | |
825 | b = pgid.is_split(2, 8, &s); | |
826 | ASSERT_TRUE(b); | |
827 | ASSERT_EQ(3u, s.size()); | |
11fdf7f2 TL |
828 | ASSERT_TRUE(s.count(pg_t(3, 0))); |
829 | ASSERT_TRUE(s.count(pg_t(5, 0))); | |
830 | ASSERT_TRUE(s.count(pg_t(7, 0))); | |
7c673cae FG |
831 | |
832 | s.clear(); | |
833 | b = pgid.is_split(4, 8, &s); | |
834 | ASSERT_TRUE(b); | |
835 | ASSERT_EQ(1u, s.size()); | |
11fdf7f2 | 836 | ASSERT_TRUE(s.count(pg_t(5, 0))); |
7c673cae FG |
837 | |
838 | s.clear(); | |
839 | b = pgid.is_split(3, 8, &s); | |
840 | ASSERT_TRUE(b); | |
841 | ASSERT_EQ(3u, s.size()); | |
11fdf7f2 TL |
842 | ASSERT_TRUE(s.count(pg_t(3, 0))); |
843 | ASSERT_TRUE(s.count(pg_t(5, 0))); | |
844 | ASSERT_TRUE(s.count(pg_t(7, 0))); | |
7c673cae FG |
845 | |
846 | s.clear(); | |
847 | b = pgid.is_split(6, 8, &s); | |
848 | ASSERT_TRUE(!b); | |
849 | ASSERT_EQ(0u, s.size()); | |
850 | ||
11fdf7f2 | 851 | pgid = pg_t(3, 0); |
7c673cae FG |
852 | |
853 | s.clear(); | |
854 | b = pgid.is_split(7, 8, &s); | |
855 | ASSERT_TRUE(b); | |
856 | ASSERT_EQ(1u, s.size()); | |
11fdf7f2 | 857 | ASSERT_TRUE(s.count(pg_t(7, 0))); |
7c673cae FG |
858 | |
859 | s.clear(); | |
860 | b = pgid.is_split(7, 12, &s); | |
861 | ASSERT_TRUE(b); | |
862 | ASSERT_EQ(2u, s.size()); | |
11fdf7f2 TL |
863 | ASSERT_TRUE(s.count(pg_t(7, 0))); |
864 | ASSERT_TRUE(s.count(pg_t(11, 0))); | |
7c673cae FG |
865 | |
866 | s.clear(); | |
867 | b = pgid.is_split(7, 11, &s); | |
868 | ASSERT_TRUE(b); | |
869 | ASSERT_EQ(1u, s.size()); | |
11fdf7f2 | 870 | ASSERT_TRUE(s.count(pg_t(7, 0))); |
7c673cae FG |
871 | |
872 | } | |
873 | ||
11fdf7f2 TL |
874 | TEST(pg_t, merge) |
875 | { | |
876 | pg_t pgid, parent; | |
877 | bool b; | |
878 | ||
879 | pgid = pg_t(7, 0); | |
880 | b = pgid.is_merge_source(8, 7, &parent); | |
881 | ASSERT_TRUE(b); | |
882 | ASSERT_EQ(parent, pg_t(3, 0)); | |
883 | ASSERT_TRUE(parent.is_merge_target(8, 7)); | |
884 | ||
885 | b = pgid.is_merge_source(8, 5, &parent); | |
886 | ASSERT_TRUE(b); | |
887 | ASSERT_EQ(parent, pg_t(3, 0)); | |
888 | ASSERT_TRUE(parent.is_merge_target(8, 5)); | |
889 | ||
890 | b = pgid.is_merge_source(8, 4, &parent); | |
891 | ASSERT_TRUE(b); | |
892 | ASSERT_EQ(parent, pg_t(3, 0)); | |
893 | ASSERT_TRUE(parent.is_merge_target(8, 4)); | |
894 | ||
895 | b = pgid.is_merge_source(8, 3, &parent); | |
896 | ASSERT_TRUE(b); | |
897 | ASSERT_EQ(parent, pg_t(1, 0)); | |
898 | ASSERT_TRUE(parent.is_merge_target(8, 4)); | |
899 | ||
900 | b = pgid.is_merge_source(9, 8, &parent); | |
901 | ASSERT_FALSE(b); | |
902 | ASSERT_FALSE(parent.is_merge_target(9, 8)); | |
903 | } | |
904 | ||
9f95a23c TL |
905 | TEST(ObjectCleanRegions, mark_data_region_dirty) |
906 | { | |
907 | ObjectCleanRegions clean_regions; | |
908 | uint64_t offset_1, len_1, offset_2, len_2; | |
909 | offset_1 = 4096; | |
910 | len_1 = 8192; | |
911 | offset_2 = 40960; | |
912 | len_2 = 4096; | |
913 | ||
914 | interval_set<uint64_t> expect_dirty_region; | |
915 | EXPECT_EQ(expect_dirty_region, clean_regions.get_dirty_regions()); | |
916 | expect_dirty_region.insert(offset_1, len_1); | |
917 | expect_dirty_region.insert(offset_2, len_2); | |
918 | ||
919 | clean_regions.mark_data_region_dirty(offset_1, len_1); | |
920 | clean_regions.mark_data_region_dirty(offset_2, len_2); | |
921 | EXPECT_EQ(expect_dirty_region, clean_regions.get_dirty_regions()); | |
922 | } | |
923 | ||
924 | TEST(ObjectCleanRegions, mark_omap_dirty) | |
925 | { | |
926 | ObjectCleanRegions clean_regions; | |
927 | ||
928 | EXPECT_FALSE(clean_regions.omap_is_dirty()); | |
929 | clean_regions.mark_omap_dirty(); | |
930 | EXPECT_TRUE(clean_regions.omap_is_dirty()); | |
931 | } | |
932 | ||
933 | TEST(ObjectCleanRegions, merge) | |
934 | { | |
935 | ObjectCleanRegions cr1, cr2; | |
936 | interval_set<uint64_t> cr1_expect; | |
937 | interval_set<uint64_t> cr2_expect; | |
938 | ASSERT_EQ(cr1_expect, cr1.get_dirty_regions()); | |
939 | ASSERT_EQ(cr2_expect, cr2.get_dirty_regions()); | |
940 | ||
941 | cr1.mark_data_region_dirty(4096, 4096); | |
942 | cr1_expect.insert(4096, 4096); | |
943 | ASSERT_EQ(cr1_expect, cr1.get_dirty_regions()); | |
944 | cr1.mark_data_region_dirty(12288, 8192); | |
945 | cr1_expect.insert(12288, 8192); | |
946 | ASSERT_TRUE(cr1_expect.subset_of(cr1.get_dirty_regions())); | |
947 | cr1.mark_data_region_dirty(32768, 10240); | |
948 | cr1_expect.insert(32768, 10240); | |
949 | cr1_expect.erase(4096, 4096); | |
950 | ASSERT_TRUE(cr1_expect.subset_of(cr1.get_dirty_regions())); | |
951 | ||
952 | cr2.mark_data_region_dirty(20480, 12288); | |
953 | cr2_expect.insert(20480, 12288); | |
954 | ASSERT_EQ(cr2_expect, cr2.get_dirty_regions()); | |
955 | cr2.mark_data_region_dirty(102400, 4096); | |
956 | cr2_expect.insert(102400, 4096); | |
957 | cr2.mark_data_region_dirty(204800, 8192); | |
958 | cr2_expect.insert(204800, 8192); | |
959 | cr2.mark_data_region_dirty(409600, 4096); | |
960 | cr2_expect.insert(409600, 4096); | |
961 | ASSERT_TRUE(cr2_expect.subset_of(cr2.get_dirty_regions())); | |
962 | ||
963 | ASSERT_FALSE(cr2.omap_is_dirty()); | |
964 | cr2.mark_omap_dirty(); | |
965 | ASSERT_FALSE(cr1.omap_is_dirty()); | |
966 | ASSERT_TRUE(cr2.omap_is_dirty()); | |
967 | ||
968 | cr1.merge(cr2); | |
969 | cr1_expect.insert(204800, 8192); | |
970 | ASSERT_TRUE(cr1_expect.subset_of(cr1.get_dirty_regions())); | |
971 | ASSERT_TRUE(cr1.omap_is_dirty()); | |
972 | } | |
973 | ||
7c673cae FG |
974 | TEST(pg_missing_t, constructor) |
975 | { | |
976 | pg_missing_t missing; | |
977 | EXPECT_EQ((unsigned int)0, missing.num_missing()); | |
978 | EXPECT_FALSE(missing.have_missing()); | |
979 | } | |
980 | ||
981 | TEST(pg_missing_t, have_missing) | |
982 | { | |
983 | hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); | |
984 | pg_missing_t missing; | |
985 | EXPECT_FALSE(missing.have_missing()); | |
c07f9fc5 | 986 | missing.add(oid, eversion_t(), eversion_t(), false); |
7c673cae FG |
987 | EXPECT_TRUE(missing.have_missing()); |
988 | } | |
989 | ||
990 | TEST(pg_missing_t, claim) | |
991 | { | |
992 | hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); | |
993 | pg_missing_t missing; | |
994 | EXPECT_FALSE(missing.have_missing()); | |
c07f9fc5 | 995 | missing.add(oid, eversion_t(), eversion_t(), false); |
7c673cae FG |
996 | EXPECT_TRUE(missing.have_missing()); |
997 | ||
998 | pg_missing_t other; | |
999 | EXPECT_FALSE(other.have_missing()); | |
1000 | ||
f67539c2 | 1001 | other.claim(std::move(missing)); |
7c673cae FG |
1002 | EXPECT_TRUE(other.have_missing()); |
1003 | } | |
1004 | ||
1005 | TEST(pg_missing_t, is_missing) | |
1006 | { | |
1007 | // pg_missing_t::is_missing(const hobject_t& oid) const | |
1008 | { | |
1009 | hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); | |
1010 | pg_missing_t missing; | |
1011 | EXPECT_FALSE(missing.is_missing(oid)); | |
c07f9fc5 | 1012 | missing.add(oid, eversion_t(), eversion_t(), false); |
7c673cae FG |
1013 | EXPECT_TRUE(missing.is_missing(oid)); |
1014 | } | |
1015 | ||
1016 | // bool pg_missing_t::is_missing(const hobject_t& oid, eversion_t v) const | |
1017 | { | |
1018 | hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); | |
1019 | pg_missing_t missing; | |
1020 | eversion_t need(10,5); | |
1021 | EXPECT_FALSE(missing.is_missing(oid, eversion_t())); | |
c07f9fc5 | 1022 | missing.add(oid, need, eversion_t(), false); |
7c673cae FG |
1023 | EXPECT_TRUE(missing.is_missing(oid)); |
1024 | EXPECT_FALSE(missing.is_missing(oid, eversion_t())); | |
1025 | EXPECT_TRUE(missing.is_missing(oid, need)); | |
1026 | } | |
1027 | } | |
1028 | ||
7c673cae FG |
1029 | TEST(pg_missing_t, add_next_event) |
1030 | { | |
1031 | hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); | |
1032 | hobject_t oid_other(object_t("other"), "key", 9123, 9456, 0, ""); | |
1033 | eversion_t version(10,5); | |
1034 | eversion_t prior_version(3,4); | |
1035 | pg_log_entry_t sample_e(pg_log_entry_t::DELETE, oid, version, prior_version, | |
1036 | 0, osd_reqid_t(entity_name_t::CLIENT(777), 8, 999), | |
1037 | utime_t(8,9), 0); | |
1038 | ||
1039 | // new object (MODIFY) | |
1040 | { | |
1041 | pg_missing_t missing; | |
1042 | pg_log_entry_t e = sample_e; | |
1043 | ||
1044 | e.op = pg_log_entry_t::MODIFY; | |
1045 | e.prior_version = eversion_t(); | |
1046 | EXPECT_TRUE(e.is_update()); | |
1047 | EXPECT_TRUE(e.object_is_indexed()); | |
1048 | EXPECT_TRUE(e.reqid_is_indexed()); | |
1049 | EXPECT_FALSE(missing.is_missing(oid)); | |
1050 | missing.add_next_event(e); | |
1051 | EXPECT_TRUE(missing.is_missing(oid)); | |
1052 | EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have); | |
1053 | EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version)); | |
1054 | EXPECT_EQ(1U, missing.num_missing()); | |
1055 | EXPECT_EQ(1U, missing.get_rmissing().size()); | |
1056 | ||
1057 | // adding the same object replaces the previous one | |
1058 | missing.add_next_event(e); | |
1059 | EXPECT_TRUE(missing.is_missing(oid)); | |
1060 | EXPECT_EQ(1U, missing.num_missing()); | |
1061 | EXPECT_EQ(1U, missing.get_rmissing().size()); | |
1062 | } | |
1063 | ||
1064 | // new object (CLONE) | |
1065 | { | |
1066 | pg_missing_t missing; | |
1067 | pg_log_entry_t e = sample_e; | |
1068 | ||
1069 | e.op = pg_log_entry_t::CLONE; | |
1070 | e.prior_version = eversion_t(); | |
1071 | EXPECT_TRUE(e.is_clone()); | |
1072 | EXPECT_TRUE(e.object_is_indexed()); | |
1073 | EXPECT_FALSE(e.reqid_is_indexed()); | |
1074 | EXPECT_FALSE(missing.is_missing(oid)); | |
1075 | missing.add_next_event(e); | |
1076 | EXPECT_TRUE(missing.is_missing(oid)); | |
1077 | EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have); | |
1078 | EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version)); | |
1079 | EXPECT_EQ(1U, missing.num_missing()); | |
1080 | EXPECT_EQ(1U, missing.get_rmissing().size()); | |
1081 | ||
1082 | // adding the same object replaces the previous one | |
1083 | missing.add_next_event(e); | |
1084 | EXPECT_TRUE(missing.is_missing(oid)); | |
1085 | EXPECT_EQ(1U, missing.num_missing()); | |
1086 | EXPECT_EQ(1U, missing.get_rmissing().size()); | |
1087 | } | |
1088 | ||
1089 | // existing object (MODIFY) | |
1090 | { | |
1091 | pg_missing_t missing; | |
1092 | pg_log_entry_t e = sample_e; | |
1093 | ||
1094 | e.op = pg_log_entry_t::MODIFY; | |
1095 | e.prior_version = eversion_t(); | |
1096 | EXPECT_TRUE(e.is_update()); | |
1097 | EXPECT_TRUE(e.object_is_indexed()); | |
1098 | EXPECT_TRUE(e.reqid_is_indexed()); | |
1099 | EXPECT_FALSE(missing.is_missing(oid)); | |
1100 | missing.add_next_event(e); | |
1101 | EXPECT_TRUE(missing.is_missing(oid)); | |
1102 | EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have); | |
1103 | EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version)); | |
1104 | EXPECT_EQ(1U, missing.num_missing()); | |
1105 | EXPECT_EQ(1U, missing.get_rmissing().size()); | |
1106 | ||
1107 | // adding the same object with a different version | |
1108 | e.prior_version = prior_version; | |
1109 | missing.add_next_event(e); | |
1110 | EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have); | |
1111 | EXPECT_TRUE(missing.is_missing(oid)); | |
1112 | EXPECT_EQ(1U, missing.num_missing()); | |
1113 | EXPECT_EQ(1U, missing.get_rmissing().size()); | |
1114 | } | |
1115 | ||
1116 | // object with prior version (MODIFY) | |
1117 | { | |
1118 | pg_missing_t missing; | |
1119 | pg_log_entry_t e = sample_e; | |
1120 | ||
1121 | e.op = pg_log_entry_t::MODIFY; | |
1122 | EXPECT_TRUE(e.is_update()); | |
1123 | EXPECT_TRUE(e.object_is_indexed()); | |
1124 | EXPECT_TRUE(e.reqid_is_indexed()); | |
1125 | EXPECT_FALSE(missing.is_missing(oid)); | |
1126 | missing.add_next_event(e); | |
1127 | EXPECT_TRUE(missing.is_missing(oid)); | |
1128 | EXPECT_EQ(prior_version, missing.get_items().at(oid).have); | |
1129 | EXPECT_EQ(version, missing.get_items().at(oid).need); | |
1130 | EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version)); | |
1131 | EXPECT_EQ(1U, missing.num_missing()); | |
1132 | EXPECT_EQ(1U, missing.get_rmissing().size()); | |
1133 | } | |
1134 | ||
7c673cae FG |
1135 | // adding a DELETE matching an existing event |
1136 | { | |
1137 | pg_missing_t missing; | |
1138 | pg_log_entry_t e = sample_e; | |
1139 | ||
1140 | e.op = pg_log_entry_t::MODIFY; | |
1141 | EXPECT_TRUE(e.is_update()); | |
1142 | EXPECT_TRUE(e.object_is_indexed()); | |
1143 | EXPECT_TRUE(e.reqid_is_indexed()); | |
1144 | EXPECT_FALSE(missing.is_missing(oid)); | |
1145 | missing.add_next_event(e); | |
1146 | EXPECT_TRUE(missing.is_missing(oid)); | |
1147 | ||
1148 | e.op = pg_log_entry_t::DELETE; | |
1149 | EXPECT_TRUE(e.is_delete()); | |
1150 | missing.add_next_event(e); | |
c07f9fc5 FG |
1151 | EXPECT_TRUE(missing.is_missing(oid)); |
1152 | EXPECT_TRUE(missing.get_items().at(oid).is_delete()); | |
1153 | EXPECT_EQ(prior_version, missing.get_items().at(oid).have); | |
1154 | EXPECT_EQ(version, missing.get_items().at(oid).need); | |
1155 | EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version)); | |
1156 | EXPECT_EQ(1U, missing.num_missing()); | |
1157 | EXPECT_EQ(1U, missing.get_rmissing().size()); | |
7c673cae FG |
1158 | } |
1159 | ||
c07f9fc5 | 1160 | // adding a LOST_DELETE after an existing event |
7c673cae FG |
1161 | { |
1162 | pg_missing_t missing; | |
1163 | pg_log_entry_t e = sample_e; | |
1164 | ||
c07f9fc5 FG |
1165 | e.op = pg_log_entry_t::MODIFY; |
1166 | EXPECT_TRUE(e.is_update()); | |
1167 | EXPECT_TRUE(e.object_is_indexed()); | |
7c673cae FG |
1168 | EXPECT_TRUE(e.reqid_is_indexed()); |
1169 | EXPECT_FALSE(missing.is_missing(oid)); | |
1170 | missing.add_next_event(e); | |
7c673cae | 1171 | EXPECT_TRUE(missing.is_missing(oid)); |
c07f9fc5 | 1172 | EXPECT_FALSE(missing.get_items().at(oid).is_delete()); |
7c673cae | 1173 | |
c07f9fc5 FG |
1174 | e.op = pg_log_entry_t::LOST_DELETE; |
1175 | e.version.version++; | |
1176 | EXPECT_TRUE(e.is_delete()); | |
1177 | missing.add_next_event(e); | |
7c673cae | 1178 | EXPECT_TRUE(missing.is_missing(oid)); |
c07f9fc5 FG |
1179 | EXPECT_TRUE(missing.get_items().at(oid).is_delete()); |
1180 | EXPECT_EQ(prior_version, missing.get_items().at(oid).have); | |
1181 | EXPECT_EQ(e.version, missing.get_items().at(oid).need); | |
1182 | EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version)); | |
1183 | EXPECT_EQ(1U, missing.num_missing()); | |
1184 | EXPECT_EQ(1U, missing.get_rmissing().size()); | |
7c673cae FG |
1185 | } |
1186 | } | |
1187 | ||
1188 | TEST(pg_missing_t, revise_need) | |
1189 | { | |
1190 | hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); | |
1191 | pg_missing_t missing; | |
1192 | // create a new entry | |
1193 | EXPECT_FALSE(missing.is_missing(oid)); | |
1194 | eversion_t need(10,10); | |
c07f9fc5 | 1195 | missing.revise_need(oid, need, false); |
7c673cae FG |
1196 | EXPECT_TRUE(missing.is_missing(oid)); |
1197 | EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have); | |
1198 | EXPECT_EQ(need, missing.get_items().at(oid).need); | |
1199 | // update an existing entry and preserve have | |
1200 | eversion_t have(1,1); | |
1201 | missing.revise_have(oid, have); | |
1202 | eversion_t new_need(10,12); | |
1203 | EXPECT_EQ(have, missing.get_items().at(oid).have); | |
c07f9fc5 | 1204 | missing.revise_need(oid, new_need, false); |
7c673cae FG |
1205 | EXPECT_EQ(have, missing.get_items().at(oid).have); |
1206 | EXPECT_EQ(new_need, missing.get_items().at(oid).need); | |
1207 | } | |
1208 | ||
1209 | TEST(pg_missing_t, revise_have) | |
1210 | { | |
1211 | hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); | |
1212 | pg_missing_t missing; | |
1213 | // a non existing entry means noop | |
1214 | EXPECT_FALSE(missing.is_missing(oid)); | |
1215 | eversion_t have(1,1); | |
1216 | missing.revise_have(oid, have); | |
1217 | EXPECT_FALSE(missing.is_missing(oid)); | |
1218 | // update an existing entry | |
1219 | eversion_t need(10,12); | |
c07f9fc5 | 1220 | missing.add(oid, need, have, false); |
7c673cae FG |
1221 | EXPECT_TRUE(missing.is_missing(oid)); |
1222 | eversion_t new_have(2,2); | |
1223 | EXPECT_EQ(have, missing.get_items().at(oid).have); | |
1224 | missing.revise_have(oid, new_have); | |
1225 | EXPECT_EQ(new_have, missing.get_items().at(oid).have); | |
1226 | EXPECT_EQ(need, missing.get_items().at(oid).need); | |
1227 | } | |
1228 | ||
1229 | TEST(pg_missing_t, add) | |
1230 | { | |
1231 | hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); | |
1232 | pg_missing_t missing; | |
1233 | EXPECT_FALSE(missing.is_missing(oid)); | |
1234 | eversion_t have(1,1); | |
1235 | eversion_t need(10,10); | |
c07f9fc5 | 1236 | missing.add(oid, need, have, false); |
7c673cae FG |
1237 | EXPECT_TRUE(missing.is_missing(oid)); |
1238 | EXPECT_EQ(have, missing.get_items().at(oid).have); | |
1239 | EXPECT_EQ(need, missing.get_items().at(oid).need); | |
1240 | } | |
1241 | ||
1242 | TEST(pg_missing_t, rm) | |
1243 | { | |
1244 | // void pg_missing_t::rm(const hobject_t& oid, eversion_t v) | |
1245 | { | |
1246 | hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); | |
1247 | pg_missing_t missing; | |
1248 | EXPECT_FALSE(missing.is_missing(oid)); | |
1249 | epoch_t epoch = 10; | |
1250 | eversion_t need(epoch,10); | |
c07f9fc5 | 1251 | missing.add(oid, need, eversion_t(), false); |
7c673cae FG |
1252 | EXPECT_TRUE(missing.is_missing(oid)); |
1253 | // rm of an older version is a noop | |
1254 | missing.rm(oid, eversion_t(epoch / 2,20)); | |
1255 | EXPECT_TRUE(missing.is_missing(oid)); | |
1256 | // rm of a later version removes the object | |
1257 | missing.rm(oid, eversion_t(epoch * 2,20)); | |
1258 | EXPECT_FALSE(missing.is_missing(oid)); | |
1259 | } | |
1260 | // void pg_missing_t::rm(const std::map<hobject_t, pg_missing_item>::iterator &m) | |
1261 | { | |
1262 | hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); | |
1263 | pg_missing_t missing; | |
1264 | EXPECT_FALSE(missing.is_missing(oid)); | |
c07f9fc5 | 1265 | missing.add(oid, eversion_t(), eversion_t(), false); |
7c673cae FG |
1266 | EXPECT_TRUE(missing.is_missing(oid)); |
1267 | auto m = missing.get_items().find(oid); | |
1268 | missing.rm(m); | |
1269 | EXPECT_FALSE(missing.is_missing(oid)); | |
1270 | } | |
1271 | } | |
1272 | ||
1273 | TEST(pg_missing_t, got) | |
1274 | { | |
1275 | // void pg_missing_t::got(const hobject_t& oid, eversion_t v) | |
1276 | { | |
1277 | hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); | |
1278 | pg_missing_t missing; | |
1279 | // assert if the oid does not exist | |
1280 | { | |
1281 | PrCtl unset_dumpable; | |
1282 | EXPECT_DEATH(missing.got(oid, eversion_t()), ""); | |
1283 | } | |
1284 | EXPECT_FALSE(missing.is_missing(oid)); | |
1285 | epoch_t epoch = 10; | |
1286 | eversion_t need(epoch,10); | |
c07f9fc5 | 1287 | missing.add(oid, need, eversion_t(), false); |
7c673cae FG |
1288 | EXPECT_TRUE(missing.is_missing(oid)); |
1289 | // assert if that the version to be removed is lower than the version of the object | |
1290 | { | |
1291 | PrCtl unset_dumpable; | |
1292 | EXPECT_DEATH(missing.got(oid, eversion_t(epoch / 2,20)), ""); | |
1293 | } | |
1294 | // remove of a later version removes the object | |
1295 | missing.got(oid, eversion_t(epoch * 2,20)); | |
1296 | EXPECT_FALSE(missing.is_missing(oid)); | |
1297 | } | |
1298 | // void pg_missing_t::got(const std::map<hobject_t, pg_missing_item>::iterator &m) | |
1299 | { | |
1300 | hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); | |
1301 | pg_missing_t missing; | |
1302 | EXPECT_FALSE(missing.is_missing(oid)); | |
c07f9fc5 | 1303 | missing.add(oid, eversion_t(), eversion_t(), false); |
7c673cae FG |
1304 | EXPECT_TRUE(missing.is_missing(oid)); |
1305 | auto m = missing.get_items().find(oid); | |
1306 | missing.got(m); | |
1307 | EXPECT_FALSE(missing.is_missing(oid)); | |
1308 | } | |
1309 | } | |
1310 | ||
1311 | TEST(pg_missing_t, split_into) | |
1312 | { | |
1313 | uint32_t hash1 = 1; | |
1314 | hobject_t oid1(object_t("objname"), "key1", 123, hash1, 0, ""); | |
1315 | uint32_t hash2 = 2; | |
1316 | hobject_t oid2(object_t("objname"), "key2", 123, hash2, 0, ""); | |
1317 | pg_missing_t missing; | |
c07f9fc5 FG |
1318 | missing.add(oid1, eversion_t(), eversion_t(), false); |
1319 | missing.add(oid2, eversion_t(), eversion_t(), false); | |
7c673cae FG |
1320 | pg_t child_pgid; |
1321 | child_pgid.m_seed = 1; | |
1322 | pg_missing_t child; | |
1323 | unsigned split_bits = 1; | |
1324 | missing.split_into(child_pgid, split_bits, &child); | |
1325 | EXPECT_TRUE(child.is_missing(oid1)); | |
1326 | EXPECT_FALSE(child.is_missing(oid2)); | |
1327 | EXPECT_FALSE(missing.is_missing(oid1)); | |
1328 | EXPECT_TRUE(missing.is_missing(oid2)); | |
1329 | } | |
1330 | ||
7c673cae FG |
1331 | TEST(pg_pool_t_test, get_pg_num_divisor) { |
1332 | pg_pool_t p; | |
1333 | p.set_pg_num(16); | |
1334 | p.set_pgp_num(16); | |
1335 | ||
1336 | for (int i = 0; i < 16; ++i) | |
1337 | ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(i, 1))); | |
1338 | ||
1339 | p.set_pg_num(12); | |
1340 | p.set_pgp_num(12); | |
31f18b77 | 1341 | |
7c673cae FG |
1342 | ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(0, 1))); |
1343 | ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(1, 1))); | |
1344 | ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(2, 1))); | |
1345 | ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(3, 1))); | |
1346 | ASSERT_EQ(8u, p.get_pg_num_divisor(pg_t(4, 1))); | |
1347 | ASSERT_EQ(8u, p.get_pg_num_divisor(pg_t(5, 1))); | |
1348 | ASSERT_EQ(8u, p.get_pg_num_divisor(pg_t(6, 1))); | |
1349 | ASSERT_EQ(8u, p.get_pg_num_divisor(pg_t(7, 1))); | |
1350 | ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(8, 1))); | |
1351 | ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(9, 1))); | |
1352 | ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(10, 1))); | |
1353 | ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(11, 1))); | |
1354 | } | |
1355 | ||
1356 | TEST(pg_pool_t_test, get_random_pg_position) { | |
1357 | srand(getpid()); | |
1358 | for (int i = 0; i < 100; ++i) { | |
1359 | pg_pool_t p; | |
1360 | p.set_pg_num(1 + (rand() % 1000)); | |
1361 | p.set_pgp_num(p.get_pg_num()); | |
1362 | pg_t pgid(rand() % p.get_pg_num(), 1); | |
1363 | uint32_t h = p.get_random_pg_position(pgid, rand()); | |
1364 | uint32_t ps = p.raw_hash_to_pg(h); | |
1365 | cout << p.get_pg_num() << " " << pgid << ": " | |
1366 | << h << " -> " << pg_t(ps, 1) << std::endl; | |
1367 | ASSERT_EQ(pgid.ps(), ps); | |
1368 | } | |
1369 | } | |
1370 | ||
1371 | TEST(shard_id_t, iostream) { | |
1372 | set<shard_id_t> shards; | |
1373 | shards.insert(shard_id_t(0)); | |
1374 | shards.insert(shard_id_t(1)); | |
1375 | shards.insert(shard_id_t(2)); | |
1376 | ostringstream out; | |
1377 | out << shards; | |
1378 | ASSERT_EQ(out.str(), "0,1,2"); | |
1379 | ||
1380 | shard_id_t noshard = shard_id_t::NO_SHARD; | |
1381 | shard_id_t zero(0); | |
1382 | ASSERT_GT(zero, noshard); | |
1383 | } | |
1384 | ||
1385 | TEST(spg_t, parse) { | |
1386 | spg_t a(pg_t(1,2), shard_id_t::NO_SHARD); | |
1387 | spg_t aa, bb; | |
1388 | spg_t b(pg_t(3,2), shard_id_t(2)); | |
1389 | std::string s = stringify(a); | |
1390 | ASSERT_TRUE(aa.parse(s.c_str())); | |
1391 | ASSERT_EQ(a, aa); | |
1392 | ||
1393 | s = stringify(b); | |
1394 | ASSERT_TRUE(bb.parse(s.c_str())); | |
1395 | ASSERT_EQ(b, bb); | |
1396 | } | |
1397 | ||
1398 | TEST(coll_t, parse) { | |
1399 | const char *ok[] = { | |
1400 | "meta", | |
1401 | "1.2_head", | |
1402 | "1.2_TEMP", | |
1403 | "1.2s3_head", | |
1404 | "1.3s2_TEMP", | |
1405 | "1.2s0_head", | |
1406 | 0 | |
1407 | }; | |
1408 | const char *bad[] = { | |
1409 | "foo", | |
1410 | "1.2_food", | |
1411 | "1.2_head ", | |
1412 | //" 1.2_head", // hrm, this parses, which is not ideal.. pg_t's fault? | |
1413 | "1.2_temp", | |
1414 | "1.2_HEAD", | |
1415 | "1.xS3_HEAD", | |
1416 | "1.2s_HEAD", | |
1417 | "1.2sfoo_HEAD", | |
1418 | 0 | |
1419 | }; | |
1420 | coll_t a; | |
1421 | for (int i = 0; ok[i]; ++i) { | |
1422 | cout << "check ok " << ok[i] << std::endl; | |
1423 | ASSERT_TRUE(a.parse(ok[i])); | |
1424 | ASSERT_EQ(string(ok[i]), a.to_str()); | |
1425 | } | |
1426 | for (int i = 0; bad[i]; ++i) { | |
1427 | cout << "check bad " << bad[i] << std::endl; | |
1428 | ASSERT_FALSE(a.parse(bad[i])); | |
1429 | } | |
1430 | } | |
1431 | ||
1432 | TEST(coll_t, temp) { | |
1433 | spg_t pgid; | |
1434 | coll_t foo(pgid); | |
1435 | ASSERT_EQ(foo.to_str(), string("0.0_head")); | |
1436 | ||
1437 | coll_t temp = foo.get_temp(); | |
1438 | ASSERT_EQ(temp.to_str(), string("0.0_TEMP")); | |
1439 | ||
1440 | spg_t pgid2; | |
1441 | ASSERT_TRUE(temp.is_temp()); | |
1442 | ASSERT_TRUE(temp.is_temp(&pgid2)); | |
1443 | ASSERT_EQ(pgid, pgid2); | |
1444 | } | |
1445 | ||
1446 | TEST(coll_t, assigment) { | |
1447 | spg_t pgid; | |
1448 | coll_t right(pgid); | |
1449 | ASSERT_EQ(right.to_str(), string("0.0_head")); | |
1450 | ||
1451 | coll_t left, middle; | |
1452 | ||
1453 | ASSERT_EQ(left.to_str(), string("meta")); | |
1454 | ASSERT_EQ(middle.to_str(), string("meta")); | |
1455 | ||
1456 | left = middle = right; | |
1457 | ||
1458 | ASSERT_EQ(left.to_str(), string("0.0_head")); | |
1459 | ASSERT_EQ(middle.to_str(), string("0.0_head")); | |
1460 | ||
1461 | ASSERT_NE(middle.c_str(), right.c_str()); | |
1462 | ASSERT_NE(left.c_str(), middle.c_str()); | |
1463 | } | |
1464 | ||
1465 | TEST(hobject_t, parse) { | |
1466 | const char *v[] = { | |
1467 | "MIN", | |
1468 | "MAX", | |
1469 | "-1:60c2fa6d:::inc_osdmap.1:0", | |
1470 | "-1:60c2fa6d:::inc_osdmap.1:333", | |
1471 | "0:00000000::::head", | |
1472 | "1:00000000:nspace:key:obj:head", | |
1473 | "-40:00000000:nspace::obj:head", | |
1474 | "20:00000000::key:obj:head", | |
1475 | "20:00000000:::o%fdj:head", | |
1476 | "20:00000000:::o%02fdj:head", | |
1477 | "20:00000000:::_zero_%00_:head", | |
1478 | NULL | |
1479 | }; | |
1480 | ||
1481 | for (unsigned i=0; v[i]; ++i) { | |
1482 | hobject_t o; | |
1483 | bool b = o.parse(v[i]); | |
1484 | if (!b) { | |
1485 | cout << "failed to parse " << v[i] << std::endl; | |
1486 | ASSERT_TRUE(false); | |
1487 | } | |
1488 | string s = stringify(o); | |
1489 | if (s != v[i]) { | |
1490 | cout << v[i] << " -> " << o << " -> " << s << std::endl; | |
1491 | ASSERT_EQ(s, string(v[i])); | |
1492 | } | |
1493 | } | |
1494 | } | |
1495 | ||
1496 | TEST(ghobject_t, cmp) { | |
1497 | ghobject_t min; | |
1498 | ghobject_t sep; | |
1499 | sep.set_shard(shard_id_t(1)); | |
1500 | sep.hobj.pool = -1; | |
1501 | cout << min << " < " << sep << std::endl; | |
1502 | ASSERT_TRUE(min < sep); | |
1503 | ||
1504 | sep.set_shard(shard_id_t::NO_SHARD); | |
1505 | cout << "sep shard " << sep.shard_id << std::endl; | |
1506 | ghobject_t o(hobject_t(object_t(), string(), CEPH_NOSNAP, 0x42, | |
1507 | 1, string())); | |
1508 | cout << "o " << o << std::endl; | |
1509 | ASSERT_TRUE(o > sep); | |
1510 | } | |
1511 | ||
1512 | TEST(ghobject_t, parse) { | |
1513 | const char *v[] = { | |
1514 | "GHMIN", | |
1515 | "GHMAX", | |
1516 | "13#0:00000000::::head#", | |
1517 | "13#0:00000000::::head#deadbeef", | |
1518 | "#-1:60c2fa6d:::inc_osdmap.1:333#deadbeef", | |
1519 | "#-1:60c2fa6d:::inc%02osdmap.1:333#deadbeef", | |
1520 | "#-1:60c2fa6d:::inc_osdmap.1:333#", | |
1521 | "1#MIN#deadbeefff", | |
1522 | "1#MAX#", | |
1523 | "#MAX#123", | |
1524 | "#-40:00000000:nspace::obj:head#", | |
1525 | NULL | |
1526 | }; | |
1527 | ||
1528 | for (unsigned i=0; v[i]; ++i) { | |
1529 | ghobject_t o; | |
1530 | bool b = o.parse(v[i]); | |
1531 | if (!b) { | |
1532 | cout << "failed to parse " << v[i] << std::endl; | |
1533 | ASSERT_TRUE(false); | |
1534 | } | |
1535 | string s = stringify(o); | |
1536 | if (s != v[i]) { | |
1537 | cout << v[i] << " -> " << o << " -> " << s << std::endl; | |
1538 | ASSERT_EQ(s, string(v[i])); | |
1539 | } | |
1540 | } | |
1541 | } | |
1542 | ||
1543 | TEST(pool_opts_t, invalid_opt) { | |
1544 | EXPECT_FALSE(pool_opts_t::is_opt_name("INVALID_OPT")); | |
1545 | PrCtl unset_dumpable; | |
1546 | EXPECT_DEATH(pool_opts_t::get_opt_desc("INVALID_OPT"), ""); | |
1547 | } | |
1548 | ||
1549 | TEST(pool_opts_t, scrub_min_interval) { | |
1550 | EXPECT_TRUE(pool_opts_t::is_opt_name("scrub_min_interval")); | |
1551 | EXPECT_EQ(pool_opts_t::get_opt_desc("scrub_min_interval"), | |
1552 | pool_opts_t::opt_desc_t(pool_opts_t::SCRUB_MIN_INTERVAL, | |
1553 | pool_opts_t::DOUBLE)); | |
1554 | ||
1555 | pool_opts_t opts; | |
1556 | EXPECT_FALSE(opts.is_set(pool_opts_t::SCRUB_MIN_INTERVAL)); | |
1557 | { | |
1558 | PrCtl unset_dumpable; | |
1559 | EXPECT_DEATH(opts.get(pool_opts_t::SCRUB_MIN_INTERVAL), ""); | |
1560 | } | |
1561 | double val; | |
1562 | EXPECT_FALSE(opts.get(pool_opts_t::SCRUB_MIN_INTERVAL, &val)); | |
1563 | opts.set(pool_opts_t::SCRUB_MIN_INTERVAL, static_cast<double>(2015)); | |
1564 | EXPECT_TRUE(opts.get(pool_opts_t::SCRUB_MIN_INTERVAL, &val)); | |
1565 | EXPECT_EQ(val, 2015); | |
1566 | opts.unset(pool_opts_t::SCRUB_MIN_INTERVAL); | |
1567 | EXPECT_FALSE(opts.is_set(pool_opts_t::SCRUB_MIN_INTERVAL)); | |
1568 | } | |
1569 | ||
1570 | TEST(pool_opts_t, scrub_max_interval) { | |
1571 | EXPECT_TRUE(pool_opts_t::is_opt_name("scrub_max_interval")); | |
1572 | EXPECT_EQ(pool_opts_t::get_opt_desc("scrub_max_interval"), | |
1573 | pool_opts_t::opt_desc_t(pool_opts_t::SCRUB_MAX_INTERVAL, | |
1574 | pool_opts_t::DOUBLE)); | |
1575 | ||
1576 | pool_opts_t opts; | |
1577 | EXPECT_FALSE(opts.is_set(pool_opts_t::SCRUB_MAX_INTERVAL)); | |
1578 | { | |
1579 | PrCtl unset_dumpable; | |
1580 | EXPECT_DEATH(opts.get(pool_opts_t::SCRUB_MAX_INTERVAL), ""); | |
1581 | } | |
1582 | double val; | |
1583 | EXPECT_FALSE(opts.get(pool_opts_t::SCRUB_MAX_INTERVAL, &val)); | |
1584 | opts.set(pool_opts_t::SCRUB_MAX_INTERVAL, static_cast<double>(2015)); | |
1585 | EXPECT_TRUE(opts.get(pool_opts_t::SCRUB_MAX_INTERVAL, &val)); | |
1586 | EXPECT_EQ(val, 2015); | |
1587 | opts.unset(pool_opts_t::SCRUB_MAX_INTERVAL); | |
1588 | EXPECT_FALSE(opts.is_set(pool_opts_t::SCRUB_MAX_INTERVAL)); | |
1589 | } | |
1590 | ||
1591 | TEST(pool_opts_t, deep_scrub_interval) { | |
1592 | EXPECT_TRUE(pool_opts_t::is_opt_name("deep_scrub_interval")); | |
1593 | EXPECT_EQ(pool_opts_t::get_opt_desc("deep_scrub_interval"), | |
1594 | pool_opts_t::opt_desc_t(pool_opts_t::DEEP_SCRUB_INTERVAL, | |
1595 | pool_opts_t::DOUBLE)); | |
1596 | ||
1597 | pool_opts_t opts; | |
1598 | EXPECT_FALSE(opts.is_set(pool_opts_t::DEEP_SCRUB_INTERVAL)); | |
1599 | { | |
1600 | PrCtl unset_dumpable; | |
1601 | EXPECT_DEATH(opts.get(pool_opts_t::DEEP_SCRUB_INTERVAL), ""); | |
1602 | } | |
1603 | double val; | |
1604 | EXPECT_FALSE(opts.get(pool_opts_t::DEEP_SCRUB_INTERVAL, &val)); | |
1605 | opts.set(pool_opts_t::DEEP_SCRUB_INTERVAL, static_cast<double>(2015)); | |
1606 | EXPECT_TRUE(opts.get(pool_opts_t::DEEP_SCRUB_INTERVAL, &val)); | |
1607 | EXPECT_EQ(val, 2015); | |
1608 | opts.unset(pool_opts_t::DEEP_SCRUB_INTERVAL); | |
1609 | EXPECT_FALSE(opts.is_set(pool_opts_t::DEEP_SCRUB_INTERVAL)); | |
1610 | } | |
1611 | ||
1612 | struct RequiredPredicate : IsPGRecoverablePredicate { | |
1613 | unsigned required_size; | |
11fdf7f2 | 1614 | explicit RequiredPredicate(unsigned required_size) : required_size(required_size) {} |
7c673cae FG |
1615 | bool operator()(const set<pg_shard_t> &have) const override { |
1616 | return have.size() >= required_size; | |
1617 | } | |
1618 | }; | |
1619 | ||
1620 | using namespace std; | |
1621 | struct MapPredicate { | |
1622 | map<int, pair<PastIntervals::osd_state_t, epoch_t>> states; | |
11fdf7f2 TL |
1623 | explicit MapPredicate( |
1624 | const vector<pair<int, pair<PastIntervals::osd_state_t, epoch_t>>> &_states) | |
7c673cae FG |
1625 | : states(_states.begin(), _states.end()) {} |
1626 | PastIntervals::osd_state_t operator()(epoch_t start, int osd, epoch_t *lost_at) { | |
1627 | auto val = states.at(osd); | |
1628 | if (lost_at) | |
1629 | *lost_at = val.second; | |
1630 | return val.first; | |
1631 | } | |
1632 | }; | |
1633 | ||
1634 | using sit = shard_id_t; | |
1635 | using PI = PastIntervals; | |
1636 | using pst = pg_shard_t; | |
1637 | using ival = PastIntervals::pg_interval_t; | |
1638 | using ivallst = std::list<ival>; | |
1639 | const int N = 0x7fffffff /* CRUSH_ITEM_NONE, can't import crush.h here */; | |
1640 | ||
1641 | struct PITest : ::testing::Test { | |
1642 | PITest() {} | |
1643 | void run( | |
1644 | bool ec_pool, | |
1645 | ivallst intervals, | |
1646 | epoch_t last_epoch_started, | |
1647 | unsigned min_to_peer, | |
1648 | vector<pair<int, pair<PastIntervals::osd_state_t, epoch_t>>> osd_states, | |
1649 | vector<int> up, | |
1650 | vector<int> acting, | |
1651 | set<pg_shard_t> probe, | |
1652 | set<int> down, | |
1653 | map<int, epoch_t> blocked_by, | |
1654 | bool pg_down) { | |
1655 | RequiredPredicate rec_pred(min_to_peer); | |
1656 | MapPredicate map_pred(osd_states); | |
1657 | ||
1658 | PI::PriorSet correct( | |
1659 | ec_pool, | |
1660 | probe, | |
1661 | down, | |
1662 | blocked_by, | |
1663 | pg_down, | |
1664 | new RequiredPredicate(rec_pred)); | |
1665 | ||
11fdf7f2 | 1666 | PastIntervals compact; |
7c673cae | 1667 | for (auto &&i: intervals) { |
7c673cae FG |
1668 | compact.add_interval(ec_pool, i); |
1669 | } | |
7c673cae FG |
1670 | PI::PriorSet compact_ps = compact.get_prior_set( |
1671 | ec_pool, | |
1672 | last_epoch_started, | |
1673 | new RequiredPredicate(rec_pred), | |
1674 | map_pred, | |
1675 | up, | |
1676 | acting, | |
1677 | nullptr); | |
7c673cae FG |
1678 | ASSERT_EQ(correct, compact_ps); |
1679 | } | |
1680 | }; | |
1681 | ||
1682 | TEST_F(PITest, past_intervals_rep) { | |
1683 | run( | |
1684 | /* ec_pool */ false, | |
1685 | /* intervals */ | |
1686 | { ival{{0, 1, 2}, {0, 1, 2}, 10, 20, true, 0, 0} | |
1687 | , ival{{ 1, 2}, { 1, 2}, 21, 30, true, 1, 1} | |
1688 | , ival{{ 2}, { 2}, 31, 35, false, 2, 2} | |
1689 | , ival{{0, 2}, {0, 2}, 36, 50, true, 0, 0} | |
1690 | }, | |
1691 | /* les */ 5, | |
1692 | /* min_peer */ 1, | |
1693 | /* osd states at end */ | |
1694 | { make_pair(0, make_pair(PI::UP , 0)) | |
1695 | , make_pair(1, make_pair(PI::UP , 0)) | |
1696 | , make_pair(2, make_pair(PI::DOWN , 0)) | |
1697 | }, | |
1698 | /* acting */ {0, 1 }, | |
1699 | /* up */ {0, 1 }, | |
1700 | /* probe */ {pst(0), pst(1)}, | |
1701 | /* down */ {2}, | |
1702 | /* blocked_by */ {}, | |
1703 | /* pg_down */ false); | |
1704 | } | |
1705 | ||
1706 | TEST_F(PITest, past_intervals_ec) { | |
1707 | run( | |
1708 | /* ec_pool */ true, | |
1709 | /* intervals */ | |
1710 | { ival{{0, 1, 2}, {0, 1, 2}, 10, 20, true, 0, 0} | |
1711 | , ival{{N, 1, 2}, {N, 1, 2}, 21, 30, true, 1, 1} | |
1712 | }, | |
1713 | /* les */ 5, | |
1714 | /* min_peer */ 2, | |
1715 | /* osd states at end */ | |
1716 | { make_pair(0, make_pair(PI::DOWN , 0)) | |
1717 | , make_pair(1, make_pair(PI::UP , 0)) | |
1718 | , make_pair(2, make_pair(PI::UP , 0)) | |
1719 | }, | |
1720 | /* acting */ {N, 1, 2}, | |
1721 | /* up */ {N, 1, 2}, | |
1722 | /* probe */ {pst(1, sit(1)), pst(2, sit(2))}, | |
1723 | /* down */ {0}, | |
1724 | /* blocked_by */ {}, | |
1725 | /* pg_down */ false); | |
1726 | } | |
1727 | ||
1728 | TEST_F(PITest, past_intervals_rep_down) { | |
1729 | run( | |
1730 | /* ec_pool */ false, | |
1731 | /* intervals */ | |
1732 | { ival{{0, 1, 2}, {0, 1, 2}, 10, 20, true, 0, 0} | |
1733 | , ival{{ 1, 2}, { 1, 2}, 21, 30, true, 1, 1} | |
1734 | , ival{{ 2}, { 2}, 31, 35, true, 2, 2} | |
1735 | , ival{{0, 2}, {0, 2}, 36, 50, true, 0, 0} | |
1736 | }, | |
1737 | /* les */ 5, | |
1738 | /* min_peer */ 1, | |
1739 | /* osd states at end */ | |
1740 | { make_pair(0, make_pair(PI::UP , 0)) | |
1741 | , make_pair(1, make_pair(PI::UP , 0)) | |
1742 | , make_pair(2, make_pair(PI::DOWN , 0)) | |
1743 | }, | |
1744 | /* acting */ {0, 1 }, | |
1745 | /* up */ {0, 1 }, | |
1746 | /* probe */ {pst(0), pst(1)}, | |
1747 | /* down */ {2}, | |
1748 | /* blocked_by */ {{2, 0}}, | |
1749 | /* pg_down */ true); | |
1750 | } | |
1751 | ||
1752 | TEST_F(PITest, past_intervals_ec_down) { | |
1753 | run( | |
1754 | /* ec_pool */ true, | |
1755 | /* intervals */ | |
1756 | { ival{{0, 1, 2}, {0, 1, 2}, 10, 20, true, 0, 0} | |
1757 | , ival{{N, 1, 2}, {N, 1, 2}, 21, 30, true, 1, 1} | |
1758 | , ival{{N, N, 2}, {N, N, 2}, 31, 35, false, 2, 2} | |
1759 | }, | |
1760 | /* les */ 5, | |
1761 | /* min_peer */ 2, | |
1762 | /* osd states at end */ | |
1763 | { make_pair(0, make_pair(PI::UP , 0)) | |
1764 | , make_pair(1, make_pair(PI::DOWN , 0)) | |
1765 | , make_pair(2, make_pair(PI::UP , 0)) | |
1766 | }, | |
1767 | /* acting */ {0, N, 2}, | |
1768 | /* up */ {0, N, 2}, | |
1769 | /* probe */ {pst(0, sit(0)), pst(2, sit(2))}, | |
1770 | /* down */ {1}, | |
1771 | /* blocked_by */ {{1, 0}}, | |
1772 | /* pg_down */ true); | |
1773 | } | |
1774 | ||
1775 | TEST_F(PITest, past_intervals_rep_no_subsets) { | |
1776 | run( | |
1777 | /* ec_pool */ false, | |
1778 | /* intervals */ | |
1779 | { ival{{0, 2}, {0, 2}, 10, 20, true, 0, 0} | |
1780 | , ival{{ 1, 2}, { 1, 2}, 21, 30, true, 1, 1} | |
1781 | , ival{{0, 1 }, {0, 1 }, 31, 35, true, 0, 0} | |
1782 | }, | |
1783 | /* les */ 5, | |
1784 | /* min_peer */ 1, | |
1785 | /* osd states at end */ | |
1786 | { make_pair(0, make_pair(PI::UP , 0)) | |
1787 | , make_pair(1, make_pair(PI::UP , 0)) | |
1788 | , make_pair(2, make_pair(PI::DOWN , 0)) | |
1789 | }, | |
1790 | /* acting */ {0, 1 }, | |
1791 | /* up */ {0, 1 }, | |
1792 | /* probe */ {pst(0), pst(1)}, | |
1793 | /* down */ {2}, | |
1794 | /* blocked_by */ {}, | |
1795 | /* pg_down */ false); | |
1796 | } | |
1797 | ||
1798 | TEST_F(PITest, past_intervals_ec_no_subsets) { | |
1799 | run( | |
1800 | /* ec_pool */ true, | |
1801 | /* intervals */ | |
1802 | { ival{{0, N, 2}, {0, N, 2}, 10, 20, true, 0, 0} | |
1803 | , ival{{N, 1, 2}, {N, 1, 2}, 21, 30, true, 1, 1} | |
1804 | , ival{{0, 1, N}, {0, 1, N}, 31, 35, true, 0, 0} | |
1805 | }, | |
1806 | /* les */ 5, | |
1807 | /* min_peer */ 2, | |
1808 | /* osd states at end */ | |
1809 | { make_pair(0, make_pair(PI::UP , 0)) | |
1810 | , make_pair(1, make_pair(PI::DOWN , 0)) | |
1811 | , make_pair(2, make_pair(PI::UP , 0)) | |
1812 | }, | |
1813 | /* acting */ {0, N, 2}, | |
1814 | /* up */ {0, N, 2}, | |
1815 | /* probe */ {pst(0, sit(0)), pst(2, sit(2))}, | |
1816 | /* down */ {1}, | |
1817 | /* blocked_by */ {{1, 0}}, | |
1818 | /* pg_down */ true); | |
1819 | } | |
1820 | ||
1821 | TEST_F(PITest, past_intervals_ec_no_subsets2) { | |
1822 | run( | |
1823 | /* ec_pool */ true, | |
1824 | /* intervals */ | |
1825 | { ival{{N, 1, 2}, {N, 1, 2}, 10, 20, true, 0, 0} | |
1826 | , ival{{0, N, 2}, {0, N, 2}, 21, 30, true, 1, 1} | |
1827 | , ival{{0, 3, N}, {0, 3, N}, 31, 35, true, 0, 0} | |
1828 | }, | |
1829 | /* les */ 31, | |
1830 | /* min_peer */ 2, | |
1831 | /* osd states at end */ | |
1832 | { make_pair(0, make_pair(PI::UP , 0)) | |
1833 | , make_pair(1, make_pair(PI::DOWN , 0)) | |
1834 | , make_pair(2, make_pair(PI::UP , 0)) | |
1835 | , make_pair(3, make_pair(PI::UP , 0)) | |
1836 | }, | |
1837 | /* acting */ {0, N, 2}, | |
1838 | /* up */ {0, N, 2}, | |
1839 | /* probe */ {pst(0, sit(0)), pst(2, sit(2)), pst(3, sit(1))}, | |
1840 | /* down */ {1}, | |
1841 | /* blocked_by */ {}, | |
1842 | /* pg_down */ false); | |
1843 | } | |
1844 | ||
1845 | TEST_F(PITest, past_intervals_rep_lost) { | |
1846 | run( | |
1847 | /* ec_pool */ false, | |
1848 | /* intervals */ | |
1849 | { ival{{0, 1, 2}, {0, 1, 2}, 10, 20, true, 0, 0} | |
1850 | , ival{{ 1, 2}, { 1, 2}, 21, 30, true, 1, 1} | |
1851 | , ival{{ 2}, { 2}, 31, 35, true, 2, 2} | |
1852 | , ival{{0, 2}, {0, 2}, 36, 50, true, 0, 0} | |
1853 | }, | |
1854 | /* les */ 5, | |
1855 | /* min_peer */ 1, | |
1856 | /* osd states at end */ | |
1857 | { make_pair(0, make_pair(PI::UP , 0)) | |
1858 | , make_pair(1, make_pair(PI::UP , 0)) | |
1859 | , make_pair(2, make_pair(PI::LOST , 55)) | |
1860 | }, | |
1861 | /* acting */ {0, 1 }, | |
1862 | /* up */ {0, 1 }, | |
1863 | /* probe */ {pst(0), pst(1)}, | |
1864 | /* down */ {2}, | |
1865 | /* blocked_by */ {}, | |
1866 | /* pg_down */ false); | |
1867 | } | |
1868 | ||
1869 | TEST_F(PITest, past_intervals_ec_lost) { | |
1870 | run( | |
1871 | /* ec_pool */ true, | |
1872 | /* intervals */ | |
1873 | { ival{{0, N, 2}, {0, N, 2}, 10, 20, true, 0, 0} | |
1874 | , ival{{N, 1, 2}, {N, 1, 2}, 21, 30, true, 1, 1} | |
1875 | , ival{{0, 1, N}, {0, 1, N}, 31, 35, true, 0, 0} | |
1876 | }, | |
1877 | /* les */ 5, | |
1878 | /* min_peer */ 2, | |
1879 | /* osd states at end */ | |
1880 | { make_pair(0, make_pair(PI::UP , 0)) | |
1881 | , make_pair(1, make_pair(PI::LOST , 36)) | |
1882 | , make_pair(2, make_pair(PI::UP , 0)) | |
1883 | }, | |
1884 | /* acting */ {0, N, 2}, | |
1885 | /* up */ {0, N, 2}, | |
1886 | /* probe */ {pst(0, sit(0)), pst(2, sit(2))}, | |
1887 | /* down */ {1}, | |
1888 | /* blocked_by */ {}, | |
1889 | /* pg_down */ false); | |
1890 | } | |
1891 | ||
f67539c2 TL |
1892 | void ci_ref_test( |
1893 | object_manifest_t l, | |
1894 | object_manifest_t to_remove, | |
1895 | object_manifest_t g, | |
1896 | object_ref_delta_t expected_delta) | |
1897 | { | |
1898 | { | |
1899 | object_ref_delta_t delta; | |
1900 | to_remove.calc_refs_to_drop_on_removal( | |
1901 | &l, | |
1902 | &g, | |
1903 | delta); | |
1904 | ASSERT_EQ( | |
1905 | expected_delta, | |
1906 | delta); | |
1907 | } | |
1908 | ||
1909 | // calc_refs_to_drop specifically handles nullptr identically to empty | |
1910 | // chunk_map | |
1911 | if (l.chunk_map.empty() || g.chunk_map.empty()) { | |
1912 | object_ref_delta_t delta; | |
1913 | to_remove.calc_refs_to_drop_on_removal( | |
1914 | l.chunk_map.empty() ? nullptr : &l, | |
1915 | g.chunk_map.empty() ? nullptr : &g, | |
1916 | delta); | |
1917 | ASSERT_EQ( | |
1918 | expected_delta, | |
1919 | delta); | |
1920 | } | |
1921 | } | |
1922 | ||
1923 | void ci_ref_test_on_modify( | |
1924 | object_manifest_t l, | |
1925 | object_manifest_t to_remove, | |
1926 | ObjectCleanRegions clean_regions, | |
1927 | object_ref_delta_t expected_delta) | |
1928 | { | |
1929 | { | |
1930 | object_ref_delta_t delta; | |
1931 | to_remove.calc_refs_to_drop_on_modify( | |
1932 | &l, | |
1933 | clean_regions, | |
1934 | delta); | |
1935 | ASSERT_EQ( | |
1936 | expected_delta, | |
1937 | delta); | |
1938 | } | |
1939 | } | |
1940 | ||
1941 | void ci_ref_test_inc_on_set( | |
1942 | object_manifest_t l, | |
1943 | object_manifest_t added_set, | |
1944 | object_manifest_t g, | |
1945 | object_ref_delta_t expected_delta) | |
1946 | { | |
1947 | { | |
1948 | object_ref_delta_t delta; | |
1949 | added_set.calc_refs_to_inc_on_set( | |
1950 | &l, | |
1951 | &g, | |
1952 | delta); | |
1953 | ASSERT_EQ( | |
1954 | expected_delta, | |
1955 | delta); | |
1956 | } | |
1957 | } | |
1958 | ||
1959 | hobject_t mk_hobject(string name) | |
1960 | { | |
1961 | return hobject_t( | |
1962 | std::move(name), | |
1963 | string(), | |
1964 | CEPH_NOSNAP, | |
1965 | 0x42, | |
1966 | 1, | |
1967 | string()); | |
1968 | } | |
1969 | ||
1970 | object_manifest_t mk_manifest( | |
1971 | std::map<uint64_t, std::tuple<uint64_t, uint64_t, string>> m) | |
1972 | { | |
1973 | object_manifest_t ret; | |
1974 | ret.type = object_manifest_t::TYPE_CHUNKED; | |
1975 | for (auto &[offset, tgt] : m) { | |
1976 | auto &[tgt_off, length, name] = tgt; | |
1977 | auto &ci = ret.chunk_map[offset]; | |
1978 | ci.offset = tgt_off; | |
1979 | ci.length = length; | |
1980 | ci.oid = mk_hobject(name); | |
1981 | } | |
1982 | return ret; | |
1983 | } | |
1984 | ||
1985 | object_ref_delta_t mk_delta(std::map<string, int> _m) { | |
1986 | std::map<hobject_t, int> m; | |
1987 | for (auto &[name, delta] : _m) { | |
1988 | m.insert( | |
1989 | std::make_pair( | |
1990 | mk_hobject(name), | |
1991 | delta)); | |
1992 | } | |
1993 | return object_ref_delta_t(std::move(m)); | |
1994 | } | |
1995 | ||
1996 | TEST(chunk_info_test, calc_refs_to_drop) { | |
1997 | ci_ref_test( | |
1998 | mk_manifest({}), | |
1999 | mk_manifest({{0, {0, 1024, "foo"}}}), | |
2000 | mk_manifest({}), | |
2001 | mk_delta({{"foo", -1}})); | |
2002 | ||
2003 | } | |
2004 | ||
2005 | ||
2006 | TEST(chunk_info_test, calc_refs_to_drop_match) { | |
2007 | ci_ref_test( | |
2008 | mk_manifest({{0, {0, 1024, "foo"}}}), | |
2009 | mk_manifest({{0, {0, 1024, "foo"}}}), | |
2010 | mk_manifest({{0, {0, 1024, "foo"}}}), | |
2011 | mk_delta({})); | |
2012 | ||
2013 | } | |
2014 | ||
2015 | TEST(chunk_info_test, calc_refs_to_drop_head_match) { | |
2016 | ci_ref_test( | |
2017 | mk_manifest({}), | |
2018 | mk_manifest({{0, {0, 1024, "foo"}}}), | |
2019 | mk_manifest({{0, {0, 1024, "foo"}}}), | |
2020 | mk_delta({})); | |
2021 | ||
2022 | } | |
2023 | ||
2024 | TEST(chunk_info_test, calc_refs_to_drop_tail_match) { | |
2025 | ci_ref_test( | |
2026 | mk_manifest({{0, {0, 1024, "foo"}}}), | |
2027 | mk_manifest({{0, {0, 1024, "foo"}}}), | |
2028 | mk_manifest({}), | |
2029 | mk_delta({})); | |
2030 | ||
2031 | } | |
2032 | ||
2033 | TEST(chunk_info_test, calc_refs_to_drop_second_reference) { | |
2034 | ci_ref_test( | |
2035 | mk_manifest({{0, {0, 1024, "foo"}}}), | |
2036 | mk_manifest({{0, {0, 1024, "foo"}}, {4<<10, {0, 1<<10, "foo"}}}), | |
2037 | mk_manifest({}), | |
2038 | mk_delta({{"foo", -1}})); | |
2039 | ||
2040 | } | |
2041 | ||
2042 | TEST(chunk_info_test, calc_refs_offsets_dont_match) { | |
2043 | ci_ref_test( | |
2044 | mk_manifest({{0, {0, 1024, "foo"}}}), | |
2045 | mk_manifest({{512, {0, 1024, "foo"}}, {(4<<10) + 512, {0, 1<<10, "foo"}}}), | |
2046 | mk_manifest({}), | |
2047 | mk_delta({{"foo", -2}})); | |
2048 | ||
2049 | } | |
2050 | ||
2051 | TEST(chunk_info_test, calc_refs_g_l_match) { | |
2052 | ci_ref_test( | |
2053 | mk_manifest({{4096, {0, 1024, "foo"}}}), | |
2054 | mk_manifest({{0, {0, 1024, "foo"}}, {4096, {0, 1024, "bar"}}}), | |
2055 | mk_manifest({{4096, {0, 1024, "foo"}}}), | |
2056 | mk_delta({{"foo", -2}, {"bar", -1}})); | |
2057 | ||
2058 | } | |
2059 | ||
2060 | TEST(chunk_info_test, calc_refs_g_l_match_no_this) { | |
2061 | ci_ref_test( | |
2062 | mk_manifest({{4096, {0, 1024, "foo"}}}), | |
2063 | mk_manifest({{0, {0, 1024, "bar"}}}), | |
2064 | mk_manifest({{4096, {0, 1024, "foo"}}}), | |
2065 | mk_delta({{"foo", -1}, {"bar", -1}})); | |
2066 | ||
2067 | } | |
2068 | ||
2069 | TEST(chunk_info_test, calc_refs_modify_mismatch) { | |
2070 | ObjectCleanRegions clean_regions(0, 8192, false); | |
2071 | clean_regions.mark_data_region_dirty(0, 1024); | |
2072 | clean_regions.mark_data_region_dirty(512, 1024); | |
2073 | ci_ref_test_on_modify( | |
2074 | mk_manifest({{512, {2048, 1024, "foo"}}, {4096, {0, 1024, "foo"}}}), | |
2075 | mk_manifest({{0, {0, 1024, "bar"}}, {512, {2048, 1024, "ttt"}}}), | |
2076 | clean_regions, | |
2077 | mk_delta({{"bar", -1}, {"ttt", -1}})); | |
2078 | } | |
2079 | ||
2080 | TEST(chunk_info_test, calc_refs_modify_match) { | |
2081 | ObjectCleanRegions clean_regions(0, 8192, false); | |
2082 | clean_regions.mark_data_region_dirty(0, 1024); | |
2083 | clean_regions.mark_data_region_dirty(512, 1024); | |
2084 | clean_regions.mark_data_region_dirty(4096, 1024); | |
2085 | ci_ref_test_on_modify( | |
2086 | mk_manifest({{512, {2048, 1024, "foo"}}, {4096, {0, 1024, "ttt"}}}), | |
2087 | mk_manifest({{0, {0, 1024, "bar"}}, {512, {2048, 1024, "foo"}}, {4096, {0, 1024, "ttt"}}}), | |
2088 | clean_regions, | |
2089 | mk_delta({{"bar", -1}})); | |
2090 | } | |
2091 | ||
2092 | TEST(chunk_info_test, calc_refs_modify_match_dirty_overlap) { | |
2093 | ObjectCleanRegions clean_regions(0, 8192, false); | |
2094 | clean_regions.mark_data_region_dirty(0, 256); | |
2095 | clean_regions.mark_data_region_dirty(256, 4096); | |
2096 | ci_ref_test_on_modify( | |
2097 | mk_manifest({}), | |
2098 | mk_manifest({{0, {0, 256, "bar"}}, {512, {2048, 1024, "foo"}}, {4096, {0, 1024, "ttt"}}}), | |
2099 | clean_regions, | |
2100 | mk_delta({{"bar", -1}, {"foo", -1}, {"ttt", -1}})); | |
2101 | } | |
2102 | ||
2103 | TEST(chunk_info_test, calc_refs_modify_match_dirty_overlap2) { | |
2104 | ObjectCleanRegions clean_regions(0, 8192, false); | |
2105 | clean_regions.mark_data_region_dirty(0, 256); | |
2106 | clean_regions.mark_data_region_dirty(256, 1024); | |
2107 | clean_regions.mark_data_region_dirty(3584, 1024); | |
2108 | ci_ref_test_on_modify( | |
2109 | mk_manifest({{512, {2048, 1024, "foo"}}, {4096, {0, 1024, "ttt"}}}), | |
2110 | mk_manifest({{0, {0, 256, "bar"}}, {512, {2048, 1024, "foo"}}, {4096, {0, 1024, "ttt"}}}), | |
2111 | clean_regions, | |
2112 | mk_delta({{"bar", -1}})); | |
2113 | } | |
2114 | ||
2115 | TEST(chunk_info_test, calc_refs_modify_match_dirty_overlap3) { | |
2116 | ObjectCleanRegions clean_regions(0, 8192, false); | |
2117 | clean_regions.mark_data_region_dirty(0, 256); | |
2118 | clean_regions.mark_data_region_dirty(256, 4096); | |
2119 | ci_ref_test_on_modify( | |
2120 | mk_manifest({{512, {2048, 1024, "foo"}}, {4096, {0, 1024, "ttt"}}}), | |
2121 | mk_manifest({{0, {0, 256, "bar"}}, {512, {2048, 1024, "foo"}}, {4096, {0, 1024, "ttt"}}}), | |
2122 | clean_regions, | |
2123 | mk_delta({{"bar", -1}})); | |
2124 | } | |
2125 | ||
2126 | TEST(chunk_info_test, calc_refs_modify_match_clone_overlap) { | |
2127 | ObjectCleanRegions clean_regions(0, 8192, false); | |
2128 | clean_regions.mark_data_region_dirty(0, 256); | |
2129 | clean_regions.mark_data_region_dirty(256, 1024); | |
2130 | clean_regions.mark_data_region_dirty(3584, 1024); | |
2131 | ci_ref_test_on_modify( | |
2132 | mk_manifest({{512, {2048, 1024, "foo"}}, {4096, {0, 1024, "ttt"}}}), | |
2133 | mk_manifest({{0, {0, 256, "bar"}}, {256, {2048, 1024, "foo"}}, {3584, {0, 1024, "ttt"}}}), | |
2134 | clean_regions, | |
2135 | mk_delta({{"bar", -1}, {"foo", -1}, {"ttt", -1}})); | |
2136 | } | |
2137 | ||
2138 | TEST(chunk_info_test, calc_refs_modify_no_snap) { | |
2139 | ObjectCleanRegions clean_regions(0, 8192, false); | |
2140 | clean_regions.mark_data_region_dirty(0, 1024); | |
2141 | clean_regions.mark_data_region_dirty(512, 1024); | |
2142 | ci_ref_test_on_modify( | |
2143 | mk_manifest({}), | |
2144 | mk_manifest({{0, {0, 1024, "bar"}}, {512, {2048, 1024, "ttt"}}}), | |
2145 | clean_regions, | |
2146 | mk_delta({{"bar", -1}, {"ttt", -1}})); | |
2147 | } | |
2148 | ||
2149 | TEST(chunk_info_test, calc_refs_inc) { | |
2150 | ci_ref_test_inc_on_set( | |
2151 | mk_manifest({{256, {0, 256, "aaa"}}, {4096, {0, 1024, "foo"}}}), | |
2152 | mk_manifest({{1024, {0, 1024, "bar"}}}), | |
2153 | mk_manifest({{4096, {0, 1024, "foo"}}}), | |
2154 | mk_delta({{"bar", 1}})); | |
2155 | } | |
2156 | ||
2157 | TEST(chunk_info_test, calc_refs_inc2) { | |
2158 | ci_ref_test_inc_on_set( | |
2159 | mk_manifest({{512, {0, 1024, "aaa"}}, {4096, {0, 1024, "foo"}}}), | |
2160 | mk_manifest({{1024, {0, 1024, "bar"}}, {4096, {0, 1024, "bbb"}}}), | |
2161 | mk_manifest({{512, {0, 1024, "foo"}}}), | |
2162 | mk_delta({{"bar", 1}, {"bbb", 1}})); | |
2163 | } | |
2164 | ||
2165 | TEST(chunk_info_test, calc_refs_inc_no_l) { | |
2166 | ci_ref_test_inc_on_set( | |
2167 | mk_manifest({}), | |
2168 | mk_manifest({{1024, {0, 1024, "bar"}}, {4096, {0, 1024, "bbb"}}}), | |
2169 | mk_manifest({{512, {0, 1024, "foo"}}}), | |
2170 | mk_delta({{"bar", 1}, {"bbb", 1}})); | |
2171 | } | |
2172 | ||
2173 | TEST(chunk_info_test, calc_refs_inc_no_g) { | |
2174 | ci_ref_test_inc_on_set( | |
2175 | mk_manifest({{512, {0, 1024, "aaa"}}, {4096, {0, 1024, "foo"}}}), | |
2176 | mk_manifest({{1024, {0, 1024, "bar"}}, {4096, {0, 1024, "foo"}}}), | |
2177 | mk_manifest({}), | |
2178 | mk_delta({{"bar", 1}})); | |
2179 | } | |
2180 | ||
2181 | TEST(chunk_info_test, calc_refs_inc_match_g_l) { | |
2182 | ci_ref_test_inc_on_set( | |
2183 | mk_manifest({{256, {0, 256, "aaa"}}, {4096, {0, 1024, "foo"}}}), | |
2184 | mk_manifest({{256, {0, 256, "aaa"}}, {4096, {0, 1024, "foo"}}}), | |
2185 | mk_manifest({{256, {0, 256, "aaa"}}, {4096, {0, 1024, "foo"}}}), | |
2186 | mk_delta({{"aaa", -1}, {"foo", -1}})); | |
2187 | } | |
2188 | ||
2189 | TEST(chunk_info_test, calc_refs_inc_match) { | |
2190 | ci_ref_test_inc_on_set( | |
2191 | mk_manifest({{256, {0, 256, "bbb"}}, {4096, {0, 1024, "foo"}}}), | |
2192 | mk_manifest({{256, {0, 256, "aaa"}}, {4096, {0, 1024, "foo"}}}), | |
2193 | mk_manifest({{256, {0, 256, "aaa"}}, {4096, {0, 1024, "ccc"}}}), | |
2194 | mk_delta({})); | |
2195 | } | |
7c673cae FG |
2196 | |
2197 | /* | |
2198 | * Local Variables: | |
2199 | * compile-command: "cd ../.. ; | |
2200 | * make unittest_osd_types ; | |
2201 | * ./unittest_osd_types # --gtest_filter=pg_missing_t.constructor | |
2202 | * " | |
2203 | * End: | |
2204 | */ |