Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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 running
12# over our soft timeout limit.
13export kselftest_default_timeout=45
14
15# 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" ]; then
18 echo "Error: BASE_DIR must be set before sourcing." >&2
19 exit 1
20fi
21
22TR_CMD=$(command -v tr)
23
24# If Perl is unavailable, we must fall back to line-at-a-time prefixing
25# with sed instead of unbuffered output.
26tap_prefix()
27{
28 if [ ! -x /usr/bin/perl ]; then
29 sed -e 's/^/# /'
30 else
31 "$BASE_DIR"/kselftest/prefix.pl
32 fi
33}
34
35tap_timeout()
36{
37 # Make sure tests will time out if utility is available.
38 if [ -x /usr/bin/timeout ] ; then
39 /usr/bin/timeout --foreground "$kselftest_timeout" \
40 /usr/bin/timeout "$kselftest_timeout" $1
41 else
42 $1
43 fi
44}
45
46run_one()
47{
48 DIR="$1"
49 TEST="$2"
50 NUM="$3"
51
52 BASENAME_TEST=$(basename $TEST)
53
54 # Reset any "settings"-file variables.
55 export kselftest_timeout="$kselftest_default_timeout"
56
57 # Safe default if tr not available
58 kselftest_cmd_args_ref="KSELFTEST_ARGS"
59
60 # Optional arguments for this command, possibly defined as an
61 # environment variable built using the test executable in all
62 # uppercase and sanitized substituting non acceptable shell
63 # 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 #
73 if [ -n "$TR_CMD" ]; then
74 BASENAME_SANITIZED=$(echo "$BASENAME_TEST" | \
75 $TR_CMD -d "[:blank:][:cntrl:]" | \
76 $TR_CMD -c "[:alnum:]_" "_" | \
77 $TR_CMD [:lower:] [:upper:])
78 kselftest_cmd_args_ref="KSELFTEST_${BASENAME_SANITIZED}_ARGS"
79 fi
80
81 # Load per-test-directory kselftest "settings" file.
82 settings="$BASE_DIR/$DIR/settings"
83 if [ -r "$settings" ] ; then
84 while read line ; do
85 # Skip comments.
86 if echo "$line" | grep -q '^#'; then
87 continue
88 fi
89 field=$(echo "$line" | cut -d= -f1)
90 value=$(echo "$line" | cut -d= -f2-)
91 eval "kselftest_$field"="$value"
92 done < "$settings"
93 fi
94
95 # Command line timeout overrides the settings file
96 if [ -n "$kselftest_override_timeout" ]; then
97 kselftest_timeout="$kselftest_override_timeout"
98 echo "# overriding timeout to $kselftest_timeout" >> "$logfile"
99 else
100 echo "# timeout set to $kselftest_timeout" >> "$logfile"
101 fi
102
103 TEST_HDR_MSG="selftests: $DIR: $BASENAME_TEST"
104 echo "# $TEST_HDR_MSG"
105 if [ ! -e "$TEST" ]; then
106 echo "# Warning: file $TEST is missing!"
107 echo "not ok $test_num $TEST_HDR_MSG"
108 else
109 if [ -x /usr/bin/stdbuf ]; then
110 stdbuf="/usr/bin/stdbuf --output=L "
111 fi
112 eval kselftest_cmd_args="\$${kselftest_cmd_args_ref:-}"
113 cmd="$stdbuf ./$BASENAME_TEST $kselftest_cmd_args"
114 if [ ! -x "$TEST" ]; then
115 echo "# Warning: file $TEST is not executable"
116
117 if [ $(head -n 1 "$TEST" | cut -c -2) = "#!" ]
118 then
119 interpreter=$(head -n 1 "$TEST" | cut -c 3-)
120 cmd="$stdbuf $interpreter ./$BASENAME_TEST"
121 else
122 echo "not ok $test_num $TEST_HDR_MSG"
123 return
124 fi
125 fi
126 cd `dirname $TEST` > /dev/null
127 ((((( tap_timeout "$cmd" 2>&1; echo $? >&3) |
128 tap_prefix >&4) 3>&1) |
129 (read xs; exit $xs)) 4>>"$logfile" &&
130 echo "ok $test_num $TEST_HDR_MSG") ||
131 (rc=$?; \
132 if [ $rc -eq $skip_rc ]; then \
133 echo "ok $test_num $TEST_HDR_MSG # SKIP"
134 elif [ $rc -eq $timeout_rc ]; then \
135 echo "#"
136 echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds"
137 else
138 echo "not ok $test_num $TEST_HDR_MSG # exit=$rc"
139 fi)
140 cd - >/dev/null
141 fi
142}
143
144run_many()
145{
146 echo "TAP version 13"
147 DIR="${PWD#${BASE_DIR}/}"
148 test_num=0
149 total=$(echo "$@" | wc -w)
150 echo "1..$total"
151 for TEST in "$@"; do
152 BASENAME_TEST=$(basename $TEST)
153 test_num=$(( test_num + 1 ))
154 if [ -n "$per_test_logging" ]; then
155 logfile="/tmp/$BASENAME_TEST"
156 cat /dev/null > "$logfile"
157 fi
158 run_one "$DIR" "$TEST" "$test_num"
159 done
160}