Path: blob/master/tools/testing/selftests/kselftest/runner.sh
50376 views
#!/bin/sh1# SPDX-License-Identifier: GPL-2.02#3# Runs a set of tests in a given subdirectory.4export skip_rc=45export timeout_rc=1246export logfile=/dev/stdout7export per_test_logging=8export RUN_IN_NETNS=910# Defaults for "settings" file fields:11# "timeout" how many seconds to let each test run before running12# over our soft timeout limit.13export kselftest_default_timeout=451415# There isn't a shell-agnostic way to find the path of a sourced file,16# so we must rely on BASE_DIR being set to find other tools.17if [ -z "$BASE_DIR" ]; then18echo "Error: BASE_DIR must be set before sourcing." >&219exit 120fi2122TR_CMD=$(command -v tr)2324# If Perl is unavailable, we must fall back to line-at-a-time prefixing25# with sed instead of unbuffered output.26tap_prefix()27{28if [ ! -x /usr/bin/perl ]; then29sed -e 's/^/# /'30else31"$BASE_DIR"/kselftest/prefix.pl32fi33}3435tap_timeout()36{37# Make sure tests will time out if utility is available.38if [ -x /usr/bin/timeout ] ; then39/usr/bin/timeout --foreground "$kselftest_timeout" \40/usr/bin/timeout "$kselftest_timeout" $141else42$143fi44}4546report_failure()47{48echo "not ok $*"49echo "$*" >> "$kselftest_failures_file"50}5152run_one()53{54DIR="$1"55TEST="$2"56local test_num="$3"5758BASENAME_TEST=$(basename $TEST)5960# Reset any "settings"-file variables.61export kselftest_timeout="$kselftest_default_timeout"6263# Safe default if tr not available64kselftest_cmd_args_ref="KSELFTEST_ARGS"6566# Optional arguments for this command, possibly defined as an67# environment variable built using the test executable in all68# uppercase and sanitized substituting non acceptable shell69# variable name characters with "_" as in:70#71# KSELFTEST_<UPPERCASE_SANITIZED_TESTNAME>_ARGS="<options>"72#73# e.g.74#75# rtctest --> KSELFTEST_RTCTEST_ARGS="/dev/rtc1"76#77# cpu-on-off-test.sh --> KSELFTEST_CPU_ON_OFF_TEST_SH_ARGS="-a -p 10"78#79if [ -n "$TR_CMD" ]; then80BASENAME_SANITIZED=$(echo "$BASENAME_TEST" | \81$TR_CMD -d "[:blank:][:cntrl:]" | \82$TR_CMD -c "[:alnum:]_" "_" | \83$TR_CMD [:lower:] [:upper:])84kselftest_cmd_args_ref="KSELFTEST_${BASENAME_SANITIZED}_ARGS"85fi8687# Load per-test-directory kselftest "settings" file.88settings="$BASE_DIR/$DIR/settings"89if [ -r "$settings" ] ; then90while read line ; do91# Skip comments.92if echo "$line" | grep -q '^#'; then93continue94fi95field=$(echo "$line" | cut -d= -f1)96value=$(echo "$line" | cut -d= -f2-)97eval "kselftest_$field"="$value"98done < "$settings"99fi100101# Command line timeout overrides the settings file102if [ -n "$kselftest_override_timeout" ]; then103kselftest_timeout="$kselftest_override_timeout"104echo "# overriding timeout to $kselftest_timeout" >> "$logfile"105else106echo "# timeout set to $kselftest_timeout" >> "$logfile"107fi108109TEST_HDR_MSG="selftests: $DIR: $BASENAME_TEST"110echo "# $TEST_HDR_MSG"111if [ ! -e "$TEST" ]; then112echo "# Warning: file $TEST is missing!"113report_failure "$test_num $TEST_HDR_MSG"114else115if [ -x /usr/bin/stdbuf ]; then116stdbuf="/usr/bin/stdbuf --output=L "117fi118eval kselftest_cmd_args="\$${kselftest_cmd_args_ref:-}"119if [ -x "$TEST" ]; then120cmd="$stdbuf ./$BASENAME_TEST $kselftest_cmd_args"121elif [ -x "./ksft_runner.sh" ]; then122cmd="$stdbuf ./ksft_runner.sh ./$BASENAME_TEST"123else124echo "# Warning: file $TEST is not executable"125126if [ $(head -n 1 "$TEST" | cut -c -2) = "#!" ]127then128interpreter=$(head -n 1 "$TEST" | cut -c 3-)129cmd="$stdbuf $interpreter ./$BASENAME_TEST"130else131report_failure "$test_num $TEST_HDR_MSG"132return133fi134fi135cd `dirname $TEST` > /dev/null136((((( tap_timeout "$cmd" 2>&1; echo $? >&3) |137tap_prefix >&4) 3>&1) |138(read xs; exit $xs)) 4>>"$logfile" &&139echo "ok $test_num $TEST_HDR_MSG") ||140(rc=$?; \141if [ $rc -eq $skip_rc ]; then \142echo "ok $test_num $TEST_HDR_MSG # SKIP"143elif [ $rc -eq $timeout_rc ]; then \144echo "#"145report_failure "$test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds"146else147report_failure "$test_num $TEST_HDR_MSG # exit=$rc"148fi)149cd - >/dev/null150fi151}152153in_netns()154{155local name=$1156ip netns exec $name bash <<-EOF157BASE_DIR=$BASE_DIR158source $BASE_DIR/kselftest/runner.sh159logfile=$logfile160run_one $DIR $TEST $test_num161EOF162}163164run_in_netns()165{166local netns=$(mktemp -u ${BASENAME_TEST}-XXXXXX)167local tmplog="/tmp/$(mktemp -u ${BASENAME_TEST}-XXXXXX)"168ip netns add $netns169if [ $? -ne 0 ]; then170echo "# Warning: Create namespace failed for $BASENAME_TEST"171echo "not ok $test_num selftests: $DIR: $BASENAME_TEST # Create NS failed"172fi173ip -n $netns link set lo up174in_netns $netns &> $tmplog175ip netns del $netns &> /dev/null176cat $tmplog177rm -f $tmplog178}179180run_many()181{182echo "TAP version 13"183DIR="${PWD#${BASE_DIR}/}"184test_num=0185total=$(echo "$@" | wc -w)186echo "1..$total"187for TEST in "$@"; do188BASENAME_TEST=$(basename $TEST)189test_num=$(( test_num + 1 ))190if [ -n "$per_test_logging" ]; then191logfile="/tmp/$BASENAME_TEST"192cat /dev/null > "$logfile"193fi194if [ -n "$RUN_IN_NETNS" ]; then195run_in_netns &196else197run_one "$DIR" "$TEST" "$test_num"198fi199done200201wait202}203204205