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