1 // Copyright 2012 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.
16 //
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.
28
29 #include "engine/metadata.hpp"
30
31 #include <sstream>
32
33 #include <atf-c++.hpp>
34
35 #include "engine/config.hpp"
36 #include "utils/config/tree.ipp"
37 #include "utils/datetime.hpp"
38 #include "utils/env.hpp"
39 #include "utils/fs/operations.hpp"
40 #include "utils/fs/path.hpp"
41 #include "utils/memory.hpp"
42 #include "utils/passwd.hpp"
43 #include "utils/units.hpp"
44
45 namespace config = utils::config;
46 namespace datetime = utils::datetime;
47 namespace fs = utils::fs;
48 namespace passwd = utils::passwd;
49 namespace units = utils::units;
50
51
52 ATF_TEST_CASE_WITHOUT_HEAD(defaults);
ATF_TEST_CASE_BODY(defaults)53 ATF_TEST_CASE_BODY(defaults)
54 {
55 const engine::metadata md = engine::metadata_builder().build();
56 ATF_REQUIRE(md.allowed_architectures().empty());
57 ATF_REQUIRE(md.allowed_platforms().empty());
58 ATF_REQUIRE(md.allowed_platforms().empty());
59 ATF_REQUIRE(md.custom().empty());
60 ATF_REQUIRE(md.description().empty());
61 ATF_REQUIRE(!md.has_cleanup());
62 ATF_REQUIRE(md.required_configs().empty());
63 ATF_REQUIRE(md.required_files().empty());
64 ATF_REQUIRE_EQ(units::bytes(0), md.required_memory());
65 ATF_REQUIRE(md.required_programs().empty());
66 ATF_REQUIRE(md.required_user().empty());
67 ATF_REQUIRE(engine::default_timeout == md.timeout());
68 }
69
70
71 ATF_TEST_CASE_WITHOUT_HEAD(add);
ATF_TEST_CASE_BODY(add)72 ATF_TEST_CASE_BODY(add)
73 {
74 engine::strings_set architectures;
75 architectures.insert("1-architecture");
76 architectures.insert("2-architecture");
77
78 engine::strings_set platforms;
79 platforms.insert("1-platform");
80 platforms.insert("2-platform");
81
82 engine::properties_map custom;
83 custom["1-custom"] = "first";
84 custom["2-custom"] = "second";
85
86 engine::strings_set configs;
87 configs.insert("1-config");
88 configs.insert("2-config");
89
90 engine::paths_set files;
91 files.insert(fs::path("1-file"));
92 files.insert(fs::path("2-file"));
93
94 engine::paths_set programs;
95 programs.insert(fs::path("1-program"));
96 programs.insert(fs::path("2-program"));
97
98 const engine::metadata md = engine::metadata_builder()
99 .add_allowed_architecture("1-architecture")
100 .add_allowed_platform("1-platform")
101 .add_custom("1-custom", "first")
102 .add_custom("2-custom", "second")
103 .add_required_config("1-config")
104 .add_required_file(fs::path("1-file"))
105 .add_required_program(fs::path("1-program"))
106 .add_allowed_architecture("2-architecture")
107 .add_allowed_platform("2-platform")
108 .add_required_config("2-config")
109 .add_required_file(fs::path("2-file"))
110 .add_required_program(fs::path("2-program"))
111 .build();
112
113 ATF_REQUIRE(architectures == md.allowed_architectures());
114 ATF_REQUIRE(platforms == md.allowed_platforms());
115 ATF_REQUIRE(custom == md.custom());
116 ATF_REQUIRE(configs == md.required_configs());
117 ATF_REQUIRE(files == md.required_files());
118 ATF_REQUIRE(programs == md.required_programs());
119 }
120
121
122 ATF_TEST_CASE_WITHOUT_HEAD(copy);
ATF_TEST_CASE_BODY(copy)123 ATF_TEST_CASE_BODY(copy)
124 {
125 const engine::metadata md1 = engine::metadata_builder()
126 .add_allowed_architecture("1-architecture")
127 .add_allowed_platform("1-platform")
128 .build();
129
130 const engine::metadata md2 = engine::metadata_builder(md1)
131 .add_allowed_architecture("2-architecture")
132 .build();
133
134 ATF_REQUIRE_EQ(1, md1.allowed_architectures().size());
135 ATF_REQUIRE_EQ(2, md2.allowed_architectures().size());
136 ATF_REQUIRE_EQ(1, md1.allowed_platforms().size());
137 ATF_REQUIRE_EQ(1, md2.allowed_platforms().size());
138 }
139
140
141 ATF_TEST_CASE_WITHOUT_HEAD(override_all_with_setters);
ATF_TEST_CASE_BODY(override_all_with_setters)142 ATF_TEST_CASE_BODY(override_all_with_setters)
143 {
144 engine::strings_set architectures;
145 architectures.insert("the-architecture");
146
147 engine::strings_set platforms;
148 platforms.insert("the-platforms");
149
150 engine::properties_map custom;
151 custom["first"] = "hello";
152 custom["second"] = "bye";
153
154 const std::string description = "Some long text";
155
156 engine::strings_set configs;
157 configs.insert("the-configs");
158
159 engine::paths_set files;
160 files.insert(fs::path("the-files"));
161
162 const units::bytes memory(12345);
163
164 engine::paths_set programs;
165 programs.insert(fs::path("the-programs"));
166
167 const std::string user = "root";
168
169 const datetime::delta timeout(123, 0);
170
171 const engine::metadata md = engine::metadata_builder()
172 .set_allowed_architectures(architectures)
173 .set_allowed_platforms(platforms)
174 .set_custom(custom)
175 .set_description(description)
176 .set_has_cleanup(true)
177 .set_required_configs(configs)
178 .set_required_files(files)
179 .set_required_memory(memory)
180 .set_required_programs(programs)
181 .set_required_user(user)
182 .set_timeout(timeout)
183 .build();
184
185 ATF_REQUIRE(architectures == md.allowed_architectures());
186 ATF_REQUIRE(platforms == md.allowed_platforms());
187 ATF_REQUIRE(custom == md.custom());
188 ATF_REQUIRE_EQ(description, md.description());
189 ATF_REQUIRE(md.has_cleanup());
190 ATF_REQUIRE(configs == md.required_configs());
191 ATF_REQUIRE(files == md.required_files());
192 ATF_REQUIRE_EQ(memory, md.required_memory());
193 ATF_REQUIRE(programs == md.required_programs());
194 ATF_REQUIRE_EQ(user, md.required_user());
195 ATF_REQUIRE(timeout == md.timeout());
196 }
197
198
199 ATF_TEST_CASE_WITHOUT_HEAD(override_all_with_set_string);
ATF_TEST_CASE_BODY(override_all_with_set_string)200 ATF_TEST_CASE_BODY(override_all_with_set_string)
201 {
202 engine::strings_set architectures;
203 architectures.insert("a1");
204 architectures.insert("a2");
205
206 engine::strings_set platforms;
207 platforms.insert("p1");
208 platforms.insert("p2");
209
210 engine::properties_map custom;
211 custom["user-defined"] = "the-value";
212
213 const std::string description = "Another long text";
214
215 engine::strings_set configs;
216 configs.insert("config-var");
217
218 engine::paths_set files;
219 files.insert(fs::path("plain"));
220 files.insert(fs::path("/absolute/path"));
221
222 const units::bytes memory(1024 * 1024);
223
224 engine::paths_set programs;
225 programs.insert(fs::path("program"));
226 programs.insert(fs::path("/absolute/prog"));
227
228 const std::string user = "unprivileged";
229
230 const datetime::delta timeout(45, 0);
231
232 const engine::metadata md = engine::metadata_builder()
233 .set_string("allowed_architectures", "a1 a2")
234 .set_string("allowed_platforms", "p1 p2")
235 .set_string("custom.user-defined", "the-value")
236 .set_string("description", "Another long text")
237 .set_string("has_cleanup", "true")
238 .set_string("required_configs", "config-var")
239 .set_string("required_files", "plain /absolute/path")
240 .set_string("required_memory", "1M")
241 .set_string("required_programs", "program /absolute/prog")
242 .set_string("required_user", "unprivileged")
243 .set_string("timeout", "45")
244 .build();
245
246 ATF_REQUIRE(architectures == md.allowed_architectures());
247 ATF_REQUIRE(platforms == md.allowed_platforms());
248 ATF_REQUIRE(custom == md.custom());
249 ATF_REQUIRE_EQ(description, md.description());
250 ATF_REQUIRE(md.has_cleanup());
251 ATF_REQUIRE(configs == md.required_configs());
252 ATF_REQUIRE(files == md.required_files());
253 ATF_REQUIRE_EQ(memory, md.required_memory());
254 ATF_REQUIRE(programs == md.required_programs());
255 ATF_REQUIRE_EQ(user, md.required_user());
256 ATF_REQUIRE(timeout == md.timeout());
257 }
258
259
260 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__empty);
ATF_TEST_CASE_BODY(operators_eq_and_ne__empty)261 ATF_TEST_CASE_BODY(operators_eq_and_ne__empty)
262 {
263 const engine::metadata md1 = engine::metadata_builder().build();
264 const engine::metadata md2 = engine::metadata_builder().build();
265 ATF_REQUIRE( md1 == md2);
266 ATF_REQUIRE(!(md1 != md2));
267 }
268
269
270 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__copy);
ATF_TEST_CASE_BODY(operators_eq_and_ne__copy)271 ATF_TEST_CASE_BODY(operators_eq_and_ne__copy)
272 {
273 const engine::metadata md1 = engine::metadata_builder()
274 .add_custom("X-foo", "bar")
275 .build();
276 const engine::metadata md2 = md1;
277 ATF_REQUIRE( md1 == md2);
278 ATF_REQUIRE(!(md1 != md2));
279 }
280
281
282 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__equal);
ATF_TEST_CASE_BODY(operators_eq_and_ne__equal)283 ATF_TEST_CASE_BODY(operators_eq_and_ne__equal)
284 {
285 const engine::metadata md1 = engine::metadata_builder()
286 .add_allowed_architecture("a")
287 .add_allowed_architecture("b")
288 .add_custom("X-foo", "bar")
289 .build();
290 const engine::metadata md2 = engine::metadata_builder()
291 .add_allowed_architecture("b")
292 .add_allowed_architecture("a")
293 .add_custom("X-foo", "bar")
294 .build();
295 ATF_REQUIRE( md1 == md2);
296 ATF_REQUIRE(!(md1 != md2));
297 }
298
299
300 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__different);
ATF_TEST_CASE_BODY(operators_eq_and_ne__different)301 ATF_TEST_CASE_BODY(operators_eq_and_ne__different)
302 {
303 const engine::metadata md1 = engine::metadata_builder()
304 .add_custom("X-foo", "bar")
305 .build();
306 const engine::metadata md2 = engine::metadata_builder()
307 .add_custom("X-foo", "bar")
308 .add_custom("X-baz", "foo bar")
309 .build();
310 ATF_REQUIRE(!(md1 == md2));
311 ATF_REQUIRE( md1 != md2);
312 }
313
314
315 ATF_TEST_CASE_WITHOUT_HEAD(output__defaults);
ATF_TEST_CASE_BODY(output__defaults)316 ATF_TEST_CASE_BODY(output__defaults)
317 {
318 std::ostringstream str;
319 str << engine::metadata_builder().build();
320 ATF_REQUIRE_EQ("metadata{allowed_architectures='', allowed_platforms='', "
321 "description='', has_cleanup='false', required_configs='', "
322 "required_files='', required_memory='0', "
323 "required_programs='', required_user='', timeout='300'}",
324 str.str());
325 }
326
327
328 ATF_TEST_CASE_WITHOUT_HEAD(output__some_values);
ATF_TEST_CASE_BODY(output__some_values)329 ATF_TEST_CASE_BODY(output__some_values)
330 {
331 std::ostringstream str;
332 str << engine::metadata_builder()
333 .add_allowed_architecture("abc")
334 .add_required_file(fs::path("foo"))
335 .add_required_file(fs::path("bar"))
336 .set_required_memory(units::bytes(1024))
337 .build();
338 ATF_REQUIRE_EQ(
339 "metadata{allowed_architectures='abc', allowed_platforms='', "
340 "description='', has_cleanup='false', required_configs='', "
341 "required_files='bar foo', required_memory='1.00K', "
342 "required_programs='', required_user='', timeout='300'}",
343 str.str());
344 }
345
346
347 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__none);
ATF_TEST_CASE_BODY(check_reqs__none)348 ATF_TEST_CASE_BODY(check_reqs__none)
349 {
350 const engine::metadata md = engine::metadata_builder().build();
351 ATF_REQUIRE(engine::check_reqs(md, engine::empty_config(), "").empty());
352 }
353
354
355 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_architectures__one_ok);
ATF_TEST_CASE_BODY(check_reqs__allowed_architectures__one_ok)356 ATF_TEST_CASE_BODY(check_reqs__allowed_architectures__one_ok)
357 {
358 const engine::metadata md = engine::metadata_builder()
359 .add_allowed_architecture("x86_64")
360 .build();
361
362 config::tree user_config = engine::default_config();
363 user_config.set_string("architecture", "x86_64");
364 user_config.set_string("platform", "");
365 ATF_REQUIRE(engine::check_reqs(md, user_config, "").empty());
366 }
367
368
369 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_architectures__one_fail);
ATF_TEST_CASE_BODY(check_reqs__allowed_architectures__one_fail)370 ATF_TEST_CASE_BODY(check_reqs__allowed_architectures__one_fail)
371 {
372 const engine::metadata md = engine::metadata_builder()
373 .add_allowed_architecture("x86_64")
374 .build();
375
376 config::tree user_config = engine::default_config();
377 user_config.set_string("architecture", "i386");
378 user_config.set_string("platform", "");
379 ATF_REQUIRE_MATCH("Current architecture 'i386' not supported",
380 engine::check_reqs(md, user_config, ""));
381 }
382
383
384 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_architectures__many_ok);
ATF_TEST_CASE_BODY(check_reqs__allowed_architectures__many_ok)385 ATF_TEST_CASE_BODY(check_reqs__allowed_architectures__many_ok)
386 {
387 const engine::metadata md = engine::metadata_builder()
388 .add_allowed_architecture("x86_64")
389 .add_allowed_architecture("i386")
390 .add_allowed_architecture("powerpc")
391 .build();
392
393 config::tree user_config = engine::default_config();
394 user_config.set_string("architecture", "i386");
395 user_config.set_string("platform", "");
396 ATF_REQUIRE(engine::check_reqs(md, user_config, "").empty());
397 }
398
399
400 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_architectures__many_fail);
ATF_TEST_CASE_BODY(check_reqs__allowed_architectures__many_fail)401 ATF_TEST_CASE_BODY(check_reqs__allowed_architectures__many_fail)
402 {
403 const engine::metadata md = engine::metadata_builder()
404 .add_allowed_architecture("x86_64")
405 .add_allowed_architecture("i386")
406 .add_allowed_architecture("powerpc")
407 .build();
408
409 config::tree user_config = engine::default_config();
410 user_config.set_string("architecture", "arm");
411 user_config.set_string("platform", "");
412 ATF_REQUIRE_MATCH("Current architecture 'arm' not supported",
413 engine::check_reqs(md, user_config, ""));
414 }
415
416
417 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_platforms__one_ok);
ATF_TEST_CASE_BODY(check_reqs__allowed_platforms__one_ok)418 ATF_TEST_CASE_BODY(check_reqs__allowed_platforms__one_ok)
419 {
420 const engine::metadata md = engine::metadata_builder()
421 .add_allowed_platform("amd64")
422 .build();
423
424 config::tree user_config = engine::default_config();
425 user_config.set_string("architecture", "");
426 user_config.set_string("platform", "amd64");
427 ATF_REQUIRE(engine::check_reqs(md, user_config, "").empty());
428 }
429
430
431 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_platforms__one_fail);
ATF_TEST_CASE_BODY(check_reqs__allowed_platforms__one_fail)432 ATF_TEST_CASE_BODY(check_reqs__allowed_platforms__one_fail)
433 {
434 const engine::metadata md = engine::metadata_builder()
435 .add_allowed_platform("amd64")
436 .build();
437
438 config::tree user_config = engine::default_config();
439 user_config.set_string("architecture", "");
440 user_config.set_string("platform", "i386");
441 ATF_REQUIRE_MATCH("Current platform 'i386' not supported",
442 engine::check_reqs(md, user_config, ""));
443 }
444
445
446 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_platforms__many_ok);
ATF_TEST_CASE_BODY(check_reqs__allowed_platforms__many_ok)447 ATF_TEST_CASE_BODY(check_reqs__allowed_platforms__many_ok)
448 {
449 const engine::metadata md = engine::metadata_builder()
450 .add_allowed_platform("amd64")
451 .add_allowed_platform("i386")
452 .add_allowed_platform("macppc")
453 .build();
454
455 config::tree user_config = engine::default_config();
456 user_config.set_string("architecture", "");
457 user_config.set_string("platform", "i386");
458 ATF_REQUIRE(engine::check_reqs(md, user_config, "").empty());
459 }
460
461
462 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_platforms__many_fail);
ATF_TEST_CASE_BODY(check_reqs__allowed_platforms__many_fail)463 ATF_TEST_CASE_BODY(check_reqs__allowed_platforms__many_fail)
464 {
465 const engine::metadata md = engine::metadata_builder()
466 .add_allowed_platform("amd64")
467 .add_allowed_platform("i386")
468 .add_allowed_platform("macppc")
469 .build();
470
471 config::tree user_config = engine::default_config();
472 user_config.set_string("architecture", "");
473 user_config.set_string("platform", "shark");
474 ATF_REQUIRE_MATCH("Current platform 'shark' not supported",
475 engine::check_reqs(md, user_config, ""));
476 }
477
478
479 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__one_ok);
ATF_TEST_CASE_BODY(check_reqs__required_configs__one_ok)480 ATF_TEST_CASE_BODY(check_reqs__required_configs__one_ok)
481 {
482 const engine::metadata md = engine::metadata_builder()
483 .add_required_config("my-var")
484 .build();
485
486 config::tree user_config = engine::default_config();
487 user_config.set_string("test_suites.suite.aaa", "value1");
488 user_config.set_string("test_suites.suite.my-var", "value2");
489 user_config.set_string("test_suites.suite.zzz", "value3");
490 ATF_REQUIRE(engine::check_reqs(md, user_config, "suite").empty());
491 }
492
493
494 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__one_fail);
ATF_TEST_CASE_BODY(check_reqs__required_configs__one_fail)495 ATF_TEST_CASE_BODY(check_reqs__required_configs__one_fail)
496 {
497 const engine::metadata md = engine::metadata_builder()
498 .add_required_config("unprivileged_user")
499 .build();
500
501 config::tree user_config = engine::default_config();
502 user_config.set_string("test_suites.suite.aaa", "value1");
503 user_config.set_string("test_suites.suite.my-var", "value2");
504 user_config.set_string("test_suites.suite.zzz", "value3");
505 ATF_REQUIRE_MATCH("Required configuration property 'unprivileged_user' not "
506 "defined",
507 engine::check_reqs(md, user_config, "suite"));
508 }
509
510
511 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__many_ok);
ATF_TEST_CASE_BODY(check_reqs__required_configs__many_ok)512 ATF_TEST_CASE_BODY(check_reqs__required_configs__many_ok)
513 {
514 const engine::metadata md = engine::metadata_builder()
515 .add_required_config("foo")
516 .add_required_config("bar")
517 .add_required_config("baz")
518 .build();
519
520 config::tree user_config = engine::default_config();
521 user_config.set_string("test_suites.suite.aaa", "value1");
522 user_config.set_string("test_suites.suite.foo", "value2");
523 user_config.set_string("test_suites.suite.bar", "value3");
524 user_config.set_string("test_suites.suite.baz", "value4");
525 user_config.set_string("test_suites.suite.zzz", "value5");
526 ATF_REQUIRE(engine::check_reqs(md, user_config, "suite").empty());
527 }
528
529
530 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__many_fail);
ATF_TEST_CASE_BODY(check_reqs__required_configs__many_fail)531 ATF_TEST_CASE_BODY(check_reqs__required_configs__many_fail)
532 {
533 const engine::metadata md = engine::metadata_builder()
534 .add_required_config("foo")
535 .add_required_config("bar")
536 .add_required_config("baz")
537 .build();
538
539 config::tree user_config = engine::default_config();
540 user_config.set_string("test_suites.suite.aaa", "value1");
541 user_config.set_string("test_suites.suite.foo", "value2");
542 user_config.set_string("test_suites.suite.zzz", "value3");
543 ATF_REQUIRE_MATCH("Required configuration property 'bar' not defined",
544 engine::check_reqs(md, user_config, "suite"));
545 }
546
547
548 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__special);
ATF_TEST_CASE_BODY(check_reqs__required_configs__special)549 ATF_TEST_CASE_BODY(check_reqs__required_configs__special)
550 {
551 const engine::metadata md = engine::metadata_builder()
552 .add_required_config("unprivileged-user")
553 .build();
554
555 config::tree user_config = engine::default_config();
556 ATF_REQUIRE_MATCH("Required configuration property 'unprivileged-user' "
557 "not defined",
558 engine::check_reqs(md, user_config, ""));
559 user_config.set< engine::user_node >(
560 "unprivileged_user", passwd::user("foo", 1, 2));
561 ATF_REQUIRE(engine::check_reqs(md, user_config, "foo").empty());
562 }
563
564
565 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__root__ok);
ATF_TEST_CASE_BODY(check_reqs__required_user__root__ok)566 ATF_TEST_CASE_BODY(check_reqs__required_user__root__ok)
567 {
568 const engine::metadata md = engine::metadata_builder()
569 .set_required_user("root")
570 .build();
571
572 config::tree user_config = engine::default_config();
573 ATF_REQUIRE(!user_config.is_set("unprivileged_user"));
574
575 passwd::set_current_user_for_testing(passwd::user("", 0, 1));
576 ATF_REQUIRE(engine::check_reqs(md, user_config, "").empty());
577 }
578
579
580 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__root__fail);
ATF_TEST_CASE_BODY(check_reqs__required_user__root__fail)581 ATF_TEST_CASE_BODY(check_reqs__required_user__root__fail)
582 {
583 const engine::metadata md = engine::metadata_builder()
584 .set_required_user("root")
585 .build();
586
587 passwd::set_current_user_for_testing(passwd::user("", 123, 1));
588 ATF_REQUIRE_MATCH("Requires root privileges",
589 engine::check_reqs(md, engine::empty_config(), ""));
590 }
591
592
593 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__unprivileged__same);
ATF_TEST_CASE_BODY(check_reqs__required_user__unprivileged__same)594 ATF_TEST_CASE_BODY(check_reqs__required_user__unprivileged__same)
595 {
596 const engine::metadata md = engine::metadata_builder()
597 .set_required_user("unprivileged")
598 .build();
599
600 config::tree user_config = engine::default_config();
601 ATF_REQUIRE(!user_config.is_set("unprivileged_user"));
602
603 passwd::set_current_user_for_testing(passwd::user("", 123, 1));
604 ATF_REQUIRE(engine::check_reqs(md, user_config, "").empty());
605 }
606
607
608 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__unprivileged__ok);
ATF_TEST_CASE_BODY(check_reqs__required_user__unprivileged__ok)609 ATF_TEST_CASE_BODY(check_reqs__required_user__unprivileged__ok)
610 {
611 const engine::metadata md = engine::metadata_builder()
612 .set_required_user("unprivileged")
613 .build();
614
615 config::tree user_config = engine::default_config();
616 user_config.set< engine::user_node >(
617 "unprivileged_user", passwd::user("", 123, 1));
618
619 passwd::set_current_user_for_testing(passwd::user("", 0, 1));
620 ATF_REQUIRE(engine::check_reqs(md, user_config, "").empty());
621 }
622
623
624 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__unprivileged__fail);
ATF_TEST_CASE_BODY(check_reqs__required_user__unprivileged__fail)625 ATF_TEST_CASE_BODY(check_reqs__required_user__unprivileged__fail)
626 {
627 const engine::metadata md = engine::metadata_builder()
628 .set_required_user("unprivileged")
629 .build();
630
631 config::tree user_config = engine::default_config();
632 ATF_REQUIRE(!user_config.is_set("unprivileged_user"));
633
634 passwd::set_current_user_for_testing(passwd::user("", 0, 1));
635 ATF_REQUIRE_MATCH("Requires.*unprivileged.*unprivileged-user",
636 engine::check_reqs(md, user_config, ""));
637 }
638
639
640 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_files__ok);
ATF_TEST_CASE_BODY(check_reqs__required_files__ok)641 ATF_TEST_CASE_BODY(check_reqs__required_files__ok)
642 {
643 const engine::metadata md = engine::metadata_builder()
644 .add_required_file(fs::current_path() / "test-file")
645 .build();
646
647 atf::utils::create_file("test-file", "");
648
649 ATF_REQUIRE(engine::check_reqs(md, engine::empty_config(), "").empty());
650 }
651
652
653 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_files__fail);
ATF_TEST_CASE_BODY(check_reqs__required_files__fail)654 ATF_TEST_CASE_BODY(check_reqs__required_files__fail)
655 {
656 const engine::metadata md = engine::metadata_builder()
657 .add_required_file(fs::path("/non-existent/file"))
658 .build();
659
660 ATF_REQUIRE_MATCH("'/non-existent/file' not found$",
661 engine::check_reqs(md, engine::empty_config(), ""));
662 }
663
664
665 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_memory__ok);
ATF_TEST_CASE_BODY(check_reqs__required_memory__ok)666 ATF_TEST_CASE_BODY(check_reqs__required_memory__ok)
667 {
668 const engine::metadata md = engine::metadata_builder()
669 .set_required_memory(units::bytes::parse("1m"))
670 .build();
671
672 ATF_REQUIRE(engine::check_reqs(md, engine::empty_config(), "").empty());
673 }
674
675
676 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_memory__fail);
ATF_TEST_CASE_BODY(check_reqs__required_memory__fail)677 ATF_TEST_CASE_BODY(check_reqs__required_memory__fail)
678 {
679 const engine::metadata md = engine::metadata_builder()
680 .set_required_memory(units::bytes::parse("100t"))
681 .build();
682
683 if (utils::physical_memory() == 0)
684 skip("Don't know how to query the amount of physical memory");
685 ATF_REQUIRE_MATCH("Requires 100.00T .*memory",
686 engine::check_reqs(md, engine::empty_config(), ""));
687 }
688
689
690 ATF_TEST_CASE(check_reqs__required_programs__ok);
ATF_TEST_CASE_HEAD(check_reqs__required_programs__ok)691 ATF_TEST_CASE_HEAD(check_reqs__required_programs__ok)
692 {
693 set_md_var("require.progs", "/bin/ls /bin/mv");
694 }
ATF_TEST_CASE_BODY(check_reqs__required_programs__ok)695 ATF_TEST_CASE_BODY(check_reqs__required_programs__ok)
696 {
697 const engine::metadata md = engine::metadata_builder()
698 .add_required_program(fs::path("/bin/ls"))
699 .add_required_program(fs::path("foo"))
700 .add_required_program(fs::path("/bin/mv"))
701 .build();
702
703 fs::mkdir(fs::path("bin"), 0755);
704 atf::utils::create_file("bin/foo", "");
705 utils::setenv("PATH", (fs::current_path() / "bin").str());
706
707 ATF_REQUIRE(engine::check_reqs(md, engine::empty_config(), "").empty());
708 }
709
710
711 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_programs__fail_absolute);
ATF_TEST_CASE_BODY(check_reqs__required_programs__fail_absolute)712 ATF_TEST_CASE_BODY(check_reqs__required_programs__fail_absolute)
713 {
714 const engine::metadata md = engine::metadata_builder()
715 .add_required_program(fs::path("/non-existent/program"))
716 .build();
717
718 ATF_REQUIRE_MATCH("'/non-existent/program' not found$",
719 engine::check_reqs(md, engine::empty_config(), ""));
720 }
721
722
723 ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_programs__fail_relative);
ATF_TEST_CASE_BODY(check_reqs__required_programs__fail_relative)724 ATF_TEST_CASE_BODY(check_reqs__required_programs__fail_relative)
725 {
726 const engine::metadata md = engine::metadata_builder()
727 .add_required_program(fs::path("foo"))
728 .add_required_program(fs::path("bar"))
729 .build();
730
731 fs::mkdir(fs::path("bin"), 0755);
732 atf::utils::create_file("bin/foo", "");
733 utils::setenv("PATH", (fs::current_path() / "bin").str());
734
735 ATF_REQUIRE_MATCH("'bar' not found in PATH$",
736 engine::check_reqs(md, engine::empty_config(), ""));
737 }
738
739
ATF_INIT_TEST_CASES(tcs)740 ATF_INIT_TEST_CASES(tcs)
741 {
742 ATF_ADD_TEST_CASE(tcs, defaults);
743 ATF_ADD_TEST_CASE(tcs, add);
744 ATF_ADD_TEST_CASE(tcs, copy);
745 ATF_ADD_TEST_CASE(tcs, override_all_with_setters);
746 ATF_ADD_TEST_CASE(tcs, override_all_with_set_string);
747
748 ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne__empty);
749 ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne__copy);
750 ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne__equal);
751 ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne__different);
752
753 ATF_ADD_TEST_CASE(tcs, output__defaults);
754 ATF_ADD_TEST_CASE(tcs, output__some_values);
755
756 // TODO(jmmv): Add tests for error conditions (invalid keys and invalid
757 // values).
758
759 ATF_ADD_TEST_CASE(tcs, check_reqs__none);
760 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_architectures__one_ok);
761 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_architectures__one_fail);
762 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_architectures__many_ok);
763 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_architectures__many_fail);
764 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_platforms__one_ok);
765 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_platforms__one_fail);
766 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_platforms__many_ok);
767 ATF_ADD_TEST_CASE(tcs, check_reqs__allowed_platforms__many_fail);
768 ATF_ADD_TEST_CASE(tcs, check_reqs__required_configs__one_ok);
769 ATF_ADD_TEST_CASE(tcs, check_reqs__required_configs__one_fail);
770 ATF_ADD_TEST_CASE(tcs, check_reqs__required_configs__many_ok);
771 ATF_ADD_TEST_CASE(tcs, check_reqs__required_configs__many_fail);
772 ATF_ADD_TEST_CASE(tcs, check_reqs__required_configs__special);
773 ATF_ADD_TEST_CASE(tcs, check_reqs__required_user__root__ok);
774 ATF_ADD_TEST_CASE(tcs, check_reqs__required_user__root__fail);
775 ATF_ADD_TEST_CASE(tcs, check_reqs__required_user__unprivileged__same);
776 ATF_ADD_TEST_CASE(tcs, check_reqs__required_user__unprivileged__ok);
777 ATF_ADD_TEST_CASE(tcs, check_reqs__required_user__unprivileged__fail);
778 ATF_ADD_TEST_CASE(tcs, check_reqs__required_files__ok);
779 ATF_ADD_TEST_CASE(tcs, check_reqs__required_files__fail);
780 ATF_ADD_TEST_CASE(tcs, check_reqs__required_memory__ok);
781 ATF_ADD_TEST_CASE(tcs, check_reqs__required_memory__fail);
782 ATF_ADD_TEST_CASE(tcs, check_reqs__required_programs__ok);
783 ATF_ADD_TEST_CASE(tcs, check_reqs__required_programs__fail_absolute);
784 ATF_ADD_TEST_CASE(tcs, check_reqs__required_programs__fail_relative);
785 }
786