Path: blob/master/tools/testing/selftests/kselftest/runner.sh
26285 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}4546run_one()47{48DIR="$1"49TEST="$2"50local test_num="$3"5152BASENAME_TEST=$(basename $TEST)5354# Reset any "settings"-file variables.55export kselftest_timeout="$kselftest_default_timeout"5657# Safe default if tr not available58kselftest_cmd_args_ref="KSELFTEST_ARGS"5960# Optional arguments for this command, possibly defined as an61# environment variable built using the test executable in all62# uppercase and sanitized substituting non acceptable shell63# variable name characters with "_" as in:64#65# KSELFTEST_<UPPERCASE_SANITIZED_TESTNAME>_ARGS="<options>"66#67# e.g.68#69# rtctest --> KSELFTEST_RTCTEST_ARGS="/dev/rtc1"70#71# cpu-on-off-test.sh --> KSELFTEST_CPU_ON_OFF_TEST_SH_ARGS="-a -p 10"72#73if [ -n "$TR_CMD" ]; then74BASENAME_SANITIZED=$(echo "$BASENAME_TEST" | \75$TR_CMD -d "[:blank:][:cntrl:]" | \76$TR_CMD -c "[:alnum:]_" "_" | \77$TR_CMD [:lower:] [:upper:])78kselftest_cmd_args_ref="KSELFTEST_${BASENAME_SANITIZED}_ARGS"79fi8081# Load per-test-directory kselftest "settings" file.82settings="$BASE_DIR/$DIR/settings"83if [ -r "$settings" ] ; then84while read line ; do85# Skip comments.86if echo "$line" | grep -q '^#'; then87continue88fi89field=$(echo "$line" | cut -d= -f1)90value=$(echo "$line" | cut -d= -f2-)91eval "kselftest_$field"="$value"92done < "$settings"93fi9495# Command line timeout overrides the settings file96if [ -n "$kselftest_override_timeout" ]; then97kselftest_timeout="$kselftest_override_timeout"98echo "# overriding timeout to $kselftest_timeout" >> "$logfile"99else100echo "# timeout set to $kselftest_timeout" >> "$logfile"101fi102103TEST_HDR_MSG="selftests: $DIR: $BASENAME_TEST"104echo "# $TEST_HDR_MSG"105if [ ! -e "$TEST" ]; then106echo "# Warning: file $TEST is missing!"107echo "not ok $test_num $TEST_HDR_MSG"108else109if [ -x /usr/bin/stdbuf ]; then110stdbuf="/usr/bin/stdbuf --output=L "111fi112eval kselftest_cmd_args="\$${kselftest_cmd_args_ref:-}"113if [ -x "$TEST" ]; then114cmd="$stdbuf ./$BASENAME_TEST $kselftest_cmd_args"115elif [ -x "./ksft_runner.sh" ]; then116cmd="$stdbuf ./ksft_runner.sh ./$BASENAME_TEST"117else118echo "# Warning: file $TEST is not executable"119120if [ $(head -n 1 "$TEST" | cut -c -2) = "#!" ]121then122interpreter=$(head -n 1 "$TEST" | cut -c 3-)123cmd="$stdbuf $interpreter ./$BASENAME_TEST"124else125echo "not ok $test_num $TEST_HDR_MSG"126return127fi128fi129cd `dirname $TEST` > /dev/null130((((( tap_timeout "$cmd" 2>&1; echo $? >&3) |131tap_prefix >&4) 3>&1) |132(read xs; exit $xs)) 4>>"$logfile" &&133echo "ok $test_num $TEST_HDR_MSG") ||134(rc=$?; \135if [ $rc -eq $skip_rc ]; then \136echo "ok $test_num $TEST_HDR_MSG # SKIP"137elif [ $rc -eq $timeout_rc ]; then \138echo "#"139echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds"140else141echo "not ok $test_num $TEST_HDR_MSG # exit=$rc"142fi)143cd - >/dev/null144fi145}146147in_netns()148{149local name=$1150ip netns exec $name bash <<-EOF151BASE_DIR=$BASE_DIR152source $BASE_DIR/kselftest/runner.sh153logfile=$logfile154run_one $DIR $TEST $test_num155EOF156}157158run_in_netns()159{160local netns=$(mktemp -u ${BASENAME_TEST}-XXXXXX)161local tmplog="/tmp/$(mktemp -u ${BASENAME_TEST}-XXXXXX)"162ip netns add $netns163if [ $? -ne 0 ]; then164echo "# Warning: Create namespace failed for $BASENAME_TEST"165echo "not ok $test_num selftests: $DIR: $BASENAME_TEST # Create NS failed"166fi167ip -n $netns link set lo up168in_netns $netns &> $tmplog169ip netns del $netns &> /dev/null170cat $tmplog171rm -f $tmplog172}173174run_many()175{176echo "TAP version 13"177DIR="${PWD#${BASE_DIR}/}"178test_num=0179total=$(echo "$@" | wc -w)180echo "1..$total"181for TEST in "$@"; do182BASENAME_TEST=$(basename $TEST)183test_num=$(( test_num + 1 ))184if [ -n "$per_test_logging" ]; then185logfile="/tmp/$BASENAME_TEST"186cat /dev/null > "$logfile"187fi188if [ -n "$RUN_IN_NETNS" ]; then189run_in_netns &190else191run_one "$DIR" "$TEST" "$test_num"192fi193done194195wait196}197198199