xref: /openbmc/linux/tools/testing/selftests/kselftest/runner.sh (revision 5804c19b80bf625c6a9925317f845e497434d6d3)
142d46e57SKees Cook#!/bin/sh
242d46e57SKees Cook# SPDX-License-Identifier: GPL-2.0
342d46e57SKees Cook#
442d46e57SKees Cook# Runs a set of tests in a given subdirectory.
542d46e57SKees Cookexport skip_rc=4
6852c8cbfSKees Cookexport timeout_rc=124
742d46e57SKees Cookexport logfile=/dev/stdout
8bf660782SKees Cookexport per_test_logging=
942d46e57SKees Cook
10852c8cbfSKees Cook# Defaults for "settings" file fields:
11f6a01213SLuis Chamberlain# "timeout" how many seconds to let each test run before running
12f6a01213SLuis Chamberlain# over our soft timeout limit.
13852c8cbfSKees Cookexport kselftest_default_timeout=45
14852c8cbfSKees Cook
155c069b6dSKees Cook# There isn't a shell-agnostic way to find the path of a sourced file,
165c069b6dSKees Cook# so we must rely on BASE_DIR being set to find other tools.
175c069b6dSKees Cookif [ -z "$BASE_DIR" ]; then
185c069b6dSKees Cook	echo "Error: BASE_DIR must be set before sourcing." >&2
195c069b6dSKees Cook	exit 1
205c069b6dSKees Cookfi
215c069b6dSKees Cook
22e005ff01SCristian MarussiTR_CMD=$(command -v tr)
23e005ff01SCristian Marussi
245c069b6dSKees Cook# If Perl is unavailable, we must fall back to line-at-a-time prefixing
255c069b6dSKees Cook# with sed instead of unbuffered output.
265c069b6dSKees Cooktap_prefix()
275c069b6dSKees Cook{
285c069b6dSKees Cook	if [ ! -x /usr/bin/perl ]; then
295c069b6dSKees Cook		sed -e 's/^/# /'
305c069b6dSKees Cook	else
315c069b6dSKees Cook		"$BASE_DIR"/kselftest/prefix.pl
325c069b6dSKees Cook	fi
335c069b6dSKees Cook}
345c069b6dSKees Cook
35852c8cbfSKees Cooktap_timeout()
36852c8cbfSKees Cook{
37852c8cbfSKees Cook	# Make sure tests will time out if utility is available.
38852c8cbfSKees Cook	if [ -x /usr/bin/timeout ] ; then
39*9616cb34SBjörn Töpel		/usr/bin/timeout --foreground "$kselftest_timeout" \
40*9616cb34SBjörn Töpel			/usr/bin/timeout "$kselftest_timeout" $1
41852c8cbfSKees Cook	else
42303f8e2dSSeongJae Park		$1
43852c8cbfSKees Cook	fi
44852c8cbfSKees Cook}
45852c8cbfSKees Cook
4642d46e57SKees Cookrun_one()
4742d46e57SKees Cook{
48bf660782SKees Cook	DIR="$1"
49bf660782SKees Cook	TEST="$2"
50bf660782SKees Cook	NUM="$3"
5142d46e57SKees Cook
5242d46e57SKees Cook	BASENAME_TEST=$(basename $TEST)
5342d46e57SKees Cook
54852c8cbfSKees Cook	# Reset any "settings"-file variables.
55852c8cbfSKees Cook	export kselftest_timeout="$kselftest_default_timeout"
56e005ff01SCristian Marussi
57e005ff01SCristian Marussi	# Safe default if tr not available
58e005ff01SCristian Marussi	kselftest_cmd_args_ref="KSELFTEST_ARGS"
59e005ff01SCristian Marussi
60e005ff01SCristian Marussi	# Optional arguments for this command, possibly defined as an
61e005ff01SCristian Marussi	# environment variable built using the test executable in all
62e005ff01SCristian Marussi	# uppercase and sanitized substituting non acceptable shell
63e005ff01SCristian Marussi	# variable name characters with "_" as in:
64e005ff01SCristian Marussi	#
65e005ff01SCristian Marussi	# 	KSELFTEST_<UPPERCASE_SANITIZED_TESTNAME>_ARGS="<options>"
66e005ff01SCristian Marussi	#
67e005ff01SCristian Marussi	# e.g.
68e005ff01SCristian Marussi	#
69e005ff01SCristian Marussi	# 	rtctest --> KSELFTEST_RTCTEST_ARGS="/dev/rtc1"
70e005ff01SCristian Marussi	#
71e005ff01SCristian Marussi	# 	cpu-on-off-test.sh --> KSELFTEST_CPU_ON_OFF_TEST_SH_ARGS="-a -p 10"
72e005ff01SCristian Marussi	#
73e005ff01SCristian Marussi	if [ -n "$TR_CMD" ]; then
74e005ff01SCristian Marussi		BASENAME_SANITIZED=$(echo "$BASENAME_TEST" | \
75e005ff01SCristian Marussi					$TR_CMD -d "[:blank:][:cntrl:]" | \
76e005ff01SCristian Marussi					$TR_CMD -c "[:alnum:]_" "_" | \
77e005ff01SCristian Marussi					$TR_CMD [:lower:] [:upper:])
78e005ff01SCristian Marussi		kselftest_cmd_args_ref="KSELFTEST_${BASENAME_SANITIZED}_ARGS"
79e005ff01SCristian Marussi	fi
80e005ff01SCristian Marussi
81852c8cbfSKees Cook	# Load per-test-directory kselftest "settings" file.
82852c8cbfSKees Cook	settings="$BASE_DIR/$DIR/settings"
83852c8cbfSKees Cook	if [ -r "$settings" ] ; then
84852c8cbfSKees Cook		while read line ; do
854505e215SKees Cook			# Skip comments.
864505e215SKees Cook			if echo "$line" | grep -q '^#'; then
874505e215SKees Cook				continue
884505e215SKees Cook			fi
89852c8cbfSKees Cook			field=$(echo "$line" | cut -d= -f1)
90852c8cbfSKees Cook			value=$(echo "$line" | cut -d= -f2-)
91852c8cbfSKees Cook			eval "kselftest_$field"="$value"
92852c8cbfSKees Cook		done < "$settings"
93852c8cbfSKees Cook	fi
94852c8cbfSKees Cook
95f6a01213SLuis Chamberlain	# Command line timeout overrides the settings file
96f6a01213SLuis Chamberlain	if [ -n "$kselftest_override_timeout" ]; then
97f6a01213SLuis Chamberlain		kselftest_timeout="$kselftest_override_timeout"
98f6a01213SLuis Chamberlain		echo "# overriding timeout to $kselftest_timeout" >> "$logfile"
99f6a01213SLuis Chamberlain	else
100f6a01213SLuis Chamberlain		echo "# timeout set to $kselftest_timeout" >> "$logfile"
101f6a01213SLuis Chamberlain	fi
102f6a01213SLuis Chamberlain
103bf660782SKees Cook	TEST_HDR_MSG="selftests: $DIR: $BASENAME_TEST"
1045c069b6dSKees Cook	echo "# $TEST_HDR_MSG"
105fd63b2eaSKees Cook	if [ ! -e "$TEST" ]; then
106303f8e2dSSeongJae Park		echo "# Warning: file $TEST is missing!"
107b0df366bSKees Cook		echo "not ok $test_num $TEST_HDR_MSG"
10842d46e57SKees Cook	else
10958e2847aSRyan Roberts		if [ -x /usr/bin/stdbuf ]; then
11058e2847aSRyan Roberts			stdbuf="/usr/bin/stdbuf --output=L "
11158e2847aSRyan Roberts		fi
112e005ff01SCristian Marussi		eval kselftest_cmd_args="\$${kselftest_cmd_args_ref:-}"
11358e2847aSRyan Roberts		cmd="$stdbuf ./$BASENAME_TEST $kselftest_cmd_args"
114303f8e2dSSeongJae Park		if [ ! -x "$TEST" ]; then
115303f8e2dSSeongJae Park			echo "# Warning: file $TEST is not executable"
116303f8e2dSSeongJae Park
117303f8e2dSSeongJae Park			if [ $(head -n 1 "$TEST" | cut -c -2) = "#!" ]
118303f8e2dSSeongJae Park			then
119303f8e2dSSeongJae Park				interpreter=$(head -n 1 "$TEST" | cut -c 3-)
12058e2847aSRyan Roberts				cmd="$stdbuf $interpreter ./$BASENAME_TEST"
121303f8e2dSSeongJae Park			else
122303f8e2dSSeongJae Park				echo "not ok $test_num $TEST_HDR_MSG"
123303f8e2dSSeongJae Park				return
124303f8e2dSSeongJae Park			fi
125303f8e2dSSeongJae Park		fi
12642d46e57SKees Cook		cd `dirname $TEST` > /dev/null
127303f8e2dSSeongJae Park		((((( tap_timeout "$cmd" 2>&1; echo $? >&3) |
1285c069b6dSKees Cook			tap_prefix >&4) 3>&1) |
1295c069b6dSKees Cook			(read xs; exit $xs)) 4>>"$logfile" &&
130b0df366bSKees Cook		echo "ok $test_num $TEST_HDR_MSG") ||
131852c8cbfSKees Cook		(rc=$?;	\
132852c8cbfSKees Cook		if [ $rc -eq $skip_rc ]; then	\
133b85d387cSPaolo Bonzini			echo "ok $test_num $TEST_HDR_MSG # SKIP"
134852c8cbfSKees Cook		elif [ $rc -eq $timeout_rc ]; then \
135d187801dSSeongJae Park			echo "#"
1364505e215SKees Cook			echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds"
13742d46e57SKees Cook		else
138852c8cbfSKees Cook			echo "not ok $test_num $TEST_HDR_MSG # exit=$rc"
13942d46e57SKees Cook		fi)
14042d46e57SKees Cook		cd - >/dev/null
14142d46e57SKees Cook	fi
14242d46e57SKees Cook}
143bf660782SKees Cook
144bf660782SKees Cookrun_many()
145bf660782SKees Cook{
146bf660782SKees Cook	echo "TAP version 13"
147ac87813dSMatthieu Baerts	DIR="${PWD#${BASE_DIR}/}"
148bf660782SKees Cook	test_num=0
149b0df366bSKees Cook	total=$(echo "$@" | wc -w)
150b0df366bSKees Cook	echo "1..$total"
151bf660782SKees Cook	for TEST in "$@"; do
152bf660782SKees Cook		BASENAME_TEST=$(basename $TEST)
153bf660782SKees Cook		test_num=$(( test_num + 1 ))
154bf660782SKees Cook		if [ -n "$per_test_logging" ]; then
155bf660782SKees Cook			logfile="/tmp/$BASENAME_TEST"
156bf660782SKees Cook			cat /dev/null > "$logfile"
157bf660782SKees Cook		fi
158bf660782SKees Cook		run_one "$DIR" "$TEST" "$test_num"
159bf660782SKees Cook	done
160bf660782SKees Cook}
161