]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
test/crimson/seastore: update test_transaction_manager for replay
authorSamuel Just <sjust@redhat.com>
Wed, 17 Jun 2020 22:24:25 +0000 (15:24 -0700)
committerSamuel Just <sjust@redhat.com>
Fri, 19 Jun 2020 19:59:26 +0000 (12:59 -0700)
TestBlock now has deltas and test_transaction_manager validates
a simple replay case.

Signed-off-by: Samuel Just <sjust@redhat.com>
src/crimson/os/seastore/CMakeLists.txt
src/test/crimson/seastore/CMakeLists.txt
src/test/crimson/seastore/test_block.cc [new file with mode: 0644]
src/test/crimson/seastore/test_block.h
src/test/crimson/seastore/test_transaction_manager.cc

index 4acc48f05d4796b0715b16ff0daf9efc7252ea1f..76ac9b6574831551ffbe9754dba376aef0a32a47 100644 (file)
@@ -14,6 +14,7 @@ add_library(crimson-seastore
   onode_manager/simple-fltree/onode_delta.cc
   onode_manager/simple-fltree/onode_node.cc
   seastore.cc
+  ../../../test/crimson/seastore/test_block.cc
        )
 target_link_libraries(crimson-seastore
   crimson)
index 458cc051db9d6f86a5118214272cbb038d53ef70..e84a4d6171a2410b84e37c7b294b864a745e6364 100644 (file)
@@ -1,4 +1,5 @@
 add_executable(unittest_transaction_manager
+  test_block.cc
   test_transaction_manager.cc
   ../gtest_seastar.cc)
 add_ceph_unittest(unittest_transaction_manager)
@@ -26,6 +27,7 @@ target_link_libraries(
   crimson-seastore)
 
 add_executable(unittest_seastore_cache
+  test_block.cc
   test_seastore_cache.cc)
 add_ceph_test(unittest_seastore_cache
   unittest_seastore_cache)
diff --git a/src/test/crimson/seastore/test_block.cc b/src/test/crimson/seastore/test_block.cc
new file mode 100644 (file)
index 0000000..649e73b
--- /dev/null
@@ -0,0 +1,25 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "test/crimson/seastore/test_block.h"
+
+namespace crimson::os::seastore {
+
+
+ceph::bufferlist TestBlock::get_delta() {
+  ceph::bufferlist bl;
+  ::encode(delta, bl);
+  return bl;
+}
+
+
+void TestBlock::apply_delta(const ceph::bufferlist &bl) {
+  auto biter = bl.begin();
+  decltype(delta) deltas;
+  ::decode(deltas, biter);
+  for (auto &&d : deltas) {
+    set_contents(d.val, d.offset, d.len);
+  }
+}
+
+}
index 4d96c6fe6c314629cb539e5e4a31b3af30674090..446e7ec031428d43c7431b4514ff9033fb06ee49 100644 (file)
@@ -3,6 +3,8 @@
 
 #pragma once
 
+#include <random>
+
 #include "crimson/os/seastore/transaction_manager.h"
 
 namespace crimson::os::seastore {
@@ -20,6 +22,21 @@ struct test_extent_desc_t {
   }
 };
 
