]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
test/crimson/seastore: introduce EphemeralDevices to cover two diffence devices
authormyoungwon oh <ohmyoungwon@gmail.com>
Thu, 29 Sep 2022 02:06:29 +0000 (11:06 +0900)
committermyoungwon oh <ohmyoungwon@gmail.com>
Wed, 16 Nov 2022 09:15:17 +0000 (18:15 +0900)
Signed-off-by: Myoungwon Oh <myoungwon.oh@samsung.com>
src/test/crimson/seastore/test_transaction_manager.cc
src/test/crimson/seastore/transaction_manager_test_state.h

index c283d49ea3ec7369b8c0252f619d2f0aa5dcacb0..5bbd2e57daa50c740c9ac6fcdfa82cbe79610c3b 100644 (file)
@@ -1274,7 +1274,6 @@ INSTANTIATE_TEST_SUITE_P(
   transaction_manager_test,
   tm_multi_device_test_t,
   ::testing::Values (
-    "segmented",
-    "circularbounded"
+    "segmented"
   )
 );
index 4b79538e34e11a787dbcc4fa386230b10f5c7352..f6f36205d1f2a4db94a22d332a3801ec64226f96 100644 (file)
@@ -23,67 +23,30 @@ using namespace crimson;
 using namespace crimson::os;
 using namespace crimson::os::seastore;
 
-class EphemeralTestState {
-protected:
+class EphemeralDevices {
+public:
+  virtual seastar::future<> setup() = 0;
+  virtual void remount() = 0;
+  virtual std::size_t get_num_devices() const = 0;
+  virtual void reset() = 0;
+  virtual std::vector<Device*> get_secondary_devices() = 0;
+  virtual ~EphemeralDevices() {}
+  virtual Device* get_primary_device() = 0;
+  virtual DeviceRef get_primary_device_ref() = 0;
+};
+using EphemeralDevicesRef = std::unique_ptr<EphemeralDevices>;
+
+class EphemeralSegmentedDevices : public EphemeralDevices {
   segment_manager::EphemeralSegmentManagerRef segment_manager;
   std::list<segment_manager::EphemeralSegmentManagerRef> secondary_segment_managers;
-  random_block_device::RBMDeviceRef rb_device;
-  std::list<random_block_device::RBMDeviceRef> secondary_rb_devices;
-  journal_type_t journal_type;
 
-  EphemeralTestState(std::size_t num_device_managers) {
+public:
+  EphemeralSegmentedDevices(std::size_t num_device_managers) {
     assert(num_device_managers > 0);
     secondary_segment_managers.resize(num_device_managers - 1);
-    secondary_rb_devices.resize(num_device_managers - 1);
-  }
-
-  std::size_t get_num_devices() const {
-    if (journal_type == journal_type_t::SEGMENTED) {
-      return secondary_segment_managers.size() + 1;
-    } else {
-      assert(journal_type == journal_type_t::RANDOM_BLOCK);
-      return secondary_rb_devices.size() + 1;
-    }
-  }
-
-  virtual void _init() = 0;
-
-  virtual void _destroy() = 0;
-  virtual seastar::future<> _teardown() = 0;
-  seastar::future<> teardown() {
-    return _teardown().then([this] {
-      _destroy();
-    });
-  }
-
-
-  virtual FuturizedStore::mkfs_ertr::future<> _mkfs() = 0;
-  virtual FuturizedStore::mount_ertr::future<> _mount() = 0;
-
-  seastar::future<> restart_fut() {
-    LOG_PREFIX(EphemeralTestState::restart_fut);
-    SUBINFO(test, "begin ...");
-    return teardown().then([this] {
-      if (journal_type == journal_type_t::SEGMENTED) {
-       segment_manager->remount();
-       for (auto &sec_sm : secondary_segment_managers) {
-         sec_sm->remount();
-       }
-      }
-      _init();
-      return _mount().handle_error(crimson::ct_error::assert_all{});
-    }).then([FNAME] {
-      SUBINFO(test, "finish");
-    });
   }
 
-  void restart() {
-    restart_fut().get0();
-  }
-
-  seastar::future<> segment_setup()
-  {
-    LOG_PREFIX(EphemeralTestState::segment_setup);
+  seastar::future<> setup() final {
     segment_manager = segment_manager::create_test_ephemeral();
     for (auto &sec_sm : secondary_segment_managers) {
       sec_sm = segment_manager::create_test_ephemeral();
@@ -112,60 +75,160 @@ protected:
             segment_manager::get_ephemeral_device_config(cnt, get_num_devices()));
         });
       });
-    }).safe_then([this] {
-      _init();
-      return _mkfs();
-    }).safe_then([this] {
-      return restart_fut();
     }).handle_error(
       crimson::ct_error::assert_all{}
-    ).then([FNAME] {
-      SUBINFO(test, "finish");
-    });
+    );
+  }
+
+  void remount() final {
+    segment_manager->remount();
+    for (auto &sec_sm : secondary_segment_managers) {
+      sec_sm->remount();
+    }
   }
 
