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