ASoc: Another series to convert to struct
[linux-block.git] / tools / testing / selftests / kselftest / runner.sh
1 #!/bin/sh
2 # SPDX-License-Identifier: GPL-2.0
3 #
4 # Runs a set of tests in a given subdirectory.
5 export skip_rc=4
6 export timeout_rc=124
7 export logfile=/dev/stdout
8 export 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.
13 export 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.
17 if [ -z "$BASE_DIR" ]; then
18         echo "Error: BASE_DIR must be set before sourcing." >&2
19         exit 1
20 fi
21
22 TR_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.
26 tap_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
35 tap_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" $1
40         else
41                 $1
42         fi
43 }
44
45 run_one()
46 {
47         DIR="$1"
48         TEST="$2"
49         NUM="$3"
50
51         BASENAME_TEST=$(basename $TEST)
52
53         # Reset any "settings"-file variables.
54         export kselftest_timeout="$kselftest_default_timeout"
55
56         # Safe default if tr not available
57         kselftest_cmd_args_ref="KSELFTEST_ARGS"
58
59         # Optional arguments for this command, possibly defined as an
60         # environment variable built using the test executable in all
61         # uppercase and sanitized substituting non acceptable shell
62         # variable name characters with "_" as in:
63         #
64         #       KSELFTEST_<UPPERCASE_SANITIZED_TESTNAME>_ARGS="<options>"
65         #
66         # e.g.
67         #
68         #       rtctest --> KSELFTEST_RTCTEST_ARGS="/dev/rtc1"
69         #
70         #       cpu-on-off-test.sh --> KSELFTEST_CPU_ON_OFF_TEST_SH_ARGS="-a -p 10"
71         #
72         if [ -n "$TR_CMD" ]; then
73                 BASENAME_SANITIZED=$(echo "$BASENAME_TEST" | \
74                                         $TR_CMD -d "[:blank:][:cntrl:]" | \
75                                         $TR_CMD -c "[:alnum:]_" "_" | \
76                                         $TR_CMD [:lower:] [:upper:])
77                 kselftest_cmd_args_ref="KSELFTEST_${BASENAME_SANITIZED}_ARGS"
78         fi
79
80         # Load per-test-directory kselftest "settings" file.
81         settings="$BASE_DIR/$DIR/settings"
82         if [ -r "$settings" ] ; then
83                 while read line ; do
84                         # Skip comments.
85                         if echo "$line" | grep -q '^#'; then
86                                 continue
87                         fi
88                         field=$(echo "$line" | cut -d= -f1)
89                         value=$(echo "$line" | cut -d= -f2-)
90                         eval "kselftest_$field"="$value"
91                 done < "$settings"
92         fi
93
94         # Command line timeout overrides the settings file
95         if [ -n "$kselftest_override_timeout" ]; then
96                 kselftest_timeout="$kselftest_override_timeout"
97                 echo "# overriding timeout to $kselftest_timeout" >> "$logfile"
98         else
99                 echo "# timeout set to $kselftest_timeout" >> "$logfile"
100         fi
101
102         TEST_HDR_MSG="selftests: $DIR: $BASENAME_TEST"
103         echo "# $TEST_HDR_MSG"
104         if [ ! -e "$TEST" ]; then
105                 echo "# Warning: file $TEST is missing!"
106                 echo "not ok $test_num $TEST_HDR_MSG"
107         else
108                 if [ -x /usr/bin/stdbuf ]; then
109                         stdbuf="/usr/bin/stdbuf --output=L "
110                 fi
111                 eval kselftest_cmd_args="\$${kselftest_cmd_args_ref:-}"
112                 cmd="$stdbuf ./$BASENAME_TEST $kselftest_cmd_args"
113                 if [ ! -x "$TEST" ]; then
114                         echo "# Warning: file $TEST is not executable"
115
116                         if [ $(head -n 1 "$TEST" | cut -c -2) = "#!" ]
117                         then
118                                 interpreter=$(head -n 1 "$TEST" | cut -c 3-)
119                                 cmd="$stdbuf $interpreter ./$BASENAME_TEST"
120                         else
121                                 echo "not ok $test_num $TEST_HDR_MSG"
122                                 return
123                         fi
124                 fi
125                 cd `dirname $TEST` > /dev/null
126                 ((((( tap_timeout "$cmd" 2>&1; echo $? >&3) |
127                         tap_prefix >&4) 3>&1) |
128                         (read xs; exit $xs)) 4>>"$logfile" &&
129                 echo "ok $test_num $TEST_HDR_MSG") ||
130                 (rc=$?; \
131                 if [ $rc -eq $skip_rc ]; then   \
132                         echo "ok $test_num $TEST_HDR_MSG # SKIP"
133                 elif [ $rc -eq $timeout_rc ]; then \
134                         echo "#"
135                         echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds"
136                 else
137                         echo "not ok $test_num $TEST_HDR_MSG # exit=$rc"
138                 fi)
139                 cd - >/dev/null
140         fi
141 }
142
143 run_many()
144 {
145         echo "TAP version 13"
146         DIR="${PWD#${BASE_DIR}/}"
147         test_num=0
148         total=$(echo "$@" | wc -w)
149         echo "1..$total"
150         for TEST in "$@"; do
151                 BASENAME_TEST=$(basename $TEST)
152                 test_num=$(( test_num + 1 ))
153                 if [ -n "$per_test_logging" ]; then
154                         logfile="/tmp/$BASENAME_TEST"
155                         cat /dev/null > "$logfile"
156                 fi
157                 run_one "$DIR" "$TEST" "$test_num"
158         done
159 }