1 #include "gtest/gtest.h"
9 #include "rgw_common.h"
12 using DB
= rgw::store::DB
;
14 vector
<const char*> args
;
17 class Environment
* env
;
19 class Environment
: public ::testing::Environment
{
21 Environment(): tenant("default_ns"), db(nullptr),
22 db_type("SQLite"), ret(-1) {}
24 Environment(string tenantname
, string db_typename
):
25 tenant("tenantname"), db(nullptr),
26 db_type("db_typename"), ret(-1) {}
28 virtual ~Environment() {}
30 void SetUp() override
{
31 cct
= global_init(NULL
, args
, CEPH_ENTITY_TYPE_CLIENT
,
32 CODE_ENVIRONMENT_DAEMON
,
33 CINIT_FLAG_NO_DEFAULT_CONFIG_FILE
| CINIT_FLAG_NO_MON_CONFIG
| CINIT_FLAG_NO_DAEMON_ACTIONS
)->get();
34 if (!db_type
.compare("SQLite")) {
35 db
= new SQLiteDB(tenant
, cct
);
36 ASSERT_TRUE(db
!= nullptr);
37 ret
= db
->Initialize(logfile
, loglevel
);
42 void TearDown() override
{
45 db
->Destroy(db
->get_def_dpp());
53 string logfile
= "rgw_dbstore_tests.log";
59 ceph::real_time bucket_mtime
= real_clock::now();
62 class DBGetDataCB
: public RGWGetDataCB
{
65 off_t data_ofs
, data_len
;
67 int handle_data(bufferlist
& bl
, off_t bl_ofs
, off_t bl_len
) {
77 class DBStoreTest
: public ::testing::Test
{
81 string user1
= "user1";
82 string user_id1
= "user_id1";
83 string bucket1
= "bucket1";
84 string object1
= "object1";
85 string data
= "Hello World";
86 DBOpParams GlobalParams
= {};
87 const DoutPrefixProvider
*dpp
;
92 ASSERT_TRUE(db
!= nullptr);
93 dpp
= db
->get_def_dpp();
94 ASSERT_TRUE(dpp
!= nullptr);
96 GlobalParams
.op
.user
.uinfo
.display_name
= user1
;
97 GlobalParams
.op
.user
.uinfo
.user_id
.id
= user_id1
;
98 GlobalParams
.op
.bucket
.info
.bucket
.name
= bucket1
;
99 GlobalParams
.op
.obj
.state
.obj
.bucket
= GlobalParams
.op
.bucket
.info
.bucket
;
100 GlobalParams
.op
.obj
.state
.obj
.key
.name
= object1
;
101 GlobalParams
.op
.obj
.state
.obj
.key
.instance
= "inst1";
102 GlobalParams
.op
.obj_data
.part_num
= 0;
104 /* As of now InitializeParams doesnt do anything
105 * special based on fop. Hence its okay to do
106 * global initialization once.
108 ret
= db
->InitializeParams(dpp
, "", &GlobalParams
);
117 TEST_F(DBStoreTest
, InsertUser
) {
118 struct DBOpParams params
= GlobalParams
;
121 params
.op
.user
.uinfo
.user_id
.tenant
= "tenant";
122 params
.op
.user
.uinfo
.user_email
= "user1@dbstore.com";
123 params
.op
.user
.uinfo
.suspended
= 123;
124 params
.op
.user
.uinfo
.max_buckets
= 456;
125 params
.op
.user
.uinfo
.assumed_role_arn
= "role";
126 params
.op
.user
.uinfo
.placement_tags
.push_back("tags");
127 RGWAccessKey
k1("id1", "key1");
128 RGWAccessKey
k2("id2", "key2");
129 params
.op
.user
.uinfo
.access_keys
["id1"] = k1
;
130 params
.op
.user
.uinfo
.access_keys
["id2"] = k2
;
131 params
.op
.user
.user_version
.ver
= 1;
132 params
.op
.user
.user_version
.tag
= "UserTAG";
134 ret
= db
->ProcessOp(dpp
, "InsertUser", ¶ms
);
138 TEST_F(DBStoreTest
, GetUser
) {
139 struct DBOpParams params
= GlobalParams
;
142 ret
= db
->ProcessOp(dpp
, "GetUser", ¶ms
);
144 ASSERT_EQ(params
.op
.user
.uinfo
.user_id
.tenant
, "tenant");
145 ASSERT_EQ(params
.op
.user
.uinfo
.user_email
, "user1@dbstore.com");
146 ASSERT_EQ(params
.op
.user
.uinfo
.user_id
.id
, "user_id1");
147 ASSERT_EQ(params
.op
.user
.uinfo
.suspended
, 123);
148 ASSERT_EQ(params
.op
.user
.uinfo
.max_buckets
, 456);
149 ASSERT_EQ(params
.op
.user
.uinfo
.assumed_role_arn
, "role");
150 ASSERT_EQ(params
.op
.user
.uinfo
.placement_tags
.back(), "tags");
152 map
<string
, RGWAccessKey
>::iterator it2
= params
.op
.user
.uinfo
.access_keys
.begin();
154 ASSERT_EQ(k
.id
, "id1");
155 ASSERT_EQ(k
.key
, "key1");
158 ASSERT_EQ(k
.id
, "id2");
159 ASSERT_EQ(k
.key
, "key2");
163 TEST_F(DBStoreTest
, GetUserQuery
) {
164 struct DBOpParams params
= GlobalParams
;
167 params
.op
.query_str
= "email";
168 params
.op
.user
.uinfo
.user_email
= "user1@dbstore.com";
170 ret
= db
->ProcessOp(dpp
, "GetUser", ¶ms
);
172 ASSERT_EQ(params
.op
.user
.uinfo
.user_id
.tenant
, "tenant");
173 ASSERT_EQ(params
.op
.user
.uinfo
.user_email
, "user1@dbstore.com");
174 ASSERT_EQ(params
.op
.user
.uinfo
.user_id
.id
, "user_id1");
175 ASSERT_EQ(params
.op
.user
.uinfo
.suspended
, 123);
176 ASSERT_EQ(params
.op
.user
.uinfo
.max_buckets
, 456);
177 ASSERT_EQ(params
.op
.user
.uinfo
.assumed_role_arn
, "role");
178 ASSERT_EQ(params
.op
.user
.uinfo
.placement_tags
.back(), "tags");
180 map
<string
, RGWAccessKey
>::iterator it2
= params
.op
.user
.uinfo
.access_keys
.begin();
182 ASSERT_EQ(k
.id
, "id1");
183 ASSERT_EQ(k
.key
, "key1");
186 ASSERT_EQ(k
.id
, "id2");
187 ASSERT_EQ(k
.key
, "key2");
191 TEST_F(DBStoreTest
, GetUserQueryByEmail
) {
194 string email
= "user1@dbstore.com";
195 map
<std::string
, bufferlist
> attrs
;
196 RGWObjVersionTracker objv
;
198 ret
= db
->get_user(dpp
, "email", email
, uinfo
, &attrs
, &objv
);
200 ASSERT_EQ(uinfo
.user_id
.tenant
, "tenant");
201 ASSERT_EQ(uinfo
.user_email
, "user1@dbstore.com");
202 ASSERT_EQ(uinfo
.user_id
.id
, "user_id1");
203 ASSERT_EQ(uinfo
.suspended
, 123);
204 ASSERT_EQ(uinfo
.max_buckets
, 456);
205 ASSERT_EQ(uinfo
.assumed_role_arn
, "role");
206 ASSERT_EQ(uinfo
.placement_tags
.back(), "tags");
208 map
<string
, RGWAccessKey
>::iterator it2
= uinfo
.access_keys
.begin();
210 ASSERT_EQ(k
.id
, "id1");
211 ASSERT_EQ(k
.key
, "key1");
214 ASSERT_EQ(k
.id
, "id2");
215 ASSERT_EQ(k
.key
, "key2");
216 ASSERT_EQ(objv
.read_version
.ver
, 1);
219 TEST_F(DBStoreTest
, GetUserQueryByAccessKey
) {
224 ret
= db
->get_user(dpp
, "access_key", key
, uinfo
, nullptr, nullptr);
226 ASSERT_EQ(uinfo
.user_id
.tenant
, "tenant");
227 ASSERT_EQ(uinfo
.user_email
, "user1@dbstore.com");
228 ASSERT_EQ(uinfo
.user_id
.id
, "user_id1");
229 ASSERT_EQ(uinfo
.suspended
, 123);
230 ASSERT_EQ(uinfo
.max_buckets
, 456);
231 ASSERT_EQ(uinfo
.assumed_role_arn
, "role");
232 ASSERT_EQ(uinfo
.placement_tags
.back(), "tags");
234 map
<string
, RGWAccessKey
>::iterator it2
= uinfo
.access_keys
.begin();
236 ASSERT_EQ(k
.id
, "id1");
237 ASSERT_EQ(k
.key
, "key1");
240 ASSERT_EQ(k
.id
, "id2");
241 ASSERT_EQ(k
.key
, "key2");
244 TEST_F(DBStoreTest
, StoreUser
) {
245 struct DBOpParams params
= GlobalParams
;
247 RGWUserInfo uinfo
, old_uinfo
;
248 map
<std::string
, bufferlist
> attrs
;
249 RGWObjVersionTracker objv_tracker
;
251 bufferlist attr1
, attr2
;
252 encode("attrs1", attr1
);
253 attrs
["attr1"] = attr1
;
254 encode("attrs2", attr2
);
255 attrs
["attr2"] = attr2
;
257 uinfo
.user_id
.id
= "user_id2";
258 uinfo
.user_id
.tenant
= "tenant";
259 uinfo
.user_email
= "user2@dbstore.com";
260 uinfo
.suspended
= 123;
261 uinfo
.max_buckets
= 456;
262 uinfo
.assumed_role_arn
= "role";
263 uinfo
.placement_tags
.push_back("tags");
264 RGWAccessKey
k1("id1", "key1");
265 RGWAccessKey
k2("id2", "key2");
266 uinfo
.access_keys
["id1"] = k1
;
267 uinfo
.access_keys
["id2"] = k2
;
269 /* non exclusive create..should create new one */
270 ret
= db
->store_user(dpp
, uinfo
, true, &attrs
, &objv_tracker
, &old_uinfo
);
272 ASSERT_EQ(old_uinfo
.user_email
, "");
273 ASSERT_EQ(objv_tracker
.read_version
.ver
, 1);
274 ASSERT_EQ(objv_tracker
.read_version
.tag
, "UserTAG");
276 /* invalid version number */
277 objv_tracker
.read_version
.ver
= 4;
278 ret
= db
->store_user(dpp
, uinfo
, true, &attrs
, &objv_tracker
, &old_uinfo
);
279 ASSERT_EQ(ret
, -125); /* returns ECANCELED */
280 ASSERT_EQ(old_uinfo
.user_id
.id
, uinfo
.user_id
.id
);
281 ASSERT_EQ(old_uinfo
.user_email
, uinfo
.user_email
);
283 /* exclusive create..should not create new one */
284 uinfo
.user_email
= "user2_new@dbstore.com";
285 objv_tracker
.read_version
.ver
= 1;
286 ret
= db
->store_user(dpp
, uinfo
, true, &attrs
, &objv_tracker
, &old_uinfo
);
288 ASSERT_EQ(old_uinfo
.user_email
, "user2@dbstore.com");
289 ASSERT_EQ(objv_tracker
.read_version
.ver
, 1);
291 ret
= db
->store_user(dpp
, uinfo
, false, &attrs
, &objv_tracker
, &old_uinfo
);
293 ASSERT_EQ(old_uinfo
.user_email
, "user2@dbstore.com");
294 ASSERT_EQ(objv_tracker
.read_version
.ver
, 2);
295 ASSERT_EQ(objv_tracker
.read_version
.tag
, "UserTAG");
298 TEST_F(DBStoreTest
, GetUserQueryByUserID
) {
301 map
<std::string
, bufferlist
> attrs
;
302 RGWObjVersionTracker objv
;
304 uinfo
.user_id
.tenant
= "tenant";
305 uinfo
.user_id
.id
= "user_id2";
307 ret
= db
->get_user(dpp
, "user_id", "", uinfo
, &attrs
, &objv
);
309 ASSERT_EQ(uinfo
.user_id
.tenant
, "tenant");
310 ASSERT_EQ(uinfo
.user_email
, "user2_new@dbstore.com");
311 ASSERT_EQ(uinfo
.user_id
.id
, "user_id2");
312 ASSERT_EQ(uinfo
.suspended
, 123);
313 ASSERT_EQ(uinfo
.max_buckets
, 456);
314 ASSERT_EQ(uinfo
.assumed_role_arn
, "role");
315 ASSERT_EQ(uinfo
.placement_tags
.back(), "tags");
317 map
<string
, RGWAccessKey
>::iterator it
= uinfo
.access_keys
.begin();
319 ASSERT_EQ(k
.id
, "id1");
320 ASSERT_EQ(k
.key
, "key1");
323 ASSERT_EQ(k
.id
, "id2");
324 ASSERT_EQ(k
.key
, "key2");
326 ASSERT_EQ(objv
.read_version
.ver
, 2);
330 map
<std::string
, bufferlist
>::iterator it2
= attrs
.begin();
333 ASSERT_EQ(attr
, "attrs1");
337 ASSERT_EQ(attr
, "attrs2");
340 TEST_F(DBStoreTest
, ListAllUsers
) {
341 struct DBOpParams params
= GlobalParams
;
344 ret
= db
->ListAllUsers(dpp
, ¶ms
);
348 TEST_F(DBStoreTest
, InsertBucket
) {
349 struct DBOpParams params
= GlobalParams
;
352 params
.op
.bucket
.info
.bucket
.name
= "bucket1";
353 params
.op
.bucket
.info
.bucket
.tenant
= "tenant";
354 params
.op
.bucket
.info
.bucket
.marker
= "marker1";
356 params
.op
.bucket
.ent
.size
= 1024;
358 params
.op
.bucket
.info
.has_instance_obj
= false;
359 params
.op
.bucket
.bucket_version
.ver
= 1;
360 params
.op
.bucket
.bucket_version
.tag
= "read_tag";
362 params
.op
.bucket
.mtime
= bucket_mtime
;
364 ret
= db
->ProcessOp(dpp
, "InsertBucket", ¶ms
);
368 TEST_F(DBStoreTest
, UpdateBucketAttrs
) {
371 map
<std::string
, bufferlist
> attrs
;
372 RGWObjVersionTracker objv
;
374 bufferlist aclbl
, aclbl2
;
375 encode("attrs1", aclbl
);
376 attrs
["attr1"] = aclbl
;
377 encode("attrs2", aclbl2
);
378 attrs
["attr2"] = aclbl2
;
380 info
.bucket
.name
= "bucket1";
382 /* invalid version number */
383 objv
.read_version
.ver
= 4;
384 ret
= db
->update_bucket(dpp
, "attrs", info
, false, nullptr, &attrs
, &bucket_mtime
, &objv
);
385 ASSERT_EQ(ret
, -125); /* returns ECANCELED */
387 /* right version number */
388 objv
.read_version
.ver
= 1;
389 ret
= db
->update_bucket(dpp
, "attrs", info
, false, nullptr, &attrs
, &bucket_mtime
, &objv
);
391 ASSERT_EQ(objv
.read_version
.ver
, 2);
394 TEST_F(DBStoreTest
, BucketChown
) {
398 user
.id
= "user_id2";
400 info
.bucket
.name
= "bucket1";
402 ret
= db
->update_bucket(dpp
, "owner", info
, false, &user
, nullptr, &bucket_mtime
, nullptr);
404 ASSERT_EQ(info
.objv_tracker
.read_version
.ver
, 3);
407 TEST_F(DBStoreTest
, UpdateBucketInfo
) {
408 struct DBOpParams params
= GlobalParams
;
412 params
.op
.bucket
.info
.bucket
.name
= "bucket1";
414 ret
= db
->ProcessOp(dpp
, "GetBucket", ¶ms
);
417 info
= params
.op
.bucket
.info
;
419 info
.bucket
.marker
= "marker2";
420 ret
= db
->update_bucket(dpp
, "info", info
, false, nullptr, nullptr, &bucket_mtime
, nullptr);
422 ASSERT_EQ(info
.objv_tracker
.read_version
.ver
, 4);
425 TEST_F(DBStoreTest
, GetBucket
) {
426 struct DBOpParams params
= GlobalParams
;
429 ret
= db
->ProcessOp(dpp
, "GetBucket", ¶ms
);
431 ASSERT_EQ(params
.op
.bucket
.info
.bucket
.name
, "bucket1");
432 ASSERT_EQ(params
.op
.bucket
.info
.bucket
.tenant
, "tenant");
433 ASSERT_EQ(params
.op
.bucket
.info
.bucket
.marker
, "marker2");
434 ASSERT_EQ(params
.op
.bucket
.ent
.size
, 1024);
435 ASSERT_EQ(params
.op
.bucket
.ent
.bucket
.name
, "bucket1");
436 ASSERT_EQ(params
.op
.bucket
.ent
.bucket
.tenant
, "tenant");
437 ASSERT_EQ(params
.op
.bucket
.info
.has_instance_obj
, false);
438 ASSERT_EQ(params
.op
.bucket
.info
.objv_tracker
.read_version
.ver
, 4);
439 ASSERT_EQ(params
.op
.bucket
.info
.objv_tracker
.read_version
.tag
, "read_tag");
440 ASSERT_EQ(params
.op
.bucket
.mtime
, bucket_mtime
);
441 ASSERT_EQ(params
.op
.bucket
.info
.owner
.id
, "user_id2");
444 map
<std::string
, bufferlist
>::iterator it2
= params
.op
.bucket
.bucket_attrs
.begin();
447 ASSERT_EQ(acl
, "attrs1");
451 ASSERT_EQ(acl
, "attrs2");
454 TEST_F(DBStoreTest
, RemoveBucketAPI
) {
458 info
.bucket
.name
= "bucket1";
460 ret
= db
->remove_bucket(dpp
, info
);
464 TEST_F(DBStoreTest
, RemoveUserAPI
) {
467 RGWObjVersionTracker objv
;
469 uinfo
.user_id
.tenant
= "tenant";
470 uinfo
.user_id
.id
= "user_id2";
472 /* invalid version number...should fail */
473 objv
.read_version
.ver
= 4;
474 ret
= db
->remove_user(dpp
, uinfo
, &objv
);
475 ASSERT_EQ(ret
, -125);
477 /* invalid version number...should fail */
478 objv
.read_version
.ver
= 2;
479 ret
= db
->remove_user(dpp
, uinfo
, &objv
);
483 TEST_F(DBStoreTest
, CreateBucket
) {
484 struct DBOpParams params
= GlobalParams
;
490 rgw_placement_rule rule
;
491 map
<std::string
, bufferlist
> attrs
;
493 owner
.user_id
.id
= "user_id1";
494 bucket
.name
= "bucket1";
495 bucket
.tenant
= "tenant";
498 objv
.tag
= "write_tag";
501 rule
.storage_class
= "sc1";
503 ret
= db
->create_bucket(dpp
, owner
, bucket
, "zid", rule
, "swift_ver", NULL
,
504 attrs
, info
, &objv
, NULL
, bucket_mtime
, NULL
, NULL
,
507 bucket
.name
= "bucket2";
508 ret
= db
->create_bucket(dpp
, owner
, bucket
, "zid", rule
, "swift_ver", NULL
,
509 attrs
, info
, &objv
, NULL
, bucket_mtime
, NULL
, NULL
,
512 bucket
.name
= "bucket3";
513 ret
= db
->create_bucket(dpp
, owner
, bucket
, "zid", rule
, "swift_ver", NULL
,
514 attrs
, info
, &objv
, NULL
, bucket_mtime
, NULL
, NULL
,
517 bucket
.name
= "bucket4";
518 ret
= db
->create_bucket(dpp
, owner
, bucket
, "zid", rule
, "swift_ver", NULL
,
519 attrs
, info
, &objv
, NULL
, bucket_mtime
, NULL
, NULL
,
522 bucket
.name
= "bucket5";
523 ret
= db
->create_bucket(dpp
, owner
, bucket
, "zid", rule
, "swift_ver", NULL
,
524 attrs
, info
, &objv
, NULL
, bucket_mtime
, NULL
, NULL
,
529 TEST_F(DBStoreTest
, GetBucketQueryByName
) {
532 binfo
.bucket
.name
= "bucket2";
533 rgw::sal::Attrs attrs
;
534 ceph::real_time mtime
;
537 ret
= db
->get_bucket_info(dpp
, "name", "", binfo
, &attrs
, &mtime
, &objv
);
539 ASSERT_EQ(binfo
.bucket
.name
, "bucket2");
540 ASSERT_EQ(binfo
.bucket
.tenant
, "tenant");
541 ASSERT_EQ(binfo
.owner
.id
, "user_id1");
542 ASSERT_EQ(binfo
.objv_tracker
.read_version
.ver
, 2);
543 ASSERT_EQ(binfo
.objv_tracker
.read_version
.tag
, "write_tag");
544 ASSERT_EQ(binfo
.zonegroup
, "zid");
545 ASSERT_EQ(binfo
.creation_time
, bucket_mtime
);
546 ASSERT_EQ(binfo
.placement_rule
.name
, "rule1");
547 ASSERT_EQ(binfo
.placement_rule
.storage_class
, "sc1");
548 ASSERT_EQ(objv
.ver
, 2);
549 ASSERT_EQ(objv
.tag
, "write_tag");
551 marker1
= binfo
.bucket
.marker
;
554 TEST_F(DBStoreTest
, ListUserBuckets
) {
555 struct DBOpParams params
= GlobalParams
;
559 bool need_stats
= true;
560 bool is_truncated
= false;
561 RGWUserBuckets ulist
;
563 owner
.id
= "user_id1";
567 is_truncated
= false;
568 ret
= db
->list_buckets(dpp
, owner
, marker1
, "", max
, need_stats
, &ulist
, &is_truncated
);
571 cout
<< "marker1 :" << marker1
<< "\n";
573 cout
<< "is_truncated :" << is_truncated
<< "\n";
575 for (const auto& ent
: ulist
.get_buckets()) {
576 RGWBucketEnt e
= ent
.second
;
577 cout
<< "###################### \n";
578 cout
<< "ent.bucket.id : " << e
.bucket
.name
<< "\n";
579 cout
<< "ent.bucket.marker : " << e
.bucket
.marker
<< "\n";
580 cout
<< "ent.bucket.bucket_id : " << e
.bucket
.bucket_id
<< "\n";
581 cout
<< "ent.size : " << e
.size
<< "\n";
582 cout
<< "ent.rule.name : " << e
.placement_rule
.name
<< "\n";
584 marker1
= e
.bucket
.name
;
587 } while(is_truncated
);
590 TEST_F(DBStoreTest
, ListAllBuckets
) {
591 struct DBOpParams params
= GlobalParams
;
594 ret
= db
->ListAllBuckets(dpp
, ¶ms
);
598 TEST_F(DBStoreTest
, PutObject
) {
599 struct DBOpParams params
= GlobalParams
;
602 params
.op
.obj
.category
= RGWObjCategory::Main
;
603 params
.op
.obj
.storage_class
= "STANDARD";
605 encode("HELLO WORLD", b1
);
606 cout
<<"XXXXXXXXX Insert b1.length " << b1
.length() << "\n";
607 params
.op
.obj
.head_data
= b1
;
608 params
.op
.obj
.state
.size
= 12;
609 params
.op
.obj
.state
.is_olh
= false;
610 ret
= db
->ProcessOp(dpp
, "PutObject", ¶ms
);
613 /* Insert another objects */
614 params
.op
.obj
.state
.obj
.key
.name
= "object2";
615 params
.op
.obj
.state
.obj
.key
.instance
= "inst2";
616 ret
= db
->ProcessOp(dpp
, "PutObject", ¶ms
);
619 params
.op
.obj
.state
.obj
.key
.name
= "object3";
620 params
.op
.obj
.state
.obj
.key
.instance
= "inst3";
621 ret
= db
->ProcessOp(dpp
, "PutObject", ¶ms
);
625 TEST_F(DBStoreTest
, ListAllObjects
) {
626 struct DBOpParams params
= GlobalParams
;
629 ret
= db
->ListAllObjects(dpp
, ¶ms
);
633 TEST_F(DBStoreTest
, GetObject
) {
634 struct DBOpParams params
= GlobalParams
;
637 ret
= db
->ProcessOp(dpp
, "GetObject", ¶ms
);
639 ASSERT_EQ(params
.op
.obj
.category
, RGWObjCategory::Main
);
640 ASSERT_EQ(params
.op
.obj
.storage_class
, "STANDARD");
642 decode(data
, params
.op
.obj
.head_data
);
643 ASSERT_EQ(data
, "HELLO WORLD");
644 ASSERT_EQ(params
.op
.obj
.state
.size
, 12);
647 TEST_F(DBStoreTest
, GetObjectState
) {
648 struct DBOpParams params
= GlobalParams
;
651 RGWObjState
*s
= &state
;
653 params
.op
.obj
.state
.obj
.key
.name
= "object2";
654 params
.op
.obj
.state
.obj
.key
.instance
= "inst2";
655 DB::Object
op_target(db
, params
.op
.bucket
.info
,
656 params
.op
.obj
.state
.obj
);
658 ret
= op_target
.get_obj_state(dpp
, params
.op
.bucket
.info
, params
.op
.obj
.state
.obj
,
661 ASSERT_EQ(state
.size
, 12);
662 ASSERT_EQ(state
.is_olh
, false);
664 /* Recheck with get_state API */
665 ret
= op_target
.get_state(dpp
, &s
, false);
667 ASSERT_EQ(state
.size
, 12);
668 ASSERT_EQ(state
.is_olh
, false);
671 TEST_F(DBStoreTest
, ObjAttrs
) {
672 struct DBOpParams params
= GlobalParams
;
674 map
<string
, bufferlist
> setattrs
;
675 map
<string
, bufferlist
> rmattrs
;
676 map
<string
, bufferlist
> readattrs
;
678 bufferlist b1
, b2
, b3
;
680 setattrs
[RGW_ATTR_ACL
] = b1
;
682 setattrs
[RGW_ATTR_LC
] = b2
;
684 setattrs
[RGW_ATTR_ETAG
] = b3
;
686 DB::Object
op_target(db
, params
.op
.bucket
.info
,
687 params
.op
.obj
.state
.obj
);
690 ret
= op_target
.set_attrs(dpp
, setattrs
, nullptr);
693 /* read those attrs */
694 DB::Object::Read
read_op(&op_target
);
695 read_op
.params
.attrs
= &readattrs
;
696 ret
= read_op
.prepare(dpp
);
700 decode(val
, readattrs
[RGW_ATTR_ACL
]);
701 ASSERT_EQ(val
, "ACL");
702 decode(val
, readattrs
[RGW_ATTR_LC
]);
703 ASSERT_EQ(val
, "LC");
704 decode(val
, readattrs
[RGW_ATTR_ETAG
]);
705 ASSERT_EQ(val
, "ETAG");
707 /* Remove some attrs */
708 rmattrs
[RGW_ATTR_ACL
] = b1
;
709 map
<string
, bufferlist
> empty
;
710 ret
= op_target
.set_attrs(dpp
, empty
, &rmattrs
);
713 /* read those attrs */
714 ret
= read_op
.prepare(dpp
);
717 ASSERT_EQ(readattrs
.count(RGW_ATTR_ACL
), 0);
718 decode(val
, readattrs
[RGW_ATTR_LC
]);
719 ASSERT_EQ(val
, "LC");
720 decode(val
, readattrs
[RGW_ATTR_ETAG
]);
721 ASSERT_EQ(val
, "ETAG");
724 TEST_F(DBStoreTest
, WriteObject
) {
725 struct DBOpParams params
= GlobalParams
;
727 map
<string
, bufferlist
> setattrs
;
728 params
.op
.obj
.state
.obj
.key
.name
= "object3";
729 params
.op
.obj
.state
.obj
.key
.instance
= "inst3";
730 DB::Object
op_target(db
, params
.op
.bucket
.info
,
731 params
.op
.obj
.state
.obj
);
732 DB::Object::Write
write_op(&op_target
);
733 ret
= write_op
.prepare(dpp
);
736 write_op
.meta
.mtime
= &bucket_mtime
;
737 write_op
.meta
.category
= RGWObjCategory::Main
;
738 write_op
.meta
.owner
= params
.op
.user
.uinfo
.user_id
;
741 encode("HELLO WORLD - Object3", b1
);
742 cout
<<"XXXXXXXXX Insert b1.length " << b1
.length() << "\n";
743 write_op
.meta
.data
= &b1
;
747 setattrs
[RGW_ATTR_ACL
] = b2
;
749 ret
= write_op
.write_meta(0, 22, 25, setattrs
);
753 TEST_F(DBStoreTest
, ReadObject
) {
754 struct DBOpParams params
= GlobalParams
;
756 map
<string
, bufferlist
> readattrs
;
757 params
.op
.obj
.state
.obj
.key
.name
= "object3";
758 params
.op
.obj
.state
.obj
.key
.instance
= "inst3";
760 DB::Object
op_target(db
, params
.op
.bucket
.info
,
761 params
.op
.obj
.state
.obj
);
762 DB::Object::Read
read_op(&op_target
);
763 read_op
.params
.attrs
= &readattrs
;
764 read_op
.params
.obj_size
= &obj_size
;
765 ret
= read_op
.prepare(dpp
);
769 ret
= read_op
.read(0, 25, bl
, dpp
);
770 cout
<<"XXXXXXXXX Insert bl.length " << bl
.length() << "\n";
775 ASSERT_EQ(data
, "HELLO WORLD - Object3");
776 ASSERT_EQ(obj_size
, 22);
779 TEST_F(DBStoreTest
, IterateObject
) {
780 struct DBOpParams params
= GlobalParams
;
782 map
<string
, bufferlist
> readattrs
;
786 DB::Object
op_target(db
, params
.op
.bucket
.info
,
787 params
.op
.obj
.state
.obj
);
788 DB::Object::Read
read_op(&op_target
);
789 read_op
.params
.attrs
= &readattrs
;
790 read_op
.params
.obj_size
= &obj_size
;
791 ret
= read_op
.prepare(dpp
);
795 ret
= read_op
.iterate(dpp
, 0, 15, &cb
);
798 decode(data
, cb
.data_bl
);
799 cout
<< "XXXXXXXXXX iterate data is " << data
<< ", bl_ofs = " << cb
.data_ofs
<< ", bl_len = " << cb
.data_len
<< "\n";
800 ASSERT_EQ(data
, "HELLO WORLD");
801 ASSERT_EQ(cb
.data_ofs
, 0);
802 ASSERT_EQ(cb
.data_len
, 15);
805 TEST_F(DBStoreTest
, ListBucketObjects
) {
806 struct DBOpParams params
= GlobalParams
;
810 bool is_truncated
= false;
812 DB::Bucket
target(db
, params
.op
.bucket
.info
);
813 DB::Bucket::List
list_op(&target
);
815 vector
<rgw_bucket_dir_entry
> dir_list
;
819 is_truncated
= false;
820 list_op
.params
.marker
= marker1
;
821 ret
= list_op
.list_objects(dpp
, max
, &dir_list
, nullptr, &is_truncated
);
824 cout
<< "marker1 :" << marker1
.name
<< "\n";
826 cout
<< "is_truncated :" << is_truncated
<< "\n";
828 for (const auto& ent
: dir_list
) {
829 cls_rgw_obj_key key
= ent
.key
;
830 cout
<< "###################### \n";
831 cout
<< "key.name : " << key
.name
<< "\n";
832 cout
<< "key.instance : " << key
.instance
<< "\n";
834 marker1
= list_op
.get_next_marker();
837 } while(is_truncated
);
840 TEST_F(DBStoreTest
, DeleteObj
) {
841 struct DBOpParams params
= GlobalParams
;
844 RGWObjState
*s
= &state
;
847 params
.op
.obj
.state
.obj
.key
.name
= "object2";
848 params
.op
.obj
.state
.obj
.key
.instance
= "inst2";
849 DB::Object
op_target(db
, params
.op
.bucket
.info
,
850 params
.op
.obj
.state
.obj
);
852 DB::Object::Delete
delete_op(&op_target
);
853 ret
= delete_op
.delete_obj(dpp
);
856 /* Should return ENOENT */
857 ret
= op_target
.get_state(dpp
, &s
, false);
861 TEST_F(DBStoreTest
, ObjectOmapSetVal
) {
862 struct DBOpParams params
= GlobalParams
;
865 DB::Object
op_target(db
, params
.op
.bucket
.info
,
866 params
.op
.obj
.state
.obj
);
868 string val
= "part1_val";
871 ret
= op_target
.obj_omap_set_val_by_key(dpp
, "part1", bl
, false);
877 ret
= op_target
.obj_omap_set_val_by_key(dpp
, "part2", bl
, false);
883 ret
= op_target
.obj_omap_set_val_by_key(dpp
, "part3", bl
, false);
889 ret
= op_target
.obj_omap_set_val_by_key(dpp
, "part4", bl
, false);
893 TEST_F(DBStoreTest
, ObjectOmapGetValsByKeys
) {
894 struct DBOpParams params
= GlobalParams
;
896 std::set
<std::string
> keys
;
897 std::map
<std::string
, bufferlist
> vals
;
899 DB::Object
op_target(db
, params
.op
.bucket
.info
,
900 params
.op
.obj
.state
.obj
);
902 keys
.insert("part2");
903 keys
.insert("part4");
905 ret
= op_target
.obj_omap_get_vals_by_keys(dpp
, "", keys
, &vals
);
907 ASSERT_EQ(vals
.size(), 2);
910 decode(val
, vals
["part2"]);
911 ASSERT_EQ(val
, "part2_val");
912 decode(val
, vals
["part4"]);
913 ASSERT_EQ(val
, "part4_val");
916 TEST_F(DBStoreTest
, ObjectOmapGetAll
) {
917 struct DBOpParams params
= GlobalParams
;
919 std::map
<std::string
, bufferlist
> vals
;
921 DB::Object
op_target(db
, params
.op
.bucket
.info
,
922 params
.op
.obj
.state
.obj
);
924 ret
= op_target
.obj_omap_get_all(dpp
, &vals
);
926 ASSERT_EQ(vals
.size(), 4);
929 decode(val
, vals
["part1"]);
930 ASSERT_EQ(val
, "part1_val");
931 decode(val
, vals
["part2"]);
932 ASSERT_EQ(val
, "part2_val");
933 decode(val
, vals
["part3"]);
934 ASSERT_EQ(val
, "part3_val");
935 decode(val
, vals
["part4"]);
936 ASSERT_EQ(val
, "part4_val");
939 TEST_F(DBStoreTest
, ObjectOmapGetVals
) {
940 struct DBOpParams params
= GlobalParams
;
942 std::set
<std::string
> keys
;
943 std::map
<std::string
, bufferlist
> vals
;
946 DB::Object
op_target(db
, params
.op
.bucket
.info
,
947 params
.op
.obj
.state
.obj
);
949 ret
= op_target
.obj_omap_get_vals(dpp
, "part3", 10, &vals
, &pmore
);
951 ASSERT_EQ(vals
.size(), 2);
954 decode(val
, vals
["part3"]);
955 ASSERT_EQ(val
, "part3_val");
956 decode(val
, vals
["part4"]);
957 ASSERT_EQ(val
, "part4_val");
960 TEST_F(DBStoreTest
, PutObjectData
) {
961 struct DBOpParams params
= GlobalParams
;
964 params
.op
.obj_data
.part_num
= 1;
965 params
.op
.obj_data
.offset
= 10;
966 params
.op
.obj_data
.multipart_part_str
= "2";
968 encode("HELLO WORLD", b1
);
969 params
.op
.obj_data
.data
= b1
;
970 params
.op
.obj_data
.size
= 12;
971 ret
= db
->ProcessOp(dpp
, "PutObjectData", ¶ms
);
975 TEST_F(DBStoreTest
, UpdateObjectData
) {
976 struct DBOpParams params
= GlobalParams
;
979 params
.op
.obj
.new_obj_key
.name
= "object3";
980 params
.op
.obj
.new_obj_key
.instance
= "inst3";
981 ret
= db
->ProcessOp(dpp
, "UpdateObjectData", ¶ms
);
985 TEST_F(DBStoreTest
, GetObjectData
) {
986 struct DBOpParams params
= GlobalParams
;
989 params
.op
.obj
.state
.obj
.key
.instance
= "inst3";
990 params
.op
.obj
.state
.obj
.key
.name
= "object3";
991 ret
= db
->ProcessOp(dpp
, "GetObjectData", ¶ms
);
993 ASSERT_EQ(params
.op
.obj_data
.part_num
, 1);
994 ASSERT_EQ(params
.op
.obj_data
.offset
, 10);
995 ASSERT_EQ(params
.op
.obj_data
.multipart_part_str
, "2");
996 ASSERT_EQ(params
.op
.obj
.state
.obj
.key
.instance
, "inst3");
997 ASSERT_EQ(params
.op
.obj
.state
.obj
.key
.name
, "object3");
999 decode(data
, params
.op
.obj_data
.data
);
1000 ASSERT_EQ(data
, "HELLO WORLD");
1003 TEST_F(DBStoreTest
, DeleteObjectData
) {
1004 struct DBOpParams params
= GlobalParams
;
1007 ret
= db
->ProcessOp(dpp
, "DeleteObjectData", ¶ms
);
1011 TEST_F(DBStoreTest
, DeleteObject
) {
1012 struct DBOpParams params
= GlobalParams
;
1015 ret
= db
->ProcessOp(dpp
, "DeleteObject", ¶ms
);
1019 TEST_F(DBStoreTest
, LCTables
) {
1020 struct DBOpParams params
= GlobalParams
;
1023 ret
= db
->createLCTables(dpp
);
1027 TEST_F(DBStoreTest
, LCHead
) {
1028 struct DBOpParams params
= GlobalParams
;
1030 std::string index1
= "bucket1";
1031 std::string index2
= "bucket2";
1032 time_t lc_time
= ceph_clock_now();
1033 rgw::sal::Lifecycle::LCHead head
;
1034 std::string ents
[] = {"entry1", "entry2", "entry3"};
1035 rgw::sal::Lifecycle::LCHead head1
= {lc_time
, ents
[0]};
1036 rgw::sal::Lifecycle::LCHead head2
= {lc_time
, ents
[1]};
1037 rgw::sal::Lifecycle::LCHead head3
= {lc_time
, ents
[2]};
1039 ret
= db
->put_head(index1
, head1
);
1041 ret
= db
->put_head(index2
, head2
);
1044 ret
= db
->get_head(index1
, head
);
1046 ASSERT_EQ(head
.marker
, "entry1");
1048 ret
= db
->get_head(index2
, head
);
1050 ASSERT_EQ(head
.marker
, "entry2");
1053 ret
= db
->put_head(index1
, head3
);
1055 ret
= db
->get_head(index1
, head
);
1057 ASSERT_EQ(head
.marker
, "entry3");
1060 TEST_F(DBStoreTest
, LCEntry
) {
1061 struct DBOpParams params
= GlobalParams
;
1063 uint64_t lc_time
= ceph_clock_now();
1064 std::string index1
= "lcindex1";
1065 std::string index2
= "lcindex2";
1066 typedef enum {lc_uninitial
= 1, lc_complete
} status
;
1067 std::string ents
[] = {"bucket1", "bucket2", "bucket3", "bucket4"};
1068 rgw::sal::Lifecycle::LCEntry entry
;
1069 rgw::sal::Lifecycle::LCEntry entry1
= {ents
[0], lc_time
, lc_uninitial
};
1070 rgw::sal::Lifecycle::LCEntry entry2
= {ents
[1], lc_time
, lc_uninitial
};
1071 rgw::sal::Lifecycle::LCEntry entry3
= {ents
[2], lc_time
, lc_uninitial
};
1072 rgw::sal::Lifecycle::LCEntry entry4
= {ents
[3], lc_time
, lc_uninitial
};
1074 vector
<rgw::sal::Lifecycle::LCEntry
> lc_entries
;
1076 ret
= db
->set_entry(index1
, entry1
);
1078 ret
= db
->set_entry(index1
, entry2
);
1080 ret
= db
->set_entry(index1
, entry3
);
1082 ret
= db
->set_entry(index2
, entry4
);
1085 // get entry index1, entry1
1086 ret
= db
->get_entry(index1
, ents
[0], entry
);
1088 ASSERT_EQ(entry
.status
, lc_uninitial
);
1089 ASSERT_EQ(entry
.start_time
, lc_time
);
1091 // get next entry index1, entry2
1092 ret
= db
->get_next_entry(index1
, ents
[1], entry
);
1094 ASSERT_EQ(entry
.bucket
, ents
[2]);
1095 ASSERT_EQ(entry
.status
, lc_uninitial
);
1096 ASSERT_EQ(entry
.start_time
, lc_time
);
1098 // update entry4 to entry5
1099 entry4
.status
= lc_complete
;
1100 ret
= db
->set_entry(index2
, entry4
);
1102 ret
= db
->get_entry(index2
, ents
[3], entry
);
1104 ASSERT_EQ(entry
.status
, lc_complete
);
1107 ret
= db
->list_entries(index1
, "", 5, lc_entries
);
1109 for (const auto& ent
: lc_entries
) {
1110 cout
<< "###################### \n";
1111 cout
<< "lc entry.bucket : " << ent
.bucket
<< "\n";
1112 cout
<< "lc entry.status : " << ent
.status
<< "\n";
1115 // remove index1, entry3
1116 ret
= db
->rm_entry(index1
, entry3
);
1119 // get next entry index1, entry2.. should be null
1121 ret
= db
->get_next_entry(index1
, ents
[1], entry
);
1123 ASSERT_EQ(entry
.start_time
, 0);
1126 TEST_F(DBStoreTest
, RemoveBucket
) {
1127 struct DBOpParams params
= GlobalParams
;
1130 ret
= db
->ProcessOp(dpp
, "RemoveBucket", ¶ms
);
1134 TEST_F(DBStoreTest
, RemoveUser
) {
1135 struct DBOpParams params
= GlobalParams
;
1138 ret
= db
->ProcessOp(dpp
, "RemoveUser", ¶ms
);
1142 TEST_F(DBStoreTest
, InsertTestIDUser
) {
1143 struct DBOpParams params
= GlobalParams
;
1146 params
.op
.user
.uinfo
.user_id
.id
= "testid";
1147 params
.op
.user
.uinfo
.display_name
= "M. Tester";
1148 params
.op
.user
.uinfo
.user_id
.tenant
= "tenant";
1149 params
.op
.user
.uinfo
.user_email
= "tester@ceph.com";
1150 RGWAccessKey
k1("0555b35654ad1656d804", "h7GhxuBLTrlhVUyxSPUKUV8r/2EI4ngqJxD7iBdBYLhwluN30JaT3Q==");
1151 params
.op
.user
.uinfo
.access_keys
["0555b35654ad1656d804"] = k1
;
1152 params
.op
.user
.user_version
.ver
= 1;
1153 params
.op
.user
.user_version
.tag
= "UserTAG";
1155 ret
= db
->ProcessOp(dpp
, "InsertUser", ¶ms
);
1159 int main(int argc
, char **argv
)
1162 string c_logfile
= "rgw_dbstore_tests.log";
1163 int c_loglevel
= 20;
1165 // format: ./dbstore-tests logfile loglevel
1167 c_logfile
= argv
[1];
1168 c_loglevel
= (atoi
)(argv
[2]);
1169 cout
<< "logfile:" << c_logfile
<< ", loglevel set to " << c_loglevel
<< "\n";
1172 ::testing::InitGoogleTest(&argc
, argv
);
1174 gtest::env
= new gtest::Environment();
1175 gtest::env
->logfile
= c_logfile
;
1176 gtest::env
->loglevel
= c_loglevel
;
1177 ::testing::AddGlobalTestEnvironment(gtest::env
);
1179 ret
= RUN_ALL_TESTS();