]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/librados/service.cc
import quincy beta 17.1.0
[ceph.git] / ceph / src / test / librados / service.cc
CommitLineData
224ce89b
WB
1#include "include/rados/librados.h"
2#include "include/rados/librados.hpp"
11fdf7f2
TL
3#include "include/stringify.h"
4#include "common/config_proxy.h"
224ce89b
WB
5#include "test/librados/test.h"
6#include "test/librados/TestCase.h"
f67539c2 7#include <sys/resource.h>
224ce89b 8
f67539c2
TL
9#include <mutex>
10#include <condition_variable>
224ce89b 11#include <algorithm>
11fdf7f2 12#include <thread>
224ce89b
WB
13#include <errno.h>
14#include "gtest/gtest.h"
15#include "test/unit.cc"
16
20effc67 17using namespace std;
224ce89b
WB
18using namespace librados;
19
c07f9fc5
FG
20TEST(LibRadosService, RegisterEarly) {
21 rados_t cluster;
22 ASSERT_EQ(0, rados_create(&cluster, "admin"));
23 ASSERT_EQ(0, rados_conf_read_file(cluster, NULL));
24 ASSERT_EQ(0, rados_conf_parse_env(cluster, NULL));
25
26 string name = string("pid") + stringify(getpid());
27 ASSERT_EQ(0, rados_service_register(cluster, "laundry", name.c_str(),
28 "foo\0bar\0this\0that\0"));
29 ASSERT_EQ(-EEXIST, rados_service_register(cluster, "laundry", name.c_str(),
30 "foo\0bar\0this\0that\0"));
31
32 ASSERT_EQ(0, rados_connect(cluster));
33 sleep(5);
34 rados_shutdown(cluster);
35}
36
37TEST(LibRadosService, RegisterLate) {
38 rados_t cluster;
39 ASSERT_EQ(0, rados_create(&cluster, "admin"));
40 ASSERT_EQ(0, rados_conf_read_file(cluster, NULL));
41 ASSERT_EQ(0, rados_conf_parse_env(cluster, NULL));
42 ASSERT_EQ(0, rados_connect(cluster));
43
44 string name = string("pid") + stringify(getpid());
45 ASSERT_EQ(0, rados_service_register(cluster, "laundry", name.c_str(),
46 "foo\0bar\0this\0that\0"));
47 ASSERT_EQ(-EEXIST, rados_service_register(cluster, "laundry", name.c_str(),
48 "foo\0bar\0this\0that\0"));
49 rados_shutdown(cluster);
50}
51
f67539c2
TL
52static void status_format_func(const int i, std::mutex &lock,
53 std::condition_variable &cond,
54 int &threads_started, bool &stopped)
55{
56 rados_t cluster;
57 char *metadata_buf = NULL;
58
59 ASSERT_EQ(0, rados_create(&cluster, "admin"));
60 ASSERT_EQ(0, rados_conf_read_file(cluster, NULL));
61 ASSERT_EQ(0, rados_conf_parse_env(cluster, NULL));
62
63 ASSERT_EQ(0, rados_connect(cluster));
64 if (i == 0) {
65 ASSERT_NE(-1, asprintf(&metadata_buf, "%s%c%s%c",
66 "foo", '\0', "bar", '\0'));
67 } else if (i == 1) {
68 ASSERT_NE(-1, asprintf(&metadata_buf, "%s%c%s%c",
69 "daemon_type", '\0', "portal", '\0'));
70 } else if (i == 2) {
71 ASSERT_NE(-1, asprintf(&metadata_buf, "%s%c%s%c",
72 "daemon_prefix", '\0', "gateway", '\0'));
73 } else {
74 string prefix = string("gw") + stringify(i % 4);
75 string zone = string("z") + stringify(i % 3);
76 ASSERT_NE(-1, asprintf(&metadata_buf, "%s%c%s%c%s%c%s%c%s%c%s%c%s%c%s%c",
77 "daemon_type", '\0', "portal", '\0',
78 "daemon_prefix", '\0', prefix.c_str(), '\0',
79 "hostname", '\0', prefix.c_str(), '\0',
80 "zone_id", '\0', zone.c_str(), '\0'
81 ));
82 }
83 string name = string("rbd/image") + stringify(i);
84 ASSERT_EQ(0, rados_service_register(cluster, "foo", name.c_str(),
85 metadata_buf));
86
87 std::unique_lock<std::mutex> l(lock);
88 threads_started++;
89 cond.notify_all();
90 cond.wait(l, [&stopped] {
91 return stopped;
92 });
93
94 rados_shutdown(cluster);
95}
96
97TEST(LibRadosService, StatusFormat) {
98 const int nthreads = 16;
99 std::thread threads[nthreads];
100 std::mutex lock;
101 std::condition_variable cond;
102 bool stopped = false;
103 int threads_started = 0;
104
105 // Need a bunch of fd's for this test
106 struct rlimit rold, rnew;
107 ASSERT_EQ(getrlimit(RLIMIT_NOFILE, &rold), 0);
108 rnew = rold;
109 rnew.rlim_cur = rnew.rlim_max;
110 ASSERT_EQ(setrlimit(RLIMIT_NOFILE, &rnew), 0);
111
112 for (int i = 0; i < nthreads; ++i)
113 threads[i] = std::thread(status_format_func, i, std::ref(lock),
114 std::ref(cond), std::ref(threads_started),
115 std::ref(stopped));
116
117 {
118 std::unique_lock<std::mutex> l(lock);
522d829b 119 cond.wait(l, [&threads_started] {
f67539c2
TL
120 return nthreads == threads_started;
121 });
122 }
123
20effc67 124 int retry = 60; // mon thrashing may make this take a long time
f67539c2
TL
125 while (retry) {
126 rados_t cluster;
127
128 ASSERT_EQ(0, rados_create(&cluster, "admin"));
129 ASSERT_EQ(0, rados_conf_read_file(cluster, NULL));
130 ASSERT_EQ(0, rados_conf_parse_env(cluster, NULL));
131
132 ASSERT_EQ(0, rados_connect(cluster));
133 JSONFormatter cmd_f;
134 cmd_f.open_object_section("command");
135 cmd_f.dump_string("prefix", "status");
136 cmd_f.close_section();
137 std::ostringstream cmd_stream;
138 cmd_f.flush(cmd_stream);
139 const std::string serialized_cmd = cmd_stream.str();
140 const char *cmd[2];
141 cmd[1] = NULL;
142 cmd[0] = serialized_cmd.c_str();
143 char *outbuf = NULL;
144 size_t outlen = 0;
145 ASSERT_EQ(0, rados_mon_command(cluster, (const char **)cmd, 1, "", 0,
146 &outbuf, &outlen, NULL, NULL));
147 std::string out(outbuf, outlen);
148 cout << out << std::endl;
149 bool success = false;
150 auto r1 = out.find("16 portals active (1 hosts, 3 zones)");
151 if (std::string::npos != r1) {
152 success = true;
153 }
154 rados_buffer_free(outbuf);
155 rados_shutdown(cluster);
156
157 if (success || !retry) {
158 break;
159 }
160
161 // wait for 2 seconds to make sure all the
162 // services have been successfully updated
163 // to ceph mon, then retry it.
164 sleep(2);
165 retry--;
166 }
f67539c2
TL
167
168 {
169 std::scoped_lock<std::mutex> l(lock);
170 stopped = true;
171 cond.notify_all();
172 }
173 for (int i = 0; i < nthreads; ++i)
174 threads[i].join();
175
b3b6e05e 176 ASSERT_NE(0, retry);
f67539c2
TL
177 ASSERT_EQ(setrlimit(RLIMIT_NOFILE, &rold), 0);
178}
179
c07f9fc5
FG
180TEST(LibRadosService, Status) {
181 rados_t cluster;
182 ASSERT_EQ(0, rados_create(&cluster, "admin"));
183 ASSERT_EQ(0, rados_conf_read_file(cluster, NULL));
184 ASSERT_EQ(0, rados_conf_parse_env(cluster, NULL));
185
186 ASSERT_EQ(-ENOTCONN, rados_service_update_status(cluster,
187 "testing\0testing\0"));
188
189 ASSERT_EQ(0, rados_connect(cluster));
190 string name = string("pid") + stringify(getpid());
191 ASSERT_EQ(0, rados_service_register(cluster, "laundry", name.c_str(),
192 "foo\0bar\0this\0that\0"));
193
194 for (int i=0; i<20; ++i) {
195 char buffer[1024];
196 snprintf(buffer, sizeof(buffer), "%s%c%s%c%s%c%d%c",
197 "testing", '\0', "testing", '\0',
198 "count", '\0', i, '\0');
199 ASSERT_EQ(0, rados_service_update_status(cluster, buffer));
200 sleep(1);
201 }
202 rados_shutdown(cluster);
203}