1// 2// Automated Testing Framework (atf) 3// 4// Copyright (c) 2010 The NetBSD Foundation, Inc. 5// All rights reserved. 6// 7// Redistribution and use in source and binary forms, with or without 8// modification, are permitted provided that the following conditions 9// are met: 10// 1. Redistributions of source code must retain the above copyright 11// notice, this list of conditions and the following disclaimer. 12// 2. Redistributions in binary form must reproduce the above copyright 13// notice, this list of conditions and the following disclaimer in the 14// documentation and/or other materials provided with the distribution. 15// 16// THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 17// CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 18// INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20// IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 21// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 22// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 23// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 25// IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 26// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27// IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28// 29 30#include <fstream> 31#include <iostream> 32 33#include "atf-c++/macros.hpp" 34 35#include "atf-c++/detail/parser.hpp" 36#include "atf-c++/detail/test_helpers.hpp" 37#include "atf-c++/detail/text.hpp" 38 39#include "test-program.hpp" 40 41namespace impl = atf::atf_run; 42namespace detail = atf::atf_run::detail; 43 44using atf::tests::vars_map; 45 46// ------------------------------------------------------------------------- 47// Auxiliary functions. 48// ------------------------------------------------------------------------- 49 50static 51atf::fs::path 52get_helper(const atf::tests::tc& tc, const char* name) 53{ 54 return atf::fs::path(tc.get_config_var("srcdir")) / name; 55} 56 57static 58void 59check_property(const vars_map& props, const char* name, const char* value) 60{ 61 const vars_map::const_iterator iter = props.find(name); 62 ATF_REQUIRE(iter != props.end()); 63 ATF_REQUIRE_EQ(value, (*iter).second); 64} 65 66static void 67check_result(const char* exp_state, const int exp_value, const char* exp_reason, 68 const impl::test_case_result& tcr) 69{ 70 ATF_REQUIRE_EQ(exp_state, tcr.state()); 71 ATF_REQUIRE_EQ(exp_value, tcr.value()); 72 ATF_REQUIRE_EQ(exp_reason, tcr.reason()); 73} 74 75static 76void 77write_test_case_result(const char *results_path, const std::string& contents) 78{ 79 std::ofstream results_file(results_path); 80 ATF_REQUIRE(results_file); 81 82 results_file << contents; 83} 84 85static 86void 87print_indented(const std::string& str) 88{ 89 std::vector< std::string > ws = atf::text::split(str, "\n"); 90 for (std::vector< std::string >::const_iterator iter = ws.begin(); 91 iter != ws.end(); iter++) 92 std::cout << ">>" << *iter << "<<\n"; 93} 94 95// XXX Should this string handling and verbosity level be part of the 96// ATF_REQUIRE_EQ macro? It may be hard to predict sometimes that a 97// string can have newlines in it, and so the error message generated 98// at the moment will be bogus if there are some. 99static 100void 101check_match(const atf::tests::tc& tc, const std::string& str, 102 const std::string& exp) 103{ 104 if (!atf::text::match(str, exp)) { 105 std::cout << "String match check failed.\n" 106 << "Adding >> and << to delimit the string boundaries " 107 "below.\n"; 108 std::cout << "GOT:\n"; 109 print_indented(str); 110 std::cout << "EXPECTED:\n"; 111 print_indented(exp); 112 tc.fail("Constructed string differs from the expected one"); 113 } 114} 115 116// ------------------------------------------------------------------------- 117// Tests for the "tp" reader. 118// ------------------------------------------------------------------------- 119 120class tp_reader : protected detail::atf_tp_reader { 121 void 122 got_tc(const std::string& ident, 123 const std::map< std::string, std::string >& md) 124 { 125 std::string call = "got_tc(" + ident + ", {"; 126 for (std::map< std::string, std::string >::const_iterator iter = 127 md.begin(); iter != md.end(); iter++) { 128 if (iter != md.begin()) 129 call += ", "; 130 call += (*iter).first + '=' + (*iter).second; 131 } 132 call += "})"; 133 m_calls.push_back(call); 134 } 135 136 void 137 got_eof(void) 138 { 139 m_calls.push_back("got_eof()"); 140 } 141 142public: 143 tp_reader(std::istream& is) : 144 detail::atf_tp_reader(is) 145 { 146 } 147 148 void 149 read(void) 150 { 151 atf_tp_reader::read(); 152 } 153 154 std::vector< std::string > m_calls; 155}; 156 157ATF_TEST_CASE_WITHOUT_HEAD(tp_1); 158ATF_TEST_CASE_BODY(tp_1) 159{ 160 const char* input = 161 "Content-Type: application/X-atf-tp; version=\"1\"\n" 162 "\n" 163 "ident: test_case_1\n" 164 "\n" 165 "ident: test_case_2\n" 166 "\n" 167 "ident: test_case_3\n" 168 ; 169 170 const char* exp_calls[] = { 171 "got_tc(test_case_1, {ident=test_case_1})", 172 "got_tc(test_case_2, {ident=test_case_2})", 173 "got_tc(test_case_3, {ident=test_case_3})", 174 "got_eof()", 175 NULL 176 }; 177 178 const char* exp_errors[] = { 179 NULL 180 }; 181 182 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 183} 184 185ATF_TEST_CASE_WITHOUT_HEAD(tp_2); 186ATF_TEST_CASE_BODY(tp_2) 187{ 188 const char* input = 189 "Content-Type: application/X-atf-tp; version=\"1\"\n" 190 "\n" 191 "ident: test_case_1\n" 192 "descr: This is the description\n" 193 "timeout: 300\n" 194 "\n" 195 "ident: test_case_2\n" 196 "\n" 197 "ident: test_case_3\n" 198 "X-prop1: A custom property\n" 199 "descr: Third test case\n" 200 ; 201 202 // NO_CHECK_STYLE_BEGIN 203 const char* exp_calls[] = { 204 "got_tc(test_case_1, {descr=This is the description, ident=test_case_1, timeout=300})", 205 "got_tc(test_case_2, {ident=test_case_2})", 206 "got_tc(test_case_3, {X-prop1=A custom property, descr=Third test case, ident=test_case_3})", 207 "got_eof()", 208 NULL 209 }; 210 // NO_CHECK_STYLE_END 211 212 const char* exp_errors[] = { 213 NULL 214 }; 215 216 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 217} 218 219ATF_TEST_CASE_WITHOUT_HEAD(tp_3); 220ATF_TEST_CASE_BODY(tp_3) 221{ 222 const char* input = 223 "Content-Type: application/X-atf-tp; version=\"1\"\n" 224 "\n" 225 "ident: single_test\n" 226 "descr: Some description\n" 227 "timeout: 300\n" 228 "require.arch: thearch\n" 229 "require.config: foo-bar\n" 230 "require.files: /a/1 /b/2\n" 231 "require.machine: themachine\n" 232 "require.progs: /bin/cp mv\n" 233 "require.user: root\n" 234 ; 235 236 // NO_CHECK_STYLE_BEGIN 237 const char* exp_calls[] = { 238 "got_tc(single_test, {descr=Some description, ident=single_test, require.arch=thearch, require.config=foo-bar, require.files=/a/1 /b/2, require.machine=themachine, require.progs=/bin/cp mv, require.user=root, timeout=300})", 239 "got_eof()", 240 NULL 241 }; 242 // NO_CHECK_STYLE_END 243 244 const char* exp_errors[] = { 245 NULL 246 }; 247 248 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 249} 250 251ATF_TEST_CASE_WITHOUT_HEAD(tp_4); 252ATF_TEST_CASE_BODY(tp_4) 253{ 254 const char* input = 255 "Content-Type: application/X-atf-tp; version=\"1\"\n" 256 "\n" 257 "ident: single_test \n" 258 "descr: Some description \n" 259 ; 260 261 const char* exp_calls[] = { 262 "got_tc(single_test, {descr=Some description, ident=single_test})", 263 "got_eof()", 264 NULL 265 }; 266 267 const char* exp_errors[] = { 268 NULL 269 }; 270 271 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 272} 273 274ATF_TEST_CASE_WITHOUT_HEAD(tp_50); 275ATF_TEST_CASE_BODY(tp_50) 276{ 277 const char* input = 278 "Content-Type: application/X-atf-tp; version=\"1\"\n" 279 "\n" 280 ; 281 282 const char* exp_calls[] = { 283 NULL 284 }; 285 286 const char* exp_errors[] = { 287 "3: Unexpected token `<<EOF>>'; expected property name", 288 NULL 289 }; 290 291 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 292} 293 294ATF_TEST_CASE_WITHOUT_HEAD(tp_51); 295ATF_TEST_CASE_BODY(tp_51) 296{ 297 const char* input = 298 "Content-Type: application/X-atf-tp; version=\"1\"\n" 299 "\n" 300 "\n" 301 "\n" 302 "\n" 303 ; 304 305 const char* exp_calls[] = { 306 NULL 307 }; 308 309 const char* exp_errors[] = { 310 "3: Unexpected token `<<NEWLINE>>'; expected property name", 311 NULL 312 }; 313 314 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 315} 316 317ATF_TEST_CASE_WITHOUT_HEAD(tp_52); 318ATF_TEST_CASE_BODY(tp_52) 319{ 320 const char* input = 321 "Content-Type: application/X-atf-tp; version=\"1\"\n" 322 "\n" 323 "ident: test1\n" 324 "ident: test2\n" 325 ; 326 327 const char* exp_calls[] = { 328 "got_tc(test1, {ident=test1})", 329 "got_eof()", 330 NULL 331 }; 332 333 const char* exp_errors[] = { 334 NULL 335 }; 336 337 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 338} 339 340ATF_TEST_CASE_WITHOUT_HEAD(tp_53); 341ATF_TEST_CASE_BODY(tp_53) 342{ 343 const char* input = 344 "Content-Type: application/X-atf-tp; version=\"1\"\n" 345 "\n" 346 "descr: Out of order\n" 347 "ident: test1\n" 348 ; 349 350 const char* exp_calls[] = { 351 NULL 352 }; 353 354 const char* exp_errors[] = { 355 "3: First property of a test case must be 'ident'", 356 NULL 357 }; 358 359 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 360} 361 362ATF_TEST_CASE_WITHOUT_HEAD(tp_54); 363ATF_TEST_CASE_BODY(tp_54) 364{ 365 const char* input = 366 "Content-Type: application/X-atf-tp; version=\"1\"\n" 367 "\n" 368 "ident:\n" 369 ; 370 371 const char* exp_calls[] = { 372 NULL 373 }; 374 375 const char* exp_errors[] = { 376 "3: The value for 'ident' cannot be empty", 377 NULL 378 }; 379 380 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 381} 382 383ATF_TEST_CASE_WITHOUT_HEAD(tp_55); 384ATF_TEST_CASE_BODY(tp_55) 385{ 386 const char* input = 387 "Content-Type: application/X-atf-tp; version=\"1\"\n" 388 "\n" 389 "ident: +*,\n" 390 ; 391 392 const char* exp_calls[] = { 393 NULL 394 }; 395 396 const char* exp_errors[] = { 397 "3: The identifier must match ^[_A-Za-z0-9]+$; was '+*,'", 398 NULL 399 }; 400 401 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 402} 403 404ATF_TEST_CASE_WITHOUT_HEAD(tp_56); 405ATF_TEST_CASE_BODY(tp_56) 406{ 407 const char* input = 408 "Content-Type: application/X-atf-tp; version=\"1\"\n" 409 "\n" 410 "ident: test\n" 411 "timeout: hello\n" 412 ; 413 414 const char* exp_calls[] = { 415 NULL 416 }; 417 418 const char* exp_errors[] = { 419 "4: The timeout property requires an integer value", 420 NULL 421 }; 422 423 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 424} 425 426ATF_TEST_CASE_WITHOUT_HEAD(tp_57); 427ATF_TEST_CASE_BODY(tp_57) 428{ 429 const char* input = 430 "Content-Type: application/X-atf-tp; version=\"1\"\n" 431 "\n" 432 "ident: test\n" 433 "unknown: property\n" 434 ; 435 436 const char* exp_calls[] = { 437 NULL 438 }; 439 440 const char* exp_errors[] = { 441 "4: Unknown property 'unknown'", 442 NULL 443 }; 444 445 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 446} 447 448ATF_TEST_CASE_WITHOUT_HEAD(tp_58); 449ATF_TEST_CASE_BODY(tp_58) 450{ 451 const char* input = 452 "Content-Type: application/X-atf-tp; version=\"1\"\n" 453 "\n" 454 "ident: test\n" 455 "X-foo:\n" 456 ; 457 458 const char* exp_calls[] = { 459 NULL 460 }; 461 462 const char* exp_errors[] = { 463 "4: The value for 'X-foo' cannot be empty", 464 NULL 465 }; 466 467 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 468} 469 470ATF_TEST_CASE_WITHOUT_HEAD(tp_59); 471ATF_TEST_CASE_BODY(tp_59) 472{ 473 const char* input = 474 "Content-Type: application/X-atf-tp; version=\"1\"\n" 475 "\n" 476 "\n" 477 "ident: test\n" 478 "timeout: 300\n" 479 ; 480 481 const char* exp_calls[] = { 482 NULL 483 }; 484 485 const char* exp_errors[] = { 486 "3: Unexpected token `<<NEWLINE>>'; expected property name", 487 NULL 488 }; 489 490 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 491} 492 493ATF_TEST_CASE_WITHOUT_HEAD(tp_60); 494ATF_TEST_CASE_BODY(tp_60) 495{ 496 const char* input = 497 "Content-Type: application/X-atf-tp; version=\"1\"\n" 498 "\n" 499 "ident: test\n" 500 "require.memory: 12345D\n" 501 ; 502 503 const char* exp_calls[] = { 504 NULL 505 }; 506 507 const char* exp_errors[] = { 508 "4: The require.memory property requires an integer value representing" 509 " an amount of bytes", 510 NULL 511 }; 512 513 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 514} 515 516// ------------------------------------------------------------------------- 517// Tests for the "tps" writer. 518// ------------------------------------------------------------------------- 519 520ATF_TEST_CASE(atf_tps_writer); 521ATF_TEST_CASE_HEAD(atf_tps_writer) 522{ 523 set_md_var("descr", "Verifies the application/X-atf-tps writer"); 524} 525ATF_TEST_CASE_BODY(atf_tps_writer) 526{ 527 std::ostringstream expss; 528 std::ostringstream ss; 529 const char *ts_regex = "[0-9]+\\.[0-9]{1,6}, "; 530 531#define RESET \ 532 expss.str(""); \ 533 ss.str("") 534 535#define CHECK \ 536 check_match(*this, ss.str(), expss.str()) 537 538 { 539 RESET; 540 541 impl::atf_tps_writer w(ss); 542 expss << "Content-Type: application/X-atf-tps; version=\"3\"\n\n"; 543 CHECK; 544 } 545 546 { 547 RESET; 548 549 impl::atf_tps_writer w(ss); 550 expss << "Content-Type: application/X-atf-tps; version=\"3\"\n\n"; 551 CHECK; 552 553 w.info("foo", "bar"); 554 expss << "info: foo, bar\n"; 555 CHECK; 556 557 w.info("baz", "second info"); 558 expss << "info: baz, second info\n"; 559 CHECK; 560 } 561 562 { 563 RESET; 564 565 impl::atf_tps_writer w(ss); 566 expss << "Content-Type: application/X-atf-tps; version=\"3\"\n\n"; 567 CHECK; 568 569 w.ntps(0); 570 expss << "tps-count: 0\n"; 571 CHECK; 572 } 573 574 { 575 RESET; 576 577 impl::atf_tps_writer w(ss); 578 expss << "Content-Type: application/X-atf-tps; version=\"3\"\n\n"; 579 CHECK; 580 581 w.ntps(123); 582 expss << "tps-count: 123\n"; 583 CHECK; 584 } 585 586 { 587 RESET; 588 589 impl::atf_tps_writer w(ss); 590 expss << "Content-Type: application/X-atf-tps; version=\"3\"\n\n"; 591 CHECK; 592 593 w.ntps(2); 594 expss << "tps-count: 2\n"; 595 CHECK; 596 597 w.start_tp("foo", 0); 598 expss << "tp-start: " << ts_regex << "foo, 0\n"; 599 CHECK; 600 601 w.end_tp(""); 602 expss << "tp-end: " << ts_regex << "foo\n"; 603 CHECK; 604 605 w.start_tp("bar", 0); 606 expss << "tp-start: " << ts_regex << "bar, 0\n"; 607 CHECK; 608 609 w.end_tp("failed program"); 610 expss << "tp-end: " << ts_regex << "bar, failed program\n"; 611 CHECK; 612 } 613 614 { 615 RESET; 616 617 impl::atf_tps_writer w(ss); 618 expss << "Content-Type: application/X-atf-tps; version=\"3\"\n\n"; 619 CHECK; 620 621 w.ntps(1); 622 expss << "tps-count: 1\n"; 623 CHECK; 624 625 w.start_tp("foo", 1); 626 expss << "tp-start: " << ts_regex << "foo, 1\n"; 627 CHECK; 628 629 w.start_tc("brokentc"); 630 expss << "tc-start: " << ts_regex << "brokentc\n"; 631 CHECK; 632 633 w.end_tp("aborted"); 634 expss << "tp-end: " << ts_regex << "foo, aborted\n"; 635 CHECK; 636 } 637 638 { 639 RESET; 640 641 impl::atf_tps_writer w(ss); 642 expss << "Content-Type: application/X-atf-tps; version=\"3\"\n\n"; 643 CHECK; 644 645 w.ntps(1); 646 expss << "tps-count: 1\n"; 647 CHECK; 648 649 w.start_tp("thetp", 3); 650 expss << "tp-start: " << ts_regex << "thetp, 3\n"; 651 CHECK; 652 653 w.start_tc("passtc"); 654 expss << "tc-start: " << ts_regex << "passtc\n"; 655 CHECK; 656 657 w.end_tc("passed", ""); 658 expss << "tc-end: " << ts_regex << "passtc, passed\n"; 659 CHECK; 660 661 w.start_tc("failtc"); 662 expss << "tc-start: " << ts_regex << "failtc\n"; 663 CHECK; 664 665 w.end_tc("failed", "The reason"); 666 expss << "tc-end: " << ts_regex << "failtc, failed, The reason\n"; 667 CHECK; 668 669 w.start_tc("skiptc"); 670 expss << "tc-start: " << ts_regex << "skiptc\n"; 671 CHECK; 672 673 w.end_tc("skipped", "The reason"); 674 expss << "tc-end: " << ts_regex << "skiptc, skipped, The reason\n"; 675 CHECK; 676 677 w.end_tp(""); 678 expss << "tp-end: " << ts_regex << "thetp\n"; 679 CHECK; 680 } 681 682 { 683 RESET; 684 685 impl::atf_tps_writer w(ss); 686 expss << "Content-Type: application/X-atf-tps; version=\"3\"\n\n"; 687 CHECK; 688 689 w.ntps(1); 690 expss << "tps-count: 1\n"; 691 CHECK; 692 693 w.start_tp("thetp", 1); 694 expss << "tp-start: " << ts_regex << "thetp, 1\n"; 695 CHECK; 696 697 w.start_tc("thetc"); 698 expss << "tc-start: " << ts_regex << "thetc\n"; 699 CHECK; 700 701 w.stdout_tc("a line"); 702 expss << "tc-so:a line\n"; 703 CHECK; 704 705 w.stdout_tc("another line"); 706 expss << "tc-so:another line\n"; 707 CHECK; 708 709 w.stderr_tc("an error message"); 710 expss << "tc-se:an error message\n"; 711 CHECK; 712 713 w.end_tc("passed", ""); 714 expss << "tc-end: " << ts_regex << "thetc, passed\n"; 715 CHECK; 716 717 w.end_tp(""); 718 expss << "tp-end: " << ts_regex << "thetp\n"; 719 CHECK; 720 } 721 722 { 723 RESET; 724 725 impl::atf_tps_writer w(ss); 726 expss << "Content-Type: application/X-atf-tps; version=\"3\"\n\n"; 727 CHECK; 728 729 w.ntps(1); 730 expss << "tps-count: 1\n"; 731 CHECK; 732 733 w.start_tp("thetp", 0); 734 expss << "tp-start: " << ts_regex << "thetp, 0\n"; 735 CHECK; 736 737 w.end_tp(""); 738 expss << "tp-end: " << ts_regex << "thetp\n"; 739 CHECK; 740 741 w.info("foo", "bar"); 742 expss << "info: foo, bar\n"; 743 CHECK; 744 745 w.info("baz", "second value"); 746 expss << "info: baz, second value\n"; 747 CHECK; 748 } 749 750#undef CHECK 751#undef RESET 752} 753 754// ------------------------------------------------------------------------- 755// Tests for the free functions. 756// ------------------------------------------------------------------------- 757 758ATF_TEST_CASE(get_metadata_bad); 759ATF_TEST_CASE_HEAD(get_metadata_bad) {} 760ATF_TEST_CASE_BODY(get_metadata_bad) { 761 const atf::fs::path executable = get_helper(*this, "bad_metadata_helper"); 762 ATF_REQUIRE_THROW(atf::parser::parse_errors, 763 impl::get_metadata(executable, vars_map())); 764} 765 766ATF_TEST_CASE(get_metadata_zero_tcs); 767ATF_TEST_CASE_HEAD(get_metadata_zero_tcs) {} 768ATF_TEST_CASE_BODY(get_metadata_zero_tcs) { 769 const atf::fs::path executable = get_helper(*this, "zero_tcs_helper"); 770 ATF_REQUIRE_THROW(atf::parser::parse_errors, 771 impl::get_metadata(executable, vars_map())); 772} 773 774ATF_TEST_CASE(get_metadata_several_tcs); 775ATF_TEST_CASE_HEAD(get_metadata_several_tcs) {} 776ATF_TEST_CASE_BODY(get_metadata_several_tcs) { 777 const atf::fs::path executable = get_helper(*this, "several_tcs_helper"); 778 const impl::metadata md = impl::get_metadata(executable, vars_map()); 779 ATF_REQUIRE_EQ(3, md.test_cases.size()); 780 781 { 782 const impl::test_cases_map::const_iterator iter = 783 md.test_cases.find("first"); 784 ATF_REQUIRE(iter != md.test_cases.end()); 785 786 ATF_REQUIRE_EQ(4, (*iter).second.size()); 787 check_property((*iter).second, "descr", "Description 1"); 788 check_property((*iter).second, "has.cleanup", "false"); 789 check_property((*iter).second, "ident", "first"); 790 check_property((*iter).second, "timeout", "300"); 791 } 792 793 { 794 const impl::test_cases_map::const_iterator iter = 795 md.test_cases.find("second"); 796 ATF_REQUIRE(iter != md.test_cases.end()); 797 798 ATF_REQUIRE_EQ(5, (*iter).second.size()); 799 check_property((*iter).second, "descr", "Description 2"); 800 check_property((*iter).second, "has.cleanup", "true"); 801 check_property((*iter).second, "ident", "second"); 802 check_property((*iter).second, "timeout", "500"); 803 check_property((*iter).second, "X-property", "Custom property"); 804 } 805 806 { 807 const impl::test_cases_map::const_iterator iter = 808 md.test_cases.find("third"); 809 ATF_REQUIRE(iter != md.test_cases.end()); 810 811 ATF_REQUIRE_EQ(3, (*iter).second.size()); 812 check_property((*iter).second, "has.cleanup", "false"); 813 check_property((*iter).second, "ident", "third"); 814 check_property((*iter).second, "timeout", "300"); 815 } 816} 817 818ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_death); 819ATF_TEST_CASE_BODY(parse_test_case_result_expected_death) { 820 check_result("expected_death", -1, "foo bar", 821 detail::parse_test_case_result("expected_death: foo bar")); 822 823 ATF_REQUIRE_THROW(std::runtime_error, 824 detail::parse_test_case_result("expected_death")); 825 ATF_REQUIRE_THROW(std::runtime_error, 826 detail::parse_test_case_result("expected_death(3): foo")); 827} 828 829ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_exit); 830ATF_TEST_CASE_BODY(parse_test_case_result_expected_exit) { 831 check_result("expected_exit", -1, "foo bar", 832 detail::parse_test_case_result("expected_exit: foo bar")); 833 check_result("expected_exit", -1, "foo bar", 834 detail::parse_test_case_result("expected_exit(): foo bar")); 835 check_result("expected_exit", 5, "foo bar", 836 detail::parse_test_case_result("expected_exit(5): foo bar")); 837 838 ATF_REQUIRE_THROW(std::runtime_error, 839 detail::parse_test_case_result("expected_exit")); 840 ATF_REQUIRE_THROW(std::runtime_error, 841 detail::parse_test_case_result("expected_exit(")); 842} 843 844ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_failure); 845ATF_TEST_CASE_BODY(parse_test_case_result_expected_failure) { 846 check_result("expected_failure", -1, "foo bar", 847 detail::parse_test_case_result("expected_failure: foo bar")); 848 849 ATF_REQUIRE_THROW(std::runtime_error, 850 detail::parse_test_case_result("expected_failure")); 851 ATF_REQUIRE_THROW(std::runtime_error, 852 detail::parse_test_case_result("expected_failure(3): foo")); 853} 854 855ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_signal); 856ATF_TEST_CASE_BODY(parse_test_case_result_expected_signal) { 857 check_result("expected_signal", -1, "foo bar", 858 detail::parse_test_case_result("expected_signal: foo bar")); 859 check_result("expected_signal", -1, "foo bar", 860 detail::parse_test_case_result("expected_signal(): foo bar")); 861 check_result("expected_signal", 5, "foo bar", 862 detail::parse_test_case_result("expected_signal(5): foo bar")); 863 864 ATF_REQUIRE_THROW(std::runtime_error, 865 detail::parse_test_case_result("expected_signal")); 866 ATF_REQUIRE_THROW(std::runtime_error, 867 detail::parse_test_case_result("expected_signal(")); 868} 869 870ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_timeout); 871ATF_TEST_CASE_BODY(parse_test_case_result_expected_timeout) { 872 check_result("expected_timeout", -1, "foo bar", 873 detail::parse_test_case_result("expected_timeout: foo bar")); 874 875 ATF_REQUIRE_THROW(std::runtime_error, 876 detail::parse_test_case_result("expected_timeout")); 877 ATF_REQUIRE_THROW(std::runtime_error, 878 detail::parse_test_case_result("expected_timeout(3): foo")); 879} 880 881ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_failed); 882ATF_TEST_CASE_BODY(parse_test_case_result_failed) { 883 check_result("failed", -1, "foo bar", 884 detail::parse_test_case_result("failed: foo bar")); 885 886 ATF_REQUIRE_THROW(std::runtime_error, 887 detail::parse_test_case_result("failed")); 888 ATF_REQUIRE_THROW(std::runtime_error, 889 detail::parse_test_case_result("failed(3): foo")); 890} 891 892ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_passed); 893ATF_TEST_CASE_BODY(parse_test_case_result_passed) { 894 check_result("passed", -1, "", 895 detail::parse_test_case_result("passed")); 896 897 ATF_REQUIRE_THROW(std::runtime_error, 898 detail::parse_test_case_result("passed: foo")); 899 ATF_REQUIRE_THROW(std::runtime_error, 900 detail::parse_test_case_result("passed(3): foo")); 901} 902 903ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_skipped); 904ATF_TEST_CASE_BODY(parse_test_case_result_skipped) { 905 check_result("skipped", -1, "foo bar", 906 detail::parse_test_case_result("skipped: foo bar")); 907 908 ATF_REQUIRE_THROW(std::runtime_error, 909 detail::parse_test_case_result("skipped")); 910 ATF_REQUIRE_THROW(std::runtime_error, 911 detail::parse_test_case_result("skipped(3): foo")); 912} 913 914ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_unknown); 915ATF_TEST_CASE_BODY(parse_test_case_result_unknown) { 916 ATF_REQUIRE_THROW(std::runtime_error, 917 detail::parse_test_case_result("foo")); 918 ATF_REQUIRE_THROW(std::runtime_error, 919 detail::parse_test_case_result("bar: foo")); 920 ATF_REQUIRE_THROW(std::runtime_error, 921 detail::parse_test_case_result("baz: foo")); 922} 923 924ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_failed); 925ATF_TEST_CASE_BODY(read_test_case_result_failed) { 926 write_test_case_result("resfile", "failed: foo bar\n"); 927 const impl::test_case_result tcr = impl::read_test_case_result( 928 atf::fs::path("resfile")); 929 ATF_REQUIRE_EQ("failed", tcr.state()); 930 ATF_REQUIRE_EQ("foo bar", tcr.reason()); 931} 932 933ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_skipped); 934ATF_TEST_CASE_BODY(read_test_case_result_skipped) { 935 write_test_case_result("resfile", "skipped: baz bar\n"); 936 const impl::test_case_result tcr = impl::read_test_case_result( 937 atf::fs::path("resfile")); 938 ATF_REQUIRE_EQ("skipped", tcr.state()); 939 ATF_REQUIRE_EQ("baz bar", tcr.reason()); 940} 941 942 943ATF_TEST_CASE(read_test_case_result_no_file); 944ATF_TEST_CASE_HEAD(read_test_case_result_no_file) {} 945ATF_TEST_CASE_BODY(read_test_case_result_no_file) { 946 ATF_REQUIRE_THROW(std::runtime_error, 947 impl::read_test_case_result(atf::fs::path("resfile"))); 948} 949 950ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_empty_file); 951ATF_TEST_CASE_BODY(read_test_case_result_empty_file) { 952 write_test_case_result("resfile", ""); 953 ATF_REQUIRE_THROW(std::runtime_error, 954 impl::read_test_case_result(atf::fs::path("resfile"))); 955} 956 957ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_invalid); 958ATF_TEST_CASE_BODY(read_test_case_result_invalid) { 959 write_test_case_result("resfile", "passed: hello\n"); 960 ATF_REQUIRE_THROW(std::runtime_error, 961 impl::read_test_case_result(atf::fs::path("resfile"))); 962} 963 964ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_multiline); 965ATF_TEST_CASE_BODY(read_test_case_result_multiline) { 966 write_test_case_result("resfile", "skipped: foo\nbar\n"); 967 const impl::test_case_result tcr = impl::read_test_case_result( 968 atf::fs::path("resfile")); 969 ATF_REQUIRE_EQ("skipped", tcr.state()); 970 ATF_REQUIRE_EQ("foo<<NEWLINE UNEXPECTED>>bar", tcr.reason()); 971} 972 973// ------------------------------------------------------------------------- 974// Main. 975// ------------------------------------------------------------------------- 976 977ATF_INIT_TEST_CASES(tcs) 978{ 979 ATF_ADD_TEST_CASE(tcs, tp_1); 980 ATF_ADD_TEST_CASE(tcs, tp_2); 981 ATF_ADD_TEST_CASE(tcs, tp_3); 982 ATF_ADD_TEST_CASE(tcs, tp_4); 983 ATF_ADD_TEST_CASE(tcs, tp_50); 984 ATF_ADD_TEST_CASE(tcs, tp_51); 985 ATF_ADD_TEST_CASE(tcs, tp_52); 986 ATF_ADD_TEST_CASE(tcs, tp_53); 987 ATF_ADD_TEST_CASE(tcs, tp_54); 988 ATF_ADD_TEST_CASE(tcs, tp_55); 989 ATF_ADD_TEST_CASE(tcs, tp_56); 990 ATF_ADD_TEST_CASE(tcs, tp_57); 991 ATF_ADD_TEST_CASE(tcs, tp_58); 992 ATF_ADD_TEST_CASE(tcs, tp_59); 993 ATF_ADD_TEST_CASE(tcs, tp_60); 994 995 ATF_ADD_TEST_CASE(tcs, atf_tps_writer); 996 997 ATF_ADD_TEST_CASE(tcs, get_metadata_bad); 998 ATF_ADD_TEST_CASE(tcs, get_metadata_zero_tcs); 999 ATF_ADD_TEST_CASE(tcs, get_metadata_several_tcs); 1000 1001 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_death); 1002 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_exit); 1003 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_failure); 1004 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_signal); 1005 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_timeout); 1006 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_failed); 1007 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_passed); 1008 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_skipped); 1009 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_unknown); 1010 1011 ATF_ADD_TEST_CASE(tcs, read_test_case_result_failed); 1012 ATF_ADD_TEST_CASE(tcs, read_test_case_result_skipped); 1013 ATF_ADD_TEST_CASE(tcs, read_test_case_result_no_file); 1014 ATF_ADD_TEST_CASE(tcs, read_test_case_result_empty_file); 1015 ATF_ADD_TEST_CASE(tcs, read_test_case_result_multiline); 1016 ATF_ADD_TEST_CASE(tcs, read_test_case_result_invalid); 1017 1018 // TODO: Add tests for run_test_case once all the missing functionality 1019 // is implemented. 1020} 1021