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