]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/librados/cmd.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / test / librados / cmd.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3
4 #include "mds/mdstypes.h"
5 #include "include/buffer.h"
6 #include "include/rbd_types.h"
7 #include "include/rados/librados.h"
8 #include "include/rados/librados.hpp"
9 #include "include/stringify.h"
10 #include "test/librados/test.h"
11
12 #include "common/Cond.h"
13
14 #include "gtest/gtest.h"
15 #include <errno.h>
16 #include <map>
17 #include <sstream>
18 #include <string>
19
20 using namespace librados;
21 using std::map;
22 using std::ostringstream;
23 using std::string;
24
25 TEST(LibRadosCmd, MonDescribe) {
26 rados_t cluster;
27 ASSERT_EQ("", connect_cluster(&cluster));
28
29 char *buf, *st;
30 size_t buflen, stlen;
31 char *cmd[2];
32
33 cmd[1] = NULL;
34
35 cmd[0] = (char *)"{\"prefix\":\"get_command_descriptions\"}";
36 ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
37 ASSERT_LT(0u, buflen);
38 rados_buffer_free(buf);
39 rados_buffer_free(st);
40
41 cmd[0] = (char *)"get_command_descriptions";
42 ASSERT_EQ(-EINVAL, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
43 rados_buffer_free(buf);
44 rados_buffer_free(st);
45
46 cmd[0] = (char *)"asdfqwer";
47 ASSERT_EQ(-EINVAL, rados_mon_command(cluster, (const char **)cmd, 1, "{}", 2, &buf, &buflen, &st, &stlen));
48 rados_buffer_free(buf);
49 rados_buffer_free(st);
50
51 cmd[0] = (char *)"";
52 ASSERT_EQ(-EINVAL, rados_mon_command(cluster, (const char **)cmd, 1, "{}", 2, &buf, &buflen, &st, &stlen));
53 rados_buffer_free(buf);
54 rados_buffer_free(st);
55
56 cmd[0] = (char *)"{}";
57 ASSERT_EQ(-EINVAL, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
58 rados_buffer_free(buf);
59 rados_buffer_free(st);
60
61 cmd[0] = (char *)"{\"abc\":\"something\"}";
62 ASSERT_EQ(-EINVAL, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
63 rados_buffer_free(buf);
64 rados_buffer_free(st);
65
66 cmd[0] = (char *)"{\"prefix\":\"\"}";
67 ASSERT_EQ(-EINVAL, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
68 rados_buffer_free(buf);
69 rados_buffer_free(st);
70
71 cmd[0] = (char *)"{\"prefix\":\" \"}";
72 ASSERT_EQ(-EINVAL, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
73 rados_buffer_free(buf);
74 rados_buffer_free(st);
75
76 cmd[0] = (char *)"{\"prefix\":\";;;,,,;;,,\"}";
77 ASSERT_EQ(-EINVAL, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
78 rados_buffer_free(buf);
79 rados_buffer_free(st);
80
81 cmd[0] = (char *)"{\"prefix\":\"extra command\"}";
82 ASSERT_EQ(-EINVAL, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
83 rados_buffer_free(buf);
84 rados_buffer_free(st);
85
86 cmd[0] = (char *)"{\"prefix\":\"mon_status\"}";
87 ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
88 ASSERT_LT(0u, buflen);
89 //ASSERT_LT(0u, stlen);
90 rados_buffer_free(buf);
91 rados_buffer_free(st);
92 rados_shutdown(cluster);
93 }
94
95 TEST(LibRadosCmd, MonDescribePP) {
96 Rados cluster;
97 ASSERT_EQ("", connect_cluster_pp(cluster));
98 bufferlist inbl, outbl;
99 string outs;
100 ASSERT_EQ(0, cluster.mon_command("{\"prefix\": \"get_command_descriptions\"}",
101 inbl, &outbl, &outs));
102 ASSERT_LT(0u, outbl.length());
103 ASSERT_LE(0u, outs.length());
104 cluster.shutdown();
105 }
106
107 TEST(LibRadosCmd, OSDCmd) {
108 rados_t cluster;
109 ASSERT_EQ("", connect_cluster(&cluster));
110 int r;
111 char *buf, *st;
112 size_t buflen, stlen;
113 char *cmd[2];
114 cmd[1] = NULL;
115
116 // note: tolerate NXIO here in case the cluster is thrashing out underneath us.
117 cmd[0] = (char *)"asdfasdf";
118 r = rados_osd_command(cluster, 0, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen);
119 rados_buffer_free(buf);
120 rados_buffer_free(st);
121 ASSERT_TRUE(r == -22 || r == -ENXIO);
122 cmd[0] = (char *)"version";
123 r = rados_osd_command(cluster, 0, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen);
124 rados_buffer_free(buf);
125 rados_buffer_free(st);
126 ASSERT_TRUE(r == -22 || r == -ENXIO);
127 cmd[0] = (char *)"{\"prefix\":\"version\"}";
128 r = rados_osd_command(cluster, 0, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen);
129 ASSERT_TRUE((r == 0 && buflen > 0) || (r == -ENXIO && buflen == 0));
130 rados_buffer_free(buf);
131 rados_buffer_free(st);
132 rados_shutdown(cluster);
133 }
134
135 TEST(LibRadosCmd, OSDCmdPP) {
136 Rados cluster;
137 ASSERT_EQ("", connect_cluster_pp(cluster));
138 int r;
139 bufferlist inbl, outbl;
140 string outs;
141 string cmd;
142
143 // note: tolerate NXIO here in case the cluster is thrashing out underneath us.
144 cmd = "asdfasdf";
145 r = cluster.osd_command(0, cmd, inbl, &outbl, &outs);
146 ASSERT_TRUE(r == -22 || r == -ENXIO);
147 cmd = "version";
148 r = cluster.osd_command(0, cmd, inbl, &outbl, &outs);
149 ASSERT_TRUE(r == -22 || r == -ENXIO);
150 cmd = "{\"prefix\":\"version\"}";
151 r = cluster.osd_command(0, cmd, inbl, &outbl, &outs);
152 ASSERT_TRUE((r == 0 && outbl.length() > 0) || (r == -ENXIO && outbl.length() == 0));
153 cluster.shutdown();
154 }
155
156 TEST(LibRadosCmd, PGCmd) {
157 rados_t cluster;
158 std::string pool_name = get_temp_pool_name();
159 ASSERT_EQ("", create_one_pool(pool_name, &cluster));
160
161 char *buf, *st;
162 size_t buflen, stlen;
163 char *cmd[2];
164 cmd[1] = NULL;
165
166 int64_t poolid = rados_pool_lookup(cluster, pool_name.c_str());
167 ASSERT_LT(0, poolid);
168
169 string pgid = stringify(poolid) + ".0";
170
171 cmd[0] = (char *)"asdfasdf";
172 // note: tolerate NXIO here in case the cluster is thrashing out underneath us.
173 int r = rados_pg_command(cluster, pgid.c_str(), (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen);
174 ASSERT_TRUE(r == -22 || r == -ENXIO);
175 rados_buffer_free(buf);
176 rados_buffer_free(st);
177
178 // make sure the pg exists on the osd before we query it
179 rados_ioctx_t io;
180 rados_ioctx_create(cluster, pool_name.c_str(), &io);
181 for (int i=0; i<100; i++) {
182 string oid = "obj" + stringify(i);
183 ASSERT_EQ(-ENOENT, rados_stat(io, oid.c_str(), NULL, NULL));
184 }
185 rados_ioctx_destroy(io);
186
187 string qstr = "{\"prefix\":\"pg\", \"cmd\":\"query\", \"pgid\":\"" + pgid + "\"}";
188 cmd[0] = (char *)qstr.c_str();
189 // note: tolerate ENOENT/ENXIO here if hte osd is thrashing out underneath us
190 r = rados_pg_command(cluster, pgid.c_str(), (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen);
191 ASSERT_TRUE(r == 0 || r == -ENOENT || r == -ENXIO);
192
193 ASSERT_LT(0u, buflen);
194 rados_buffer_free(buf);
195 rados_buffer_free(st);
196
197 ASSERT_EQ(0, destroy_one_pool(pool_name, &cluster));
198 }
199
200 TEST(LibRadosCmd, PGCmdPP) {
201 Rados cluster;
202 std::string pool_name = get_temp_pool_name();
203 ASSERT_EQ("", create_one_pool_pp(pool_name, cluster));
204
205 int r;
206 bufferlist inbl, outbl;
207 string outs;
208 string cmd;
209
210 int64_t poolid = cluster.pool_lookup(pool_name.c_str());
211 ASSERT_LT(0, poolid);
212
213 string pgid = stringify(poolid) + ".0";
214
215 cmd = "asdfasdf";
216 // note: tolerate NXIO here in case the cluster is thrashing out underneath us.
217 r = cluster.pg_command(pgid.c_str(), cmd, inbl, &outbl, &outs);
218 ASSERT_TRUE(r == -22 || r == -ENXIO);
219
220 // make sure the pg exists on the osd before we query it
221 IoCtx io;
222 cluster.ioctx_create(pool_name.c_str(), io);
223 for (int i=0; i<100; i++) {
224 string oid = "obj" + stringify(i);
225 ASSERT_EQ(-ENOENT, io.stat(oid, NULL, NULL));
226 }
227 io.close();
228
229 cmd = "{\"prefix\":\"pg\", \"cmd\":\"query\", \"pgid\":\"" + pgid + "\"}";
230 // note: tolerate ENOENT/ENXIO here if hte osd is thrashing out underneath us
231 r = cluster.pg_command(pgid.c_str(), cmd, inbl, &outbl, &outs);
232 ASSERT_TRUE(r == 0 || r == -ENOENT || r == -ENXIO);
233
234 ASSERT_LT(0u, outbl.length());
235
236 ASSERT_EQ(0, destroy_one_pool_pp(pool_name, cluster));
237 }
238
239 struct Log {
240 list<string> log;
241 Cond cond;
242 Mutex lock;
243
244 Log() : lock("l::lock") {}
245
246 bool contains(string str) {
247 Mutex::Locker l(lock);
248 for (list<string>::iterator p = log.begin(); p != log.end(); ++p) {
249 if (p->find(str) != std::string::npos)
250 return true;
251 }
252 return false;
253 }
254 };
255
256 void log_cb(void *arg,
257 const char *line,
258 const char *who, uint64_t stampsec, uint64_t stamp_nsec,
259 uint64_t seq, const char *level,
260 const char *msg) {
261 Log *l = static_cast<Log *>(arg);
262 Mutex::Locker locker(l->lock);
263 l->log.push_back(line);
264 l->cond.Signal();
265 cout << "got: " << line << std::endl;
266 }
267
268 TEST(LibRadosCmd, WatchLog) {
269 rados_t cluster;
270 ASSERT_EQ("", connect_cluster(&cluster));
271 char *buf, *st;
272 char *cmd[2];
273 cmd[1] = NULL;
274 size_t buflen, stlen;
275 Log l;
276
277 ASSERT_EQ(0, rados_monitor_log(cluster, "info", log_cb, &l));
278 cmd[0] = (char *)"{\"prefix\":\"log\", \"logtext\":[\"onexx\"]}";
279 ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
280 for (int i=0; !l.contains("onexx"); i++) {
281 ASSERT_TRUE(i<100);
282 sleep(1);
283 }
284 ASSERT_TRUE(l.contains("onexx"));
285
286 cmd[0] = (char *)"{\"prefix\":\"log\", \"logtext\":[\"twoxx\"]}";
287 ASSERT_EQ(0, rados_monitor_log(cluster, "err", log_cb, &l));
288 ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
289 sleep(2);
290 ASSERT_FALSE(l.contains("twoxx"));
291
292 ASSERT_EQ(0, rados_monitor_log(cluster, "info", log_cb, &l));
293 cmd[0] = (char *)"{\"prefix\":\"log\", \"logtext\":[\"threexx\"]}";
294 ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
295 for (int i=0; !l.contains("threexx"); i++) {
296 ASSERT_TRUE(i<100);
297 sleep(1);
298 }
299
300 ASSERT_EQ(0, rados_monitor_log(cluster, "info", NULL, NULL));
301 cmd[0] = (char *)"{\"prefix\":\"log\", \"logtext\":[\"fourxx\"]}";
302 ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0, &buf, &buflen, &st, &stlen));
303 sleep(2);
304 ASSERT_FALSE(l.contains("fourxx"));
305 rados_shutdown(cluster);
306 }