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