-  seastar::future<> randomblock_setup()
-  {
-    LOG_PREFIX(EphemeralTestState::randomblock_setup);
+  std::size_t get_num_devices() const final {
+    return secondary_segment_managers.size() + 1;
+  }
+
+  void reset() final {
+    segment_manager.reset();
+    for (auto &sec_sm : secondary_segment_managers) {
+      sec_sm.reset();
+    }
+  }
+
+  std::vector<Device*> get_secondary_devices() final {
+    std::vector<Device*> sec_devices;
+    for (auto &sec_sm : secondary_segment_managers) {
+      sec_devices.emplace_back(sec_sm.get());
+    }
+    return sec_devices;
+  }
+
+  Device* get_primary_device() final {
+    return segment_manager.get();
+  }
+  DeviceRef get_primary_device_ref() final;
+};
+
+class EphemeralRandomBlockDevices : public EphemeralDevices {
+  random_block_device::RBMDeviceRef rb_device;
+  std::list<random_block_device::RBMDeviceRef> secondary_rb_devices;
+
+public:
+  EphemeralRandomBlockDevices(std::size_t num_device_managers) {
+    assert(num_device_managers > 0);
+    secondary_rb_devices.resize(num_device_managers - 1);
+  }
+  
+  seastar::future<> setup() final {
     rb_device = random_block_device::create_test_ephemeral(
       journal::DEFAULT_TEST_CBJOURNAL_SIZE, journal::DEFAULT_TEST_CBJOURNAL_SIZE);
     return rb_device->mount().handle_error(crimson::ct_error::assert_all{}
     ).then([this]() {
       device_config_t config = get_rbm_ephemeral_device_config(0, 1);
       rb_device->set_journal_size(journal::DEFAULT_TEST_CBJOURNAL_SIZE);
-      return rb_device->mkfs(config).handle_error(crimson::ct_error::assert_all{}
-      ).then([this]() {
-       return segment_setup();
-      });
+      return rb_device->mkfs(config).handle_error(crimson::ct_error::assert_all{});
     });
   }
 
+  void remount() final {}
+
+  std::size_t get_num_devices() const final {
+    return secondary_rb_devices.size() + 1;
+  }
+
+  void reset() final {
+    rb_device.reset();
+    for (auto &sec_rb : secondary_rb_devices) {
+      sec_rb.reset();
+    }
+  }
+
+  std::vector<Device*> get_secondary_devices() final {
+    std::vector<Device*> sec_devices;
+    for (auto &sec_rb : secondary_rb_devices) {
+      sec_devices.emplace_back(sec_rb.get());
+    }
+    return sec_devices;
+  }
+
+  Device* get_primary_device() final {
+    return rb_device.get();
+  }
+  DeviceRef get_primary_device_ref() final;
+};
+
+class EphemeralTestState {
+protected:
+  journal_type_t journal_type;
+  size_t num_device_managers = 0;
+  EphemeralDevicesRef devices;
+  EphemeralTestState(std::size_t num_device_managers) :
+    num_device_managers(num_device_managers) {}
+
+  virtual void _init() = 0;
+
+  virtual void _destroy() = 0;
+  virtual seastar::future<> _teardown() = 0;
+  seastar::future<> teardown() {
+    return _teardown().then([this] {
+      _destroy();
+    });
+  }
+
+  virtual FuturizedStore::mkfs_ertr::future<> _mkfs() = 0;
+  virtual FuturizedStore::mount_ertr::future<> _mount() = 0;
+
+  seastar::future<> restart_fut() {
+    LOG_PREFIX(EphemeralTestState::restart_fut);
+    SUBINFO(test, "begin ...");
+    return teardown().then([this] {
+      devices->remount();
+      _init();
+      return _mount().handle_error(crimson::ct_error::assert_all{});
+    }).then([FNAME] {
+      SUBINFO(test, "finish");
+    });
+  }
+
+  void restart() {
+    restart_fut().get0();
+  }
+
   seastar::future<> tm_setup(
     journal_type_t type = journal_type_t::SEGMENTED) {
     LOG_PREFIX(EphemeralTestState::tm_setup);
     journal_type = type;
-    SUBINFO(test, "begin with {} devices ...", get_num_devices());
-    // FIXME: should not initialize segment_manager with circularbounded-journal
     if (journal_type == journal_type_t::SEGMENTED) {
-      return segment_setup();
+      devices.reset(new EphemeralSegmentedDevices(num_device_managers));
     } else {
       assert(journal_type == journal_type_t::RANDOM_BLOCK);
-      return randomblock_setup();
+      //TODO: multiple devices
+      ceph_assert(num_device_managers == 1);
+      devices.reset(new EphemeralRandomBlockDevices(1));
     }
+    SUBINFO(test, "begin with {} devices ...", devices->get_num_devices());
+    return devices->setup(
+    ).then([this, FNAME]() {                                                               
+      _init();
+      return _mkfs(
+      ).safe_then([this] {
+       return restart_fut();                                                               
+      }).handle_error(
+       crimson::ct_error::assert_all{}                                                     
+      ).then([FNAME] {
+       SUBINFO(test, "finish");                                                            
+      });                                                                                   
+    });   
   }
 
   seastar::future<> tm_teardown() {
     LOG_PREFIX(EphemeralTestState::tm_teardown);
     SUBINFO(test, "begin");
     return teardown().then([this, FNAME] {
-      segment_manager.reset();
-      for (auto &sec_sm : secondary_segment_managers) {
-        sec_sm.reset();
-      }
-      rb_device.reset();
-      for (auto &sec_rb : secondary_rb_devices) {
-        sec_rb.reset();
-      }
+      devices->reset();
       SUBINFO(test, "finish");
     });
   }
@@ -184,20 +247,9 @@ protected:
   TMTestState(std::size_t num_devices) : EphemeralTestState(num_devices) {}
 
   virtual void _init() override {
-    std::vector<Device*> sec_devices;
-    if (journal_type == journal_type_t::RANDOM_BLOCK) {
-      // FIXME: should not initialize segment_manager with circularbounded-journal
-      // FIXME: no secondary device in the single device test
-      for (auto &sec_rb : secondary_rb_devices) {
-       sec_devices.emplace_back(sec_rb.get());
-      }
-      tm = make_transaction_manager(rb_device.get(), sec_devices, true);
-    } else {
-      for (auto &sec_sm : secondary_segment_managers) {
-       sec_devices.emplace_back(sec_sm.get());
-      }
-      tm = make_transaction_manager(segment_manager.get(), sec_devices, true);
-    }
+    auto sec_devices = devices->get_secondary_devices();
+    auto p_dev = devices->get_primary_device();
+    tm = make_transaction_manager(p_dev, sec_devices, true);
     epm = tm->get_epm();
     lba_manager = tm->get_lba_manager();
     cache = tm->get_cache();
@@ -339,6 +391,68 @@ public:
   ~TestSegmentManagerWrapper() final {}
 };
 
+DeviceRef EphemeralSegmentedDevices::get_primary_device_ref() {
+  return std::make_unique<TestSegmentManagerWrapper>(*segment_manager);
+}
+
+class TestRandomBlockDeviceWrapper final : public Device {
+  RBMDevice &rb_device;
+  device_id_t device_id = 0;
+  secondary_device_set_t set;
+public:
+  TestRandomBlockDeviceWrapper(
+    RBMDevice &rb_device,
+    device_id_t device_id = 0)
+    : rb_device(rb_device), device_id(device_id) {}
+
+  device_id_t get_device_id() const {
+    return device_id;
+  }
+
+  mount_ret mount() final {
+    return mount_ertr::now(); // we handle this above
+  }
+
+  mkfs_ret mkfs(device_config_t c) final {
+    return mkfs_ertr::now(); // we handle this above
+  }
+
+  close_ertr::future<> close() final {
+    return rb_device.close();
+  }
+
+  secondary_device_set_t& get_secondary_devices() final {
+    return rb_device.get_secondary_devices();
+  }
+
+  magic_t get_magic() const final {
+    return rb_device.get_magic();
+  }
+  read_ertr::future<> read(
+    paddr_t addr, size_t len, ceph::bufferptr &out) final {
+    return rb_device.read(addr, len, out);
+  }
+
+  size_t get_available_size() const final { return rb_device.get_available_size(); }
+  extent_len_t get_block_size() const final { return rb_device.get_block_size(); }
+  const seastore_meta_t &get_meta() const final {
+    return rb_device.get_meta();
+  }
+  device_type_t get_device_type() const final {
+    return device_type_t::RANDOM_BLOCK_SSD;
+  }
+
+  backend_type_t get_backend_type() const final {
+    return backend_type_t::RANDOM_BLOCK;
+  }
+
+  ~TestRandomBlockDeviceWrapper() final {}
+};
+
+DeviceRef EphemeralRandomBlockDevices::get_primary_device_ref() {
+  return std::make_unique<TestRandomBlockDeviceWrapper>(*rb_device);
+}
+
 class SeaStoreTestState : public EphemeralTestState {
   class TestMDStoreState {
     std::map<std::string, std::string> md;
@@ -379,7 +493,7 @@ protected:
 
   virtual void _init() final {
     seastore = make_test_seastore(
-      std::make_unique<TestSegmentManagerWrapper>(*segment_manager),
+      devices->get_primary_device_ref(),
       std::make_unique<TestMDStoreState::Store>(mdstore_state.get_mdstore()));
   }