EXPECT_FALSE(opts.is_set(pool_opts_t::DEEP_SCRUB_INTERVAL));
}
+struct RequiredPredicate : IsPGRecoverablePredicate {
+ unsigned required_size;
+ RequiredPredicate(unsigned required_size) : required_size(required_size) {}
+ bool operator()(const set<pg_shard_t> &have) const override {
+ return have.size() >= required_size;
+ }
+};
+
+using namespace std;
+struct MapPredicate {
+ map<int, pair<PastIntervals::osd_state_t, epoch_t>> states;
+ MapPredicate(
+ vector<pair<int, pair<PastIntervals::osd_state_t, epoch_t>>> _states)
+ : states(_states.begin(), _states.end()) {}
+ PastIntervals::osd_state_t operator()(epoch_t start, int osd, epoch_t *lost_at) {
+ auto val = states.at(osd);
+ if (lost_at)
+ *lost_at = val.second;
+ return val.first;
+ }
+};
+
+using sit = shard_id_t;
+using PI = PastIntervals;
+using pst = pg_shard_t;
+using ival = PastIntervals::pg_interval_t;
+using ivallst = std::list<ival>;
+const int N = 0x7fffffff /* CRUSH_ITEM_NONE, can't import crush.h here */;
+
+struct PITest : ::testing::Test {
+ PITest() {}
+ void run(
+ bool ec_pool,
+ ivallst intervals,
+ epoch_t last_epoch_started,
+ unsigned min_to_peer,
+ vector<pair<int, pair<PastIntervals::osd_state_t, epoch_t>>> osd_states,
+ vector<int> up,
+ vector<int> acting,
+ set<pg_shard_t> probe,
+ set<int> down,
+ map<int, epoch_t> blocked_by,
+ bool pg_down) {
+ RequiredPredicate rec_pred(min_to_peer);
+ MapPredicate map_pred(osd_states);
+
+ PI::PriorSet correct(
+ ec_pool,
+ probe,
+ down,
+ blocked_by,
+ pg_down,
+ new RequiredPredicate(rec_pred));
+
+ PastIntervals simple, compact;
+ simple.update_type(ec_pool, false);
+ compact.update_type(ec_pool, true);
+ for (auto &&i: intervals) {
+ simple.add_interval(ec_pool, i);
+ compact.add_interval(ec_pool, i);
+ }
+ PI::PriorSet simple_ps = simple.get_prior_set(
+ ec_pool,
+ last_epoch_started,
+ new RequiredPredicate(rec_pred),
+ map_pred,
+ up,
+ acting,
+ nullptr);
+ PI::PriorSet compact_ps = compact.get_prior_set(
+ ec_pool,
+ last_epoch_started,
+ new RequiredPredicate(rec_pred),
+ map_pred,
+ up,
+ acting,
+ nullptr);
+ ASSERT_EQ(correct, simple_ps);
+ ASSERT_EQ(correct, compact_ps);
+ }
+};
+
+TEST_F(PITest, past_intervals_rep) {
+ run(
+ /* ec_pool */ false,
+ /* intervals */
+ { ival{{0, 1, 2}, {0, 1, 2}, 10, 20, true, 0, 0}
+ , ival{{ 1, 2}, { 1, 2}, 21, 30, true, 1, 1}
+ , ival{{ 2}, { 2}, 31, 35, false, 2, 2}
+ , ival{{0, 2}, {0, 2}, 36, 50, true, 0, 0}
+ },
+ /* les */ 5,
+ /* min_peer */ 1,
+ /* osd states at end */
+ { make_pair(0, make_pair(PI::UP , 0))
+ , make_pair(1, make_pair(PI::UP , 0))
+ , make_pair(2, make_pair(PI::DOWN , 0))
+ },
+ /* acting */ {0, 1 },
+ /* up */ {0, 1 },
+ /* probe */ {pst(0), pst(1)},
+ /* down */ {2},
+ /* blocked_by */ {},
+ /* pg_down */ false);
+}
+
+TEST_F(PITest, past_intervals_ec) {
+ run(
+ /* ec_pool */ true,
+ /* intervals */
+ { ival{{0, 1, 2}, {0, 1, 2}, 10, 20, true, 0, 0}
+ , ival{{N, 1, 2}, {N, 1, 2}, 21, 30, true, 1, 1}
+ },
+ /* les */ 5,
+ /* min_peer */ 2,
+ /* osd states at end */
+ { make_pair(0, make_pair(PI::DOWN , 0))
+ , make_pair(1, make_pair(PI::UP , 0))
+ , make_pair(2, make_pair(PI::UP , 0))
+ },
+ /* acting */ {N, 1, 2},
+ /* up */ {N, 1, 2},
+ /* probe */ {pst(1, sit(1)), pst(2, sit(2))},
+ /* down */ {0},
+ /* blocked_by */ {},
+ /* pg_down */ false);
+}
+
+TEST_F(PITest, past_intervals_rep_down) {
+ run(
+ /* ec_pool */ false,
+ /* intervals */
+ { ival{{0, 1, 2}, {0, 1, 2}, 10, 20, true, 0, 0}
+ , ival{{ 1, 2}, { 1, 2}, 21, 30, true, 1, 1}
+ , ival{{ 2}, { 2}, 31, 35, true, 2, 2}
+ , ival{{0, 2}, {0, 2}, 36, 50, true, 0, 0}
+ },
+ /* les */ 5,
+ /* min_peer */ 1,
+ /* osd states at end */
+ { make_pair(0, make_pair(PI::UP , 0))
+ , make_pair(1, make_pair(PI::UP , 0))
+ , make_pair(2, make_pair(PI::DOWN , 0))
+ },
+ /* acting */ {0, 1 },
+ /* up */ {0, 1 },
+ /* probe */ {pst(0), pst(1)},
+ /* down */ {2},
+ /* blocked_by */ {{2, 0}},
+ /* pg_down */ true);
+}
+
+TEST_F(PITest, past_intervals_ec_down) {
+ run(
+ /* ec_pool */ true,
+ /* intervals */
+ { ival{{0, 1, 2}, {0, 1, 2}, 10, 20, true, 0, 0}
+ , ival{{N, 1, 2}, {N, 1, 2}, 21, 30, true, 1, 1}
+ , ival{{N, N, 2}, {N, N, 2}, 31, 35, false, 2, 2}
+ },
+ /* les */ 5,
+ /* min_peer */ 2,
+ /* osd states at end */
+ { make_pair(0, make_pair(PI::UP , 0))
+ , make_pair(1, make_pair(PI::DOWN , 0))
+ , make_pair(2, make_pair(PI::UP , 0))
+ },
+ /* acting */ {0, N, 2},
+ /* up */ {0, N, 2},
+ /* probe */ {pst(0, sit(0)), pst(2, sit(2))},
+ /* down */ {1},
+ /* blocked_by */ {{1, 0}},
+ /* pg_down */ true);
+}
+
+TEST_F(PITest, past_intervals_rep_no_subsets) {
+ run(
+ /* ec_pool */ false,
+ /* intervals */
+ { ival{{0, 2}, {0, 2}, 10, 20, true, 0, 0}
+ , ival{{ 1, 2}, { 1, 2}, 21, 30, true, 1, 1}
+ , ival{{0, 1 }, {0, 1 }, 31, 35, true, 2, 2}
+ },
+ /* les */ 5,
+ /* min_peer */ 1,
+ /* osd states at end */
+ { make_pair(0, make_pair(PI::UP , 0))
+ , make_pair(1, make_pair(PI::UP , 0))
+ , make_pair(2, make_pair(PI::DOWN , 0))
+ },
+ /* acting */ {0, 1 },
+ /* up */ {0, 1 },
+ /* probe */ {pst(0), pst(1)},
+ /* down */ {2},
+ /* blocked_by */ {},
+ /* pg_down */ false);
+}
+
+TEST_F(PITest, past_intervals_ec_no_subsets) {
+ run(
+ /* ec_pool */ true,
+ /* intervals */
+ { ival{{0, N, 2}, {0, N, 2}, 10, 20, true, 0, 0}
+ , ival{{N, 1, 2}, {N, 1, 2}, 21, 30, true, 1, 1}
+ , ival{{0, 1, N}, {0, 1, N}, 31, 35, true, 2, 2}
+ },
+ /* les */ 5,
+ /* min_peer */ 2,
+ /* osd states at end */
+ { make_pair(0, make_pair(PI::UP , 0))
+ , make_pair(1, make_pair(PI::DOWN , 0))
+ , make_pair(2, make_pair(PI::UP , 0))
+ },
+ /* acting */ {0, N, 2},
+ /* up */ {0, N, 2},
+ /* probe */ {pst(0, sit(0)), pst(2, sit(2))},
+ /* down */ {1},
+ /* blocked_by */ {{1, 0}},
+ /* pg_down */ true);
+}
+
+TEST_F(PITest, past_intervals_ec_no_subsets2) {
+ run(
+ /* ec_pool */ true,
+ /* intervals */
+ { ival{{N, 1, 2}, {N, 1, 2}, 10, 20, true, 0, 0}
+ , ival{{0, N, 2}, {0, N, 2}, 21, 30, true, 1, 1}
+ , ival{{0, 3, N}, {0, 3, N}, 31, 35, true, 2, 2}
+ },
+ /* les */ 31,
+ /* min_peer */ 2,
+ /* osd states at end */
+ { make_pair(0, make_pair(PI::UP , 0))
+ , make_pair(1, make_pair(PI::DOWN , 0))
+ , make_pair(2, make_pair(PI::UP , 0))
+ , make_pair(3, make_pair(PI::UP , 0))
+ },
+ /* acting */ {0, N, 2},
+ /* up */ {0, N, 2},
+ /* probe */ {pst(0, sit(0)), pst(2, sit(2)), pst(3, sit(1))},
+ /* down */ {1},
+ /* blocked_by */ {},
+ /* pg_down */ false);
+}
+
+TEST_F(PITest, past_intervals_rep_lost) {
+ run(
+ /* ec_pool */ false,
+ /* intervals */
+ { ival{{0, 1, 2}, {0, 1, 2}, 10, 20, true, 0, 0}
+ , ival{{ 1, 2}, { 1, 2}, 21, 30, true, 1, 1}
+ , ival{{ 2}, { 2}, 31, 35, true, 2, 2}
+ , ival{{0, 2}, {0, 2}, 36, 50, true, 0, 0}
+ },
+ /* les */ 5,
+ /* min_peer */ 1,
+ /* osd states at end */
+ { make_pair(0, make_pair(PI::UP , 0))
+ , make_pair(1, make_pair(PI::UP , 0))
+ , make_pair(2, make_pair(PI::LOST , 55))
+ },
+ /* acting */ {0, 1 },
+ /* up */ {0, 1 },
+ /* probe */ {pst(0), pst(1)},
+ /* down */ {2},
+ /* blocked_by */ {},
+ /* pg_down */ false);
+}
+
+TEST_F(PITest, past_intervals_ec_lost) {
+ run(
+ /* ec_pool */ true,
+ /* intervals */
+ { ival{{0, N, 2}, {0, N, 2}, 10, 20, true, 0, 0}
+ , ival{{N, 1, 2}, {N, 1, 2}, 21, 30, true, 1, 1}
+ , ival{{0, 1, N}, {0, 1, N}, 31, 35, true, 2, 2}
+ },
+ /* les */ 5,
+ /* min_peer */ 2,
+ /* osd states at end */
+ { make_pair(0, make_pair(PI::UP , 0))
+ , make_pair(1, make_pair(PI::LOST , 36))
+ , make_pair(2, make_pair(PI::UP , 0))
+ },
+ /* acting */ {0, N, 2},
+ /* up */ {0, N, 2},
+ /* probe */ {pst(0, sit(0)), pst(2, sit(2))},
+ /* down */ {1},
+ /* blocked_by */ {},
+ /* pg_down */ false);
+}
+
+
/*
* Local Variables:
* compile-command: "cd ../.. ;