summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorathanatos <rexludorum@gmail.com>2013-06-04 12:38:10 -0700
committerathanatos <rexludorum@gmail.com>2013-06-04 12:38:10 -0700
commit8d948f6109e0ac600ab450e8d71b9747ab1044bd (patch)
tree1a8479b6bc2df01acf81707ad4d9367ce1806b46
parentcdf5785c5e8b744f35ea34b2deb2a71edf8b9580 (diff)
parentddb3a8d6ae6174d57a58c59a73724975914ffd4b (diff)
downloadceph-8d948f6109e0ac600ab450e8d71b9747ab1044bd.tar.gz
Merge pull request #327 from dachary/wip-pg_missing_t-tests
unit tests for pg_missing_t Reviewed-by: Sam Just <sam.just@inktank.com>
-rw-r--r--src/test/test_osd_types.cc332
1 files changed, 319 insertions, 13 deletions
diff --git a/src/test/test_osd_types.cc b/src/test/test_osd_types.cc
index d3f5364f793..c0a9a95b11a 100644
--- a/src/test/test_osd_types.cc
+++ b/src/test/test_osd_types.cc
@@ -4,6 +4,9 @@
* Ceph - scalable distributed file system
*
* Copyright (C) 2011 New Dream Network
+ * Copyright (C) 2013 Cloudwatt <libre.licensing@cloudwatt.com>
+ *
+ * Author: Loic Dachary <loic@dachary.org>
*
* This is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public
@@ -224,25 +227,328 @@ TEST(pg_missing_t, constructor)
EXPECT_FALSE(missing.have_missing());
}
-TEST(pg_missing_t, add_next_event)
+TEST(pg_missing_t, have_missing)
{
- pg_missing_t missing;
-
- // adding a DELETE entry
hobject_t oid(object_t("objname"), "key", 123, 456, 0);
- eversion_t version(1,2);
- eversion_t prior_version(3,4);
- pg_log_entry_t e(pg_log_entry_t::DELETE, oid, version, prior_version,
- osd_reqid_t(entity_name_t::CLIENT(777), 8, 999), utime_t(8,9));
- EXPECT_FALSE(missing.have_missing());
- missing.add_next_event(e);
+ pg_missing_t missing;
EXPECT_FALSE(missing.have_missing());
+ missing.add(oid, eversion_t(), eversion_t());
+ EXPECT_TRUE(missing.have_missing());
+}
- // adding a MODIFY entry
- e.op = pg_log_entry_t::MODIFY;
+TEST(pg_missing_t, swap)
+{
+ hobject_t oid(object_t("objname"), "key", 123, 456, 0);
+ pg_missing_t missing;
EXPECT_FALSE(missing.have_missing());
- missing.add_next_event(e);
+ missing.add(oid, eversion_t(), eversion_t());
EXPECT_TRUE(missing.have_missing());
+
+ pg_missing_t other;
+ EXPECT_FALSE(other.have_missing());
+
+ other.swap(missing);
+ EXPECT_FALSE(missing.have_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());
+ 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());
+ 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());
+ 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,
+ osd_reqid_t(entity_name_t::CLIENT(777), 8, 999), utime_t(8,9));
+
+ // 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_FALSE(missing.is_missing(oid));
+ missing.add_next_event(e);
+ EXPECT_TRUE(missing.is_missing(oid));
+ EXPECT_EQ(eversion_t(), missing.missing[oid].have);
+ EXPECT_EQ(oid, missing.rmissing[e.version.version]);
+ EXPECT_EQ(1U, missing.num_missing());
+ EXPECT_EQ(1U, missing.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.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_FALSE(missing.is_missing(oid));
+ missing.add_next_event(e);
+ EXPECT_TRUE(missing.is_missing(oid));
+ EXPECT_EQ(eversion_t(), missing.missing[oid].have);
+ EXPECT_EQ(oid, missing.rmissing[e.version.version]);
+ EXPECT_EQ(1U, missing.num_missing());
+ EXPECT_EQ(1U, missing.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.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_FALSE(missing.is_missing(oid));
+ missing.add_next_event(e);
+ EXPECT_TRUE(missing.is_missing(oid));
+ EXPECT_EQ(eversion_t(), missing.missing[oid].have);
+ EXPECT_EQ(oid, missing.rmissing[e.version.version]);
+ EXPECT_EQ(1U, missing.num_missing());
+ EXPECT_EQ(1U, missing.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.missing[oid].have);
+ EXPECT_TRUE(missing.is_missing(oid));
+ EXPECT_EQ(1U, missing.num_missing());
+ EXPECT_EQ(1U, missing.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_FALSE(missing.is_missing(oid));
+ missing.add_next_event(e);
+ EXPECT_TRUE(missing.is_missing(oid));
+ EXPECT_EQ(prior_version, missing.missing[oid].have);
+ EXPECT_EQ(version, missing.missing[oid].need);
+ EXPECT_EQ(oid, missing.rmissing[e.version.version]);
+ EXPECT_EQ(1U, missing.num_missing());
+ EXPECT_EQ(1U, missing.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_FALSE(missing.is_missing(oid));
+ EXPECT_THROW(missing.add_next_event(e), FailedAssertion);
+ }
+
+ // 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_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_FALSE(missing.have_missing());
+ }
+}
+
+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);
+ EXPECT_TRUE(missing.is_missing(oid));
+ EXPECT_EQ(eversion_t(), missing.missing[oid].have);
+ EXPECT_EQ(need, missing.missing[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.missing[oid].have);
+ missing.revise_need(oid, new_need);
+ EXPECT_EQ(have, missing.missing[oid].have);
+ EXPECT_EQ(new_need, missing.missing[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);
+ EXPECT_TRUE(missing.is_missing(oid));
+ eversion_t new_have(2,2);
+ EXPECT_EQ(have, missing.missing[oid].have);
+ missing.revise_have(oid, new_have);
+ EXPECT_EQ(new_have, missing.missing[oid].have);
+ EXPECT_EQ(need, missing.missing[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);
+ EXPECT_TRUE(missing.is_missing(oid));
+ EXPECT_EQ(have, missing.missing[oid].have);
+ EXPECT_EQ(need, missing.missing[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());
+ 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<hobject_t, pg_missing_t::item>::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());
+ EXPECT_TRUE(missing.is_missing(oid));
+ const std::map<hobject_t, pg_missing_t::item>::iterator m = missing.missing.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
+ EXPECT_THROW(missing.got(oid, eversion_t()), FailedAssertion);
+ EXPECT_FALSE(missing.is_missing(oid));
+ epoch_t epoch = 10;
+ eversion_t need(epoch,10);
+ missing.add(oid, need, eversion_t());
+ EXPECT_TRUE(missing.is_missing(oid));
+ // assert if that the version to be removed is lower than the version of the object
+ EXPECT_THROW(missing.got(oid, eversion_t(epoch / 2,20)), FailedAssertion);
+ // 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<hobject_t, pg_missing_t::item>::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());
+ EXPECT_TRUE(missing.is_missing(oid));
+ const std::map<hobject_t, pg_missing_t::item>::iterator m = missing.missing.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());
+ missing.add(oid2, eversion_t(), eversion_t());
+ 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));
}
// Local Variables: