1#!/bin/sh 2# SPDX-License-Identifier: GPL-2.0 3# 4# Runs a set of tests in a given subdirectory. 5export skip_rc=4 6export timeout_rc=124 7export logfile=/dev/stdout 8export per_test_logging= 9 10# Defaults for "settings" file fields: 11# "timeout" how many seconds to let each test run before failing. 12export kselftest_default_timeout=45 13 14# There isn't a shell-agnostic way to find the path of a sourced file, 15# so we must rely on BASE_DIR being set to find other tools. 16if [ -z "$BASE_DIR" ]; then 17 echo "Error: BASE_DIR must be set before sourcing." >&2 18 exit 1 19fi 20 21TR_CMD=$(command -v tr) 22 23# If Perl is unavailable, we must fall back to line-at-a-time prefixing 24# with sed instead of unbuffered output. 25tap_prefix() 26{ 27 if [ ! -x /usr/bin/perl ]; then 28 sed -e 's/^/# /' 29 else 30 "$BASE_DIR"/kselftest/prefix.pl 31 fi 32} 33 34tap_timeout() 35{ 36 # Make sure tests will time out if utility is available. 37 if [ -x /usr/bin/timeout ] ; then 38 /usr/bin/timeout --foreground "$kselftest_timeout" $1 39 else 40 $1 41 fi 42} 43 44run_one() 45{ 46 DIR="$1" 47 TEST="$2" 48 NUM="$3" 49 50 BASENAME_TEST=$(basename $TEST) 51 52 # Reset any "settings"-file variables. 53 export kselftest_timeout="$kselftest_default_timeout" 54 55 # Safe default if tr not available 56 kselftest_cmd_args_ref="KSELFTEST_ARGS" 57 58 # Optional arguments for this command, possibly defined as an 59 # environment variable built using the test executable in all 60 # uppercase and sanitized substituting non acceptable shell 61 # variable name characters with "_" as in: 62 # 63 # KSELFTEST_<UPPERCASE_SANITIZED_TESTNAME>_ARGS="<options>" 64 # 65 # e.g. 66 # 67 # rtctest --> KSELFTEST_RTCTEST_ARGS="/dev/rtc1" 68 # 69 # cpu-on-off-test.sh --> KSELFTEST_CPU_ON_OFF_TEST_SH_ARGS="-a -p 10" 70 # 71 if [ -n "$TR_CMD" ]; then 72 BASENAME_SANITIZED=$(echo "$BASENAME_TEST" | \ 73 $TR_CMD -d "[:blank:][:cntrl:]" | \ 74 $TR_CMD -c "[:alnum:]_" "_" | \ 75 $TR_CMD [:lower:] [:upper:]) 76 kselftest_cmd_args_ref="KSELFTEST_${BASENAME_SANITIZED}_ARGS" 77 fi 78 79 # Load per-test-directory kselftest "settings" file. 80 settings="$BASE_DIR/$DIR/settings" 81 if [ -r "$settings" ] ; then 82 while read line ; do 83 # Skip comments. 84 if echo "$line" | grep -q '^#'; then 85 continue 86 fi 87 field=$(echo "$line" | cut -d= -f1) 88 value=$(echo "$line" | cut -d= -f2-) 89 eval "kselftest_$field"="$value" 90 done < "$settings" 91 fi 92 93 TEST_HDR_MSG="selftests: $DIR: $BASENAME_TEST" 94 echo "# $TEST_HDR_MSG" 95 if [ ! -e "$TEST" ]; then 96 echo "# Warning: file $TEST is missing!" 97 echo "not ok $test_num $TEST_HDR_MSG" 98 else 99 eval kselftest_cmd_args="\$${kselftest_cmd_args_ref:-}" 100 cmd="./$BASENAME_TEST $kselftest_cmd_args" 101 if [ ! -x "$TEST" ]; then 102 echo "# Warning: file $TEST is not executable" 103 104 if [ $(head -n 1 "$TEST" | cut -c -2) = "#!" ] 105 then 106 interpreter=$(head -n 1 "$TEST" | cut -c 3-) 107 cmd="$interpreter ./$BASENAME_TEST" 108 else 109 echo "not ok $test_num $TEST_HDR_MSG" 110 return 111 fi 112 fi 113 cd `dirname $TEST` > /dev/null 114 ((((( tap_timeout "$cmd" 2>&1; echo $? >&3) | 115 tap_prefix >&4) 3>&1) | 116 (read xs; exit $xs)) 4>>"$logfile" && 117 echo "ok $test_num $TEST_HDR_MSG") || 118 (rc=$?; \ 119 if [ $rc -eq $skip_rc ]; then \ 120 echo "ok $test_num $TEST_HDR_MSG # SKIP" 121 elif [ $rc -eq $timeout_rc ]; then \ 122 echo "#" 123 echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds" 124 else 125 echo "not ok $test_num $TEST_HDR_MSG # exit=$rc" 126 fi) 127 cd - >/dev/null 128 fi 129} 130 131run_many() 132{ 133 echo "TAP version 13" 134 DIR="${PWD#${BASE_DIR}/}" 135 test_num=0 136 total=$(echo "$@" | wc -w) 137 echo "1..$total" 138 for TEST in "$@"; do 139 BASENAME_TEST=$(basename $TEST) 140 test_num=$(( test_num + 1 )) 141 if [ -n "$per_test_logging" ]; then 142 logfile="/tmp/$BASENAME_TEST" 143 cat /dev/null > "$logfile" 144 fi 145 run_one "$DIR" "$TEST" "$test_num" 146 done 147} 148