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