150 lines
3.0 KiB
Bash
Executable File
150 lines
3.0 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
TESTS="$@"
|
|
RET=0
|
|
TIMEOUT=60
|
|
DMESG_FILTER="cat"
|
|
TEST_DIR=$(dirname $0)
|
|
FAILED=""
|
|
SKIPPED=""
|
|
MAYBE_FAILED=""
|
|
TEST_FILES=""
|
|
declare -A TEST_MAP
|
|
|
|
# Only use /dev/kmsg if running as root
|
|
DO_KMSG="1"
|
|
[ "$(id -u)" != "0" ] && DO_KMSG="0"
|
|
|
|
# Include config.local if exists and check TEST_FILES for valid devices
|
|
if [ -f "$TEST_DIR/config.local" ]; then
|
|
. $TEST_DIR/config.local
|
|
for dev in $TEST_FILES; do
|
|
if [ ! -e "$dev" ]; then
|
|
echo "Test file $dev not valid"
|
|
exit 1
|
|
fi
|
|
done
|
|
for dev in ${TEST_MAP[@]}; do
|
|
if [ ! -e "$dev" ]; then
|
|
echo "Test file in map $dev not valid"
|
|
exit 1
|
|
fi
|
|
done
|
|
fi
|
|
|
|
_check_dmesg()
|
|
{
|
|
local dmesg_marker="$1"
|
|
local seqres="$2.seqres"
|
|
|
|
if [ $DO_KMSG -eq 0 ]; then
|
|
return 0
|
|
fi
|
|
|
|
dmesg | bash -c "$DMESG_FILTER" | grep -A 9999 "$dmesg_marker" >"${seqres}.dmesg"
|
|
grep -q -e "kernel BUG at" \
|
|
-e "WARNING:" \
|
|
-e "BUG:" \
|
|
-e "Oops:" \
|
|
-e "possible recursive locking detected" \
|
|
-e "Internal error" \
|
|
-e "INFO: suspicious RCU usage" \
|
|
-e "INFO: possible circular locking dependency detected" \
|
|
-e "general protection fault:" \
|
|
-e "blktests failure" \
|
|
"${seqres}.dmesg"
|
|
# shellcheck disable=SC2181
|
|
if [[ $? -eq 0 ]]; then
|
|
return 1
|
|
else
|
|
rm -f "${seqres}.dmesg"
|
|
return 0
|
|
fi
|
|
}
|
|
|
|
run_test()
|
|
{
|
|
local test_name="$1"
|
|
local dev="$2"
|
|
local test_string=$test_name
|
|
|
|
# Specify test string to print
|
|
if [ -n "$dev" ]; then
|
|
test_string="$test_name $dev"
|
|
fi
|
|
|
|
# Log start of the test
|
|
if [ "$DO_KMSG" -eq 1 ]; then
|
|
local dmesg_marker="Running test $test_string:"
|
|
echo $dmesg_marker | tee /dev/kmsg
|
|
else
|
|
local dmesg_marker=""
|
|
echo Running test $test_name $dev
|
|
fi
|
|
|
|
# Do we have to exclude the test ?
|
|
echo $TEST_EXCLUDE | grep -w "$test_name" > /dev/null 2>&1
|
|
if [ $? -eq 0 ]; then
|
|
echo "Test skipped"
|
|
SKIPPED="$SKIPPED <$test_string>"
|
|
return
|
|
fi
|
|
|
|
# Run the test
|
|
timeout -s INT -k $TIMEOUT $TIMEOUT ./$test_name $dev
|
|
local status=$?
|
|
|
|
# Check test status
|
|
if [ "$status" -eq 124 ]; then
|
|
echo "Test $test_name timed out (may not be a failure)"
|
|
elif [ "$status" -ne 0 ]; then
|
|
echo "Test $test_name failed with ret $status"
|
|
FAILED="$FAILED <$test_string>"
|
|
RET=1
|
|
elif ! _check_dmesg "$dmesg_marker" "$test_name"; then
|
|
echo "Test $test_name failed dmesg check"
|
|
FAILED="$FAILED <$test_string>"
|
|
RET=1
|
|
elif [ -n "$dev" ]; then
|
|
sleep .1
|
|
ps aux | grep "\[io_wq_manager\]" > /dev/null
|
|
if [ $? -eq 0 ]; then
|
|
MAYBE_FAILED="$MAYBE_FAILED $test_string"
|
|
fi
|
|
fi
|
|
}
|
|
|
|
# Run all specified tests
|
|
for tst in $TESTS; do
|
|
if [ ! -n "${TEST_MAP[$tst]}" ]; then
|
|
run_test $tst
|
|
if [ ! -z "$TEST_FILES" ]; then
|
|
for dev in $TEST_FILES; do
|
|
run_test $tst $dev
|
|
done
|
|
fi
|
|
else
|
|
run_test $tst ${TEST_MAP[$tst]}
|
|
fi
|
|
done
|
|
|
|
if [ -n "$SKIPPED" ]; then
|
|
echo "Tests skipped: $SKIPPED"
|
|
fi
|
|
|
|
if [ "${RET}" -ne 0 ]; then
|
|
echo "Tests failed: $FAILED"
|
|
exit $RET
|
|
else
|
|
sleep 1
|
|
ps aux | grep "\[io_wq_manager\]" > /dev/null
|
|
if [ $? -ne 0 ]; then
|
|
MAYBE_FAILED=""
|
|
fi
|
|
if [ ! -z "$MAYBE_FAILED" ]; then
|
|
echo "Tests _maybe_ failed: $MAYBE_FAILED"
|
|
fi
|
|
echo "All tests passed"
|
|
exit 0
|
|
fi
|