1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2011 New Dream Network
7 * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com>
9 * Author: Loic Dachary <loic@dachary.org>
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.
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"
28 TEST(hobject
, prefixes0
)
30 uint32_t mask
= 0xE947FA20;
34 set
<string
> prefixes_correct
;
35 prefixes_correct
.insert(string("0000000000000000.02A"));
37 set
<string
> prefixes_out(hobject_t::get_prefixes(bits
, mask
, pool
));
38 ASSERT_EQ(prefixes_out
, prefixes_correct
);
41 TEST(hobject
, prefixes1
)
43 uint32_t mask
= 0x0000000F;
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"));
53 set
<string
> prefixes_out(hobject_t::get_prefixes(bits
, mask
, pool
));
54 ASSERT_EQ(prefixes_out
, prefixes_correct
);
57 TEST(hobject
, prefixes2
)
59 uint32_t mask
= 0xDEADBEAF;
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"));
73 set
<string
> prefixes_out(hobject_t::get_prefixes(bits
, mask
, pool
));
74 ASSERT_EQ(prefixes_out
, prefixes_correct
);
77 TEST(hobject
, prefixes3
)
79 uint32_t mask
= 0xE947FA20;
83 set
<string
> prefixes_correct
;
84 prefixes_correct
.insert(string("0000000000000023.02AF749E"));
86 set
<string
> prefixes_out(hobject_t::get_prefixes(bits
, mask
, pool
));
87 ASSERT_EQ(prefixes_out
, prefixes_correct
);
90 TEST(hobject
, prefixes4
)
92 uint32_t mask
= 0xE947FA20;
96 set
<string
> prefixes_correct
;
97 prefixes_correct
.insert(string("0000000000000023."));
99 set
<string
> prefixes_out(hobject_t::get_prefixes(bits
, mask
, pool
));
100 ASSERT_EQ(prefixes_out
, prefixes_correct
);
103 TEST(hobject
, prefixes5
)
105 uint32_t mask
= 0xDEADBEAF;
107 int64_t pool
= 0x34AC5D00;
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"));
119 set
<string
> prefixes_out(hobject_t::get_prefixes(bits
, mask
, pool
));
120 ASSERT_EQ(prefixes_out
, prefixes_correct
);
123 TEST(pg_interval_t
, check_new_interval
)
125 // iterate through all 4 combinations
126 for (unsigned i
= 0; i
< 4; ++i
) {
128 // Create a situation where osdmaps are the same so that
129 // each test case can diverge from it using minimal code.
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;
146 boost::scoped_ptr
<IsPGRecoverablePredicate
> recoverable(new ReplicatedBackend::RPCRecPred());
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
);
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
;
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
;
168 pgid
.set_pool(pool_id
);
171 // Do nothing if there are no modifications in
172 // acting, up or pool size and that the pool is not
176 PastIntervals past_intervals
;
178 ASSERT_TRUE(past_intervals
.empty());
179 ASSERT_FALSE(PastIntervals::check_new_interval(old_primary
,
194 ASSERT_TRUE(past_intervals
.empty());
198 // The acting set has changed
201 vector
<int> new_acting
;
202 int _new_primary
= osd_id
+ 1;
203 new_acting
.push_back(_new_primary
);
205 PastIntervals past_intervals
;
207 ASSERT_TRUE(past_intervals
.empty());
208 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
223 old_primary
= new_primary
;
227 // The up set has changed
231 int _new_primary
= osd_id
+ 1;
232 new_up
.push_back(_new_primary
);
234 PastIntervals past_intervals
;
236 ASSERT_TRUE(past_intervals
.empty());
237 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
255 // The up primary has changed
259 int _new_up_primary
= osd_id
+ 1;
261 PastIntervals past_intervals
;
263 ASSERT_TRUE(past_intervals
.empty());
264 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
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
);
295 PastIntervals past_intervals
;
297 ASSERT_TRUE(past_intervals
.empty());
298 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
316 // PG is pre-merge source
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
;
331 ASSERT_TRUE(past_intervals
.empty());
332 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
344 pg_t(pg_num
- 1, pool_id
),
350 // PG was pre-merge source
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
);
363 cout
<< "pg_num " << pg_num
<< std::endl
;
364 PastIntervals past_intervals
;
366 ASSERT_TRUE(past_intervals
.empty());
367 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
377 lastmap
, // reverse order!
379 pg_t(pg_num
- 1, pool_id
),
385 // PG is merge source
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
);
397 PastIntervals past_intervals
;
399 ASSERT_TRUE(past_intervals
.empty());
400 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
412 pg_t(pg_num
- 1, pool_id
),
418 // PG is pre-merge target
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
);
430 PastIntervals past_intervals
;
432 ASSERT_TRUE(past_intervals
.empty());
433 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
445 pg_t(pg_num
/ 2 - 1, pool_id
),
451 // PG was pre-merge target
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
);
463 PastIntervals past_intervals
;
465 ASSERT_TRUE(past_intervals
.empty());
466 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
476 lastmap
, // reverse order!
478 pg_t(pg_num
/ 2 - 1, pool_id
),
484 // PG is merge target
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
);
496 PastIntervals past_intervals
;
498 ASSERT_TRUE(past_intervals
.empty());
499 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
511 pg_t(pg_num
/ 2 - 1, pool_id
),
517 // PG size has changed
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
);
530 PastIntervals past_intervals
;
532 ASSERT_TRUE(past_intervals
.empty());
533 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
551 // The old acting set was empty : the previous interval could not
555 vector
<int> old_acting
;
557 PastIntervals past_intervals
;
561 ASSERT_TRUE(past_intervals
.empty());
562 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
578 ASSERT_NE(string::npos
, out
.str().find("acting set is too small"));
582 // The old acting set did not have enough osd : it could
586 vector
<int> old_acting
;
587 old_acting
.push_back(osd_id
);
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
594 // The new osdmap is created so that it triggers the
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
);
609 PastIntervals past_intervals
;
611 ASSERT_TRUE(past_intervals
.empty());
612 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
628 ASSERT_NE(string::npos
, out
.str().find("acting set is too small"));
632 // The acting set changes. The old acting set primary was up during the
633 // previous interval and may have been rw.
636 vector
<int> new_acting
;
637 new_acting
.push_back(osd_id
+ 4);
638 new_acting
.push_back(osd_id
+ 5);
642 PastIntervals past_intervals
;
644 ASSERT_TRUE(past_intervals
.empty());
645 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
661 ASSERT_NE(string::npos
, out
.str().find("includes interval"));
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.
669 vector
<int> new_acting
;
670 new_acting
.push_back(osd_id
+ 4);
671 new_acting
.push_back(osd_id
+ 5);
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
);
685 PastIntervals past_intervals
;
687 ASSERT_TRUE(past_intervals
.empty());
688 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
704 ASSERT_NE(string::npos
, out
.str().find("presumed to have been rw"));
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
714 vector
<int> new_acting
;
715 new_acting
.push_back(osd_id
+ 4);
716 new_acting
.push_back(osd_id
+ 5);
718 epoch_t last_epoch_clean
= epoch
- 10;
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
);
732 PastIntervals past_intervals
;
734 ASSERT_TRUE(past_intervals
.empty());
735 ASSERT_TRUE(PastIntervals::check_new_interval(old_primary
,
751 ASSERT_NE(string::npos
, out
.str().find("does not include interval"));
753 } // end for, didn't want to reindent
756 TEST(pg_t
, get_ancestor
)
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));
775 b
= pgid
.is_split(1, 1, &s
);
779 b
= pgid
.is_split(2, 4, NULL
);
781 b
= pgid
.is_split(2, 4, &s
);
783 ASSERT_EQ(1u, s
.size());
784 ASSERT_TRUE(s
.count(pg_t(2, 0)));
787 b
= pgid
.is_split(2, 8, &s
);
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)));
795 b
= pgid
.is_split(3, 8, &s
);
797 ASSERT_EQ(1u, s
.size());
798 ASSERT_TRUE(s
.count(pg_t(4, 0)));
801 b
= pgid
.is_split(6, 8, NULL
);
803 b
= pgid
.is_split(6, 8, &s
);
805 ASSERT_EQ(0u, s
.size());
810 b
= pgid
.is_split(2, 4, &s
);
812 ASSERT_EQ(1u, s
.size());
813 ASSERT_TRUE(s
.count(pg_t(3, 0)));
816 b
= pgid
.is_split(2, 6, &s
);
818 ASSERT_EQ(2u, s
.size());
819 ASSERT_TRUE(s
.count(pg_t(3, 0)));
820 ASSERT_TRUE(s
.count(pg_t(5, 0)));
823 b
= pgid
.is_split(2, 8, &s
);
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)));
831 b
= pgid
.is_split(4, 8, &s
);
833 ASSERT_EQ(1u, s
.size());
834 ASSERT_TRUE(s
.count(pg_t(5, 0)));
837 b
= pgid
.is_split(3, 8, &s
);
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)));
845 b
= pgid
.is_split(6, 8, &s
);
847 ASSERT_EQ(0u, s
.size());
852 b
= pgid
.is_split(7, 8, &s
);
854 ASSERT_EQ(1u, s
.size());
855 ASSERT_TRUE(s
.count(pg_t(7, 0)));
858 b
= pgid
.is_split(7, 12, &s
);
860 ASSERT_EQ(2u, s
.size());
861 ASSERT_TRUE(s
.count(pg_t(7, 0)));
862 ASSERT_TRUE(s
.count(pg_t(11, 0)));
865 b
= pgid
.is_split(7, 11, &s
);
867 ASSERT_EQ(1u, s
.size());
868 ASSERT_TRUE(s
.count(pg_t(7, 0)));
878 b
= pgid
.is_merge_source(8, 7, &parent
);
880 ASSERT_EQ(parent
, pg_t(3, 0));
881 ASSERT_TRUE(parent
.is_merge_target(8, 7));
883 b
= pgid
.is_merge_source(8, 5, &parent
);
885 ASSERT_EQ(parent
, pg_t(3, 0));
886 ASSERT_TRUE(parent
.is_merge_target(8, 5));
888 b
= pgid
.is_merge_source(8, 4, &parent
);
890 ASSERT_EQ(parent
, pg_t(3, 0));
891 ASSERT_TRUE(parent
.is_merge_target(8, 4));
893 b
= pgid
.is_merge_source(8, 3, &parent
);
895 ASSERT_EQ(parent
, pg_t(1, 0));
896 ASSERT_TRUE(parent
.is_merge_target(8, 4));
898 b
= pgid
.is_merge_source(9, 8, &parent
);
900 ASSERT_FALSE(parent
.is_merge_target(9, 8));
903 TEST(ObjectCleanRegions
, mark_data_region_dirty
)
905 ObjectCleanRegions clean_regions
;
906 uint64_t offset_1
, len_1
, offset_2
, len_2
;
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
);
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());
922 TEST(ObjectCleanRegions
, mark_omap_dirty
)
924 ObjectCleanRegions clean_regions
;
926 EXPECT_FALSE(clean_regions
.omap_is_dirty());
927 clean_regions
.mark_omap_dirty();
928 EXPECT_TRUE(clean_regions
.omap_is_dirty());
931 TEST(ObjectCleanRegions
, merge
)
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());
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()));
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()));
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());
967 cr1_expect
.insert(204800, 8192);
968 ASSERT_TRUE(cr1_expect
.subset_of(cr1
.get_dirty_regions()));
969 ASSERT_TRUE(cr1
.omap_is_dirty());
972 TEST(pg_missing_t
, constructor
)
974 pg_missing_t missing
;
975 EXPECT_EQ((unsigned int)0, missing
.num_missing());
976 EXPECT_FALSE(missing
.have_missing());
979 TEST(pg_missing_t
, have_missing
)
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());
988 TEST(pg_missing_t
, claim
)
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());
997 EXPECT_FALSE(other
.have_missing());
999 other
.claim(missing
);
1000 EXPECT_TRUE(other
.have_missing());
1003 TEST(pg_missing_t
, is_missing
)
1005 // pg_missing_t::is_missing(const hobject_t& oid) const
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
));
1014 // bool pg_missing_t::is_missing(const hobject_t& oid, eversion_t v) const
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
));
1027 TEST(pg_missing_t
, add_next_event
)
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),
1037 // new object (MODIFY)
1039 pg_missing_t missing
;
1040 pg_log_entry_t e
= sample_e
;
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());
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());
1062 // new object (CLONE)
1064 pg_missing_t missing
;
1065 pg_log_entry_t e
= sample_e
;
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());
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());
1087 // existing object (MODIFY)
1089 pg_missing_t missing
;
1090 pg_log_entry_t e
= sample_e
;
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());
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());
1114 // object with prior version (MODIFY)
1116 pg_missing_t missing
;
1117 pg_log_entry_t e
= sample_e
;
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());
1133 // adding a DELETE matching an existing event
1135 pg_missing_t missing
;
1136 pg_log_entry_t e
= sample_e
;
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
));
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());
1158 // adding a LOST_DELETE after an existing event
1160 pg_missing_t missing
;
1161 pg_log_entry_t e
= sample_e
;
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());
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());
1186 TEST(pg_missing_t
, revise_need
)
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
);
1207 TEST(pg_missing_t
, revise_have
)
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
);
1227 TEST(pg_missing_t
, add
)
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
);
1240 TEST(pg_missing_t
, rm
)
1242 // void pg_missing_t::rm(const hobject_t& oid, eversion_t v)
1244 hobject_t
oid(object_t("objname"), "key", 123, 456, 0, "");
1245 pg_missing_t missing
;
1246 EXPECT_FALSE(missing
.is_missing(oid
));
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
));
1258 // void pg_missing_t::rm(const std::map<hobject_t, pg_missing_item>::iterator &m)
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
);
1267 EXPECT_FALSE(missing
.is_missing(oid
));
1271 TEST(pg_missing_t
, got
)
1273 // void pg_missing_t::got(const hobject_t& oid, eversion_t v)
1275 hobject_t
oid(object_t("objname"), "key", 123, 456, 0, "");
1276 pg_missing_t missing
;
1277 // assert if the oid does not exist
1279 PrCtl unset_dumpable
;
1280 EXPECT_DEATH(missing
.got(oid
, eversion_t()), "");
1282 EXPECT_FALSE(missing
.is_missing(oid
));
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
1289 PrCtl unset_dumpable
;
1290 EXPECT_DEATH(missing
.got(oid
, eversion_t(epoch
/ 2,20)), "");
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
));
1296 // void pg_missing_t::got(const std::map<hobject_t, pg_missing_item>::iterator &m)
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
);
1305 EXPECT_FALSE(missing
.is_missing(oid
));
1309 TEST(pg_missing_t
, split_into
)
1312 hobject_t
oid1(object_t("objname"), "key1", 123, hash1
, 0, "");
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);
1319 child_pgid
.m_seed
= 1;
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
));
1329 TEST(pg_pool_t_test
, get_pg_num_divisor
) {
1334 for (int i
= 0; i
< 16; ++i
)
1335 ASSERT_EQ(16u, p
.get_pg_num_divisor(pg_t(i
, 1)));
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)));
1354 TEST(pg_pool_t_test
, get_random_pg_position
) {
1356 for (int i
= 0; i
< 100; ++i
) {
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
);
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));
1376 ASSERT_EQ(out
.str(), "0,1,2");
1378 shard_id_t noshard
= shard_id_t::NO_SHARD
;
1380 ASSERT_GT(zero
, noshard
);
1383 TEST(spg_t
, parse
) {
1384 spg_t
a(pg_t(1,2), shard_id_t::NO_SHARD
);
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()));
1392 ASSERT_TRUE(bb
.parse(s
.c_str()));
1396 TEST(coll_t
, parse
) {
1397 const char *ok
[] = {
1406 const char *bad
[] = {
1410 //" 1.2_head", // hrm, this parses, which is not ideal.. pg_t's fault?
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());
1424 for (int i
= 0; bad
[i
]; ++i
) {
1425 cout
<< "check bad " << bad
[i
] << std::endl
;
1426 ASSERT_FALSE(a
.parse(bad
[i
]));
1430 TEST(coll_t
, temp
) {
1433 ASSERT_EQ(foo
.to_str(), string("0.0_head"));
1435 coll_t temp
= foo
.get_temp();
1436 ASSERT_EQ(temp
.to_str(), string("0.0_TEMP"));
1439 ASSERT_TRUE(temp
.is_temp());
1440 ASSERT_TRUE(temp
.is_temp(&pgid2
));
1441 ASSERT_EQ(pgid
, pgid2
);
1444 TEST(coll_t
, assigment
) {
1447 ASSERT_EQ(right
.to_str(), string("0.0_head"));
1449 coll_t left
, middle
;
1451 ASSERT_EQ(left
.to_str(), string("meta"));
1452 ASSERT_EQ(middle
.to_str(), string("meta"));
1454 left
= middle
= right
;
1456 ASSERT_EQ(left
.to_str(), string("0.0_head"));
1457 ASSERT_EQ(middle
.to_str(), string("0.0_head"));
1459 ASSERT_NE(middle
.c_str(), right
.c_str());
1460 ASSERT_NE(left
.c_str(), middle
.c_str());
1463 TEST(hobject_t
, parse
) {
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",
1479 for (unsigned i
=0; v
[i
]; ++i
) {
1481 bool b
= o
.parse(v
[i
]);
1483 cout
<< "failed to parse " << v
[i
] << std::endl
;
1486 string s
= stringify(o
);
1488 cout
<< v
[i
] << " -> " << o
<< " -> " << s
<< std::endl
;
1489 ASSERT_EQ(s
, string(v
[i
]));
1494 TEST(ghobject_t
, cmp
) {
1497 sep
.set_shard(shard_id_t(1));
1499 cout
<< min
<< " < " << sep
<< std::endl
;
1500 ASSERT_TRUE(min
< sep
);
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,
1506 cout
<< "o " << o
<< std::endl
;
1507 ASSERT_TRUE(o
> sep
);
1510 TEST(ghobject_t
, parse
) {
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#",
1522 "#-40:00000000:nspace::obj:head#",
1526 for (unsigned i
=0; v
[i
]; ++i
) {
1528 bool b
= o
.parse(v
[i
]);
1530 cout
<< "failed to parse " << v
[i
] << std::endl
;
1533 string s
= stringify(o
);
1535 cout
<< v
[i
] << " -> " << o
<< " -> " << s
<< std::endl
;
1536 ASSERT_EQ(s
, string(v
[i
]));
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"), "");
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
));
1554 EXPECT_FALSE(opts
.is_set(pool_opts_t::SCRUB_MIN_INTERVAL
));
1556 PrCtl unset_dumpable
;
1557 EXPECT_DEATH(opts
.get(pool_opts_t::SCRUB_MIN_INTERVAL
), "");
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
));
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
));
1575 EXPECT_FALSE(opts
.is_set(pool_opts_t::SCRUB_MAX_INTERVAL
));
1577 PrCtl unset_dumpable
;
1578 EXPECT_DEATH(opts
.get(pool_opts_t::SCRUB_MAX_INTERVAL
), "");
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
));
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
));
1596 EXPECT_FALSE(opts
.is_set(pool_opts_t::DEEP_SCRUB_INTERVAL
));
1598 PrCtl unset_dumpable
;
1599 EXPECT_DEATH(opts
.get(pool_opts_t::DEEP_SCRUB_INTERVAL
), "");
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
));
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
;
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
);
1627 *lost_at
= val
.second
;
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 */;
1639 struct PITest
: ::testing::Test
{
1644 epoch_t last_epoch_started
,
1645 unsigned min_to_peer
,
1646 vector
<pair
<int, pair
<PastIntervals::osd_state_t
, epoch_t
>>> osd_states
,
1649 set
<pg_shard_t
> probe
,
1651 map
<int, epoch_t
> blocked_by
,
1653 RequiredPredicate
rec_pred(min_to_peer
);
1654 MapPredicate
map_pred(osd_states
);
1656 PI::PriorSet
correct(
1662 new RequiredPredicate(rec_pred
));
1664 PastIntervals compact
;
1665 for (auto &&i
: intervals
) {
1666 compact
.add_interval(ec_pool
, i
);
1668 PI::PriorSet compact_ps
= compact
.get_prior_set(
1671 new RequiredPredicate(rec_pred
),
1676 ASSERT_EQ(correct
, compact_ps
);
1680 TEST_F(PITest
, past_intervals_rep
) {
1682 /* ec_pool */ false,
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}
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))
1696 /* acting */ {0, 1 },
1698 /* probe */ {pst(0), pst(1)},
1700 /* blocked_by */ {},
1701 /* pg_down */ false);
1704 TEST_F(PITest
, past_intervals_ec
) {
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}
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))
1718 /* acting */ {N
, 1, 2},
1720 /* probe */ {pst(1, sit(1)), pst(2, sit(2))},
1722 /* blocked_by */ {},
1723 /* pg_down */ false);
1726 TEST_F(PITest
, past_intervals_rep_down
) {
1728 /* ec_pool */ false,
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}
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))
1742 /* acting */ {0, 1 },
1744 /* probe */ {pst(0), pst(1)},
1746 /* blocked_by */ {{2, 0}},
1747 /* pg_down */ true);
1750 TEST_F(PITest
, past_intervals_ec_down
) {
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}
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))
1765 /* acting */ {0, N
, 2},
1767 /* probe */ {pst(0, sit(0)), pst(2, sit(2))},
1769 /* blocked_by */ {{1, 0}},
1770 /* pg_down */ true);
1773 TEST_F(PITest
, past_intervals_rep_no_subsets
) {
1775 /* ec_pool */ false,
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}
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))
1788 /* acting */ {0, 1 },
1790 /* probe */ {pst(0), pst(1)},
1792 /* blocked_by */ {},
1793 /* pg_down */ false);
1796 TEST_F(PITest
, past_intervals_ec_no_subsets
) {
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}
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))
1811 /* acting */ {0, N
, 2},
1813 /* probe */ {pst(0, sit(0)), pst(2, sit(2))},
1815 /* blocked_by */ {{1, 0}},
1816 /* pg_down */ true);
1819 TEST_F(PITest
, past_intervals_ec_no_subsets2
) {
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}
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))
1835 /* acting */ {0, N
, 2},
1837 /* probe */ {pst(0, sit(0)), pst(2, sit(2)), pst(3, sit(1))},
1839 /* blocked_by */ {},
1840 /* pg_down */ false);
1843 TEST_F(PITest
, past_intervals_rep_lost
) {
1845 /* ec_pool */ false,
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}
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))
1859 /* acting */ {0, 1 },
1861 /* probe */ {pst(0), pst(1)},
1863 /* blocked_by */ {},
1864 /* pg_down */ false);
1867 TEST_F(PITest
, past_intervals_ec_lost
) {
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}
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))
1882 /* acting */ {0, N
, 2},
1884 /* probe */ {pst(0, sit(0)), pst(2, sit(2))},
1886 /* blocked_by */ {},
1887 /* pg_down */ false);
1893 * compile-command: "cd ../.. ;
1894 * make unittest_osd_types ;
1895 * ./unittest_osd_types # --gtest_filter=pg_missing_t.constructor