return seastar::now();
}
+SeaStore::mount_ertr::future<> SeaStore::test_mount()
+{
+ init_managers();
+ return transaction_manager->mount(
+ ).handle_error(
+ crimson::ct_error::assert_all{
+ "Invalid error in SeaStore::test_mount"
+ }
+ );
+}
+
SeaStore::mount_ertr::future<> SeaStore::mount()
{
return device->mount(
});
}
+seastar::future<> SeaStore::_mkfs(uuid_d new_osd_fsid)
+{
+ init_managers();
+ return transaction_manager->mkfs(
+ ).safe_then([this] {
+ init_managers();
+ return transaction_manager->mount();
+ }).safe_then([this] {
+ return repeat_eagain([this] {
+ return transaction_manager->with_transaction_intr(
+ Transaction::src_t::MUTATE,
+ "mkfs_seastore",
+ [this](auto& t)
+ {
+ return onode_manager->mkfs(t
+ ).si_then([this, &t] {
+ return collection_manager->mkfs(t);
+ }).si_then([this, &t](auto coll_root) {
+ transaction_manager->write_collection_root(
+ t, coll_root);
+ return transaction_manager->submit_transaction(t);
+ });
+ });
+ });
+ }).safe_then([this, new_osd_fsid] {
+ return write_fsid(new_osd_fsid);
+ }).safe_then([this] {
+ return read_meta("type").then([this] (auto tuple) {
+ auto [ret, type] = tuple;
+ if (ret == 0 && type == "seastore") {
+ return seastar::now();
+ } else if (ret == 0 && type != "seastore") {
+ LOG_PREFIX(SeaStore::mkfs);
+ ERROR("expected seastore, but type is {}", type);
+ throw std::runtime_error("store type error");
+ } else {
+ return write_meta("type", "seastore");
+ }
+ });
+ }).safe_then([this] {
+ return write_meta("mkfs_done", "yes");
+ }).handle_error(
+ crimson::ct_error::assert_all{
+ "Invalid error in SeaStore::_mkfs"
+ }
+ );
+}
+
+SeaStore::mkfs_ertr::future<> SeaStore::test_mkfs(uuid_d new_osd_fsid)
+{
+
+ return read_meta("mkfs_done").then([this, new_osd_fsid] (auto tuple) {
+ auto [done, value] = tuple;
+ if (done == 0) {
+ return seastar::now();
+ }
+ return _mkfs(new_osd_fsid);
+ });
+}
+
SeaStore::mkfs_ertr::future<> SeaStore::mkfs(uuid_d new_osd_fsid)
{
return read_meta("mkfs_done").then([this, new_osd_fsid] (auto tuple) {
});
}).safe_then([this] {
return device->mount();
- }).safe_then([this] {
- init_managers();
- return transaction_manager->mkfs();
- }).safe_then([this] {
- init_managers();
- return transaction_manager->mount();
- }).safe_then([this] {
- return repeat_eagain([this] {
- return transaction_manager->with_transaction_intr(
- Transaction::src_t::MUTATE,
- "mkfs_seastore",
- [this](auto& t)
- {
- return onode_manager->mkfs(t
- ).si_then([this, &t] {
- return collection_manager->mkfs(t);
- }).si_then([this, &t](auto coll_root) {
- transaction_manager->write_collection_root(
- t, coll_root);
- return transaction_manager->submit_transaction(t);
- });
- });
- });
}).safe_then([this, new_osd_fsid] {
- return write_fsid(new_osd_fsid);
- }).safe_then([this] {
- return read_meta("type").then([this] (auto tuple) {
- auto [ret, type] = tuple;
- if (ret == 0 && type == "seastore") {
- return seastar::now();
- } else if (ret == 0 && type != "seastore") {
- LOG_PREFIX(SeaStore::mkfs);
- ERROR("expected seastore, but type is {}", type);
- throw std::runtime_error("store type error");
- } else {
- return write_meta("type", "seastore");
- }
- });
- }).safe_then([this] {
- return write_meta("mkfs_done", "yes");
+ return _mkfs(new_osd_fsid);
}).safe_then([this] {
- return umount();
+ return umount();
}).handle_error(
crimson::ct_error::assert_all{
"Invalid error in SeaStore::mkfs"
MAX
};
+ // for test
+ mount_ertr::future<> test_mount();
+ mkfs_ertr::future<> test_mkfs(uuid_d new_osd_fsid);
+ DeviceRef get_primary_device_ref() {
+ return std::move(device);
+ }
+
private:
struct internal_context_t {
CollectionRef ch;
seastar::metrics::metric_group metrics;
void register_metrics();
seastar::future<> write_fsid(uuid_d new_osd_fsid);
+ seastar::future<> _mkfs(uuid_d new_osd_fsid);
};
seastar::future<std::unique_ptr<SeaStore>> make_seastore(
struct seastore_test_t :
public seastar_test_suite_t,
- SeaStoreTestState {
+ SeaStoreTestState,
+ ::testing::WithParamInterface<const char*> {
coll_t coll_name{spg_t{pg_t{0, 0}}};
CollectionRef coll;
seastore_test_t() {}
seastar::future<> set_up_fut() final {
- return tm_setup(
+ std::string j_type = GetParam();
+ journal_type_t journal;
+ if (j_type == "segmented") {
+ journal = journal_type_t::SEGMENTED;
+ } else if (j_type == "circularbounded") {
+ journal = journal_type_t::RANDOM_BLOCK;
+ } else {
+ ceph_assert(0 == "no support");
+ }
+ return tm_setup(journal
).then([this] {
return seastore->create_new_collection(coll_name);
}).then([this](auto coll_ref) {
v) != t.end();
}
-TEST_F(seastore_test_t, collection_create_list_remove)
+TEST_P(seastore_test_t, collection_create_list_remove)
{
run_async([this] {
coll_t test_coll{spg_t{pg_t{1, 0}}};
});
}
-TEST_F(seastore_test_t, meta) {
+TEST_P(seastore_test_t, meta) {
run_async([this] {
set_meta("key1", "value1");
set_meta("key2", "value2");
});
}
-TEST_F(seastore_test_t, touch_stat_list_remove)
+TEST_P(seastore_test_t, touch_stat_list_remove)
{
run_async([this] {
auto &test_obj = get_object(make_oid(0));
{ 0, bound_t::get_temp_end(), bound_t::get_max() },
};
-TEST_F(seastore_test_t, list_objects_temp_only)
+TEST_P(seastore_test_t, list_objects_temp_only)
{
run_async([this] { test_list(5, 0, temp_list_cases); });
}
-TEST_F(seastore_test_t, list_objects_temp_overlap)
+TEST_P(seastore_test_t, list_objects_temp_overlap)
{
run_async([this] { test_list(5, 5, temp_list_cases); });
}
{ 0, bound_t::get_normal_begin(), bound_t::get_max() },
};
-TEST_F(seastore_test_t, list_objects_normal_only)
+TEST_P(seastore_test_t, list_objects_normal_only)
{
run_async([this] { test_list(5, 0, normal_list_cases); });
}
-TEST_F(seastore_test_t, list_objects_normal_overlap)
+TEST_P(seastore_test_t, list_objects_normal_overlap)
{
run_async([this] { test_list(5, 5, normal_list_cases); });
}
return bl;
}
-TEST_F(seastore_test_t, omap_test_simple)
+TEST_P(seastore_test_t, omap_test_simple)
{
run_async([this] {
auto &test_obj = get_object(make_oid(0));
});
}
-TEST_F(seastore_test_t, attr)
+TEST_P(seastore_test_t, attr)
{
run_async([this] {
auto& test_obj = get_object(make_oid(0));
});
}
-TEST_F(seastore_test_t, omap_test_iterator)
+TEST_P(seastore_test_t, omap_test_iterator)
{
run_async([this] {
auto make_key = [](unsigned i) {
}
-TEST_F(seastore_test_t, simple_extent_test)
+TEST_P(seastore_test_t, simple_extent_test)
{
run_async([this] {
auto &test_obj = get_object(make_oid(0));
});
}
-TEST_F(seastore_test_t, fiemap_empty)
+TEST_P(seastore_test_t, fiemap_empty)
{
run_async([this] {
auto &test_obj = get_object(make_oid(0));
});
}
-TEST_F(seastore_test_t, fiemap_holes)
+TEST_P(seastore_test_t, fiemap_holes)
{
run_async([this] {
const uint64_t MAX_EXTENTS = 100;
});
}
-TEST_F(seastore_test_t, sparse_read)
+TEST_P(seastore_test_t, sparse_read)
{
run_async([this] {
const uint64_t MAX_EXTENTS = 100;
});
}
-TEST_F(seastore_test_t, zero)
+TEST_P(seastore_test_t, zero)
{
run_async([this] {
auto test_zero = [this](
(BS * 4) + 128);
});
}
+INSTANTIATE_TEST_SUITE_P(
+ seastore_test,
+ seastore_test_t,
+ ::testing::Values (
+ "segmented",
+ "circularbounded"
+ )
+);
virtual ~EphemeralDevices() {}
virtual Device* get_primary_device() = 0;
virtual DeviceRef get_primary_device_ref() = 0;
+ virtual void set_primary_device_ref(DeviceRef) = 0;
};
using EphemeralDevicesRef = std::unique_ptr<EphemeralDevices>;
return segment_manager.get();
}
DeviceRef get_primary_device_ref() final;
+ void set_primary_device_ref(DeviceRef) final;
};
class EphemeralRandomBlockDevices : public EphemeralDevices {
return rb_device.get();
}
DeviceRef get_primary_device_ref() final;
+ void set_primary_device_ref(DeviceRef) final;
};
class EphemeralTestState {
}
};
-class TestSegmentManagerWrapper final : public SegmentManager {
- SegmentManager &sm;
- device_id_t device_id = 0;
- secondary_device_set_t set;
-public:
- TestSegmentManagerWrapper(
- SegmentManager &sm,
- device_id_t device_id = 0)
- : sm(sm), 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 sm.close();
- }
-
- secondary_device_set_t& get_secondary_devices() final {
- return sm.get_secondary_devices();
- }
-
- magic_t get_magic() const final {
- return sm.get_magic();
- }
-
- open_ertr::future<SegmentRef> open(segment_id_t id) final {
- return sm.open(id);
- }
-
- release_ertr::future<> release(segment_id_t id) final {
- return sm.release(id);
- }
-
- read_ertr::future<> read(
- paddr_t addr, size_t len, ceph::bufferptr &out) final {
- return sm.read(addr, len, out);
- }
-
- size_t get_available_size() const final { return sm.get_available_size(); }
- extent_len_t get_block_size() const final { return sm.get_block_size(); }
- segment_off_t get_segment_size() const final {
- return sm.get_segment_size();
- }
- const seastore_meta_t &get_meta() const final {
- return sm.get_meta();
- }
- ~TestSegmentManagerWrapper() final {}
-};
DeviceRef EphemeralSegmentedDevices::get_primary_device_ref() {
- return std::make_unique<TestSegmentManagerWrapper>(*segment_manager);
+ return std::move(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;
- }
+DeviceRef EphemeralRandomBlockDevices::get_primary_device_ref() {
+ return std::move(rb_device);
+}
- ~TestRandomBlockDeviceWrapper() final {}
-};
+void EphemeralSegmentedDevices::set_primary_device_ref(DeviceRef dev) {
+ segment_manager =
+ segment_manager::EphemeralSegmentManagerRef(
+ static_cast<segment_manager::EphemeralSegmentManager*>(dev.release()));
+}
-DeviceRef EphemeralRandomBlockDevices::get_primary_device_ref() {
- return std::make_unique<TestRandomBlockDeviceWrapper>(*rb_device);
+void EphemeralRandomBlockDevices::set_primary_device_ref(DeviceRef dev) {
+ rb_device =
+ random_block_device::RBMDeviceRef(
+ static_cast<random_block_device::RBMDevice*>(dev.release()));
}
class SeaStoreTestState : public EphemeralTestState {
}
virtual void _destroy() final {
+ devices->set_primary_device_ref(seastore->get_primary_device_ref());
seastore.reset();
}
}
virtual FuturizedStore::mount_ertr::future<> _mount() final {
- return seastore->mount();
+ return seastore->test_mount();
}
virtual FuturizedStore::mkfs_ertr::future<> _mkfs() final {
- return seastore->mkfs(uuid_d{});
+ return seastore->test_mkfs(uuid_d{});
}
};