Improve the process for GNU tools
[minix3.git] / external / bsd / kyua-cli / dist / cli / config_test.cpp
blobbf8c6aca9272edc2626b90062e0d106356ddef89
1 // Copyright 2011 Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 // may be used to endorse or promote products derived from this software
15 // without specific prior written permission.
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 #include "cli/config.hpp"
31 #include <atf-c++.hpp>
33 #include "engine/config.hpp"
34 #include "engine/exceptions.hpp"
35 #include "utils/env.hpp"
36 #include "utils/format/macros.hpp"
37 #include "utils/fs/operations.hpp"
38 #include "utils/fs/path.hpp"
40 namespace cmdline = utils::cmdline;
41 namespace config = utils::config;
42 namespace fs = utils::fs;
45 namespace {
48 /// Creates a configuration file for testing purposes.
49 ///
50 /// To ensure that the loaded file is the one created by this function, use
51 /// validate_mock_config().
52 ///
53 /// \param name The name of the configuration file to create.
54 /// \param cookie The magic value to set in the configuration file, or NULL if a
55 /// broken configuration file is desired.
56 static void
57 create_mock_config(const char* name, const char* cookie)
59 if (cookie != NULL) {
60 atf::utils::create_file(
61 name,
62 F("syntax(2)\n"
63 "test_suites.suite.magic_value = '%s'\n") % cookie);
64 } else {
65 atf::utils::create_file(name, "syntax(200)\n");
70 /// Creates an invalid system configuration.
71 ///
72 /// \param cookie The magic value to set in the configuration file, or NULL if a
73 /// broken configuration file is desired.
74 static void
75 mock_system_config(const char* cookie)
77 fs::mkdir(fs::path("system-dir"), 0755);
78 utils::setenv("KYUA_CONFDIR", (fs::current_path() / "system-dir").str());
79 create_mock_config("system-dir/kyua.conf", cookie);
83 /// Creates an invalid user configuration.
84 ///
85 /// \param cookie The magic value to set in the configuration file, or NULL if a
86 /// broken configuration file is desired.
87 static void
88 mock_user_config(const char* cookie)
90 fs::mkdir(fs::path("user-dir"), 0755);
91 fs::mkdir(fs::path("user-dir/.kyua"), 0755);
92 utils::setenv("HOME", (fs::current_path() / "user-dir").str());
93 create_mock_config("user-dir/.kyua/kyua.conf", cookie);
97 /// Ensures that a loaded configuration was created with create_mock_config().
98 ///
99 /// \param user_config The configuration to validate.
100 /// \param cookie The magic value to expect in the configuration file.
101 static void
102 validate_mock_config(const config::tree& user_config, const char* cookie)
104 const config::properties_map& properties = user_config.all_properties(
105 "test_suites.suite", true);
106 const config::properties_map::const_iterator iter =
107 properties.find("magic_value");
108 ATF_REQUIRE(iter != properties.end());
109 ATF_REQUIRE_EQ(cookie, (*iter).second);
113 /// Ensures that two configuration trees are equal.
115 /// \param exp_tree The expected configuration tree.
116 /// \param actual_tree The configuration tree being validated against exp_tree.
117 static void
118 require_eq(const config::tree& exp_tree, const config::tree& actual_tree)
120 ATF_REQUIRE(exp_tree.all_properties() == actual_tree.all_properties());
124 } // anonymous namespace
127 ATF_TEST_CASE_WITHOUT_HEAD(load_config__none);
128 ATF_TEST_CASE_BODY(load_config__none)
130 utils::setenv("KYUA_CONFDIR", "/the/system/does/not/exist");
131 utils::setenv("HOME", "/the/user/does/not/exist");
133 std::map< std::string, std::vector< std::string > > options;
134 options["config"].push_back(cli::config_option.default_value());
135 const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
137 require_eq(engine::default_config(),
138 cli::load_config(mock_cmdline, true));
142 ATF_TEST_CASE_WITHOUT_HEAD(load_config__explicit__ok);
143 ATF_TEST_CASE_BODY(load_config__explicit__ok)
145 mock_system_config(NULL);
146 mock_user_config(NULL);
148 create_mock_config("test-file", "hello");
150 std::map< std::string, std::vector< std::string > > options;
151 options["config"].push_back("test-file");
152 const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
154 const config::tree user_config = cli::load_config(mock_cmdline, true);
155 validate_mock_config(user_config, "hello");
159 ATF_TEST_CASE_WITHOUT_HEAD(load_config__explicit__disable);
160 ATF_TEST_CASE_BODY(load_config__explicit__disable)
162 mock_system_config(NULL);
163 mock_user_config(NULL);
165 std::map< std::string, std::vector< std::string > > options;
166 options["config"].push_back("none");
167 const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
169 require_eq(engine::default_config(),
170 cli::load_config(mock_cmdline, true));
174 ATF_TEST_CASE_WITHOUT_HEAD(load_config__explicit__fail);
175 ATF_TEST_CASE_BODY(load_config__explicit__fail)
177 mock_system_config("ok1");
178 mock_user_config("ok2");
180 create_mock_config("test-file", NULL);
182 std::map< std::string, std::vector< std::string > > options;
183 options["config"].push_back("test-file");
184 const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
186 ATF_REQUIRE_THROW_RE(engine::error, "200",
187 cli::load_config(mock_cmdline, true));
189 const config::tree config = cli::load_config(mock_cmdline, false);
190 require_eq(engine::default_config(), config);
194 ATF_TEST_CASE_WITHOUT_HEAD(load_config__user__ok);
195 ATF_TEST_CASE_BODY(load_config__user__ok)
197 mock_system_config(NULL);
198 mock_user_config("I am the user config");
200 std::map< std::string, std::vector< std::string > > options;
201 options["config"].push_back(cli::config_option.default_value());
202 const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
204 const config::tree user_config = cli::load_config(mock_cmdline, true);
205 validate_mock_config(user_config, "I am the user config");
209 ATF_TEST_CASE_WITHOUT_HEAD(load_config__user__fail);
210 ATF_TEST_CASE_BODY(load_config__user__fail)
212 mock_system_config("valid");
213 mock_user_config(NULL);
215 std::map< std::string, std::vector< std::string > > options;
216 options["config"].push_back(cli::config_option.default_value());
217 const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
219 ATF_REQUIRE_THROW_RE(engine::error, "200",
220 cli::load_config(mock_cmdline, true));
222 const config::tree config = cli::load_config(mock_cmdline, false);
223 require_eq(engine::default_config(), config);
227 ATF_TEST_CASE_WITHOUT_HEAD(load_config__user__bad_home);
228 ATF_TEST_CASE_BODY(load_config__user__bad_home)
230 mock_system_config("Fallback system config");
231 utils::setenv("HOME", "");
233 std::map< std::string, std::vector< std::string > > options;
234 options["config"].push_back(cli::config_option.default_value());
235 const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
237 const config::tree user_config = cli::load_config(mock_cmdline, true);
238 validate_mock_config(user_config, "Fallback system config");
242 ATF_TEST_CASE_WITHOUT_HEAD(load_config__system__ok);
243 ATF_TEST_CASE_BODY(load_config__system__ok)
245 mock_system_config("I am the system config");
246 utils::setenv("HOME", "/the/user/does/not/exist");
248 std::map< std::string, std::vector< std::string > > options;
249 options["config"].push_back(cli::config_option.default_value());
250 const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
252 const config::tree user_config = cli::load_config(mock_cmdline, true);
253 validate_mock_config(user_config, "I am the system config");
257 ATF_TEST_CASE_WITHOUT_HEAD(load_config__system__fail);
258 ATF_TEST_CASE_BODY(load_config__system__fail)
260 mock_system_config(NULL);
261 utils::setenv("HOME", "/the/user/does/not/exist");
263 std::map< std::string, std::vector< std::string > > options;
264 options["config"].push_back(cli::config_option.default_value());
265 const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
267 ATF_REQUIRE_THROW_RE(engine::error, "200",
268 cli::load_config(mock_cmdline, true));
270 const config::tree config = cli::load_config(mock_cmdline, false);
271 require_eq(engine::default_config(), config);
275 ATF_TEST_CASE_WITHOUT_HEAD(load_config__overrides__no);
276 ATF_TEST_CASE_BODY(load_config__overrides__no)
278 utils::setenv("KYUA_CONFDIR", fs::current_path().str());
280 std::map< std::string, std::vector< std::string > > options;
281 options["config"].push_back(cli::config_option.default_value());
282 options["variable"].push_back("architecture=1");
283 options["variable"].push_back("platform=2");
284 const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
286 const config::tree user_config = cli::load_config(mock_cmdline, true);
287 ATF_REQUIRE_EQ("1",
288 user_config.lookup< config::string_node >("architecture"));
289 ATF_REQUIRE_EQ("2",
290 user_config.lookup< config::string_node >("platform"));
294 ATF_TEST_CASE_WITHOUT_HEAD(load_config__overrides__yes);
295 ATF_TEST_CASE_BODY(load_config__overrides__yes)
297 atf::utils::create_file(
298 "config",
299 "syntax(2)\n"
300 "architecture = 'do not see me'\n"
301 "platform = 'see me'\n");
303 std::map< std::string, std::vector< std::string > > options;
304 options["config"].push_back("config");
305 options["variable"].push_back("architecture=overriden");
306 const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
308 const config::tree user_config = cli::load_config(mock_cmdline, true);
309 ATF_REQUIRE_EQ("overriden",
310 user_config.lookup< config::string_node >("architecture"));
311 ATF_REQUIRE_EQ("see me",
312 user_config.lookup< config::string_node >("platform"));
316 ATF_TEST_CASE_WITHOUT_HEAD(load_config__overrides__fail);
317 ATF_TEST_CASE_BODY(load_config__overrides__fail)
319 utils::setenv("KYUA_CONFDIR", fs::current_path().str());
321 std::map< std::string, std::vector< std::string > > options;
322 options["config"].push_back(cli::config_option.default_value());
323 options["variable"].push_back(".a=d");
324 const cmdline::parsed_cmdline mock_cmdline(options, cmdline::args_vector());
326 ATF_REQUIRE_THROW_RE(engine::error, "Empty component in key.*'\\.a'",
327 cli::load_config(mock_cmdline, true));
329 const config::tree config = cli::load_config(mock_cmdline, false);
330 require_eq(engine::default_config(), config);
334 ATF_INIT_TEST_CASES(tcs)
336 ATF_ADD_TEST_CASE(tcs, load_config__none);
337 ATF_ADD_TEST_CASE(tcs, load_config__explicit__ok);
338 ATF_ADD_TEST_CASE(tcs, load_config__explicit__disable);
339 ATF_ADD_TEST_CASE(tcs, load_config__explicit__fail);
340 ATF_ADD_TEST_CASE(tcs, load_config__user__ok);
341 ATF_ADD_TEST_CASE(tcs, load_config__user__fail);
342 ATF_ADD_TEST_CASE(tcs, load_config__user__bad_home);
343 ATF_ADD_TEST_CASE(tcs, load_config__system__ok);
344 ATF_ADD_TEST_CASE(tcs, load_config__system__fail);
345 ATF_ADD_TEST_CASE(tcs, load_config__overrides__no);
346 ATF_ADD_TEST_CASE(tcs, load_config__overrides__yes);
347 ATF_ADD_TEST_CASE(tcs, load_config__overrides__fail);