]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/librados/test.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*
2 // vim: ts=8 sw=2 smarttab
4 #include "include/rados/librados.h"
5 #include "include/rados/librados.hpp"
6 #include "test/librados/test.h"
8 #include "include/stringify.h"
9 #include "common/ceph_context.h"
10 #include "common/config.h"
19 #include "gtest/gtest.h"
21 using namespace librados
;
23 std::string
get_temp_pool_name(const std::string
&prefix
)
27 memset(hostname
, 0, sizeof(hostname
));
28 memset(out
, 0, sizeof(out
));
29 gethostname(hostname
, sizeof(hostname
)-1);
31 snprintf(out
, sizeof(out
), "%s-%d-%d", hostname
, getpid(), num
);
37 std::string
create_one_pool(
38 const std::string
&pool_name
, rados_t
*cluster
, uint32_t pg_num
)
40 std::string err_str
= connect_cluster(cluster
);
44 int ret
= rados_pool_create(*cluster
, pool_name
.c_str());
46 rados_shutdown(*cluster
);
47 std::ostringstream oss
;
48 oss
<< "create_one_pool(" << pool_name
<< ") failed with error " << ret
;
55 int destroy_ec_profile(rados_t
*cluster
,
56 const std::string
& pool_name
,
60 snprintf(buf
, sizeof(buf
),
61 "{\"prefix\": \"osd erasure-code-profile rm\", \"name\": \"testprofile-%s\"}",
66 int ret
= rados_mon_command(*cluster
, (const char **)cmd
, 1, "", 0, NULL
,
69 oss
<< "rados_mon_command: erasure-code-profile rm testprofile-"
70 << pool_name
<< " failed with error " << ret
;
74 int destroy_ruleset(rados_t
*cluster
,
79 std::string tmp
= ("{\"prefix\": \"osd crush rule rm\", \"name\":\"" +
81 cmd
[0] = (char*)tmp
.c_str();
83 int ret
= rados_mon_command(*cluster
, (const char **)cmd
, 1, "", 0, NULL
, 0, NULL
, 0);
85 oss
<< "rados_mon_command: osd crush rule rm " + ruleset
+ " failed with error " << ret
;
89 int destroy_ec_profile_and_ruleset(rados_t
*cluster
,
94 ret
= destroy_ec_profile(cluster
, ruleset
, oss
);
97 return destroy_ruleset(cluster
, ruleset
, oss
);
101 std::string
create_one_ec_pool(const std::string
&pool_name
, rados_t
*cluster
)
103 std::string err
= connect_cluster(cluster
);
107 std::ostringstream oss
;
108 int ret
= destroy_ec_profile_and_ruleset(cluster
, pool_name
, oss
);
110 rados_shutdown(*cluster
);
117 std::string profile_create
= "{\"prefix\": \"osd erasure-code-profile set\", \"name\": \"testprofile-" + pool_name
+ "\", \"profile\": [ \"k=2\", \"m=1\", \"crush-failure-domain=osd\"]}";
118 cmd
[0] = (char *)profile_create
.c_str();
119 ret
= rados_mon_command(*cluster
, (const char **)cmd
, 1, "", 0, NULL
, 0, NULL
, 0);
121 rados_shutdown(*cluster
);
122 oss
<< "rados_mon_command erasure-code-profile set name:testprofile-" << pool_name
<< " failed with error " << ret
;
126 std::string cmdstr
= "{\"prefix\": \"osd pool create\", \"pool\": \"" +
127 pool_name
+ "\", \"pool_type\":\"erasure\", \"pg_num\":8, \"pgp_num\":8, \"erasure_code_profile\":\"testprofile-" + pool_name
+ "\"}";
128 cmd
[0] = (char *)cmdstr
.c_str();
129 ret
= rados_mon_command(*cluster
, (const char **)cmd
, 1, "", 0, NULL
, 0, NULL
, 0);
131 destroy_ec_profile(cluster
, pool_name
, oss
);
132 rados_shutdown(*cluster
);
133 oss
<< "rados_mon_command osd pool create failed with error " << ret
;
137 rados_wait_for_latest_osdmap(*cluster
);
141 std::string
create_one_pool_pp(const std::string
&pool_name
, Rados
&cluster
)
143 return create_one_pool_pp(pool_name
, cluster
, {});
145 std::string
create_one_pool_pp(const std::string
&pool_name
, Rados
&cluster
,
146 const std::map
<std::string
, std::string
> &config
)
148 std::string err
= connect_cluster_pp(cluster
, config
);
151 int ret
= cluster
.pool_create(pool_name
.c_str());
154 std::ostringstream oss
;
155 oss
<< "cluster.pool_create(" << pool_name
<< ") failed with error " << ret
;
161 int destroy_ruleset_pp(Rados
&cluster
,
166 int ret
= cluster
.mon_command("{\"prefix\": \"osd crush rule rm\", \"name\":\"" +
167 ruleset
+ "\"}", inbl
, NULL
, NULL
);
169 oss
<< "mon_command: osd crush rule rm " + ruleset
+ " failed with error " << ret
<< std::endl
;
173 int destroy_ec_profile_pp(Rados
&cluster
, const std::string
& pool_name
,
177 int ret
= cluster
.mon_command("{\"prefix\": \"osd erasure-code-profile rm\", \"name\": \"testprofile-" + pool_name
+ "\"}",
180 oss
<< "mon_command: osd erasure-code-profile rm testprofile-" << pool_name
<< " failed with error " << ret
<< std::endl
;
184 int destroy_ec_profile_and_ruleset_pp(Rados
&cluster
,
189 ret
= destroy_ec_profile_pp(cluster
, ruleset
, oss
);
192 return destroy_ruleset_pp(cluster
, ruleset
, oss
);
195 std::string
create_one_ec_pool_pp(const std::string
&pool_name
, Rados
&cluster
)
197 std::string err
= connect_cluster_pp(cluster
);
201 std::ostringstream oss
;
202 int ret
= destroy_ec_profile_and_ruleset_pp(cluster
, pool_name
, oss
);
209 ret
= cluster
.mon_command(
210 "{\"prefix\": \"osd erasure-code-profile set\", \"name\": \"testprofile-" + pool_name
+ "\", \"profile\": [ \"k=2\", \"m=1\", \"crush-failure-domain=osd\"]}",
214 oss
<< "mon_command erasure-code-profile set name:testprofile-" << pool_name
<< " failed with error " << ret
;
218 ret
= cluster
.mon_command(
219 "{\"prefix\": \"osd pool create\", \"pool\": \"" + pool_name
+ "\", \"pool_type\":\"erasure\", \"pg_num\":8, \"pgp_num\":8, \"erasure_code_profile\":\"testprofile-" + pool_name
+ "\"}",
223 destroy_ec_profile_pp(cluster
, pool_name
, oss
);
225 oss
<< "mon_command osd pool create pool:" << pool_name
<< " pool_type:erasure failed with error " << ret
;
229 cluster
.wait_for_latest_osdmap();
233 std::string
connect_cluster(rados_t
*cluster
)
235 char *id
= getenv("CEPH_CLIENT_ID");
236 if (id
) std::cerr
<< "Client id is: " << id
<< std::endl
;
239 ret
= rados_create(cluster
, NULL
);
241 std::ostringstream oss
;
242 oss
<< "rados_create failed with error " << ret
;
245 ret
= rados_conf_read_file(*cluster
, NULL
);
247 rados_shutdown(*cluster
);
248 std::ostringstream oss
;
249 oss
<< "rados_conf_read_file failed with error " << ret
;
252 rados_conf_parse_env(*cluster
, NULL
);
253 ret
= rados_connect(*cluster
);
255 rados_shutdown(*cluster
);
256 std::ostringstream oss
;
257 oss
<< "rados_connect failed with error " << ret
;
263 std::string
connect_cluster_pp(librados::Rados
&cluster
)
265 return connect_cluster_pp(cluster
, {});
268 std::string
connect_cluster_pp(librados::Rados
&cluster
,
269 const std::map
<std::string
, std::string
> &config
)
271 char *id
= getenv("CEPH_CLIENT_ID");
272 if (id
) std::cerr
<< "Client id is: " << id
<< std::endl
;
275 ret
= cluster
.init(id
);
277 std::ostringstream oss
;
278 oss
<< "cluster.init failed with error " << ret
;
281 ret
= cluster
.conf_read_file(NULL
);
284 std::ostringstream oss
;
285 oss
<< "cluster.conf_read_file failed with error " << ret
;
288 cluster
.conf_parse_env(NULL
);
290 for (auto &setting
: config
) {
291 ret
= cluster
.conf_set(setting
.first
.c_str(), setting
.second
.c_str());
293 std::ostringstream oss
;
294 oss
<< "failed to set config value " << setting
.first
<< " to '"
295 << setting
.second
<< "': " << strerror(-ret
);
300 ret
= cluster
.connect();
303 std::ostringstream oss
;
304 oss
<< "cluster.connect failed with error " << ret
;
310 int destroy_one_pool(const std::string
&pool_name
, rados_t
*cluster
)
312 int ret
= rados_pool_delete(*cluster
, pool_name
.c_str());
314 rados_shutdown(*cluster
);
317 rados_shutdown(*cluster
);
321 int destroy_one_ec_pool(const std::string
&pool_name
, rados_t
*cluster
)
323 int ret
= rados_pool_delete(*cluster
, pool_name
.c_str());
325 rados_shutdown(*cluster
);
329 CephContext
*cct
= static_cast<CephContext
*>(rados_cct(*cluster
));
330 if (!cct
->_conf
->mon_fake_pool_delete
) { // hope this is in [global]
331 std::ostringstream oss
;
332 ret
= destroy_ec_profile_and_ruleset(cluster
, pool_name
, oss
);
334 rados_shutdown(*cluster
);
339 rados_wait_for_latest_osdmap(*cluster
);
340 rados_shutdown(*cluster
);
344 int destroy_one_pool_pp(const std::string
&pool_name
, Rados
&cluster
)
346 int ret
= cluster
.pool_delete(pool_name
.c_str());
355 int destroy_one_ec_pool_pp(const std::string
&pool_name
, Rados
&cluster
)
357 int ret
= cluster
.pool_delete(pool_name
.c_str());
363 CephContext
*cct
= static_cast<CephContext
*>(cluster
.cct());
364 if (!cct
->_conf
->mon_fake_pool_delete
) { // hope this is in [global]
365 std::ostringstream oss
;
366 ret
= destroy_ec_profile_and_ruleset_pp(cluster
, pool_name
, oss
);
373 cluster
.wait_for_latest_osdmap();
378 void assert_eq_sparse(bufferlist
& expected
,
379 const std::map
<uint64_t, uint64_t>& extents
,
380 bufferlist
& actual
) {
381 auto i
= expected
.begin();
382 auto p
= actual
.begin();
384 for (auto extent
: extents
) {
385 const uint64_t start
= extent
.first
;
386 const uint64_t end
= start
+ extent
.second
;
387 for (; pos
< end
; ++i
, ++pos
) {
388 ASSERT_FALSE(i
.end());
399 ASSERT_EQ(expected
.length(), pos
);