xref: /OK3568_Linux_fs/kernel/tools/testing/selftests/kselftest/runner.sh (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun#!/bin/sh
2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0
3*4882a593Smuzhiyun#
4*4882a593Smuzhiyun# Runs a set of tests in a given subdirectory.
5*4882a593Smuzhiyunexport skip_rc=4
6*4882a593Smuzhiyunexport timeout_rc=124
7*4882a593Smuzhiyunexport logfile=/dev/stdout
8*4882a593Smuzhiyunexport per_test_logging=
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun# Defaults for "settings" file fields:
11*4882a593Smuzhiyun# "timeout" how many seconds to let each test run before failing.
12*4882a593Smuzhiyunexport kselftest_default_timeout=45
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun# There isn't a shell-agnostic way to find the path of a sourced file,
15*4882a593Smuzhiyun# so we must rely on BASE_DIR being set to find other tools.
16*4882a593Smuzhiyunif [ -z "$BASE_DIR" ]; then
17*4882a593Smuzhiyun	echo "Error: BASE_DIR must be set before sourcing." >&2
18*4882a593Smuzhiyun	exit 1
19*4882a593Smuzhiyunfi
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun# If Perl is unavailable, we must fall back to line-at-a-time prefixing
22*4882a593Smuzhiyun# with sed instead of unbuffered output.
23*4882a593Smuzhiyuntap_prefix()
24*4882a593Smuzhiyun{
25*4882a593Smuzhiyun	if [ ! -x /usr/bin/perl ]; then
26*4882a593Smuzhiyun		sed -e 's/^/# /'
27*4882a593Smuzhiyun	else
28*4882a593Smuzhiyun		"$BASE_DIR"/kselftest/prefix.pl
29*4882a593Smuzhiyun	fi
30*4882a593Smuzhiyun}
31*4882a593Smuzhiyun
32*4882a593Smuzhiyuntap_timeout()
33*4882a593Smuzhiyun{
34*4882a593Smuzhiyun	# Make sure tests will time out if utility is available.
35*4882a593Smuzhiyun	if [ -x /usr/bin/timeout ] ; then
36*4882a593Smuzhiyun		/usr/bin/timeout --foreground "$kselftest_timeout" "$1"
37*4882a593Smuzhiyun	else
38*4882a593Smuzhiyun		"$1"
39*4882a593Smuzhiyun	fi
40*4882a593Smuzhiyun}
41*4882a593Smuzhiyun
42*4882a593Smuzhiyunrun_one()
43*4882a593Smuzhiyun{
44*4882a593Smuzhiyun	DIR="$1"
45*4882a593Smuzhiyun	TEST="$2"
46*4882a593Smuzhiyun	NUM="$3"
47*4882a593Smuzhiyun
48*4882a593Smuzhiyun	BASENAME_TEST=$(basename $TEST)
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun	# Reset any "settings"-file variables.
51*4882a593Smuzhiyun	export kselftest_timeout="$kselftest_default_timeout"
52*4882a593Smuzhiyun	# Load per-test-directory kselftest "settings" file.
53*4882a593Smuzhiyun	settings="$BASE_DIR/$DIR/settings"
54*4882a593Smuzhiyun	if [ -r "$settings" ] ; then
55*4882a593Smuzhiyun		while read line ; do
56*4882a593Smuzhiyun			# Skip comments.
57*4882a593Smuzhiyun			if echo "$line" | grep -q '^#'; then
58*4882a593Smuzhiyun				continue
59*4882a593Smuzhiyun			fi
60*4882a593Smuzhiyun			field=$(echo "$line" | cut -d= -f1)
61*4882a593Smuzhiyun			value=$(echo "$line" | cut -d= -f2-)
62*4882a593Smuzhiyun			eval "kselftest_$field"="$value"
63*4882a593Smuzhiyun		done < "$settings"
64*4882a593Smuzhiyun	fi
65*4882a593Smuzhiyun
66*4882a593Smuzhiyun	TEST_HDR_MSG="selftests: $DIR: $BASENAME_TEST"
67*4882a593Smuzhiyun	echo "# $TEST_HDR_MSG"
68*4882a593Smuzhiyun	if [ ! -x "$TEST" ]; then
69*4882a593Smuzhiyun		echo -n "# Warning: file $TEST is "
70*4882a593Smuzhiyun		if [ ! -e "$TEST" ]; then
71*4882a593Smuzhiyun			echo "missing!"
72*4882a593Smuzhiyun		else
73*4882a593Smuzhiyun			echo "not executable, correct this."
74*4882a593Smuzhiyun		fi
75*4882a593Smuzhiyun		echo "not ok $test_num $TEST_HDR_MSG"
76*4882a593Smuzhiyun	else
77*4882a593Smuzhiyun		cd `dirname $TEST` > /dev/null
78*4882a593Smuzhiyun		((((( tap_timeout ./$BASENAME_TEST 2>&1; echo $? >&3) |
79*4882a593Smuzhiyun			tap_prefix >&4) 3>&1) |
80*4882a593Smuzhiyun			(read xs; exit $xs)) 4>>"$logfile" &&
81*4882a593Smuzhiyun		echo "ok $test_num $TEST_HDR_MSG") ||
82*4882a593Smuzhiyun		(rc=$?;	\
83*4882a593Smuzhiyun		if [ $rc -eq $skip_rc ]; then	\
84*4882a593Smuzhiyun			echo "ok $test_num $TEST_HDR_MSG # SKIP"
85*4882a593Smuzhiyun		elif [ $rc -eq $timeout_rc ]; then \
86*4882a593Smuzhiyun			echo "#"
87*4882a593Smuzhiyun			echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds"
88*4882a593Smuzhiyun		else
89*4882a593Smuzhiyun			echo "not ok $test_num $TEST_HDR_MSG # exit=$rc"
90*4882a593Smuzhiyun		fi)
91*4882a593Smuzhiyun		cd - >/dev/null
92*4882a593Smuzhiyun	fi
93*4882a593Smuzhiyun}
94*4882a593Smuzhiyun
95*4882a593Smuzhiyunrun_many()
96*4882a593Smuzhiyun{
97*4882a593Smuzhiyun	echo "TAP version 13"
98*4882a593Smuzhiyun	DIR="${PWD#${BASE_DIR}/}"
99*4882a593Smuzhiyun	test_num=0
100*4882a593Smuzhiyun	total=$(echo "$@" | wc -w)
101*4882a593Smuzhiyun	echo "1..$total"
102*4882a593Smuzhiyun	for TEST in "$@"; do
103*4882a593Smuzhiyun		BASENAME_TEST=$(basename $TEST)
104*4882a593Smuzhiyun		test_num=$(( test_num + 1 ))
105*4882a593Smuzhiyun		if [ -n "$per_test_logging" ]; then
106*4882a593Smuzhiyun			logfile="/tmp/$BASENAME_TEST"
107*4882a593Smuzhiyun			cat /dev/null > "$logfile"
108*4882a593Smuzhiyun		fi
109*4882a593Smuzhiyun		run_one "$DIR" "$TEST" "$test_num"
110*4882a593Smuzhiyun	done
111*4882a593Smuzhiyun}
112