initial code repo
[stor4nfv.git] / src / ceph / src / test / librbd / test_ObjectMap.cc
diff --git a/src/ceph/src/test/librbd/test_ObjectMap.cc b/src/ceph/src/test/librbd/test_ObjectMap.cc
new file mode 100644 (file)
index 0000000..464c233
--- /dev/null
@@ -0,0 +1,136 @@
+// -*- 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/ExclusiveLock.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 <list>
+
+void register_test_object_map() {
+}
+
+class TestObjectMap : public TestFixture {
+public:
+
+  int when_open_object_map(librbd::ImageCtx *ictx) {
+    C_SaferCond ctx;
+    librbd::ObjectMap<> object_map(*ictx, ictx->snap_id);
+    object_map.open(&ctx);
+    return ctx.wait();
+  }
+};
+
+TEST_F(TestObjectMap, RefreshInvalidatesWhenCorrupt) {
+  REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  bool flags_set;
+  ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+  ASSERT_FALSE(flags_set);
+
+  C_SaferCond lock_ctx;
+  {
+    RWLock::WLocker owner_locker(ictx->owner_lock);
+    ictx->exclusive_lock->try_acquire_lock(&lock_ctx);
+  }
+  ASSERT_EQ(0, lock_ctx.wait());
+
+  std::string oid = librbd::ObjectMap<>::object_map_name(ictx->id, CEPH_NOSNAP);
+  bufferlist bl;
+  bl.append("corrupt");
+  ASSERT_EQ(0, ictx->md_ctx.write_full(oid, bl));
+
+  ASSERT_EQ(0, when_open_object_map(ictx));
+  ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+  ASSERT_TRUE(flags_set);
+}
+
+TEST_F(TestObjectMap, RefreshInvalidatesWhenTooSmall) {
+  REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  bool flags_set;
+  ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+  ASSERT_FALSE(flags_set);
+
+  C_SaferCond lock_ctx;
+  {
+    RWLock::WLocker owner_locker(ictx->owner_lock);
+    ictx->exclusive_lock->try_acquire_lock(&lock_ctx);
+  }
+  ASSERT_EQ(0, lock_ctx.wait());
+
+  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->md_ctx.operate(oid, &op));
+
+  ASSERT_EQ(0, when_open_object_map(ictx));
+  ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+  ASSERT_TRUE(flags_set);
+}
+
+TEST_F(TestObjectMap, InvalidateFlagOnDisk) {
+  REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  bool flags_set;
+  ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+  ASSERT_FALSE(flags_set);
+
+  C_SaferCond lock_ctx;
+  {
+    RWLock::WLocker owner_locker(ictx->owner_lock);
+    ictx->exclusive_lock->try_acquire_lock(&lock_ctx);
+  }
+  ASSERT_EQ(0, lock_ctx.wait());
+
+  std::string oid = librbd::ObjectMap<>::object_map_name(ictx->id, CEPH_NOSNAP);
+  bufferlist bl;
+  bl.append("corrupt");
+  ASSERT_EQ(0, ictx->md_ctx.write_full(oid, bl));
+
+  ASSERT_EQ(0, when_open_object_map(ictx));
+  ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+  ASSERT_TRUE(flags_set);
+
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+  ASSERT_TRUE(flags_set);
+}
+
+TEST_F(TestObjectMap, InvalidateFlagInMemoryOnly) {
+  REQUIRE_FEATURE(RBD_FEATURE_OBJECT_MAP);
+
+  librbd::ImageCtx *ictx;
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  bool flags_set;
+  ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+  ASSERT_FALSE(flags_set);
+
+  std::string oid = librbd::ObjectMap<>::object_map_name(ictx->id, CEPH_NOSNAP);
+  bufferlist valid_bl;
+  ASSERT_LT(0, ictx->md_ctx.read(oid, valid_bl, 0, 0));
+
+  bufferlist corrupt_bl;
+  corrupt_bl.append("corrupt");
+  ASSERT_EQ(0, ictx->md_ctx.write_full(oid, corrupt_bl));
+
+  ASSERT_EQ(0, when_open_object_map(ictx));
+  ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+  ASSERT_TRUE(flags_set);
+
+  ASSERT_EQ(0, ictx->md_ctx.write_full(oid, valid_bl));
+  ASSERT_EQ(0, open_image(m_image_name, &ictx));
+  ASSERT_EQ(0, ictx->test_flags(RBD_FLAG_OBJECT_MAP_INVALID, &flags_set));
+  ASSERT_FALSE(flags_set);
+}
+