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 45namespace config = utils::config; 46namespace datetime = utils::datetime; 47namespace fs = utils::fs; 48namespace passwd = utils::passwd; 49namespace units = utils::units; 50 51 52ATF_TEST_CASE_WITHOUT_HEAD(defaults); 53ATF_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 71ATF_TEST_CASE_WITHOUT_HEAD(add); 72ATF_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 122ATF_TEST_CASE_WITHOUT_HEAD(copy); 123ATF_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 141ATF_TEST_CASE_WITHOUT_HEAD(override_all_with_setters); 142ATF_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 199ATF_TEST_CASE_WITHOUT_HEAD(override_all_with_set_string); 200ATF_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 260ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__empty); 261ATF_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 270ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__copy); 271ATF_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 282ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__equal); 283ATF_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 300ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__different); 301ATF_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 315ATF_TEST_CASE_WITHOUT_HEAD(output__defaults); 316ATF_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 328ATF_TEST_CASE_WITHOUT_HEAD(output__some_values); 329ATF_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 347ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__none); 348ATF_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 355ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_architectures__one_ok); 356ATF_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 369ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_architectures__one_fail); 370ATF_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 384ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_architectures__many_ok); 385ATF_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 400ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_architectures__many_fail); 401ATF_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 417ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_platforms__one_ok); 418ATF_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 431ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_platforms__one_fail); 432ATF_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 446ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_platforms__many_ok); 447ATF_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 462ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__allowed_platforms__many_fail); 463ATF_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 479ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__one_ok); 480ATF_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 494ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__one_fail); 495ATF_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 511ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__many_ok); 512ATF_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 530ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__many_fail); 531ATF_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 548ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_configs__special); 549ATF_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 565ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__root__ok); 566ATF_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 580ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__root__fail); 581ATF_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 593ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__unprivileged__same); 594ATF_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 608ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__unprivileged__ok); 609ATF_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 624ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_user__unprivileged__fail); 625ATF_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 640ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_files__ok); 641ATF_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 653ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_files__fail); 654ATF_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 665ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_memory__ok); 666ATF_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 676ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_memory__fail); 677ATF_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 690ATF_TEST_CASE(check_reqs__required_programs__ok); 691ATF_TEST_CASE_HEAD(check_reqs__required_programs__ok) 692{ 693 set_md_var("require.progs", "/bin/ls /bin/mv"); 694} 695ATF_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 711ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_programs__fail_absolute); 712ATF_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 723ATF_TEST_CASE_WITHOUT_HEAD(check_reqs__required_programs__fail_relative); 724ATF_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 740ATF_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