]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/daemon_config.cc
update sources to v12.1.2
[ceph.git] / ceph / src / test / daemon_config.cc
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2011 New Dream Network
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15#include "gtest/gtest.h"
16#include "common/ceph_argparse.h"
17#include "common/config.h"
18#include "global/global_context.h"
19#include "include/cephfs/libcephfs.h"
20#include "include/rados/librados.h"
21
22#include <errno.h>
23#include <sstream>
24#include <string>
25#include <string.h>
26
27#include <boost/lexical_cast.hpp>
28
29
30using std::string;
31
32TEST(DaemonConfig, SimpleSet) {
33 int ret;
c07f9fc5 34 ret = g_ceph_context->_conf->set_val("log_graylog_port", "21");
7c673cae
FG
35 ASSERT_EQ(ret, 0);
36 g_ceph_context->_conf->apply_changes(NULL);
37 char buf[128];
38 memset(buf, 0, sizeof(buf));
39 char *tmp = buf;
c07f9fc5 40 ret = g_ceph_context->_conf->get_val("log_graylog_port", &tmp, sizeof(buf));
7c673cae
FG
41 ASSERT_EQ(ret, 0);
42 ASSERT_EQ(string("21"), string(buf));
43}
44
45TEST(DaemonConfig, Substitution) {
46 int ret;
47 ret = g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false");
48 ASSERT_EQ(ret, 0);
49 ret = g_ceph_context->_conf->set_val("host", "foo");
50 ASSERT_EQ(ret, 0);
51 ret = g_ceph_context->_conf->set_val("public_network", "bar$host.baz", false);
52 ASSERT_EQ(ret, 0);
53 g_ceph_context->_conf->apply_changes(NULL);
54 char buf[128];
55 memset(buf, 0, sizeof(buf));
56 char *tmp = buf;
57 ret = g_ceph_context->_conf->get_val("public_network", &tmp, sizeof(buf));
58 ASSERT_EQ(ret, 0);
59 ASSERT_EQ(string("barfoo.baz"), string(buf));
60}
61
62TEST(DaemonConfig, SubstitutionTrailing) {
63 int ret;
64 ret = g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false");
65 ASSERT_EQ(ret, 0);
66 ret = g_ceph_context->_conf->set_val("host", "foo");
67 ASSERT_EQ(ret, 0);
68 ret = g_ceph_context->_conf->set_val("public_network", "bar$host", false);
69 ASSERT_EQ(ret, 0);
70 g_ceph_context->_conf->apply_changes(NULL);
71 char buf[128];
72 memset(buf, 0, sizeof(buf));
73 char *tmp = buf;
74 ret = g_ceph_context->_conf->get_val("public_network", &tmp, sizeof(buf));
75 ASSERT_EQ(ret, 0);
76 ASSERT_EQ(string("barfoo"), string(buf));
77}
78
79TEST(DaemonConfig, SubstitutionBraces) {
80 int ret;
81 ret = g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false");
82 ASSERT_EQ(ret, 0);
83 ret = g_ceph_context->_conf->set_val("host", "foo");
84 ASSERT_EQ(ret, 0);
85 ret = g_ceph_context->_conf->set_val("public_network", "bar${host}baz", false);
86 ASSERT_EQ(ret, 0);
87 g_ceph_context->_conf->apply_changes(NULL);
88 char buf[128];
89 memset(buf, 0, sizeof(buf));
90 char *tmp = buf;
91 ret = g_ceph_context->_conf->get_val("public_network", &tmp, sizeof(buf));
92 ASSERT_EQ(ret, 0);
93 ASSERT_EQ(string("barfoobaz"), string(buf));
94}
95TEST(DaemonConfig, SubstitutionBracesTrailing) {
96 int ret;
97 ret = g_ceph_context->_conf->set_val("internal_safe_to_start_threads", "false");
98 ASSERT_EQ(ret, 0);
99 ret = g_ceph_context->_conf->set_val("host", "foo");
100 ASSERT_EQ(ret, 0);
101 ret = g_ceph_context->_conf->set_val("public_network", "bar${host}", false);
102 ASSERT_EQ(ret, 0);
103 g_ceph_context->_conf->apply_changes(NULL);
104 char buf[128];
105 memset(buf, 0, sizeof(buf));
106 char *tmp = buf;
107 ret = g_ceph_context->_conf->get_val("public_network", &tmp, sizeof(buf));
108 ASSERT_EQ(ret, 0);
109 ASSERT_EQ(string("barfoo"), string(buf));
110}
111
112// config: variable substitution happen only once http://tracker.ceph.com/issues/7103
113TEST(DaemonConfig, SubstitutionMultiple) {
114 int ret;
115 ret = g_ceph_context->_conf->set_val("mon_host", "localhost", false);
116 ASSERT_EQ(ret, 0);
117 ret = g_ceph_context->_conf->set_val("keyring", "$mon_host/$cluster.keyring,$mon_host/$cluster.mon.keyring", false);
118 ASSERT_EQ(ret, 0);
119 g_ceph_context->_conf->apply_changes(NULL);
120 char buf[512];
121 memset(buf, 0, sizeof(buf));
122 char *tmp = buf;
123 ret = g_ceph_context->_conf->get_val("keyring", &tmp, sizeof(buf));
124 ASSERT_EQ(ret, 0);
125 ASSERT_EQ(string("localhost/ceph.keyring,localhost/ceph.mon.keyring"), tmp);
126 ASSERT_TRUE(strchr(buf, '$') == NULL);
127}
128
129TEST(DaemonConfig, ArgV) {
130 ASSERT_EQ(0, g_ceph_context->_conf->set_val("internal_safe_to_start_threads",
131 "false"));
132
133 int ret;
c07f9fc5 134 const char *argv[] = { "foo", "--log-graylog-port", "22",
7c673cae
FG
135 "--keyfile", "/tmp/my-keyfile", NULL };
136 size_t argc = (sizeof(argv) / sizeof(argv[0])) - 1;
137 vector<const char*> args;
138 argv_to_vec(argc, argv, args);
139 g_ceph_context->_conf->parse_argv(args);
140 g_ceph_context->_conf->apply_changes(NULL);
141
142 char buf[128];
143 char *tmp = buf;
144 memset(buf, 0, sizeof(buf));
145 ret = g_ceph_context->_conf->get_val("keyfile", &tmp, sizeof(buf));
146 ASSERT_EQ(ret, 0);
147 ASSERT_EQ(string("/tmp/my-keyfile"), string(buf));
148
149 memset(buf, 0, sizeof(buf));
c07f9fc5 150 ret = g_ceph_context->_conf->get_val("log_graylog_port", &tmp, sizeof(buf));
7c673cae
FG
151 ASSERT_EQ(ret, 0);
152 ASSERT_EQ(string("22"), string(buf));
153
154 ASSERT_EQ(0, g_ceph_context->_conf->set_val("internal_safe_to_start_threads",
155 "true"));
156}
157
158TEST(DaemonConfig, InjectArgs) {
159 int ret;
c07f9fc5 160 std::string injection("--log-graylog-port 56 --leveldb-max-open-files 42");
7c673cae
FG
161 ret = g_ceph_context->_conf->injectargs(injection, &cout);
162 ASSERT_EQ(ret, 0);
163
164 char buf[128];
165 char *tmp = buf;
166 memset(buf, 0, sizeof(buf));
c07f9fc5 167 ret = g_ceph_context->_conf->get_val("leveldb_max_open_files", &tmp, sizeof(buf));
7c673cae
FG
168 ASSERT_EQ(ret, 0);
169 ASSERT_EQ(string("42"), string(buf));
170
171 memset(buf, 0, sizeof(buf));
c07f9fc5 172 ret = g_ceph_context->_conf->get_val("log_graylog_port", &tmp, sizeof(buf));
7c673cae
FG
173 ASSERT_EQ(ret, 0);
174 ASSERT_EQ(string("56"), string(buf));
175
c07f9fc5 176 injection = "--log-graylog-port 57";
7c673cae
FG
177 ret = g_ceph_context->_conf->injectargs(injection, &cout);
178 ASSERT_EQ(ret, 0);
c07f9fc5 179 ret = g_ceph_context->_conf->get_val("log_graylog_port", &tmp, sizeof(buf));
7c673cae
FG
180 ASSERT_EQ(ret, 0);
181 ASSERT_EQ(string("57"), string(buf));
182}
183
184TEST(DaemonConfig, InjectArgsReject) {
185 int ret;
186 char buf[128];
187 char *tmp = buf;
188 char buf2[128];
189 char *tmp2 = buf2;
190
191 // We should complain about the garbage in the input
c07f9fc5 192 std::string injection("--random-garbage-in-injectargs 26 --log-graylog-port 28");
7c673cae
FG
193 ret = g_ceph_context->_conf->injectargs(injection, &cout);
194 ASSERT_EQ(ret, -EINVAL);
195
196 // But, debug should still be set...
197 memset(buf, 0, sizeof(buf));
c07f9fc5 198 ret = g_ceph_context->_conf->get_val("log_graylog_port", &tmp, sizeof(buf));
7c673cae
FG
199 ASSERT_EQ(ret, 0);
200 ASSERT_EQ(string("28"), string(buf));
201
202 // What's the current value of osd_data?
203 memset(buf, 0, sizeof(buf));
204 ret = g_ceph_context->_conf->get_val("osd_data", &tmp, sizeof(buf));
205 ASSERT_EQ(ret, 0);
206
207 // Injectargs shouldn't let us change this, since it is a string-valued
208 // variable and there isn't an observer for it.
c07f9fc5 209 std::string injection2("--osd_data /tmp/some-other-directory --log-graylog-port 4");
7c673cae
FG
210 ret = g_ceph_context->_conf->injectargs(injection2, &cout);
211 ASSERT_EQ(ret, -ENOSYS);
212
213 // It should be unchanged.
214 memset(buf2, 0, sizeof(buf2));
215 ret = g_ceph_context->_conf->get_val("osd_data", &tmp2, sizeof(buf2));
216 ASSERT_EQ(ret, 0);
217 ASSERT_EQ(string(buf), string(buf2));
218}
219
220TEST(DaemonConfig, InjectArgsBooleans) {
221 int ret;
222 char buf[128];
223 char *tmp = buf;
224
225 // Change log_to_syslog
c07f9fc5 226 std::string injection("--log_to_syslog --log-graylog-port 28");
7c673cae
FG
227 ret = g_ceph_context->_conf->injectargs(injection, &cout);
228 ASSERT_EQ(ret, 0);
229
230 // log_to_syslog should be set...
231 memset(buf, 0, sizeof(buf));
232 ret = g_ceph_context->_conf->get_val("log_to_syslog", &tmp, sizeof(buf));
233 ASSERT_EQ(ret, 0);
234 ASSERT_EQ(string("true"), string(buf));
235
236 // Turn off log_to_syslog
c07f9fc5 237 injection = "--log_to_syslog=false --log-graylog-port 28";
7c673cae
FG
238 ret = g_ceph_context->_conf->injectargs(injection, &cout);
239 ASSERT_EQ(ret, 0);
240
241 // log_to_syslog should be cleared...
242 memset(buf, 0, sizeof(buf));
243 ret = g_ceph_context->_conf->get_val("log_to_syslog", &tmp, sizeof(buf));
244 ASSERT_EQ(ret, 0);
245 ASSERT_EQ(string("false"), string(buf));
246
247 // Turn on log_to_syslog
c07f9fc5 248 injection = "--log-graylog-port=1 --log_to_syslog=true --leveldb-max-open-files 40";
7c673cae
FG
249 ret = g_ceph_context->_conf->injectargs(injection, &cout);
250 ASSERT_EQ(ret, 0);
251
252 // log_to_syslog should be set...
253 memset(buf, 0, sizeof(buf));
254 ret = g_ceph_context->_conf->get_val("log_to_syslog", &tmp, sizeof(buf));
255 ASSERT_EQ(ret, 0);
256 ASSERT_EQ(string("true"), string(buf));
257
258 // parse error
c07f9fc5 259 injection = "--log-graylog-port 1 --log_to_syslog=falsey --leveldb-max-open-files 42";
7c673cae
FG
260 ret = g_ceph_context->_conf->injectargs(injection, &cout);
261 ASSERT_EQ(ret, -EINVAL);
262
263 // log_to_syslog should still be set...
264 memset(buf, 0, sizeof(buf));
265 ret = g_ceph_context->_conf->get_val("log_to_syslog", &tmp, sizeof(buf));
266 ASSERT_EQ(ret, 0);
267 ASSERT_EQ(string("true"), string(buf));
268
269 // debug-ms should still become 42...
270 memset(buf, 0, sizeof(buf));
c07f9fc5 271 ret = g_ceph_context->_conf->get_val("leveldb_max_open_files", &tmp, sizeof(buf));
7c673cae
FG
272 ASSERT_EQ(ret, 0);
273 ASSERT_EQ(string("42"), string(buf));
274}
275
276TEST(DaemonConfig, InjectArgsLogfile) {
277 int ret;
278 char tmpfile[PATH_MAX];
279 const char *tmpdir = getenv("TMPDIR");
280 if (!tmpdir)
281 tmpdir = "/tmp";
282 snprintf(tmpfile, sizeof(tmpfile), "%s/daemon_config_test.%d",
283 tmpdir, getpid());
284 std::string injection("--log_file ");
285 injection += tmpfile;
286 // We're allowed to change log_file because there is an observer.
287 ret = g_ceph_context->_conf->injectargs(injection, &cout);
288 ASSERT_EQ(ret, 0);
289
290 // It should have taken effect.
291 char buf[128];
292 char *tmp = buf;
293 memset(buf, 0, sizeof(buf));
294 ret = g_ceph_context->_conf->get_val("log_file", &tmp, sizeof(buf));
295 ASSERT_EQ(ret, 0);
296 ASSERT_EQ(string(buf), string(tmpfile));
297
298 // The logfile should exist.
299 ASSERT_EQ(access(tmpfile, R_OK), 0);
300
301 // Let's turn off the logfile.
302 ret = g_ceph_context->_conf->set_val("log_file", "");
303 ASSERT_EQ(ret, 0);
304 g_ceph_context->_conf->apply_changes(NULL);
305 ret = g_ceph_context->_conf->get_val("log_file", &tmp, sizeof(buf));
306 ASSERT_EQ(ret, 0);
307 ASSERT_EQ(string(""), string(buf));
308
309 // Clean up the garbage
310 unlink(tmpfile);
311}
312
313TEST(DaemonConfig, ThreadSafety1) {
314 int ret;
315 // Verify that we can't change this, since internal_safe_to_start_threads has
316 // been set.
317 ret = g_ceph_context->_conf->set_val("osd_data", "");
318 ASSERT_EQ(ret, -ENOSYS);
319
320 ASSERT_EQ(0, g_ceph_context->_conf->set_val("internal_safe_to_start_threads",
321 "false"));
322
323 // Ok, now we can change this. Since this is just a test, and there are no
324 // OSD threads running, we know changing osd_data won't actually blow up the
325 // world.
326 ret = g_ceph_context->_conf->set_val("osd_data", "/tmp/crazydata");
327 ASSERT_EQ(ret, 0);
328
329 char buf[128];
330 char *tmp = buf;
331 memset(buf, 0, sizeof(buf));
332 ret = g_ceph_context->_conf->get_val("osd_data", &tmp, sizeof(buf));
333 ASSERT_EQ(ret, 0);
334 ASSERT_EQ(string("/tmp/crazydata"), string(buf));
335
336 ASSERT_EQ(0, g_ceph_context->_conf->set_val("internal_safe_to_start_threads",
337 "false"));
338 ASSERT_EQ(ret, 0);
339}
340
341TEST(DaemonConfig, InvalidIntegers) {
342 {
c07f9fc5 343 int ret = g_ceph_context->_conf->set_val("log_graylog_port", "rhubarb");
7c673cae
FG
344 ASSERT_EQ(ret, -EINVAL);
345 }
c07f9fc5 346
7c673cae 347 {
c07f9fc5
FG
348 int64_t max = std::numeric_limits<int64_t>::max();
349 string str = boost::lexical_cast<string>(max);
350 str = str + "999"; // some extra digits to take us out of bounds
351 int ret = g_ceph_context->_conf->set_val("log_graylog_port", str);
7c673cae
FG
352 ASSERT_EQ(ret, -EINVAL);
353 }
354}
355
356TEST(DaemonConfig, InvalidFloats) {
357 {
358 double bad_value = 2 * (double)std::numeric_limits<float>::max();
359 string str = boost::lexical_cast<string>(-bad_value);
360 int ret = g_ceph_context->_conf->set_val("log_stop_at_utilization", str);
361 ASSERT_EQ(ret, -EINVAL);
362 }
363 {
364 double bad_value = 2 * (double)std::numeric_limits<float>::max();
365 string str = boost::lexical_cast<string>(bad_value);
366 int ret = g_ceph_context->_conf->set_val("log_stop_at_utilization", str);
367 ASSERT_EQ(ret, -EINVAL);
368 }
369 {
370 int ret = g_ceph_context->_conf->set_val("log_stop_at_utilization", "not a float");
371 ASSERT_EQ(ret, -EINVAL);
372 }
373}
374
375/*
376 * Local Variables:
377 * compile-command: "cd .. ; make unittest_daemon_config && ./unittest_daemon_config"
378 * End:
379 */