1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
25 #include <curl/curl.h>
27 #include "common/ceph_crypto.h"
28 #include "include/str_list.h"
29 #include "common/ceph_json.h"
30 #include "common/code_environment.h"
31 #include "common/ceph_argparse.h"
32 #include "common/Finisher.h"
33 #include "global/global_init.h"
34 #include "rgw_common.h"
35 #include "rgw_rados.h"
36 #include <gtest/gtest.h>
40 #define CURL_VERBOSE 0
41 #define HTTP_RESPONSE_STR "RespCode"
42 #define CEPH_CRYPTO_HMACSHA1_DIGESTSIZE 20
43 #define RGW_ADMIN_RESP_PATH "/tmp/.test_rgw_admin_resp"
44 #define CEPH_UID "ceph"
46 static string uid
= CEPH_UID
;
47 static string display_name
= "CEPH";
48 static string meta_caps
= "metadata";
50 extern "C" int ceph_armor(char *dst
, const char *dst_end
,
51 const char *src
, const char *end
);
52 static void print_usage(char *exec
){
53 cout
<< "Usage: " << exec
<< " <Options>\n";
55 "-g <gw-ip> - The ip address of the gateway\n"
56 "-p <gw-port> - The port number of the gateway\n"
57 "-c <ceph.conf> - Absolute path of ceph config file\n"
58 "-rgw-admin <path/to/radosgw-admin> - radosgw-admin absolute path\n";
61 namespace admin_meta
{
67 string rgw_admin_path
;
70 map
<string
, string
> response
;
71 list
<string
> extra_hdrs
;
75 test_helper() : curl_inst(0), resp_data(NULL
), resp_code(0) {
76 curl_global_init(CURL_GLOBAL_ALL
);
79 curl_global_cleanup();
81 int send_request(string method
, string uri
,
82 size_t (*function
)(void *,size_t,size_t,void *) = 0,
83 void *ud
= 0, size_t length
= 0);
84 int extract_input(int argc
, char *argv
[]);
85 string
& get_response(string hdr
){
88 void set_extra_header(string hdr
){
89 extra_hdrs
.push_back(hdr
);
91 void set_response(char *val
);
92 void set_response_data(char *data
, size_t len
){
93 if(resp_data
) delete resp_data
;
94 resp_data
= new string(data
, len
);
96 string
& get_rgw_admin_path() {
97 return rgw_admin_path
;
99 string
& get_ceph_conf_path() {
102 void set_creds(string
& c
) {
105 const string
*get_response_data(){return resp_data
;}
106 unsigned get_resp_code(){return resp_code
;}
109 int test_helper::extract_input(int argc
, char *argv
[]){
110 #define ERR_CHECK_NEXT_PARAM(o) \
111 if(((int)loop + 1) >= argc)return -1; \
112 else o = argv[loop+1];
114 for(unsigned loop
= 1;loop
< (unsigned)argc
; loop
+= 2){
115 if(strcmp(argv
[loop
], "-g") == 0){
116 ERR_CHECK_NEXT_PARAM(host
);
117 }else if(strcmp(argv
[loop
],"-p") == 0){
118 ERR_CHECK_NEXT_PARAM(port
);
119 }else if(strcmp(argv
[loop
], "-c") == 0){
120 ERR_CHECK_NEXT_PARAM(conf_path
);
121 }else if(strcmp(argv
[loop
], "-rgw-admin") == 0){
122 ERR_CHECK_NEXT_PARAM(rgw_admin_path
);
125 if(host
.empty() || rgw_admin_path
.empty())
130 void test_helper::set_response(char *r
){
132 size_t off
= sr
.find(": ");
133 if(off
!= string::npos
){
134 h
.assign(sr
, 0, off
);
135 v
.assign(sr
, off
+ 2, sr
.find("\r\n") - (off
+2));
137 /*Could be the status code*/
138 if(sr
.find("HTTP/") != string::npos
){
139 h
.assign(HTTP_RESPONSE_STR
);
141 v
.assign(sr
, off
+ 1, sr
.find("\r\n") - (off
+ 1));
142 resp_code
= atoi((v
.substr(0, 3)).c_str());
148 size_t write_header(void *ptr
, size_t size
, size_t nmemb
, void *ud
){
149 test_helper
*h
= static_cast<test_helper
*>(ud
);
150 h
->set_response((char *)ptr
);
154 size_t write_data(void *ptr
, size_t size
, size_t nmemb
, void *ud
){
155 test_helper
*h
= static_cast<test_helper
*>(ud
);
156 h
->set_response_data((char *)ptr
, size
*nmemb
);
160 static inline void buf_to_hex(const unsigned char *buf
, int len
, char *str
)
164 for (i
= 0; i
< len
; i
++) {
165 sprintf(&str
[i
*2], "%02x", (int)buf
[i
]);
169 static void calc_hmac_sha1(const char *key
, int key_len
,
170 const char *msg
, int msg_len
, char *dest
)
171 /* destination should be CEPH_CRYPTO_HMACSHA1_DIGESTSIZE bytes long */
173 ceph::crypto::HMACSHA1
hmac((const unsigned char *)key
, key_len
);
174 hmac
.Update((const unsigned char *)msg
, msg_len
);
175 hmac
.Final((unsigned char *)dest
);
177 char hex_str
[(CEPH_CRYPTO_HMACSHA1_DIGESTSIZE
* 2) + 1];
178 admin_meta::buf_to_hex((unsigned char *)dest
, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE
, hex_str
);
181 static int get_s3_auth(const string
&method
, string creds
, const string
&date
, string res
, string
& out
){
182 string aid
, secret
, auth_hdr
;
184 size_t off
= creds
.find(":");
186 if(off
!= string::npos
){
187 aid
.assign(creds
, 0, off
);
188 secret
.assign(creds
, off
+ 1, string::npos
);
190 /*sprintf(auth_hdr, "%s\n\n\n%s\n%s", req_type, date, res);*/
191 char hmac_sha1
[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE
];
192 char b64
[65]; /* 64 is really enough */
193 size_t off
= res
.find("?");
194 if(off
== string::npos
)
197 tmp_res
.assign(res
, 0, off
);
198 auth_hdr
.append(method
+ string("\n\n\n") + date
+ string("\n") + tmp_res
);
199 admin_meta::calc_hmac_sha1(secret
.c_str(), secret
.length(),
200 auth_hdr
.c_str(), auth_hdr
.length(), hmac_sha1
);
201 int ret
= ceph_armor(b64
, b64
+ 64, hmac_sha1
,
202 hmac_sha1
+ CEPH_CRYPTO_HMACSHA1_DIGESTSIZE
);
204 cout
<< "ceph_armor failed\n";
208 out
.append(aid
+ string(":") + b64
);
213 void get_date(string
& d
){
217 char *days
[] = {(char *)"Sun", (char *)"Mon", (char *)"Tue",
218 (char *)"Wed", (char *)"Thu", (char *)"Fri",
220 char *months
[] = {(char *)"Jan", (char *)"Feb", (char *)"Mar",
221 (char *)"Apr", (char *)"May", (char *)"Jun",
222 (char *)"Jul",(char *) "Aug", (char *)"Sep",
223 (char *)"Oct", (char *)"Nov", (char *)"Dec"};
224 gettimeofday(&tv
, NULL
);
225 gmtime_r(&tv
.tv_sec
, &tm
);
226 sprintf(date
, "%s, %d %s %d %d:%d:%d GMT",
228 tm
.tm_mday
, months
[tm
.tm_mon
],
230 tm
.tm_hour
, tm
.tm_min
, 0 /*tm.tm_sec*/);
234 int test_helper::send_request(string method
, string res
,
235 size_t (*read_function
)( void *,size_t,size_t,void *),
240 url
.append(string("http://") + host
);
241 if(port
.length() > 0)url
.append(string(":") + port
);
243 curl_inst
= curl_easy_init();
245 curl_easy_setopt(curl_inst
, CURLOPT_URL
, url
.c_str());
246 curl_easy_setopt(curl_inst
, CURLOPT_CUSTOMREQUEST
, method
.c_str());
247 curl_easy_setopt(curl_inst
, CURLOPT_VERBOSE
, CURL_VERBOSE
);
248 curl_easy_setopt(curl_inst
, CURLOPT_HEADERFUNCTION
, admin_meta::write_header
);
249 curl_easy_setopt(curl_inst
, CURLOPT_WRITEHEADER
, (void *)this);
250 curl_easy_setopt(curl_inst
, CURLOPT_WRITEFUNCTION
, admin_meta::write_data
);
251 curl_easy_setopt(curl_inst
, CURLOPT_WRITEDATA
, (void *)this);
253 curl_easy_setopt(curl_inst
, CURLOPT_READFUNCTION
, read_function
);
254 curl_easy_setopt(curl_inst
, CURLOPT_READDATA
, (void *)ud
);
255 curl_easy_setopt(curl_inst
, CURLOPT_UPLOAD
, 1L);
256 curl_easy_setopt(curl_inst
, CURLOPT_INFILESIZE_LARGE
, (curl_off_t
)length
);
261 http_date
.append(string("Date: ") + date
);
264 if (admin_meta::get_s3_auth(method
, creds
, date
, res
, s3auth
) < 0)
266 auth
.append(string("Authorization: AWS ") + s3auth
);
268 struct curl_slist
*slist
= NULL
;
269 slist
= curl_slist_append(slist
, auth
.c_str());
270 slist
= curl_slist_append(slist
, http_date
.c_str());
271 for(list
<string
>::iterator it
= extra_hdrs
.begin();
272 it
!= extra_hdrs
.end(); ++it
){
273 slist
= curl_slist_append(slist
, (*it
).c_str());
276 curl_slist_append(slist
, "Expect:");
277 curl_easy_setopt(curl_inst
, CURLOPT_HTTPHEADER
, slist
);
279 response
.erase(response
.begin(), response
.end());
280 extra_hdrs
.erase(extra_hdrs
.begin(), extra_hdrs
.end());
281 CURLcode res
= curl_easy_perform(curl_inst
);
283 cout
<< "Curl perform failed for " << url
<< ", res: " <<
284 curl_easy_strerror(res
) << "\n";
287 curl_slist_free_all(slist
);
289 curl_easy_cleanup(curl_inst
);
294 admin_meta::test_helper
*g_test
;
297 int run_rgw_admin(string
& cmd
, string
& resp
) {
303 get_str_list(cmd
, " \t", l
);
304 char *argv
[l
.size()];
307 argv
[0] = (char *)"radosgw-admin";
308 for (list
<string
>::iterator it
= l
.begin();
309 it
!= l
.end(); ++it
) {
310 argv
[loop
++] = (char *)(*it
).c_str();
313 if (!freopen(RGW_ADMIN_RESP_PATH
, "w+", stdout
)) {
314 cout
<< "Unable to open stdout file" << std::endl
;
316 execv((g_test
->get_rgw_admin_path()).c_str(), argv
);
317 } else if (pid
> 0) {
319 waitpid(pid
, &status
, 0);
320 if (WIFEXITED(status
)) {
321 if(WEXITSTATUS(status
) != 0) {
322 cout
<< "Child exited with status " << WEXITSTATUS(status
) << std::endl
;
329 if (stat(RGW_ADMIN_RESP_PATH
, &st
) < 0) {
330 cout
<< "Error stating the admin response file, errno " << errno
<< std::endl
;
333 char *data
= (char *)malloc(st
.st_size
+ 1);
334 in
.open(RGW_ADMIN_RESP_PATH
);
335 in
.read(data
, st
.st_size
);
337 data
[st
.st_size
] = 0;
340 unlink(RGW_ADMIN_RESP_PATH
);
341 /* cout << "radosgw-admin " << cmd << ": " << resp << std::endl;*/
348 int get_creds(string
& json
, string
& creds
) {
350 if(!parser
.parse(json
.c_str(), json
.length())) {
351 cout
<< "Error parsing create user response" << std::endl
;
356 decode_json_obj(info
, &parser
);
358 for(map
<string
, RGWAccessKey
>::iterator it
= info
.access_keys
.begin();
359 it
!= info
.access_keys
.end(); ++it
) {
360 RGWAccessKey _k
= it
->second
;
361 /*cout << "accesskeys [ " << it->first << " ] = " <<
362 "{ " << _k.id << ", " << _k.key << ", " << _k.subuser << "}" << std::endl;*/
363 creds
.append(it
->first
+ string(":") + _k
.key
);
369 int user_create(string
& uid
, string
& display_name
, bool set_creds
= true) {
372 ss
<< "-c " << g_test
->get_ceph_conf_path() << " user create --uid=" << uid
373 << " --display-name=" << display_name
;
376 string cmd
= ss
.str();
377 if(run_rgw_admin(cmd
, out
) != 0) {
378 cout
<< "Error creating user" << std::endl
;
381 get_creds(out
, creds
);
383 g_test
->set_creds(creds
);
387 int user_info(string
& uid
, string
& display_name
, RGWUserInfo
& uinfo
) {
389 ss
<< "-c " << g_test
->get_ceph_conf_path() << " user info --uid=" << uid
390 << " --display-name=" << display_name
;
393 string cmd
= ss
.str();
394 if(run_rgw_admin(cmd
, out
) != 0) {
395 cout
<< "Error reading user information" << std::endl
;
399 if(!parser
.parse(out
.c_str(), out
.length())) {
400 cout
<< "Error parsing create user response" << std::endl
;
403 decode_json_obj(uinfo
, &parser
);
407 int user_rm(string
& uid
, string
& display_name
) {
409 ss
<< "-c " << g_test
->get_ceph_conf_path() << " user rm --uid=" << uid
410 << " --display-name=" << display_name
;
413 string cmd
= ss
.str();
414 if(run_rgw_admin(cmd
, out
) != 0) {
415 cout
<< "Error removing user" << std::endl
;
421 int meta_caps_add(const char *perm
) {
424 ss
<< "-c " << g_test
->get_ceph_conf_path() << " caps add --caps=" <<
425 meta_caps
<< "=" << perm
<< " --uid=" << uid
;
427 string cmd
= ss
.str();
428 if(run_rgw_admin(cmd
, out
) != 0) {
429 cout
<< "Error creating user" << std::endl
;
435 int meta_caps_rm(const char *perm
) {
438 ss
<< "-c " << g_test
->get_ceph_conf_path() << " caps rm --caps=" <<
439 meta_caps
<< "=" << perm
<< " --uid=" << uid
;
441 string cmd
= ss
.str();
442 if(run_rgw_admin(cmd
, out
) != 0) {
443 cout
<< "Error creating user" << std::endl
;
449 int compare_access_keys(RGWAccessKey
& k1
, RGWAccessKey
& k2
) {
450 if (k1
.id
.compare(k2
.id
) != 0)
452 if (k1
.key
.compare(k2
.key
) != 0)
454 if (k1
.subuser
.compare(k2
.subuser
) != 0)
460 int compare_user_info(RGWUserInfo
& i1
, RGWUserInfo
& i2
) {
463 if ((rv
= i1
.user_id
.compare(i2
.user_id
)) != 0)
465 if ((rv
= i1
.display_name
.compare(i2
.display_name
)) != 0)
467 if ((rv
= i1
.user_email
.compare(i2
.user_email
)) != 0)
469 if (i1
.access_keys
.size() != i2
.access_keys
.size())
471 for (map
<string
, RGWAccessKey
>::iterator it
= i1
.access_keys
.begin();
472 it
!= i1
.access_keys
.end(); ++it
) {
475 if (i2
.access_keys
.count(it
->first
) == 0)
477 k2
= i2
.access_keys
[it
->first
];
478 if (compare_access_keys(k1
, k2
) != 0)
481 if (i1
.swift_keys
.size() != i2
.swift_keys
.size())
483 for (map
<string
, RGWAccessKey
>::iterator it
= i1
.swift_keys
.begin();
484 it
!= i1
.swift_keys
.end(); ++it
) {
487 if (i2
.swift_keys
.count(it
->first
) == 0)
489 k2
= i2
.swift_keys
[it
->first
];
490 if (compare_access_keys(k1
, k2
) != 0)
493 if (i1
.subusers
.size() != i2
.subusers
.size())
495 for (map
<string
, RGWSubUser
>::iterator it
= i1
.subusers
.begin();
496 it
!= i1
.subusers
.end(); ++it
) {
499 if (!i2
.subusers
.count(it
->first
))
501 k2
= i2
.subusers
[it
->first
];
502 if (k1
.name
.compare(k2
.name
) != 0)
504 if (k1
.perm_mask
!= k2
.perm_mask
)
507 if (i1
.suspended
!= i2
.suspended
)
509 if (i1
.max_buckets
!= i2
.max_buckets
)
512 p1
= p2
= RGW_CAP_ALL
;
513 if (i1
.caps
.check_cap(meta_caps
, p1
) != 0)
515 if (i2
.caps
.check_cap(meta_caps
, p2
) != 0)
520 size_t read_dummy_post(void *ptr
, size_t s
, size_t n
, void *ud
) {
522 memcpy(ptr
, &dummy
, sizeof(dummy
));
523 return sizeof(dummy
);
527 int parse_json_resp(JSONParser
&parser
) {
529 resp
= (string
*)g_test
->get_response_data();
532 if(!parser
.parse(resp
->c_str(), resp
->length())) {
533 cout
<< "Error parsing create user response" << std::endl
;
539 size_t meta_read_json(void *ptr
, size_t s
, size_t n
, void *ud
){
540 stringstream
*ss
= (stringstream
*)ud
;
541 size_t len
= ss
->str().length();
543 cout
<< "Cannot copy json data, as len is not enough\n";
546 memcpy(ptr
, (void *)ss
->str().c_str(), len
);
550 TEST(TestRGWAdmin
, meta_list
){
553 const char *perm
= "*";
555 ASSERT_EQ(0, user_create(uid
, display_name
));
556 ASSERT_EQ(0, meta_caps_add(perm
));
558 /*Check the sections*/
559 g_test
->send_request(string("GET"), string("/admin/metadata/"));
560 EXPECT_EQ(200U, g_test
->get_resp_code());
562 ASSERT_TRUE(parse_json_resp(parser
) == 0);
563 EXPECT_TRUE(parser
.is_array());
566 l
= parser
.get_array_elements();
567 for(vector
<string
>::iterator it
= l
.begin();
568 it
!= l
.end(); ++it
) {
569 if((*it
).compare("\"user\"") == 0) {
576 /*Check with a wrong section*/
577 g_test
->send_request(string("GET"), string("/admin/metadata/users"));
578 EXPECT_EQ(404U, g_test
->get_resp_code());
580 /*Check the list of keys*/
581 g_test
->send_request(string("GET"), string("/admin/metadata/user"));
582 EXPECT_EQ(200U, g_test
->get_resp_code());
584 ASSERT_TRUE(parse_json_resp(parser
) == 0);
585 EXPECT_TRUE(parser
.is_array());
587 l
= parser
.get_array_elements();
588 EXPECT_EQ(1U, l
.size());
589 for(vector
<string
>::iterator it
= l
.begin();
590 it
!= l
.end(); ++it
) {
591 if((*it
).compare(string("\"") + uid
+ string("\"")) == 0) {
598 /*Check with second user*/
599 string uid2
= "ceph1", display_name2
= "CEPH1";
600 ASSERT_EQ(0, user_create(uid2
, display_name2
, false));
601 /*Check the list of keys*/
602 g_test
->send_request(string("GET"), string("/admin/metadata/user"));
603 EXPECT_EQ(200U, g_test
->get_resp_code());
605 ASSERT_TRUE(parse_json_resp(parser
) == 0);
606 EXPECT_TRUE(parser
.is_array());
608 l
= parser
.get_array_elements();
609 EXPECT_EQ(2U, l
.size());
611 for(vector
<string
>::iterator it
= l
.begin();
612 it
!= l
.end(); ++it
) {
613 if((*it
).compare(string("\"") + uid
+ string("\"")) == 0) {
616 if((*it
).compare(string("\"") + uid2
+ string("\"")) == 0) {
620 EXPECT_TRUE(found
&& found2
);
621 ASSERT_EQ(0, user_rm(uid2
, display_name2
));
623 /*Remove the metadata caps*/
624 int rv
= meta_caps_rm(perm
);
628 g_test
->send_request(string("GET"), string("/admin/metadata/"));
629 EXPECT_EQ(403U, g_test
->get_resp_code());
631 g_test
->send_request(string("GET"), string("/admin/metadata/user"));
632 EXPECT_EQ(403U, g_test
->get_resp_code());
634 ASSERT_EQ(0, user_rm(uid
, display_name
));
637 TEST(TestRGWAdmin
, meta_get
){
639 const char *perm
= "*";
642 ASSERT_EQ(0, user_create(uid
, display_name
));
643 ASSERT_EQ(0, meta_caps_add(perm
));
645 ASSERT_EQ(0, user_info(uid
, display_name
, info
));
647 g_test
->send_request(string("GET"), string("/admin/metadata/user?key=test"));
648 EXPECT_EQ(404U, g_test
->get_resp_code());
650 g_test
->send_request(string("GET"), (string("/admin/metadata/user?key=") + uid
));
651 EXPECT_EQ(200U, g_test
->get_resp_code());
653 ASSERT_TRUE(parse_json_resp(parser
) == 0);
654 RGWObjVersionTracker objv_tracker
;
657 obj_version
*objv
= &objv_tracker
.read_version
;
659 JSONDecoder::decode_json("key", metadata_key
, &parser
);
660 JSONDecoder::decode_json("ver", *objv
, &parser
);
661 JSONObj
*jo
= parser
.find_obj("data");
663 string exp_meta_key
= "user:";
664 exp_meta_key
.append(uid
);
665 EXPECT_TRUE(metadata_key
.compare(exp_meta_key
) == 0);
667 RGWUserInfo obt_info
;
668 decode_json_obj(obt_info
, jo
);
670 EXPECT_TRUE(compare_user_info(info
, obt_info
) == 0);
672 /*Make a modification and check if its reflected*/
673 ASSERT_EQ(0, meta_caps_rm(perm
));
675 ASSERT_EQ(0, meta_caps_add(perm
));
678 g_test
->send_request(string("GET"), (string("/admin/metadata/user?key=") + uid
));
679 EXPECT_EQ(200U, g_test
->get_resp_code());
681 ASSERT_TRUE(parse_json_resp(parser1
) == 0);
683 RGWObjVersionTracker objv_tracker1
;
684 obj_version
*objv1
= &objv_tracker1
.read_version
;
686 JSONDecoder::decode_json("key", metadata_key
, &parser1
);
687 JSONDecoder::decode_json("ver", *objv1
, &parser1
);
688 jo
= parser1
.find_obj("data");
691 decode_json_obj(obt_info
, jo
);
695 EXPECT_TRUE (info
.caps
.check_cap(meta_caps
, p1
) == 0);
696 EXPECT_TRUE (obt_info
.caps
.check_cap(meta_caps
, p2
) == 0);
698 EXPECT_TRUE (obt_info
.caps
.check_cap(meta_caps
, p2
) != 0);
700 /*Version and tag infromation*/
701 EXPECT_TRUE(objv1
->ver
> objv
->ver
);
702 EXPECT_EQ(objv1
->tag
, objv
->tag
);
704 int rv
= meta_caps_rm(perm
);
708 g_test
->send_request(string("GET"), (string("/admin/metadata/user?key=") + uid
));
709 EXPECT_EQ(403U, g_test
->get_resp_code());
711 ASSERT_EQ(0, user_rm(uid
, display_name
));
714 TEST(TestRGWAdmin
, meta_put
){
716 const char *perm
= "*";
719 ASSERT_EQ(0, user_create(uid
, display_name
));
720 ASSERT_EQ(0, meta_caps_add(perm
));
722 g_test
->send_request(string("GET"), (string("/admin/metadata/user?key=") + uid
));
723 EXPECT_EQ(200U, g_test
->get_resp_code());
725 ASSERT_TRUE(parse_json_resp(parser
) == 0);
726 RGWObjVersionTracker objv_tracker
;
729 obj_version
*objv
= &objv_tracker
.read_version
;
731 JSONDecoder::decode_json("key", metadata_key
, &parser
);
732 JSONDecoder::decode_json("ver", *objv
, &parser
);
733 JSONObj
*jo
= parser
.find_obj("data");
735 string exp_meta_key
= "user:";
736 exp_meta_key
.append(uid
);
737 EXPECT_TRUE(metadata_key
.compare(exp_meta_key
) == 0);
739 RGWUserInfo obt_info
;
740 decode_json_obj(obt_info
, jo
);
742 /*Change the cap and PUT */
745 Formatter
*f
= new JSONFormatter();
747 new_cap
= meta_caps
+ string("=write");
748 caps
.add_from_string(new_cap
);
749 obt_info
.caps
= caps
;
750 f
->open_object_section("metadata_info");
751 ::encode_json("key", metadata_key
, f
);
752 ::encode_json("ver", *objv
, f
);
753 ::encode_json("data", obt_info
, f
);
755 std::stringstream ss
;
758 g_test
->send_request(string("PUT"), (string("/admin/metadata/user?key=") + uid
),
760 (void *)&ss
, ss
.str().length());
761 EXPECT_EQ(200U, g_test
->get_resp_code());
763 ASSERT_EQ(0, user_info(uid
, display_name
, obt_info
));
766 EXPECT_TRUE (obt_info
.caps
.check_cap(meta_caps
, cp
) == 0);
768 EXPECT_TRUE (obt_info
.caps
.check_cap(meta_caps
, cp
) != 0);
770 int rv
= meta_caps_rm("write");
773 g_test
->send_request(string("PUT"), (string("/admin/metadata/user?key=") + uid
));
774 EXPECT_EQ(403U, g_test
->get_resp_code());
776 ASSERT_EQ(0, user_rm(uid
, display_name
));
779 TEST(TestRGWAdmin
, meta_lock_unlock
) {
780 const char *perm
= "*";
783 ASSERT_EQ(0, user_create(uid
, display_name
));
784 ASSERT_EQ(0, meta_caps_add(perm
));
786 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&lock&length=3";
787 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
788 EXPECT_EQ(400U, g_test
->get_resp_code()); /*Bad request*/
790 rest_req
= "/admin/metadata/user?lock&length=3&lock_id=ceph";
791 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
792 EXPECT_EQ(400U, g_test
->get_resp_code()); /*Bad request*/
794 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&unlock";
795 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
796 EXPECT_EQ(400U, g_test
->get_resp_code()); /*Bad request*/
798 rest_req
= "/admin/metadata/user?unlock&lock_id=ceph";
799 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
800 EXPECT_EQ(400U, g_test
->get_resp_code()); /*Bad request*/
802 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&lock&length=3&lock_id=ceph";
803 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
804 EXPECT_EQ(200U, g_test
->get_resp_code());
806 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&unlock&lock_id=ceph";
807 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
808 EXPECT_EQ(200U, g_test
->get_resp_code());
810 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&lock&length=3&lock_id=ceph1";
811 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
812 EXPECT_EQ(200U, g_test
->get_resp_code());
814 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&unlock&lock_id=ceph1";
815 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
816 EXPECT_EQ(200U, g_test
->get_resp_code());
818 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&lock&length=3&lock_id=ceph";
819 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
820 EXPECT_EQ(200U, g_test
->get_resp_code());
821 utime_t
sleep_time(3, 0);
823 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&lock&length=3&lock_id=ceph1";
824 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
825 EXPECT_EQ(500U, g_test
->get_resp_code());
827 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&lock&length=3&lock_id=ceph";
828 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
829 EXPECT_EQ(409U, g_test
->get_resp_code());
832 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&lock&length=3&lock_id=ceph1";
833 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
834 EXPECT_EQ(200U, g_test
->get_resp_code());
836 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&unlock&lock_id=ceph1";
837 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
838 EXPECT_EQ(200U, g_test
->get_resp_code());
840 ASSERT_EQ(0, meta_caps_rm(perm
));
842 ASSERT_EQ(0, meta_caps_add(perm
));
843 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&lock&length=3&lock_id=ceph";
844 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
845 EXPECT_EQ(403U, g_test
->get_resp_code());
847 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&unlock&lock_id=ceph";
848 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
849 EXPECT_EQ(403U, g_test
->get_resp_code());
851 ASSERT_EQ(0, meta_caps_rm(perm
));
853 ASSERT_EQ(0, meta_caps_add(perm
));
854 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&lock&length=3&lock_id=ceph";
855 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
856 EXPECT_EQ(200U, g_test
->get_resp_code());
858 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&unlock&lock_id=ceph";
859 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
860 EXPECT_EQ(200U, g_test
->get_resp_code());
862 ASSERT_EQ(0, meta_caps_rm(perm
));
863 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&lock&length=3&lock_id=ceph";
864 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
865 EXPECT_EQ(403U, g_test
->get_resp_code());
867 rest_req
= "/admin/metadata/user?key=" CEPH_UID
"&unlock&lock_id=ceph";
868 g_test
->send_request(string("POST"), rest_req
, read_dummy_post
, NULL
, sizeof(int));
869 EXPECT_EQ(403U, g_test
->get_resp_code());
871 ASSERT_EQ(0, user_rm(uid
, display_name
));
874 TEST(TestRGWAdmin
, meta_delete
){
876 const char *perm
= "*";
879 ASSERT_EQ(0, user_create(uid
, display_name
));
880 ASSERT_EQ(0, meta_caps_add(perm
));
882 g_test
->send_request(string("DELETE"), (string("/admin/metadata/user?key=") + uid
));
883 EXPECT_EQ(200U, g_test
->get_resp_code());
885 ASSERT_TRUE(user_info(uid
, display_name
, info
) != 0);
887 ASSERT_EQ(0, user_create(uid
, display_name
));
889 ASSERT_EQ(0, meta_caps_add(perm
));
891 g_test
->send_request(string("DELETE"), (string("/admin/metadata/user?key=") + uid
));
892 EXPECT_EQ(403U, g_test
->get_resp_code());
893 ASSERT_EQ(0, user_rm(uid
, display_name
));
896 int main(int argc
, char *argv
[]){
897 auto args
= argv_to_vec(argc
, argv
);
899 auto cct
= global_init(NULL
, args
, CEPH_ENTITY_TYPE_CLIENT
,
900 CODE_ENVIRONMENT_UTILITY
,
901 CINIT_FLAG_NO_DEFAULT_CONFIG_FILE
);
902 common_init_finish(g_ceph_context
);
903 g_test
= new admin_meta::test_helper();
904 finisher
= new Finisher(g_ceph_context
);
906 ::testing::InitGoogleTest(&argc
, argv
);
910 if(g_test
->extract_input(argc
, argv
) < 0){
911 print_usage(argv
[0]);
915 int r
= RUN_ALL_TESTS();
917 cout
<< "There are no failures in the test case\n";
919 cout
<< "There are some failures\n";