]>
git.proxmox.com Git - ceph.git/blob - ceph/src/test/common/test_config.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2014 Cloudwatt <libre.licensing@cloudwatt.com>
8 * Author: Loic Dachary <loic@dachary.org>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU Library Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU Library Public License for more details.
22 #include "common/config.h"
23 #include "common/errno.h"
24 #include "gtest/gtest.h"
25 #include "common/hostname.h"
27 extern std::string
exec(const char* cmd
); // defined in test_hostname.cc
29 class test_md_config_t
: public md_config_t
, public ::testing::Test
{
33 : md_config_t(true), Test()
36 void test_expand_meta() {
37 Mutex::Locker
l(lock
);
38 // successfull meta expansion $run_dir and ${run_dir}
41 std::string before
= " BEFORE ";
42 std::string after
= " AFTER ";
44 std::string
val(before
+ "$run_dir${run_dir}" + after
);
45 EXPECT_TRUE(expand_meta(val
, &oss
));
46 EXPECT_EQ(before
+ "/var/run/ceph/var/run/ceph" + after
, val
);
47 EXPECT_EQ("", oss
.str());
51 std::string before
= " BEFORE ";
52 std::string after
= " AFTER ";
53 std::string
val(before
+ "$host${host}" + after
);
54 EXPECT_TRUE(expand_meta(val
, &oss
));
55 std::string hostname
= ceph_get_short_hostname();
56 EXPECT_EQ(before
+ hostname
+ hostname
+ after
, val
);
57 EXPECT_EQ("", oss
.str());
59 // no meta expansion if variables are unknown
62 std::string expected
= "expect $foo and ${bar} to not expand";
63 std::string val
= expected
;
64 EXPECT_FALSE(expand_meta(val
, &oss
));
65 EXPECT_EQ(expected
, val
);
66 EXPECT_EQ("", oss
.str());
68 // recursive variable expansion
70 std::string host
= "localhost";
71 EXPECT_EQ(0, set_val("host", host
.c_str(), false));
73 std::string mon_host
= "$cluster_network";
74 EXPECT_EQ(0, set_val("mon_host", mon_host
.c_str(), false));
76 std::string lockdep
= "true";
77 EXPECT_EQ(0, set_val("lockdep", lockdep
.c_str(), false));
79 std::string cluster_network
= "$public_network $public_network $lockdep $host";
80 EXPECT_EQ(0, set_val("cluster_network", cluster_network
.c_str(), false));
82 std::string public_network
= "NETWORK";
83 EXPECT_EQ(0, set_val("public_network", public_network
.c_str(), false));
86 std::string val
= "$mon_host";
87 EXPECT_TRUE(expand_meta(val
, &oss
));
88 EXPECT_EQ(public_network
+ " " +
89 public_network
+ " " +
92 EXPECT_EQ("", oss
.str());
94 // variable expansion loops are non fatal
96 std::string mon_host
= "$cluster_network";
97 EXPECT_EQ(0, set_val("mon_host", mon_host
.c_str(), false));
99 std::string cluster_network
= "$public_network";
100 EXPECT_EQ(0, set_val("cluster_network", cluster_network
.c_str(), false));
102 std::string public_network
= "$mon_host";
103 EXPECT_EQ(0, set_val("public_network", public_network
.c_str(), false));
106 std::string val
= "$mon_host";
107 EXPECT_TRUE(expand_meta(val
, &oss
));
108 EXPECT_EQ("$cluster_network", val
);
109 const char *expected_oss
=
110 "variable expansion loop at mon_host=$cluster_network\n"
111 "expansion stack: \n"
112 "public_network=$mon_host\n"
113 "cluster_network=$public_network\n"
114 "mon_host=$cluster_network\n";
115 EXPECT_EQ(expected_oss
, oss
.str());
119 void test_expand_all_meta() {
120 Mutex::Locker
l(lock
);
121 int before_count
= 0, data_dir
= 0;
122 for (const auto &i
: schema
) {
123 const Option
&opt
= i
.second
;
124 if (opt
.type
== Option::TYPE_STR
) {
125 const auto &str
= boost::get
<std::string
>(opt
.value
);
126 if (str
.find("$") != string::npos
)
128 if (str
.find("$data_dir") != string::npos
)
133 // if there are no meta variables in the default configuration,
134 // something must be done to check the expected side effect
135 // of expand_all_meta
136 ASSERT_LT(0, before_count
);
139 for (auto& i
: values
) {
140 const auto &opt
= schema
.at(i
.first
);
141 if (opt
.type
== Option::TYPE_STR
) {
142 const std::string
&str
= boost::get
<std::string
>(i
.second
);
144 while ((pos
= str
.find("$", pos
)) != string::npos
) {
145 if (str
.substr(pos
, 8) != "$channel") {
146 std::cout
<< "unexpected meta-variable found at pos " << pos
147 << " of '" << str
<< "'" << std::endl
;
154 ASSERT_EQ(data_dir
, after_count
);
158 TEST_F(test_md_config_t
, expand_meta
)
163 TEST_F(test_md_config_t
, expand_all_meta
)
165 test_expand_all_meta();
168 TEST(md_config_t
, set_val
)
172 // disable meta variable expansion
174 char *buf
= (char*)malloc(buf_size
);
175 std::string expected
= "$host";
176 EXPECT_EQ(0, conf
.set_val("mon_host", expected
.c_str(), false));
177 EXPECT_EQ(0, conf
.get_val("mon_host", &buf
, buf_size
));
178 EXPECT_EQ(expected
, buf
);
181 // meta variable expansion is enabled by default
183 char *run_dir
= (char*)malloc(buf_size
);
184 EXPECT_EQ(0, conf
.get_val("run_dir", &run_dir
, buf_size
));
185 EXPECT_EQ(0, conf
.set_val("admin_socket", "$run_dir"));
186 char *admin_socket
= (char*)malloc(buf_size
);
187 EXPECT_EQ(0, conf
.get_val("admin_socket", &admin_socket
, buf_size
));
188 EXPECT_EQ(std::string(run_dir
), std::string(admin_socket
));
194 TEST(Option
, validation
)
196 Option
opt_int("foo", Option::TYPE_INT
, Option::LEVEL_BASIC
);
197 opt_int
.set_min_max(5, 10);
200 EXPECT_EQ(-EINVAL
, opt_int
.validate(Option::value_t(int64_t(4)), &msg
));
201 EXPECT_EQ(-EINVAL
, opt_int
.validate(Option::value_t(int64_t(11)), &msg
));
202 EXPECT_EQ(0, opt_int
.validate(Option::value_t(int64_t(7)), &msg
));
204 Option
opt_enum("foo", Option::TYPE_STR
, Option::LEVEL_BASIC
);
205 opt_enum
.set_enum_allowed({"red", "blue"});
206 EXPECT_EQ(0, opt_enum
.validate(Option::value_t(std::string("red")), &msg
));
207 EXPECT_EQ(0, opt_enum
.validate(Option::value_t(std::string("blue")), &msg
));
208 EXPECT_EQ(-EINVAL
, opt_enum
.validate(Option::value_t(std::string("green")), &msg
));
210 Option
opt_validator("foo", Option::TYPE_INT
, Option::LEVEL_BASIC
);
211 opt_validator
.set_validator([](std::string
*value
, std::string
*error_message
){
212 if (*value
== std::string("one")) {
215 } else if (*value
== std::string("666")) {
222 std::string input
= "666"; // An explicitly forbidden value
223 EXPECT_EQ(-EINVAL
, opt_validator
.pre_validate(&input
, &msg
));
224 EXPECT_EQ(input
, "666");
226 input
= "123"; // A permitted value with no special behaviour
227 EXPECT_EQ(0, opt_validator
.pre_validate(&input
, &msg
));
228 EXPECT_EQ(input
, "123");
230 input
= "one"; // A value that has a magic conversion
231 EXPECT_EQ(0, opt_validator
.pre_validate(&input
, &msg
));
232 EXPECT_EQ(input
, "1");
237 * compile-command: "cd ../.. ;
238 * make unittest_config &&
240 * --max-stackframe=20000000 --tool=memcheck \
241 * ./unittest_config # --gtest_filter=md_config_t.set_val