libatf-sh.subr revision 1.1.1.4
1# 2# Automated Testing Framework (atf) 3# 4# Copyright (c) 2007, 2008, 2009, 2010, 2011 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 30set -e 31 32# ------------------------------------------------------------------------ 33# GLOBAL VARIABLES 34# ------------------------------------------------------------------------ 35 36# The list of all test cases defined by the test program. 37Defined_Test_Cases= 38 39# Values for the expect property. 40Expect=pass 41Expect_Reason= 42 43# A boolean variable that indicates whether we are parsing a test case's 44# head or not. 45Parsing_Head=false 46 47# The program name. 48Prog_Name=${0##*/} 49 50# The file to which the test case will print its result. 51Results_File= 52 53# The test program's source directory: i.e. where its auxiliary data files 54# and helper utilities can be found. Can be overriden through the '-s' flag. 55Source_Dir="$(dirname ${0})" 56 57# Indicates the test case we are currently processing. 58Test_Case= 59 60# List of meta-data variables for the current test case. 61Test_Case_Vars= 62 63# The list of all test cases provided by the test program. 64# Subset of ${Defined_Test_Cases}. 65Test_Cases= 66Test_Cases_With_Cleanup= 67 68# ------------------------------------------------------------------------ 69# PUBLIC INTERFACE 70# ------------------------------------------------------------------------ 71 72# 73# atf_add_test_case tc-name 74# 75# Adds the given test case to the list of test cases that form the test 76# program. The name provided here must be accompanied by two functions 77# named after it: <tc-name>_head and <tc-name>_body, and optionally by 78# a <tc-name>_cleanup function. 79# 80atf_add_test_case() 81{ 82 _atf_is_tc_defined "${1}" || \ 83 _atf_error 128 "Test case ${1} was not correctly defined by" \ 84 "this test program" 85 Test_Cases="${Test_Cases} ${1}" 86} 87 88# 89# atf_check cmd expcode expout experr 90# 91# Executes atf-check with given arguments and automatically calls 92# atf_fail in case of failure. 93# 94atf_check() 95{ 96 ${Atf_Check} "${@}" || \ 97 atf_fail "atf-check failed; see the output of the test for details" 98} 99 100# 101# atf_check_equal expr1 expr2 102# 103# Checks that expr1's value matches expr2's and, if not, raises an 104# error. Ideally expr1 and expr2 should be provided quoted (not 105# expanded) so that the error message is helpful; otherwise it will 106# only show the values, not the expressions themselves. 107# 108atf_check_equal() 109{ 110 eval _val1=\"${1}\" 111 eval _val2=\"${2}\" 112 test "${_val1}" = "${_val2}" || \ 113 atf_fail "${1} != ${2} (${_val1} != ${_val2})" 114} 115 116# 117# atf_config_get varname [defvalue] 118# 119# Prints the value of a configuration variable. If it is not 120# defined, prints the given default value. 121# 122atf_config_get() 123{ 124 _varname="__tc_config_var_$(_atf_normalize ${1})" 125 if [ ${#} -eq 1 ]; then 126 eval _value=\"\${${_varname}-__unset__}\" 127 [ "${_value}" = __unset__ ] && \ 128 _atf_error 1 "Could not find configuration variable \`${1}'" 129 echo ${_value} 130 elif [ ${#} -eq 2 ]; then 131 eval echo \${${_varname}-${2}} 132 else 133 _atf_error 1 "Incorrect number of parameters for atf_config_get" 134 fi 135} 136 137# 138# atf_config_has varname 139# 140# Returns a boolean indicating if the given configuration variable is 141# defined or not. 142# 143atf_config_has() 144{ 145 _varname="__tc_config_var_$(_atf_normalize ${1})" 146 eval _value=\"\${${_varname}-__unset__}\" 147 [ "${_value}" != __unset__ ] 148} 149 150# 151# atf_expect_death reason 152# 153# Sets the expectations to 'death'. 154# 155atf_expect_death() 156{ 157 _atf_validate_expect 158 159 Expect=death 160 _atf_create_resfile expected_death -1 "${@}" 161} 162 163# 164# atf_expect_timeout reason 165# 166# Sets the expectations to 'timeout'. 167# 168atf_expect_timeout() 169{ 170 _atf_validate_expect 171 172 Expect=timeout 173 _atf_create_resfile expected_timeout -1 "${@}" 174} 175 176# 177# atf_expect_exit exitcode reason 178# 179# Sets the expectations to 'exit'. 180# 181atf_expect_exit() 182{ 183 _exitcode="${1}"; shift 184 185 _atf_validate_expect 186 187 Expect=exit 188 _atf_create_resfile expected_exit "${_exitcode}" "${@}" 189} 190 191# 192# atf_expect_fail reason 193# 194# Sets the expectations to 'fail'. 195# 196atf_expect_fail() 197{ 198 _atf_validate_expect 199 200 Expect=fail 201 Expect_Reason="${*}" 202} 203 204# 205# atf_expect_pass 206# 207# Sets the expectations to 'pass'. 208# 209atf_expect_pass() 210{ 211 _atf_validate_expect 212 213 Expect=pass 214 Expect_Reason= 215} 216 217# 218# atf_expect_signal signo reason 219# 220# Sets the expectations to 'signal'. 221# 222atf_expect_signal() 223{ 224 _signo="${1}"; shift 225 226 _atf_validate_expect 227 228 Expect=signal 229 _atf_create_resfile expected_signal "${_signo}" "${@}" 230} 231 232# 233# atf_expected_failure msg1 [.. msgN] 234# 235# Makes the test case report an expected failure with the given error 236# message. Multiple words can be provided, which are concatenated with 237# a single blank space. 238# 239atf_expected_failure() 240{ 241 _atf_create_resfile expected_failure -1 "${Expect_Reason}:" "${@}" 242 exit 0 243} 244 245# 246# atf_fail msg1 [.. msgN] 247# 248# Makes the test case fail with the given error message. Multiple 249# words can be provided, in which case they are joined by a single 250# blank space. 251# 252atf_fail() 253{ 254 case "${Expect}" in 255 fail) 256 atf_expected_failure "${@}" 257 ;; 258 pass) 259 _atf_create_resfile failed -1 "${@}" 260 exit 1 261 ;; 262 *) 263 _atf_error 128 "Unreachable" 264 ;; 265 esac 266} 267 268# 269# atf_get varname 270# 271# Prints the value of a test case-specific variable. Given that one 272# should not get the value of non-existent variables, it is fine to 273# always use this function as 'val=$(atf_get var)'. 274# 275atf_get() 276{ 277 eval echo \${__tc_var_${Test_Case}_$(_atf_normalize ${1})} 278} 279 280# 281# atf_get_srcdir 282# 283# Prints the value of the test case's source directory. 284# 285atf_get_srcdir() 286{ 287 _atf_internal_get srcdir 288} 289 290# 291# atf_init_test_cases 292# 293# The function in charge of registering the test cases that have to 294# be made available to the user. Must be redefined. 295# 296atf_init_test_cases() 297{ 298 _atf_error 128 "No test cases defined" 299} 300 301# 302# atf_pass 303# 304# Makes the test case pass. Shouldn't be used in general, as a test 305# case that does not explicitly fail is assumed to pass. 306# 307atf_pass() 308{ 309 case "${Expect}" in 310 fail) 311 Expect=pass 312 atf_fail "Test case was expecting a failure but got a pass instead" 313 ;; 314 pass) 315 _atf_create_resfile passed -1 316 exit 0 317 ;; 318 *) 319 _atf_error 128 "Unreachable" 320 ;; 321 esac 322} 323 324# 325# atf_require_prog prog 326# 327# Checks that the given program name (either provided as an absolute 328# path or as a plain file name) can be found. If it is not available, 329# automatically skips the test case with an appropriate message. 330# 331# Relative paths are not allowed because the test case cannot predict 332# where it will be executed from. 333# 334atf_require_prog() 335{ 336 _prog= 337 case ${1} in 338 /*) 339 _prog="${1}" 340 [ -x ${_prog} ] || \ 341 atf_skip "The required program ${1} could not be found" 342 ;; 343 */*) 344 atf_fail "atf_require_prog does not accept relative path names \`${1}'" 345 ;; 346 *) 347 _prog=$(_atf_find_in_path "${1}") 348 [ -n "${_prog}" ] || \ 349 atf_skip "The required program ${1} could not be found" \ 350 "in the PATH" 351 ;; 352 esac 353} 354 355# 356# atf_set varname val1 [.. valN] 357# 358# Sets the test case's variable 'varname' to the specified values 359# which are concatenated using a single blank space. This function 360# is supposed to be called form the test case's head only. 361# 362atf_set() 363{ 364 ${Parsing_Head} || \ 365 _atf_error 128 "atf_set called from the test case's body" 366 367 Test_Case_Vars="${Test_Case_Vars} ${1}" 368 _var=$(_atf_normalize ${1}); shift 369 eval __tc_var_${Test_Case}_${_var}=\"\${*}\" 370} 371 372# 373# atf_skip msg1 [.. msgN] 374# 375# Skips the test case because of the reason provided. Multiple words 376# can be given, in which case they are joined by a single blank space. 377# 378atf_skip() 379{ 380 _atf_create_resfile skipped -1 "${@}" 381 exit 0 382} 383 384# 385# atf_test_case tc-name cleanup 386# 387# Defines a new test case named tc-name. The name provided here must be 388# accompanied by two functions named after it: <tc-name>_head and 389# <tc-name>_body. If cleanup is set to 'cleanup', then this also expects 390# a <tc-name>_cleanup function to be defined. 391# 392atf_test_case() 393{ 394 Defined_Test_Cases="${Defined_Test_Cases} ${1}" 395 396 eval "${1}_head() { :; }" 397 eval "${1}_body() { atf_fail 'Test case not implemented'; }" 398 if [ "${2}" = cleanup ]; then 399 Test_Cases_With_Cleanup="${Test_Cases_With_Cleanup} ${1}" 400 eval "${1}_cleanup() { :; }" 401 else 402 eval "${1}_cleanup() { 403 _atf_error 1 'Test case ${1} declared without a cleanup routine'; }" 404 fi 405} 406 407# ------------------------------------------------------------------------ 408# PRIVATE INTERFACE 409# ------------------------------------------------------------------------ 410 411# 412# _atf_config_set varname val1 [.. valN] 413# 414# Sets the test case's private variable 'varname' to the specified 415# values which are concatenated using a single blank space. 416# 417_atf_config_set() 418{ 419 _var=$(_atf_normalize ${1}); shift 420 eval __tc_config_var_${_var}=\"\${*}\" 421 Config_Vars="${Config_Vars} __tc_config_var_${_var}" 422} 423 424# 425# _atf_config_set_str varname=val 426# 427# Sets the test case's private variable 'varname' to the specified 428# value. The parameter is of the form 'varname=val'. 429# 430_atf_config_set_from_str() 431{ 432 _oldifs=${IFS} 433 IFS='=' 434 set -- ${*} 435 _var=${1} 436 shift 437 _val="${@}" 438 IFS=${_oldifs} 439 _atf_config_set "${_var}" "${_val}" 440} 441 442# 443# _atf_create_resfile result arg [reason ...] 444# 445# Creates the results file. 446# 447_atf_create_resfile() 448{ 449 _result="${1}"; shift 450 if [ "${1}" -eq -1 ]; then 451 _arg="" 452 shift 453 else 454 _arg="(${1})" 455 shift 456 fi 457 if [ ${#} -gt 0 ]; then 458 _reason=": ${*}" 459 else 460 _reason="" 461 fi 462 463 if [ -n "${Results_File}" ]; then 464 echo "${_result}${_arg}${_reason}" >"${Results_File}" || \ 465 _atf_error 128 "Cannot create results file '${Results_File}'" 466 else 467 echo "${_result}${_arg}${_reason}" 468 fi 469} 470 471# 472# _atf_ensure_boolean var 473# 474# Ensures that the test case defined the variable 'var' to a boolean 475# value. 476# 477_atf_ensure_boolean() 478{ 479 _atf_ensure_not_empty ${1} 480 481 case $(atf_get ${1}) in 482 [Yy][Ee][Ss]|[Tt][Rr][Uu][Ee]) 483 atf_set ${1} true 484 ;; 485 [Nn][Oo]|[Ff][Aa][Ll][Ss][Ee]) 486 atf_set ${1} false 487 ;; 488 *) 489 _atf_error 128 "Invalid value for boolean variable \`${1}'" 490 ;; 491 esac 492} 493 494# 495# _atf_ensure_not_empty var 496# 497# Ensures that the test case defined the variable 'var' to a non-empty 498# value. 499# 500_atf_ensure_not_empty() 501{ 502 [ -n "$(atf_get ${1})" ] || \ 503 _atf_error 128 "Undefined or empty variable \`${1}'" 504} 505 506# 507# _atf_error error_code [msg1 [.. msgN]] 508# 509# Prints the given error message (which can be composed of multiple 510# arguments, in which case are joined by a single space) and exits 511# with the specified error code. 512# 513# This must not be used by test programs themselves (hence making 514# the function private) to indicate a test case's failure. They 515# have to use the atf_fail function. 516# 517_atf_error() 518{ 519 _error_code="${1}"; shift 520 521 echo "${Prog_Name}: ERROR:" "$@" 1>&2 522 exit ${_error_code} 523} 524 525# 526# _atf_warning msg1 [.. msgN] 527# 528# Prints the given warning message (which can be composed of multiple 529# arguments, in which case are joined by a single space). 530# 531_atf_warning() 532{ 533 echo "${Prog_Name}: WARNING:" "$@" 1>&2 534} 535 536# 537# _atf_find_in_path program 538# 539# Looks for a program in the path and prints the full path to it or 540# nothing if it could not be found. It also returns true in case of 541# success. 542# 543_atf_find_in_path() 544{ 545 _prog="${1}" 546 547 _oldifs=${IFS} 548 IFS=: 549 for _dir in ${PATH} 550 do 551 if [ -x ${_dir}/${_prog} ]; then 552 IFS=${_oldifs} 553 echo ${_dir}/${_prog} 554 return 0 555 fi 556 done 557 IFS=${_oldifs} 558 559 return 1 560} 561 562# 563# _atf_has_tc name 564# 565# Returns true if the given test case exists. 566# 567_atf_has_tc() 568{ 569 for _tc in ${Test_Cases}; do 570 if [ ${_tc} = ${1} ]; then 571 return 0 572 fi 573 done 574 return 1 575} 576 577# 578# _atf_get_bool varname 579# 580# Evaluates a test case-specific variable as a boolean and returns its 581# value. 582# 583_atf_get_bool() 584{ 585 eval $(atf_get ${1}) 586} 587 588# 589# _atf_internal_get varname 590# 591# Prints the value of a test case-specific internal variable. Given 592# that one should not get the value of non-existent variables, it is 593# fine to always use this function as 'val=$(_atf_internal_get var)'. 594# 595_atf_internal_get() 596{ 597 eval echo \${__tc_internal_var_${Test_Case}_${1}} 598} 599 600# 601# _atf_internal_set varname val1 [.. valN] 602# 603# Sets the test case's private variable 'varname' to the specified 604# values which are concatenated using a single blank space. 605# 606_atf_internal_set() 607{ 608 _var=${1}; shift 609 eval __tc_internal_var_${Test_Case}_${_var}=\"\${*}\" 610} 611 612# 613# _atf_list_tcs 614# 615# Describes all test cases and prints the list to the standard output. 616# 617_atf_list_tcs() 618{ 619 echo 'Content-Type: application/X-atf-tp; version="1"' 620 echo 621 622 set -- ${Test_Cases} 623 while [ ${#} -gt 0 ]; do 624 _atf_parse_head ${1} 625 626 echo "ident: $(atf_get ident)" 627 for _var in ${Test_Case_Vars}; do 628 [ "${_var}" != "ident" ] && echo "${_var}: $(atf_get ${_var})" 629 done 630 631 [ ${#} -gt 1 ] && echo 632 shift 633 done 634} 635 636# 637# _atf_normalize str 638# 639# Normalizes a string so that it is a valid shell variable name. 640# 641_atf_normalize() 642{ 643 echo ${1} | tr .- __ 644} 645 646# 647# _atf_parse_head tcname 648# 649# Evaluates a test case's head to gather its variables and prepares the 650# test program to run it. 651# 652_atf_parse_head() 653{ 654 ${Parsing_Head} && _atf_error 128 "_atf_parse_head called recursively" 655 Parsing_Head=true 656 657 Test_Case="${1}" 658 Test_Case_Vars= 659 660 if _atf_has_cleanup "${1}"; then 661 atf_set has.cleanup "true" 662 fi 663 664 atf_set ident "${1}" 665 ${1}_head 666 _atf_ensure_not_empty ident 667 test $(atf_get ident) = "${1}" || \ 668 _atf_error 128 "Test case redefined ident" 669 670 Parsing_Head=false 671} 672 673# 674# _atf_run_tc tc 675# 676# Runs the specified test case. Prints its exit status to the 677# standard output and returns a boolean indicating if the test was 678# successful or not. 679# 680_atf_run_tc() 681{ 682 case ${1} in 683 *:*) 684 _tcname=${1%%:*} 685 _tcpart=${1#*:} 686 687 if [ "${_tcpart}" != body -a "${_tcpart}" != cleanup ]; then 688 _atf_syntax_error "Unknown test case part \`${_tcpart}'" 689 fi 690 ;; 691 692 *) 693 _tcname=${1} 694 _tcpart=body 695 ;; 696 esac 697 698 if _atf_has_tc ${_tcname}; then 699 if [ "${__RUNNING_INSIDE_ATF_RUN}" != "internal-yes-value" ]; then 700 _atf_warning "Running test cases without atf-run(1) is unsupported" 701 _atf_warning "No isolation nor timeout control is being applied;" \ 702 "you may get unexpected failures; see atf-test-case(4)" 703 fi 704 705 _atf_parse_head ${_tcname} 706 707 _atf_internal_set srcdir "${Source_Dir}" 708 709 case ${_tcpart} in 710 body) 711 if ${_tcname}_body; then 712 _atf_validate_expect 713 _atf_create_resfile passed -1 714 else 715 Expect=pass 716 atf_fail "Test case body returned a non-ok exit code, but" \ 717 "this is not allowed" 718 fi 719 ;; 720 cleanup) 721 if _atf_has_cleanup "${_tcname}"; then 722 if ${_tcname}_cleanup; then 723 : 724 else 725 _atf_error 128 "The test case cleanup returned a non-ok" \ 726 "exit code, but this is not allowed" 727 fi 728 fi 729 ;; 730 *) 731 _atf_error 128 "Unknown test case part" 732 ;; 733 esac 734 else 735 _atf_syntax_error "Unknown test case \`${1}'" 736 fi 737} 738 739# 740# _atf_sighup_handler 741# 742# Handler for the SIGHUP signal that registers its occurrence so that 743# it can be processed at a later stage. 744# 745_atf_sighup_handler() 746{ 747 Held_Signals="${Held_Signals} SIGHUP" 748} 749 750# 751# _atf_sigint_handler 752# 753# Handler for the SIGINT signal that registers its occurrence so that 754# it can be processed at a later stage. 755# 756_atf_sigint_handler() 757{ 758 Held_Signals="${Held_Signals} SIGINT" 759} 760 761# 762# _atf_sigterm_handler 763# 764# Handler for the SIGTERM signal that registers its occurrence so that 765# it can be processed at a later stage. 766# 767_atf_sigterm_handler() 768{ 769 Held_Signals="${Held_Signals} SIGTERM" 770} 771 772# 773# _atf_syntax_error msg1 [.. msgN] 774# 775# Formats and prints a syntax error message and terminates the 776# program prematurely. 777# 778_atf_syntax_error() 779{ 780 echo "${Prog_Name}: ERROR: ${@}" 1>&2 781 echo "${Prog_Name}: See atf-test-program(1) for usage details." 1>&2 782 exit 1 783} 784 785# 786# _atf_is_tc_defined tc-name 787# 788# Returns a boolean indicating if the given test case was defined by the 789# test program or not. 790# 791_atf_is_tc_defined() 792{ 793 for _tc in ${Defined_Test_Cases}; do 794 [ ${_tc} = ${1} ] && return 0 795 done 796 return 1 797} 798 799# 800# _atf_has_cleanup tc-name 801# 802# Returns a boolean indicating if the given test case has a cleanup 803# routine or not. 804# 805_atf_has_cleanup() 806{ 807 for _tc in ${Test_Cases_With_Cleanup}; do 808 [ ${_tc} = ${1} ] && return 0 809 done 810 return 1 811} 812 813# 814# _atf_validate_expect 815# 816# Ensures that the current test case state is correct regarding the expect 817# status. 818# 819_atf_validate_expect() 820{ 821 case "${Expect}" in 822 death) 823 Expect=pass 824 atf_fail "Test case was expected to terminate abruptly but it" \ 825 "continued execution" 826 ;; 827 exit) 828 Expect=pass 829 atf_fail "Test case was expected to exit cleanly but it continued" \ 830 "execution" 831 ;; 832 fail) 833 Expect=pass 834 atf_fail "Test case was expecting a failure but none were raised" 835 ;; 836 pass) 837 ;; 838 signal) 839 Expect=pass 840 atf_fail "Test case was expected to receive a termination signal" \ 841 "but it continued execution" 842 ;; 843 timeout) 844 Expect=pass 845 atf_fail "Test case was expected to hang but it continued execution" 846 ;; 847 *) 848 _atf_error 128 "Unreachable" 849 ;; 850 esac 851} 852 853# 854# _atf_warning [msg1 [.. msgN]] 855# 856# Prints the given warning message (which can be composed of multiple 857# arguments, in which case are joined by a single space). 858# 859# This must not be used by test programs themselves (hence making 860# the function private). 861# 862_atf_warning() 863{ 864 echo "${Prog_Name}: WARNING:" "$@" 1>&2 865} 866 867# 868# main [options] test_case 869# 870# Test program's entry point. 871# 872main() 873{ 874 # Process command-line options first. 875 _numargs=${#} 876 _lflag=false 877 while getopts :lr:s:v: arg; do 878 case ${arg} in 879 l) 880 _lflag=true 881 ;; 882 883 r) 884 Results_File=${OPTARG} 885 ;; 886 887 s) 888 Source_Dir=${OPTARG} 889 ;; 890 891 v) 892 _atf_config_set_from_str "${OPTARG}" 893 ;; 894 895 \?) 896 _atf_syntax_error "Unknown option -${OPTARG}." 897 # NOTREACHED 898 ;; 899 esac 900 done 901 shift `expr ${OPTIND} - 1` 902 903 # First of all, make sure that the source directory is correct. It 904 # doesn't matter if the user did not change it, because the default 905 # value may not work. (TODO: It possibly should, even though it is 906 # not a big deal because atf-run deals with this.) 907 case ${Source_Dir} in 908 /*) 909 ;; 910 *) 911 Source_Dir=$(pwd)/${Source_Dir} 912 ;; 913 esac 914 [ -f ${Source_Dir}/${Prog_Name} ] || \ 915 _atf_error 1 "Cannot find the test program in the source" \ 916 "directory \`${Source_Dir}'" 917 918 # Set some global variables useful to the user. Not specific to the 919 # test case because they may be needed during initialization too. 920 # XXX I'm not too fond on this though. Sure, it is very useful in some 921 # situations -- such as in NetBSD's fs/tmpfs/* tests where each test 922 # program includes a helper subroutines file -- but there are also 923 # other, maybe better ways to achieve the same. Because, for example, 924 # at the moment it is not possible to detect failures in the inclusion 925 # and report them nicely. Plus this change is difficult to implement 926 # in the current C++ API. 927 _atf_internal_set srcdir "${Source_Dir}" 928 929 # Call the test program's hook to register all available test cases. 930 atf_init_test_cases 931 932 # Run or list test cases. 933 if `${_lflag}`; then 934 if [ ${#} -gt 0 ]; then 935 _atf_syntax_error "Cannot provide test case names with -l" 936 fi 937 _atf_list_tcs 938 else 939 if [ ${#} -eq 0 ]; then 940 _atf_syntax_error "Must provide a test case name" 941 elif [ ${#} -gt 1 ]; then 942 _atf_syntax_error "Cannot provide more than one test case name" 943 else 944 _atf_run_tc "${1}" 945 fi 946 fi 947} 948 949# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4 950