1#!/usr/bin/env bash 2 3TESTS=("$@") 4RET=0 5TIMEOUT=60 6DMESG_FILTER="cat" 7TEST_DIR=$(dirname "$0") 8FAILED="" 9SKIPPED="" 10TIMED_OUT="" 11TEST_FILES="" 12declare -A TEST_MAP 13 14# Only use /dev/kmsg if running as root 15DO_KMSG="1" 16[ "$(id -u)" != "0" ] && DO_KMSG="0" 17 18# Include config.local if exists and check TEST_FILES for valid devices 19if [ -f "$TEST_DIR/config.local" ]; then 20 # shellcheck source=/dev/null disable=SC1091 21 . "$TEST_DIR/config.local" 22 for dev in $TEST_FILES; do 23 if [ ! -e "$dev" ]; then 24 echo "Test file $dev not valid" 25 exit 1 26 fi 27 done 28 for dev in "${TEST_MAP[@]}"; do 29 if [ ! -e "$dev" ]; then 30 echo "Test file in map $dev not valid" 31 exit 1 32 fi 33 done 34fi 35 36_check_dmesg() 37{ 38 local dmesg_marker="$1" 39 local seqres="$2.seqres" 40 41 if [ "$DO_KMSG" -eq 0 ]; then 42 return 0 43 fi 44 45 dmesg | bash -c "$DMESG_FILTER" | grep -A 9999 "$dmesg_marker" >"${seqres}.dmesg" 46 grep -q -e "kernel BUG at" \ 47 -e "WARNING:" \ 48 -e "BUG:" \ 49 -e "Oops:" \ 50 -e "possible recursive locking detected" \ 51 -e "Internal error" \ 52 -e "INFO: suspicious RCU usage" \ 53 -e "INFO: possible circular locking dependency detected" \ 54 -e "general protection fault:" \ 55 -e "blktests failure" \ 56 "${seqres}.dmesg" 57 # shellcheck disable=SC2181 58 if [[ $? -eq 0 ]]; then 59 return 1 60 else 61 rm -f "${seqres}.dmesg" 62 return 0 63 fi 64} 65 66run_test() 67{ 68 local test_name="$1" 69 local dev="$2" 70 local test_exec=("./$test_name") 71 local test_string="$test_name" 72 local out_name="$test_name" 73 74 # Specify test string to print 75 if [ -n "$dev" ]; then 76 test_exec+=("$dev") 77 test_string="$test_name $dev" 78 local suffix 79 suffix=$(basename "$dev") 80 out_name="$out_name.$suffix" 81 fi 82 83 # Log start of the test 84 if [ "$DO_KMSG" -eq 1 ]; then 85 local dmesg_marker="Running test $test_string:" 86 echo "$dmesg_marker" > /dev/kmsg 87 else 88 local dmesg_marker="" 89 fi 90 printf "Running test %-55s" "$test_string" 91 92 # Do we have to exclude the test ? 93 echo "$TEST_EXCLUDE" | grep -w "$test_name" > /dev/null 2>&1 94 # shellcheck disable=SC2181 95 if [ $? -eq 0 ]; then 96 echo "Test skipped" 97 SKIPPED="$SKIPPED <$test_string>" 98 return 99 fi 100 101 # Run the test 102 T_START=$(date +%s) 103 timeout -s INT -k $TIMEOUT $TIMEOUT "${test_exec[@]}" 104 local status=$? 105 T_END=$(date +%s) 106 107 if [ -e ./core ]; then 108 mv core "core-$test_name" 109 fi 110 111 # Check test status 112 if [ "$status" -eq 124 ]; then 113 echo "Test $test_name timed out (may not be a failure)" 114 TIMED_OUT="$TIMED_OUT <$test_string>" 115 elif [ "$status" -ne 0 ]; then 116 echo "Test $test_name failed with ret $status" 117 FAILED="$FAILED <$test_string>" 118 RET=1 119 elif ! _check_dmesg "$dmesg_marker" "$test_name"; then 120 echo "Test $test_name failed dmesg check" 121 FAILED="$FAILED <$test_string>" 122 RET=1 123 else 124 if [ -f "output/$out_name" ]; then 125 T_PREV=$(cat "output/$out_name") 126 else 127 T_PREV="" 128 fi 129 T_DIFF=$((T_END-T_START)) 130 if [ -n "$T_PREV" ]; then 131 echo "$T_DIFF sec [$T_PREV]" 132 else 133 echo "$T_DIFF sec" 134 fi 135 echo $T_DIFF > "output/$out_name" 136 fi 137} 138 139# Run all specified tests 140for tst in "${TESTS[@]}"; do 141 if [ ! -d output ]; then 142 mkdir -p output 143 fi 144 if [ -z "${TEST_MAP[$tst]}" ]; then 145 run_test "$tst" 146 if [ -n "$TEST_FILES" ]; then 147 for dev in $TEST_FILES; do 148 run_test "$tst" "$dev" 149 done 150 fi 151 else 152 run_test "$tst" "${TEST_MAP[$tst]}" 153 fi 154done 155 156if [ -n "$SKIPPED" ]; then 157 echo "Tests skipped: $SKIPPED" 158fi 159 160if [ -n "$TIMED_OUT" ]; then 161 echo "Tests timed out: $TIMED_OUT" 162fi 163 164if [ "${RET}" -ne 0 ]; then 165 echo "Tests failed: $FAILED" 166 exit $RET 167else 168 echo "All tests passed" 169 exit 0 170fi 171