]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- |
2 | // vim: ts=8 sw=2 smarttab | |
3 | /* | |
4 | * Ceph - scalable distributed file system | |
5 | * | |
6 | * Copyright (C) 2013 eNovance SAS <licensing@enovance.com> | |
7 | * | |
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. | |
12 | * | |
13 | */ | |
14 | #include <iostream> | |
15 | #include <stdio.h> | |
16 | #include <stdlib.h> | |
17 | #include <string.h> | |
18 | #include <errno.h> | |
19 | #include <time.h> | |
20 | #include <sys/wait.h> | |
21 | #include <unistd.h> | |
22 | #include <fstream> | |
23 | #include <map> | |
24 | #include <list> | |
25 | extern "C"{ | |
26 | #include <curl/curl.h> | |
27 | } | |
28 | #include "common/ceph_crypto.h" | |
29 | #include "include/str_list.h" | |
30 | #include "common/ceph_json.h" | |
31 | #include "common/code_environment.h" | |
32 | #include "common/ceph_argparse.h" | |
33 | #include "common/Finisher.h" | |
34 | #include "global/global_init.h" | |
35 | #include "rgw/rgw_common.h" | |
f67539c2 | 36 | #include "rgw/rgw_datalog.h" |
9f95a23c | 37 | #include "rgw/rgw_mdlog.h" |
7c673cae FG |
38 | #include "rgw/rgw_bucket.h" |
39 | #include "rgw/rgw_rados.h" | |
40 | #include "include/utime.h" | |
41 | #include "include/object.h" | |
7c673cae | 42 | #include <gtest/gtest.h> |
9f95a23c | 43 | |
7c673cae FG |
44 | using namespace std; |
45 | ||
46 | #define CURL_VERBOSE 0 | |
47 | #define HTTP_RESPONSE_STR "RespCode" | |
48 | #define CEPH_CRYPTO_HMACSHA1_DIGESTSIZE 20 | |
49 | #define RGW_ADMIN_RESP_PATH "/tmp/.test_rgw_admin_resp" | |
50 | #define TEST_BUCKET_NAME "test_bucket" | |
51 | #define TEST_BUCKET_OBJECT "test_object" | |
52 | #define TEST_BUCKET_OBJECT_1 "test_object1" | |
53 | #define TEST_BUCKET_OBJECT_SIZE 1024 | |
54 | ||
55 | static string uid = "ceph"; | |
56 | static string display_name = "CEPH"; | |
57 | ||
58 | extern "C" int ceph_armor(char *dst, const char *dst_end, | |
59 | const char *src, const char *end); | |
60 | static void print_usage(char *exec){ | |
61 | cout << "Usage: " << exec << " <Options>\n"; | |
62 | cout << "Options:\n" | |
63 | "-g <gw-ip> - The ip address of the gateway\n" | |
64 | "-p <gw-port> - The port number of the gateway\n" | |
65 | "-c <ceph.conf> - Absolute path of ceph config file\n" | |
66 | "-rgw-admin <path/to/radosgw-admin> - radosgw-admin absolute path\n"; | |
67 | } | |
68 | ||
69 | namespace admin_log { | |
70 | class test_helper { | |
71 | private: | |
72 | string host; | |
73 | string port; | |
74 | string creds; | |
75 | string rgw_admin_path; | |
76 | string conf_path; | |
77 | CURL *curl_inst; | |
78 | map<string, string> response; | |
79 | list<string> extra_hdrs; | |
80 | string *resp_data; | |
81 | unsigned resp_code; | |
82 | public: | |
83 | test_helper() : resp_data(NULL){ | |
84 | curl_global_init(CURL_GLOBAL_ALL); | |
85 | } | |
86 | ~test_helper(){ | |
87 | curl_global_cleanup(); | |
88 | } | |
89 | int send_request(string method, string uri, | |
90 | size_t (*function)(void *,size_t,size_t,void *) = 0, | |
91 | void *ud = 0, size_t length = 0); | |
92 | int extract_input(int argc, char *argv[]); | |
93 | string& get_response(string hdr){ | |
94 | return response[hdr]; | |
95 | } | |
96 | void set_extra_header(string hdr){ | |
97 | extra_hdrs.push_back(hdr); | |
98 | } | |
99 | void set_response(char *val); | |
100 | void set_response_data(char *data, size_t len){ | |
101 | if(resp_data) delete resp_data; | |
102 | resp_data = new string(data, len); | |
103 | } | |
104 | string& get_rgw_admin_path() { | |
105 | return rgw_admin_path; | |
106 | } | |
107 | string& get_ceph_conf_path() { | |
108 | return conf_path; | |
109 | } | |
110 | void set_creds(string& c) { | |
111 | creds = c; | |
112 | } | |
113 | const string *get_response_data(){return resp_data;} | |
114 | unsigned get_resp_code(){return resp_code;} | |
115 | }; | |
116 | ||
117 | int test_helper::extract_input(int argc, char *argv[]){ | |
118 | #define ERR_CHECK_NEXT_PARAM(o) \ | |
119 | if(((int)loop + 1) >= argc)return -1; \ | |
120 | else o = argv[loop+1]; | |
121 | ||
122 | for(unsigned loop = 1;loop < (unsigned)argc; loop += 2){ | |
123 | if(strcmp(argv[loop], "-g") == 0){ | |
124 | ERR_CHECK_NEXT_PARAM(host); | |
125 | }else if(strcmp(argv[loop],"-p") == 0){ | |
126 | ERR_CHECK_NEXT_PARAM(port); | |
127 | }else if(strcmp(argv[loop], "-c") == 0){ | |
128 | ERR_CHECK_NEXT_PARAM(conf_path); | |
129 | }else if(strcmp(argv[loop], "-rgw-admin") == 0){ | |
130 | ERR_CHECK_NEXT_PARAM(rgw_admin_path); | |
131 | }else return -1; | |
132 | } | |
11fdf7f2 | 133 | if(!host.length() || !rgw_admin_path.length()) |
7c673cae FG |
134 | return -1; |
135 | return 0; | |
136 | } | |
137 | ||
138 | void test_helper::set_response(char *r){ | |
139 | string sr(r), h, v; | |
140 | size_t off = sr.find(": "); | |
141 | if(off != string::npos){ | |
142 | h.assign(sr, 0, off); | |
143 | v.assign(sr, off + 2, sr.find("\r\n") - (off+2)); | |
144 | }else{ | |
145 | /*Could be the status code*/ | |
146 | if(sr.find("HTTP/") != string::npos){ | |
147 | h.assign(HTTP_RESPONSE_STR); | |
148 | off = sr.find(" "); | |
149 | v.assign(sr, off + 1, sr.find("\r\n") - (off + 1)); | |
150 | resp_code = atoi((v.substr(0, 3)).c_str()); | |
151 | } | |
152 | } | |
153 | response[h] = v; | |
154 | } | |
155 | ||
156 | size_t write_header(void *ptr, size_t size, size_t nmemb, void *ud){ | |
157 | test_helper *h = static_cast<test_helper *>(ud); | |
158 | h->set_response((char *)ptr); | |
159 | return size*nmemb; | |
160 | } | |
161 | ||
162 | size_t write_data(void *ptr, size_t size, size_t nmemb, void *ud){ | |
163 | test_helper *h = static_cast<test_helper *>(ud); | |
164 | h->set_response_data((char *)ptr, size*nmemb); | |
165 | return size*nmemb; | |
166 | } | |
167 | ||
168 | static inline void buf_to_hex(const unsigned char *buf, int len, char *str) | |
169 | { | |
170 | int i; | |
171 | str[0] = '\0'; | |
172 | for (i = 0; i < len; i++) { | |
173 | sprintf(&str[i*2], "%02x", (int)buf[i]); | |
174 | } | |
175 | } | |
176 | ||
177 | static void calc_hmac_sha1(const char *key, int key_len, | |
178 | const char *msg, int msg_len, char *dest) | |
179 | /* destination should be CEPH_CRYPTO_HMACSHA1_DIGESTSIZE bytes long */ | |
180 | { | |
181 | ceph::crypto::HMACSHA1 hmac((const unsigned char *)key, key_len); | |
182 | hmac.Update((const unsigned char *)msg, msg_len); | |
183 | hmac.Final((unsigned char *)dest); | |
184 | ||
185 | char hex_str[(CEPH_CRYPTO_HMACSHA1_DIGESTSIZE * 2) + 1]; | |
186 | admin_log::buf_to_hex((unsigned char *)dest, CEPH_CRYPTO_HMACSHA1_DIGESTSIZE, hex_str); | |
187 | } | |
188 | ||
11fdf7f2 | 189 | static int get_s3_auth(const string &method, string creds, const string &date, string res, string& out){ |
7c673cae FG |
190 | string aid, secret, auth_hdr; |
191 | string tmp_res; | |
192 | size_t off = creds.find(":"); | |
193 | out = ""; | |
194 | if(off != string::npos){ | |
195 | aid.assign(creds, 0, off); | |
196 | secret.assign(creds, off + 1, string::npos); | |
197 | ||
198 | /*sprintf(auth_hdr, "%s\n\n\n%s\n%s", req_type, date, res);*/ | |
199 | char hmac_sha1[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE]; | |
200 | char b64[65]; /* 64 is really enough */ | |
201 | size_t off = res.find("?"); | |
202 | if(off == string::npos) | |
203 | tmp_res = res; | |
204 | else | |
205 | tmp_res.assign(res, 0, off); | |
206 | auth_hdr.append(method + string("\n\n\n") + date + string("\n") + tmp_res); | |
207 | admin_log::calc_hmac_sha1(secret.c_str(), secret.length(), | |
208 | auth_hdr.c_str(), auth_hdr.length(), hmac_sha1); | |
209 | int ret = ceph_armor(b64, b64 + 64, hmac_sha1, | |
210 | hmac_sha1 + CEPH_CRYPTO_HMACSHA1_DIGESTSIZE); | |
211 | if (ret < 0) { | |
212 | cout << "ceph_armor failed\n"; | |
213 | return -1; | |
214 | } | |
215 | b64[ret] = 0; | |
216 | out.append(aid + string(":") + b64); | |
217 | }else return -1; | |
218 | return 0; | |
219 | } | |
220 | ||
221 | void get_date(string& d){ | |
222 | struct timeval tv; | |
223 | char date[64]; | |
224 | struct tm tm; | |
225 | char *days[] = {(char *)"Sun", (char *)"Mon", (char *)"Tue", | |
226 | (char *)"Wed", (char *)"Thu", (char *)"Fri", | |
227 | (char *)"Sat"}; | |
228 | char *months[] = {(char *)"Jan", (char *)"Feb", (char *)"Mar", | |
229 | (char *)"Apr", (char *)"May", (char *)"Jun", | |
230 | (char *)"Jul",(char *) "Aug", (char *)"Sep", | |
231 | (char *)"Oct", (char *)"Nov", (char *)"Dec"}; | |
232 | gettimeofday(&tv, NULL); | |
233 | gmtime_r(&tv.tv_sec, &tm); | |
234 | sprintf(date, "%s, %d %s %d %d:%d:%d GMT", | |
235 | days[tm.tm_wday], | |
236 | tm.tm_mday, months[tm.tm_mon], | |
237 | tm.tm_year + 1900, | |
238 | tm.tm_hour, tm.tm_min, tm.tm_sec); | |
239 | d = date; | |
240 | } | |
241 | ||
242 | int test_helper::send_request(string method, string res, | |
243 | size_t (*read_function)( void *,size_t,size_t,void *), | |
244 | void *ud, | |
245 | size_t length){ | |
246 | string url; | |
247 | string auth, date; | |
248 | url.append(string("http://") + host); | |
249 | if(port.length() > 0)url.append(string(":") + port); | |
250 | url.append(res); | |
251 | curl_inst = curl_easy_init(); | |
252 | if(curl_inst){ | |
253 | curl_easy_setopt(curl_inst, CURLOPT_URL, url.c_str()); | |
254 | curl_easy_setopt(curl_inst, CURLOPT_CUSTOMREQUEST, method.c_str()); | |
255 | curl_easy_setopt(curl_inst, CURLOPT_VERBOSE, CURL_VERBOSE); | |
256 | curl_easy_setopt(curl_inst, CURLOPT_HEADERFUNCTION, admin_log::write_header); | |
257 | curl_easy_setopt(curl_inst, CURLOPT_WRITEHEADER, (void *)this); | |
258 | curl_easy_setopt(curl_inst, CURLOPT_WRITEFUNCTION, admin_log::write_data); | |
259 | curl_easy_setopt(curl_inst, CURLOPT_WRITEDATA, (void *)this); | |
260 | if(read_function){ | |
261 | curl_easy_setopt(curl_inst, CURLOPT_READFUNCTION, read_function); | |
262 | curl_easy_setopt(curl_inst, CURLOPT_READDATA, (void *)ud); | |
263 | curl_easy_setopt(curl_inst, CURLOPT_UPLOAD, 1L); | |
264 | curl_easy_setopt(curl_inst, CURLOPT_INFILESIZE_LARGE, (curl_off_t)length); | |
265 | } | |
266 | ||
267 | get_date(date); | |
268 | string http_date; | |
269 | http_date.append(string("Date: ") + date); | |
270 | ||
271 | string s3auth; | |
272 | if (admin_log::get_s3_auth(method, creds, date, res, s3auth) < 0) | |
273 | return -1; | |
274 | auth.append(string("Authorization: AWS ") + s3auth); | |
275 | ||
276 | struct curl_slist *slist = NULL; | |
277 | slist = curl_slist_append(slist, auth.c_str()); | |
278 | slist = curl_slist_append(slist, http_date.c_str()); | |
279 | for(list<string>::iterator it = extra_hdrs.begin(); | |
280 | it != extra_hdrs.end(); ++it){ | |
281 | slist = curl_slist_append(slist, (*it).c_str()); | |
282 | } | |
283 | if(read_function) | |
284 | curl_slist_append(slist, "Expect:"); | |
285 | curl_easy_setopt(curl_inst, CURLOPT_HTTPHEADER, slist); | |
286 | ||
287 | response.erase(response.begin(), response.end()); | |
288 | extra_hdrs.erase(extra_hdrs.begin(), extra_hdrs.end()); | |
289 | CURLcode res = curl_easy_perform(curl_inst); | |
290 | if(res != CURLE_OK){ | |
291 | cout << "Curl perform failed for " << url << ", res: " << | |
292 | curl_easy_strerror(res) << "\n"; | |
293 | return -1; | |
294 | } | |
295 | curl_slist_free_all(slist); | |
296 | } | |
297 | curl_easy_cleanup(curl_inst); | |
298 | return 0; | |
299 | } | |
300 | }; | |
301 | ||
302 | admin_log::test_helper *g_test; | |
303 | Finisher *finisher; | |
304 | ||
305 | int run_rgw_admin(string& cmd, string& resp) { | |
306 | pid_t pid; | |
307 | pid = fork(); | |
308 | if (pid == 0) { | |
309 | /* child */ | |
310 | list<string> l; | |
311 | get_str_list(cmd, " \t", l); | |
312 | char *argv[l.size()]; | |
313 | unsigned loop = 1; | |
314 | ||
315 | argv[0] = (char *)"radosgw-admin"; | |
316 | for (list<string>::iterator it = l.begin(); | |
317 | it != l.end(); ++it) { | |
318 | argv[loop++] = (char *)(*it).c_str(); | |
319 | } | |
320 | argv[loop] = NULL; | |
321 | if (!freopen(RGW_ADMIN_RESP_PATH, "w+", stdout)) { | |
322 | cout << "Unable to open stdout file" << std::endl; | |
323 | } | |
324 | execv((g_test->get_rgw_admin_path()).c_str(), argv); | |
325 | } else if (pid > 0) { | |
326 | int status; | |
327 | waitpid(pid, &status, 0); | |
328 | if (WIFEXITED(status)) { | |
329 | if(WEXITSTATUS(status) != 0) { | |
330 | cout << "Child exited with status " << WEXITSTATUS(status) << std::endl; | |
331 | return -1; | |
332 | } | |
333 | } | |
334 | ifstream in; | |
335 | struct stat st; | |
336 | ||
337 | if (stat(RGW_ADMIN_RESP_PATH, &st) < 0) { | |
338 | cout << "Error stating the admin response file, errno " << errno << std::endl; | |
339 | return -1; | |
340 | } else { | |
341 | char *data = (char *)malloc(st.st_size + 1); | |
342 | in.open(RGW_ADMIN_RESP_PATH); | |
343 | in.read(data, st.st_size); | |
344 | in.close(); | |
345 | data[st.st_size] = 0; | |
346 | resp = data; | |
347 | free(data); | |
348 | unlink(RGW_ADMIN_RESP_PATH); | |
349 | /* cout << "radosgw-admin " << cmd << ": " << resp << std::endl; */ | |
350 | } | |
351 | } else | |
352 | return -1; | |
353 | return 0; | |
354 | } | |
355 | ||
356 | int get_creds(string& json, string& creds) { | |
357 | JSONParser parser; | |
358 | if(!parser.parse(json.c_str(), json.length())) { | |
359 | cout << "Error parsing create user response" << std::endl; | |
360 | return -1; | |
361 | } | |
362 | ||
363 | RGWUserInfo info; | |
364 | decode_json_obj(info, &parser); | |
365 | creds = ""; | |
366 | for(map<string, RGWAccessKey>::iterator it = info.access_keys.begin(); | |
367 | it != info.access_keys.end(); ++it) { | |
368 | RGWAccessKey _k = it->second; | |
369 | /*cout << "accesskeys [ " << it->first << " ] = " << | |
370 | "{ " << _k.id << ", " << _k.key << ", " << _k.subuser << "}" << std::endl;*/ | |
371 | creds.append(it->first + string(":") + _k.key); | |
372 | break; | |
373 | } | |
374 | return 0; | |
375 | } | |
376 | ||
377 | int user_create(string& uid, string& display_name, bool set_creds = true) { | |
378 | stringstream ss; | |
379 | string creds; | |
380 | ss << "-c " << g_test->get_ceph_conf_path() << " user create --uid=" << uid | |
381 | << " --display-name=" << display_name; | |
382 | ||
383 | string out; | |
384 | string cmd = ss.str(); | |
385 | if(run_rgw_admin(cmd, out) != 0) { | |
386 | cout << "Error creating user" << std::endl; | |
387 | return -1; | |
388 | } | |
389 | get_creds(out, creds); | |
390 | if(set_creds) | |
391 | g_test->set_creds(creds); | |
392 | return 0; | |
393 | } | |
394 | ||
395 | int user_info(string& uid, string& display_name, RGWUserInfo& uinfo) { | |
396 | stringstream ss; | |
397 | ss << "-c " << g_test->get_ceph_conf_path() << " user info --uid=" << uid | |
398 | << " --display-name=" << display_name; | |
399 | ||
400 | string out; | |
401 | string cmd = ss.str(); | |
402 | if(run_rgw_admin(cmd, out) != 0) { | |
403 | cout << "Error reading user information" << std::endl; | |
404 | return -1; | |
405 | } | |
406 | JSONParser parser; | |
407 | if(!parser.parse(out.c_str(), out.length())) { | |
408 | cout << "Error parsing create user response" << std::endl; | |
409 | return -1; | |
410 | } | |
411 | decode_json_obj(uinfo, &parser); | |
412 | return 0; | |
413 | } | |
414 | ||
415 | int user_rm(string& uid, string& display_name) { | |
416 | stringstream ss; | |
417 | ss << "-c " << g_test->get_ceph_conf_path() << | |
418 | " metadata rm --metadata-key=user:" << uid; | |
419 | ||
420 | string out; | |
421 | string cmd = ss.str(); | |
422 | if(run_rgw_admin(cmd, out) != 0) { | |
423 | cout << "Error removing user" << std::endl; | |
424 | return -1; | |
425 | } | |
426 | return 0; | |
427 | } | |
428 | ||
429 | int caps_add(const char * name, const char *perm) { | |
430 | stringstream ss; | |
431 | ||
432 | ss << "-c " << g_test->get_ceph_conf_path() << " caps add --caps=" << | |
433 | name << "=" << perm << " --uid=" << uid; | |
434 | string out; | |
435 | string cmd = ss.str(); | |
436 | if(run_rgw_admin(cmd, out) != 0) { | |
437 | cout << "Error creating user" << std::endl; | |
438 | return -1; | |
439 | } | |
440 | return 0; | |
441 | } | |
442 | ||
443 | int caps_rm(const char * name, const char *perm) { | |
444 | stringstream ss; | |
445 | ||
446 | ss << "-c " << g_test->get_ceph_conf_path() << " caps rm --caps=" << | |
447 | name << "=" << perm << " --uid=" << uid; | |
448 | string out; | |
449 | string cmd = ss.str(); | |
450 | if(run_rgw_admin(cmd, out) != 0) { | |
451 | cout << "Error creating user" << std::endl; | |
452 | return -1; | |
453 | } | |
454 | return 0; | |
455 | } | |
456 | ||
457 | static int create_bucket(void){ | |
458 | g_test->send_request(string("PUT"), string("/" TEST_BUCKET_NAME)); | |
459 | if(g_test->get_resp_code() != 200U){ | |
460 | cout << "Error creating bucket, http code " << g_test->get_resp_code(); | |
461 | return -1; | |
462 | } | |
463 | return 0; | |
464 | } | |
465 | ||
466 | static int delete_bucket(void){ | |
467 | g_test->send_request(string("DELETE"), string("/" TEST_BUCKET_NAME)); | |
468 | if(g_test->get_resp_code() != 204U){ | |
469 | cout << "Error deleting bucket, http code " << g_test->get_resp_code(); | |
470 | return -1; | |
471 | } | |
472 | return 0; | |
473 | } | |
474 | ||
475 | size_t read_dummy_post(void *ptr, size_t s, size_t n, void *ud) { | |
476 | int dummy = 0; | |
477 | memcpy(ptr, &dummy, sizeof(dummy)); | |
478 | return sizeof(dummy); | |
479 | } | |
480 | ||
481 | size_t read_bucket_object(void *ptr, size_t s, size_t n, void *ud) { | |
482 | memcpy(ptr, ud, TEST_BUCKET_OBJECT_SIZE); | |
483 | return TEST_BUCKET_OBJECT_SIZE; | |
484 | } | |
485 | ||
486 | static int put_bucket_obj(const char *obj_name, char *data, unsigned len) { | |
487 | string req = "/" TEST_BUCKET_NAME"/"; | |
488 | req.append(obj_name); | |
489 | g_test->send_request(string("PUT"), req, | |
490 | read_bucket_object, (void *)data, (size_t)len); | |
491 | if (g_test->get_resp_code() != 200U) { | |
492 | cout << "Errror sending object to the bucket, http_code " << g_test->get_resp_code(); | |
493 | return -1; | |
494 | } | |
495 | return 0; | |
496 | } | |
497 | ||
498 | static int read_bucket_obj(const char *obj_name) { | |
499 | string req = "/" TEST_BUCKET_NAME"/"; | |
500 | req.append(obj_name); | |
501 | g_test->send_request(string("GET"), req); | |
502 | if (g_test->get_resp_code() != 200U) { | |
503 | cout << "Errror sending object to the bucket, http_code " << g_test->get_resp_code(); | |
504 | return -1; | |
505 | } | |
506 | return 0; | |
507 | } | |
508 | ||
509 | static int delete_obj(const char *obj_name) { | |
510 | string req = "/" TEST_BUCKET_NAME"/"; | |
511 | req.append(obj_name); | |
512 | g_test->send_request(string("DELETE"), req); | |
513 | if (g_test->get_resp_code() != 204U) { | |
514 | cout << "Errror deleting object from bucket, http_code " << g_test->get_resp_code(); | |
515 | return -1; | |
516 | } | |
517 | return 0; | |
518 | } | |
519 | ||
520 | int get_formatted_time(string& ret) { | |
521 | struct tm *tm = NULL; | |
522 | char str_time[200]; | |
523 | const char *format = "%Y-%m-%d%%20%H:%M:%S"; | |
524 | time_t t; | |
525 | ||
526 | t = time(NULL); | |
527 | tm = gmtime(&t); | |
528 | if(!tm) { | |
529 | cerr << "Error returned by gmtime\n"; | |
530 | return -1; | |
531 | } | |
532 | if (strftime(str_time, sizeof(str_time), format, tm) == 0) { | |
533 | cerr << "Error returned by strftime\n"; | |
534 | return -1; | |
535 | } | |
536 | ret = str_time; | |
537 | return 0; | |
538 | } | |
539 | ||
540 | int parse_json_resp(JSONParser &parser) { | |
541 | string *resp; | |
542 | resp = (string *)g_test->get_response_data(); | |
543 | if(!resp) | |
544 | return -1; | |
545 | if(!parser.parse(resp->c_str(), resp->length())) { | |
546 | cout << "Error parsing create user response" << std::endl; | |
547 | return -1; | |
548 | } | |
549 | return 0; | |
550 | } | |
551 | ||
552 | struct cls_log_entry_json { | |
553 | string section; | |
554 | string name; | |
555 | utime_t timestamp; | |
556 | RGWMetadataLogData log_data; | |
557 | }; | |
558 | ||
559 | static int decode_json(JSONObj *obj, RGWMetadataLogData &data) { | |
560 | JSONObj *jo; | |
561 | ||
562 | jo = obj->find_obj("read_version"); | |
563 | if (!jo) | |
564 | return -1; | |
565 | data.read_version.decode_json(obj); | |
566 | data.write_version.decode_json(obj); | |
567 | ||
568 | jo = obj->find_obj("status"); | |
569 | if (!jo) | |
570 | return -1; | |
571 | JSONDecoder::decode_json("status", data, jo); | |
572 | return 0; | |
573 | } | |
574 | ||
575 | static int decode_json(JSONObj *obj, cls_log_entry_json& ret) { | |
576 | JSONDecoder::decode_json("section", ret.section, obj); | |
577 | JSONDecoder::decode_json("name", ret.name, obj); | |
578 | JSONObj *jo = obj->find_obj("data"); | |
579 | if(!jo) | |
580 | return 0; | |
581 | return decode_json(jo, ret.log_data); | |
582 | } | |
583 | ||
584 | static int get_log_list(list<cls_log_entry_json> &entries) { | |
585 | JSONParser parser; | |
586 | if (parse_json_resp(parser) != 0) | |
587 | return -1; | |
588 | if (!parser.is_array()) | |
589 | return -1; | |
590 | ||
591 | vector<string> l; | |
592 | l = parser.get_array_elements(); | |
593 | int loop = 0; | |
594 | for(vector<string>::iterator it = l.begin(); | |
595 | it != l.end(); ++it, loop++) { | |
596 | JSONParser jp; | |
597 | cls_log_entry_json entry; | |
598 | ||
599 | if(!jp.parse((*it).c_str(), (*it).length())) { | |
600 | cerr << "Error parsing log json object" << std::endl; | |
601 | return -1; | |
602 | } | |
603 | EXPECT_EQ(decode_json((JSONObj *)&jp, entry), 0); | |
604 | entries.push_back(entry); | |
605 | } | |
606 | return 0; | |
607 | } | |
608 | ||
609 | struct cls_bilog_entry { | |
610 | string op_id; | |
611 | string op_tag; | |
612 | string op; | |
613 | string object; | |
614 | string status; | |
615 | unsigned index_ver; | |
616 | }; | |
617 | ||
618 | static int decode_json(JSONObj *obj, cls_bilog_entry& ret) { | |
619 | JSONDecoder::decode_json("op_id", ret.op_id, obj); | |
620 | JSONDecoder::decode_json("op_tag", ret.op_tag, obj); | |
621 | JSONDecoder::decode_json("op", ret.op, obj); | |
622 | JSONDecoder::decode_json("object", ret.object, obj); | |
623 | JSONDecoder::decode_json("state", ret.status, obj); | |
624 | JSONDecoder::decode_json("index_ver", ret.index_ver, obj); | |
625 | return 0; | |
626 | } | |
627 | ||
628 | static int get_bilog_list(list<cls_bilog_entry> &entries) { | |
629 | JSONParser parser; | |
630 | if (parse_json_resp(parser) != 0) | |
631 | return -1; | |
632 | if (!parser.is_array()) | |
633 | return -1; | |
634 | ||
635 | vector<string> l; | |
636 | l = parser.get_array_elements(); | |
637 | int loop = 0; | |
638 | for(vector<string>::iterator it = l.begin(); | |
639 | it != l.end(); ++it, loop++) { | |
640 | JSONParser jp; | |
641 | cls_bilog_entry entry; | |
642 | ||
643 | if(!jp.parse((*it).c_str(), (*it).length())) { | |
644 | cerr << "Error parsing log json object" << std::endl; | |
645 | return -1; | |
646 | } | |
647 | EXPECT_EQ(decode_json((JSONObj *)&jp, entry), 0); | |
648 | entries.push_back(entry); | |
649 | } | |
650 | return 0; | |
651 | } | |
652 | ||
653 | static int decode_json(JSONObj *obj, rgw_data_change& ret) { | |
654 | string entity; | |
655 | ||
656 | JSONDecoder::decode_json("entity_type", entity, obj); | |
657 | if (entity.compare("bucket") == 0) | |
658 | ret.entity_type = ENTITY_TYPE_BUCKET; | |
659 | JSONDecoder::decode_json("key", ret.key, obj); | |
660 | return 0; | |
661 | } | |
662 | ||
663 | static int get_datalog_list(list<rgw_data_change> &entries) { | |
664 | JSONParser parser; | |
665 | ||
666 | if (parse_json_resp(parser) != 0) | |
667 | return -1; | |
668 | if (!parser.is_array()) | |
669 | return -1; | |
670 | ||
671 | vector<string> l; | |
672 | l = parser.get_array_elements(); | |
673 | int loop = 0; | |
674 | for(vector<string>::iterator it = l.begin(); | |
675 | it != l.end(); ++it, loop++) { | |
676 | JSONParser jp; | |
677 | rgw_data_change entry; | |
678 | ||
679 | if(!jp.parse((*it).c_str(), (*it).length())) { | |
680 | cerr << "Error parsing log json object" << std::endl; | |
681 | return -1; | |
682 | } | |
683 | EXPECT_EQ(decode_json((JSONObj *)&jp, entry), 0); | |
684 | entries.push_back(entry); | |
685 | } | |
686 | return 0; | |
687 | } | |
688 | ||
689 | unsigned get_mdlog_shard_id(string& key, int max_shards) { | |
690 | string section = "user"; | |
691 | uint32_t val = ceph_str_hash_linux(key.c_str(), key.size()); | |
692 | val ^= ceph_str_hash_linux(section.c_str(), section.size()); | |
693 | return (unsigned)(val % max_shards); | |
694 | } | |
695 | ||
696 | unsigned get_datalog_shard_id(const char *bucket_name, int max_shards) { | |
697 | uint32_t r = ceph_str_hash_linux(bucket_name, strlen(bucket_name)) % max_shards; | |
698 | return (int)r; | |
699 | } | |
700 | ||
701 | TEST(TestRGWAdmin, datalog_list) { | |
702 | string start_time, | |
703 | end_time; | |
704 | const char *cname = "datalog", | |
705 | *perm = "*"; | |
706 | string rest_req; | |
707 | unsigned shard_id = get_datalog_shard_id(TEST_BUCKET_NAME, g_ceph_context->_conf->rgw_data_log_num_shards); | |
708 | stringstream ss; | |
709 | list<rgw_data_change> entries; | |
710 | ||
711 | ASSERT_EQ(get_formatted_time(start_time), 0); | |
712 | ASSERT_EQ(0, user_create(uid, display_name)); | |
713 | ASSERT_EQ(0, caps_add(cname, perm)); | |
714 | ||
715 | rest_req = "/admin/log?type=data"; | |
716 | g_test->send_request(string("GET"), rest_req); | |
717 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
718 | JSONParser parser; | |
719 | int num_objects; | |
720 | EXPECT_EQ (parse_json_resp(parser), 0); | |
721 | JSONDecoder::decode_json("num_objects", num_objects, (JSONObj *)&parser); | |
722 | ASSERT_EQ(num_objects,g_ceph_context->_conf->rgw_data_log_num_shards); | |
723 | ||
724 | sleep(1); | |
725 | ASSERT_EQ(0, create_bucket()); | |
726 | ||
727 | char *bucket_obj = (char *)calloc(1, TEST_BUCKET_OBJECT_SIZE); | |
728 | ASSERT_TRUE(bucket_obj != NULL); | |
729 | EXPECT_EQ(put_bucket_obj(TEST_BUCKET_OBJECT, bucket_obj, TEST_BUCKET_OBJECT_SIZE), 0); | |
730 | sleep(1); | |
731 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time; | |
732 | rest_req = ss.str(); | |
733 | g_test->send_request(string("GET"), rest_req); | |
734 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
735 | entries.clear(); | |
736 | get_datalog_list(entries); | |
737 | EXPECT_EQ(1U, entries.size()); | |
738 | if (entries.size() == 1) { | |
739 | rgw_data_change entry = *(entries.begin()); | |
740 | EXPECT_EQ(entry.entity_type, ENTITY_TYPE_BUCKET); | |
741 | EXPECT_EQ(entry.key.compare(TEST_BUCKET_NAME), 0); | |
742 | } | |
743 | ASSERT_EQ(0, delete_obj(TEST_BUCKET_OBJECT)); | |
744 | sleep(1); | |
745 | ASSERT_EQ(get_formatted_time(end_time), 0); | |
746 | ss.str(""); | |
747 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time; | |
748 | rest_req = ss.str(); | |
749 | g_test->send_request(string("GET"), rest_req); | |
750 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
751 | entries.clear(); | |
752 | get_datalog_list(entries); | |
753 | EXPECT_EQ(1U, entries.size()); | |
754 | if (entries.size() == 1) { | |
755 | list<rgw_data_change>::iterator it = (entries.begin()); | |
756 | EXPECT_EQ((*it).entity_type, ENTITY_TYPE_BUCKET); | |
757 | EXPECT_EQ((*it).key.compare(TEST_BUCKET_NAME), 0); | |
758 | } | |
759 | ||
760 | sleep(1); | |
761 | EXPECT_EQ(put_bucket_obj(TEST_BUCKET_OBJECT, bucket_obj, TEST_BUCKET_OBJECT_SIZE), 0); | |
762 | free(bucket_obj); | |
763 | sleep(20); | |
764 | ss.str(""); | |
765 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time; | |
766 | rest_req = ss.str(); | |
767 | g_test->send_request(string("GET"), rest_req); | |
768 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
769 | entries.clear(); | |
770 | get_datalog_list(entries); | |
771 | EXPECT_EQ(2U, entries.size()); | |
772 | if (entries.size() == 2) { | |
773 | list<rgw_data_change>::iterator it = (entries.begin()); | |
774 | EXPECT_EQ((*it).entity_type, ENTITY_TYPE_BUCKET); | |
775 | EXPECT_EQ((*it).key.compare(TEST_BUCKET_NAME), 0); | |
776 | ++it; | |
777 | EXPECT_EQ((*it).entity_type, ENTITY_TYPE_BUCKET); | |
778 | EXPECT_EQ((*it).key.compare(TEST_BUCKET_NAME), 0); | |
779 | } | |
780 | ||
781 | ss.str(""); | |
782 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time | |
783 | << "&max-entries=1"; | |
784 | rest_req = ss.str(); | |
785 | g_test->send_request(string("GET"), rest_req); | |
786 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
787 | entries.clear(); | |
788 | get_datalog_list(entries); | |
789 | EXPECT_EQ(1U, entries.size()); | |
790 | ||
791 | ss.str(""); | |
792 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time | |
793 | << "&end-time=" << end_time; | |
794 | rest_req = ss.str(); | |
795 | g_test->send_request(string("GET"), rest_req); | |
796 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
797 | entries.clear(); | |
798 | get_datalog_list(entries); | |
799 | EXPECT_EQ(1U, entries.size()); | |
800 | ||
801 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
802 | perm = "read"; | |
803 | ASSERT_EQ(0, caps_add(cname, perm)); | |
804 | ss.str(""); | |
805 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time; | |
806 | rest_req = ss.str(); | |
807 | g_test->send_request(string("GET"), rest_req); | |
808 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
809 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
810 | ss.str(""); | |
811 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time; | |
812 | rest_req = ss.str(); | |
813 | ||
814 | g_test->send_request(string("GET"), rest_req); | |
815 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
816 | ||
817 | ASSERT_EQ(0, delete_obj(TEST_BUCKET_OBJECT)); | |
818 | ASSERT_EQ(0, delete_bucket()); | |
819 | ASSERT_EQ(0, user_rm(uid, display_name)); | |
820 | } | |
821 | ||
822 | TEST(TestRGWAdmin, datalog_lock_unlock) { | |
823 | const char *cname = "datalog", | |
824 | *perm = "*"; | |
825 | string rest_req; | |
826 | ||
827 | ASSERT_EQ(0, user_create(uid, display_name)); | |
828 | ASSERT_EQ(0, caps_add(cname, perm)); | |
829 | ||
830 | rest_req = "/admin/log?type=data&lock&length=3&locker-id=ceph&zone-id=1"; | |
831 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
832 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
833 | ||
834 | rest_req = "/admin/log?type=data&lock&id=3&locker-id=ceph&zone-id=1"; | |
835 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
836 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
837 | ||
838 | rest_req = "/admin/log?type=data&lock&length=3&id=1&zone-id=1"; | |
839 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
840 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
841 | ||
842 | rest_req = "/admin/log?type=data&lock&length=3&id=1&locker-id=1"; | |
843 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
844 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
845 | ||
846 | rest_req = "/admin/log?type=data&unlock&id=1&zone-id=1"; | |
847 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
848 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
849 | ||
850 | rest_req = "/admin/log?type=data&unlock&locker-id=ceph&zone-id=1"; | |
851 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
852 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
853 | ||
854 | rest_req = "/admin/log?type=data&unlock&locker-id=ceph&id=1"; | |
855 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
856 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
857 | ||
858 | rest_req = "/admin/log?type=data&lock&id=1&length=3&locker-id=ceph&zone-id=1"; | |
859 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
860 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
861 | ||
862 | rest_req = "/admin/log?type=data&unlock&id=1&locker-id=ceph&zone-id=1"; | |
863 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
864 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
865 | ||
866 | rest_req = "/admin/log?type=data&lock&id=1&length=3&locker-id=ceph1&zone-id=1"; | |
867 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
868 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
869 | ||
870 | rest_req = "/admin/log?type=data&unlock&id=1&locker-id=ceph1&zone-id=1"; | |
871 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
872 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
873 | ||
874 | rest_req = "/admin/log?type=data&lock&id=1&length=3&locker-id=ceph&zone-id=1"; | |
875 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
876 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
877 | utime_t sleep_time(3, 0); | |
878 | ||
879 | rest_req = "/admin/log?type=data&lock&id=1&length=3&locker-id=ceph1&zone-id=1"; | |
880 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
881 | EXPECT_EQ(500U, g_test->get_resp_code()); | |
882 | ||
883 | rest_req = "/admin/log?type=data&lock&id=1&length=3&locker-id=ceph1&zone-id=2"; | |
884 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
885 | EXPECT_EQ(500U, g_test->get_resp_code()); | |
886 | ||
887 | rest_req = "/admin/log?type=data&lock&id=1&length=3&locker-id=ceph&zone-id=1"; | |
888 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
889 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
890 | sleep_time.sleep(); | |
891 | ||
892 | rest_req = "/admin/log?type=data&lock&id=1&length=3&locker-id=ceph1&zone-id=1"; | |
893 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
894 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
895 | ||
896 | rest_req = "/admin/log?type=data&unlock&id=1&locker-id=ceph1&zone-id=1"; | |
897 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
898 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
899 | ||
900 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
901 | perm = "read"; | |
902 | ASSERT_EQ(0, caps_add(cname, perm)); | |
903 | rest_req = "/admin/log?type=data&lock&id=1&length=3&locker-id=ceph&zone-id=1"; | |
904 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
905 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
906 | ||
907 | rest_req = "/admin/log?type=data&unlock&id=1&locker-id=ceph&zone-id=1"; | |
908 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
909 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
910 | ||
911 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
912 | perm = "write"; | |
913 | ASSERT_EQ(0, caps_add(cname, perm)); | |
914 | rest_req = "/admin/log?type=data&lock&id=1&length=3&locker-id=ceph&zone-id=1"; | |
915 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
916 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
917 | ||
918 | rest_req = "/admin/log?type=data&unlock&id=1&locker-id=ceph&zone-id=1"; | |
919 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
920 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
921 | ||
922 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
923 | rest_req = "/admin/log?type=data&lock&id=1&length=3&locker-id=ceph&zone-id=1"; | |
924 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
925 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
926 | ||
927 | rest_req = "/admin/log?type=data&unlock&id=1&locker-id=ceph&zone-id=1"; | |
928 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
929 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
930 | ||
931 | ASSERT_EQ(0, user_rm(uid, display_name)); | |
932 | } | |
933 | ||
934 | TEST(TestRGWAdmin, datalog_trim) { | |
935 | string start_time, | |
936 | end_time; | |
937 | const char *cname = "datalog", | |
938 | *perm = "*"; | |
939 | string rest_req; | |
940 | unsigned shard_id = get_datalog_shard_id(TEST_BUCKET_NAME, g_ceph_context->_conf->rgw_data_log_num_shards); | |
941 | stringstream ss; | |
942 | list<rgw_data_change> entries; | |
943 | ||
944 | ASSERT_EQ(get_formatted_time(start_time), 0); | |
945 | ASSERT_EQ(0, user_create(uid, display_name)); | |
946 | ASSERT_EQ(0, caps_add(cname, perm)); | |
947 | ||
948 | rest_req = "/admin/log?type=data"; | |
949 | g_test->send_request(string("DELETE"), rest_req); | |
950 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
951 | ||
952 | ss.str(""); | |
953 | ss << "/admin/log?type=data&start-time=" << start_time; | |
954 | rest_req = ss.str(); | |
955 | g_test->send_request(string("DELETE"), rest_req); | |
956 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
957 | ||
958 | ss.str(""); | |
959 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time; | |
960 | rest_req = ss.str(); | |
961 | g_test->send_request(string("DELETE"), rest_req); | |
962 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
963 | ||
964 | ASSERT_EQ(0, create_bucket()); | |
965 | ||
966 | char *bucket_obj = (char *)calloc(1, TEST_BUCKET_OBJECT_SIZE); | |
967 | ASSERT_TRUE(bucket_obj != NULL); | |
968 | EXPECT_EQ(put_bucket_obj(TEST_BUCKET_OBJECT, bucket_obj, TEST_BUCKET_OBJECT_SIZE), 0); | |
969 | ASSERT_EQ(0, delete_obj(TEST_BUCKET_OBJECT)); | |
970 | sleep(1); | |
971 | EXPECT_EQ(put_bucket_obj(TEST_BUCKET_OBJECT, bucket_obj, TEST_BUCKET_OBJECT_SIZE), 0); | |
972 | ASSERT_EQ(0, delete_obj(TEST_BUCKET_OBJECT)); | |
973 | sleep(20); | |
974 | free(bucket_obj); | |
975 | ||
976 | ASSERT_EQ(get_formatted_time(end_time), 0); | |
977 | ss.str(""); | |
978 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time | |
979 | << "&end-time=" << end_time; | |
980 | rest_req = ss.str(); | |
981 | g_test->send_request(string("GET"), rest_req); | |
982 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
983 | entries.clear(); | |
984 | get_datalog_list(entries); | |
985 | EXPECT_TRUE(!entries.empty()); | |
986 | ||
987 | ss.str(""); | |
988 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time | |
989 | << "&end-time=" << end_time; | |
990 | rest_req = ss.str(); | |
991 | g_test->send_request(string("DELETE"), rest_req); | |
992 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
993 | ||
994 | ss.str(""); | |
995 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time | |
996 | << "&end-time=" << end_time; | |
997 | rest_req = ss.str(); | |
998 | g_test->send_request(string("GET"), rest_req); | |
999 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1000 | entries.clear(); | |
1001 | get_datalog_list(entries); | |
1002 | EXPECT_TRUE(entries.empty()); | |
1003 | ||
1004 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
1005 | perm = "write"; | |
1006 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1007 | ss.str(""); | |
1008 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time | |
1009 | << "&end-time=" << end_time; | |
1010 | rest_req = ss.str(); | |
1011 | g_test->send_request(string("DELETE"), rest_req); | |
1012 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1013 | ||
1014 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
1015 | perm = ""; | |
1016 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1017 | ss.str(""); | |
1018 | ss << "/admin/log?type=data&id=" << shard_id << "&start-time=" << start_time | |
1019 | << "&end-time=" << end_time; | |
1020 | rest_req = ss.str(); | |
1021 | g_test->send_request(string("DELETE"), rest_req); | |
1022 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
1023 | ||
1024 | ASSERT_EQ(0, delete_bucket()); | |
1025 | ASSERT_EQ(0, user_rm(uid, display_name)); | |
1026 | } | |
1027 | ||
1028 | TEST(TestRGWAdmin, mdlog_list) { | |
1029 | string start_time, | |
1030 | end_time, | |
1031 | start_time_2; | |
1032 | const char *cname = "mdlog", | |
1033 | *perm = "*"; | |
1034 | string rest_req; | |
1035 | unsigned shard_id = get_mdlog_shard_id(uid, g_ceph_context->_conf->rgw_md_log_max_shards); | |
1036 | stringstream ss; | |
1037 | ||
1038 | sleep(2); | |
1039 | ASSERT_EQ(get_formatted_time(start_time), 0); | |
1040 | ASSERT_EQ(0, user_create(uid, display_name)); | |
1041 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1042 | ||
1043 | rest_req = "/admin/log?type=metadata"; | |
1044 | g_test->send_request(string("GET"), rest_req); | |
1045 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1046 | JSONParser parser; | |
1047 | int num_objects; | |
1048 | EXPECT_EQ (parse_json_resp(parser), 0); | |
1049 | JSONDecoder::decode_json("num_objects", num_objects, (JSONObj *)&parser); | |
1050 | ASSERT_EQ(num_objects,g_ceph_context->_conf->rgw_md_log_max_shards); | |
1051 | ||
1052 | ss.str(""); | |
1053 | ss << "/admin/log?type=metadata&id=" << shard_id << "&start-time=" << start_time; | |
1054 | rest_req = ss.str(); | |
1055 | g_test->send_request(string("GET"), rest_req); | |
1056 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1057 | ||
1058 | list<cls_log_entry_json> entries; | |
1059 | EXPECT_EQ(get_log_list(entries), 0); | |
1060 | EXPECT_EQ(entries.size(), 4U); | |
1061 | ||
1062 | if(entries.size() == 4) { | |
1063 | list<cls_log_entry_json>::iterator it = entries.begin(); | |
1064 | EXPECT_TRUE(it->section.compare("user") == 0); | |
1065 | EXPECT_TRUE(it->name.compare(uid) == 0); | |
1066 | EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_WRITE); | |
1067 | ++it; | |
1068 | EXPECT_TRUE(it->section.compare("user") == 0); | |
1069 | EXPECT_TRUE(it->name.compare(uid) == 0); | |
1070 | EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_COMPLETE); | |
1071 | ++it; | |
1072 | EXPECT_TRUE(it->section.compare("user") == 0); | |
1073 | EXPECT_TRUE(it->name.compare(uid) == 0); | |
1074 | EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_WRITE); | |
1075 | ++it; | |
1076 | EXPECT_TRUE(it->section.compare("user") == 0); | |
1077 | EXPECT_TRUE(it->name.compare(uid) == 0); | |
1078 | EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_COMPLETE); | |
1079 | } | |
1080 | ||
1081 | sleep(1); /*To get a modified time*/ | |
1082 | ASSERT_EQ(get_formatted_time(start_time_2), 0); | |
1083 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
1084 | perm="read"; | |
1085 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1086 | ss.str(""); | |
1087 | ss << "/admin/log?type=metadata&id=" << shard_id << "&start-time=" << start_time_2; | |
1088 | rest_req = ss.str(); | |
1089 | g_test->send_request(string("GET"), rest_req); | |
1090 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1091 | ||
1092 | entries.clear(); | |
1093 | EXPECT_EQ(get_log_list(entries), 0); | |
1094 | EXPECT_EQ(entries.size(), 4U); | |
1095 | ||
1096 | if(entries.size() == 4) { | |
1097 | list<cls_log_entry_json>::iterator it = entries.begin(); | |
1098 | EXPECT_TRUE(it->section.compare("user") == 0); | |
1099 | EXPECT_TRUE(it->name.compare(uid) == 0); | |
1100 | EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_WRITE); | |
1101 | ++it; | |
1102 | EXPECT_TRUE(it->section.compare("user") == 0); | |
1103 | EXPECT_TRUE(it->name.compare(uid) == 0); | |
1104 | EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_COMPLETE); | |
1105 | ++it; | |
1106 | EXPECT_TRUE(it->section.compare("user") == 0); | |
1107 | EXPECT_TRUE(it->name.compare(uid) == 0); | |
1108 | EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_WRITE); | |
1109 | ++it; | |
1110 | EXPECT_TRUE(it->section.compare("user") == 0); | |
1111 | EXPECT_TRUE(it->name.compare(uid) == 0); | |
1112 | EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_COMPLETE); | |
1113 | } | |
1114 | ||
1115 | sleep(1); | |
1116 | ASSERT_EQ(get_formatted_time(start_time_2), 0); | |
1117 | ASSERT_EQ(0, user_rm(uid, display_name)); | |
1118 | ||
1119 | ASSERT_EQ(0, user_create(uid, display_name)); | |
1120 | perm = "*"; | |
1121 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1122 | ||
1123 | ss.str(""); | |
1124 | ss << "/admin/log?type=metadata&id=" << shard_id << "&start-time=" << start_time_2; | |
1125 | rest_req = ss.str(); | |
1126 | g_test->send_request(string("GET"), rest_req); | |
1127 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1128 | ||
1129 | entries.clear(); | |
1130 | EXPECT_EQ(get_log_list(entries), 0); | |
1131 | EXPECT_EQ(entries.size(), 6U); | |
1132 | if(entries.size() == 6) { | |
1133 | list<cls_log_entry_json>::iterator it = entries.begin(); | |
1134 | EXPECT_TRUE(it->section.compare("user") == 0); | |
1135 | EXPECT_TRUE(it->name.compare(uid) == 0); | |
1136 | EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_REMOVE); | |
1137 | ++it; | |
1138 | EXPECT_TRUE(it->section.compare("user") == 0); | |
1139 | EXPECT_TRUE(it->name.compare(uid) == 0); | |
1140 | ++it; | |
1141 | EXPECT_TRUE(it->section.compare("user") == 0); | |
1142 | EXPECT_TRUE(it->name.compare(uid) == 0); | |
1143 | EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_WRITE); | |
1144 | ++it; | |
1145 | EXPECT_TRUE(it->section.compare("user") == 0); | |
1146 | EXPECT_TRUE(it->name.compare(uid) == 0); | |
1147 | EXPECT_TRUE(it->log_data.status == MDLOG_STATUS_COMPLETE); | |
1148 | } | |
1149 | ||
1150 | sleep(1); | |
1151 | ASSERT_EQ(get_formatted_time(end_time), 0); | |
1152 | ss.str(""); | |
1153 | ss << "/admin/log?type=metadata&id=" << shard_id << "&start-time=" << start_time | |
1154 | << "&end-time=" << end_time; | |
1155 | rest_req = ss.str(); | |
1156 | g_test->send_request(string("GET"), rest_req); | |
1157 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1158 | entries.clear(); | |
1159 | EXPECT_EQ(get_log_list(entries), 0); | |
1160 | EXPECT_EQ(entries.size(), 14U); | |
1161 | ||
1162 | ss.str(""); | |
1163 | ss << "/admin/log?type=metadata&id=" << shard_id << "&start-time=" << start_time | |
1164 | << "&max-entries=" << 1; | |
1165 | rest_req = ss.str(); | |
1166 | g_test->send_request(string("GET"), rest_req); | |
1167 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1168 | entries.clear(); | |
1169 | EXPECT_EQ(get_log_list(entries), 0); | |
1170 | EXPECT_EQ(entries.size(), 1U); | |
1171 | ||
1172 | ss.str(""); | |
1173 | ss << "/admin/log?type=metadata&id=" << shard_id << "&start-time=" << start_time | |
1174 | << "&max-entries=" << 6; | |
1175 | rest_req = ss.str(); | |
1176 | g_test->send_request(string("GET"), rest_req); | |
1177 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1178 | entries.clear(); | |
1179 | EXPECT_EQ(get_log_list(entries), 0); | |
1180 | EXPECT_EQ(entries.size(), 6U); | |
1181 | ||
1182 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
1183 | ss.str(""); | |
1184 | ss << "/admin/log?type=metadata&id=" << shard_id << "&start-time=" << start_time; | |
1185 | rest_req = ss.str(); | |
1186 | g_test->send_request(string("GET"), rest_req); | |
1187 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
1188 | ||
1189 | /*cleanup*/ | |
1190 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1191 | sleep(1); | |
1192 | ASSERT_EQ(get_formatted_time(end_time), 0); | |
1193 | ss.str(""); | |
1194 | ss << "/admin/log?type=metadata&id=" << shard_id << "&start-time=" << start_time | |
1195 | << "&end-time=" << end_time; | |
1196 | rest_req = ss.str(); | |
1197 | g_test->send_request(string("DELETE"), rest_req); | |
1198 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1199 | ||
1200 | ASSERT_EQ(0, user_rm(uid, display_name)); | |
1201 | } | |
1202 | ||
1203 | TEST(TestRGWAdmin, mdlog_trim) { | |
1204 | string start_time, | |
1205 | end_time; | |
1206 | const char *cname = "mdlog", | |
1207 | *perm = "*"; | |
1208 | string rest_req; | |
1209 | list<cls_log_entry_json> entries; | |
1210 | unsigned shard_id = get_mdlog_shard_id(uid, g_ceph_context->_conf->rgw_md_log_max_shards); | |
1211 | ostringstream ss; | |
1212 | ||
1213 | sleep(1); | |
1214 | ASSERT_EQ(get_formatted_time(start_time), 0); | |
1215 | ASSERT_EQ(0, user_create(uid, display_name)); | |
1216 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1217 | ||
1218 | ss.str(""); | |
1219 | ss << "/admin/log?type=metadata&id=" << shard_id << "&start-time=" << start_time; | |
1220 | rest_req = ss.str(); | |
1221 | g_test->send_request(string("DELETE"), rest_req); | |
1222 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
1223 | ||
1224 | g_test->send_request(string("GET"), rest_req); | |
1225 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1226 | EXPECT_EQ(get_log_list(entries), 0); | |
1227 | EXPECT_EQ(entries.size(), 4U); | |
1228 | ||
1229 | sleep(1); | |
1230 | ASSERT_EQ(get_formatted_time(end_time), 0); | |
1231 | ss.str(""); | |
1232 | ss << "/admin/log?type=metadata&id=" << shard_id << "&start-time=" << start_time << "&end-time=" << end_time; | |
1233 | rest_req = ss.str(); | |
1234 | g_test->send_request(string("DELETE"), rest_req); | |
1235 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1236 | ||
1237 | ss.str(""); | |
1238 | ss << "/admin/log?type=metadata&id=" << shard_id << "&start-time=" << start_time; | |
1239 | rest_req = ss.str(); | |
1240 | g_test->send_request(string("GET"), rest_req); | |
1241 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1242 | entries.clear(); | |
1243 | EXPECT_EQ(get_log_list(entries), 0); | |
1244 | EXPECT_EQ(entries.size(), 0U); | |
1245 | ||
1246 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
1247 | perm="write"; | |
1248 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1249 | ASSERT_EQ(get_formatted_time(end_time), 0); | |
1250 | ss.str(""); | |
1251 | ss << "/admin/log?type=metadata&id=" << shard_id << "&start-time=" << start_time << "&end-time=" << end_time; | |
1252 | rest_req = ss.str(); | |
1253 | g_test->send_request(string("DELETE"), rest_req); | |
1254 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1255 | ||
1256 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
1257 | g_test->send_request(string("DELETE"), rest_req); | |
1258 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
1259 | ASSERT_EQ(0, user_rm(uid, display_name)); | |
1260 | } | |
1261 | ||
1262 | TEST(TestRGWAdmin, mdlog_lock_unlock) { | |
1263 | const char *cname = "mdlog", | |
1264 | *perm = "*"; | |
1265 | string rest_req; | |
1266 | ||
1267 | ASSERT_EQ(0, user_create(uid, display_name)); | |
1268 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1269 | ||
1270 | rest_req = "/admin/log?type=metadata&lock&length=3&locker-id=ceph&zone-id=1"; | |
1271 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1272 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
1273 | ||
1274 | rest_req = "/admin/log?type=metadata&lock&id=3&locker-id=ceph&zone-id=1"; | |
1275 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1276 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
1277 | ||
1278 | rest_req = "/admin/log?type=metadata&lock&length=3&id=1&zone-id=1"; | |
1279 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1280 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
1281 | ||
1282 | rest_req = "/admin/log?type=metadata&lock&id=3&locker-id=ceph&length=1"; | |
1283 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1284 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
1285 | ||
1286 | rest_req = "/admin/log?type=metadata&unlock&id=1&zone-id=1"; | |
1287 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1288 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
1289 | ||
1290 | rest_req = "/admin/log?type=metadata&unlock&locker-id=ceph&zone-id=1"; | |
1291 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1292 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
1293 | ||
1294 | rest_req = "/admin/log?type=metadata&unlock&locker-id=ceph&id=1"; | |
1295 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1296 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
1297 | ||
1298 | rest_req = "/admin/log?type=metadata&lock&id=1&length=3&locker-id=ceph&zone-id=1"; | |
1299 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1300 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1301 | ||
1302 | rest_req = "/admin/log?type=metadata&unlock&id=1&locker-id=ceph&zone-id=1"; | |
1303 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1304 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1305 | ||
1306 | rest_req = "/admin/log?type=metadata&lock&id=1&length=3&locker-id=ceph1&zone-id=1"; | |
1307 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1308 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1309 | ||
1310 | rest_req = "/admin/log?type=metadata&unlock&id=1&locker-id=ceph1&zone-id=1"; | |
1311 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1312 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1313 | ||
1314 | rest_req = "/admin/log?type=metadata&lock&id=1&length=3&locker-id=ceph&zone-id=1"; | |
1315 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1316 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1317 | utime_t sleep_time(3, 0); | |
1318 | ||
1319 | rest_req = "/admin/log?type=metadata&lock&id=1&length=3&locker-id=ceph1&zone-id=1"; | |
1320 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1321 | EXPECT_EQ(500U, g_test->get_resp_code()); | |
1322 | ||
1323 | rest_req = "/admin/log?type=metadata&lock&id=1&length=3&locker-id=ceph&zone-id=2"; | |
1324 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1325 | EXPECT_EQ(500U, g_test->get_resp_code()); | |
1326 | ||
1327 | rest_req = "/admin/log?type=metadata&lock&id=1&length=3&locker-id=ceph&zone-id=1"; | |
1328 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1329 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1330 | sleep_time.sleep(); | |
1331 | ||
1332 | rest_req = "/admin/log?type=metadata&lock&id=1&length=3&locker-id=ceph1&zone-id=1"; | |
1333 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1334 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1335 | ||
1336 | rest_req = "/admin/log?type=metadata&unlock&id=1&locker-id=ceph1&zone-id=1"; | |
1337 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1338 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1339 | ||
1340 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
1341 | perm = "read"; | |
1342 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1343 | rest_req = "/admin/log?type=metadata&lock&id=1&length=3&locker-id=ceph&zone-id=1"; | |
1344 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1345 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
1346 | ||
1347 | rest_req = "/admin/log?type=metadata&unlock&id=1&locker-id=ceph&zone-id=1"; | |
1348 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1349 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
1350 | ||
1351 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
1352 | perm = "write"; | |
1353 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1354 | rest_req = "/admin/log?type=metadata&lock&id=1&length=3&locker-id=ceph&zone-id=1"; | |
1355 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1356 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1357 | ||
1358 | rest_req = "/admin/log?type=metadata&unlock&id=1&locker-id=ceph&zone-id=1"; | |
1359 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1360 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1361 | ||
1362 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
1363 | rest_req = "/admin/log?type=metadata&lock&id=1&length=3&locker-id=ceph&zone-id=1"; | |
1364 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1365 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
1366 | ||
1367 | rest_req = "/admin/log?type=metadata&unlock&id=1&locker-id=ceph&zone-id=1"; | |
1368 | g_test->send_request(string("POST"), rest_req, read_dummy_post, NULL, sizeof(int)); | |
1369 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
1370 | ||
1371 | ASSERT_EQ(0, user_rm(uid, display_name)); | |
1372 | } | |
1373 | ||
1374 | TEST(TestRGWAdmin, bilog_list) { | |
1375 | const char *cname = "bilog", | |
1376 | *perm = "*"; | |
1377 | string rest_req; | |
1378 | ||
1379 | ASSERT_EQ(0, user_create(uid, display_name)); | |
1380 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1381 | ||
1382 | ASSERT_EQ(0, create_bucket()); | |
1383 | ||
1384 | char *bucket_obj = (char *)calloc(1, TEST_BUCKET_OBJECT_SIZE); | |
1385 | ASSERT_TRUE(bucket_obj != NULL); | |
1386 | EXPECT_EQ(put_bucket_obj(TEST_BUCKET_OBJECT, bucket_obj, TEST_BUCKET_OBJECT_SIZE), 0); | |
1387 | free(bucket_obj); | |
1388 | ||
1389 | rest_req = "/admin/log?type=bucket-index&bucket=" TEST_BUCKET_NAME; | |
1390 | g_test->send_request(string("GET"), rest_req); | |
1391 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1392 | list<cls_bilog_entry> entries; | |
1393 | get_bilog_list(entries); | |
1394 | EXPECT_EQ(2U, entries.size()); | |
1395 | if (entries.size() == 2) { | |
1396 | list<cls_bilog_entry>::iterator it = entries.begin(); | |
1397 | EXPECT_EQ(it->op.compare("write"), 0); | |
1398 | EXPECT_EQ(it->object.compare(TEST_BUCKET_OBJECT), 0); | |
1399 | EXPECT_EQ(it->status.compare("pending"), 0); | |
1400 | EXPECT_EQ(it->index_ver, 1U); | |
1401 | ++it; | |
1402 | EXPECT_EQ(it->op.compare("write"), 0); | |
1403 | EXPECT_EQ(it->object.compare(TEST_BUCKET_OBJECT), 0); | |
1404 | EXPECT_EQ(it->status.compare("complete"), 0); | |
1405 | EXPECT_EQ(it->index_ver, 2U); | |
1406 | } | |
1407 | EXPECT_EQ(read_bucket_obj(TEST_BUCKET_OBJECT), 0); | |
1408 | g_test->send_request(string("GET"), rest_req); | |
1409 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1410 | entries.clear(); | |
1411 | get_bilog_list(entries); | |
1412 | EXPECT_EQ(2U, entries.size()); | |
1413 | ||
1414 | bucket_obj = (char *)calloc(1, TEST_BUCKET_OBJECT_SIZE); | |
1415 | ASSERT_TRUE(bucket_obj != NULL); | |
1416 | EXPECT_EQ(put_bucket_obj(TEST_BUCKET_OBJECT_1, bucket_obj, TEST_BUCKET_OBJECT_SIZE), 0); | |
1417 | free(bucket_obj); | |
1418 | ||
1419 | rest_req = "/admin/log?type=bucket-index&bucket=" TEST_BUCKET_NAME; | |
1420 | g_test->send_request(string("GET"), rest_req); | |
1421 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1422 | entries.clear(); | |
1423 | get_bilog_list(entries); | |
1424 | EXPECT_EQ(4U, entries.size()); | |
1425 | if (entries.size() == 4) { | |
1426 | list<cls_bilog_entry>::iterator it = entries.begin(); | |
1427 | ||
1428 | ++it; ++it; | |
1429 | EXPECT_EQ(it->op.compare("write"), 0); | |
1430 | EXPECT_EQ(it->object.compare(TEST_BUCKET_OBJECT_1), 0); | |
1431 | EXPECT_EQ(it->status.compare("pending"), 0); | |
1432 | EXPECT_EQ(it->index_ver, 3U); | |
1433 | ++it; | |
1434 | EXPECT_EQ(it->op.compare("write"), 0); | |
1435 | EXPECT_EQ(it->object.compare(TEST_BUCKET_OBJECT_1), 0); | |
1436 | EXPECT_EQ(it->status.compare("complete"), 0); | |
1437 | EXPECT_EQ(it->index_ver, 4U); | |
1438 | } | |
1439 | ||
1440 | ASSERT_EQ(0, delete_obj(TEST_BUCKET_OBJECT)); | |
1441 | rest_req = "/admin/log?type=bucket-index&bucket=" TEST_BUCKET_NAME; | |
1442 | g_test->send_request(string("GET"), rest_req); | |
1443 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1444 | entries.clear(); | |
1445 | get_bilog_list(entries); | |
1446 | ||
1447 | EXPECT_EQ(6U, entries.size()); | |
1448 | string marker; | |
1449 | if (entries.size() == 6) { | |
1450 | list<cls_bilog_entry>::iterator it = entries.begin(); | |
1451 | ||
1452 | ++it; ++it; ++it; ++it; | |
1453 | marker = it->op_id; | |
1454 | EXPECT_EQ(it->op.compare("del"), 0); | |
1455 | EXPECT_EQ(it->object.compare(TEST_BUCKET_OBJECT), 0); | |
1456 | EXPECT_EQ(it->status.compare("pending"), 0); | |
1457 | EXPECT_EQ(it->index_ver, 5U); | |
1458 | ++it; | |
1459 | EXPECT_EQ(it->op.compare("del"), 0); | |
1460 | EXPECT_EQ(it->object.compare(TEST_BUCKET_OBJECT), 0); | |
1461 | EXPECT_EQ(it->status.compare("complete"), 0); | |
1462 | EXPECT_EQ(it->index_ver, 6U); | |
1463 | } | |
1464 | ||
1465 | rest_req = "/admin/log?type=bucket-index&bucket=" TEST_BUCKET_NAME; | |
1466 | rest_req.append("&marker="); | |
1467 | rest_req.append(marker); | |
1468 | g_test->send_request(string("GET"), rest_req); | |
1469 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1470 | entries.clear(); | |
1471 | get_bilog_list(entries); | |
1472 | EXPECT_EQ(2U, entries.size()); | |
1473 | if (entries.size() == 2U) { | |
1474 | list<cls_bilog_entry>::iterator it = entries.begin(); | |
1475 | EXPECT_EQ(it->index_ver, 5U); | |
1476 | ++it; | |
1477 | EXPECT_EQ(it->index_ver, 6U); | |
1478 | EXPECT_EQ(it->op.compare("del"), 0); | |
1479 | } | |
1480 | ||
1481 | rest_req = "/admin/log?type=bucket-index&bucket=" TEST_BUCKET_NAME; | |
1482 | rest_req.append("&marker="); | |
1483 | rest_req.append(marker); | |
1484 | rest_req.append("&max-entries=1"); | |
1485 | g_test->send_request(string("GET"), rest_req); | |
1486 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1487 | entries.clear(); | |
1488 | get_bilog_list(entries); | |
1489 | EXPECT_EQ(1U, entries.size()); | |
1490 | EXPECT_EQ((entries.begin())->index_ver, 5U); | |
1491 | ||
1492 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
1493 | perm = "read"; | |
1494 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1495 | rest_req = "/admin/log?type=bucket-index&bucket=" TEST_BUCKET_NAME; | |
1496 | g_test->send_request(string("GET"), rest_req); | |
1497 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1498 | ||
1499 | ASSERT_EQ(0, caps_rm(cname, perm)); | |
1500 | perm = "write"; | |
1501 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1502 | rest_req = "/admin/log?type=bucket-index&bucket=" TEST_BUCKET_NAME; | |
1503 | g_test->send_request(string("GET"), rest_req); | |
1504 | EXPECT_EQ(403U, g_test->get_resp_code()); | |
1505 | ||
1506 | ASSERT_EQ(0, delete_obj(TEST_BUCKET_OBJECT_1)); | |
1507 | ASSERT_EQ(0, delete_bucket()); | |
1508 | ASSERT_EQ(0, user_rm(uid, display_name)); | |
1509 | } | |
1510 | ||
1511 | TEST(TestRGWAdmin, bilog_trim) { | |
1512 | const char *cname = "bilog", | |
1513 | *perm = "*"; | |
1514 | string rest_req, start_marker, end_marker; | |
1515 | ||
1516 | ASSERT_EQ(0, user_create(uid, display_name)); | |
1517 | ASSERT_EQ(0, caps_add(cname, perm)); | |
1518 | ||
1519 | ASSERT_EQ(0, create_bucket()); | |
1520 | ||
1521 | rest_req = "/admin/log?type=bucket-index&bucket=" TEST_BUCKET_NAME; | |
1522 | g_test->send_request(string("DELETE"), rest_req); | |
1523 | EXPECT_EQ(400U, g_test->get_resp_code()); /*Bad request*/ | |
1524 | ||
1525 | char *bucket_obj = (char *)calloc(1, TEST_BUCKET_OBJECT_SIZE); | |
1526 | ASSERT_TRUE(bucket_obj != NULL); | |
1527 | EXPECT_EQ(put_bucket_obj(TEST_BUCKET_OBJECT, bucket_obj, TEST_BUCKET_OBJECT_SIZE), 0); | |
1528 | free(bucket_obj); | |
1529 | ||
1530 | rest_req = "/admin/log?type=bucket-index&bucket=" TEST_BUCKET_NAME; | |
1531 | g_test->send_request(string("GET"), rest_req); | |
1532 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1533 | list<cls_bilog_entry> entries; | |
1534 | get_bilog_list(entries); | |
1535 | EXPECT_EQ(2U, entries.size()); | |
1536 | ||
1537 | list<cls_bilog_entry>::iterator it = entries.begin(); | |
1538 | start_marker = it->op_id; | |
1539 | ++it; | |
1540 | end_marker = it->op_id; | |
1541 | ||
1542 | rest_req = "/admin/log?type=bucket-index&bucket=" TEST_BUCKET_NAME; | |
1543 | rest_req.append("&start-marker="); | |
1544 | rest_req.append(start_marker); | |
1545 | rest_req.append("&end-marker="); | |
1546 | rest_req.append(end_marker); | |
1547 | g_test->send_request(string("DELETE"), rest_req); | |
1548 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1549 | ||
1550 | rest_req = "/admin/log?type=bucket-index&bucket=" TEST_BUCKET_NAME; | |
1551 | g_test->send_request(string("GET"), rest_req); | |
1552 | EXPECT_EQ(200U, g_test->get_resp_code()); | |
1553 | entries.clear(); | |
1554 | get_bilog_list(entries); | |
1555 | EXPECT_EQ(0U, entries.size()); | |
1556 | ||
1557 | ASSERT_EQ(0, delete_obj(TEST_BUCKET_OBJECT)); | |
1558 | ASSERT_EQ(0, delete_bucket()); | |
1559 | ASSERT_EQ(0, user_rm(uid, display_name)); | |
1560 | } | |
1561 | ||
1562 | int main(int argc, char *argv[]){ | |
20effc67 | 1563 | auto args = argv_to_vec(argc, argv); |
7c673cae FG |
1564 | |
1565 | auto cct = global_init(NULL, args, CEPH_ENTITY_TYPE_CLIENT, | |
11fdf7f2 TL |
1566 | CODE_ENVIRONMENT_UTILITY, |
1567 | CINIT_FLAG_NO_DEFAULT_CONFIG_FILE); | |
7c673cae FG |
1568 | common_init_finish(g_ceph_context); |
1569 | g_test = new admin_log::test_helper(); | |
1570 | finisher = new Finisher(g_ceph_context); | |
1571 | #ifdef GTEST | |
1572 | ::testing::InitGoogleTest(&argc, argv); | |
1573 | #endif | |
1574 | finisher->start(); | |
1575 | ||
1576 | if(g_test->extract_input(argc, argv) < 0){ | |
1577 | print_usage(argv[0]); | |
1578 | return -1; | |
1579 | } | |
1580 | #ifdef GTEST | |
1581 | int r = RUN_ALL_TESTS(); | |
1582 | if (r >= 0) { | |
1583 | cout << "There are no failures in the test case\n"; | |
1584 | } else { | |
1585 | cout << "There are some failures\n"; | |
1586 | } | |
1587 | #endif | |
1588 | finisher->stop(); | |
1589 | return 0; | |
1590 | } |