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

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'linux_kselftest-next-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest

Pull kselftest updates from Shuah Khan:

- cpu-hotplug: fix to check if cpu hotplug is supported to avoid
test failures when cpu hotplug isn't supported.

- frace: fix to relevant comparisons and path checks in the helper so
it handles those patterns without spurious shell warnings.

- runner.sh: add ktrap support

- tracing: fix to make --logdir option work again

- tracing: fix to check awk supports non POSIX strtonum()

- mqueue: fix incorrectly named settings file to make sure the test
used the correct timeout value

- kselftest:
- fix to treat xpass as successful result
- add ksft_reset_state()

- kselftest_harness:
- validate kselftest exit codes are handled explicitly
- add detection of invalid mixing of kselftest and harness
functionality
- add validation of intermixing of kselftest and harness
functionality

- run_kselftest.sh:
- remove unused $ROOT
- resolve BASE_DIR with pwd -P to avoid dependency on realpath
or readlink commands to generate a physical absolute path for
BASE_DIR
- allow choosing per-test log directory
- preserve subtarget failures in all/install

* tag 'linux_kselftest-next-7.1-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/shuah/linux-kselftest:
selftests/ftrace: Quote check_requires comparisons
selftests: Preserve subtarget failures in all/install
selftests/run_kselftest.sh: Allow choosing per-test log directory
selftests/run_kselftest.sh: Resolve BASE_DIR with pwd -P
selftests/run_kselftest.sh: Remove unused $ROOT
selftests/cpu-hotplug: Fix check for cpu hotplug not supported
selftests/mqueue: Fix incorrectly named file
selftests: Use ktap helpers for runner.sh
selftests: harness: Validate intermixing of kselftest and harness functionality
selftests: harness: Detect illegal mixing of kselftest and harness functionality
selftests: kselftest: Add ksft_reset_state()
selftests: harness: Validate that explicit kselftest exitcodes are handled
selftests: kselftest: Treat xpass as successful result
selftests/tracing: Fix to check awk supports non POSIX strtonum()
selftests/tracing: Fix to make --logdir option work again

