From 2e9a804d9e7e530d76c467de1fb5696a07a30522 Mon Sep 17 00:00:00 2001 From: Igor Fedotov Date: Thu, 8 Oct 2020 21:53:18 +0300 Subject: [PATCH] test/store_test: add unshare blob tests cases Signed-off-by: Igor Fedotov --- src/os/bluestore/BlueStore.h | 3 + src/test/objectstore/store_test.cc | 177 +++++++++++++++++++++++++++++ 2 files changed, 180 insertions(+) diff --git a/src/os/bluestore/BlueStore.h b/src/os/bluestore/BlueStore.h index f7a72f1f73b..20fb94e58a2 100644 --- a/src/os/bluestore/BlueStore.h +++ b/src/os/bluestore/BlueStore.h @@ -2947,6 +2947,9 @@ public: const PerfCounters* get_bluefs_perf_counters() const { return bluefs->get_perf_counters(); } + KeyValueDB* get_kv() { + return db; + } int queue_transactions( CollectionHandle& ch, diff --git a/src/test/objectstore/store_test.cc b/src/test/objectstore/store_test.cc index c382c3ac1f8..e9c4ee510da 100644 --- a/src/test/objectstore/store_test.cc +++ b/src/test/objectstore/store_test.cc @@ -3525,6 +3525,92 @@ TEST_P(StoreTest, SimpleCloneRangeTest) { ObjectStore::Transaction t; t.remove(cid, hoid); t.remove(cid, hoid2); + r = queue_transaction(store, ch, std::move(t)); + ASSERT_EQ(r, 0); + } +} + +#if defined(WITH_BLUESTORE) +TEST_P(StoreTest, BlueStoreUnshareBlobTest) { + if (string(GetParam()) != "bluestore") + return; + int r; + coll_t cid; + auto ch = store->create_new_collection(cid); + { + ObjectStore::Transaction t; + t.create_collection(cid, 0); + cerr << "Creating collection " << cid << std::endl; + r = queue_transaction(store, ch, std::move(t)); + ASSERT_EQ(r, 0); + } + ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP))); + hoid.hobj.pool = -1; + ghobject_t hoid2(hobject_t(sobject_t("Object 1", CEPH_NOSNAP))); + hoid2.hobj.pool = -1; + hoid2.generation = 2; + { + // check if blob is unshared properly + bufferlist data, newdata; + data.append(string(8192, 'a')); + + ObjectStore::Transaction t; + t.write(cid, hoid, 0, data.length(), data); + cerr << "Creating object and write 8K " << hoid << std::endl; + r = queue_transaction(store, ch, std::move(t)); + ASSERT_EQ(r, 0); + + ObjectStore::Transaction t2; + t2.clone_range(cid, hoid, hoid2, 0, 4096, 0); + cerr << "Clone range object" << std::endl; + r = queue_transaction(store, ch, std::move(t2)); + ASSERT_EQ(r, 0); + + data.clear(); + data.append(string(4096, 'b')); + + ObjectStore::Transaction t3; + t3.write(cid, hoid, 0, data.length(), data); + cerr << "Writing 4k to source object " << hoid << std::endl; + r = queue_transaction(store, ch, std::move(t3)); + ASSERT_EQ(r, 0); + + { + // this trims hoid one out of onode cache + EXPECT_EQ(store->umount(), 0); + EXPECT_EQ(store->mount(), 0); + ch = store->open_collection(cid); + } + + ObjectStore::Transaction t4; + t4.remove(cid, hoid2); + cerr << "Deleting dest object" << hoid2 << std::endl; + r = queue_transaction(store, ch, std::move(t4)); + ASSERT_EQ(r, 0); + + bufferlist resdata; + r = store->read(ch, hoid, 0, 0x2000, resdata); + ASSERT_EQ(r, 0x2000); + + { + BlueStore* bstore = dynamic_cast (store.get()); + auto* kv = bstore->get_kv(); + + // to be inline with BlueStore.cc + const string PREFIX_SHARED_BLOB = "X"; + + size_t cnt = 0; + auto it = kv->get_iterator(PREFIX_SHARED_BLOB); + ceph_assert(it); + for (it->lower_bound(string()); it->valid(); it->next()) { + ++cnt; + } + ASSERT_EQ(cnt, 0); + } + } + { + ObjectStore::Transaction t; + t.remove(cid, hoid); t.remove_collection(cid); cerr << "Cleaning" << std::endl; r = queue_transaction(store, ch, std::move(t)); @@ -3532,6 +3618,97 @@ TEST_P(StoreTest, SimpleCloneRangeTest) { } } +TEST_P(StoreTest, BlueStoreUnshareBlobBugTest) { + if (string(GetParam()) != "bluestore") + return; + int r; + coll_t cid; + auto ch = store->create_new_collection(cid); + { + ObjectStore::Transaction t; + t.create_collection(cid, 0); + cerr << "Creating collection " << cid << std::endl; + r = queue_transaction(store, ch, std::move(t)); + ASSERT_EQ(r, 0); + } + ghobject_t hoid(hobject_t(sobject_t("Object 1", CEPH_NOSNAP))); + hoid.hobj.pool = -1; + ghobject_t hoid2(hobject_t(sobject_t("Object 1", CEPH_NOSNAP))); + hoid2.hobj.pool = -1; + hoid2.generation = 2; + { + // check if blob is unshared properly + bufferlist data, newdata; + data.append(string(8192, 'a')); + + ObjectStore::Transaction t; + t.write(cid, hoid, 0, data.length(), data); + cerr << "Creating object and write 8K " << hoid << std::endl; + r = queue_transaction(store, ch, std::move(t)); + ASSERT_EQ(r, 0); + + ObjectStore::Transaction t2; + t2.clone_range(cid, hoid, hoid2, 0, 4096, 0); + cerr << "Clone range object" << std::endl; + r = queue_transaction(store, ch, std::move(t2)); + ASSERT_EQ(r, 0); + + data.clear(); + data.append(string(4096, 'b')); + + ObjectStore::Transaction t3; + t3.write(cid, hoid, 0, data.length(), data); + cerr << "Writing 4k to source object " << hoid << std::endl; + r = queue_transaction(store, ch, std::move(t3)); + ASSERT_EQ(r, 0); + + { + // this trims hoid one out of onode cache + EXPECT_EQ(store->umount(), 0); + EXPECT_EQ(store->mount(), 0); + ch = store->open_collection(cid); + } + + ObjectStore::Transaction t4; + t4.write(cid, hoid2, 0, data.length(), data); + cerr << "Writing 4k to second object " << hoid2 << std::endl; + r = queue_transaction(store, ch, std::move(t4)); + ASSERT_EQ(r, 0); + + bufferlist resdata; + r = store->read(ch, hoid, 0, 0x2000, resdata); + ASSERT_EQ(r, 0x2000); + + { + BlueStore* bstore = dynamic_cast (store.get()); + auto* kv = bstore->get_kv(); + + // to be inline with BlueStore.cc + const string PREFIX_SHARED_BLOB = "X"; + + size_t cnt = 0; + auto it = kv->get_iterator(PREFIX_SHARED_BLOB); + ceph_assert(it); + for (it->lower_bound(string()); it->valid(); it->next()) { + ++cnt; + } + // This shows a bug in unsharing a blob, + // after writing to 0x0~1000 to hoid2 share blob at hoid should be + //unshared but it doesn't in the current implementation + ASSERT_EQ(cnt, 1); + } + } + { + ObjectStore::Transaction t; + t.remove(cid, hoid); + t.remove(cid, hoid2); + t.remove_collection(cid); + cerr << "Cleaning" << std::endl; + r = queue_transaction(store, ch, std::move(t)); + ASSERT_EQ(r, 0); + } +} +#endif TEST_P(StoreTest, SimpleObjectLongnameTest) { int r; -- 2.39.5