1 // Copyright 2012 The Kyua Authors.
2 // All rights reserved.
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
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 "model/metadata.hpp"
31 #include <atf-c++.hpp>
33 #include "engine/config.hpp"
34 #include "engine/requirements.hpp"
35 #include "utils/config/tree.ipp"
36 #include "utils/env.hpp"
37 #include "utils/fs/operations.hpp"
38 #include "utils/fs/path.hpp"
39 #include "utils/memory.hpp"
40 #include "utils/passwd.hpp"
41 #include "utils/units.hpp"
43 namespace config = utils::config;
44 namespace fs = utils::fs;
45 namespace passwd = utils::passwd;
46 namespace units = utils::units;
49 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__none);
50 ATF_TEST_CASE_BODY(check_reqs__none)
52 const model::metadata md = model::metadata_builder().build();
53 ATF_REQUIRE(engine::check_reqs(md, engine::empty_config(), "",
54 fs::path(".")).empty());
58 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_architectures__one_ok);
59 ATF_TEST_CASE_BODY(check_reqs__allowed_architectures__one_ok)
61 const model::metadata md = model::metadata_builder()
62 .add_allowed_architecture("x86_64")
65 config::tree user_config = engine::default_config();
66 user_config.set_string("architecture", "x86_64");
67 user_config.set_string("platform", "");
68 ATF_REQUIRE(engine::check_reqs(md, user_config, "", fs::path(".")).empty());
72 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_architectures__one_fail);
73 ATF_TEST_CASE_BODY(check_reqs__allowed_architectures__one_fail)
75 const model::metadata md = model::metadata_builder()
76 .add_allowed_architecture("x86_64")
79 config::tree user_config = engine::default_config();
80 user_config.set_string("architecture", "i386");
81 user_config.set_string("platform", "");
82 ATF_REQUIRE_MATCH("Current architecture 'i386' not supported",
83 engine::check_reqs(md, user_config, "", fs::path(".")));
87 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_architectures__many_ok);
88 ATF_TEST_CASE_BODY(check_reqs__allowed_architectures__many_ok)
90 const model::metadata md = model::metadata_builder()
91 .add_allowed_architecture("x86_64")
92 .add_allowed_architecture("i386")
93 .add_allowed_architecture("powerpc")
96 config::tree user_config = engine::default_config();
97 user_config.set_string("architecture", "i386");
98 user_config.set_string("platform", "");
99 ATF_REQUIRE(engine::check_reqs(md, user_config, "", fs::path(".")).empty());
103 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_architectures__many_fail);
104 ATF_TEST_CASE_BODY(check_reqs__allowed_architectures__many_fail)
106 const model::metadata md = model::metadata_builder()
107 .add_allowed_architecture("x86_64")
108 .add_allowed_architecture("i386")
109 .add_allowed_architecture("powerpc")
112 config::tree user_config = engine::default_config();
113 user_config.set_string("architecture", "arm");
114 user_config.set_string("platform", "");
115 ATF_REQUIRE_MATCH("Current architecture 'arm' not supported",
116 engine::check_reqs(md, user_config, "", fs::path(".")));
120 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_platforms__one_ok);
121 ATF_TEST_CASE_BODY(check_reqs__allowed_platforms__one_ok)
123 const model::metadata md = model::metadata_builder()
124 .add_allowed_platform("amd64")
127 config::tree user_config = engine::default_config();
128 user_config.set_string("architecture", "");
129 user_config.set_string("platform", "amd64");
130 ATF_REQUIRE(engine::check_reqs(md, user_config, "", fs::path(".")).empty());
134 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_platforms__one_fail);
135 ATF_TEST_CASE_BODY(check_reqs__allowed_platforms__one_fail)
137 const model::metadata md = model::metadata_builder()
138 .add_allowed_platform("amd64")
141 config::tree user_config = engine::default_config();
142 user_config.set_string("architecture", "");
143 user_config.set_string("platform", "i386");
144 ATF_REQUIRE_MATCH("Current platform 'i386' not supported",
145 engine::check_reqs(md, user_config, "", fs::path(".")));
149 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_platforms__many_ok);
150 ATF_TEST_CASE_BODY(check_reqs__allowed_platforms__many_ok)
152 const model::metadata md = model::metadata_builder()
153 .add_allowed_platform("amd64")
154 .add_allowed_platform("i386")
155 .add_allowed_platform("macppc")
158 config::tree user_config = engine::default_config();
159 user_config.set_string("architecture", "");
160 user_config.set_string("platform", "i386");
161 ATF_REQUIRE(engine::check_reqs(md, user_config, "", fs::path(".")).empty());
165 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_platforms__many_fail);
166 ATF_TEST_CASE_BODY(check_reqs__allowed_platforms__many_fail)
168 const model::metadata md = model::metadata_builder()
169 .add_allowed_platform("amd64")
170 .add_allowed_platform("i386")
171 .add_allowed_platform("macppc")
174 config::tree user_config = engine::default_config();
175 user_config.set_string("architecture", "");
176 user_config.set_string("platform", "shark");
177 ATF_REQUIRE_MATCH("Current platform 'shark' not supported",
178 engine::check_reqs(md, user_config, "", fs::path(".")));
182 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__one_ok);
183 ATF_TEST_CASE_BODY(check_reqs__required_configs__one_ok)
185 const model::metadata md = model::metadata_builder()
186 .add_required_config("my-var")
189 config::tree user_config = engine::default_config();
190 user_config.set_string("test_suites.suite.aaa", "value1");
191 user_config.set_string("test_suites.suite.my-var", "value2");
192 user_config.set_string("test_suites.suite.zzz", "value3");
193 ATF_REQUIRE(engine::check_reqs(md, user_config, "suite",
194 fs::path(".")).empty());
198 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__one_fail);
199 ATF_TEST_CASE_BODY(check_reqs__required_configs__one_fail)
201 const model::metadata md = model::metadata_builder()
202 .add_required_config("unprivileged_user")
205 config::tree user_config = engine::default_config();
206 user_config.set_string("test_suites.suite.aaa", "value1");
207 user_config.set_string("test_suites.suite.my-var", "value2");
208 user_config.set_string("test_suites.suite.zzz", "value3");
209 ATF_REQUIRE_MATCH("Required configuration property 'unprivileged_user' not "
211 engine::check_reqs(md, user_config, "suite",
216 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__many_ok);
217 ATF_TEST_CASE_BODY(check_reqs__required_configs__many_ok)
219 const model::metadata md = model::metadata_builder()
220 .add_required_config("foo")
221 .add_required_config("bar")
222 .add_required_config("baz")
225 config::tree user_config = engine::default_config();
226 user_config.set_string("test_suites.suite.aaa", "value1");
227 user_config.set_string("test_suites.suite.foo", "value2");
228 user_config.set_string("test_suites.suite.bar", "value3");
229 user_config.set_string("test_suites.suite.baz", "value4");
230 user_config.set_string("test_suites.suite.zzz", "value5");
231 ATF_REQUIRE(engine::check_reqs(md, user_config, "suite",
232 fs::path(".")).empty());
236 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__many_fail);
237 ATF_TEST_CASE_BODY(check_reqs__required_configs__many_fail)
239 const model::metadata md = model::metadata_builder()
240 .add_required_config("foo")
241 .add_required_config("bar")
242 .add_required_config("baz")
245 config::tree user_config = engine::default_config();
246 user_config.set_string("test_suites.suite.aaa", "value1");
247 user_config.set_string("test_suites.suite.foo", "value2");
248 user_config.set_string("test_suites.suite.zzz", "value3");
249 ATF_REQUIRE_MATCH("Required configuration property 'bar' not defined",
250 engine::check_reqs(md, user_config, "suite",
255 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__special);
256 ATF_TEST_CASE_BODY(check_reqs__required_configs__special)
258 const model::metadata md = model::metadata_builder()
259 .add_required_config("unprivileged-user")
262 config::tree user_config = engine::default_config();
263 ATF_REQUIRE_MATCH("Required configuration property 'unprivileged-user' "
265 engine::check_reqs(md, user_config, "", fs::path(".")));
266 user_config.set< engine::user_node >(
267 "unprivileged_user", passwd::user("foo", 1, 2));
268 ATF_REQUIRE(engine::check_reqs(md, user_config, "foo",
269 fs::path(".")).empty());
273 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__root__ok);
274 ATF_TEST_CASE_BODY(check_reqs__required_user__root__ok)
276 const model::metadata md = model::metadata_builder()
277 .set_required_user("root")
280 config::tree user_config = engine::default_config();
281 ATF_REQUIRE(!user_config.is_set("unprivileged_user"));
283 passwd::set_current_user_for_testing(passwd::user("", 0, 1));
284 ATF_REQUIRE(engine::check_reqs(md, user_config, "", fs::path(".")).empty());
288 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__root__fail);
289 ATF_TEST_CASE_BODY(check_reqs__required_user__root__fail)
291 const model::metadata md = model::metadata_builder()
292 .set_required_user("root")
295 passwd::set_current_user_for_testing(passwd::user("", 123, 1));
296 ATF_REQUIRE_MATCH("Requires root privileges",
297 engine::check_reqs(md, engine::empty_config(), "",
302 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__unprivileged__same);
303 ATF_TEST_CASE_BODY(check_reqs__required_user__unprivileged__same)
305 const model::metadata md = model::metadata_builder()
306 .set_required_user("unprivileged")
309 config::tree user_config = engine::default_config();
310 ATF_REQUIRE(!user_config.is_set("unprivileged_user"));
312 passwd::set_current_user_for_testing(passwd::user("", 123, 1));
313 ATF_REQUIRE(engine::check_reqs(md, user_config, "", fs::path(".")).empty());
317 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__unprivileged__ok);
318 ATF_TEST_CASE_BODY(check_reqs__required_user__unprivileged__ok)
320 const model::metadata md = model::metadata_builder()
321 .set_required_user("unprivileged")
324 config::tree user_config = engine::default_config();
325 user_config.set< engine::user_node >(
326 "unprivileged_user", passwd::user("", 123, 1));
328 passwd::set_current_user_for_testing(passwd::user("", 0, 1));
329 ATF_REQUIRE(engine::check_reqs(md, user_config, "", fs::path(".")).empty());
333 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__unprivileged__fail);
334 ATF_TEST_CASE_BODY(check_reqs__required_user__unprivileged__fail)
336 const model::metadata md = model::metadata_builder()
337 .set_required_user("unprivileged")
340 config::tree user_config = engine::default_config();
341 ATF_REQUIRE(!user_config.is_set("unprivileged_user"));
343 passwd::set_current_user_for_testing(passwd::user("", 0, 1));
344 ATF_REQUIRE_MATCH("Requires.*unprivileged.*unprivileged-user",
345 engine::check_reqs(md, user_config, "", fs::path(".")));
349 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_disk_space__ok);
350 ATF_TEST_CASE_BODY(check_reqs__required_disk_space__ok)
352 const model::metadata md = model::metadata_builder()
353 .set_required_disk_space(units::bytes::parse("1m"))
356 ATF_REQUIRE(engine::check_reqs(md, engine::empty_config(), "",
357 fs::path(".")).empty());
361 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_disk_space__fail);
362 ATF_TEST_CASE_BODY(check_reqs__required_disk_space__fail)
364 const model::metadata md = model::metadata_builder()
365 .set_required_disk_space(units::bytes::parse("1000t"))
368 ATF_REQUIRE_MATCH("Requires 1000.00T .*disk space",
369 engine::check_reqs(md, engine::empty_config(), "",
374 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_files__ok);
375 ATF_TEST_CASE_BODY(check_reqs__required_files__ok)
377 const model::metadata md = model::metadata_builder()
378 .add_required_file(fs::current_path() / "test-file")
381 atf::utils::create_file("test-file", "");
383 ATF_REQUIRE(engine::check_reqs(md, engine::empty_config(), "",
384 fs::path(".")).empty());
388 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_files__fail);
389 ATF_TEST_CASE_BODY(check_reqs__required_files__fail)
391 const model::metadata md = model::metadata_builder()
392 .add_required_file(fs::path("/non-existent/file"))
395 ATF_REQUIRE_MATCH("'/non-existent/file' not found$",
396 engine::check_reqs(md, engine::empty_config(), "",
401 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_memory__ok);
402 ATF_TEST_CASE_BODY(check_reqs__required_memory__ok)
404 const model::metadata md = model::metadata_builder()
405 .set_required_memory(units::bytes::parse("1m"))
408 ATF_REQUIRE(engine::check_reqs(md, engine::empty_config(), "",
409 fs::path(".")).empty());
413 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_memory__fail);
414 ATF_TEST_CASE_BODY(check_reqs__required_memory__fail)
416 const model::metadata md = model::metadata_builder()
417 .set_required_memory(units::bytes::parse("100t"))
420 if (utils::physical_memory() == 0)
421 skip("Don't know how to query the amount of physical memory");
422 ATF_REQUIRE_MATCH("Requires 100.00T .*memory",
423 engine::check_reqs(md, engine::empty_config(), "",
428 ATF_TEST_CASE(check_reqs__required_programs__ok);
429 ATF_TEST_CASE_HEAD(check_reqs__required_programs__ok)
431 set_md_var("require.progs", "/bin/ls /bin/mv");
433 ATF_TEST_CASE_BODY(check_reqs__required_programs__ok)
435 const model::metadata md = model::metadata_builder()
436 .add_required_program(fs::path("/bin/ls"))
437 .add_required_program(fs::path("foo"))
438 .add_required_program(fs::path("/bin/mv"))
441 fs::mkdir(fs::path("bin"), 0755);
442 atf::utils::create_file("bin/foo", "");
443 utils::setenv("PATH", (fs::current_path() / "bin").str());
445 ATF_REQUIRE(engine::check_reqs(md, engine::empty_config(), "",
446 fs::path(".")).empty());
450 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_programs__fail_absolute);
451 ATF_TEST_CASE_BODY(check_reqs__required_programs__fail_absolute)
453 const model::metadata md = model::metadata_builder()
454 .add_required_program(fs::path("/non-existent/program"))
457 ATF_REQUIRE_MATCH("'/non-existent/program' not found$",
458 engine::check_reqs(md, engine::empty_config(), "",
463 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_programs__fail_relative);
464 ATF_TEST_CASE_BODY(check_reqs__required_programs__fail_relative)
466 const model::metadata md = model::metadata_builder()
467 .add_required_program(fs::path("foo"))
468 .add_required_program(fs::path("bar"))
471 fs::mkdir(fs::path("bin"), 0755);
472 atf::utils::create_file("bin/foo", "");
473 utils::setenv("PATH", (fs::current_path() / "bin").str());
475 ATF_REQUIRE_MATCH("'bar' not found in PATH$",
476 engine::check_reqs(md, engine::empty_config(), "",
481 ATF_INIT_TEST_CASES(tcs)
483 ATF_ADD_TEST_CASE(tcs, check_reqs__none);
484 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_architectures__one_ok);
485 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_architectures__one_fail);
486 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_architectures__many_ok);
487 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_architectures__many_fail);
488 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_platforms__one_ok);
489 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_platforms__one_fail);
490 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_platforms__many_ok);
491 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_platforms__many_fail);
492 ATF_ADD_TEST_CASE(tcs, check_reqs__required_configs__one_ok);
493 ATF_ADD_TEST_CASE(tcs, check_reqs__required_configs__one_fail);
494 ATF_ADD_TEST_CASE(tcs, check_reqs__required_configs__many_ok);
495 ATF_ADD_TEST_CASE(tcs, check_reqs__required_configs__many_fail);
496 ATF_ADD_TEST_CASE(tcs, check_reqs__required_configs__special);
497 ATF_ADD_TEST_CASE(tcs, check_reqs__required_user__root__ok);
498 ATF_ADD_TEST_CASE(tcs, check_reqs__required_user__root__fail);
499 ATF_ADD_TEST_CASE(tcs, check_reqs__required_user__unprivileged__same);
500 ATF_ADD_TEST_CASE(tcs, check_reqs__required_user__unprivileged__ok);
501 ATF_ADD_TEST_CASE(tcs, check_reqs__required_user__unprivileged__fail);
502 ATF_ADD_TEST_CASE(tcs, check_reqs__required_disk_space__ok);
503 ATF_ADD_TEST_CASE(tcs, check_reqs__required_disk_space__fail);
504 ATF_ADD_TEST_CASE(tcs, check_reqs__required_files__ok);
505 ATF_ADD_TEST_CASE(tcs, check_reqs__required_files__fail);
506 ATF_ADD_TEST_CASE(tcs, check_reqs__required_memory__ok);
507 ATF_ADD_TEST_CASE(tcs, check_reqs__required_memory__fail);
508 ATF_ADD_TEST_CASE(tcs, check_reqs__required_programs__ok);
509 ATF_ADD_TEST_CASE(tcs, check_reqs__required_programs__fail_absolute);
510 ATF_ADD_TEST_CASE(tcs, check_reqs__required_programs__fail_relative);