+237 -79
+4 -4
tools/testing/selftests/Makefile
··· 209 209 .DEFAULT_GOAL := all 210 210 211 211 all: 212 - @ret=1; \ 212 + @ret=0; \ 213 213 for TARGET in $(TARGETS) $(INSTALL_DEP_TARGETS); do \ 214 214 BUILD_TARGET=$$BUILD/$$TARGET; \ 215 215 mkdir $$BUILD_TARGET -p; \ 216 216 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET \ 217 217 O=$(abs_objtree) \ 218 218 $(if $(FORCE_TARGETS),|| exit); \ 219 - ret=$$((ret * $$?)); \ 219 + [ $$? -eq 0 ] || ret=1; \ 220 220 done; exit $$ret; 221 221 222 222 run_tests: all ··· 274 274 install -m 744 kselftest/ksft.py $(INSTALL_PATH)/kselftest/ 275 275 install -m 744 run_kselftest.sh $(INSTALL_PATH)/ 276 276 rm -f $(TEST_LIST) 277 - @ret=1; \ 277 + @ret=0; \ 278 278 for TARGET in $(TARGETS) $(INSTALL_DEP_TARGETS); do \ 279 279 BUILD_TARGET=$$BUILD/$$TARGET; \ 280 280 $(MAKE) OUTPUT=$$BUILD_TARGET -C $$TARGET install \ ··· 283 283 OBJ_PATH=$(INSTALL_PATH) \ 284 284 O=$(abs_objtree) \ 285 285 $(if $(FORCE_TARGETS),|| exit); \ 286 - ret=$$((ret * $$?)); \ 286 + [ $$? -eq 0 ] || ret=1; \ 287 287 done; exit $$ret; 288 288 289 289
+1 -1
tools/testing/selftests/cpu-hotplug/cpu-on-off-test.sh
··· 24 24 exit $ksft_skip 25 25 fi 26 26 27 - if ! ls $SYSFS/devices/system/cpu/cpu* > /dev/null 2>&1; then 27 + if ! ls $SYSFS/devices/system/cpu/cpu*/online > /dev/null 2>&1; then 28 28 echo $msg cpu hotplug is not supported >&2 29 29 exit $ksft_skip 30 30 fi
+12 -6
tools/testing/selftests/ftrace/ftracetest
··· 130 130 shift 1 131 131 ;; 132 132 --logdir|-l) 133 - LOG_DIR=$2 134 - LINK_PTR= 133 + USER_LOG_DIR=$2 135 134 shift 2 136 135 ;; 137 136 --rv) ··· 198 199 TOP_DIR=`absdir $0` 199 200 TEST_DIR=$TOP_DIR/test.d 200 201 TEST_CASES=`find_testcases $TEST_DIR` 202 + USER_LOG_DIR= 201 203 KEEP_LOG=0 202 204 KTAP=0 203 205 DEBUG=0 ··· 210 210 # Parse command-line options 211 211 parse_opts $* 212 212 213 + [ $DEBUG -ne 0 ] && set -x 214 + 215 + # TOP_DIR can be changed for rv. Setting log directory. 213 216 LOG_TOP_DIR=$TOP_DIR/logs 214 217 LOG_DATE=`date +%Y%m%d-%H%M%S` 215 - LOG_DIR=$LOG_TOP_DIR/$LOG_DATE/ 216 - LINK_PTR=$LOG_TOP_DIR/latest 217 - 218 - [ $DEBUG -ne 0 ] && set -x 218 + if [ -n "$USER_LOG_DIR" ]; then 219 + LOG_DIR=$USER_LOG_DIR 220 + LINK_PTR= 221 + else 222 + LOG_DIR=$LOG_TOP_DIR/$LOG_DATE/ 223 + LINK_PTR=$LOG_TOP_DIR/latest 224 + fi 219 225 220 226 if [ $RV_TEST -ne 0 ]; then 221 227 TRACING_DIR=$TRACING_DIR/rv
+2
tools/testing/selftests/ftrace/test.d/00basic/trace_marker_raw.tc
··· 4 4 # requires: trace_marker_raw 5 5 # flags: instance 6 6 7 + check_awk_strtonum || exit_unresolved 8 + 7 9 is_little_endian() { 8 10 if lscpu | grep -q 'Little Endian'; then 9 11 echo 1;
+10 -6
tools/testing/selftests/ftrace/test.d/functions
··· 145 145 p=${i%:program} 146 146 r=${i%:README} 147 147 t=${i%:tracer} 148 - if [ $p != $i ]; then 149 - if ! which $p ; then 148 + if [ "$p" != "$i" ]; then 149 + if ! which "$p" ; then 150 150 echo "Required program $p is not found." 151 151 exit_unresolved 152 152 fi 153 - elif [ $t != $i ]; then 154 - if ! grep -wq $t available_tracers ; then 153 + elif [ "$t" != "$i" ]; then 154 + if ! grep -wq "$t" available_tracers ; then 155 155 echo "Required tracer $t is not configured." 156 156 exit_unsupported 157 157 fi ··· 162 162 else 163 163 test=$TRACING_DIR 164 164 fi 165 - if ! grep -Fq "$r" $test/README ; then 165 + if ! grep -Fq "$r" "$test"/README ; then 166 166 echo "Required feature pattern \"$r\" is not in README." 167 167 exit_unsupported 168 168 fi 169 - elif [ ! -e $i ]; then 169 + elif [ ! -e "$i" ]; then 170 170 echo "Required feature interface $i doesn't exist." 171 171 exit_unsupported 172 172 fi 173 173 done 174 + } 175 + 176 + check_awk_strtonum() { # strtonum is GNU awk extension 177 + awk 'BEGIN{strtonum("0x1")}' 174 178 } 175 179 176 180 LOCALHOST=127.0.0.1
+12
tools/testing/selftests/kselftest.h
··· 399 399 #define ksft_finished() \ 400 400 ksft_exit(ksft_plan == \ 401 401 ksft_cnt.ksft_pass + \ 402 + ksft_cnt.ksft_xpass + \ 402 403 ksft_cnt.ksft_xfail + \ 403 404 ksft_cnt.ksft_xskip) 404 405 ··· 474 473 ksft_exit_fail_msg("Can't parse kernel version\n"); 475 474 476 475 return major > min_major || (major == min_major && minor >= min_minor); 476 + } 477 + 478 + static inline void ksft_reset_state(void) 479 + { 480 + ksft_cnt.ksft_pass = 0; 481 + ksft_cnt.ksft_fail = 0; 482 + ksft_cnt.ksft_xfail = 0; 483 + ksft_cnt.ksft_xpass = 0; 484 + ksft_cnt.ksft_xskip = 0; 485 + ksft_cnt.ksft_error = 0; 486 + ksft_plan = 0; 477 487 } 478 488 479 489 #endif /* __KSELFTEST_H */
+62 -36
tools/testing/selftests/kselftest/runner.sh
··· 1 - #!/bin/sh 1 + #!/bin/bash 2 2 # SPDX-License-Identifier: GPL-2.0 3 3 # 4 4 # Runs a set of tests in a given subdirectory. 5 - export skip_rc=4 5 + . $(dirname "$(readlink -e "${BASH_SOURCE[0]}")")/ktap_helpers.sh 6 6 export timeout_rc=124 7 7 export logfile=/dev/stdout 8 8 export per_test_logging= 9 + export per_test_log_dir=/tmp 9 10 export RUN_IN_NETNS= 10 11 11 12 # Defaults for "settings" file fields: ··· 45 44 fi 46 45 } 47 46 48 - report_failure() 49 - { 50 - echo "not ok $*" 51 - echo "$*" >> "$kselftest_failures_file" 52 - } 53 - 54 47 run_one() 55 48 { 56 49 DIR="$1" 57 50 TEST="$2" 58 - local test_num="$3" 51 + local rc test_num="$3" 59 52 60 53 BASENAME_TEST=$(basename $TEST) 61 54 ··· 97 102 # Command line timeout overrides the settings file 98 103 if [ -n "$kselftest_override_timeout" ]; then 99 104 kselftest_timeout="$kselftest_override_timeout" 100 - echo "# overriding timeout to $kselftest_timeout" >> "$logfile" 105 + ktap_print_msg "overriding timeout to $kselftest_timeout" >> "$logfile" 101 106 else 102 - echo "# timeout set to $kselftest_timeout" >> "$logfile" 107 + ktap_print_msg "timeout set to $kselftest_timeout" >> "$logfile" 103 108 fi 104 109 105 110 TEST_HDR_MSG="selftests: $DIR: $BASENAME_TEST" 106 111 echo "# $TEST_HDR_MSG" 107 112 if [ ! -e "$TEST" ]; then 108 - echo "# Warning: file $TEST is missing!" 109 - report_failure "$test_num $TEST_HDR_MSG" 113 + ktap_print_msg "Warning: file $TEST is missing!" 114 + ktap_test_fail "$test_num $TEST_HDR_MSG" 115 + rc=$KSFT_FAIL 110 116 else 111 117 if [ -x /usr/bin/stdbuf ]; then 112 118 stdbuf="/usr/bin/stdbuf --output=L " ··· 118 122 elif [ -x "./ksft_runner.sh" ]; then 119 123 cmd="$stdbuf ./ksft_runner.sh ./$BASENAME_TEST" 120 124 else 121 - echo "# Warning: file $TEST is not executable" 125 + ktap_print_msg "Warning: file $TEST is not executable" 122 126 123 127 if [ $(head -n 1 "$TEST" | cut -c -2) = "#!" ] 124 128 then 125 129 interpreter=$(head -n 1 "$TEST" | cut -c 3-) 126 130 cmd="$stdbuf $interpreter ./$BASENAME_TEST" 127 131 else 128 - report_failure "$test_num $TEST_HDR_MSG" 129 - return 132 + ktap_test_fail "$test_num $TEST_HDR_MSG" 133 + return $KSFT_FAIL 130 134 fi 131 135 fi 132 136 cd `dirname $TEST` > /dev/null 133 - ((((( tap_timeout "$cmd" 2>&1; echo $? >&3) | 137 + (((( tap_timeout "$cmd" 2>&1; echo $? >&3) | 134 138 tap_prefix >&4) 3>&1) | 135 - (read xs; exit $xs)) 4>>"$logfile" && 136 - echo "ok $test_num $TEST_HDR_MSG") || 137 - (rc=$?; \ 138 - if [ $rc -eq $skip_rc ]; then \ 139 - echo "ok $test_num $TEST_HDR_MSG # SKIP" 140 - elif [ $rc -eq $timeout_rc ]; then \ 141 - echo "#" 142 - report_failure "$test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds" 143 - else 144 - report_failure "$test_num $TEST_HDR_MSG # exit=$rc" 145 - fi) 139 + (read xs; exit $xs)) 4>>"$logfile" 140 + rc=$? 141 + case "$rc" in 142 + "$KSFT_PASS") 143 + ktap_test_pass "$test_num $TEST_HDR_MSG";; 144 + "$KSFT_SKIP") 145 + ktap_test_skip "$test_num $TEST_HDR_MSG";; 146 + "$KSFT_XFAIL") 147 + ktap_test_xfail "$test_num $TEST_HDR_MSG";; 148 + "$timeout_rc") 149 + ktap_test_fail "$test_num $TEST_HDR_MSG # TIMEOUT $kselftest_timeout seconds";; 150 + *) 151 + ktap_test_fail "$test_num $TEST_HDR_MSG # exit=$rc";; 152 + esac 146 153 cd - >/dev/null 147 154 fi 155 + 156 + return $rc 148 157 } 149 158 150 159 in_netns() ··· 165 164 166 165 run_in_netns() 167 166 { 168 - local netns=$(mktemp -u ${BASENAME_TEST}-XXXXXX) 169 167 local tmplog="/tmp/$(mktemp -u ${BASENAME_TEST}-XXXXXX)" 168 + local netns=$(mktemp -u ${BASENAME_TEST}-XXXXXX) 169 + local rc 170 + 170 171 ip netns add $netns 171 172 if [ $? -ne 0 ]; then 172 - echo "# Warning: Create namespace failed for $BASENAME_TEST" 173 - echo "not ok $test_num selftests: $DIR: $BASENAME_TEST # Create NS failed" 173 + ktap_print_msg "Warning: Create namespace failed for $BASENAME_TEST" 174 + ktap_test_fail "$test_num selftests: $DIR: $BASENAME_TEST # Create NS failed" 174 175 fi 175 176 ip -n $netns link set lo up 177 + 176 178 in_netns $netns &> $tmplog 179 + rc=$? 180 + 177 181 ip netns del $netns &> /dev/null 182 + # Cat the log at once to avoid parallel netns logs. 178 183 cat $tmplog 179 184 rm -f $tmplog 185 + return $rc 180 186 } 181 187 182 188 run_many() 183 189 { 184 - echo "TAP version 13" 185 190 DIR="${PWD#${BASE_DIR}/}" 186 191 test_num=0 187 - total=$(echo "$@" | wc -w) 188 - echo "1..$total" 192 + local rc 193 + pids=() 194 + 189 195 for TEST in "$@"; do 190 196 BASENAME_TEST=$(basename $TEST) 191 197 test_num=$(( test_num + 1 )) 192 198 if [ -n "$per_test_logging" ]; then 193 - logfile="/tmp/$BASENAME_TEST" 199 + logfile="$per_test_log_dir/$BASENAME_TEST" 194 200 cat /dev/null > "$logfile" 195 201 fi 196 202 if [ -n "$RUN_IN_NETNS" ]; then 197 203 run_in_netns & 204 + pids+=($!) 198 205 else 199 206 run_one "$DIR" "$TEST" "$test_num" 200 207 fi 201 208 done 202 209 203 - wait 210 + # These variables are outputs of ktap_helpers.sh but since we've 211 + # run the test in a subprocess we need to update them manually 212 + for pid in "${pids[@]}"; do 213 + wait "$pid" 214 + rc=$? 215 + case "$rc" in 216 + "$KSFT_PASS") 217 + KTAP_CNT_PASS=$((KTAP_CNT_PASS + 1));; 218 + "$KSFT_FAIL") 219 + KTAP_CNT_FAIL=$((KTAP_CNT_FAIL + 1));; 220 + "$KSFT_SKIP") 221 + KTAP_CNT_SKIP=$((KTAP_CNT_SKIP + 1));; 222 + "$KSFT_XFAIL") 223 + KTAP_CNT_XFAIL=$((KTAP_CNT_XFAIL + 1));; 224 + *) 225 + KTAP_CNT_FAIL=$((KTAP_CNT_FAIL + 1));; 226 + esac 227 + done 204 228 }
+9
tools/testing/selftests/kselftest_harness.h
··· 1225 1225 t->exit_code = KSFT_FAIL; 1226 1226 } else if (child == 0) { 1227 1227 setpgrp(); 1228 + 1229 + /* Reset state inherited from the harness */ 1230 + ksft_reset_state(); 1231 + 1228 1232 t->fn(t, variant); 1233 + 1234 + if (__test_passed(t) && (ksft_get_fail_cnt() || ksft_get_error_cnt())) { 1235 + ksft_print_msg("Illegal usage of low-level ksft APIs in harness test\n"); 1236 + t->exit_code = KSFT_FAIL; 1237 + } 1229 1238 _exit(t->exit_code); 1230 1239 } else { 1231 1240 t->pid = child;
+40
tools/testing/selftests/kselftest_harness/harness-selftest.c
··· 118 118 TH_LOG("after"); 119 119 } 120 120 121 + TEST(exit_pass) { 122 + exit(KSFT_PASS); 123 + } 124 + 125 + TEST(exit_xpass) { 126 + exit(KSFT_XPASS); 127 + } 128 + 129 + TEST(exit_fail) { 130 + exit(KSFT_FAIL); 131 + } 132 + 133 + TEST(exit_xfail) { 134 + exit(KSFT_XFAIL); 135 + } 136 + 137 + TEST(exit_skip) { 138 + exit(KSFT_SKIP); 139 + } 140 + 141 + TEST(test_result_pass) { 142 + ksft_test_result_pass(""); 143 + } 144 + 145 + TEST(test_result_xpass) { 146 + ksft_test_result_xpass(""); 147 + } 148 + 149 + TEST(test_result_fail) { 150 + ksft_test_result_fail(""); 151 + } 152 + 153 + TEST(test_result_xfail) { 154 + ksft_test_result_xfail(""); 155 + } 156 + 157 + TEST(test_result_skip) { 158 + ksft_test_result_skip(""); 159 + } 160 + 121 161 int main(int argc, char **argv) 122 162 { 123 163 /*
+43 -9
tools/testing/selftests/kselftest_harness/harness-selftest.expected
··· 1 1 TAP version 13 2 - 1..9 3 - # Starting 9 tests from 4 test cases. 2 + 1..19 3 + # Starting 19 tests from 4 test cases. 4 4 # RUN global.standalone_pass ... 5 5 # harness-selftest.c:19:standalone_pass:before 6 6 # harness-selftest.c:23:standalone_pass:after ··· 24 24 # signal_fail: Test terminated by assertion 25 25 # FAIL global.signal_fail 26 26 not ok 4 global.signal_fail 27 + # RUN global.exit_pass ... 28 + # OK global.exit_pass 29 + ok 5 global.exit_pass 30 + # RUN global.exit_xpass ... 31 + # OK global.exit_xpass 32 + ok 6 global.exit_xpass # XPASS unknown 33 + # RUN global.exit_fail ... 34 + # exit_fail: Test failed 35 + # FAIL global.exit_fail 36 + not ok 7 global.exit_fail 37 + # RUN global.exit_xfail ... 38 + # OK global.exit_xfail 39 + ok 8 global.exit_xfail # XFAIL unknown 40 + # RUN global.exit_skip ... 41 + # OK global.exit_skip 42 + ok 9 global.exit_skip # SKIP unknown 43 + # RUN global.test_result_pass ... 44 + # OK global.test_result_pass 45 + ok 10 global.test_result_pass 46 + # RUN global.test_result_xpass ... 47 + # OK global.test_result_xpass 48 + ok 11 global.test_result_xpass 49 + # RUN global.test_result_fail ... 50 + not ok 1 # Illegal usage of low-level ksft APIs in harness test 51 + # test_result_fail: Test failed 52 + # FAIL global.test_result_fail 53 + not ok 12 global.test_result_fail 54 + # RUN global.test_result_xfail ... 55 + # OK global.test_result_xfail 56 + ok 13 global.test_result_xfail 57 + # RUN global.test_result_skip ... 58 + # OK global.test_result_skip 59 + ok 14 global.test_result_skip 27 60 # RUN fixture.pass ... 28 61 # harness-selftest.c:53:pass:setup 29 62 # harness-selftest.c:62:pass:before ··· 65 32 # harness-selftest.c:66:pass:after 66 33 # harness-selftest.c:58:pass:teardown same-process=1 67 34 # OK fixture.pass 68 - ok 5 fixture.pass 35 + ok 15 fixture.pass 69 36 # RUN fixture.fail ... 70 37 # harness-selftest.c:53:fail:setup 71 38 # harness-selftest.c:70:fail:before ··· 73 40 # harness-selftest.c:58:fail:teardown same-process=1 74 41 # fail: Test terminated by assertion 75 42 # FAIL fixture.fail 76 - not ok 6 fixture.fail 43 + not ok 16 fixture.fail 77 44 # RUN fixture.timeout ... 78 45 # harness-selftest.c:53:timeout:setup 79 46 # harness-selftest.c:77:timeout:before 80 47 # timeout: Test terminated by timeout 81 48 # FAIL fixture.timeout 82 - not ok 7 fixture.timeout 49 + not ok 17 fixture.timeout 83 50 # RUN fixture_parent.pass ... 84 51 # harness-selftest.c:87:pass:setup 85 52 # harness-selftest.c:96:pass:before 86 53 # harness-selftest.c:98:pass:after 87 54 # harness-selftest.c:92:pass:teardown same-process=0 88 55 # OK fixture_parent.pass 89 - ok 8 fixture_parent.pass 56 + ok 18 fixture_parent.pass 90 57 # RUN fixture_setup_failure.pass ... 91 58 # harness-selftest.c:106:pass:setup 92 59 # harness-selftest.c:108:pass:Expected 0 (0) == 1 (1) 93 60 # pass: Test terminated by assertion 94 61 # FAIL fixture_setup_failure.pass 95 - not ok 9 fixture_setup_failure.pass 96 - # FAILED: 4 / 9 tests passed. 97 - # Totals: pass:4 fail:5 xfail:0 xpass:0 skip:0 error:0 62 + not ok 19 fixture_setup_failure.pass 63 + # FAILED: 12 / 19 tests passed. 64 + # 1 skipped test(s) detected. Consider enabling relevant config options to improve coverage. 65 + # Totals: pass:9 fail:7 xfail:1 xpass:1 skip:1 error:0
tools/testing/selftests/mqueue/setting tools/testing/selftests/mqueue/settings
+42 -17
tools/testing/selftests/run_kselftest.sh
··· 4 4 # Run installed kselftest tests. 5 5 # 6 6 7 - # Fallback to readlink if realpath is not available 8 - if which realpath > /dev/null; then 9 - BASE_DIR=$(realpath $(dirname $0)) 10 - else 11 - BASE_DIR=$(readlink -f $(dirname $0)) 12 - fi 7 + BASE_DIR=$(cd "$(dirname "$0")" && pwd -P) 13 8 14 9 cd $BASE_DIR 15 10 TESTS="$BASE_DIR"/kselftest-list.txt ··· 16 21 fi 17 22 18 23 . ./kselftest/runner.sh 19 - ROOT=$PWD 20 24 21 25 usage() 22 26 { 23 27 cat <<EOF 24 28 Usage: $0 [OPTIONS] 25 29 -s | --summary Print summary with detailed log in output.log (conflict with -p) 26 - -p | --per-test-log Print test log in /tmp with each test name (conflict with -s) 30 + -p | --per-test-log [DIR] Print test log in /tmp or DIR with each test name (conflict with -s) 27 31 -t | --test COLLECTION:TEST Run TEST from COLLECTION 28 32 -S | --skip COLLECTION:TEST Skip TEST from COLLECTION 29 33 -c | --collection COLLECTION Run all tests from COLLECTION ··· 50 56 shift ;; 51 57 -p | --per-test-log) 52 58 per_test_logging=1 53 - shift ;; 59 + if [ -n "$2" ] && [ "${2#-}" = "$2" ]; then 60 + per_test_log_dir="$2" 61 + if [ -e "$per_test_log_dir" ] && [ ! -d "$per_test_log_dir" ]; then 62 + echo "Per-test log path is not a dir:" \ 63 + "$per_test_log_dir" >&2 64 + exit 1 65 + fi 66 + if [ ! -d "$per_test_log_dir" ] && \ 67 + ! mkdir -p "$per_test_log_dir"; then 68 + echo "Could not create log dir:" \ 69 + "$per_test_log_dir" >&2 70 + exit 1 71 + fi 72 + per_test_log_dir=$(cd "$per_test_log_dir" && pwd -P) 73 + if [ -z "$per_test_log_dir" ]; then 74 + echo "Could not resolve per-test log directory" >&2 75 + exit 1 76 + fi 77 + if [ ! -w "$per_test_log_dir" ]; then 78 + echo "Per-test log dir is not writable:" \ 79 + "$per_test_log_dir" >&2 80 + exit 1 81 + fi 82 + shift 2 83 + else 84 + shift 85 + fi ;; 54 86 -t | --test) 55 87 TESTS="$TESTS $2" 56 88 shift 2 ;; ··· 141 121 done 142 122 fi 143 123 144 - kselftest_failures_file="$(mktemp --tmpdir kselftest-failures-XXXXXX)" 145 - export kselftest_failures_file 146 - 124 + curdir=$(pwd) 125 + total=$(echo "$available" | wc -w) 147 126 collections=$(echo "$available" | cut -d: -f1 | sort | uniq) 127 + 128 + ktap_print_header 129 + ktap_set_plan "$total" 130 + 148 131 for collection in $collections ; do 149 132 [ -w /dev/kmsg ] && echo "kselftest: Running tests in $collection" >> /dev/kmsg 150 133 tests=$(echo "$available" | grep "^$collection:" | cut -d: -f2) 151 - ($dryrun cd "$collection" && $dryrun run_many $tests) 134 + $dryrun cd "$collection" && $dryrun run_many $tests 135 + $dryrun cd "$curdir" 152 136 done 153 137 154 - failures="$(cat "$kselftest_failures_file")" 155 - rm "$kselftest_failures_file" 156 - if "$ERROR_ON_FAIL" && [ "$failures" ]; then 157 - exit 1 138 + ktap_print_totals 139 + if "$ERROR_ON_FAIL" && [ "$KTAP_CNT_FAIL" -ne 0 ]; then 140 + exit "$KSFT_FAIL" 141 + else 142 + exit "$KSFT_PASS" 158 143 fi