From 0215e9753c09460f6fc84ded9397e36a209f2e32 Mon Sep 17 00:00:00 2001 From: Jason Dillaman Date: Tue, 23 Jun 2015 11:17:12 -0400 Subject: [PATCH] tests: add new unit tests for object map invalidation Signed-off-by: Jason Dillaman --- src/test/Makefile-client.am | 3 +- src/test/librbd/test_ObjectMap.cc | 124 ++++++++++++++++++++++++++++++ src/test/librbd/test_main.cc | 2 + 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 src/test/librbd/test_ObjectMap.cc diff --git a/src/test/Makefile-client.am b/src/test/Makefile-client.am index c56f89240dbf..f2ce3cc67995 100644 --- a/src/test/Makefile-client.am +++ b/src/test/Makefile-client.am @@ -304,7 +304,8 @@ librbd_test_la_SOURCES = \ test/librbd/test_support.cc \ test/librbd/test_librbd.cc \ test/librbd/test_ImageWatcher.cc \ - test/librbd/test_internal.cc + test/librbd/test_internal.cc \ + test/librbd/test_ObjectMap.cc librbd_test_la_CXXFLAGS = $(UNITTEST_CXXFLAGS) noinst_LTLIBRARIES += librbd_test.la diff --git a/src/test/librbd/test_ObjectMap.cc b/src/test/librbd/test_ObjectMap.cc new file mode 100644 index 000000000000..70ea7639c7eb --- /dev/null +++ b/src/test/librbd/test_ObjectMap.cc @@ -0,0 +1,124 @@ +// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab +#include "test/librbd/test_fixture.h" +#include "test/librbd/test_support.h" +#include "librbd/ImageCtx.h" +#include "librbd/ImageWatcher.h" +#include "librbd/internal.h" +#include "librbd/ObjectMap.h" +#include "cls/rbd/cls_rbd_client.h" +#include + +void register_test_object_map() { +} + +class TestObjectMap : public TestFixture { +public: +}; + +TEST_F(TestObjectMap, RefreshInvalidatesWhenCorrupt) { + REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + ASSERT_FALSE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID)); + + { + RWLock::WLocker owner_locker(ictx->owner_lock); + ASSERT_EQ(0, ictx->image_watcher->try_lock()); + } + + std::string oid = librbd::ObjectMap::object_map_name(ictx->id, CEPH_NOSNAP); + bufferlist bl; + bl.append("corrupt"); + ASSERT_EQ(0, ictx->data_ctx.write_full(oid, bl)); + + { + RWLock::RLocker owner_locker(ictx->owner_lock); + RWLock::WLocker snap_locker(ictx->snap_lock); + ictx->object_map.refresh(CEPH_NOSNAP); + } + ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID)); +} + +TEST_F(TestObjectMap, RefreshInvalidatesWhenTooSmall) { + REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + ASSERT_FALSE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID)); + + { + RWLock::WLocker owner_locker(ictx->owner_lock); + ASSERT_EQ(0, ictx->image_watcher->try_lock()); + } + + librados::ObjectWriteOperation op; + librbd::cls_client::object_map_resize(&op, 0, OBJECT_NONEXISTENT); + + std::string oid = librbd::ObjectMap::object_map_name(ictx->id, CEPH_NOSNAP); + ASSERT_EQ(0, ictx->data_ctx.operate(oid, &op)); + + { + RWLock::RLocker owner_locker(ictx->owner_lock); + RWLock::WLocker snap_locker(ictx->snap_lock); + ictx->object_map.refresh(CEPH_NOSNAP); + } + ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID)); +} + +TEST_F(TestObjectMap, InvalidateFlagOnDisk) { + REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + ASSERT_FALSE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID)); + + { + RWLock::WLocker owner_locker(ictx->owner_lock); + ASSERT_EQ(0, ictx->image_watcher->try_lock()); + } + + std::string oid = librbd::ObjectMap::object_map_name(ictx->id, CEPH_NOSNAP); + bufferlist bl; + bl.append("corrupt"); + ASSERT_EQ(0, ictx->data_ctx.write_full(oid, bl)); + + { + RWLock::RLocker owner_locker(ictx->owner_lock); + RWLock::WLocker snap_locker(ictx->snap_lock); + ictx->object_map.refresh(CEPH_NOSNAP); + } + ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID)); + + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID)); +} + +TEST_F(TestObjectMap, InvalidateFlagInMemoryOnly) { + REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP); + + librbd::ImageCtx *ictx; + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + ASSERT_FALSE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID)); + + std::string oid = librbd::ObjectMap::object_map_name(ictx->id, CEPH_NOSNAP); + bufferlist valid_bl; + ASSERT_EQ(0, ictx->data_ctx.read(oid, valid_bl, 0, 0)); + + bufferlist corrupt_bl; + corrupt_bl.append("corrupt"); + ASSERT_EQ(0, ictx->data_ctx.write_full(oid, corrupt_bl)); + + { + RWLock::RLocker owner_locker(ictx->owner_lock); + RWLock::WLocker snap_locker(ictx->snap_lock); + ictx->object_map.refresh(CEPH_NOSNAP); + } + ASSERT_TRUE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID)); + + ASSERT_EQ(0, ictx->data_ctx.write_full(oid, valid_bl)); + ASSERT_EQ(0, open_image(m_image_name, &ictx)); + ASSERT_FALSE(ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID)); +} + diff --git a/src/test/librbd/test_main.cc b/src/test/librbd/test_main.cc index c483e51b580e..b68d4d28ca9d 100644 --- a/src/test/librbd/test_main.cc +++ b/src/test/librbd/test_main.cc @@ -13,6 +13,7 @@ extern void register_test_librbd(); #ifdef TEST_LIBRBD_INTERNALS extern void register_test_image_watcher(); extern void register_test_internal(); +extern void register_test_object_map(); #endif // TEST_LIBRBD_INTERNALS int main(int argc, char **argv) @@ -21,6 +22,7 @@ int main(int argc, char **argv) #ifdef TEST_LIBRBD_INTERNALS register_test_image_watcher(); register_test_internal(); + register_test_object_map(); #endif // TEST_LIBRBD_INTERNALS ::testing::InitGoogleTest(&argc, argv); -- 2.47.3