]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: add gc log helpers and unit tests
authorCasey Bodley <cbodley@redhat.com>
Tue, 1 Oct 2019 17:19:52 +0000 (13:19 -0400)
committerPritha Srivastava <prsrivas@redhat.com>
Wed, 16 Oct 2019 03:54:18 +0000 (09:24 +0530)
Signed-off-by: Casey Bodley <cbodley@redhat.com>
src/rgw/CMakeLists.txt
src/rgw/rgw_gc_log.cc [new file with mode: 0644]
src/rgw/rgw_gc_log.h [new file with mode: 0644]
src/test/rgw/CMakeLists.txt
src/test/rgw/test_rgw_gc_log.cc [new file with mode: 0644]

index fb17473bc9376b95fd023daa06ac94100097c05c..c2de6a4d818bbadd48229bc44233bea76477053d 100644 (file)
@@ -66,6 +66,7 @@ set(librgw_common_srcs
   rgw_es_query.cc
   rgw_formats.cc
   rgw_gc.cc
+  rgw_gc_log.cc
   rgw_http_client.cc
   rgw_json_enc.cc
   rgw_keystone.cc
diff --git a/src/rgw/rgw_gc_log.cc b/src/rgw/rgw_gc_log.cc
new file mode 100644 (file)
index 0000000..cd30af1
--- /dev/null
@@ -0,0 +1,54 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+#include "rgw_gc_log.h"
+
+#include "cls/rgw/cls_rgw_client.h"
+#include "cls/rgw_gc/cls_rgw_gc_client.h"
+#include "cls/version/cls_version_client.h"
+
+
+void gc_log_init2(librados::ObjectWriteOperation& op,
+                  uint64_t max_size, uint64_t max_urgent)
+{
+  obj_version objv; // objv.ver = 0
+  cls_version_check(op, objv, VER_COND_EQ);
+  cls_rgw_gc_queue_init(op, max_size, max_urgent);
+  cls_version_inc(op); // objv.ver -> 1
+}
+
+void gc_log_enqueue1(librados::ObjectWriteOperation& op,
+                     uint32_t expiration, cls_rgw_gc_obj_info& info)
+{
+  obj_version objv; // objv.ver = 0
+  cls_version_check(op, objv, VER_COND_EQ);
+  cls_rgw_gc_set_entry(op, expiration, info);
+}
+
+void gc_log_enqueue2(librados::ObjectWriteOperation& op,
+                     uint32_t expiration, const cls_rgw_gc_obj_info& info)
+{
+  obj_version objv;
+  objv.ver = 1;
+  cls_version_check(op, objv, VER_COND_EQ);
+  cls_rgw_gc_queue_enqueue(op, expiration, info);
+}
+
+void gc_log_defer1(librados::ObjectWriteOperation& op,
+                   uint32_t expiration, const cls_rgw_gc_obj_info& info)
+{
+  obj_version objv; // objv.ver = 0
+  cls_version_check(op, objv, VER_COND_EQ);
+  cls_rgw_gc_defer_entry(op, expiration, info.tag);
+}
+
+void gc_log_defer2(librados::ObjectWriteOperation& op,
+                   uint32_t expiration, const cls_rgw_gc_obj_info& info)
+{
+  obj_version objv;
+  objv.ver = 1;
+  cls_version_check(op, objv, VER_COND_EQ);
+  cls_rgw_gc_queue_defer_entry(op, expiration, info);
+  // TODO: conditional on whether omap is known to be empty
+  cls_rgw_gc_remove(op, {info.tag});
+}
diff --git a/src/rgw/rgw_gc_log.h b/src/rgw/rgw_gc_log.h
new file mode 100644 (file)
index 0000000..8c223e5
--- /dev/null
@@ -0,0 +1,28 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab ft=cpp
+
+#pragma once
+
+#include "include/rados/librados.hpp"
+#include "cls/rgw/cls_rgw_types.h"
+
+
+// initialize the cls_rgw_gc queue
+void gc_log_init2(librados::ObjectWriteOperation& op,
+                  uint64_t max_size, uint64_t max_urgent);
+
+// enqueue a gc entry to omap with cls_rgw
+void gc_log_enqueue1(librados::ObjectWriteOperation& op,
+                     uint32_t expiration, cls_rgw_gc_obj_info& info);
+
+// enqueue a gc entry to the cls_rgw_gc queue
+void gc_log_enqueue2(librados::ObjectWriteOperation& op,
+                     uint32_t expiration, const cls_rgw_gc_obj_info& info);
+
+// defer a gc entry in omap with cls_rgw
+void gc_log_defer1(librados::ObjectWriteOperation& op,
+                   uint32_t expiration, const cls_rgw_gc_obj_info& info);
+
+// defer a gc entry in the cls_rgw_gc queue
+void gc_log_defer2(librados::ObjectWriteOperation& op,
+                   uint32_t expiration, const cls_rgw_gc_obj_info& info);
index 3089faf0b7c835c892421d0474706e5eb5ec6a96..cb010b54355cbc389d82de0d22878d92526ce279 100644 (file)
@@ -170,3 +170,7 @@ add_executable(unittest_rgw_kms test_rgw_kms.cc)
 add_ceph_unittest(unittest_rgw_kms)
 
 target_link_libraries(unittest_rgw_kms ${rgw_libs})
+
+add_executable(ceph_test_rgw_gc_log test_rgw_gc_log.cc $<TARGET_OBJECTS:unit-main>)
+add_ceph_unittest(ceph_test_rgw_gc_log)
+target_link_libraries(ceph_test_rgw_gc_log radostest-cxx ${rgw_libs})
diff --git a/src/test/rgw/test_rgw_gc_log.cc b/src/test/rgw/test_rgw_gc_log.cc
new file mode 100644 (file)
index 0000000..4bcee4a
--- /dev/null
@@ -0,0 +1,125 @@
+// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#include "rgw/rgw_gc_log.h"
+
+#include "test/librados/test_cxx.h"
+#include "gtest/gtest.h"
+
+// creates a temporary pool and initializes an IoCtx for each test
+class rgw_gc_log : public ::testing::Test {
+  static librados::Rados rados;
+  static std::string pool_name;
+ protected:
+  static librados::IoCtx ioctx;
+
+  static void SetUpTestCase() {
+    pool_name = get_temp_pool_name();
+    /* create pool */
+    ASSERT_EQ("", create_one_pool_pp(pool_name, rados));
+    ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
+  }
+  static void TearDownTestCase() {
+    /* remove pool */
+    ioctx.close();
+    ASSERT_EQ(0, destroy_one_pool_pp(pool_name, rados));
+  }
+
+  // use the test's name as the oid so different tests don't conflict
+  std::string get_test_oid() const {
+    return ::testing::UnitTest::GetInstance()->current_test_info()->name();
+  }
+};
+librados::Rados rgw_gc_log::rados;
+std::string rgw_gc_log::pool_name;
+librados::IoCtx rgw_gc_log::ioctx;
+
+
+TEST_F(rgw_gc_log, init_existing_queue)
+{
+  const std::string oid = get_test_oid();
+  {
+    // successfully inits new object
+    librados::ObjectWriteOperation op;
+    gc_log_init2(op, 1, 1);
+    ASSERT_EQ(0, ioctx.operate(oid, &op));
+  }
+  {
+    // version check fails on second init
+    librados::ObjectWriteOperation op;
+    gc_log_init2(op, 1, 1);
+    ASSERT_EQ(-ECANCELED, ioctx.operate(oid, &op));
+  }
+}
+
+TEST_F(rgw_gc_log, init_existing_omap)
+{
+  const std::string oid = get_test_oid();
+  {
+    librados::ObjectWriteOperation op;
+    cls_rgw_gc_obj_info info;
+    gc_log_enqueue1(op, 5, info);
+    ASSERT_EQ(0, ioctx.operate(oid, &op));
+  }
+  {
+    // init succeeds with existing omap entries
+    librados::ObjectWriteOperation op;
+    gc_log_init2(op, 1, 1);
+    ASSERT_EQ(0, ioctx.operate(oid, &op));
+  }
+}
+
+TEST_F(rgw_gc_log, enqueue1_after_init)
+{
+  const std::string oid = get_test_oid();
+  {
+    librados::ObjectWriteOperation op;
+    gc_log_init2(op, 1, 1);
+    ASSERT_EQ(0, ioctx.operate(oid, &op));
+  }
+  {
+    // version check fails on omap enqueue
+    librados::ObjectWriteOperation op;
+    cls_rgw_gc_obj_info info;
+    gc_log_enqueue1(op, 5, info);
+    ASSERT_EQ(-ECANCELED, ioctx.operate(oid, &op));
+  }
+}
+
+TEST_F(rgw_gc_log, enqueue2_before_init)
+{
+  const std::string oid = get_test_oid();
+  {
+    // version check fails on cls_rgw_gc enqueue
+    librados::ObjectWriteOperation op;
+    gc_log_enqueue2(op, 5, {});
+    ASSERT_EQ(-ECANCELED, ioctx.operate(oid, &op));
+  }
+}
+
+TEST_F(rgw_gc_log, defer1_after_init)
+{
+  const std::string oid = get_test_oid();
+  {
+    librados::ObjectWriteOperation op;
+    gc_log_init2(op, 1, 1);
+    ASSERT_EQ(0, ioctx.operate(oid, &op));
+  }
+  {
+    // version check fails on omap defer
+    librados::ObjectWriteOperation op;
+    gc_log_defer1(op, 5, {});
+    ASSERT_EQ(-ECANCELED, ioctx.operate(oid, &op));
+  }
+}
+
+TEST_F(rgw_gc_log, defer2_before_init)
+{
+  const std::string oid = get_test_oid();
+  {
+    // version check fails on cls_rgw_gc defer
+    librados::ObjectWriteOperation op;
+    gc_log_defer2(op, 5, {});
+    ASSERT_EQ(-ECANCELED, ioctx.operate(oid, &op));
+  }
+}