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_equal(const atf::tests::tc& tc, const std::string& str, 102 const std::string& exp) 103{ 104 if (str != exp) { 105 std::cout << "String equality 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: 30\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=30})", 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: 30\n" 228 "require.arch: thearch\n" 229 "require.config: foo-bar\n" 230 "require.machine: themachine\n" 231 "require.progs: /bin/cp mv\n" 232 "require.user: root\n" 233 ; 234 235 // NO_CHECK_STYLE_BEGIN 236 const char* exp_calls[] = { 237 "got_tc(single_test, {descr=Some description, ident=single_test, require.arch=thearch, require.config=foo-bar, require.machine=themachine, require.progs=/bin/cp mv, require.user=root, timeout=30})", 238 "got_eof()", 239 NULL 240 }; 241 // NO_CHECK_STYLE_END 242 243 const char* exp_errors[] = { 244 NULL 245 }; 246 247 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 248} 249 250ATF_TEST_CASE_WITHOUT_HEAD(tp_4); 251ATF_TEST_CASE_BODY(tp_4) 252{ 253 const char* input = 254 "Content-Type: application/X-atf-tp; version=\"1\"\n" 255 "\n" 256 "ident: single_test \n" 257 "descr: Some description \n" 258 ; 259 260 const char* exp_calls[] = { 261 "got_tc(single_test, {descr=Some description, ident=single_test})", 262 "got_eof()", 263 NULL 264 }; 265 266 const char* exp_errors[] = { 267 NULL 268 }; 269 270 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 271} 272 273ATF_TEST_CASE_WITHOUT_HEAD(tp_50); 274ATF_TEST_CASE_BODY(tp_50) 275{ 276 const char* input = 277 "Content-Type: application/X-atf-tp; version=\"1\"\n" 278 "\n" 279 ; 280 281 const char* exp_calls[] = { 282 NULL 283 }; 284 285 const char* exp_errors[] = { 286 "3: Unexpected token `<<EOF>>'; expected property name", 287 NULL 288 }; 289 290 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 291} 292 293ATF_TEST_CASE_WITHOUT_HEAD(tp_51); 294ATF_TEST_CASE_BODY(tp_51) 295{ 296 const char* input = 297 "Content-Type: application/X-atf-tp; version=\"1\"\n" 298 "\n" 299 "\n" 300 "\n" 301 "\n" 302 ; 303 304 const char* exp_calls[] = { 305 NULL 306 }; 307 308 const char* exp_errors[] = { 309 "3: Unexpected token `<<NEWLINE>>'; expected property name", 310 NULL 311 }; 312 313 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 314} 315 316ATF_TEST_CASE_WITHOUT_HEAD(tp_52); 317ATF_TEST_CASE_BODY(tp_52) 318{ 319 const char* input = 320 "Content-Type: application/X-atf-tp; version=\"1\"\n" 321 "\n" 322 "ident: test1\n" 323 "ident: test2\n" 324 ; 325 326 const char* exp_calls[] = { 327 "got_tc(test1, {ident=test1})", 328 "got_eof()", 329 NULL 330 }; 331 332 const char* exp_errors[] = { 333 NULL 334 }; 335 336 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 337} 338 339ATF_TEST_CASE_WITHOUT_HEAD(tp_53); 340ATF_TEST_CASE_BODY(tp_53) 341{ 342 const char* input = 343 "Content-Type: application/X-atf-tp; version=\"1\"\n" 344 "\n" 345 "descr: Out of order\n" 346 "ident: test1\n" 347 ; 348 349 const char* exp_calls[] = { 350 NULL 351 }; 352 353 const char* exp_errors[] = { 354 "3: First property of a test case must be 'ident'", 355 NULL 356 }; 357 358 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 359} 360 361ATF_TEST_CASE_WITHOUT_HEAD(tp_54); 362ATF_TEST_CASE_BODY(tp_54) 363{ 364 const char* input = 365 "Content-Type: application/X-atf-tp; version=\"1\"\n" 366 "\n" 367 "ident:\n" 368 ; 369 370 const char* exp_calls[] = { 371 NULL 372 }; 373 374 const char* exp_errors[] = { 375 "3: The value for 'ident' cannot be empty", 376 NULL 377 }; 378 379 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 380} 381 382ATF_TEST_CASE_WITHOUT_HEAD(tp_55); 383ATF_TEST_CASE_BODY(tp_55) 384{ 385 const char* input = 386 "Content-Type: application/X-atf-tp; version=\"1\"\n" 387 "\n" 388 "ident: +*,\n" 389 ; 390 391 const char* exp_calls[] = { 392 NULL 393 }; 394 395 const char* exp_errors[] = { 396 "3: The identifier must match ^[_A-Za-z0-9]+$; was '+*,'", 397 NULL 398 }; 399 400 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 401} 402 403ATF_TEST_CASE_WITHOUT_HEAD(tp_56); 404ATF_TEST_CASE_BODY(tp_56) 405{ 406 const char* input = 407 "Content-Type: application/X-atf-tp; version=\"1\"\n" 408 "\n" 409 "ident: test\n" 410 "timeout: hello\n" 411 ; 412 413 const char* exp_calls[] = { 414 NULL 415 }; 416 417 const char* exp_errors[] = { 418 "4: The timeout property requires an integer value", 419 NULL 420 }; 421 422 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 423} 424 425ATF_TEST_CASE_WITHOUT_HEAD(tp_57); 426ATF_TEST_CASE_BODY(tp_57) 427{ 428 const char* input = 429 "Content-Type: application/X-atf-tp; version=\"1\"\n" 430 "\n" 431 "ident: test\n" 432 "unknown: property\n" 433 ; 434 435 const char* exp_calls[] = { 436 NULL 437 }; 438 439 const char* exp_errors[] = { 440 "4: Unknown property 'unknown'", 441 NULL 442 }; 443 444 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 445} 446 447ATF_TEST_CASE_WITHOUT_HEAD(tp_58); 448ATF_TEST_CASE_BODY(tp_58) 449{ 450 const char* input = 451 "Content-Type: application/X-atf-tp; version=\"1\"\n" 452 "\n" 453 "ident: test\n" 454 "X-foo:\n" 455 ; 456 457 const char* exp_calls[] = { 458 NULL 459 }; 460 461 const char* exp_errors[] = { 462 "4: The value for 'X-foo' cannot be empty", 463 NULL 464 }; 465 466 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 467} 468 469ATF_TEST_CASE_WITHOUT_HEAD(tp_59); 470ATF_TEST_CASE_BODY(tp_59) 471{ 472 const char* input = 473 "Content-Type: application/X-atf-tp; version=\"1\"\n" 474 "\n" 475 "\n" 476 "ident: test\n" 477 "timeout: 30\n" 478 ; 479 480 const char* exp_calls[] = { 481 NULL 482 }; 483 484 const char* exp_errors[] = { 485 "3: Unexpected token `<<NEWLINE>>'; expected property name", 486 NULL 487 }; 488 489 do_parser_test< tp_reader >(input, exp_calls, exp_errors); 490} 491 492// ------------------------------------------------------------------------- 493// Tests for the "tps" writer. 494// ------------------------------------------------------------------------- 495 496ATF_TEST_CASE(atf_tps_writer); 497ATF_TEST_CASE_HEAD(atf_tps_writer) 498{ 499 set_md_var("descr", "Verifies the application/X-atf-tps writer"); 500} 501ATF_TEST_CASE_BODY(atf_tps_writer) 502{ 503 std::ostringstream expss; 504 std::ostringstream ss; 505 506#define RESET \ 507 expss.str(""); \ 508 ss.str("") 509 510#define CHECK \ 511 check_equal(*this, ss.str(), expss.str()) 512 513 { 514 RESET; 515 516 impl::atf_tps_writer w(ss); 517 expss << "Content-Type: application/X-atf-tps; version=\"2\"\n\n"; 518 CHECK; 519 } 520 521 { 522 RESET; 523 524 impl::atf_tps_writer w(ss); 525 expss << "Content-Type: application/X-atf-tps; version=\"2\"\n\n"; 526 CHECK; 527 528 w.info("foo", "bar"); 529 expss << "info: foo, bar\n"; 530 CHECK; 531 532 w.info("baz", "second info"); 533 expss << "info: baz, second info\n"; 534 CHECK; 535 } 536 537 { 538 RESET; 539 540 impl::atf_tps_writer w(ss); 541 expss << "Content-Type: application/X-atf-tps; version=\"2\"\n\n"; 542 CHECK; 543 544 w.ntps(0); 545 expss << "tps-count: 0\n"; 546 CHECK; 547 } 548 549 { 550 RESET; 551 552 impl::atf_tps_writer w(ss); 553 expss << "Content-Type: application/X-atf-tps; version=\"2\"\n\n"; 554 CHECK; 555 556 w.ntps(123); 557 expss << "tps-count: 123\n"; 558 CHECK; 559 } 560 561 { 562 RESET; 563 564 impl::atf_tps_writer w(ss); 565 expss << "Content-Type: application/X-atf-tps; version=\"2\"\n\n"; 566 CHECK; 567 568 w.ntps(2); 569 expss << "tps-count: 2\n"; 570 CHECK; 571 572 w.start_tp("foo", 0); 573 expss << "tp-start: foo, 0\n"; 574 CHECK; 575 576 w.end_tp(""); 577 expss << "tp-end: foo\n"; 578 CHECK; 579 580 w.start_tp("bar", 0); 581 expss << "tp-start: bar, 0\n"; 582 CHECK; 583 584 w.end_tp("failed program"); 585 expss << "tp-end: bar, failed program\n"; 586 CHECK; 587 } 588 589 { 590 RESET; 591 592 impl::atf_tps_writer w(ss); 593 expss << "Content-Type: application/X-atf-tps; version=\"2\"\n\n"; 594 CHECK; 595 596 w.ntps(1); 597 expss << "tps-count: 1\n"; 598 CHECK; 599 600 w.start_tp("foo", 1); 601 expss << "tp-start: foo, 1\n"; 602 CHECK; 603 604 w.start_tc("brokentc"); 605 expss << "tc-start: brokentc\n"; 606 CHECK; 607 608 w.end_tp("aborted"); 609 expss << "tp-end: foo, aborted\n"; 610 CHECK; 611 } 612 613 { 614 RESET; 615 616 impl::atf_tps_writer w(ss); 617 expss << "Content-Type: application/X-atf-tps; version=\"2\"\n\n"; 618 CHECK; 619 620 w.ntps(1); 621 expss << "tps-count: 1\n"; 622 CHECK; 623 624 w.start_tp("thetp", 3); 625 expss << "tp-start: thetp, 3\n"; 626 CHECK; 627 628 w.start_tc("passtc"); 629 expss << "tc-start: passtc\n"; 630 CHECK; 631 632 w.end_tc("passed", ""); 633 expss << "tc-end: passtc, passed\n"; 634 CHECK; 635 636 w.start_tc("failtc"); 637 expss << "tc-start: failtc\n"; 638 CHECK; 639 640 w.end_tc("failed", "The reason"); 641 expss << "tc-end: failtc, failed, The reason\n"; 642 CHECK; 643 644 w.start_tc("skiptc"); 645 expss << "tc-start: skiptc\n"; 646 CHECK; 647 648 w.end_tc("skipped", "The reason"); 649 expss << "tc-end: skiptc, skipped, The reason\n"; 650 CHECK; 651 652 w.end_tp(""); 653 expss << "tp-end: thetp\n"; 654 CHECK; 655 } 656 657 { 658 RESET; 659 660 impl::atf_tps_writer w(ss); 661 expss << "Content-Type: application/X-atf-tps; version=\"2\"\n\n"; 662 CHECK; 663 664 w.ntps(1); 665 expss << "tps-count: 1\n"; 666 CHECK; 667 668 w.start_tp("thetp", 1); 669 expss << "tp-start: thetp, 1\n"; 670 CHECK; 671 672 w.start_tc("thetc"); 673 expss << "tc-start: thetc\n"; 674 CHECK; 675 676 w.stdout_tc("a line"); 677 expss << "tc-so:a line\n"; 678 CHECK; 679 680 w.stdout_tc("another line"); 681 expss << "tc-so:another line\n"; 682 CHECK; 683 684 w.stderr_tc("an error message"); 685 expss << "tc-se:an error message\n"; 686 CHECK; 687 688 w.end_tc("passed", ""); 689 expss << "tc-end: thetc, passed\n"; 690 CHECK; 691 692 w.end_tp(""); 693 expss << "tp-end: thetp\n"; 694 CHECK; 695 } 696 697 { 698 RESET; 699 700 impl::atf_tps_writer w(ss); 701 expss << "Content-Type: application/X-atf-tps; version=\"2\"\n\n"; 702 CHECK; 703 704 w.ntps(1); 705 expss << "tps-count: 1\n"; 706 CHECK; 707 708 w.start_tp("thetp", 0); 709 expss << "tp-start: thetp, 0\n"; 710 CHECK; 711 712 w.end_tp(""); 713 expss << "tp-end: thetp\n"; 714 CHECK; 715 716 w.info("foo", "bar"); 717 expss << "info: foo, bar\n"; 718 CHECK; 719 720 w.info("baz", "second value"); 721 expss << "info: baz, second value\n"; 722 CHECK; 723 } 724 725#undef CHECK 726#undef RESET 727} 728 729// ------------------------------------------------------------------------- 730// Tests for the free functions. 731// ------------------------------------------------------------------------- 732 733ATF_TEST_CASE(get_metadata_bad); 734ATF_TEST_CASE_HEAD(get_metadata_bad) {} 735ATF_TEST_CASE_BODY(get_metadata_bad) { 736 const atf::fs::path executable = get_helper(*this, "bad_metadata_helper"); 737 ATF_REQUIRE_THROW(atf::parser::parse_errors, 738 impl::get_metadata(executable, vars_map())); 739} 740 741ATF_TEST_CASE(get_metadata_zero_tcs); 742ATF_TEST_CASE_HEAD(get_metadata_zero_tcs) {} 743ATF_TEST_CASE_BODY(get_metadata_zero_tcs) { 744 const atf::fs::path executable = get_helper(*this, "zero_tcs_helper"); 745 ATF_REQUIRE_THROW(atf::parser::parse_errors, 746 impl::get_metadata(executable, vars_map())); 747} 748 749ATF_TEST_CASE(get_metadata_several_tcs); 750ATF_TEST_CASE_HEAD(get_metadata_several_tcs) {} 751ATF_TEST_CASE_BODY(get_metadata_several_tcs) { 752 const atf::fs::path executable = get_helper(*this, "several_tcs_helper"); 753 const impl::metadata md = impl::get_metadata(executable, vars_map()); 754 ATF_REQUIRE_EQ(3, md.test_cases.size()); 755 756 { 757 const impl::test_cases_map::const_iterator iter = 758 md.test_cases.find("first"); 759 ATF_REQUIRE(iter != md.test_cases.end()); 760 761 ATF_REQUIRE_EQ(4, (*iter).second.size()); 762 check_property((*iter).second, "descr", "Description 1"); 763 check_property((*iter).second, "has.cleanup", "false"); 764 check_property((*iter).second, "ident", "first"); 765 check_property((*iter).second, "timeout", "30"); 766 } 767 768 { 769 const impl::test_cases_map::const_iterator iter = 770 md.test_cases.find("second"); 771 ATF_REQUIRE(iter != md.test_cases.end()); 772 773 ATF_REQUIRE_EQ(5, (*iter).second.size()); 774 check_property((*iter).second, "descr", "Description 2"); 775 check_property((*iter).second, "has.cleanup", "true"); 776 check_property((*iter).second, "ident", "second"); 777 check_property((*iter).second, "timeout", "500"); 778 check_property((*iter).second, "X-property", "Custom property"); 779 } 780 781 { 782 const impl::test_cases_map::const_iterator iter = 783 md.test_cases.find("third"); 784 ATF_REQUIRE(iter != md.test_cases.end()); 785 786 ATF_REQUIRE_EQ(3, (*iter).second.size()); 787 check_property((*iter).second, "has.cleanup", "false"); 788 check_property((*iter).second, "ident", "third"); 789 check_property((*iter).second, "timeout", "30"); 790 } 791} 792 793ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_death); 794ATF_TEST_CASE_BODY(parse_test_case_result_expected_death) { 795 check_result("expected_death", -1, "foo bar", 796 detail::parse_test_case_result("expected_death: foo bar")); 797 798 ATF_REQUIRE_THROW(std::runtime_error, 799 detail::parse_test_case_result("expected_death")); 800 ATF_REQUIRE_THROW(std::runtime_error, 801 detail::parse_test_case_result("expected_death(3): foo")); 802} 803 804ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_exit); 805ATF_TEST_CASE_BODY(parse_test_case_result_expected_exit) { 806 check_result("expected_exit", -1, "foo bar", 807 detail::parse_test_case_result("expected_exit: foo bar")); 808 check_result("expected_exit", -1, "foo bar", 809 detail::parse_test_case_result("expected_exit(): foo bar")); 810 check_result("expected_exit", 5, "foo bar", 811 detail::parse_test_case_result("expected_exit(5): foo bar")); 812 813 ATF_REQUIRE_THROW(std::runtime_error, 814 detail::parse_test_case_result("expected_exit")); 815 ATF_REQUIRE_THROW(std::runtime_error, 816 detail::parse_test_case_result("expected_exit(")); 817} 818 819ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_failure); 820ATF_TEST_CASE_BODY(parse_test_case_result_expected_failure) { 821 check_result("expected_failure", -1, "foo bar", 822 detail::parse_test_case_result("expected_failure: foo bar")); 823 824 ATF_REQUIRE_THROW(std::runtime_error, 825 detail::parse_test_case_result("expected_failure")); 826 ATF_REQUIRE_THROW(std::runtime_error, 827 detail::parse_test_case_result("expected_failure(3): foo")); 828} 829 830ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_signal); 831ATF_TEST_CASE_BODY(parse_test_case_result_expected_signal) { 832 check_result("expected_signal", -1, "foo bar", 833 detail::parse_test_case_result("expected_signal: foo bar")); 834 check_result("expected_signal", -1, "foo bar", 835 detail::parse_test_case_result("expected_signal(): foo bar")); 836 check_result("expected_signal", 5, "foo bar", 837 detail::parse_test_case_result("expected_signal(5): foo bar")); 838 839 ATF_REQUIRE_THROW(std::runtime_error, 840 detail::parse_test_case_result("expected_signal")); 841 ATF_REQUIRE_THROW(std::runtime_error, 842 detail::parse_test_case_result("expected_signal(")); 843} 844 845ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_expected_timeout); 846ATF_TEST_CASE_BODY(parse_test_case_result_expected_timeout) { 847 check_result("expected_timeout", -1, "foo bar", 848 detail::parse_test_case_result("expected_timeout: foo bar")); 849 850 ATF_REQUIRE_THROW(std::runtime_error, 851 detail::parse_test_case_result("expected_timeout")); 852 ATF_REQUIRE_THROW(std::runtime_error, 853 detail::parse_test_case_result("expected_timeout(3): foo")); 854} 855 856ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_failed); 857ATF_TEST_CASE_BODY(parse_test_case_result_failed) { 858 check_result("failed", -1, "foo bar", 859 detail::parse_test_case_result("failed: foo bar")); 860 861 ATF_REQUIRE_THROW(std::runtime_error, 862 detail::parse_test_case_result("failed")); 863 ATF_REQUIRE_THROW(std::runtime_error, 864 detail::parse_test_case_result("failed(3): foo")); 865} 866 867ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_passed); 868ATF_TEST_CASE_BODY(parse_test_case_result_passed) { 869 check_result("passed", -1, "", 870 detail::parse_test_case_result("passed")); 871 872 ATF_REQUIRE_THROW(std::runtime_error, 873 detail::parse_test_case_result("passed: foo")); 874 ATF_REQUIRE_THROW(std::runtime_error, 875 detail::parse_test_case_result("passed(3): foo")); 876} 877 878ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_skipped); 879ATF_TEST_CASE_BODY(parse_test_case_result_skipped) { 880 check_result("skipped", -1, "foo bar", 881 detail::parse_test_case_result("skipped: foo bar")); 882 883 ATF_REQUIRE_THROW(std::runtime_error, 884 detail::parse_test_case_result("skipped")); 885 ATF_REQUIRE_THROW(std::runtime_error, 886 detail::parse_test_case_result("skipped(3): foo")); 887} 888 889ATF_TEST_CASE_WITHOUT_HEAD(parse_test_case_result_unknown); 890ATF_TEST_CASE_BODY(parse_test_case_result_unknown) { 891 ATF_REQUIRE_THROW(std::runtime_error, 892 detail::parse_test_case_result("foo")); 893 ATF_REQUIRE_THROW(std::runtime_error, 894 detail::parse_test_case_result("bar: foo")); 895 ATF_REQUIRE_THROW(std::runtime_error, 896 detail::parse_test_case_result("baz: foo")); 897} 898 899ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_failed); 900ATF_TEST_CASE_BODY(read_test_case_result_failed) { 901 write_test_case_result("resfile", "failed: foo bar\n"); 902 const impl::test_case_result tcr = impl::read_test_case_result( 903 atf::fs::path("resfile")); 904 ATF_REQUIRE_EQ("failed", tcr.state()); 905 ATF_REQUIRE_EQ("foo bar", tcr.reason()); 906} 907 908ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_skipped); 909ATF_TEST_CASE_BODY(read_test_case_result_skipped) { 910 write_test_case_result("resfile", "skipped: baz bar\n"); 911 const impl::test_case_result tcr = impl::read_test_case_result( 912 atf::fs::path("resfile")); 913 ATF_REQUIRE_EQ("skipped", tcr.state()); 914 ATF_REQUIRE_EQ("baz bar", tcr.reason()); 915} 916 917 918ATF_TEST_CASE(read_test_case_result_no_file); 919ATF_TEST_CASE_HEAD(read_test_case_result_no_file) {} 920ATF_TEST_CASE_BODY(read_test_case_result_no_file) { 921 ATF_REQUIRE_THROW(std::runtime_error, 922 impl::read_test_case_result(atf::fs::path("resfile"))); 923} 924 925ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_empty_file); 926ATF_TEST_CASE_BODY(read_test_case_result_empty_file) { 927 write_test_case_result("resfile", ""); 928 ATF_REQUIRE_THROW(std::runtime_error, 929 impl::read_test_case_result(atf::fs::path("resfile"))); 930} 931 932ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_invalid); 933ATF_TEST_CASE_BODY(read_test_case_result_invalid) { 934 write_test_case_result("resfile", "passed: hello\n"); 935 ATF_REQUIRE_THROW(std::runtime_error, 936 impl::read_test_case_result(atf::fs::path("resfile"))); 937} 938 939ATF_TEST_CASE_WITHOUT_HEAD(read_test_case_result_multiline); 940ATF_TEST_CASE_BODY(read_test_case_result_multiline) { 941 write_test_case_result("resfile", "skipped: foo\nbar\n"); 942 const impl::test_case_result tcr = impl::read_test_case_result( 943 atf::fs::path("resfile")); 944 ATF_REQUIRE_EQ("skipped", tcr.state()); 945 ATF_REQUIRE_EQ("foo<<NEWLINE UNEXPECTED>>bar", tcr.reason()); 946} 947 948// ------------------------------------------------------------------------- 949// Main. 950// ------------------------------------------------------------------------- 951 952ATF_INIT_TEST_CASES(tcs) 953{ 954 ATF_ADD_TEST_CASE(tcs, tp_1); 955 ATF_ADD_TEST_CASE(tcs, tp_2); 956 ATF_ADD_TEST_CASE(tcs, tp_3); 957 ATF_ADD_TEST_CASE(tcs, tp_4); 958 ATF_ADD_TEST_CASE(tcs, tp_50); 959 ATF_ADD_TEST_CASE(tcs, tp_51); 960 ATF_ADD_TEST_CASE(tcs, tp_52); 961 ATF_ADD_TEST_CASE(tcs, tp_53); 962 ATF_ADD_TEST_CASE(tcs, tp_54); 963 ATF_ADD_TEST_CASE(tcs, tp_55); 964 ATF_ADD_TEST_CASE(tcs, tp_56); 965 ATF_ADD_TEST_CASE(tcs, tp_57); 966 ATF_ADD_TEST_CASE(tcs, tp_58); 967 ATF_ADD_TEST_CASE(tcs, tp_59); 968 969 ATF_ADD_TEST_CASE(tcs, atf_tps_writer); 970 971 ATF_ADD_TEST_CASE(tcs, get_metadata_bad); 972 ATF_ADD_TEST_CASE(tcs, get_metadata_zero_tcs); 973 ATF_ADD_TEST_CASE(tcs, get_metadata_several_tcs); 974 975 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_death); 976 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_exit); 977 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_failure); 978 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_signal); 979 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_expected_timeout); 980 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_failed); 981 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_passed); 982 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_skipped); 983 ATF_ADD_TEST_CASE(tcs, parse_test_case_result_unknown); 984 985 ATF_ADD_TEST_CASE(tcs, read_test_case_result_no_file); 986 ATF_ADD_TEST_CASE(tcs, read_test_case_result_empty_file); 987 ATF_ADD_TEST_CASE(tcs, read_test_case_result_multiline); 988 ATF_ADD_TEST_CASE(tcs, read_test_case_result_invalid); 989 990 // TODO: Add tests for run_test_case once all the missing functionality 991 // is implemented. 992} 993