]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
test/cls_refcount: Add unit-test for ec pools and refcount
authorNitzanMordhai <nmordech@redhat.com>
Thu, 28 Jul 2022 12:27:51 +0000 (12:27 +0000)
committerNitzanMordhai <nmordech@redhat.com>
Wed, 10 Aug 2022 14:18:55 +0000 (14:18 +0000)
Create set of unit-test for erasure code pools

Fixes: https://tracker.ceph.com/issues/56707
Signed-off-by: Nitzan Mordechai <nmordec@redhat.com>
src/test/cls_refcount/test_cls_refcount.cc

index b080c86ad782f4d6f3c379b3e102a2bd01290a41..2868b48b660b37e4d7c44cc36547c9fa0be8c441 100644 (file)
@@ -396,3 +396,383 @@ TEST(cls_rgw, set) /* test refcount using implicit referencing of newly created
   ioctx.close();
   ASSERT_EQ(0, destroy_one_pool_pp(pool_name, rados));
 }
+
+TEST(cls_rgw, test_implicit_ec) /* test refcount using implicit referencing of newly created objects */
+{
+  librados::Rados rados;
+  librados::IoCtx ioctx;
+  string pool_name = get_temp_pool_name();
+
+  /* create pool */
+  ASSERT_EQ("", create_one_ec_pool_pp(pool_name, rados));
+  ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
+
+  /* add chains */
+  string oid = "obj";
+  string oldtag = "oldtag";
+  string newtag = "newtag";
+
+
+  /* get on a missing object will fail */
+  librados::ObjectWriteOperation *op = new_op();
+  cls_refcount_get(*op, newtag, true);
+  ASSERT_EQ(-ENOENT, ioctx.operate(oid, op));
+  delete op;
+
+  /* create object */
+  ASSERT_EQ(0, ioctx.create(oid, true));
+
+  /* read reference, should return a single wildcard entry */
+
+  list<string> refs;
+
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
+  ASSERT_EQ(1, (int)refs.size());
+
+  string wildcard_tag;
+  string tag = refs.front();
+
+  ASSERT_EQ(wildcard_tag, tag);
+
+  /* take another reference, verify */
+  op = new_op();
+  cls_refcount_get(*op, newtag, true);
+  ASSERT_EQ(0, ioctx.operate(oid, op));
+
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
+  ASSERT_EQ(2, (int)refs.size());
+
+  map<string, bool> refs_map;
+  for (list<string>::iterator iter = refs.begin(); iter != refs.end(); ++iter) {
+    refs_map[*iter] = true;
+  }
+
+  ASSERT_EQ(1, (int)refs_map.count(wildcard_tag));
+  ASSERT_EQ(1, (int)refs_map.count(newtag));
+
+  delete op;
+
+  /* drop reference to oldtag */
+
+  op = new_op();
+  cls_refcount_put(*op, oldtag, true);
+  ASSERT_EQ(0, ioctx.operate(oid, op));
+
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
+  ASSERT_EQ(1, (int)refs.size());
+
+  tag = refs.front();
+  ASSERT_EQ(newtag, tag);
+
+  delete op;
+
+  /* drop oldtag reference again, op should return success, wouldn't do anything */
+
+  op = new_op();
+  cls_refcount_put(*op, oldtag, true);
+  ASSERT_EQ(0, ioctx.operate(oid, op));
+
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
+  ASSERT_EQ(1, (int)refs.size());
+
+  tag = refs.front();
+  ASSERT_EQ(newtag, tag);
+
+  delete op;
+
+  /* drop newtag reference, make sure object removed */
+  op = new_op();
+  cls_refcount_put(*op, newtag, true);
+  ASSERT_EQ(0, ioctx.operate(oid, op));
+
+  ASSERT_EQ(-ENOENT, ioctx.stat(oid, NULL, NULL));
+
+  delete op;
+
+  /* remove pool */
+  ioctx.close();
+  ASSERT_EQ(0, destroy_one_ec_pool_pp(pool_name, rados));
+}
+
+/*
+ * similar to test_implicit, just changes the order of the tags removal
+ * see issue #20107
+ */
+TEST(cls_rgw, test_implicit_idempotent_ec) /* test refcount using implicit referencing of newly created objects */
+{
+  librados::Rados rados;
+  librados::IoCtx ioctx;
+  string pool_name = get_temp_pool_name();
+
+  /* create pool */
+  ASSERT_EQ("", create_one_ec_pool_pp(pool_name, rados));
+  ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
+
+  /* add chains */
+  string oid = "obj";
+  string oldtag = "oldtag";
+  string newtag = "newtag";
+
+
+  /* get on a missing object will fail */
+  librados::ObjectWriteOperation *op = new_op();
+  cls_refcount_get(*op, newtag, true);
+  ASSERT_EQ(-ENOENT, ioctx.operate(oid, op));
+  delete op;
+
+  /* create object */
+  ASSERT_EQ(0, ioctx.create(oid, true));
+
+  /* read reference, should return a single wildcard entry */
+
+  list<string> refs;
+
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
+  ASSERT_EQ(1, (int)refs.size());
+
+  string wildcard_tag;
+  string tag = refs.front();
+
+  ASSERT_EQ(wildcard_tag, tag);
+
+  /* take another reference, verify */
+  op = new_op();
+  cls_refcount_get(*op, newtag, true);
+  ASSERT_EQ(0, ioctx.operate(oid, op));
+
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
+  ASSERT_EQ(2, (int)refs.size());
+
+  map<string, bool> refs_map;
+  for (list<string>::iterator iter = refs.begin(); iter != refs.end(); ++iter) {
+    refs_map[*iter] = true;
+  }
+
+  ASSERT_EQ(1, (int)refs_map.count(wildcard_tag));
+  ASSERT_EQ(1, (int)refs_map.count(newtag));
+
+  delete op;
+
+  /* drop reference to newtag */
+
+  op = new_op();
+  cls_refcount_put(*op, newtag, true);
+  ASSERT_EQ(0, ioctx.operate(oid, op));
+
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
+  ASSERT_EQ(1, (int)refs.size());
+
+  tag = refs.front();
+  ASSERT_EQ(string(), tag);
+
+  delete op;
+
+  /* drop newtag reference again, op should return success, wouldn't do anything */
+
+  op = new_op();
+  cls_refcount_put(*op, newtag, true);
+  ASSERT_EQ(0, ioctx.operate(oid, op));
+
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
+  ASSERT_EQ(1, (int)refs.size());
+
+  tag = refs.front();
+  ASSERT_EQ(string(), tag);
+
+  delete op;
+
+  /* drop oldtag reference, make sure object removed */
+  op = new_op();
+  cls_refcount_put(*op, oldtag, true);
+  ASSERT_EQ(0, ioctx.operate(oid, op));
+
+  ASSERT_EQ(-ENOENT, ioctx.stat(oid, NULL, NULL));
+
+  delete op;
+
+  /* remove pool */
+  ioctx.close();
+  ASSERT_EQ(0, destroy_one_ec_pool_pp(pool_name, rados));
+}
+
+
+TEST(cls_rgw, test_put_snap_ec) {
+  librados::Rados rados;
+  librados::IoCtx ioctx;
+  string pool_name = get_temp_pool_name();
+
+  /* create pool */
+  ASSERT_EQ("", create_one_ec_pool_pp(pool_name, rados));
+  ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
+
+  bufferlist bl;
+  bl.append("hi there");
+  ASSERT_EQ(0, ioctx.write("foo", bl, bl.length(), 0));
+  ASSERT_EQ(0, ioctx.snap_create("snapfoo"));
+  ASSERT_EQ(0, ioctx.remove("foo"));
+
+  sleep(2);
+
+  ASSERT_EQ(0, ioctx.snap_create("snapbar"));
+
+  librados::ObjectWriteOperation *op = new_op();
+  cls_refcount_put(*op, "notag", true);
+  ASSERT_EQ(-ENOENT, ioctx.operate("foo", op));
+
+  EXPECT_EQ(0, ioctx.snap_remove("snapfoo"));
+  EXPECT_EQ(0, ioctx.snap_remove("snapbar"));
+
+  delete op;
+
+  /* remove pool */
+  ioctx.close();
+  ASSERT_EQ(0, destroy_one_ec_pool_pp(pool_name, rados));
+}
+
+TEST(cls_rgw, test_explicit_ec) /* test refcount using implicit referencing of newly created objects */
+{
+  librados::Rados rados;
+  librados::IoCtx ioctx;
+  string pool_name = get_temp_pool_name();
+
+  /* create pool */
+  ASSERT_EQ("", create_one_ec_pool_pp(pool_name, rados));
+  ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
+
+  /* add chains */
+  string oid = "obj";
+
+
+  /* create object */
+
+  ASSERT_EQ(0, ioctx.create(oid, true));
+
+  /* read reference, should return a single wildcard entry */
+
+  list<string> refs;
+
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs));
+  ASSERT_EQ(0, (int)refs.size());
+
+
+  /* take first reference, verify */
+
+  string newtag = "newtag";
+
+  librados::ObjectWriteOperation *op = new_op();
+  cls_refcount_get(*op, newtag);
+  ASSERT_EQ(0, ioctx.operate(oid, op));
+
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs));
+  ASSERT_EQ(1, (int)refs.size());
+
+  map<string, bool> refs_map;
+  for (list<string>::iterator iter = refs.begin(); iter != refs.end(); ++iter) {
+    refs_map[*iter] = true;
+  }
+
+  ASSERT_EQ(1, (int)refs_map.count(newtag));
+
+  delete op;
+
+  /* try to drop reference to unexisting tag */
+
+  string nosuchtag = "nosuchtag";
+
+  op = new_op();
+  cls_refcount_put(*op, nosuchtag);
+  ASSERT_EQ(0, ioctx.operate(oid, op));
+
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs));
+  ASSERT_EQ(1, (int)refs.size());
+
+  string tag = refs.front();
+  ASSERT_EQ(newtag, tag);
+
+  delete op;
+
+  /* drop newtag reference, make sure object removed */
+  op = new_op();
+  cls_refcount_put(*op, newtag);
+  ASSERT_EQ(0, ioctx.operate(oid, op));
+
+  ASSERT_EQ(-ENOENT, ioctx.stat(oid, NULL, NULL));
+
+  delete op;
+
+  /* remove pool */
+  ioctx.close();
+  ASSERT_EQ(0, destroy_one_ec_pool_pp(pool_name, rados));
+}
+
+TEST(cls_rgw, set_ec) /* test refcount using implicit referencing of newly created objects */
+{
+  librados::Rados rados;
+  librados::IoCtx ioctx;
+  string pool_name = get_temp_pool_name();
+
+  /* create pool */
+  ASSERT_EQ("", create_one_ec_pool_pp(pool_name, rados));
+  ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
+
+  /* add chains */
+  string oid = "obj";
+
+
+  /* create object */
+
+  ASSERT_EQ(0, ioctx.create(oid, true));
+
+  /* read reference, should return a single wildcard entry */
+
+  list<string> tag_refs, refs;
+
+#define TAGS_NUM 5
+  string tags[TAGS_NUM];
+
+  char buf[16];
+  for (int i = 0; i < TAGS_NUM; i++) {
+    snprintf(buf, sizeof(buf), "tag%d", i);
+    tags[i] = buf;
+    tag_refs.push_back(tags[i]);
+  }
+
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs));
+  ASSERT_EQ(0, (int)refs.size());
+
+  /* set reference list, verify */
+
+  librados::ObjectWriteOperation *op = new_op();
+  cls_refcount_set(*op, tag_refs);
+  ASSERT_EQ(0, ioctx.operate(oid, op));
+
+  refs.clear();
+  ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs));
+  ASSERT_EQ(TAGS_NUM, (int)refs.size());
+
+  map<string, bool> refs_map;
+  for (list<string>::iterator iter = refs.begin(); iter != refs.end(); ++iter) {
+    refs_map[*iter] = true;
+  }
+
+  for (int i = 0; i < TAGS_NUM; i++) {
+    ASSERT_EQ(1, (int)refs_map.count(tags[i]));
+  }
+
+  delete op;
+
+  /* remove all refs */
+
+  for (int i = 0; i < TAGS_NUM; i++) {
+    op = new_op();
+    cls_refcount_put(*op, tags[i]);
+    ASSERT_EQ(0, ioctx.operate(oid, op));
+    delete op;
+  }
+
+  ASSERT_EQ(-ENOENT, ioctx.stat(oid, NULL, NULL));
+
+  /* remove pool */
+  ioctx.close();
+  ASSERT_EQ(0, destroy_one_ec_pool_pp(pool_name, rados));
+}