]>
Commit | Line | Data |
---|---|---|
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) 2014 Cloudwatt <libre.licensing@cloudwatt.com> | |
7 | * | |
8 | * Author: Loic Dachary <loic@dachary.org> | |
9 | * | |
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) | |
13 | * any later version. | |
14 | * | |
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. | |
19 | * | |
20 | * | |
21 | */ | |
22 | #include "common/config.h" | |
23 | #include "common/errno.h" | |
24 | #include "gtest/gtest.h" | |
25 | ||
26 | extern std::string exec(const char* cmd); // defined in test_hostname.cc | |
27 | ||
28 | class test_md_config_t : public md_config_t, public ::testing::Test { | |
29 | public: | |
30 | void test_expand_meta() { | |
31 | Mutex::Locker l(lock); | |
32 | // successfull meta expansion $run_dir and ${run_dir} | |
33 | { | |
34 | ostringstream oss; | |
35 | std::string before = " BEFORE "; | |
36 | std::string after = " AFTER "; | |
37 | std::string val(before + "$run_dir${run_dir}" + after); | |
38 | EXPECT_TRUE(expand_meta(val, &oss)); | |
39 | EXPECT_EQ(before + "/var/run/ceph/var/run/ceph" + after, val); | |
40 | EXPECT_EQ("", oss.str()); | |
41 | } | |
42 | { | |
43 | ostringstream oss; | |
44 | std::string before = " BEFORE "; | |
45 | std::string after = " AFTER "; | |
46 | std::string val(before + "$host${host}" + after); | |
47 | EXPECT_TRUE(expand_meta(val, &oss)); | |
48 | std::string hostname = exec("hostname -s"); | |
49 | EXPECT_EQ(before + hostname + hostname + after, val); | |
50 | EXPECT_EQ("", oss.str()); | |
51 | } | |
52 | // no meta expansion if variables are unknown | |
53 | { | |
54 | ostringstream oss; | |
55 | std::string expected = "expect $foo and ${bar} to not expand"; | |
56 | std::string val = expected; | |
57 | EXPECT_FALSE(expand_meta(val, &oss)); | |
58 | EXPECT_EQ(expected, val); | |
59 | EXPECT_EQ("", oss.str()); | |
60 | } | |
61 | // recursive variable expansion | |
62 | { | |
63 | std::string host = "localhost"; | |
64 | EXPECT_EQ(0, set_val("host", host.c_str(), false)); | |
65 | ||
66 | std::string mon_host = "$cluster_network"; | |
67 | EXPECT_EQ(0, set_val("mon_host", mon_host.c_str(), false)); | |
68 | ||
69 | std::string lockdep = "true"; | |
70 | EXPECT_EQ(0, set_val("lockdep", lockdep.c_str(), false)); | |
71 | ||
72 | std::string cluster_network = "$public_network $public_network $lockdep $host"; | |
73 | EXPECT_EQ(0, set_val("cluster_network", cluster_network.c_str(), false)); | |
74 | ||
75 | std::string public_network = "NETWORK"; | |
76 | EXPECT_EQ(0, set_val("public_network", public_network.c_str(), false)); | |
77 | ||
78 | ostringstream oss; | |
79 | std::string val = "$mon_host"; | |
80 | EXPECT_TRUE(expand_meta(val, &oss)); | |
81 | EXPECT_EQ(public_network + " " + | |
82 | public_network + " " + | |
83 | lockdep + " " + | |
84 | "localhost", val); | |
85 | EXPECT_EQ("", oss.str()); | |
86 | } | |
87 | // variable expansion loops are non fatal | |
88 | { | |
89 | std::string mon_host = "$cluster_network"; | |
90 | EXPECT_EQ(0, set_val("mon_host", mon_host.c_str(), false)); | |
91 | ||
92 | std::string cluster_network = "$public_network"; | |
93 | EXPECT_EQ(0, set_val("cluster_network", cluster_network.c_str(), false)); | |
94 | ||
95 | std::string public_network = "$mon_host"; | |
96 | EXPECT_EQ(0, set_val("public_network", public_network.c_str(), false)); | |
97 | ||
98 | ostringstream oss; | |
99 | std::string val = "$mon_host"; | |
100 | EXPECT_TRUE(expand_meta(val, &oss)); | |
101 | EXPECT_EQ("$cluster_network", val); | |
102 | const char *expected_oss = | |
103 | "variable expansion loop at mon_host=$cluster_network\n" | |
104 | "expansion stack: \n" | |
105 | "public_network=$mon_host\n" | |
106 | "cluster_network=$public_network\n" | |
107 | "mon_host=$cluster_network\n"; | |
108 | EXPECT_EQ(expected_oss, oss.str()); | |
109 | } | |
110 | } | |
111 | ||
112 | void test_expand_all_meta() { | |
113 | Mutex::Locker l(lock); | |
114 | int before_count = 0, data_dir = 0; | |
115 | for (auto& opt: *config_options) { | |
116 | std::string *str; | |
117 | opt.conf_ptr(str, this); | |
118 | if (str) { | |
119 | if (str->find("$") != string::npos) | |
120 | before_count++; | |
121 | if (str->find("$data_dir") != string::npos) | |
122 | data_dir++; | |
123 | } | |
124 | } | |
125 | // if there are no meta variables in the default configuration, | |
126 | // something must be done to check the expected side effect | |
127 | // of expand_all_meta | |
128 | ASSERT_LT(0, before_count); | |
129 | expand_all_meta(); | |
130 | int after_count = 0; | |
131 | for (auto& opt: *config_options) { | |
132 | std::string *str; | |
133 | opt.conf_ptr(str, this); | |
134 | if (str) { | |
135 | size_t pos = 0; | |
136 | while ((pos = str->find("$", pos)) != string::npos) { | |
137 | if (str->substr(pos, 8) != "$channel") { | |
138 | std::cout << "unexpected meta-variable found at pos " << pos | |
139 | << " of '" << *str << "'" << std::endl; | |
140 | after_count++; | |
141 | } | |
142 | pos++; | |
143 | } | |
144 | } | |
145 | } | |
146 | ASSERT_EQ(data_dir, after_count); | |
147 | } | |
148 | }; | |
149 | ||
150 | TEST_F(test_md_config_t, expand_meta) | |
151 | { | |
152 | test_expand_meta(); | |
153 | } | |
154 | ||
155 | TEST_F(test_md_config_t, expand_all_meta) | |
156 | { | |
157 | test_expand_all_meta(); | |
158 | } | |
159 | ||
160 | TEST(md_config_t, set_val) | |
161 | { | |
162 | int buf_size = 1024; | |
163 | md_config_t conf; | |
164 | // disable meta variable expansion | |
165 | { | |
166 | char *buf = (char*)malloc(buf_size); | |
167 | std::string expected = "$host"; | |
168 | EXPECT_EQ(0, conf.set_val("mon_host", expected.c_str(), false)); | |
169 | EXPECT_EQ(0, conf.get_val("mon_host", &buf, buf_size)); | |
170 | EXPECT_EQ(expected, buf); | |
171 | free(buf); | |
172 | } | |
173 | // meta variable expansion is enabled by default | |
174 | { | |
175 | char *run_dir = (char*)malloc(buf_size); | |
176 | EXPECT_EQ(0, conf.get_val("run_dir", &run_dir, buf_size)); | |
177 | EXPECT_EQ(0, conf.set_val("admin_socket", "$run_dir")); | |
178 | char *admin_socket = (char*)malloc(buf_size); | |
179 | EXPECT_EQ(0, conf.get_val("admin_socket", &admin_socket, buf_size)); | |
180 | EXPECT_EQ(std::string(run_dir), std::string(admin_socket)); | |
181 | free(run_dir); | |
182 | free(admin_socket); | |
183 | } | |
184 | } | |
185 | ||
186 | /* | |
187 | * Local Variables: | |
188 | * compile-command: "cd ../.. ; | |
189 | * make unittest_config && | |
190 | * valgrind \ | |
191 | * --max-stackframe=20000000 --tool=memcheck \ | |
192 | * ./unittest_config # --gtest_filter=md_config_t.set_val | |
193 | * " | |
194 | * End: | |
195 | */ |