+struct test_block_delta_t {
+  int8_t val = 0;
+  uint16_t offset = 0;
+  uint16_t len = 0;
+
+
+  DENC(test_block_delta_t, v, p) {
+    DENC_START(1, 1, p);
+    denc(v.val, p);
+    denc(v.offset, p);
+    denc(v.len, p);
+    DENC_FINISH(p);
+  }
+};
+
 inline std::ostream &operator<<(
   std::ostream &lhs, const test_extent_desc_t &rhs) {
   return lhs << "test_extent_desc_t(len=" << rhs.len
@@ -30,8 +47,12 @@ struct TestBlock : crimson::os::seastore::LogicalCachedExtent {
   constexpr static segment_off_t SIZE = 4<<10;
   using Ref = TCachedExtentRef<TestBlock>;
 
-  TestBlock(ceph::bufferptr &&ptr) : LogicalCachedExtent(std::move(ptr)) {}
-  TestBlock(const TestBlock &other) : LogicalCachedExtent(other) {}
+  std::vector<test_block_delta_t> delta = {};
+
+  TestBlock(ceph::bufferptr &&ptr)
+    : LogicalCachedExtent(std::move(ptr)) {}
+  TestBlock(const TestBlock &other)
+    : LogicalCachedExtent(other) {}
 
   CachedExtentRef duplicate_for_write() final {
     return CachedExtentRef(new TestBlock(*this));
@@ -42,12 +63,15 @@ struct TestBlock : crimson::os::seastore::LogicalCachedExtent {
     return TYPE;
   }
 
-  ceph::bufferlist get_delta() final {
-    return ceph::bufferlist();
+  ceph::bufferlist get_delta() final;
+
+  void set_contents(char c, uint16_t offset, uint16_t len) {
+    ::memset(get_bptr().c_str() + offset, c, len);
+    delta.push_back({c, offset, len});
   }
 
   void set_contents(char c) {
-    ::memset(get_bptr().c_str(), c, get_length());
+    set_contents(c, 0, get_length());
   }
 
   int checksum() {
@@ -61,10 +85,37 @@ struct TestBlock : crimson::os::seastore::LogicalCachedExtent {
     return { get_length(), get_crc32c(1) };
   }
 
-  void apply_delta(const ceph::bufferlist &bl) final {
-    ceph_assert(0 == "TODO");
-  }
+  void apply_delta(const ceph::bufferlist &bl) final;
 };
 using TestBlockRef = TCachedExtentRef<TestBlock>;
 
+struct test_block_mutator_t {
+  std::uniform_int_distribution<int8_t>
+  contents_distribution = std::uniform_int_distribution<int8_t>(
+    std::numeric_limits<int8_t>::min(),
+    std::numeric_limits<int8_t>::max());
+
+  std::uniform_int_distribution<uint16_t>
+  offset_distribution = std::uniform_int_distribution<uint16_t>(
+    0, TestBlock::SIZE - 1);
+
+  std::default_random_engine generator = std::default_random_engine(0);
+
+  std::uniform_int_distribution<uint16_t> length_distribution(uint16_t offset) {
+    return std::uniform_int_distribution<uint16_t>(
+      0, TestBlock::SIZE - offset - 1);
+  }
+
+
+  void mutate(TestBlock &block) {
+    auto offset = offset_distribution(generator);
+    block.set_contents(
+      contents_distribution(generator),
+      offset,
+      length_distribution(offset)(generator));
+  }
+};
+
 }
+
+WRITE_CLASS_DENC_BOUNDED(crimson::os::seastore::test_block_delta_t)
index 7ef6187183f6060b8d20330cf15f54c3337e4644..5c6cccbebefafe7f22e32580970c693d7de0c9b5 100644 (file)
@@ -146,6 +146,11 @@ struct transaction_manager_test_t : public seastar_test_suite_t {
     return extent;
   }
 
+  void replay() {
+    tm.close().unsafe_get();
+    tm.mount().unsafe_get();
+  }
+
   void check_mappings() {
     auto t = create_transaction();
     check_mappings(t);
@@ -169,16 +174,16 @@ struct transaction_manager_test_t : public seastar_test_suite_t {
     return ext;
   }
 
+  test_block_mutator_t mutator;
   TestBlockRef mutate_extent(
     test_transaction_t &t,
-    TestBlockRef ref,
-    char contents) {
+    TestBlockRef ref) {
     ceph_assert(t.mappings.count(ref->get_laddr()));
     ceph_assert(t.mappings[ref->get_laddr()].desc.len == ref->get_length());
     auto ext = tm.get_mutable_extent(*t.t, ref)->cast<TestBlock>();
     EXPECT_EQ(ext->get_laddr(), ref->get_laddr());
     EXPECT_EQ(ext->get_desc(), ref->get_desc());
-    ext->set_contents(contents);
+    mutator.mutate(*ext);
     t.mappings[ext->get_laddr()].update(ext->get_desc());
     return ext;
   }
@@ -255,18 +260,21 @@ TEST_F(transaction_manager_test_t, mutate)
       submit_transaction(std::move(t));
       check_mappings();
     }
+    replay();
     {
       auto t = create_transaction();
       auto ext = get_extent(
        t,
        ADDR,
        SIZE);
-      auto mut = mutate_extent(t, ext, 'c');
+      auto mut = mutate_extent(t, ext);
       check_mappings(t);
       check_mappings();
       submit_transaction(std::move(t));
       check_mappings();
     }
+    replay();
+    check_mappings();
   });
 }
 
@@ -288,6 +296,7 @@ TEST_F(transaction_manager_test_t, inc_dec_ref)
       submit_transaction(std::move(t));
       check_mappings();
     }
+    replay();
     {
       auto t = create_transaction();
       inc_ref(t, ADDR);
@@ -304,6 +313,7 @@ TEST_F(transaction_manager_test_t, inc_dec_ref)
       submit_transaction(std::move(t));
       check_mappings();
     }
+    replay();
     {
       auto t = create_transaction();
       dec_ref(t, ADDR);