1 // Copyright 2010 The Kyua Authors. 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 "model/test_program.hpp" 30 31 extern "C" { 32 #include <sys/stat.h> 33 34 #include <signal.h> 35 } 36 37 #include <set> 38 #include <sstream> 39 40 #include <atf-c++.hpp> 41 42 #include "model/exceptions.hpp" 43 #include "model/metadata.hpp" 44 #include "model/test_case.hpp" 45 #include "model/test_result.hpp" 46 #include "utils/env.hpp" 47 #include "utils/format/containers.ipp" 48 #include "utils/format/macros.hpp" 49 #include "utils/fs/operations.hpp" 50 #include "utils/fs/path.hpp" 51 #include "utils/optional.ipp" 52 53 namespace fs = utils::fs; 54 55 56 namespace { 57 58 59 /// Test program that sets its test cases lazily. 60 /// 61 /// This test class exists to test the behavior of a test_program object when 62 /// the class is extended to offer lazy loading of test cases. We simulate such 63 /// lazy loading here by storing the list of test cases aside at construction 64 /// time and later setting it lazily the first time test_cases() is called. 65 class lazy_test_program : public model::test_program { 66 /// Whether set_test_cases() has yet been called or not. 67 mutable bool _set_test_cases_called; 68 69 /// The list of test cases for this test program. 70 /// 71 /// Only use this in the call to set_test_cases(). All other reads of the 72 /// test cases list should happen via the parent class' test_cases() method. 73 model::test_cases_map _lazy_test_cases; 74 75 public: 76 /// Constructs a new test program. 77 /// 78 /// \param interface_name_ Name of the test program interface. 79 /// \param binary_ The name of the test program binary relative to root_. 80 /// \param root_ The root of the test suite containing the test program. 81 /// \param test_suite_name_ The name of the test suite. 82 /// \param metadata_ Metadata of the test program. 83 /// \param test_cases_ The collection of test cases in the test program. 84 lazy_test_program(const std::string& interface_name_, 85 const utils::fs::path& binary_, 86 const utils::fs::path& root_, 87 const std::string& test_suite_name_, 88 const model::metadata& metadata_, 89 const model::test_cases_map& test_cases_) : 90 test_program(interface_name_, binary_, root_, test_suite_name_, 91 metadata_, model::test_cases_map()), 92 _set_test_cases_called(false), 93 _lazy_test_cases(test_cases_) 94 { 95 } 96 97 /// Lazily sets the test cases on the parent and returns them. 98 /// 99 /// \return The list of test cases. 100 const model::test_cases_map& 101 test_cases(void) const 102 { 103 if (!_set_test_cases_called) { 104 const_cast< lazy_test_program* >(this)->set_test_cases( 105 _lazy_test_cases); 106 _set_test_cases_called = true; 107 } 108 return test_program::test_cases(); 109 } 110 }; 111 112 113 } // anonymous namespace 114 115 116 /// Runs a ctor_and_getters test. 117 /// 118 /// \tparam TestProgram Either model::test_program or lazy_test_program. 119 template< class TestProgram > 120 static void 121 check_ctor_and_getters(void) 122 { 123 const model::metadata tp_md = model::metadata_builder() 124 .add_custom("first", "foo") 125 .add_custom("second", "bar") 126 .build(); 127 const model::metadata tc_md = model::metadata_builder() 128 .add_custom("first", "baz") 129 .build(); 130 131 const TestProgram test_program( 132 "mock", fs::path("binary"), fs::path("root"), "suite-name", tp_md, 133 model::test_cases_map_builder().add("foo", tc_md).build()); 134 135 136 ATF_REQUIRE_EQ("mock", test_program.interface_name()); 137 ATF_REQUIRE_EQ(fs::path("binary"), test_program.relative_path()); 138 ATF_REQUIRE_EQ(fs::current_path() / "root/binary", 139 test_program.absolute_path()); 140 ATF_REQUIRE_EQ(fs::path("root"), test_program.root()); 141 ATF_REQUIRE_EQ("suite-name", test_program.test_suite_name()); 142 ATF_REQUIRE_EQ(tp_md, test_program.get_metadata()); 143 144 const model::metadata exp_tc_md = model::metadata_builder() 145 .add_custom("first", "baz") 146 .add_custom("second", "bar") 147 .build(); 148 const model::test_cases_map exp_tcs = model::test_cases_map_builder() 149 .add("foo", exp_tc_md) 150 .build(); 151 ATF_REQUIRE_EQ(exp_tcs, test_program.test_cases()); 152 } 153 154 155 ATF_TEST_CASE_WITHOUT_HEAD(ctor_and_getters); 156 ATF_TEST_CASE_BODY(ctor_and_getters) 157 { 158 check_ctor_and_getters< model::test_program >(); 159 } 160 161 162 ATF_TEST_CASE_WITHOUT_HEAD(derived__ctor_and_getters); 163 ATF_TEST_CASE_BODY(derived__ctor_and_getters) 164 { 165 check_ctor_and_getters< lazy_test_program >(); 166 } 167 168 169 /// Runs a find_ok test. 170 /// 171 /// \tparam TestProgram Either model::test_program or lazy_test_program. 172 template< class TestProgram > 173 static void 174 check_find_ok(void) 175 { 176 const model::test_case test_case("main", model::metadata_builder().build()); 177 178 const TestProgram test_program( 179 "mock", fs::path("non-existent"), fs::path("."), "suite-name", 180 model::metadata_builder().build(), 181 model::test_cases_map_builder().add(test_case).build()); 182 183 const model::test_case& found_test_case = test_program.find("main"); 184 ATF_REQUIRE_EQ(test_case, found_test_case); 185 } 186 187 188 ATF_TEST_CASE_WITHOUT_HEAD(find__ok); 189 ATF_TEST_CASE_BODY(find__ok) 190 { 191 check_find_ok< model::test_program >(); 192 } 193 194 195 ATF_TEST_CASE_WITHOUT_HEAD(derived__find__ok); 196 ATF_TEST_CASE_BODY(derived__find__ok) 197 { 198 check_find_ok< lazy_test_program >(); 199 } 200 201 202 /// Runs a find_missing test. 203 /// 204 /// \tparam TestProgram Either model::test_program or lazy_test_program. 205 template< class TestProgram > 206 static void 207 check_find_missing(void) 208 { 209 const TestProgram test_program( 210 "mock", fs::path("non-existent"), fs::path("."), "suite-name", 211 model::metadata_builder().build(), 212 model::test_cases_map_builder().add("main").build()); 213 214 ATF_REQUIRE_THROW_RE(model::not_found_error, 215 "case.*abc.*program.*non-existent", 216 test_program.find("abc")); 217 } 218 219 220 ATF_TEST_CASE_WITHOUT_HEAD(find__missing); 221 ATF_TEST_CASE_BODY(find__missing) 222 { 223 check_find_missing< model::test_program >(); 224 } 225 226 227 ATF_TEST_CASE_WITHOUT_HEAD(derived__find__missing); 228 ATF_TEST_CASE_BODY(derived__find__missing) 229 { 230 check_find_missing< lazy_test_program >(); 231 } 232 233 234 /// Runs a metadata_inheritance test. 235 /// 236 /// \tparam TestProgram Either model::test_program or lazy_test_program. 237 template< class TestProgram > 238 static void 239 check_metadata_inheritance(void) 240 { 241 const model::test_cases_map test_cases = model::test_cases_map_builder() 242 .add("inherit-all") 243 .add("inherit-some", 244 model::metadata_builder() 245 .set_description("Overriden description") 246 .build()) 247 .add("inherit-none", 248 model::metadata_builder() 249 .add_allowed_architecture("overriden-arch") 250 .add_allowed_platform("overriden-platform") 251 .set_description("Overriden description") 252 .build()) 253 .build(); 254 255 const model::metadata metadata = model::metadata_builder() 256 .add_allowed_architecture("base-arch") 257 .set_description("Base description") 258 .build(); 259 const TestProgram test_program( 260 "plain", fs::path("non-existent"), fs::path("."), "suite-name", 261 metadata, test_cases); 262 263 { 264 const model::metadata exp_metadata = model::metadata_builder() 265 .add_allowed_architecture("base-arch") 266 .set_description("Base description") 267 .build(); 268 ATF_REQUIRE_EQ(exp_metadata, 269 test_program.find("inherit-all").get_metadata()); 270 } 271 272 { 273 const model::metadata exp_metadata = model::metadata_builder() 274 .add_allowed_architecture("base-arch") 275 .set_description("Overriden description") 276 .build(); 277 ATF_REQUIRE_EQ(exp_metadata, 278 test_program.find("inherit-some").get_metadata()); 279 } 280 281 { 282 const model::metadata exp_metadata = model::metadata_builder() 283 .add_allowed_architecture("overriden-arch") 284 .add_allowed_platform("overriden-platform") 285 .set_description("Overriden description") 286 .build(); 287 ATF_REQUIRE_EQ(exp_metadata, 288 test_program.find("inherit-none").get_metadata()); 289 } 290 } 291 292 293 ATF_TEST_CASE_WITHOUT_HEAD(metadata_inheritance); 294 ATF_TEST_CASE_BODY(metadata_inheritance) 295 { 296 check_metadata_inheritance< model::test_program >(); 297 } 298 299 300 ATF_TEST_CASE_WITHOUT_HEAD(derived__metadata_inheritance); 301 ATF_TEST_CASE_BODY(derived__metadata_inheritance) 302 { 303 check_metadata_inheritance< lazy_test_program >(); 304 } 305 306 307 /// Runs a operators_eq_and_ne__copy test. 308 /// 309 /// \tparam TestProgram Either model::test_program or lazy_test_program. 310 template< class TestProgram > 311 static void 312 check_operators_eq_and_ne__copy(void) 313 { 314 const TestProgram tp1( 315 "plain", fs::path("non-existent"), fs::path("."), "suite-name", 316 model::metadata_builder().build(), 317 model::test_cases_map()); 318 const TestProgram tp2 = tp1; 319 ATF_REQUIRE( tp1 == tp2); 320 ATF_REQUIRE(!(tp1 != tp2)); 321 } 322 323 324 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__copy); 325 ATF_TEST_CASE_BODY(operators_eq_and_ne__copy) 326 { 327 check_operators_eq_and_ne__copy< model::test_program >(); 328 } 329 330 331 ATF_TEST_CASE_WITHOUT_HEAD(derived__operators_eq_and_ne__copy); 332 ATF_TEST_CASE_BODY(derived__operators_eq_and_ne__copy) 333 { 334 check_operators_eq_and_ne__copy< lazy_test_program >(); 335 } 336 337 338 /// Runs a operators_eq_and_ne__not_copy test. 339 /// 340 /// \tparam TestProgram Either model::test_program or lazy_test_program. 341 template< class TestProgram > 342 static void 343 check_operators_eq_and_ne__not_copy(void) 344 { 345 const std::string base_interface("plain"); 346 const fs::path base_relative_path("the/test/program"); 347 const fs::path base_root("/the/root"); 348 const std::string base_test_suite("suite-name"); 349 const model::metadata base_metadata = model::metadata_builder() 350 .add_custom("foo", "bar") 351 .build(); 352 353 const model::test_cases_map base_tcs = model::test_cases_map_builder() 354 .add("main", model::metadata_builder() 355 .add_custom("second", "baz") 356 .build()) 357 .build(); 358 359 const TestProgram base_tp( 360 base_interface, base_relative_path, base_root, base_test_suite, 361 base_metadata, base_tcs); 362 363 // Construct with all same values. 364 { 365 const model::test_cases_map other_tcs = model::test_cases_map_builder() 366 .add("main", model::metadata_builder() 367 .add_custom("second", "baz") 368 .build()) 369 .build(); 370 371 const TestProgram other_tp( 372 base_interface, base_relative_path, base_root, base_test_suite, 373 base_metadata, other_tcs); 374 375 ATF_REQUIRE( base_tp == other_tp); 376 ATF_REQUIRE(!(base_tp != other_tp)); 377 } 378 379 // Construct with same final metadata values but using a different 380 // intermediate representation. The original test program has one property 381 // in the base test program definition and another in the test case; here, 382 // we put both definitions explicitly in the test case. 383 { 384 const model::test_cases_map other_tcs = model::test_cases_map_builder() 385 .add("main", model::metadata_builder() 386 .add_custom("foo", "bar") 387 .add_custom("second", "baz") 388 .build()) 389 .build(); 390 391 const TestProgram other_tp( 392 base_interface, base_relative_path, base_root, base_test_suite, 393 base_metadata, other_tcs); 394 395 ATF_REQUIRE( base_tp == other_tp); 396 ATF_REQUIRE(!(base_tp != other_tp)); 397 } 398 399 // Different interface. 400 { 401 const TestProgram other_tp( 402 "atf", base_relative_path, base_root, base_test_suite, 403 base_metadata, base_tcs); 404 405 ATF_REQUIRE(!(base_tp == other_tp)); 406 ATF_REQUIRE( base_tp != other_tp); 407 } 408 409 // Different relative path. 410 { 411 const TestProgram other_tp( 412 base_interface, fs::path("a/b/c"), base_root, base_test_suite, 413 base_metadata, base_tcs); 414 415 ATF_REQUIRE(!(base_tp == other_tp)); 416 ATF_REQUIRE( base_tp != other_tp); 417 } 418 419 // Different root. 420 { 421 const TestProgram other_tp( 422 base_interface, base_relative_path, fs::path("."), base_test_suite, 423 base_metadata, base_tcs); 424 425 ATF_REQUIRE(!(base_tp == other_tp)); 426 ATF_REQUIRE( base_tp != other_tp); 427 } 428 429 // Different test suite. 430 { 431 const TestProgram other_tp( 432 base_interface, base_relative_path, base_root, "different-suite", 433 base_metadata, base_tcs); 434 435 ATF_REQUIRE(!(base_tp == other_tp)); 436 ATF_REQUIRE( base_tp != other_tp); 437 } 438 439 // Different metadata. 440 { 441 const TestProgram other_tp( 442 base_interface, base_relative_path, base_root, base_test_suite, 443 model::metadata_builder().build(), base_tcs); 444 445 ATF_REQUIRE(!(base_tp == other_tp)); 446 ATF_REQUIRE( base_tp != other_tp); 447 } 448 449 // Different test cases. 450 { 451 const model::test_cases_map other_tcs = model::test_cases_map_builder() 452 .add("foo").build(); 453 454 const TestProgram other_tp( 455 base_interface, base_relative_path, base_root, base_test_suite, 456 base_metadata, other_tcs); 457 458 ATF_REQUIRE(!(base_tp == other_tp)); 459 ATF_REQUIRE( base_tp != other_tp); 460 } 461 } 462 463 464 ATF_TEST_CASE_WITHOUT_HEAD(operators_eq_and_ne__not_copy); 465 ATF_TEST_CASE_BODY(operators_eq_and_ne__not_copy) 466 { 467 check_operators_eq_and_ne__not_copy< model::test_program >(); 468 } 469 470 471 ATF_TEST_CASE_WITHOUT_HEAD(derived__operators_eq_and_ne__not_copy); 472 ATF_TEST_CASE_BODY(derived__operators_eq_and_ne__not_copy) 473 { 474 check_operators_eq_and_ne__not_copy< lazy_test_program >(); 475 } 476 477 478 /// Runs a operator_lt test. 479 /// 480 /// \tparam TestProgram Either model::test_program or lazy_test_program. 481 template< class TestProgram > 482 static void 483 check_operator_lt(void) 484 { 485 const TestProgram tp1( 486 "plain", fs::path("a/b/c"), fs::path("/foo/bar"), "suite-name", 487 model::metadata_builder().build(), 488 model::test_cases_map()); 489 const TestProgram tp2( 490 "atf", fs::path("c"), fs::path("/foo/bar"), "suite-name", 491 model::metadata_builder().build(), 492 model::test_cases_map()); 493 const TestProgram tp3( 494 "plain", fs::path("a/b/c"), fs::path("/abc"), "suite-name", 495 model::metadata_builder().build(), 496 model::test_cases_map()); 497 498 ATF_REQUIRE(!(tp1 < tp1)); 499 500 ATF_REQUIRE( tp1 < tp2); 501 ATF_REQUIRE(!(tp2 < tp1)); 502 503 ATF_REQUIRE(!(tp1 < tp3)); 504 ATF_REQUIRE( tp3 < tp1); 505 506 // And now, test the actual reason why we want to have an < overload by 507 // attempting to put the various programs in a set. 508 std::set< TestProgram > programs; 509 programs.insert(tp1); 510 programs.insert(tp2); 511 programs.insert(tp3); 512 } 513 514 515 ATF_TEST_CASE_WITHOUT_HEAD(operator_lt); 516 ATF_TEST_CASE_BODY(operator_lt) 517 { 518 check_operator_lt< model::test_program >(); 519 } 520 521 522 ATF_TEST_CASE_WITHOUT_HEAD(derived__operator_lt); 523 ATF_TEST_CASE_BODY(derived__operator_lt) 524 { 525 check_operator_lt< lazy_test_program >(); 526 } 527 528 529 /// Runs a output__no_test_cases test. 530 /// 531 /// \tparam TestProgram Either model::test_program or lazy_test_program. 532 template< class TestProgram > 533 static void 534 check_output__no_test_cases(void) 535 { 536 TestProgram tp( 537 "plain", fs::path("binary/path"), fs::path("/the/root"), "suite-name", 538 model::metadata_builder().add_allowed_architecture("a").build(), 539 model::test_cases_map()); 540 541 std::ostringstream str; 542 str << tp; 543 ATF_REQUIRE_EQ( 544 "test_program{interface='plain', binary='binary/path', " 545 "root='/the/root', test_suite='suite-name', " 546 "metadata=metadata{allowed_architectures='a', allowed_platforms='', " 547 "description='', has_cleanup='false', is_exclusive='false', " 548 "required_configs='', required_disk_space='0', required_files='', " 549 "required_memory='0', " 550 "required_programs='', required_user='', timeout='300'}, " 551 "test_cases=map()}", 552 str.str()); 553 } 554 555 556 ATF_TEST_CASE_WITHOUT_HEAD(output__no_test_cases); 557 ATF_TEST_CASE_BODY(output__no_test_cases) 558 { 559 check_output__no_test_cases< model::test_program >(); 560 } 561 562 563 ATF_TEST_CASE_WITHOUT_HEAD(derived__output__no_test_cases); 564 ATF_TEST_CASE_BODY(derived__output__no_test_cases) 565 { 566 check_output__no_test_cases< lazy_test_program >(); 567 } 568 569 570 /// Runs a output__some_test_cases test. 571 /// 572 /// \tparam TestProgram Either model::test_program or lazy_test_program. 573 template< class TestProgram > 574 static void 575 check_output__some_test_cases(void) 576 { 577 const model::test_cases_map test_cases = model::test_cases_map_builder() 578 .add("the-name", model::metadata_builder() 579 .add_allowed_platform("foo") 580 .add_custom("bar", "baz") 581 .build()) 582 .add("another-name") 583 .build(); 584 585 const TestProgram tp = TestProgram( 586 "plain", fs::path("binary/path"), fs::path("/the/root"), "suite-name", 587 model::metadata_builder().add_allowed_architecture("a").build(), 588 test_cases); 589 590 std::ostringstream str; 591 str << tp; 592 ATF_REQUIRE_EQ( 593 "test_program{interface='plain', binary='binary/path', " 594 "root='/the/root', test_suite='suite-name', " 595 "metadata=metadata{allowed_architectures='a', allowed_platforms='', " 596 "description='', has_cleanup='false', is_exclusive='false', " 597 "required_configs='', required_disk_space='0', required_files='', " 598 "required_memory='0', " 599 "required_programs='', required_user='', timeout='300'}, " 600 "test_cases=map(" 601 "another-name=test_case{name='another-name', " 602 "metadata=metadata{allowed_architectures='a', allowed_platforms='', " 603 "description='', has_cleanup='false', is_exclusive='false', " 604 "required_configs='', required_disk_space='0', required_files='', " 605 "required_memory='0', " 606 "required_programs='', required_user='', timeout='300'}}, " 607 "the-name=test_case{name='the-name', " 608 "metadata=metadata{allowed_architectures='a', allowed_platforms='foo', " 609 "custom.bar='baz', description='', has_cleanup='false', " 610 "is_exclusive='false', " 611 "required_configs='', required_disk_space='0', required_files='', " 612 "required_memory='0', " 613 "required_programs='', required_user='', timeout='300'}})}", 614 str.str()); 615 } 616 617 618 ATF_TEST_CASE_WITHOUT_HEAD(output__some_test_cases); 619 ATF_TEST_CASE_BODY(output__some_test_cases) 620 { 621 check_output__some_test_cases< model::test_program >(); 622 } 623 624 625 ATF_TEST_CASE_WITHOUT_HEAD(derived__output__some_test_cases); 626 ATF_TEST_CASE_BODY(derived__output__some_test_cases) 627 { 628 check_output__some_test_cases< lazy_test_program >(); 629 } 630 631 632 ATF_TEST_CASE_WITHOUT_HEAD(builder__defaults); 633 ATF_TEST_CASE_BODY(builder__defaults) 634 { 635 const model::test_program expected( 636 "mock", fs::path("non-existent"), fs::path("."), "suite-name", 637 model::metadata_builder().build(), model::test_cases_map()); 638 639 const model::test_program built = model::test_program_builder( 640 "mock", fs::path("non-existent"), fs::path("."), "suite-name") 641 .build(); 642 643 ATF_REQUIRE_EQ(built, expected); 644 } 645 646 647 ATF_TEST_CASE_WITHOUT_HEAD(builder__overrides); 648 ATF_TEST_CASE_BODY(builder__overrides) 649 { 650 const model::metadata md = model::metadata_builder() 651 .add_custom("foo", "bar") 652 .build(); 653 const model::test_cases_map tcs = model::test_cases_map_builder() 654 .add("first") 655 .add("second", md) 656 .build(); 657 const model::test_program expected( 658 "mock", fs::path("binary"), fs::path("root"), "suite-name", md, tcs); 659 660 const model::test_program built = model::test_program_builder( 661 "mock", fs::path("binary"), fs::path("root"), "suite-name") 662 .add_test_case("first") 663 .add_test_case("second", md) 664 .set_metadata(md) 665 .build(); 666 667 ATF_REQUIRE_EQ(built, expected); 668 } 669 670 671 ATF_TEST_CASE_WITHOUT_HEAD(builder__ptr); 672 ATF_TEST_CASE_BODY(builder__ptr) 673 { 674 const model::test_program expected( 675 "mock", fs::path("non-existent"), fs::path("."), "suite-name", 676 model::metadata_builder().build(), model::test_cases_map()); 677 678 const model::test_program_ptr built = model::test_program_builder( 679 "mock", fs::path("non-existent"), fs::path("."), "suite-name") 680 .build_ptr(); 681 682 ATF_REQUIRE_EQ(*built, expected); 683 } 684 685 686 ATF_INIT_TEST_CASES(tcs) 687 { 688 ATF_ADD_TEST_CASE(tcs, ctor_and_getters); 689 ATF_ADD_TEST_CASE(tcs, find__ok); 690 ATF_ADD_TEST_CASE(tcs, find__missing); 691 ATF_ADD_TEST_CASE(tcs, metadata_inheritance); 692 ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne__copy); 693 ATF_ADD_TEST_CASE(tcs, operators_eq_and_ne__not_copy); 694 ATF_ADD_TEST_CASE(tcs, operator_lt); 695 ATF_ADD_TEST_CASE(tcs, output__no_test_cases); 696 ATF_ADD_TEST_CASE(tcs, output__some_test_cases); 697 698 ATF_ADD_TEST_CASE(tcs, derived__ctor_and_getters); 699 ATF_ADD_TEST_CASE(tcs, derived__find__ok); 700 ATF_ADD_TEST_CASE(tcs, derived__find__missing); 701 ATF_ADD_TEST_CASE(tcs, derived__metadata_inheritance); 702 ATF_ADD_TEST_CASE(tcs, derived__operators_eq_and_ne__copy); 703 ATF_ADD_TEST_CASE(tcs, derived__operators_eq_and_ne__not_copy); 704 ATF_ADD_TEST_CASE(tcs, derived__operator_lt); 705 ATF_ADD_TEST_CASE(tcs, derived__output__no_test_cases); 706 ATF_ADD_TEST_CASE(tcs, derived__output__some_test_cases); 707 708 ATF_ADD_TEST_CASE(tcs, builder__defaults); 709 ATF_ADD_TEST_CASE(tcs, builder__overrides); 710 ATF_ADD_TEST_CASE(tcs, builder__ptr); 711 } 712