Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests/run_kselftest.sh: exit with error if tests fail

Parsing KTAP is quite an inconvenience, but most of the time the thing
you really want to know is "did anything fail"?

Let's give the user the his information without them needing
to parse anything.

Because of the use of subshells and namespaces, this needs to be
communicated via a file. Just write arbitrary data into the file and
treat non-empty content as a signal that something failed.

In case any user depends on the current behaviour, such as running this
from a script with `set -e` and parsing the result for failures
afterwards, add a flag they can set to get the old behaviour, namely
--no-error-on-fail.

Link: https://lore.kernel.org/r/20251111-b4-ksft-error-on-fail-v3-1-0951a51135f6@google.com
Signed-off-by: Brendan Jackman <jackmanb@google.com>
Signed-off-by: Shuah Khan <skhan@linuxfoundation.org>

authored by

Brendan Jackman and committed by
Shuah Khan
d9e6269e 26347f84

+24 -4
+10 -4
tools/testing/selftests/kselftest/runner.sh
··· 44 44 fi 45 45 } 46 46 47 + report_failure() 48 + { 49 + echo "not ok $*" 50 + echo "$*" >> "$kselftest_failures_file" 51 + } 52 + 47 53 run_one() 48 54 { 49 55 DIR="$1" ··· 111 105 echo "# $TEST_HDR_MSG" 112 106 if [ ! -e "$TEST" ]; then 113 107 echo "# Warning: file $TEST is missing!" 114 - echo "not ok $test_num $TEST_HDR_MSG" 108 + report_failure "$test_num $TEST_HDR_MSG" 115 109 else 116 110 if [ -x /usr/bin/stdbuf ]; then 117 111 stdbuf="/usr/bin/stdbuf --output=L " ··· 129 123 interpreter=$(head -n 1 "$TEST" | cut -c 3-) 130 124 cmd="$stdbuf $interpreter ./$BASENAME_TEST" 131 125 else 132 - echo "not ok $test_num $TEST_HDR_MSG" 126 + report_failure "$test_num $TEST_HDR_MSG" 133 127 return 134 128 fi 135 129 fi ··· 143 137 echo "ok $test_num $TEST_HDR_MSG # SKIP" 144 138 elif [ $rc -eq $timeout_rc ]; then \ 145 139 echo "#" 146 - echo "not ok $test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds" 140 + report_failure "$test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds" 147 141 else 148 - echo "not ok $test_num $TEST_HDR_MSG # exit=$rc" 142 + report_failure "$test_num $TEST_HDR_MSG # exit=$rc" 149 143 fi) 150 144 cd - >/dev/null 151 145 fi
+14
tools/testing/selftests/run_kselftest.sh
··· 33 33 -c | --collection COLLECTION Run all tests from COLLECTION 34 34 -l | --list List the available collection:test entries 35 35 -d | --dry-run Don't actually run any tests 36 + -f | --no-error-on-fail Don't exit with an error just because tests failed 36 37 -n | --netns Run each test in namespace 37 38 -h | --help Show this usage info 38 39 -o | --override-timeout Number of seconds after which we timeout ··· 45 44 TESTS="" 46 45 dryrun="" 47 46 kselftest_override_timeout="" 47 + ERROR_ON_FAIL=true 48 48 while true; do 49 49 case "$1" in 50 50 -s | --summary) ··· 66 64 exit 0 ;; 67 65 -d | --dry-run) 68 66 dryrun="echo" 67 + shift ;; 68 + -f | --no-error-on-fail) 69 + ERROR_ON_FAIL=false 69 70 shift ;; 70 71 -n | --netns) 71 72 RUN_IN_NETNS=1 ··· 110 105 available="$(echo "$valid" | sed -e 's/ /\n/g')" 111 106 fi 112 107 108 + kselftest_failures_file="$(mktemp --tmpdir kselftest-failures-XXXXXX)" 109 + export kselftest_failures_file 110 + 113 111 collections=$(echo "$available" | cut -d: -f1 | sort | uniq) 114 112 for collection in $collections ; do 115 113 [ -w /dev/kmsg ] && echo "kselftest: Running tests in $collection" >> /dev/kmsg 116 114 tests=$(echo "$available" | grep "^$collection:" | cut -d: -f2) 117 115 ($dryrun cd "$collection" && $dryrun run_many $tests) 118 116 done 117 + 118 + failures="$(cat "$kselftest_failures_file")" 119 + rm "$kselftest_failures_file" 120 + if "$ERROR_ON_FAIL" && [ "$failures" ]; then 121 + exit 1 122 + fi