X-Git-Url: https://gerrit.opnfv.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fceph%2Fsrc%2Ftest%2Fosd%2Ftypes.cc;fp=src%2Fceph%2Fsrc%2Ftest%2Fosd%2Ftypes.cc;h=0000000000000000000000000000000000000000;hb=7da45d65be36d36b880cc55c5036e96c24b53f00;hp=2a26c395a70df2d22ebdd1cea4ea5ebd298d9a86;hpb=691462d09d0987b47e112d6ee8740375df3c51b2;p=stor4nfv.git diff --git a/src/ceph/src/test/osd/types.cc b/src/ceph/src/test/osd/types.cc deleted file mode 100644 index 2a26c39..0000000 --- a/src/ceph/src/test/osd/types.cc +++ /dev/null @@ -1,1828 +0,0 @@ -// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- -// vim: ts=8 sw=2 smarttab -/* - * Ceph - scalable distributed file system - * - * Copyright (C) 2011 New Dream Network - * Copyright (C) 2013 Cloudwatt - * - * Author: Loic Dachary - * - * This is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License version 2, as published by the Free Software - * Foundation. See file COPYING. - * - */ - -#include "include/types.h" -#include "osd/osd_types.h" -#include "osd/OSDMap.h" -#include "gtest/gtest.h" -#include "include/coredumpctl.h" -#include "common/Thread.h" -#include "include/stringify.h" -#include "osd/ReplicatedBackend.h" - -#include - -TEST(hobject, prefixes0) -{ - uint32_t mask = 0xE947FA20; - uint32_t bits = 12; - int64_t pool = 0; - - set prefixes_correct; - prefixes_correct.insert(string("0000000000000000.02A")); - - set prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); - ASSERT_EQ(prefixes_out, prefixes_correct); -} - -TEST(hobject, prefixes1) -{ - uint32_t mask = 0x0000000F; - uint32_t bits = 6; - int64_t pool = 20; - - set prefixes_correct; - prefixes_correct.insert(string("0000000000000014.F0")); - prefixes_correct.insert(string("0000000000000014.F4")); - prefixes_correct.insert(string("0000000000000014.F8")); - prefixes_correct.insert(string("0000000000000014.FC")); - - set prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); - ASSERT_EQ(prefixes_out, prefixes_correct); -} - -TEST(hobject, prefixes2) -{ - uint32_t mask = 0xDEADBEAF; - uint32_t bits = 25; - int64_t pool = 0; - - set prefixes_correct; - prefixes_correct.insert(string("0000000000000000.FAEBDA0")); - prefixes_correct.insert(string("0000000000000000.FAEBDA2")); - prefixes_correct.insert(string("0000000000000000.FAEBDA4")); - prefixes_correct.insert(string("0000000000000000.FAEBDA6")); - prefixes_correct.insert(string("0000000000000000.FAEBDA8")); - prefixes_correct.insert(string("0000000000000000.FAEBDAA")); - prefixes_correct.insert(string("0000000000000000.FAEBDAC")); - prefixes_correct.insert(string("0000000000000000.FAEBDAE")); - - set prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); - ASSERT_EQ(prefixes_out, prefixes_correct); -} - -TEST(hobject, prefixes3) -{ - uint32_t mask = 0xE947FA20; - uint32_t bits = 32; - int64_t pool = 0x23; - - set prefixes_correct; - prefixes_correct.insert(string("0000000000000023.02AF749E")); - - set prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); - ASSERT_EQ(prefixes_out, prefixes_correct); -} - -TEST(hobject, prefixes4) -{ - uint32_t mask = 0xE947FA20; - uint32_t bits = 0; - int64_t pool = 0x23; - - set prefixes_correct; - prefixes_correct.insert(string("0000000000000023.")); - - set prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); - ASSERT_EQ(prefixes_out, prefixes_correct); -} - -TEST(hobject, prefixes5) -{ - uint32_t mask = 0xDEADBEAF; - uint32_t bits = 1; - int64_t pool = 0x34AC5D00; - - set prefixes_correct; - prefixes_correct.insert(string("0000000034AC5D00.1")); - prefixes_correct.insert(string("0000000034AC5D00.3")); - prefixes_correct.insert(string("0000000034AC5D00.5")); - prefixes_correct.insert(string("0000000034AC5D00.7")); - prefixes_correct.insert(string("0000000034AC5D00.9")); - prefixes_correct.insert(string("0000000034AC5D00.B")); - prefixes_correct.insert(string("0000000034AC5D00.D")); - prefixes_correct.insert(string("0000000034AC5D00.F")); - - set prefixes_out(hobject_t::get_prefixes(bits, mask, pool)); - ASSERT_EQ(prefixes_out, prefixes_correct); -} - -TEST(pg_interval_t, check_new_interval) -{ -// iterate through all 4 combinations -for (unsigned i = 0; i < 4; ++i) { - bool compact = i & 1; - bool ec_pool = i & 2; - // - // Create a situation where osdmaps are the same so that - // each test case can diverge from it using minimal code. - // - int osd_id = 1; - epoch_t epoch = 40; - ceph::shared_ptr osdmap(new OSDMap()); - osdmap->set_max_osd(10); - osdmap->set_state(osd_id, CEPH_OSD_EXISTS); - osdmap->set_epoch(epoch); - ceph::shared_ptr lastmap(new OSDMap()); - lastmap->set_max_osd(10); - lastmap->set_state(osd_id, CEPH_OSD_EXISTS); - lastmap->set_epoch(epoch); - epoch_t same_interval_since = epoch; - epoch_t last_epoch_clean = same_interval_since; - int64_t pool_id = 200; - int pg_num = 4; - __u8 min_size = 2; - boost::scoped_ptr recoverable(new ReplicatedBackend::RPCRecPred()); - { - OSDMap::Incremental inc(epoch + 1); - inc.new_pools[pool_id].min_size = min_size; - inc.new_pools[pool_id].set_pg_num(pg_num); - inc.new_up_thru[osd_id] = epoch + 1; - osdmap->apply_incremental(inc); - lastmap->apply_incremental(inc); - } - vector new_acting; - new_acting.push_back(osd_id); - new_acting.push_back(osd_id + 1); - vector old_acting = new_acting; - int old_primary = osd_id; - int new_primary = osd_id; - vector new_up; - new_up.push_back(osd_id); - int old_up_primary = osd_id; - int new_up_primary = osd_id; - vector old_up = new_up; - pg_t pgid; - pgid.set_pool(pool_id); - - // - // Do nothing if there are no modifications in - // acting, up or pool size and that the pool is not - // being split - // - { - PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact); - - ASSERT_TRUE(past_intervals.empty()); - ASSERT_FALSE(PastIntervals::check_new_interval(old_primary, - new_primary, - old_acting, - new_acting, - old_up_primary, - new_up_primary, - old_up, - new_up, - same_interval_since, - last_epoch_clean, - osdmap, - lastmap, - pgid, - recoverable.get(), - &past_intervals)); - ASSERT_TRUE(past_intervals.empty()); - } - - // - // The acting set has changed - // - { - vector new_acting; - int _new_primary = osd_id + 1; - new_acting.push_back(_new_primary); - - PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact); - - ASSERT_TRUE(past_intervals.empty()); - ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, - new_primary, - old_acting, - new_acting, - old_up_primary, - new_up_primary, - old_up, - new_up, - same_interval_since, - last_epoch_clean, - osdmap, - lastmap, - pgid, - recoverable.get(), - &past_intervals)); - old_primary = new_primary; - } - - // - // The up set has changed - // - { - vector new_up; - int _new_primary = osd_id + 1; - new_up.push_back(_new_primary); - - PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact); - - ASSERT_TRUE(past_intervals.empty()); - ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, - new_primary, - old_acting, - new_acting, - old_up_primary, - new_up_primary, - old_up, - new_up, - same_interval_since, - last_epoch_clean, - osdmap, - lastmap, - pgid, - recoverable.get(), - &past_intervals)); - } - - // - // The up primary has changed - // - { - vector new_up; - int _new_up_primary = osd_id + 1; - - PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact); - - ASSERT_TRUE(past_intervals.empty()); - ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, - new_primary, - old_acting, - new_acting, - old_up_primary, - _new_up_primary, - old_up, - new_up, - same_interval_since, - last_epoch_clean, - osdmap, - lastmap, - pgid, - recoverable.get(), - &past_intervals)); - } - - // - // PG is splitting - // - { - ceph::shared_ptr osdmap(new OSDMap()); - osdmap->set_max_osd(10); - osdmap->set_state(osd_id, CEPH_OSD_EXISTS); - osdmap->set_epoch(epoch); - int new_pg_num = pg_num ^ 2; - OSDMap::Incremental inc(epoch + 1); - inc.new_pools[pool_id].min_size = min_size; - inc.new_pools[pool_id].set_pg_num(new_pg_num); - osdmap->apply_incremental(inc); - - PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact); - - ASSERT_TRUE(past_intervals.empty()); - ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, - new_primary, - old_acting, - new_acting, - old_up_primary, - new_up_primary, - old_up, - new_up, - same_interval_since, - last_epoch_clean, - osdmap, - lastmap, - pgid, - recoverable.get(), - &past_intervals)); - } - - // - // PG size has changed - // - { - ceph::shared_ptr osdmap(new OSDMap()); - osdmap->set_max_osd(10); - osdmap->set_state(osd_id, CEPH_OSD_EXISTS); - osdmap->set_epoch(epoch); - OSDMap::Incremental inc(epoch + 1); - __u8 new_min_size = min_size + 1; - inc.new_pools[pool_id].min_size = new_min_size; - inc.new_pools[pool_id].set_pg_num(pg_num); - osdmap->apply_incremental(inc); - - PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact); - - ASSERT_TRUE(past_intervals.empty()); - ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, - new_primary, - old_acting, - new_acting, - old_up_primary, - new_up_primary, - old_up, - new_up, - same_interval_since, - last_epoch_clean, - osdmap, - lastmap, - pgid, - recoverable.get(), - &past_intervals)); - } - - // - // The old acting set was empty : the previous interval could not - // have been rw - // - { - vector old_acting; - - PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact); - - ostringstream out; - - ASSERT_TRUE(past_intervals.empty()); - ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, - new_primary, - old_acting, - new_acting, - old_up_primary, - new_up_primary, - old_up, - new_up, - same_interval_since, - last_epoch_clean, - osdmap, - lastmap, - pgid, - recoverable.get(), - &past_intervals, - &out)); - ASSERT_NE(string::npos, out.str().find("acting set is too small")); - } - - // - // The old acting set did not have enough osd : it could - // not have been rw - // - { - vector old_acting; - old_acting.push_back(osd_id); - - // - // see http://tracker.ceph.com/issues/5780 - // the size of the old acting set should be compared - // with the min_size of the old osdmap - // - // The new osdmap is created so that it triggers the - // bug. - // - ceph::shared_ptr osdmap(new OSDMap()); - osdmap->set_max_osd(10); - osdmap->set_state(osd_id, CEPH_OSD_EXISTS); - osdmap->set_epoch(epoch); - OSDMap::Incremental inc(epoch + 1); - __u8 new_min_size = old_acting.size(); - inc.new_pools[pool_id].min_size = new_min_size; - inc.new_pools[pool_id].set_pg_num(pg_num); - osdmap->apply_incremental(inc); - - ostringstream out; - - PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact); - - ASSERT_TRUE(past_intervals.empty()); - ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, - new_primary, - old_acting, - new_acting, - old_up_primary, - new_up_primary, - old_up, - new_up, - same_interval_since, - last_epoch_clean, - osdmap, - lastmap, - pgid, - recoverable.get(), - &past_intervals, - &out)); - ASSERT_NE(string::npos, out.str().find("acting set is too small")); - } - - // - // The acting set changes. The old acting set primary was up during the - // previous interval and may have been rw. - // - { - vector new_acting; - new_acting.push_back(osd_id + 4); - new_acting.push_back(osd_id + 5); - - ostringstream out; - - PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact); - - ASSERT_TRUE(past_intervals.empty()); - ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, - new_primary, - old_acting, - new_acting, - old_up_primary, - new_up_primary, - old_up, - new_up, - same_interval_since, - last_epoch_clean, - osdmap, - lastmap, - pgid, - recoverable.get(), - &past_intervals, - &out)); - ASSERT_NE(string::npos, out.str().find("includes interval")); - } - // - // The acting set changes. The old acting set primary was not up - // during the old interval but last_epoch_clean is in the - // old interval and it may have been rw. - // - { - vector new_acting; - new_acting.push_back(osd_id + 4); - new_acting.push_back(osd_id + 5); - - ceph::shared_ptr lastmap(new OSDMap()); - lastmap->set_max_osd(10); - lastmap->set_state(osd_id, CEPH_OSD_EXISTS); - lastmap->set_epoch(epoch); - OSDMap::Incremental inc(epoch + 1); - inc.new_pools[pool_id].min_size = min_size; - inc.new_pools[pool_id].set_pg_num(pg_num); - inc.new_up_thru[osd_id] = epoch - 10; - lastmap->apply_incremental(inc); - - ostringstream out; - - PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact); - - ASSERT_TRUE(past_intervals.empty()); - ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, - new_primary, - old_acting, - new_acting, - old_up_primary, - new_up_primary, - old_up, - new_up, - same_interval_since, - last_epoch_clean, - osdmap, - lastmap, - pgid, - recoverable.get(), - &past_intervals, - &out)); - ASSERT_NE(string::npos, out.str().find("presumed to have been rw")); - } - - // - // The acting set changes. The old acting set primary was not up - // during the old interval and last_epoch_clean is before the - // old interval : the previous interval could not possibly have - // been rw. - // - { - vector new_acting; - new_acting.push_back(osd_id + 4); - new_acting.push_back(osd_id + 5); - - epoch_t last_epoch_clean = epoch - 10; - - ceph::shared_ptr lastmap(new OSDMap()); - lastmap->set_max_osd(10); - lastmap->set_state(osd_id, CEPH_OSD_EXISTS); - lastmap->set_epoch(epoch); - OSDMap::Incremental inc(epoch + 1); - inc.new_pools[pool_id].min_size = min_size; - inc.new_pools[pool_id].set_pg_num(pg_num); - inc.new_up_thru[osd_id] = last_epoch_clean; - lastmap->apply_incremental(inc); - - ostringstream out; - - PastIntervals past_intervals; past_intervals.update_type(ec_pool, compact); - - ASSERT_TRUE(past_intervals.empty()); - ASSERT_TRUE(PastIntervals::check_new_interval(old_primary, - new_primary, - old_acting, - new_acting, - old_up_primary, - new_up_primary, - old_up, - new_up, - same_interval_since, - last_epoch_clean, - osdmap, - lastmap, - pgid, - recoverable.get(), - &past_intervals, - &out)); - ASSERT_NE(string::npos, out.str().find("does not include interval")); - } -} // end for, didn't want to reindent -} - -TEST(pg_t, get_ancestor) -{ - ASSERT_EQ(pg_t(0, 0, -1), pg_t(16, 0, -1).get_ancestor(16)); - ASSERT_EQ(pg_t(1, 0, -1), pg_t(17, 0, -1).get_ancestor(16)); - ASSERT_EQ(pg_t(0, 0, -1), pg_t(16, 0, -1).get_ancestor(8)); - ASSERT_EQ(pg_t(16, 0, -1), pg_t(16, 0, -1).get_ancestor(80)); - ASSERT_EQ(pg_t(16, 0, -1), pg_t(16, 0, -1).get_ancestor(83)); - ASSERT_EQ(pg_t(1, 0, -1), pg_t(1321, 0, -1).get_ancestor(123).get_ancestor(8)); - ASSERT_EQ(pg_t(3, 0, -1), pg_t(1323, 0, -1).get_ancestor(123).get_ancestor(8)); - ASSERT_EQ(pg_t(3, 0, -1), pg_t(1323, 0, -1).get_ancestor(8)); -} - -TEST(pg_t, split) -{ - pg_t pgid(0, 0, -1); - set s; - bool b; - - s.clear(); - b = pgid.is_split(1, 1, &s); - ASSERT_TRUE(!b); - - s.clear(); - b = pgid.is_split(2, 4, NULL); - ASSERT_TRUE(b); - b = pgid.is_split(2, 4, &s); - ASSERT_TRUE(b); - ASSERT_EQ(1u, s.size()); - ASSERT_TRUE(s.count(pg_t(2, 0, -1))); - - s.clear(); - b = pgid.is_split(2, 8, &s); - ASSERT_TRUE(b); - ASSERT_EQ(3u, s.size()); - ASSERT_TRUE(s.count(pg_t(2, 0, -1))); - ASSERT_TRUE(s.count(pg_t(4, 0, -1))); - ASSERT_TRUE(s.count(pg_t(6, 0, -1))); - - s.clear(); - b = pgid.is_split(3, 8, &s); - ASSERT_TRUE(b); - ASSERT_EQ(1u, s.size()); - ASSERT_TRUE(s.count(pg_t(4, 0, -1))); - - s.clear(); - b = pgid.is_split(6, 8, NULL); - ASSERT_TRUE(!b); - b = pgid.is_split(6, 8, &s); - ASSERT_TRUE(!b); - ASSERT_EQ(0u, s.size()); - - pgid = pg_t(1, 0, -1); - - s.clear(); - b = pgid.is_split(2, 4, &s); - ASSERT_TRUE(b); - ASSERT_EQ(1u, s.size()); - ASSERT_TRUE(s.count(pg_t(3, 0, -1))); - - s.clear(); - b = pgid.is_split(2, 6, &s); - ASSERT_TRUE(b); - ASSERT_EQ(2u, s.size()); - ASSERT_TRUE(s.count(pg_t(3, 0, -1))); - ASSERT_TRUE(s.count(pg_t(5, 0, -1))); - - s.clear(); - b = pgid.is_split(2, 8, &s); - ASSERT_TRUE(b); - ASSERT_EQ(3u, s.size()); - ASSERT_TRUE(s.count(pg_t(3, 0, -1))); - ASSERT_TRUE(s.count(pg_t(5, 0, -1))); - ASSERT_TRUE(s.count(pg_t(7, 0, -1))); - - s.clear(); - b = pgid.is_split(4, 8, &s); - ASSERT_TRUE(b); - ASSERT_EQ(1u, s.size()); - ASSERT_TRUE(s.count(pg_t(5, 0, -1))); - - s.clear(); - b = pgid.is_split(3, 8, &s); - ASSERT_TRUE(b); - ASSERT_EQ(3u, s.size()); - ASSERT_TRUE(s.count(pg_t(3, 0, -1))); - ASSERT_TRUE(s.count(pg_t(5, 0, -1))); - ASSERT_TRUE(s.count(pg_t(7, 0, -1))); - - s.clear(); - b = pgid.is_split(6, 8, &s); - ASSERT_TRUE(!b); - ASSERT_EQ(0u, s.size()); - - pgid = pg_t(3, 0, -1); - - s.clear(); - b = pgid.is_split(7, 8, &s); - ASSERT_TRUE(b); - ASSERT_EQ(1u, s.size()); - ASSERT_TRUE(s.count(pg_t(7, 0, -1))); - - s.clear(); - b = pgid.is_split(7, 12, &s); - ASSERT_TRUE(b); - ASSERT_EQ(2u, s.size()); - ASSERT_TRUE(s.count(pg_t(7, 0, -1))); - ASSERT_TRUE(s.count(pg_t(11, 0, -1))); - - s.clear(); - b = pgid.is_split(7, 11, &s); - ASSERT_TRUE(b); - ASSERT_EQ(1u, s.size()); - ASSERT_TRUE(s.count(pg_t(7, 0, -1))); - -} - -TEST(pg_missing_t, constructor) -{ - pg_missing_t missing; - EXPECT_EQ((unsigned int)0, missing.num_missing()); - EXPECT_FALSE(missing.have_missing()); -} - -TEST(pg_missing_t, have_missing) -{ - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - pg_missing_t missing; - EXPECT_FALSE(missing.have_missing()); - missing.add(oid, eversion_t(), eversion_t(), false); - EXPECT_TRUE(missing.have_missing()); -} - -TEST(pg_missing_t, claim) -{ - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - pg_missing_t missing; - EXPECT_FALSE(missing.have_missing()); - missing.add(oid, eversion_t(), eversion_t(), false); - EXPECT_TRUE(missing.have_missing()); - - pg_missing_t other; - EXPECT_FALSE(other.have_missing()); - - other.claim(missing); - EXPECT_TRUE(other.have_missing()); -} - -TEST(pg_missing_t, is_missing) -{ - // pg_missing_t::is_missing(const hobject_t& oid) const - { - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - pg_missing_t missing; - EXPECT_FALSE(missing.is_missing(oid)); - missing.add(oid, eversion_t(), eversion_t(), false); - EXPECT_TRUE(missing.is_missing(oid)); - } - - // bool pg_missing_t::is_missing(const hobject_t& oid, eversion_t v) const - { - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - pg_missing_t missing; - eversion_t need(10,5); - EXPECT_FALSE(missing.is_missing(oid, eversion_t())); - missing.add(oid, need, eversion_t(), false); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_FALSE(missing.is_missing(oid, eversion_t())); - EXPECT_TRUE(missing.is_missing(oid, need)); - } -} - -TEST(pg_missing_t, have_old) -{ - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - pg_missing_t missing; - EXPECT_EQ(eversion_t(), missing.have_old(oid)); - missing.add(oid, eversion_t(), eversion_t(), false); - EXPECT_EQ(eversion_t(), missing.have_old(oid)); - eversion_t have(1,1); - missing.revise_have(oid, have); - EXPECT_EQ(have, missing.have_old(oid)); -} - -TEST(pg_missing_t, add_next_event) -{ - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - hobject_t oid_other(object_t("other"), "key", 9123, 9456, 0, ""); - eversion_t version(10,5); - eversion_t prior_version(3,4); - pg_log_entry_t sample_e(pg_log_entry_t::DELETE, oid, version, prior_version, - 0, osd_reqid_t(entity_name_t::CLIENT(777), 8, 999), - utime_t(8,9), 0); - - // new object (MODIFY) - { - pg_missing_t missing; - pg_log_entry_t e = sample_e; - - e.op = pg_log_entry_t::MODIFY; - e.prior_version = eversion_t(); - EXPECT_TRUE(e.is_update()); - EXPECT_TRUE(e.object_is_indexed()); - EXPECT_TRUE(e.reqid_is_indexed()); - EXPECT_FALSE(missing.is_missing(oid)); - missing.add_next_event(e); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have); - EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version)); - EXPECT_EQ(1U, missing.num_missing()); - EXPECT_EQ(1U, missing.get_rmissing().size()); - - // adding the same object replaces the previous one - missing.add_next_event(e); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_EQ(1U, missing.num_missing()); - EXPECT_EQ(1U, missing.get_rmissing().size()); - } - - // new object (CLONE) - { - pg_missing_t missing; - pg_log_entry_t e = sample_e; - - e.op = pg_log_entry_t::CLONE; - e.prior_version = eversion_t(); - EXPECT_TRUE(e.is_clone()); - EXPECT_TRUE(e.object_is_indexed()); - EXPECT_FALSE(e.reqid_is_indexed()); - EXPECT_FALSE(missing.is_missing(oid)); - missing.add_next_event(e); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have); - EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version)); - EXPECT_EQ(1U, missing.num_missing()); - EXPECT_EQ(1U, missing.get_rmissing().size()); - - // adding the same object replaces the previous one - missing.add_next_event(e); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_EQ(1U, missing.num_missing()); - EXPECT_EQ(1U, missing.get_rmissing().size()); - } - - // existing object (MODIFY) - { - pg_missing_t missing; - pg_log_entry_t e = sample_e; - - e.op = pg_log_entry_t::MODIFY; - e.prior_version = eversion_t(); - EXPECT_TRUE(e.is_update()); - EXPECT_TRUE(e.object_is_indexed()); - EXPECT_TRUE(e.reqid_is_indexed()); - EXPECT_FALSE(missing.is_missing(oid)); - missing.add_next_event(e); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have); - EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version)); - EXPECT_EQ(1U, missing.num_missing()); - EXPECT_EQ(1U, missing.get_rmissing().size()); - - // adding the same object with a different version - e.prior_version = prior_version; - missing.add_next_event(e); - EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_EQ(1U, missing.num_missing()); - EXPECT_EQ(1U, missing.get_rmissing().size()); - } - - // object with prior version (MODIFY) - { - pg_missing_t missing; - pg_log_entry_t e = sample_e; - - e.op = pg_log_entry_t::MODIFY; - EXPECT_TRUE(e.is_update()); - EXPECT_TRUE(e.object_is_indexed()); - EXPECT_TRUE(e.reqid_is_indexed()); - EXPECT_FALSE(missing.is_missing(oid)); - missing.add_next_event(e); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_EQ(prior_version, missing.get_items().at(oid).have); - EXPECT_EQ(version, missing.get_items().at(oid).need); - EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version)); - EXPECT_EQ(1U, missing.num_missing()); - EXPECT_EQ(1U, missing.get_rmissing().size()); - } - - // obsolete (BACKLOG) - { - pg_missing_t missing; - pg_log_entry_t e = sample_e; - - e.op = pg_log_entry_t::BACKLOG; - EXPECT_TRUE(e.is_backlog()); - EXPECT_TRUE(e.object_is_indexed()); - EXPECT_FALSE(e.reqid_is_indexed()); - EXPECT_FALSE(missing.is_missing(oid)); - PrCtl unset_dumpable; - EXPECT_DEATH(missing.add_next_event(e), ""); - } - - // adding a DELETE matching an existing event - { - pg_missing_t missing; - pg_log_entry_t e = sample_e; - - e.op = pg_log_entry_t::MODIFY; - EXPECT_TRUE(e.is_update()); - EXPECT_TRUE(e.object_is_indexed()); - EXPECT_TRUE(e.reqid_is_indexed()); - EXPECT_FALSE(missing.is_missing(oid)); - missing.add_next_event(e); - EXPECT_TRUE(missing.is_missing(oid)); - - e.op = pg_log_entry_t::DELETE; - EXPECT_TRUE(e.is_delete()); - missing.add_next_event(e); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_TRUE(missing.get_items().at(oid).is_delete()); - EXPECT_EQ(prior_version, missing.get_items().at(oid).have); - EXPECT_EQ(version, missing.get_items().at(oid).need); - EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version)); - EXPECT_EQ(1U, missing.num_missing()); - EXPECT_EQ(1U, missing.get_rmissing().size()); - } - - // adding a LOST_DELETE after an existing event - { - pg_missing_t missing; - pg_log_entry_t e = sample_e; - - e.op = pg_log_entry_t::MODIFY; - EXPECT_TRUE(e.is_update()); - EXPECT_TRUE(e.object_is_indexed()); - EXPECT_TRUE(e.reqid_is_indexed()); - EXPECT_FALSE(missing.is_missing(oid)); - missing.add_next_event(e); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_FALSE(missing.get_items().at(oid).is_delete()); - - e.op = pg_log_entry_t::LOST_DELETE; - e.version.version++; - EXPECT_TRUE(e.is_delete()); - missing.add_next_event(e); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_TRUE(missing.get_items().at(oid).is_delete()); - EXPECT_EQ(prior_version, missing.get_items().at(oid).have); - EXPECT_EQ(e.version, missing.get_items().at(oid).need); - EXPECT_EQ(oid, missing.get_rmissing().at(e.version.version)); - EXPECT_EQ(1U, missing.num_missing()); - EXPECT_EQ(1U, missing.get_rmissing().size()); - } -} - -TEST(pg_missing_t, revise_need) -{ - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - pg_missing_t missing; - // create a new entry - EXPECT_FALSE(missing.is_missing(oid)); - eversion_t need(10,10); - missing.revise_need(oid, need, false); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_EQ(eversion_t(), missing.get_items().at(oid).have); - EXPECT_EQ(need, missing.get_items().at(oid).need); - // update an existing entry and preserve have - eversion_t have(1,1); - missing.revise_have(oid, have); - eversion_t new_need(10,12); - EXPECT_EQ(have, missing.get_items().at(oid).have); - missing.revise_need(oid, new_need, false); - EXPECT_EQ(have, missing.get_items().at(oid).have); - EXPECT_EQ(new_need, missing.get_items().at(oid).need); -} - -TEST(pg_missing_t, revise_have) -{ - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - pg_missing_t missing; - // a non existing entry means noop - EXPECT_FALSE(missing.is_missing(oid)); - eversion_t have(1,1); - missing.revise_have(oid, have); - EXPECT_FALSE(missing.is_missing(oid)); - // update an existing entry - eversion_t need(10,12); - missing.add(oid, need, have, false); - EXPECT_TRUE(missing.is_missing(oid)); - eversion_t new_have(2,2); - EXPECT_EQ(have, missing.get_items().at(oid).have); - missing.revise_have(oid, new_have); - EXPECT_EQ(new_have, missing.get_items().at(oid).have); - EXPECT_EQ(need, missing.get_items().at(oid).need); -} - -TEST(pg_missing_t, add) -{ - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - pg_missing_t missing; - EXPECT_FALSE(missing.is_missing(oid)); - eversion_t have(1,1); - eversion_t need(10,10); - missing.add(oid, need, have, false); - EXPECT_TRUE(missing.is_missing(oid)); - EXPECT_EQ(have, missing.get_items().at(oid).have); - EXPECT_EQ(need, missing.get_items().at(oid).need); -} - -TEST(pg_missing_t, rm) -{ - // void pg_missing_t::rm(const hobject_t& oid, eversion_t v) - { - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - pg_missing_t missing; - EXPECT_FALSE(missing.is_missing(oid)); - epoch_t epoch = 10; - eversion_t need(epoch,10); - missing.add(oid, need, eversion_t(), false); - EXPECT_TRUE(missing.is_missing(oid)); - // rm of an older version is a noop - missing.rm(oid, eversion_t(epoch / 2,20)); - EXPECT_TRUE(missing.is_missing(oid)); - // rm of a later version removes the object - missing.rm(oid, eversion_t(epoch * 2,20)); - EXPECT_FALSE(missing.is_missing(oid)); - } - // void pg_missing_t::rm(const std::map::iterator &m) - { - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - pg_missing_t missing; - EXPECT_FALSE(missing.is_missing(oid)); - missing.add(oid, eversion_t(), eversion_t(), false); - EXPECT_TRUE(missing.is_missing(oid)); - auto m = missing.get_items().find(oid); - missing.rm(m); - EXPECT_FALSE(missing.is_missing(oid)); - } -} - -TEST(pg_missing_t, got) -{ - // void pg_missing_t::got(const hobject_t& oid, eversion_t v) - { - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - pg_missing_t missing; - // assert if the oid does not exist - { - PrCtl unset_dumpable; - EXPECT_DEATH(missing.got(oid, eversion_t()), ""); - } - EXPECT_FALSE(missing.is_missing(oid)); - epoch_t epoch = 10; - eversion_t need(epoch,10); - missing.add(oid, need, eversion_t(), false); - EXPECT_TRUE(missing.is_missing(oid)); - // assert if that the version to be removed is lower than the version of the object - { - PrCtl unset_dumpable; - EXPECT_DEATH(missing.got(oid, eversion_t(epoch / 2,20)), ""); - } - // remove of a later version removes the object - missing.got(oid, eversion_t(epoch * 2,20)); - EXPECT_FALSE(missing.is_missing(oid)); - } - // void pg_missing_t::got(const std::map::iterator &m) - { - hobject_t oid(object_t("objname"), "key", 123, 456, 0, ""); - pg_missing_t missing; - EXPECT_FALSE(missing.is_missing(oid)); - missing.add(oid, eversion_t(), eversion_t(), false); - EXPECT_TRUE(missing.is_missing(oid)); - auto m = missing.get_items().find(oid); - missing.got(m); - EXPECT_FALSE(missing.is_missing(oid)); - } -} - -TEST(pg_missing_t, split_into) -{ - uint32_t hash1 = 1; - hobject_t oid1(object_t("objname"), "key1", 123, hash1, 0, ""); - uint32_t hash2 = 2; - hobject_t oid2(object_t("objname"), "key2", 123, hash2, 0, ""); - pg_missing_t missing; - missing.add(oid1, eversion_t(), eversion_t(), false); - missing.add(oid2, eversion_t(), eversion_t(), false); - pg_t child_pgid; - child_pgid.m_seed = 1; - pg_missing_t child; - unsigned split_bits = 1; - missing.split_into(child_pgid, split_bits, &child); - EXPECT_TRUE(child.is_missing(oid1)); - EXPECT_FALSE(child.is_missing(oid2)); - EXPECT_FALSE(missing.is_missing(oid1)); - EXPECT_TRUE(missing.is_missing(oid2)); -} - -class ObjectContextTest : public ::testing::Test { -protected: - - static const useconds_t DELAY_MAX = 20 * 1000 * 1000; - - class Thread_read_lock : public Thread { - public: - ObjectContext &obc; - - explicit Thread_read_lock(ObjectContext& _obc) : - obc(_obc) - { - } - - void *entry() override { - obc.ondisk_read_lock(); - return NULL; - } - }; - - class Thread_write_lock : public Thread { - public: - ObjectContext &obc; - - explicit Thread_write_lock(ObjectContext& _obc) : - obc(_obc) - { - } - - void *entry() override { - obc.ondisk_write_lock(); - return NULL; - } - }; - -}; - -TEST_F(ObjectContextTest, read_write_lock) -{ - { - ObjectContext obc; - - // - // write_lock - // write_lock - // write_unlock - // write_unlock - // - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(0, obc.unstable_writes); - - obc.ondisk_write_lock(); - - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(1, obc.unstable_writes); - - obc.ondisk_write_lock(); - - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(2, obc.unstable_writes); - - obc.ondisk_write_unlock(); - - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(1, obc.unstable_writes); - - obc.ondisk_write_unlock(); - - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(0, obc.unstable_writes); - } - - useconds_t delay = 0; - - { - ObjectContext obc; - - // - // write_lock - // read_lock => wait - // write_unlock => signal - // read_unlock - // - EXPECT_EQ(0, obc.readers_waiting); - EXPECT_EQ(0, obc.readers); - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(0, obc.unstable_writes); - - obc.ondisk_write_lock(); - - EXPECT_EQ(0, obc.readers_waiting); - EXPECT_EQ(0, obc.readers); - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(1, obc.unstable_writes); - - Thread_read_lock t(obc); - t.create("obc_read"); - - do { - cout << "Trying (1) with delay " << delay << "us\n"; - usleep(delay); - } while (obc.readers_waiting == 0 && - ( delay = delay * 2 + 1) < DELAY_MAX); - - EXPECT_EQ(1, obc.readers_waiting); - EXPECT_EQ(0, obc.readers); - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(1, obc.unstable_writes); - - obc.ondisk_write_unlock(); - - do { - cout << "Trying (2) with delay " << delay << "us\n"; - usleep(delay); - } while ((obc.readers == 0 || obc.readers_waiting == 1) && - ( delay = delay * 2 + 1) < DELAY_MAX); - EXPECT_EQ(0, obc.readers_waiting); - EXPECT_EQ(1, obc.readers); - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(0, obc.unstable_writes); - - obc.ondisk_read_unlock(); - - EXPECT_EQ(0, obc.readers_waiting); - EXPECT_EQ(0, obc.readers); - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(0, obc.unstable_writes); - - t.join(); - } - - { - ObjectContext obc; - - // - // read_lock - // write_lock => wait - // read_unlock => signal - // write_unlock - // - EXPECT_EQ(0, obc.readers_waiting); - EXPECT_EQ(0, obc.readers); - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(0, obc.unstable_writes); - - obc.ondisk_read_lock(); - - EXPECT_EQ(0, obc.readers_waiting); - EXPECT_EQ(1, obc.readers); - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(0, obc.unstable_writes); - - Thread_write_lock t(obc); - t.create("obc_write"); - - do { - cout << "Trying (3) with delay " << delay << "us\n"; - usleep(delay); - } while ((obc.writers_waiting == 0) && - ( delay = delay * 2 + 1) < DELAY_MAX); - - EXPECT_EQ(0, obc.readers_waiting); - EXPECT_EQ(1, obc.readers); - EXPECT_EQ(1, obc.writers_waiting); - EXPECT_EQ(0, obc.unstable_writes); - - obc.ondisk_read_unlock(); - - do { - cout << "Trying (4) with delay " << delay << "us\n"; - usleep(delay); - } while ((obc.unstable_writes == 0 || obc.writers_waiting == 1) && - ( delay = delay * 2 + 1) < DELAY_MAX); - - EXPECT_EQ(0, obc.readers_waiting); - EXPECT_EQ(0, obc.readers); - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(1, obc.unstable_writes); - - obc.ondisk_write_unlock(); - - EXPECT_EQ(0, obc.readers_waiting); - EXPECT_EQ(0, obc.readers); - EXPECT_EQ(0, obc.writers_waiting); - EXPECT_EQ(0, obc.unstable_writes); - - t.join(); - } - -} - -TEST(pg_pool_t_test, get_pg_num_divisor) { - pg_pool_t p; - p.set_pg_num(16); - p.set_pgp_num(16); - - for (int i = 0; i < 16; ++i) - ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(i, 1))); - - p.set_pg_num(12); - p.set_pgp_num(12); - - ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(0, 1))); - ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(1, 1))); - ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(2, 1))); - ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(3, 1))); - ASSERT_EQ(8u, p.get_pg_num_divisor(pg_t(4, 1))); - ASSERT_EQ(8u, p.get_pg_num_divisor(pg_t(5, 1))); - ASSERT_EQ(8u, p.get_pg_num_divisor(pg_t(6, 1))); - ASSERT_EQ(8u, p.get_pg_num_divisor(pg_t(7, 1))); - ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(8, 1))); - ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(9, 1))); - ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(10, 1))); - ASSERT_EQ(16u, p.get_pg_num_divisor(pg_t(11, 1))); -} - -TEST(pg_pool_t_test, get_random_pg_position) { - srand(getpid()); - for (int i = 0; i < 100; ++i) { - pg_pool_t p; - p.set_pg_num(1 + (rand() % 1000)); - p.set_pgp_num(p.get_pg_num()); - pg_t pgid(rand() % p.get_pg_num(), 1); - uint32_t h = p.get_random_pg_position(pgid, rand()); - uint32_t ps = p.raw_hash_to_pg(h); - cout << p.get_pg_num() << " " << pgid << ": " - << h << " -> " << pg_t(ps, 1) << std::endl; - ASSERT_EQ(pgid.ps(), ps); - } -} - -TEST(shard_id_t, iostream) { - set shards; - shards.insert(shard_id_t(0)); - shards.insert(shard_id_t(1)); - shards.insert(shard_id_t(2)); - ostringstream out; - out << shards; - ASSERT_EQ(out.str(), "0,1,2"); - - shard_id_t noshard = shard_id_t::NO_SHARD; - shard_id_t zero(0); - ASSERT_GT(zero, noshard); -} - -TEST(spg_t, parse) { - spg_t a(pg_t(1,2), shard_id_t::NO_SHARD); - spg_t aa, bb; - spg_t b(pg_t(3,2), shard_id_t(2)); - std::string s = stringify(a); - ASSERT_TRUE(aa.parse(s.c_str())); - ASSERT_EQ(a, aa); - - s = stringify(b); - ASSERT_TRUE(bb.parse(s.c_str())); - ASSERT_EQ(b, bb); -} - -TEST(coll_t, parse) { - const char *ok[] = { - "meta", - "1.2_head", - "1.2_TEMP", - "1.2s3_head", - "1.3s2_TEMP", - "1.2s0_head", - 0 - }; - const char *bad[] = { - "foo", - "1.2_food", - "1.2_head ", - //" 1.2_head", // hrm, this parses, which is not ideal.. pg_t's fault? - "1.2_temp", - "1.2_HEAD", - "1.xS3_HEAD", - "1.2s_HEAD", - "1.2sfoo_HEAD", - 0 - }; - coll_t a; - for (int i = 0; ok[i]; ++i) { - cout << "check ok " << ok[i] << std::endl; - ASSERT_TRUE(a.parse(ok[i])); - ASSERT_EQ(string(ok[i]), a.to_str()); - } - for (int i = 0; bad[i]; ++i) { - cout << "check bad " << bad[i] << std::endl; - ASSERT_FALSE(a.parse(bad[i])); - } -} - -TEST(coll_t, temp) { - spg_t pgid; - coll_t foo(pgid); - ASSERT_EQ(foo.to_str(), string("0.0_head")); - - coll_t temp = foo.get_temp(); - ASSERT_EQ(temp.to_str(), string("0.0_TEMP")); - - spg_t pgid2; - ASSERT_TRUE(temp.is_temp()); - ASSERT_TRUE(temp.is_temp(&pgid2)); - ASSERT_EQ(pgid, pgid2); -} - -TEST(coll_t, assigment) { - spg_t pgid; - coll_t right(pgid); - ASSERT_EQ(right.to_str(), string("0.0_head")); - - coll_t left, middle; - - ASSERT_EQ(left.to_str(), string("meta")); - ASSERT_EQ(middle.to_str(), string("meta")); - - left = middle = right; - - ASSERT_EQ(left.to_str(), string("0.0_head")); - ASSERT_EQ(middle.to_str(), string("0.0_head")); - - ASSERT_NE(middle.c_str(), right.c_str()); - ASSERT_NE(left.c_str(), middle.c_str()); -} - -TEST(hobject_t, parse) { - const char *v[] = { - "MIN", - "MAX", - "-1:60c2fa6d:::inc_osdmap.1:0", - "-1:60c2fa6d:::inc_osdmap.1:333", - "0:00000000::::head", - "1:00000000:nspace:key:obj:head", - "-40:00000000:nspace::obj:head", - "20:00000000::key:obj:head", - "20:00000000:::o%fdj:head", - "20:00000000:::o%02fdj:head", - "20:00000000:::_zero_%00_:head", - NULL - }; - - for (unsigned i=0; v[i]; ++i) { - hobject_t o; - bool b = o.parse(v[i]); - if (!b) { - cout << "failed to parse " << v[i] << std::endl; - ASSERT_TRUE(false); - } - string s = stringify(o); - if (s != v[i]) { - cout << v[i] << " -> " << o << " -> " << s << std::endl; - ASSERT_EQ(s, string(v[i])); - } - } -} - -TEST(ghobject_t, cmp) { - ghobject_t min; - ghobject_t sep; - sep.set_shard(shard_id_t(1)); - sep.hobj.pool = -1; - cout << min << " < " << sep << std::endl; - ASSERT_TRUE(min < sep); - - sep.set_shard(shard_id_t::NO_SHARD); - cout << "sep shard " << sep.shard_id << std::endl; - ghobject_t o(hobject_t(object_t(), string(), CEPH_NOSNAP, 0x42, - 1, string())); - cout << "o " << o << std::endl; - ASSERT_TRUE(o > sep); -} - -TEST(ghobject_t, parse) { - const char *v[] = { - "GHMIN", - "GHMAX", - "13#0:00000000::::head#", - "13#0:00000000::::head#deadbeef", - "#-1:60c2fa6d:::inc_osdmap.1:333#deadbeef", - "#-1:60c2fa6d:::inc%02osdmap.1:333#deadbeef", - "#-1:60c2fa6d:::inc_osdmap.1:333#", - "1#MIN#deadbeefff", - "1#MAX#", - "#MAX#123", - "#-40:00000000:nspace::obj:head#", - NULL - }; - - for (unsigned i=0; v[i]; ++i) { - ghobject_t o; - bool b = o.parse(v[i]); - if (!b) { - cout << "failed to parse " << v[i] << std::endl; - ASSERT_TRUE(false); - } - string s = stringify(o); - if (s != v[i]) { - cout << v[i] << " -> " << o << " -> " << s << std::endl; - ASSERT_EQ(s, string(v[i])); - } - } -} - -TEST(pool_opts_t, invalid_opt) { - EXPECT_FALSE(pool_opts_t::is_opt_name("INVALID_OPT")); - PrCtl unset_dumpable; - EXPECT_DEATH(pool_opts_t::get_opt_desc("INVALID_OPT"), ""); -} - -TEST(pool_opts_t, scrub_min_interval) { - EXPECT_TRUE(pool_opts_t::is_opt_name("scrub_min_interval")); - EXPECT_EQ(pool_opts_t::get_opt_desc("scrub_min_interval"), - pool_opts_t::opt_desc_t(pool_opts_t::SCRUB_MIN_INTERVAL, - pool_opts_t::DOUBLE)); - - pool_opts_t opts; - EXPECT_FALSE(opts.is_set(pool_opts_t::SCRUB_MIN_INTERVAL)); - { - PrCtl unset_dumpable; - EXPECT_DEATH(opts.get(pool_opts_t::SCRUB_MIN_INTERVAL), ""); - } - double val; - EXPECT_FALSE(opts.get(pool_opts_t::SCRUB_MIN_INTERVAL, &val)); - opts.set(pool_opts_t::SCRUB_MIN_INTERVAL, static_cast(2015)); - EXPECT_TRUE(opts.get(pool_opts_t::SCRUB_MIN_INTERVAL, &val)); - EXPECT_EQ(val, 2015); - opts.unset(pool_opts_t::SCRUB_MIN_INTERVAL); - EXPECT_FALSE(opts.is_set(pool_opts_t::SCRUB_MIN_INTERVAL)); -} - -TEST(pool_opts_t, scrub_max_interval) { - EXPECT_TRUE(pool_opts_t::is_opt_name("scrub_max_interval")); - EXPECT_EQ(pool_opts_t::get_opt_desc("scrub_max_interval"), - pool_opts_t::opt_desc_t(pool_opts_t::SCRUB_MAX_INTERVAL, - pool_opts_t::DOUBLE)); - - pool_opts_t opts; - EXPECT_FALSE(opts.is_set(pool_opts_t::SCRUB_MAX_INTERVAL)); - { - PrCtl unset_dumpable; - EXPECT_DEATH(opts.get(pool_opts_t::SCRUB_MAX_INTERVAL), ""); - } - double val; - EXPECT_FALSE(opts.get(pool_opts_t::SCRUB_MAX_INTERVAL, &val)); - opts.set(pool_opts_t::SCRUB_MAX_INTERVAL, static_cast(2015)); - EXPECT_TRUE(opts.get(pool_opts_t::SCRUB_MAX_INTERVAL, &val)); - EXPECT_EQ(val, 2015); - opts.unset(pool_opts_t::SCRUB_MAX_INTERVAL); - EXPECT_FALSE(opts.is_set(pool_opts_t::SCRUB_MAX_INTERVAL)); -} - -TEST(pool_opts_t, deep_scrub_interval) { - EXPECT_TRUE(pool_opts_t::is_opt_name("deep_scrub_interval")); - EXPECT_EQ(pool_opts_t::get_opt_desc("deep_scrub_interval"), - pool_opts_t::opt_desc_t(pool_opts_t::DEEP_SCRUB_INTERVAL, - pool_opts_t::DOUBLE)); - - pool_opts_t opts; - EXPECT_FALSE(opts.is_set(pool_opts_t::DEEP_SCRUB_INTERVAL)); - { - PrCtl unset_dumpable; - EXPECT_DEATH(opts.get(pool_opts_t::DEEP_SCRUB_INTERVAL), ""); - } - double val; - EXPECT_FALSE(opts.get(pool_opts_t::DEEP_SCRUB_INTERVAL, &val)); - opts.set(pool_opts_t::DEEP_SCRUB_INTERVAL, static_cast(2015)); - EXPECT_TRUE(opts.get(pool_opts_t::DEEP_SCRUB_INTERVAL, &val)); - EXPECT_EQ(val, 2015); - opts.unset(pool_opts_t::DEEP_SCRUB_INTERVAL); - 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 &have) const override { - return have.size() >= required_size; - } -}; - -using namespace std; -struct MapPredicate { - map> states; - MapPredicate( - vector>> _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; -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>> osd_states, - vector up, - vector acting, - set probe, - set down, - map 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, 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_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, 0, 0} - }, - /* 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, 0, 0} - }, - /* 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, 0, 0} - }, - /* 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 ../.. ; - * make unittest_osd_types ; - * ./unittest_osd_types # --gtest_filter=pg_missing_t.constructor - * " - * End: - */