]>
Commit | Line | Data |
---|---|---|
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 | 17 | using namespace std; |
224ce89b WB |
18 | using namespace librados; |
19 | ||
c07f9fc5 FG |
20 | TEST(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 | ||
37 | TEST(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 |
52 | static 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 | ||
97 | TEST(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 |
180 | TEST(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 | } |