]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/osd/types.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / test / osd / types.cc
CommitLineData
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
28using namespace std;
29
7c673cae
FG
30TEST(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
43TEST(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
59TEST(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
79TEST(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
92TEST(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
105TEST(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
125TEST(pg_interval_t, check_new_interval)
126{
127// iterate through all 4 combinations
128for (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
758TEST(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
770TEST(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
874TEST(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
905TEST(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
924TEST(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
933TEST(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
974TEST(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
981TEST(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
990TEST(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
1005TEST(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
1029TEST(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
1188TEST(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
1209TEST(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
1229TEST(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
1242TEST(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
1273TEST(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
1311TEST(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
1331TEST(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
1356TEST(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
1371TEST(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
1385TEST(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
1398TEST(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
1432TEST(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
1446TEST(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
1465TEST(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
1496TEST(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
1512TEST(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
1543TEST(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
1549TEST(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
1570TEST(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
1591TEST(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
1612struct 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
1620using namespace std;
1621struct 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
1634using sit = shard_id_t;
1635using PI = PastIntervals;
1636using pst = pg_shard_t;
1637using ival = PastIntervals::pg_interval_t;
1638using ivallst = std::list<ival>;
1639const int N = 0x7fffffff /* CRUSH_ITEM_NONE, can't import crush.h here */;
1640
1641struct 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
1682TEST_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
1706TEST_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
1728TEST_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
1752TEST_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
1775TEST_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
1798TEST_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
1821TEST_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
1845TEST_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
1869TEST_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
1892void 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
1923void 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
1941void 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
1959hobject_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
1970object_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
1985object_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
1996TEST(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
2006TEST(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
2015TEST(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
2024TEST(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
2033TEST(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
2042TEST(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
2051TEST(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
2060TEST(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
2069TEST(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
2080TEST(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
2092TEST(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
2103TEST(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
2115TEST(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
2126TEST(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
2138TEST(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
2149TEST(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
2157TEST(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
2165TEST(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
2173TEST(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
2181TEST(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
2189TEST(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 */