]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
unit tests for PGLog::rewind_divergent_log 349/head
authorLoic Dachary <loic@dachary.org>
Sat, 8 Jun 2013 07:45:58 +0000 (09:45 +0200)
committerLoic Dachary <loic@dachary.org>
Mon, 10 Jun 2013 12:08:51 +0000 (14:08 +0200)
The tests covers 100% of the LOC of rewind_divergent_log. There are
three situations :

 * throw an assert because the data is inconsistent

 * special case when the entire logs is divergent

 * regular workflow where all divergent entries are run to
   merge_old_entry

http://tracker.ceph.com/issues/5213 refs #5213

Signed-off-by: Loic Dachary <loic@dachary.org>
src/test/osd/TestPGLog.cc

index 3cb90e94a1d4670fec1e31033c068f6a1be97dbb..896b6193a579120102ef78a59f91df8326465d66 100644 (file)
@@ -35,6 +35,172 @@ public:
   }
 };
 
+TEST_F(PGLogTest, rewind_divergent_log) {
+  // newhead > log.tail : throw an assert
+  {
+    clear();
+
+    ObjectStore::Transaction t;
+    pg_info_t info;
+    list<hobject_t> remove_snap;
+    bool dirty_log = false;
+    bool dirty_info = false;
+    bool dirty_big_info = false;
+
+    log.tail = eversion_t(2, 1);
+    EXPECT_THROW(rewind_divergent_log(t, eversion_t(1, 1), info, remove_snap,
+                                     dirty_log, dirty_info, dirty_big_info),
+                FailedAssertion);
+  }
+
+  /*        +----------------+
+            |  log           | 
+            +--------+-------+
+            |        |object |
+            |version | hash  |
+            |        |       |
+       tail > (1,1)  |  x5   |
+            |        |       |
+            |        |       |
+            | (1,4)  |  x9   < newhead
+            | MODIFY |       |
+            |        |       |
+       head > (1,5)  |  x9   |
+            | DELETE |       |
+            |        |       |
+            +--------+-------+
+
+  */
+  {
+    clear();
+
+    ObjectStore::Transaction t;
+    pg_info_t info;
+    list<hobject_t> remove_snap;
+    bool dirty_log = false;
+    bool dirty_info = false;
+    bool dirty_big_info = false;
+
+    hobject_t divergent_object;
+    eversion_t divergent_version;
+    eversion_t newhead;
+    {
+      pg_log_entry_t e;
+
+      e.version = eversion_t(1, 1);
+      e.soid.hash = 0x5;
+      log.tail = e.version;
+      log.log.push_back(e);
+      e.version = newhead = eversion_t(1, 4);
+      e.soid.hash = 0x9;
+      e.op = pg_log_entry_t::MODIFY;
+      log.log.push_back(e);
+      log.index();
+      e.version = divergent_version = eversion_t(1, 5);
+      e.soid.hash = 0x9;
+      divergent_object = e.soid;
+      e.op = pg_log_entry_t::DELETE;
+      log.log.push_back(e);
+      log.head = e.version;
+
+      info.last_update = log.head;
+      info.last_complete = log.head;
+    }
+
+    EXPECT_FALSE(missing.have_missing());
+    EXPECT_EQ(3U, log.log.size());
+    EXPECT_EQ(0U, ondisklog.length());
+    EXPECT_TRUE(remove_snap.empty());
+    EXPECT_TRUE(t.empty());
+    EXPECT_EQ(log.head, info.last_update);
+    EXPECT_EQ(log.head, info.last_complete);
+    EXPECT_FALSE(dirty_log);
+    EXPECT_FALSE(dirty_info);
+    EXPECT_FALSE(dirty_big_info);
+
+    rewind_divergent_log(t, newhead, info, remove_snap,
+                        dirty_log, dirty_info, dirty_big_info);
+
+    EXPECT_TRUE(missing.is_missing(divergent_object));
+    EXPECT_EQ(1U, log.objects.count(divergent_object));
+    EXPECT_EQ(2U, log.log.size());
+    EXPECT_EQ(0U, ondisklog.length());
+    EXPECT_TRUE(remove_snap.empty());
+    EXPECT_TRUE(t.empty());
+    EXPECT_EQ(newhead, info.last_update);
+    EXPECT_EQ(newhead, info.last_complete);
+    EXPECT_TRUE(dirty_log);
+    EXPECT_TRUE(dirty_info);
+    EXPECT_TRUE(dirty_big_info);
+  }
+
+  /*        +----------------+
+            |  log           | 
+            +--------+-------+
+            |        |object |
+            |version | hash  |
+            |        |       |
+       tail > (1,1)  | NULL  | 
+            |        |       |
+            | (1,4)  | NULL  < newhead
+            |        |       |
+       head > (1,5)  |  x9   |
+            |        |       |
+            +--------+-------+
+
+  */
+  {
+    clear();
+
+    ObjectStore::Transaction t;
+    pg_info_t info;
+    list<hobject_t> remove_snap;
+    bool dirty_log = false;
+    bool dirty_info = false;
+    bool dirty_big_info = false;
+
+    hobject_t divergent_object;
+    eversion_t divergent_version;
+    eversion_t prior_version;
+    eversion_t newhead;
+    {
+      pg_log_entry_t e;
+
+      info.log_tail = log.tail = eversion_t(1, 1);
+      newhead = eversion_t(1, 3);
+      e.version = divergent_version = eversion_t(1, 5);
+      e.soid.hash = 0x9;
+      divergent_object = e.soid;
+      e.op = pg_log_entry_t::DELETE;
+      e.prior_version = prior_version = eversion_t(0, 2);
+      log.log.push_back(e);
+      log.head = e.version;
+    }
+
+    EXPECT_FALSE(missing.have_missing());
+    EXPECT_EQ(1U, log.log.size());
+    EXPECT_EQ(0U, ondisklog.length());
+    EXPECT_TRUE(remove_snap.empty());
+    EXPECT_TRUE(t.empty());
+    EXPECT_FALSE(dirty_log);
+    EXPECT_FALSE(dirty_info);
+    EXPECT_FALSE(dirty_big_info);
+
+    rewind_divergent_log(t, newhead, info, remove_snap,
+                        dirty_log, dirty_info, dirty_big_info);
+
+    EXPECT_TRUE(missing.is_missing(divergent_object));
+    EXPECT_EQ(0U, log.objects.count(divergent_object));
+    EXPECT_TRUE(log.empty());
+    EXPECT_EQ(0U, ondisklog.length());
+    EXPECT_TRUE(remove_snap.empty());
+    EXPECT_TRUE(t.empty());
+    EXPECT_TRUE(dirty_log);
+    EXPECT_TRUE(dirty_info);
+    EXPECT_TRUE(dirty_big_info);
+  }
+}
+
 TEST_F(PGLogTest, merge_old_entry) {
   // entries > last_backfill are silently ignored
   {