1 // -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #include "include/types.h"
5 #include "cls/refcount/cls_refcount_client.h"
7 #include "gtest/gtest.h"
8 #include "test/librados/test.h"
14 static librados::ObjectWriteOperation *new_op() {
15 return new librados::ObjectWriteOperation();
18 TEST(cls_rgw, test_implicit) /* test refcount using implicit referencing of newly created objects */
20 librados::Rados rados;
21 librados::IoCtx ioctx;
22 string pool_name = get_temp_pool_name();
25 ASSERT_EQ("", create_one_pool_pp(pool_name, rados));
26 ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
30 string oldtag = "oldtag";
31 string newtag = "newtag";
34 /* get on a missing object will fail */
35 librados::ObjectWriteOperation *op = new_op();
36 cls_refcount_get(*op, newtag, true);
37 ASSERT_EQ(-ENOENT, ioctx.operate(oid, op));
41 ASSERT_EQ(0, ioctx.create(oid, true));
43 /* read reference, should return a single wildcard entry */
47 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
48 ASSERT_EQ(1, (int)refs.size());
51 string tag = refs.front();
53 ASSERT_EQ(wildcard_tag, tag);
55 /* take another reference, verify */
57 cls_refcount_get(*op, newtag, true);
58 ASSERT_EQ(0, ioctx.operate(oid, op));
60 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
61 ASSERT_EQ(2, (int)refs.size());
63 map<string, bool> refs_map;
64 for (list<string>::iterator iter = refs.begin(); iter != refs.end(); ++iter) {
65 refs_map[*iter] = true;
68 ASSERT_EQ(1, (int)refs_map.count(wildcard_tag));
69 ASSERT_EQ(1, (int)refs_map.count(newtag));
73 /* drop reference to oldtag */
76 cls_refcount_put(*op, oldtag, true);
77 ASSERT_EQ(0, ioctx.operate(oid, op));
79 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
80 ASSERT_EQ(1, (int)refs.size());
83 ASSERT_EQ(newtag, tag);
87 /* drop oldtag reference again, op should return success, wouldn't do anything */
90 cls_refcount_put(*op, oldtag, true);
91 ASSERT_EQ(0, ioctx.operate(oid, op));
93 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
94 ASSERT_EQ(1, (int)refs.size());
97 ASSERT_EQ(newtag, tag);
101 /* drop newtag reference, make sure object removed */
103 cls_refcount_put(*op, newtag, true);
104 ASSERT_EQ(0, ioctx.operate(oid, op));
106 ASSERT_EQ(-ENOENT, ioctx.stat(oid, NULL, NULL));
112 ASSERT_EQ(0, destroy_one_pool_pp(pool_name, rados));
116 * similar to test_implicit, just changes the order of the tags removal
119 TEST(cls_rgw, test_implicit_idempotent) /* test refcount using implicit referencing of newly created objects */
121 librados::Rados rados;
122 librados::IoCtx ioctx;
123 string pool_name = get_temp_pool_name();
126 ASSERT_EQ("", create_one_pool_pp(pool_name, rados));
127 ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
131 string oldtag = "oldtag";
132 string newtag = "newtag";
135 /* get on a missing object will fail */
136 librados::ObjectWriteOperation *op = new_op();
137 cls_refcount_get(*op, newtag, true);
138 ASSERT_EQ(-ENOENT, ioctx.operate(oid, op));
142 ASSERT_EQ(0, ioctx.create(oid, true));
144 /* read reference, should return a single wildcard entry */
148 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
149 ASSERT_EQ(1, (int)refs.size());
152 string tag = refs.front();
154 ASSERT_EQ(wildcard_tag, tag);
156 /* take another reference, verify */
158 cls_refcount_get(*op, newtag, true);
159 ASSERT_EQ(0, ioctx.operate(oid, op));
161 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
162 ASSERT_EQ(2, (int)refs.size());
164 map<string, bool> refs_map;
165 for (list<string>::iterator iter = refs.begin(); iter != refs.end(); ++iter) {
166 refs_map[*iter] = true;
169 ASSERT_EQ(1, (int)refs_map.count(wildcard_tag));
170 ASSERT_EQ(1, (int)refs_map.count(newtag));
174 /* drop reference to newtag */
177 cls_refcount_put(*op, newtag, true);
178 ASSERT_EQ(0, ioctx.operate(oid, op));
180 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
181 ASSERT_EQ(1, (int)refs.size());
184 ASSERT_EQ(string(), tag);
188 /* drop newtag reference again, op should return success, wouldn't do anything */
191 cls_refcount_put(*op, newtag, true);
192 ASSERT_EQ(0, ioctx.operate(oid, op));
194 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs, true));
195 ASSERT_EQ(1, (int)refs.size());
198 ASSERT_EQ(string(), tag);
202 /* drop oldtag reference, make sure object removed */
204 cls_refcount_put(*op, oldtag, true);
205 ASSERT_EQ(0, ioctx.operate(oid, op));
207 ASSERT_EQ(-ENOENT, ioctx.stat(oid, NULL, NULL));
213 ASSERT_EQ(0, destroy_one_pool_pp(pool_name, rados));
217 TEST(cls_rgw, test_put_snap) {
218 librados::Rados rados;
219 librados::IoCtx ioctx;
220 string pool_name = get_temp_pool_name();
223 ASSERT_EQ("", create_one_pool_pp(pool_name, rados));
224 ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
227 bl.append("hi there");
228 ASSERT_EQ(0, ioctx.write("foo", bl, bl.length(), 0));
229 ASSERT_EQ(0, ioctx.snap_create("snapfoo"));
230 ASSERT_EQ(0, ioctx.remove("foo"));
234 ASSERT_EQ(0, ioctx.snap_create("snapbar"));
236 librados::ObjectWriteOperation *op = new_op();
237 cls_refcount_put(*op, "notag", true);
238 ASSERT_EQ(-ENOENT, ioctx.operate("foo", op));
240 EXPECT_EQ(0, ioctx.snap_remove("snapfoo"));
241 EXPECT_EQ(0, ioctx.snap_remove("snapbar"));
247 ASSERT_EQ(0, destroy_one_pool_pp(pool_name, rados));
250 TEST(cls_rgw, test_explicit) /* test refcount using implicit referencing of newly created objects */
252 librados::Rados rados;
253 librados::IoCtx ioctx;
254 string pool_name = get_temp_pool_name();
257 ASSERT_EQ("", create_one_pool_pp(pool_name, rados));
258 ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
266 ASSERT_EQ(0, ioctx.create(oid, true));
268 /* read reference, should return a single wildcard entry */
272 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs));
273 ASSERT_EQ(0, (int)refs.size());
276 /* take first reference, verify */
278 string newtag = "newtag";
280 librados::ObjectWriteOperation *op = new_op();
281 cls_refcount_get(*op, newtag);
282 ASSERT_EQ(0, ioctx.operate(oid, op));
284 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs));
285 ASSERT_EQ(1, (int)refs.size());
287 map<string, bool> refs_map;
288 for (list<string>::iterator iter = refs.begin(); iter != refs.end(); ++iter) {
289 refs_map[*iter] = true;
292 ASSERT_EQ(1, (int)refs_map.count(newtag));
296 /* try to drop reference to unexisting tag */
298 string nosuchtag = "nosuchtag";
301 cls_refcount_put(*op, nosuchtag);
302 ASSERT_EQ(0, ioctx.operate(oid, op));
304 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs));
305 ASSERT_EQ(1, (int)refs.size());
307 string tag = refs.front();
308 ASSERT_EQ(newtag, tag);
312 /* drop newtag reference, make sure object removed */
314 cls_refcount_put(*op, newtag);
315 ASSERT_EQ(0, ioctx.operate(oid, op));
317 ASSERT_EQ(-ENOENT, ioctx.stat(oid, NULL, NULL));
323 ASSERT_EQ(0, destroy_one_pool_pp(pool_name, rados));
326 TEST(cls_rgw, set) /* test refcount using implicit referencing of newly created objects */
328 librados::Rados rados;
329 librados::IoCtx ioctx;
330 string pool_name = get_temp_pool_name();
333 ASSERT_EQ("", create_one_pool_pp(pool_name, rados));
334 ASSERT_EQ(0, rados.ioctx_create(pool_name.c_str(), ioctx));
342 ASSERT_EQ(0, ioctx.create(oid, true));
344 /* read reference, should return a single wildcard entry */
346 list<string> tag_refs, refs;
349 string tags[TAGS_NUM];
352 for (int i = 0; i < TAGS_NUM; i++) {
353 snprintf(buf, sizeof(buf), "tag%d", i);
355 tag_refs.push_back(tags[i]);
358 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs));
359 ASSERT_EQ(0, (int)refs.size());
361 /* set reference list, verify */
363 librados::ObjectWriteOperation *op = new_op();
364 cls_refcount_set(*op, tag_refs);
365 ASSERT_EQ(0, ioctx.operate(oid, op));
368 ASSERT_EQ(0, cls_refcount_read(ioctx, oid, &refs));
369 ASSERT_EQ(TAGS_NUM, (int)refs.size());
371 map<string, bool> refs_map;
372 for (list<string>::iterator iter = refs.begin(); iter != refs.end(); ++iter) {
373 refs_map[*iter] = true;
376 for (int i = 0; i < TAGS_NUM; i++) {
377 ASSERT_EQ(1, (int)refs_map.count(tags[i]));
382 /* remove all refs */
384 for (int i = 0; i < TAGS_NUM; i++) {
386 cls_refcount_put(*op, tags[i]);
387 ASSERT_EQ(0, ioctx.operate(oid, op));
391 ASSERT_EQ(-ENOENT, ioctx.stat(oid, NULL, NULL));
395 ASSERT_EQ(0, destroy_one_pool_pp(pool_name, rados));