1c243e490SMarcel Moolenaar# Copyright (c) 2007 The NetBSD Foundation, Inc. 2c243e490SMarcel Moolenaar# All rights reserved. 3c243e490SMarcel Moolenaar# 4c243e490SMarcel Moolenaar# Redistribution and use in source and binary forms, with or without 5c243e490SMarcel Moolenaar# modification, are permitted provided that the following conditions 6c243e490SMarcel Moolenaar# are met: 7c243e490SMarcel Moolenaar# 1. Redistributions of source code must retain the above copyright 8c243e490SMarcel Moolenaar# notice, this list of conditions and the following disclaimer. 9c243e490SMarcel Moolenaar# 2. Redistributions in binary form must reproduce the above copyright 10c243e490SMarcel Moolenaar# notice, this list of conditions and the following disclaimer in the 11c243e490SMarcel Moolenaar# documentation and/or other materials provided with the distribution. 12c243e490SMarcel Moolenaar# 13c243e490SMarcel Moolenaar# THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND 14c243e490SMarcel Moolenaar# CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, 15c243e490SMarcel Moolenaar# INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 16c243e490SMarcel Moolenaar# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 17c243e490SMarcel Moolenaar# IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY 18c243e490SMarcel Moolenaar# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19c243e490SMarcel Moolenaar# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 20c243e490SMarcel Moolenaar# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 21c243e490SMarcel Moolenaar# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 22c243e490SMarcel Moolenaar# IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 23c243e490SMarcel Moolenaar# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 24c243e490SMarcel Moolenaar# IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25c243e490SMarcel Moolenaar 26c243e490SMarcel Moolenaar# ------------------------------------------------------------------------ 27c243e490SMarcel Moolenaar# GLOBAL VARIABLES 28c243e490SMarcel Moolenaar# ------------------------------------------------------------------------ 29c243e490SMarcel Moolenaar 30c243e490SMarcel Moolenaar# Values for the expect property. 31c243e490SMarcel MoolenaarExpect=pass 32c243e490SMarcel MoolenaarExpect_Reason= 33c243e490SMarcel Moolenaar 34c243e490SMarcel Moolenaar# A boolean variable that indicates whether we are parsing a test case's 35c243e490SMarcel Moolenaar# head or not. 36c243e490SMarcel MoolenaarParsing_Head=false 37c243e490SMarcel Moolenaar 38c243e490SMarcel Moolenaar# The program name. 39c243e490SMarcel MoolenaarProg_Name=${0##*/} 40c243e490SMarcel Moolenaar 41c243e490SMarcel Moolenaar# The file to which the test case will print its result. 42c243e490SMarcel MoolenaarResults_File= 43c243e490SMarcel Moolenaar 44c243e490SMarcel Moolenaar# The test program's source directory: i.e. where its auxiliary data files 45c243e490SMarcel Moolenaar# and helper utilities can be found. Can be overriden through the '-s' flag. 46c243e490SMarcel MoolenaarSource_Dir="$(dirname ${0})" 47c243e490SMarcel Moolenaar 48c243e490SMarcel Moolenaar# Indicates the test case we are currently processing. 49c243e490SMarcel MoolenaarTest_Case= 50c243e490SMarcel Moolenaar 51c243e490SMarcel Moolenaar# List of meta-data variables for the current test case. 52c243e490SMarcel MoolenaarTest_Case_Vars= 53c243e490SMarcel Moolenaar 54c243e490SMarcel Moolenaar# The list of all test cases provided by the test program. 55c243e490SMarcel MoolenaarTest_Cases= 56c243e490SMarcel Moolenaar 57c243e490SMarcel Moolenaar# ------------------------------------------------------------------------ 58c243e490SMarcel Moolenaar# PUBLIC INTERFACE 59c243e490SMarcel Moolenaar# ------------------------------------------------------------------------ 60c243e490SMarcel Moolenaar 61c243e490SMarcel Moolenaar# 62c243e490SMarcel Moolenaar# atf_add_test_case tc-name 63c243e490SMarcel Moolenaar# 64c243e490SMarcel Moolenaar# Adds the given test case to the list of test cases that form the test 65c243e490SMarcel Moolenaar# program. The name provided here must be accompanied by two functions 66c243e490SMarcel Moolenaar# named after it: <tc-name>_head and <tc-name>_body, and optionally by 67c243e490SMarcel Moolenaar# a <tc-name>_cleanup function. 68c243e490SMarcel Moolenaar# 69c243e490SMarcel Moolenaaratf_add_test_case() 70c243e490SMarcel Moolenaar{ 71c243e490SMarcel Moolenaar Test_Cases="${Test_Cases} ${1}" 72c243e490SMarcel Moolenaar} 73c243e490SMarcel Moolenaar 74c243e490SMarcel Moolenaar# 75c243e490SMarcel Moolenaar# atf_check cmd expcode expout experr 76c243e490SMarcel Moolenaar# 77c243e490SMarcel Moolenaar# Executes atf-check with given arguments and automatically calls 78c243e490SMarcel Moolenaar# atf_fail in case of failure. 79c243e490SMarcel Moolenaar# 80c243e490SMarcel Moolenaaratf_check() 81c243e490SMarcel Moolenaar{ 82c243e490SMarcel Moolenaar ${Atf_Check} "${@}" || \ 83c243e490SMarcel Moolenaar atf_fail "atf-check failed; see the output of the test for details" 84c243e490SMarcel Moolenaar} 85c243e490SMarcel Moolenaar 86c243e490SMarcel Moolenaar# 870677dfd1SJulio Merino# atf_check_equal expected_expression actual_expression 88c243e490SMarcel Moolenaar# 890677dfd1SJulio Merino# Checks that expected_expression's value matches actual_expression's 900677dfd1SJulio Merino# and, if not, raises an error. Ideally expected_expression and 910677dfd1SJulio Merino# actual_expression should be provided quoted (not expanded) so that 920677dfd1SJulio Merino# the error message is helpful; otherwise it will only show the values, 930677dfd1SJulio Merino# not the expressions themselves. 94c243e490SMarcel Moolenaar# 95c243e490SMarcel Moolenaaratf_check_equal() 96c243e490SMarcel Moolenaar{ 97c243e490SMarcel Moolenaar eval _val1=\"${1}\" 98c243e490SMarcel Moolenaar eval _val2=\"${2}\" 99c243e490SMarcel Moolenaar test "${_val1}" = "${_val2}" || \ 100c243e490SMarcel Moolenaar atf_fail "${1} != ${2} (${_val1} != ${_val2})" 101c243e490SMarcel Moolenaar} 102c243e490SMarcel Moolenaar 103c243e490SMarcel Moolenaar# 104c203bd70SAlex Richardson# atf_check_not_equal expected_expression actual_expression 105c203bd70SAlex Richardson# 106c203bd70SAlex Richardson# Checks that expected_expression's value does not match actual_expression's 107c203bd70SAlex Richardson# and, if it does, raises an error. Ideally expected_expression and 108c203bd70SAlex Richardson# actual_expression should be provided quoted (not expanded) so that 109c203bd70SAlex Richardson# the error message is helpful; otherwise it will only show the values, 110c203bd70SAlex Richardson# not the expressions themselves. 111c203bd70SAlex Richardson# 112c203bd70SAlex Richardsonatf_check_not_equal() 113c203bd70SAlex Richardson{ 114c203bd70SAlex Richardson eval _val1=\"${1}\" 115c203bd70SAlex Richardson eval _val2=\"${2}\" 116c203bd70SAlex Richardson test "${_val1}" != "${_val2}" || \ 117c203bd70SAlex Richardson atf_fail "${1} == ${2} (${_val1} == ${_val2})" 118c203bd70SAlex Richardson} 119c203bd70SAlex Richardson 120c203bd70SAlex Richardson# 121c243e490SMarcel Moolenaar# atf_config_get varname [defvalue] 122c243e490SMarcel Moolenaar# 123c243e490SMarcel Moolenaar# Prints the value of a configuration variable. If it is not 124c243e490SMarcel Moolenaar# defined, prints the given default value. 125c243e490SMarcel Moolenaar# 126c243e490SMarcel Moolenaaratf_config_get() 127c243e490SMarcel Moolenaar{ 128c243e490SMarcel Moolenaar _varname="__tc_config_var_$(_atf_normalize ${1})" 129c243e490SMarcel Moolenaar if [ ${#} -eq 1 ]; then 130c243e490SMarcel Moolenaar eval _value=\"\${${_varname}-__unset__}\" 131c243e490SMarcel Moolenaar [ "${_value}" = __unset__ ] && \ 132c243e490SMarcel Moolenaar _atf_error 1 "Could not find configuration variable \`${1}'" 133c243e490SMarcel Moolenaar echo ${_value} 134c243e490SMarcel Moolenaar elif [ ${#} -eq 2 ]; then 135c243e490SMarcel Moolenaar eval echo \${${_varname}-${2}} 136c243e490SMarcel Moolenaar else 137c243e490SMarcel Moolenaar _atf_error 1 "Incorrect number of parameters for atf_config_get" 138c243e490SMarcel Moolenaar fi 139c243e490SMarcel Moolenaar} 140c243e490SMarcel Moolenaar 141c243e490SMarcel Moolenaar# 142c243e490SMarcel Moolenaar# atf_config_has varname 143c243e490SMarcel Moolenaar# 144c243e490SMarcel Moolenaar# Returns a boolean indicating if the given configuration variable is 145c243e490SMarcel Moolenaar# defined or not. 146c243e490SMarcel Moolenaar# 147c243e490SMarcel Moolenaaratf_config_has() 148c243e490SMarcel Moolenaar{ 149c243e490SMarcel Moolenaar _varname="__tc_config_var_$(_atf_normalize ${1})" 150c243e490SMarcel Moolenaar eval _value=\"\${${_varname}-__unset__}\" 151c243e490SMarcel Moolenaar [ "${_value}" != __unset__ ] 152c243e490SMarcel Moolenaar} 153c243e490SMarcel Moolenaar 154c243e490SMarcel Moolenaar# 155c243e490SMarcel Moolenaar# atf_expect_death reason 156c243e490SMarcel Moolenaar# 157c243e490SMarcel Moolenaar# Sets the expectations to 'death'. 158c243e490SMarcel Moolenaar# 159c243e490SMarcel Moolenaaratf_expect_death() 160c243e490SMarcel Moolenaar{ 161c243e490SMarcel Moolenaar _atf_validate_expect 162c243e490SMarcel Moolenaar 163c243e490SMarcel Moolenaar Expect=death 164c243e490SMarcel Moolenaar _atf_create_resfile "expected_death: ${*}" 165c243e490SMarcel Moolenaar} 166c243e490SMarcel Moolenaar 167c243e490SMarcel Moolenaar# 168c243e490SMarcel Moolenaar# atf_expect_timeout reason 169c243e490SMarcel Moolenaar# 170c243e490SMarcel Moolenaar# Sets the expectations to 'timeout'. 171c243e490SMarcel Moolenaar# 172c243e490SMarcel Moolenaaratf_expect_timeout() 173c243e490SMarcel Moolenaar{ 174c243e490SMarcel Moolenaar _atf_validate_expect 175c243e490SMarcel Moolenaar 176c243e490SMarcel Moolenaar Expect=timeout 177c243e490SMarcel Moolenaar _atf_create_resfile "expected_timeout: ${*}" 178c243e490SMarcel Moolenaar} 179c243e490SMarcel Moolenaar 180c243e490SMarcel Moolenaar# 181c243e490SMarcel Moolenaar# atf_expect_exit exitcode reason 182c243e490SMarcel Moolenaar# 183c243e490SMarcel Moolenaar# Sets the expectations to 'exit'. 184c243e490SMarcel Moolenaar# 185c243e490SMarcel Moolenaaratf_expect_exit() 186c243e490SMarcel Moolenaar{ 187c243e490SMarcel Moolenaar _exitcode="${1}"; shift 188c243e490SMarcel Moolenaar 189c243e490SMarcel Moolenaar _atf_validate_expect 190c243e490SMarcel Moolenaar 191c243e490SMarcel Moolenaar Expect=exit 192c243e490SMarcel Moolenaar if [ "${_exitcode}" = "-1" ]; then 193c243e490SMarcel Moolenaar _atf_create_resfile "expected_exit: ${*}" 194c243e490SMarcel Moolenaar else 195c243e490SMarcel Moolenaar _atf_create_resfile "expected_exit(${_exitcode}): ${*}" 196c243e490SMarcel Moolenaar fi 197c243e490SMarcel Moolenaar} 198c243e490SMarcel Moolenaar 199c243e490SMarcel Moolenaar# 200c243e490SMarcel Moolenaar# atf_expect_fail reason 201c243e490SMarcel Moolenaar# 202c243e490SMarcel Moolenaar# Sets the expectations to 'fail'. 203c243e490SMarcel Moolenaar# 204c243e490SMarcel Moolenaaratf_expect_fail() 205c243e490SMarcel Moolenaar{ 206c243e490SMarcel Moolenaar _atf_validate_expect 207c243e490SMarcel Moolenaar 208c243e490SMarcel Moolenaar Expect=fail 209c243e490SMarcel Moolenaar Expect_Reason="${*}" 210c243e490SMarcel Moolenaar} 211c243e490SMarcel Moolenaar 212c243e490SMarcel Moolenaar# 213c243e490SMarcel Moolenaar# atf_expect_pass 214c243e490SMarcel Moolenaar# 215c243e490SMarcel Moolenaar# Sets the expectations to 'pass'. 216c243e490SMarcel Moolenaar# 217c243e490SMarcel Moolenaaratf_expect_pass() 218c243e490SMarcel Moolenaar{ 219c243e490SMarcel Moolenaar _atf_validate_expect 220c243e490SMarcel Moolenaar 221c243e490SMarcel Moolenaar Expect=pass 222c243e490SMarcel Moolenaar Expect_Reason= 223c243e490SMarcel Moolenaar} 224c243e490SMarcel Moolenaar 225c243e490SMarcel Moolenaar# 226c243e490SMarcel Moolenaar# atf_expect_signal signo reason 227c243e490SMarcel Moolenaar# 228c243e490SMarcel Moolenaar# Sets the expectations to 'signal'. 229c243e490SMarcel Moolenaar# 230c243e490SMarcel Moolenaaratf_expect_signal() 231c243e490SMarcel Moolenaar{ 232c243e490SMarcel Moolenaar _signo="${1}"; shift 233c243e490SMarcel Moolenaar 234c243e490SMarcel Moolenaar _atf_validate_expect 235c243e490SMarcel Moolenaar 236c243e490SMarcel Moolenaar Expect=signal 237c243e490SMarcel Moolenaar if [ "${_signo}" = "-1" ]; then 238c243e490SMarcel Moolenaar _atf_create_resfile "expected_signal: ${*}" 239c243e490SMarcel Moolenaar else 240c243e490SMarcel Moolenaar _atf_create_resfile "expected_signal(${_signo}): ${*}" 241c243e490SMarcel Moolenaar fi 242c243e490SMarcel Moolenaar} 243c243e490SMarcel Moolenaar 244c243e490SMarcel Moolenaar# 245c243e490SMarcel Moolenaar# atf_expected_failure msg1 [.. msgN] 246c243e490SMarcel Moolenaar# 247c243e490SMarcel Moolenaar# Makes the test case report an expected failure with the given error 248c243e490SMarcel Moolenaar# message. Multiple words can be provided, which are concatenated with 249c243e490SMarcel Moolenaar# a single blank space. 250c243e490SMarcel Moolenaar# 251c243e490SMarcel Moolenaaratf_expected_failure() 252c243e490SMarcel Moolenaar{ 253c243e490SMarcel Moolenaar _atf_create_resfile "expected_failure: ${Expect_Reason}: ${*}" 254c243e490SMarcel Moolenaar exit 0 255c243e490SMarcel Moolenaar} 256c243e490SMarcel Moolenaar 257c243e490SMarcel Moolenaar# 258c243e490SMarcel Moolenaar# atf_fail msg1 [.. msgN] 259c243e490SMarcel Moolenaar# 260c243e490SMarcel Moolenaar# Makes the test case fail with the given error message. Multiple 261c243e490SMarcel Moolenaar# words can be provided, in which case they are joined by a single 262c243e490SMarcel Moolenaar# blank space. 263c243e490SMarcel Moolenaar# 264c243e490SMarcel Moolenaaratf_fail() 265c243e490SMarcel Moolenaar{ 266c243e490SMarcel Moolenaar case "${Expect}" in 267c243e490SMarcel Moolenaar fail) 268c243e490SMarcel Moolenaar atf_expected_failure "${@}" 269c243e490SMarcel Moolenaar ;; 270c243e490SMarcel Moolenaar pass) 271c243e490SMarcel Moolenaar _atf_create_resfile "failed: ${*}" 272c243e490SMarcel Moolenaar exit 1 273c243e490SMarcel Moolenaar ;; 274c243e490SMarcel Moolenaar *) 275c243e490SMarcel Moolenaar _atf_error 128 "Unreachable" 276c243e490SMarcel Moolenaar ;; 277c243e490SMarcel Moolenaar esac 278c243e490SMarcel Moolenaar} 279c243e490SMarcel Moolenaar 280c243e490SMarcel Moolenaar# 281c243e490SMarcel Moolenaar# atf_get varname 282c243e490SMarcel Moolenaar# 283c243e490SMarcel Moolenaar# Prints the value of a test case-specific variable. Given that one 284c243e490SMarcel Moolenaar# should not get the value of non-existent variables, it is fine to 285c243e490SMarcel Moolenaar# always use this function as 'val=$(atf_get var)'. 286c243e490SMarcel Moolenaar# 287c243e490SMarcel Moolenaaratf_get() 288c243e490SMarcel Moolenaar{ 289c243e490SMarcel Moolenaar eval echo \${__tc_var_${Test_Case}_$(_atf_normalize ${1})} 290c243e490SMarcel Moolenaar} 291c243e490SMarcel Moolenaar 292c243e490SMarcel Moolenaar# 293c243e490SMarcel Moolenaar# atf_get_srcdir 294c243e490SMarcel Moolenaar# 295c243e490SMarcel Moolenaar# Prints the value of the test case's source directory. 296c243e490SMarcel Moolenaar# 297c243e490SMarcel Moolenaaratf_get_srcdir() 298c243e490SMarcel Moolenaar{ 299c243e490SMarcel Moolenaar echo ${Source_Dir} 300c243e490SMarcel Moolenaar} 301c243e490SMarcel Moolenaar 302c243e490SMarcel Moolenaar# 303c243e490SMarcel Moolenaar# atf_pass 304c243e490SMarcel Moolenaar# 305c243e490SMarcel Moolenaar# Makes the test case pass. Shouldn't be used in general, as a test 306c243e490SMarcel Moolenaar# case that does not explicitly fail is assumed to pass. 307c243e490SMarcel Moolenaar# 308c243e490SMarcel Moolenaaratf_pass() 309c243e490SMarcel Moolenaar{ 310c243e490SMarcel Moolenaar case "${Expect}" in 311c243e490SMarcel Moolenaar fail) 312c243e490SMarcel Moolenaar Expect=pass 313c243e490SMarcel Moolenaar atf_fail "Test case was expecting a failure but got a pass instead" 314c243e490SMarcel Moolenaar ;; 315c243e490SMarcel Moolenaar pass) 316c243e490SMarcel Moolenaar _atf_create_resfile passed 317c243e490SMarcel Moolenaar exit 0 318c243e490SMarcel Moolenaar ;; 319c243e490SMarcel Moolenaar *) 320c243e490SMarcel Moolenaar _atf_error 128 "Unreachable" 321c243e490SMarcel Moolenaar ;; 322c243e490SMarcel Moolenaar esac 323c243e490SMarcel Moolenaar} 324c243e490SMarcel Moolenaar 325c243e490SMarcel Moolenaar# 326c243e490SMarcel Moolenaar# atf_require_prog prog 327c243e490SMarcel Moolenaar# 328c243e490SMarcel Moolenaar# Checks that the given program name (either provided as an absolute 329c243e490SMarcel Moolenaar# path or as a plain file name) can be found. If it is not available, 330c243e490SMarcel Moolenaar# automatically skips the test case with an appropriate message. 331c243e490SMarcel Moolenaar# 332c243e490SMarcel Moolenaar# Relative paths are not allowed because the test case cannot predict 333c243e490SMarcel Moolenaar# where it will be executed from. 334c243e490SMarcel Moolenaar# 335c243e490SMarcel Moolenaaratf_require_prog() 336c243e490SMarcel Moolenaar{ 337c243e490SMarcel Moolenaar _prog= 338c243e490SMarcel Moolenaar case ${1} in 339c243e490SMarcel Moolenaar /*) 340c243e490SMarcel Moolenaar _prog="${1}" 341c243e490SMarcel Moolenaar [ -x ${_prog} ] || \ 342c243e490SMarcel Moolenaar atf_skip "The required program ${1} could not be found" 343c243e490SMarcel Moolenaar ;; 344c243e490SMarcel Moolenaar */*) 345c243e490SMarcel Moolenaar atf_fail "atf_require_prog does not accept relative path names \`${1}'" 346c243e490SMarcel Moolenaar ;; 347c243e490SMarcel Moolenaar *) 348c243e490SMarcel Moolenaar _prog=$(_atf_find_in_path "${1}") 349c243e490SMarcel Moolenaar [ -n "${_prog}" ] || \ 350c243e490SMarcel Moolenaar atf_skip "The required program ${1} could not be found" \ 351c243e490SMarcel Moolenaar "in the PATH" 352c243e490SMarcel Moolenaar ;; 353c243e490SMarcel Moolenaar esac 354c243e490SMarcel Moolenaar} 355c243e490SMarcel Moolenaar 356c243e490SMarcel Moolenaar# 357*83a1ee57SDag-Erling Smørgrav# atf_require_kmod kmod 358*83a1ee57SDag-Erling Smørgrav# 359*83a1ee57SDag-Erling Smørgrav# Checks that the given kmod is loaded. If it is not, automatically 360*83a1ee57SDag-Erling Smørgrav# skips the test case with an appropriate message. 361*83a1ee57SDag-Erling Smørgrav# 362*83a1ee57SDag-Erling Smørgravatf_require_kmod() 363*83a1ee57SDag-Erling Smørgrav{ 364*83a1ee57SDag-Erling Smørgrav kldstat -q "${1}" || \ 365*83a1ee57SDag-Erling Smørgrav atf_skip "The required kmod ${1} is not loaded" 366*83a1ee57SDag-Erling Smørgrav} 367*83a1ee57SDag-Erling Smørgrav 368*83a1ee57SDag-Erling Smørgrav# 369c243e490SMarcel Moolenaar# atf_set varname val1 [.. valN] 370c243e490SMarcel Moolenaar# 371c243e490SMarcel Moolenaar# Sets the test case's variable 'varname' to the specified values 372c243e490SMarcel Moolenaar# which are concatenated using a single blank space. This function 373d4d14d96SIgor Ostapenko# is supposed to be called from the test case's head only. 374c243e490SMarcel Moolenaar# 375c243e490SMarcel Moolenaaratf_set() 376c243e490SMarcel Moolenaar{ 377c243e490SMarcel Moolenaar ${Parsing_Head} || \ 378c243e490SMarcel Moolenaar _atf_error 128 "atf_set called from the test case's body" 379c243e490SMarcel Moolenaar 380c243e490SMarcel Moolenaar Test_Case_Vars="${Test_Case_Vars} ${1}" 381c243e490SMarcel Moolenaar _var=$(_atf_normalize ${1}); shift 382c243e490SMarcel Moolenaar eval __tc_var_${Test_Case}_${_var}=\"\${*}\" 383c243e490SMarcel Moolenaar} 384c243e490SMarcel Moolenaar 385c243e490SMarcel Moolenaar# 386c243e490SMarcel Moolenaar# atf_skip msg1 [.. msgN] 387c243e490SMarcel Moolenaar# 388c243e490SMarcel Moolenaar# Skips the test case because of the reason provided. Multiple words 389c243e490SMarcel Moolenaar# can be given, in which case they are joined by a single blank space. 390c243e490SMarcel Moolenaar# 391c243e490SMarcel Moolenaaratf_skip() 392c243e490SMarcel Moolenaar{ 393c243e490SMarcel Moolenaar _atf_create_resfile "skipped: ${*}" 394c243e490SMarcel Moolenaar exit 0 395c243e490SMarcel Moolenaar} 396c243e490SMarcel Moolenaar 397c243e490SMarcel Moolenaar# 398c243e490SMarcel Moolenaar# atf_test_case tc-name cleanup 399c243e490SMarcel Moolenaar# 400c243e490SMarcel Moolenaar# Defines a new test case named tc-name. The name provided here must be 401c243e490SMarcel Moolenaar# accompanied by two functions named after it: <tc-name>_head and 402c243e490SMarcel Moolenaar# <tc-name>_body. If cleanup is set to 'cleanup', then this also expects 403c243e490SMarcel Moolenaar# a <tc-name>_cleanup function to be defined. 404c243e490SMarcel Moolenaar# 405c243e490SMarcel Moolenaaratf_test_case() 406c243e490SMarcel Moolenaar{ 407c243e490SMarcel Moolenaar eval "${1}_head() { :; }" 408c243e490SMarcel Moolenaar eval "${1}_body() { atf_fail 'Test case not implemented'; }" 409c243e490SMarcel Moolenaar if [ "${2}" = cleanup ]; then 410c243e490SMarcel Moolenaar eval __has_cleanup_${1}=true 411c243e490SMarcel Moolenaar eval "${1}_cleanup() { :; }" 412c243e490SMarcel Moolenaar else 413c243e490SMarcel Moolenaar eval "${1}_cleanup() { 414c243e490SMarcel Moolenaar _atf_error 1 'Test case ${1} declared without a cleanup routine'; }" 415c243e490SMarcel Moolenaar fi 416c243e490SMarcel Moolenaar} 417c243e490SMarcel Moolenaar 418c243e490SMarcel Moolenaar# ------------------------------------------------------------------------ 419c243e490SMarcel Moolenaar# PRIVATE INTERFACE 420c243e490SMarcel Moolenaar# ------------------------------------------------------------------------ 421c243e490SMarcel Moolenaar 422c243e490SMarcel Moolenaar# 423c243e490SMarcel Moolenaar# _atf_config_set varname val1 [.. valN] 424c243e490SMarcel Moolenaar# 425c243e490SMarcel Moolenaar# Sets the test case's private variable 'varname' to the specified 426c243e490SMarcel Moolenaar# values which are concatenated using a single blank space. 427c243e490SMarcel Moolenaar# 428c243e490SMarcel Moolenaar_atf_config_set() 429c243e490SMarcel Moolenaar{ 430c243e490SMarcel Moolenaar _var=$(_atf_normalize ${1}); shift 431c243e490SMarcel Moolenaar eval __tc_config_var_${_var}=\"\${*}\" 432c243e490SMarcel Moolenaar Config_Vars="${Config_Vars} __tc_config_var_${_var}" 433c243e490SMarcel Moolenaar} 434c243e490SMarcel Moolenaar 435c243e490SMarcel Moolenaar# 436c243e490SMarcel Moolenaar# _atf_config_set_str varname=val 437c243e490SMarcel Moolenaar# 438c243e490SMarcel Moolenaar# Sets the test case's private variable 'varname' to the specified 439c243e490SMarcel Moolenaar# value. The parameter is of the form 'varname=val'. 440c243e490SMarcel Moolenaar# 441c243e490SMarcel Moolenaar_atf_config_set_from_str() 442c243e490SMarcel Moolenaar{ 443c243e490SMarcel Moolenaar _oldifs=${IFS} 444c243e490SMarcel Moolenaar IFS='=' 445c243e490SMarcel Moolenaar set -- ${*} 446c243e490SMarcel Moolenaar _var=${1} 447c243e490SMarcel Moolenaar shift 448c243e490SMarcel Moolenaar _val="${@}" 449c243e490SMarcel Moolenaar IFS=${_oldifs} 450c243e490SMarcel Moolenaar _atf_config_set "${_var}" "${_val}" 451c243e490SMarcel Moolenaar} 452c243e490SMarcel Moolenaar 453c243e490SMarcel Moolenaar# 454c243e490SMarcel Moolenaar# _atf_create_resfile contents 455c243e490SMarcel Moolenaar# 456c243e490SMarcel Moolenaar# Creates the results file. 457c243e490SMarcel Moolenaar# 458c243e490SMarcel Moolenaar_atf_create_resfile() 459c243e490SMarcel Moolenaar{ 460c243e490SMarcel Moolenaar if [ -n "${Results_File}" ]; then 461c243e490SMarcel Moolenaar echo "${*}" >"${Results_File}" || \ 462c243e490SMarcel Moolenaar _atf_error 128 "Cannot create results file '${Results_File}'" 463c243e490SMarcel Moolenaar else 464c243e490SMarcel Moolenaar echo "${*}" 465c243e490SMarcel Moolenaar fi 466c243e490SMarcel Moolenaar} 467c243e490SMarcel Moolenaar 468c243e490SMarcel Moolenaar# 469c243e490SMarcel Moolenaar# _atf_error error_code [msg1 [.. msgN]] 470c243e490SMarcel Moolenaar# 471c243e490SMarcel Moolenaar# Prints the given error message (which can be composed of multiple 472c243e490SMarcel Moolenaar# arguments, in which case are joined by a single space) and exits 473c243e490SMarcel Moolenaar# with the specified error code. 474c243e490SMarcel Moolenaar# 475c243e490SMarcel Moolenaar# This must not be used by test programs themselves (hence making 476c243e490SMarcel Moolenaar# the function private) to indicate a test case's failure. They 477c243e490SMarcel Moolenaar# have to use the atf_fail function. 478c243e490SMarcel Moolenaar# 479c243e490SMarcel Moolenaar_atf_error() 480c243e490SMarcel Moolenaar{ 481c243e490SMarcel Moolenaar _error_code="${1}"; shift 482c243e490SMarcel Moolenaar 483c243e490SMarcel Moolenaar echo "${Prog_Name}: ERROR:" "$@" 1>&2 484c243e490SMarcel Moolenaar exit ${_error_code} 485c243e490SMarcel Moolenaar} 486c243e490SMarcel Moolenaar 487c243e490SMarcel Moolenaar# 488c243e490SMarcel Moolenaar# _atf_warning msg1 [.. msgN] 489c243e490SMarcel Moolenaar# 490c243e490SMarcel Moolenaar# Prints the given warning message (which can be composed of multiple 491c243e490SMarcel Moolenaar# arguments, in which case are joined by a single space). 492c243e490SMarcel Moolenaar# 493c243e490SMarcel Moolenaar_atf_warning() 494c243e490SMarcel Moolenaar{ 495c243e490SMarcel Moolenaar echo "${Prog_Name}: WARNING:" "$@" 1>&2 496c243e490SMarcel Moolenaar} 497c243e490SMarcel Moolenaar 498c243e490SMarcel Moolenaar# 499c243e490SMarcel Moolenaar# _atf_find_in_path program 500c243e490SMarcel Moolenaar# 501c243e490SMarcel Moolenaar# Looks for a program in the path and prints the full path to it or 502c243e490SMarcel Moolenaar# nothing if it could not be found. It also returns true in case of 503c243e490SMarcel Moolenaar# success. 504c243e490SMarcel Moolenaar# 505c243e490SMarcel Moolenaar_atf_find_in_path() 506c243e490SMarcel Moolenaar{ 507c243e490SMarcel Moolenaar _prog="${1}" 508c243e490SMarcel Moolenaar 509c243e490SMarcel Moolenaar _oldifs=${IFS} 510c243e490SMarcel Moolenaar IFS=: 511c243e490SMarcel Moolenaar for _dir in ${PATH} 512c243e490SMarcel Moolenaar do 513c243e490SMarcel Moolenaar if [ -x ${_dir}/${_prog} ]; then 514c243e490SMarcel Moolenaar IFS=${_oldifs} 515c243e490SMarcel Moolenaar echo ${_dir}/${_prog} 516c243e490SMarcel Moolenaar return 0 517c243e490SMarcel Moolenaar fi 518c243e490SMarcel Moolenaar done 519c243e490SMarcel Moolenaar IFS=${_oldifs} 520c243e490SMarcel Moolenaar 521c243e490SMarcel Moolenaar return 1 522c243e490SMarcel Moolenaar} 523c243e490SMarcel Moolenaar 524c243e490SMarcel Moolenaar# 525c243e490SMarcel Moolenaar# _atf_has_tc name 526c243e490SMarcel Moolenaar# 527c243e490SMarcel Moolenaar# Returns true if the given test case exists. 528c243e490SMarcel Moolenaar# 529c243e490SMarcel Moolenaar_atf_has_tc() 530c243e490SMarcel Moolenaar{ 531c243e490SMarcel Moolenaar for _tc in ${Test_Cases}; do 532c243e490SMarcel Moolenaar [ "${_tc}" != "${1}" ] || return 0 533c243e490SMarcel Moolenaar done 534c243e490SMarcel Moolenaar return 1 535c243e490SMarcel Moolenaar} 536c243e490SMarcel Moolenaar 537c243e490SMarcel Moolenaar# 538c243e490SMarcel Moolenaar# _atf_list_tcs 539c243e490SMarcel Moolenaar# 540c243e490SMarcel Moolenaar# Describes all test cases and prints the list to the standard output. 541c243e490SMarcel Moolenaar# 542c243e490SMarcel Moolenaar_atf_list_tcs() 543c243e490SMarcel Moolenaar{ 544c243e490SMarcel Moolenaar echo 'Content-Type: application/X-atf-tp; version="1"' 545c243e490SMarcel Moolenaar echo 546c243e490SMarcel Moolenaar 547c243e490SMarcel Moolenaar set -- ${Test_Cases} 548c243e490SMarcel Moolenaar while [ ${#} -gt 0 ]; do 549c243e490SMarcel Moolenaar _atf_parse_head ${1} 550c243e490SMarcel Moolenaar 551c243e490SMarcel Moolenaar echo "ident: $(atf_get ident)" 552c243e490SMarcel Moolenaar for _var in ${Test_Case_Vars}; do 553c243e490SMarcel Moolenaar [ "${_var}" != "ident" ] && echo "${_var}: $(atf_get ${_var})" 554c243e490SMarcel Moolenaar done 555c243e490SMarcel Moolenaar 556c243e490SMarcel Moolenaar [ ${#} -gt 1 ] && echo 557c243e490SMarcel Moolenaar shift 558c243e490SMarcel Moolenaar done 559c243e490SMarcel Moolenaar} 560c243e490SMarcel Moolenaar 561c243e490SMarcel Moolenaar# 562c243e490SMarcel Moolenaar# _atf_normalize str 563c243e490SMarcel Moolenaar# 564c243e490SMarcel Moolenaar# Normalizes a string so that it is a valid shell variable name. 565c243e490SMarcel Moolenaar# 566c243e490SMarcel Moolenaar_atf_normalize() 567c243e490SMarcel Moolenaar{ 568c203bd70SAlex Richardson # Check if the string contains any of the forbidden characters using 569c203bd70SAlex Richardson # POSIX parameter expansion (the ${var//} string substitution is 570c203bd70SAlex Richardson # unfortunately not supported in POSIX sh) and only use tr(1) then. 571c203bd70SAlex Richardson # tr(1) is generally not a builtin, so doing the substring check first 572c203bd70SAlex Richardson # avoids unnecessary fork()+execve() calls. As this function is called 573c203bd70SAlex Richardson # many times in each test script startup, those overheads add up 574c203bd70SAlex Richardson # (especially when running on emulated platforms such as QEMU). 575c203bd70SAlex Richardson if [ "${1#*[.-]}" != "$1" ]; then 576c203bd70SAlex Richardson echo "$1" | tr .- __ 577c203bd70SAlex Richardson else 578c203bd70SAlex Richardson echo "$1" 579c203bd70SAlex Richardson fi 580c243e490SMarcel Moolenaar} 581c243e490SMarcel Moolenaar 582c243e490SMarcel Moolenaar# 583c243e490SMarcel Moolenaar# _atf_parse_head tcname 584c243e490SMarcel Moolenaar# 585c243e490SMarcel Moolenaar# Evaluates a test case's head to gather its variables and prepares the 586c243e490SMarcel Moolenaar# test program to run it. 587c243e490SMarcel Moolenaar# 588c243e490SMarcel Moolenaar_atf_parse_head() 589c243e490SMarcel Moolenaar{ 590c243e490SMarcel Moolenaar Parsing_Head=true 591c243e490SMarcel Moolenaar 592c243e490SMarcel Moolenaar Test_Case="${1}" 593c243e490SMarcel Moolenaar Test_Case_Vars= 594c243e490SMarcel Moolenaar 595c243e490SMarcel Moolenaar if _atf_has_cleanup "${1}"; then 596c243e490SMarcel Moolenaar atf_set has.cleanup "true" 597c243e490SMarcel Moolenaar fi 598c243e490SMarcel Moolenaar 599c243e490SMarcel Moolenaar ${1}_head 600c243e490SMarcel Moolenaar atf_set ident "${1}" 601c243e490SMarcel Moolenaar 602c243e490SMarcel Moolenaar Parsing_Head=false 603c243e490SMarcel Moolenaar} 604c243e490SMarcel Moolenaar 605c243e490SMarcel Moolenaar# 606c243e490SMarcel Moolenaar# _atf_run_tc tc 607c243e490SMarcel Moolenaar# 608c243e490SMarcel Moolenaar# Runs the specified test case. Prints its exit status to the 609c243e490SMarcel Moolenaar# standard output and returns a boolean indicating if the test was 610c243e490SMarcel Moolenaar# successful or not. 611c243e490SMarcel Moolenaar# 612c243e490SMarcel Moolenaar_atf_run_tc() 613c243e490SMarcel Moolenaar{ 614c243e490SMarcel Moolenaar case ${1} in 615c243e490SMarcel Moolenaar *:*) 616c243e490SMarcel Moolenaar _tcname=${1%%:*} 617c243e490SMarcel Moolenaar _tcpart=${1#*:} 618c243e490SMarcel Moolenaar 619c243e490SMarcel Moolenaar if [ "${_tcpart}" != body -a "${_tcpart}" != cleanup ]; then 620c243e490SMarcel Moolenaar _atf_syntax_error "Unknown test case part \`${_tcpart}'" 621c243e490SMarcel Moolenaar fi 622c243e490SMarcel Moolenaar ;; 623c243e490SMarcel Moolenaar 624c243e490SMarcel Moolenaar *) 625c243e490SMarcel Moolenaar _tcname=${1} 626c243e490SMarcel Moolenaar _tcpart=body 627c243e490SMarcel Moolenaar ;; 628c243e490SMarcel Moolenaar esac 629c243e490SMarcel Moolenaar 630c243e490SMarcel Moolenaar _atf_has_tc "${_tcname}" || _atf_syntax_error "Unknown test case \`${1}'" 631c243e490SMarcel Moolenaar 632c243e490SMarcel Moolenaar if [ "${__RUNNING_INSIDE_ATF_RUN}" != "internal-yes-value" ]; then 6330677dfd1SJulio Merino _atf_warning "Running test cases outside of kyua(1) is unsupported" 634c243e490SMarcel Moolenaar _atf_warning "No isolation nor timeout control is being applied;" \ 635c243e490SMarcel Moolenaar "you may get unexpected failures; see atf-test-case(4)" 636c243e490SMarcel Moolenaar fi 637c243e490SMarcel Moolenaar 638c243e490SMarcel Moolenaar _atf_parse_head ${_tcname} 639c243e490SMarcel Moolenaar 640c243e490SMarcel Moolenaar case ${_tcpart} in 641c243e490SMarcel Moolenaar body) 642c243e490SMarcel Moolenaar if ${_tcname}_body; then 643c243e490SMarcel Moolenaar _atf_validate_expect 644c243e490SMarcel Moolenaar _atf_create_resfile passed 645c243e490SMarcel Moolenaar else 646c243e490SMarcel Moolenaar Expect=pass 647c243e490SMarcel Moolenaar atf_fail "Test case body returned a non-ok exit code, but" \ 648c243e490SMarcel Moolenaar "this is not allowed" 649c243e490SMarcel Moolenaar fi 650c243e490SMarcel Moolenaar ;; 651c243e490SMarcel Moolenaar cleanup) 652c243e490SMarcel Moolenaar if _atf_has_cleanup "${_tcname}"; then 653c243e490SMarcel Moolenaar ${_tcname}_cleanup || _atf_error 128 "The test case cleanup" \ 654c243e490SMarcel Moolenaar "returned a non-ok exit code, but this is not allowed" 655c243e490SMarcel Moolenaar fi 656c243e490SMarcel Moolenaar ;; 657c243e490SMarcel Moolenaar *) 658c243e490SMarcel Moolenaar _atf_error 128 "Unknown test case part" 659c243e490SMarcel Moolenaar ;; 660c243e490SMarcel Moolenaar esac 661c243e490SMarcel Moolenaar} 662c243e490SMarcel Moolenaar 663c243e490SMarcel Moolenaar# 664c243e490SMarcel Moolenaar# _atf_syntax_error msg1 [.. msgN] 665c243e490SMarcel Moolenaar# 666c243e490SMarcel Moolenaar# Formats and prints a syntax error message and terminates the 667c243e490SMarcel Moolenaar# program prematurely. 668c243e490SMarcel Moolenaar# 669c243e490SMarcel Moolenaar_atf_syntax_error() 670c243e490SMarcel Moolenaar{ 671c243e490SMarcel Moolenaar echo "${Prog_Name}: ERROR: ${@}" 1>&2 672c243e490SMarcel Moolenaar echo "${Prog_Name}: See atf-test-program(1) for usage details." 1>&2 673c243e490SMarcel Moolenaar exit 1 674c243e490SMarcel Moolenaar} 675c243e490SMarcel Moolenaar 676c243e490SMarcel Moolenaar# 677c243e490SMarcel Moolenaar# _atf_has_cleanup tc-name 678c243e490SMarcel Moolenaar# 679c243e490SMarcel Moolenaar# Returns a boolean indicating if the given test case has a cleanup 680c243e490SMarcel Moolenaar# routine or not. 681c243e490SMarcel Moolenaar# 682c243e490SMarcel Moolenaar_atf_has_cleanup() 683c243e490SMarcel Moolenaar{ 684c243e490SMarcel Moolenaar _found=true 685c243e490SMarcel Moolenaar eval "[ x\"\${__has_cleanup_${1}}\" = xtrue ] || _found=false" 686c243e490SMarcel Moolenaar [ "${_found}" = true ] 687c243e490SMarcel Moolenaar} 688c243e490SMarcel Moolenaar 689c243e490SMarcel Moolenaar# 690c243e490SMarcel Moolenaar# _atf_validate_expect 691c243e490SMarcel Moolenaar# 692c243e490SMarcel Moolenaar# Ensures that the current test case state is correct regarding the expect 693c243e490SMarcel Moolenaar# status. 694c243e490SMarcel Moolenaar# 695c243e490SMarcel Moolenaar_atf_validate_expect() 696c243e490SMarcel Moolenaar{ 697c243e490SMarcel Moolenaar case "${Expect}" in 698c243e490SMarcel Moolenaar death) 699c243e490SMarcel Moolenaar Expect=pass 700c243e490SMarcel Moolenaar atf_fail "Test case was expected to terminate abruptly but it" \ 701c243e490SMarcel Moolenaar "continued execution" 702c243e490SMarcel Moolenaar ;; 703c243e490SMarcel Moolenaar exit) 704c243e490SMarcel Moolenaar Expect=pass 705c243e490SMarcel Moolenaar atf_fail "Test case was expected to exit cleanly but it continued" \ 706c243e490SMarcel Moolenaar "execution" 707c243e490SMarcel Moolenaar ;; 708c243e490SMarcel Moolenaar fail) 709c243e490SMarcel Moolenaar Expect=pass 710c243e490SMarcel Moolenaar atf_fail "Test case was expecting a failure but none were raised" 711c243e490SMarcel Moolenaar ;; 712c243e490SMarcel Moolenaar pass) 713c243e490SMarcel Moolenaar ;; 714c243e490SMarcel Moolenaar signal) 715c243e490SMarcel Moolenaar Expect=pass 716c243e490SMarcel Moolenaar atf_fail "Test case was expected to receive a termination signal" \ 717c243e490SMarcel Moolenaar "but it continued execution" 718c243e490SMarcel Moolenaar ;; 719c243e490SMarcel Moolenaar timeout) 720c243e490SMarcel Moolenaar Expect=pass 721c243e490SMarcel Moolenaar atf_fail "Test case was expected to hang but it continued execution" 722c243e490SMarcel Moolenaar ;; 723c243e490SMarcel Moolenaar *) 724c243e490SMarcel Moolenaar _atf_error 128 "Unreachable" 725c243e490SMarcel Moolenaar ;; 726c243e490SMarcel Moolenaar esac 727c243e490SMarcel Moolenaar} 728c243e490SMarcel Moolenaar 729c243e490SMarcel Moolenaar# 730c243e490SMarcel Moolenaar# _atf_warning [msg1 [.. msgN]] 731c243e490SMarcel Moolenaar# 732c243e490SMarcel Moolenaar# Prints the given warning message (which can be composed of multiple 733c243e490SMarcel Moolenaar# arguments, in which case are joined by a single space). 734c243e490SMarcel Moolenaar# 735c243e490SMarcel Moolenaar# This must not be used by test programs themselves (hence making 736c243e490SMarcel Moolenaar# the function private). 737c243e490SMarcel Moolenaar# 738c243e490SMarcel Moolenaar_atf_warning() 739c243e490SMarcel Moolenaar{ 740c243e490SMarcel Moolenaar echo "${Prog_Name}: WARNING:" "$@" 1>&2 741c243e490SMarcel Moolenaar} 742c243e490SMarcel Moolenaar 743c243e490SMarcel Moolenaar# 744c243e490SMarcel Moolenaar# main [options] test_case 745c243e490SMarcel Moolenaar# 746c243e490SMarcel Moolenaar# Test program's entry point. 747c243e490SMarcel Moolenaar# 748c243e490SMarcel Moolenaarmain() 749c243e490SMarcel Moolenaar{ 750c243e490SMarcel Moolenaar # Process command-line options first. 751c243e490SMarcel Moolenaar _numargs=${#} 752c243e490SMarcel Moolenaar _lflag=false 753c243e490SMarcel Moolenaar while getopts :lr:s:v: arg; do 754c243e490SMarcel Moolenaar case ${arg} in 755c243e490SMarcel Moolenaar l) 756c243e490SMarcel Moolenaar _lflag=true 757c243e490SMarcel Moolenaar ;; 758c243e490SMarcel Moolenaar 759c243e490SMarcel Moolenaar r) 760c243e490SMarcel Moolenaar Results_File=${OPTARG} 761c243e490SMarcel Moolenaar ;; 762c243e490SMarcel Moolenaar 763c243e490SMarcel Moolenaar s) 764c243e490SMarcel Moolenaar Source_Dir=${OPTARG} 765c243e490SMarcel Moolenaar ;; 766c243e490SMarcel Moolenaar 767c243e490SMarcel Moolenaar v) 768c243e490SMarcel Moolenaar _atf_config_set_from_str "${OPTARG}" 769c243e490SMarcel Moolenaar ;; 770c243e490SMarcel Moolenaar 771c243e490SMarcel Moolenaar \?) 772c243e490SMarcel Moolenaar _atf_syntax_error "Unknown option -${OPTARG}." 773c243e490SMarcel Moolenaar # NOTREACHED 774c243e490SMarcel Moolenaar ;; 775c243e490SMarcel Moolenaar esac 776c243e490SMarcel Moolenaar done 777c203bd70SAlex Richardson shift $((OPTIND - 1)) 778c243e490SMarcel Moolenaar 779c243e490SMarcel Moolenaar case ${Source_Dir} in 780c243e490SMarcel Moolenaar /*) 781c243e490SMarcel Moolenaar ;; 782c243e490SMarcel Moolenaar *) 783c243e490SMarcel Moolenaar Source_Dir=$(pwd)/${Source_Dir} 784c243e490SMarcel Moolenaar ;; 785c243e490SMarcel Moolenaar esac 786c243e490SMarcel Moolenaar [ -f ${Source_Dir}/${Prog_Name} ] || \ 787c243e490SMarcel Moolenaar _atf_error 1 "Cannot find the test program in the source" \ 788c243e490SMarcel Moolenaar "directory \`${Source_Dir}'" 789c243e490SMarcel Moolenaar 790c243e490SMarcel Moolenaar # Call the test program's hook to register all available test cases. 791c243e490SMarcel Moolenaar atf_init_test_cases 792c243e490SMarcel Moolenaar 793c243e490SMarcel Moolenaar # Run or list test cases. 794c243e490SMarcel Moolenaar if `${_lflag}`; then 795c243e490SMarcel Moolenaar if [ ${#} -gt 0 ]; then 796c243e490SMarcel Moolenaar _atf_syntax_error "Cannot provide test case names with -l" 797c243e490SMarcel Moolenaar fi 798c243e490SMarcel Moolenaar _atf_list_tcs 799c243e490SMarcel Moolenaar else 800c243e490SMarcel Moolenaar if [ ${#} -eq 0 ]; then 801c243e490SMarcel Moolenaar _atf_syntax_error "Must provide a test case name" 802c243e490SMarcel Moolenaar elif [ ${#} -gt 1 ]; then 803c243e490SMarcel Moolenaar _atf_syntax_error "Cannot provide more than one test case name" 804c243e490SMarcel Moolenaar else 805c243e490SMarcel Moolenaar _atf_run_tc "${1}" 806c243e490SMarcel Moolenaar fi 807c243e490SMarcel Moolenaar fi 808c243e490SMarcel Moolenaar} 809c243e490SMarcel Moolenaar 810c243e490SMarcel Moolenaar# vim: syntax=sh:expandtab:shiftwidth=4:softtabstop=4 811