mirror of
https://github.com/ceph/ceph
synced 2025-03-10 10:19:26 +00:00
test/cls/rgw: test that index entry is removed after racing deletes
Signed-off-by: Casey Bodley <cbodley@redhat.com>
This commit is contained in:
parent
08efcc2536
commit
5ddde6eb3d
@ -1252,3 +1252,91 @@ TEST_F(cls_rgw, bi_log_trim)
|
||||
EXPECT_FALSE(truncated);
|
||||
}
|
||||
}
|
||||
|
||||
TEST_F(cls_rgw, index_racing_removes)
|
||||
{
|
||||
string bucket_oid = str_int("bucket", 8);
|
||||
|
||||
ObjectWriteOperation op;
|
||||
cls_rgw_bucket_init_index(op);
|
||||
ASSERT_EQ(0, ioctx.operate(bucket_oid, &op));
|
||||
|
||||
int epoch = 0;
|
||||
rgw_bucket_dir_entry dirent;
|
||||
rgw_bucket_dir_entry_meta meta;
|
||||
|
||||
// prepare/complete add for single object
|
||||
const cls_rgw_obj_key obj{"obj"};
|
||||
std::string loc = "loc";
|
||||
{
|
||||
std::string tag = "tag-add";
|
||||
index_prepare(ioctx, bucket_oid, CLS_RGW_OP_ADD, tag, obj, loc);
|
||||
index_complete(ioctx, bucket_oid, CLS_RGW_OP_ADD, tag, ++epoch, obj, meta);
|
||||
test_stats(ioctx, bucket_oid, RGWObjCategory::None, 1, 0);
|
||||
}
|
||||
|
||||
// list to verify no pending ops
|
||||
{
|
||||
std::map<int, rgw_cls_list_ret> results;
|
||||
list_entries(ioctx, bucket_oid, 1, results);
|
||||
ASSERT_EQ(1, results.size());
|
||||
const auto& entries = results.begin()->second.dir.m;
|
||||
ASSERT_EQ(1, entries.size());
|
||||
dirent = std::move(entries.begin()->second);
|
||||
ASSERT_EQ(obj, dirent.key);
|
||||
ASSERT_TRUE(dirent.exists);
|
||||
ASSERT_TRUE(dirent.pending_map.empty());
|
||||
}
|
||||
|
||||
// prepare three racing removals
|
||||
std::string tag1 = "tag-rm1";
|
||||
std::string tag2 = "tag-rm2";
|
||||
std::string tag3 = "tag-rm3";
|
||||
index_prepare(ioctx, bucket_oid, CLS_RGW_OP_DEL, tag1, obj, loc);
|
||||
index_prepare(ioctx, bucket_oid, CLS_RGW_OP_DEL, tag2, obj, loc);
|
||||
index_prepare(ioctx, bucket_oid, CLS_RGW_OP_DEL, tag3, obj, loc);
|
||||
|
||||
test_stats(ioctx, bucket_oid, RGWObjCategory::None, 1, 0);
|
||||
|
||||
// complete on tag2
|
||||
index_complete(ioctx, bucket_oid, CLS_RGW_OP_DEL, tag2, ++epoch, obj, meta);
|
||||
{
|
||||
std::map<int, rgw_cls_list_ret> results;
|
||||
list_entries(ioctx, bucket_oid, 1, results);
|
||||
ASSERT_EQ(1, results.size());
|
||||
const auto& entries = results.begin()->second.dir.m;
|
||||
ASSERT_EQ(1, entries.size());
|
||||
dirent = std::move(entries.begin()->second);
|
||||
ASSERT_EQ(obj, dirent.key);
|
||||
ASSERT_FALSE(dirent.exists);
|
||||
ASSERT_FALSE(dirent.pending_map.empty());
|
||||
}
|
||||
|
||||
// cancel on tag1
|
||||
index_complete(ioctx, bucket_oid, CLS_RGW_OP_CANCEL, tag1, ++epoch, obj, meta);
|
||||
{
|
||||
std::map<int, rgw_cls_list_ret> results;
|
||||
list_entries(ioctx, bucket_oid, 1, results);
|
||||
ASSERT_EQ(1, results.size());
|
||||
const auto& entries = results.begin()->second.dir.m;
|
||||
ASSERT_EQ(1, entries.size());
|
||||
dirent = std::move(entries.begin()->second);
|
||||
ASSERT_EQ(obj, dirent.key);
|
||||
ASSERT_FALSE(dirent.exists);
|
||||
ASSERT_FALSE(dirent.pending_map.empty());
|
||||
}
|
||||
|
||||
// final cancel on tag3
|
||||
index_complete(ioctx, bucket_oid, CLS_RGW_OP_CANCEL, tag3, ++epoch, obj, meta);
|
||||
|
||||
// verify that the key was removed
|
||||
{
|
||||
std::map<int, rgw_cls_list_ret> results;
|
||||
list_entries(ioctx, bucket_oid, 1, results);
|
||||
EXPECT_EQ(1, results.size());
|
||||
const auto& entries = results.begin()->second.dir.m;
|
||||
ASSERT_EQ(0, entries.size());
|
||||
}
|
||||
|
||||
test_stats(ioctx, bucket_oid, RGWObjCategory::None, 0, 0);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user