]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/store/dbstore/tests/dbstore_tests.cc
buildsys: change download over to reef release
[ceph.git] / ceph / src / rgw / store / dbstore / tests / dbstore_tests.cc
1 #include "gtest/gtest.h"
2 #include <iostream>
3 #include <stdlib.h>
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <dbstore.h>
8 #include <sqliteDB.h>
9 #include "rgw_common.h"
10
11 using namespace std;
12 using DB = rgw::store::DB;
13
14 vector<const char*> args;
15
16 namespace gtest {
17 class Environment* env;
18
19 class Environment : public ::testing::Environment {
20 public:
21 Environment(): tenant("default_ns"), db(nullptr),
22 db_type("SQLite"), ret(-1) {}
23
24 Environment(string tenantname, string db_typename):
25 tenant("tenantname"), db(nullptr),
26 db_type("db_typename"), ret(-1) {}
27
28 virtual ~Environment() {}
29
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);
38 ASSERT_GE(ret, 0);
39 }
40 }
41
42 void TearDown() override {
43 if (!db)
44 return;
45 db->Destroy(db->get_def_dpp());
46 delete db;
47 }
48
49 string tenant;
50 DB *db;
51 string db_type;
52 int ret;
53 string logfile = "rgw_dbstore_tests.log";
54 int loglevel = 30;
55 CephContext *cct;
56 };
57 }
58
59 ceph::real_time bucket_mtime = real_clock::now();
60 string marker1;
61
62 class DBGetDataCB : public RGWGetDataCB {
63 public:
64 bufferlist data_bl;
65 off_t data_ofs, data_len;
66
67 int handle_data(bufferlist& bl, off_t bl_ofs, off_t bl_len) {
68 data_bl = bl;
69 data_ofs = bl_ofs;
70 data_len = bl_len;
71 return 0;
72 }
73 };
74
75 namespace {
76
77 class DBStoreTest : public ::testing::Test {
78 protected:
79 int ret;
80 DB *db = nullptr;
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;
88
89 DBStoreTest() {}
90 void SetUp() {
91 db = gtest::env->db;
92 ASSERT_TRUE(db != nullptr);
93 dpp = db->get_def_dpp();
94 ASSERT_TRUE(dpp != nullptr);
95
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;
103
104 /* As of now InitializeParams doesnt do anything
105 * special based on fop. Hence its okay to do
106 * global initialization once.
107 */
108 ret = db->InitializeParams(dpp, "", &GlobalParams);
109 ASSERT_EQ(ret, 0);
110 }
111
112 void TearDown() {
113 }
114 };
115 }
116
117 TEST_F(DBStoreTest, InsertUser) {
118 struct DBOpParams params = GlobalParams;
119 int ret = -1;
120
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";
133
134 ret = db->ProcessOp(dpp, "InsertUser", &params);
135 ASSERT_EQ(ret, 0);
136 }
137
138 TEST_F(DBStoreTest, GetUser) {
139 struct DBOpParams params = GlobalParams;
140 int ret = -1;
141
142 ret = db->ProcessOp(dpp, "GetUser", &params);
143 ASSERT_EQ(ret, 0);
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");
151 RGWAccessKey k;
152 map<string, RGWAccessKey>::iterator it2 = params.op.user.uinfo.access_keys.begin();
153 k = it2->second;
154 ASSERT_EQ(k.id, "id1");
155 ASSERT_EQ(k.key, "key1");
156 it2++;
157 k = it2->second;
158 ASSERT_EQ(k.id, "id2");
159 ASSERT_EQ(k.key, "key2");
160
161 }
162
163 TEST_F(DBStoreTest, GetUserQuery) {
164 struct DBOpParams params = GlobalParams;
165 int ret = -1;
166
167 params.op.query_str = "email";
168 params.op.user.uinfo.user_email = "user1@dbstore.com";
169
170 ret = db->ProcessOp(dpp, "GetUser", &params);
171 ASSERT_EQ(ret, 0);
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");
179 RGWAccessKey k;
180 map<string, RGWAccessKey>::iterator it2 = params.op.user.uinfo.access_keys.begin();
181 k = it2->second;
182 ASSERT_EQ(k.id, "id1");
183 ASSERT_EQ(k.key, "key1");
184 it2++;
185 k = it2->second;
186 ASSERT_EQ(k.id, "id2");
187 ASSERT_EQ(k.key, "key2");
188
189 }
190
191 TEST_F(DBStoreTest, GetUserQueryByEmail) {
192 int ret = -1;
193 RGWUserInfo uinfo;
194 string email = "user1@dbstore.com";
195 map<std::string, bufferlist> attrs;
196 RGWObjVersionTracker objv;
197
198 ret = db->get_user(dpp, "email", email, uinfo, &attrs, &objv);
199 ASSERT_EQ(ret, 0);
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");
207 RGWAccessKey k;
208 map<string, RGWAccessKey>::iterator it2 = uinfo.access_keys.begin();
209 k = it2->second;
210 ASSERT_EQ(k.id, "id1");
211 ASSERT_EQ(k.key, "key1");
212 it2++;
213 k = it2->second;
214 ASSERT_EQ(k.id, "id2");
215 ASSERT_EQ(k.key, "key2");
216 ASSERT_EQ(objv.read_version.ver, 1);
217 }
218
219 TEST_F(DBStoreTest, GetUserQueryByAccessKey) {
220 int ret = -1;
221 RGWUserInfo uinfo;
222 string key = "id1";
223
224 ret = db->get_user(dpp, "access_key", key, uinfo, nullptr, nullptr);
225 ASSERT_EQ(ret, 0);
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");
233 RGWAccessKey k;
234 map<string, RGWAccessKey>::iterator it2 = uinfo.access_keys.begin();
235 k = it2->second;
236 ASSERT_EQ(k.id, "id1");
237 ASSERT_EQ(k.key, "key1");
238 it2++;
239 k = it2->second;
240 ASSERT_EQ(k.id, "id2");
241 ASSERT_EQ(k.key, "key2");
242 }
243
244 TEST_F(DBStoreTest, StoreUser) {
245 struct DBOpParams params = GlobalParams;
246 int ret = -1;
247 RGWUserInfo uinfo, old_uinfo;
248 map<std::string, bufferlist> attrs;
249 RGWObjVersionTracker objv_tracker;
250
251 bufferlist attr1, attr2;
252 encode("attrs1", attr1);
253 attrs["attr1"] = attr1;
254 encode("attrs2", attr2);
255 attrs["attr2"] = attr2;
256
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;
268
269 /* non exclusive create..should create new one */
270 ret = db->store_user(dpp, uinfo, true, &attrs, &objv_tracker, &old_uinfo);
271 ASSERT_EQ(ret, 0);
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");
275
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);
282
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);
287 ASSERT_EQ(ret, 0);
288 ASSERT_EQ(old_uinfo.user_email, "user2@dbstore.com");
289 ASSERT_EQ(objv_tracker.read_version.ver, 1);
290
291 ret = db->store_user(dpp, uinfo, false, &attrs, &objv_tracker, &old_uinfo);
292 ASSERT_EQ(ret, 0);
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");
296 }
297
298 TEST_F(DBStoreTest, GetUserQueryByUserID) {
299 int ret = -1;
300 RGWUserInfo uinfo;
301 map<std::string, bufferlist> attrs;
302 RGWObjVersionTracker objv;
303
304 uinfo.user_id.tenant = "tenant";
305 uinfo.user_id.id = "user_id2";
306
307 ret = db->get_user(dpp, "user_id", "", uinfo, &attrs, &objv);
308 ASSERT_EQ(ret, 0);
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");
316 RGWAccessKey k;
317 map<string, RGWAccessKey>::iterator it = uinfo.access_keys.begin();
318 k = it->second;
319 ASSERT_EQ(k.id, "id1");
320 ASSERT_EQ(k.key, "key1");
321 it++;
322 k = it->second;
323 ASSERT_EQ(k.id, "id2");
324 ASSERT_EQ(k.key, "key2");
325
326 ASSERT_EQ(objv.read_version.ver, 2);
327
328 bufferlist k1, k2;
329 string attr;
330 map<std::string, bufferlist>::iterator it2 = attrs.begin();
331 k1 = it2->second;
332 decode(attr, k1);
333 ASSERT_EQ(attr, "attrs1");
334 it2++;
335 k2 = it2->second;
336 decode(attr, k2);
337 ASSERT_EQ(attr, "attrs2");
338 }
339
340 TEST_F(DBStoreTest, ListAllUsers) {
341 struct DBOpParams params = GlobalParams;
342 int ret = -1;
343
344 ret = db->ListAllUsers(dpp, &params);
345 ASSERT_EQ(ret, 0);
346 }
347
348 TEST_F(DBStoreTest, InsertBucket) {
349 struct DBOpParams params = GlobalParams;
350 int ret = -1;
351
352 params.op.bucket.info.bucket.name = "bucket1";
353 params.op.bucket.info.bucket.tenant = "tenant";
354 params.op.bucket.info.bucket.marker = "marker1";
355
356 params.op.bucket.ent.size = 1024;
357
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";
361
362 params.op.bucket.mtime = bucket_mtime;
363
364 ret = db->ProcessOp(dpp, "InsertBucket", &params);
365 ASSERT_EQ(ret, 0);
366 }
367
368 TEST_F(DBStoreTest, UpdateBucketAttrs) {
369 int ret = -1;
370 RGWBucketInfo info;
371 map<std::string, bufferlist> attrs;
372 RGWObjVersionTracker objv;
373
374 bufferlist aclbl, aclbl2;
375 encode("attrs1", aclbl);
376 attrs["attr1"] = aclbl;
377 encode("attrs2", aclbl2);
378 attrs["attr2"] = aclbl2;
379
380 info.bucket.name = "bucket1";
381
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 */
386
387 /* right version number */
388 objv.read_version.ver = 1;
389 ret = db->update_bucket(dpp, "attrs", info, false, nullptr, &attrs, &bucket_mtime, &objv);
390 ASSERT_EQ(ret, 0);
391 ASSERT_EQ(objv.read_version.ver, 2);
392 }
393
394 TEST_F(DBStoreTest, BucketChown) {
395 int ret = -1;
396 RGWBucketInfo info;
397 rgw_user user;
398 user.id = "user_id2";
399
400 info.bucket.name = "bucket1";
401
402 ret = db->update_bucket(dpp, "owner", info, false, &user, nullptr, &bucket_mtime, nullptr);
403 ASSERT_EQ(ret, 0);
404 ASSERT_EQ(info.objv_tracker.read_version.ver, 3);
405 }
406
407 TEST_F(DBStoreTest, UpdateBucketInfo) {
408 struct DBOpParams params = GlobalParams;
409 int ret = -1;
410 RGWBucketInfo info;
411
412 params.op.bucket.info.bucket.name = "bucket1";
413
414 ret = db->ProcessOp(dpp, "GetBucket", &params);
415 ASSERT_EQ(ret, 0);
416
417 info = params.op.bucket.info;
418
419 info.bucket.marker = "marker2";
420 ret = db->update_bucket(dpp, "info", info, false, nullptr, nullptr, &bucket_mtime, nullptr);
421 ASSERT_EQ(ret, 0);
422 ASSERT_EQ(info.objv_tracker.read_version.ver, 4);
423 }
424
425 TEST_F(DBStoreTest, GetBucket) {
426 struct DBOpParams params = GlobalParams;
427 int ret = -1;
428
429 ret = db->ProcessOp(dpp, "GetBucket", &params);
430 ASSERT_EQ(ret, 0);
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");
442 bufferlist k, k2;
443 string acl;
444 map<std::string, bufferlist>::iterator it2 = params.op.bucket.bucket_attrs.begin();
445 k = it2->second;
446 decode(acl, k);
447 ASSERT_EQ(acl, "attrs1");
448 it2++;
449 k2 = it2->second;
450 decode(acl, k2);
451 ASSERT_EQ(acl, "attrs2");
452 }
453
454 TEST_F(DBStoreTest, RemoveBucketAPI) {
455 int ret = -1;
456 RGWBucketInfo info;
457
458 info.bucket.name = "bucket1";
459
460 ret = db->remove_bucket(dpp, info);
461 ASSERT_EQ(ret, 0);
462 }
463
464 TEST_F(DBStoreTest, RemoveUserAPI) {
465 int ret = -1;
466 RGWUserInfo uinfo;
467 RGWObjVersionTracker objv;
468
469 uinfo.user_id.tenant = "tenant";
470 uinfo.user_id.id = "user_id2";
471
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);
476
477 /* invalid version number...should fail */
478 objv.read_version.ver = 2;
479 ret = db->remove_user(dpp, uinfo, &objv);
480 ASSERT_EQ(ret, 0);
481 }
482
483 TEST_F(DBStoreTest, CreateBucket) {
484 struct DBOpParams params = GlobalParams;
485 int ret = -1;
486 RGWBucketInfo info;
487 RGWUserInfo owner;
488 rgw_bucket bucket;
489 obj_version objv;
490 rgw_placement_rule rule;
491 map<std::string, bufferlist> attrs;
492
493 owner.user_id.id = "user_id1";
494 bucket.name = "bucket1";
495 bucket.tenant = "tenant";
496
497 objv.ver = 2;
498 objv.tag = "write_tag";
499
500 rule.name = "rule1";
501 rule.storage_class = "sc1";
502
503 ret = db->create_bucket(dpp, owner, bucket, "zid", rule, "swift_ver", NULL,
504 attrs, info, &objv, NULL, bucket_mtime, NULL, NULL,
505 null_yield, false);
506 ASSERT_EQ(ret, 0);
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,
510 null_yield, false);
511 ASSERT_EQ(ret, 0);
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,
515 null_yield, false);
516 ASSERT_EQ(ret, 0);
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,
520 null_yield, false);
521 ASSERT_EQ(ret, 0);
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,
525 null_yield, false);
526 ASSERT_EQ(ret, 0);
527 }
528
529 TEST_F(DBStoreTest, GetBucketQueryByName) {
530 int ret = -1;
531 RGWBucketInfo binfo;
532 binfo.bucket.name = "bucket2";
533 rgw::sal::Attrs attrs;
534 ceph::real_time mtime;
535 obj_version objv;
536
537 ret = db->get_bucket_info(dpp, "name", "", binfo, &attrs, &mtime, &objv);
538 ASSERT_EQ(ret, 0);
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");
550
551 marker1 = binfo.bucket.marker;
552 }
553
554 TEST_F(DBStoreTest, ListUserBuckets) {
555 struct DBOpParams params = GlobalParams;
556 int ret = -1;
557 rgw_user owner;
558 int max = 2;
559 bool need_stats = true;
560 bool is_truncated = false;
561 RGWUserBuckets ulist;
562
563 owner.id = "user_id1";
564
565 marker1 = "";
566 do {
567 is_truncated = false;
568 ret = db->list_buckets(dpp, owner, marker1, "", max, need_stats, &ulist, &is_truncated);
569 ASSERT_EQ(ret, 0);
570
571 cout << "marker1 :" << marker1 << "\n";
572
573 cout << "is_truncated :" << is_truncated << "\n";
574
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";
583
584 marker1 = e.bucket.name;
585 }
586 ulist.clear();
587 } while(is_truncated);
588 }
589
590 TEST_F(DBStoreTest, ListAllBuckets) {
591 struct DBOpParams params = GlobalParams;
592 int ret = -1;
593
594 ret = db->ListAllBuckets(dpp, &params);
595 ASSERT_EQ(ret, 0);
596 }
597
598 TEST_F(DBStoreTest, PutObject) {
599 struct DBOpParams params = GlobalParams;
600 int ret = -1;
601
602 params.op.obj.category = RGWObjCategory::Main;
603 params.op.obj.storage_class = "STANDARD";
604 bufferlist b1;
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", &params);
611 ASSERT_EQ(ret, 0);
612
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", &params);
617 ASSERT_EQ(ret, 0);
618
619 params.op.obj.state.obj.key.name = "object3";
620 params.op.obj.state.obj.key.instance = "inst3";
621 ret = db->ProcessOp(dpp, "PutObject", &params);
622 ASSERT_EQ(ret, 0);
623 }
624
625 TEST_F(DBStoreTest, ListAllObjects) {
626 struct DBOpParams params = GlobalParams;
627 int ret = -1;
628
629 ret = db->ListAllObjects(dpp, &params);
630 ASSERT_GE(ret, 0);
631 }
632
633 TEST_F(DBStoreTest, GetObject) {
634 struct DBOpParams params = GlobalParams;
635 int ret = -1;
636
637 ret = db->ProcessOp(dpp, "GetObject", &params);
638 ASSERT_EQ(ret, 0);
639 ASSERT_EQ(params.op.obj.category, RGWObjCategory::Main);
640 ASSERT_EQ(params.op.obj.storage_class, "STANDARD");
641 string data;
642 decode(data, params.op.obj.head_data);
643 ASSERT_EQ(data, "HELLO WORLD");
644 ASSERT_EQ(params.op.obj.state.size, 12);
645 }
646
647 TEST_F(DBStoreTest, GetObjectState) {
648 struct DBOpParams params = GlobalParams;
649 int ret = -1;
650 RGWObjState state;
651 RGWObjState *s = &state;
652
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);
657
658 ret = op_target.get_obj_state(dpp, params.op.bucket.info, params.op.obj.state.obj,
659 false, &s);
660 ASSERT_EQ(ret, 0);
661 ASSERT_EQ(state.size, 12);
662 ASSERT_EQ(state.is_olh, false);
663
664 /* Recheck with get_state API */
665 ret = op_target.get_state(dpp, &s, false);
666 ASSERT_EQ(ret, 0);
667 ASSERT_EQ(state.size, 12);
668 ASSERT_EQ(state.is_olh, false);
669 }
670
671 TEST_F(DBStoreTest, ObjAttrs) {
672 struct DBOpParams params = GlobalParams;
673 int ret = -1;
674 map<string, bufferlist> setattrs;
675 map<string, bufferlist> rmattrs;
676 map<string, bufferlist> readattrs;
677
678 bufferlist b1, b2, b3;
679 encode("ACL", b1);
680 setattrs[RGW_ATTR_ACL] = b1;
681 encode("LC", b2);
682 setattrs[RGW_ATTR_LC] = b2;
683 encode("ETAG", b3);
684 setattrs[RGW_ATTR_ETAG] = b3;
685
686 DB::Object op_target(db, params.op.bucket.info,
687 params.op.obj.state.obj);
688
689 /* Set some attrs */
690 ret = op_target.set_attrs(dpp, setattrs, nullptr);
691 ASSERT_EQ(ret, 0);
692
693 /* read those attrs */
694 DB::Object::Read read_op(&op_target);
695 read_op.params.attrs = &readattrs;
696 ret = read_op.prepare(dpp);
697 ASSERT_EQ(ret, 0);
698
699 string val;
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");
706
707 /* Remove some attrs */
708 rmattrs[RGW_ATTR_ACL] = b1;
709 map<string, bufferlist> empty;
710 ret = op_target.set_attrs(dpp, empty, &rmattrs);
711 ASSERT_EQ(ret, 0);
712
713 /* read those attrs */
714 ret = read_op.prepare(dpp);
715 ASSERT_EQ(ret, 0);
716
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");
722 }
723
724 TEST_F(DBStoreTest, WriteObject) {
725 struct DBOpParams params = GlobalParams;
726 int ret = -1;
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);
734 ASSERT_EQ(ret, 0);
735
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;
739
740 bufferlist b1;
741 encode("HELLO WORLD - Object3", b1);
742 cout<<"XXXXXXXXX Insert b1.length " << b1.length() << "\n";
743 write_op.meta.data = &b1;
744
745 bufferlist b2;
746 encode("ACL", b2);
747 setattrs[RGW_ATTR_ACL] = b2;
748
749 ret = write_op.write_meta(0, 22, 25, setattrs);
750 ASSERT_EQ(ret, 0);
751 }
752
753 TEST_F(DBStoreTest, ReadObject) {
754 struct DBOpParams params = GlobalParams;
755 int ret = -1;
756 map<string, bufferlist> readattrs;
757 params.op.obj.state.obj.key.name = "object3";
758 params.op.obj.state.obj.key.instance = "inst3";
759 uint64_t obj_size;
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);
766 ASSERT_EQ(ret, 0);
767
768 bufferlist bl;
769 ret = read_op.read(0, 25, bl, dpp);
770 cout<<"XXXXXXXXX Insert bl.length " << bl.length() << "\n";
771 ASSERT_EQ(ret, 25);
772
773 string data;
774 decode(data, bl);
775 ASSERT_EQ(data, "HELLO WORLD - Object3");
776 ASSERT_EQ(obj_size, 22);
777 }
778
779 TEST_F(DBStoreTest, IterateObject) {
780 struct DBOpParams params = GlobalParams;
781 int ret = -1;
782 map<string, bufferlist> readattrs;
783 uint64_t obj_size;
784 DBGetDataCB cb;
785
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);
792 ASSERT_EQ(ret, 0);
793
794 bufferlist bl;
795 ret = read_op.iterate(dpp, 0, 15, &cb);
796 ASSERT_EQ(ret, 0);
797 string data;
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);
803 }
804
805 TEST_F(DBStoreTest, ListBucketObjects) {
806 struct DBOpParams params = GlobalParams;
807 int ret = -1;
808
809 int max = 2;
810 bool is_truncated = false;
811 rgw_obj_key marker1;
812 DB::Bucket target(db, params.op.bucket.info);
813 DB::Bucket::List list_op(&target);
814
815 vector<rgw_bucket_dir_entry> dir_list;
816
817 marker1.name = "";
818 do {
819 is_truncated = false;
820 list_op.params.marker = marker1;
821 ret = list_op.list_objects(dpp, max, &dir_list, nullptr, &is_truncated);
822 ASSERT_EQ(ret, 0);
823
824 cout << "marker1 :" << marker1.name << "\n";
825
826 cout << "is_truncated :" << is_truncated << "\n";
827
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";
833
834 marker1 = list_op.get_next_marker();
835 }
836 dir_list.clear();
837 } while(is_truncated);
838 }
839
840 TEST_F(DBStoreTest, DeleteObj) {
841 struct DBOpParams params = GlobalParams;
842 int ret = -1;
843 RGWObjState state;
844 RGWObjState *s = &state;
845
846 /* delete object2 */
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);
851
852 DB::Object::Delete delete_op(&op_target);
853 ret = delete_op.delete_obj(dpp);
854 ASSERT_EQ(ret, 0);
855
856 /* Should return ENOENT */
857 ret = op_target.get_state(dpp, &s, false);
858 ASSERT_EQ(ret, -2);
859 }
860
861 TEST_F(DBStoreTest, ObjectOmapSetVal) {
862 struct DBOpParams params = GlobalParams;
863 int ret = -1;
864
865 DB::Object op_target(db, params.op.bucket.info,
866 params.op.obj.state.obj);
867
868 string val = "part1_val";
869 bufferlist bl;
870 encode(val, bl);
871 ret = op_target.obj_omap_set_val_by_key(dpp, "part1", bl, false);
872 ASSERT_EQ(ret, 0);
873
874 val = "part2_val";
875 bl.clear();
876 encode(val, bl);
877 ret = op_target.obj_omap_set_val_by_key(dpp, "part2", bl, false);
878 ASSERT_EQ(ret, 0);
879
880 val = "part3_val";
881 bl.clear();
882 encode(val, bl);
883 ret = op_target.obj_omap_set_val_by_key(dpp, "part3", bl, false);
884 ASSERT_EQ(ret, 0);
885
886 val = "part4_val";
887 bl.clear();
888 encode(val, bl);
889 ret = op_target.obj_omap_set_val_by_key(dpp, "part4", bl, false);
890 ASSERT_EQ(ret, 0);
891 }
892
893 TEST_F(DBStoreTest, ObjectOmapGetValsByKeys) {
894 struct DBOpParams params = GlobalParams;
895 int ret = -1;
896 std::set<std::string> keys;
897 std::map<std::string, bufferlist> vals;
898
899 DB::Object op_target(db, params.op.bucket.info,
900 params.op.obj.state.obj);
901
902 keys.insert("part2");
903 keys.insert("part4");
904
905 ret = op_target.obj_omap_get_vals_by_keys(dpp, "", keys, &vals);
906 ASSERT_EQ(ret, 0);
907 ASSERT_EQ(vals.size(), 2);
908
909 string val;
910 decode(val, vals["part2"]);
911 ASSERT_EQ(val, "part2_val");
912 decode(val, vals["part4"]);
913 ASSERT_EQ(val, "part4_val");
914 }
915
916 TEST_F(DBStoreTest, ObjectOmapGetAll) {
917 struct DBOpParams params = GlobalParams;
918 int ret = -1;
919 std::map<std::string, bufferlist> vals;
920
921 DB::Object op_target(db, params.op.bucket.info,
922 params.op.obj.state.obj);
923
924 ret = op_target.obj_omap_get_all(dpp, &vals);
925 ASSERT_EQ(ret, 0);
926 ASSERT_EQ(vals.size(), 4);
927
928 string val;
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");
937 }
938
939 TEST_F(DBStoreTest, ObjectOmapGetVals) {
940 struct DBOpParams params = GlobalParams;
941 int ret = -1;
942 std::set<std::string> keys;
943 std::map<std::string, bufferlist> vals;
944 bool pmore;
945
946 DB::Object op_target(db, params.op.bucket.info,
947 params.op.obj.state.obj);
948
949 ret = op_target.obj_omap_get_vals(dpp, "part3", 10, &vals, &pmore);
950 ASSERT_EQ(ret, 0);
951 ASSERT_EQ(vals.size(), 2);
952
953 string val;
954 decode(val, vals["part3"]);
955 ASSERT_EQ(val, "part3_val");
956 decode(val, vals["part4"]);
957 ASSERT_EQ(val, "part4_val");
958 }
959
960 TEST_F(DBStoreTest, PutObjectData) {
961 struct DBOpParams params = GlobalParams;
962 int ret = -1;
963
964 params.op.obj_data.part_num = 1;
965 params.op.obj_data.offset = 10;
966 params.op.obj_data.multipart_part_str = "2";
967 bufferlist b1;
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", &params);
972 ASSERT_EQ(ret, 0);
973 }
974
975 TEST_F(DBStoreTest, UpdateObjectData) {
976 struct DBOpParams params = GlobalParams;
977 int ret = -1;
978
979 params.op.obj.new_obj_key.name = "object3";
980 params.op.obj.new_obj_key.instance = "inst3";
981 ret = db->ProcessOp(dpp, "UpdateObjectData", &params);
982 ASSERT_EQ(ret, 0);
983 }
984
985 TEST_F(DBStoreTest, GetObjectData) {
986 struct DBOpParams params = GlobalParams;
987 int ret = -1;
988
989 params.op.obj.state.obj.key.instance = "inst3";
990 params.op.obj.state.obj.key.name = "object3";
991 ret = db->ProcessOp(dpp, "GetObjectData", &params);
992 ASSERT_EQ(ret, 0);
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");
998 string data;
999 decode(data, params.op.obj_data.data);
1000 ASSERT_EQ(data, "HELLO WORLD");
1001 }
1002
1003 TEST_F(DBStoreTest, DeleteObjectData) {
1004 struct DBOpParams params = GlobalParams;
1005 int ret = -1;
1006
1007 ret = db->ProcessOp(dpp, "DeleteObjectData", &params);
1008 ASSERT_EQ(ret, 0);
1009 }
1010
1011 TEST_F(DBStoreTest, DeleteObject) {
1012 struct DBOpParams params = GlobalParams;
1013 int ret = -1;
1014
1015 ret = db->ProcessOp(dpp, "DeleteObject", &params);
1016 ASSERT_EQ(ret, 0);
1017 }
1018
1019 TEST_F(DBStoreTest, LCTables) {
1020 struct DBOpParams params = GlobalParams;
1021 int ret = -1;
1022
1023 ret = db->createLCTables(dpp);
1024 ASSERT_GE(ret, 0);
1025 }
1026
1027 TEST_F(DBStoreTest, LCHead) {
1028 struct DBOpParams params = GlobalParams;
1029 int ret = -1;
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]};
1038
1039 ret = db->put_head(index1, head1);
1040 ASSERT_EQ(ret, 0);
1041 ret = db->put_head(index2, head2);
1042 ASSERT_EQ(ret, 0);
1043
1044 ret = db->get_head(index1, head);
1045 ASSERT_EQ(ret, 0);
1046 ASSERT_EQ(head.marker, "entry1");
1047
1048 ret = db->get_head(index2, head);
1049 ASSERT_EQ(ret, 0);
1050 ASSERT_EQ(head.marker, "entry2");
1051
1052 // update index1
1053 ret = db->put_head(index1, head3);
1054 ASSERT_EQ(ret, 0);
1055 ret = db->get_head(index1, head);
1056 ASSERT_EQ(ret, 0);
1057 ASSERT_EQ(head.marker, "entry3");
1058
1059 }
1060 TEST_F(DBStoreTest, LCEntry) {
1061 struct DBOpParams params = GlobalParams;
1062 int ret = -1;
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};
1073
1074 vector<rgw::sal::Lifecycle::LCEntry> lc_entries;
1075
1076 ret = db->set_entry(index1, entry1);
1077 ASSERT_EQ(ret, 0);
1078 ret = db->set_entry(index1, entry2);
1079 ASSERT_EQ(ret, 0);
1080 ret = db->set_entry(index1, entry3);
1081 ASSERT_EQ(ret, 0);
1082 ret = db->set_entry(index2, entry4);
1083 ASSERT_EQ(ret, 0);
1084
1085 // get entry index1, entry1
1086 ret = db->get_entry(index1, ents[0], entry);
1087 ASSERT_EQ(ret, 0);
1088 ASSERT_EQ(entry.status, lc_uninitial);
1089 ASSERT_EQ(entry.start_time, lc_time);
1090
1091 // get next entry index1, entry2
1092 ret = db->get_next_entry(index1, ents[1], entry);
1093 ASSERT_EQ(ret, 0);
1094 ASSERT_EQ(entry.bucket, ents[2]);
1095 ASSERT_EQ(entry.status, lc_uninitial);
1096 ASSERT_EQ(entry.start_time, lc_time);
1097
1098 // update entry4 to entry5
1099 entry4.status = lc_complete;
1100 ret = db->set_entry(index2, entry4);
1101 ASSERT_EQ(ret, 0);
1102 ret = db->get_entry(index2, ents[3], entry);
1103 ASSERT_EQ(ret, 0);
1104 ASSERT_EQ(entry.status, lc_complete);
1105
1106 // list entries
1107 ret = db->list_entries(index1, "", 5, lc_entries);
1108 ASSERT_EQ(ret, 0);
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";
1113 }
1114
1115 // remove index1, entry3
1116 ret = db->rm_entry(index1, entry3);
1117 ASSERT_EQ(ret, 0);
1118
1119 // get next entry index1, entry2.. should be null
1120 entry = {};
1121 ret = db->get_next_entry(index1, ents[1], entry);
1122 ASSERT_EQ(ret, 0);
1123 ASSERT_EQ(entry.start_time, 0);
1124 }
1125
1126 TEST_F(DBStoreTest, RemoveBucket) {
1127 struct DBOpParams params = GlobalParams;
1128 int ret = -1;
1129
1130 ret = db->ProcessOp(dpp, "RemoveBucket", &params);
1131 ASSERT_EQ(ret, 0);
1132 }
1133
1134 TEST_F(DBStoreTest, RemoveUser) {
1135 struct DBOpParams params = GlobalParams;
1136 int ret = -1;
1137
1138 ret = db->ProcessOp(dpp, "RemoveUser", &params);
1139 ASSERT_EQ(ret, 0);
1140 }
1141
1142 TEST_F(DBStoreTest, InsertTestIDUser) {
1143 struct DBOpParams params = GlobalParams;
1144 int ret = -1;
1145
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";
1154
1155 ret = db->ProcessOp(dpp, "InsertUser", &params);
1156 ASSERT_EQ(ret, 0);
1157 }
1158
1159 int main(int argc, char **argv)
1160 {
1161 int ret = -1;
1162 string c_logfile = "rgw_dbstore_tests.log";
1163 int c_loglevel = 20;
1164
1165 // format: ./dbstore-tests logfile loglevel
1166 if (argc == 3) {
1167 c_logfile = argv[1];
1168 c_loglevel = (atoi)(argv[2]);
1169 cout << "logfile:" << c_logfile << ", loglevel set to " << c_loglevel << "\n";
1170 }
1171
1172 ::testing::InitGoogleTest(&argc, argv);
1173
1174 gtest::env = new gtest::Environment();
1175 gtest::env->logfile = c_logfile;
1176 gtest::env->loglevel = c_loglevel;
1177 ::testing::AddGlobalTestEnvironment(gtest::env);
1178
1179 ret = RUN_ALL_TESTS();
1180
1181 return ret;
1182 }