xref: /kvm-unit-tests/run_tests.sh (revision d50fa5a856a9ac1508cac9a923aad21abb593322)
1#!/usr/bin/env bash
2
3verbose="no"
4tap_output="no"
5run_all_tests="no" # don't run nodefault tests
6
7if [ ! -f config.mak ]; then
8    echo "run ./configure && make first. See ./configure -h"
9    exit 1
10fi
11source config.mak
12source scripts/common.bash
13
14function usage()
15{
16cat <<EOF
17
18Usage: $0 [-h] [-v] [-a] [-g group] [-j NUM-TASKS] [-t] [-l]
19
20    -h, --help      Output this help text
21    -v, --verbose   Enables verbose mode
22    -a, --all       Run all tests, including those flagged as 'nodefault'
23                    and those guarded by errata.
24    -g, --group     Only execute tests in the given group
25    -j, --parallel  Execute tests in parallel
26    -t, --tap13     Output test results in TAP format
27    -l, --list      Only output all tests list
28
29Set the environment variable QEMU=/path/to/qemu-system-ARCH to
30specify the appropriate qemu binary for ARCH-run.
31
32EOF
33}
34
35RUNTIME_arch_run="./$TEST_SUBDIR/run"
36source scripts/runtime.bash
37
38# require enhanced getopt
39getopt -T > /dev/null
40if [ $? -ne 4 ]; then
41    echo "Enhanced getopt is not available, add it to your PATH?"
42    exit 1
43fi
44
45only_tests=""
46list_tests=""
47args=$(getopt -u -o ag:htj:vl -l all,group:,help,tap13,parallel:,verbose,list,probe-maxsmp -- $*)
48[ $? -ne 0 ] && exit 2;
49set -- $args;
50while [ $# -gt 0 ]; do
51    case "$1" in
52        -a | --all)
53            run_all_tests="yes"
54            export ERRATA_FORCE=y
55            ;;
56        -g | --group)
57            shift
58            only_group=$1
59            ;;
60        -h | --help)
61            usage
62            exit
63            ;;
64        -j | --parallel)
65            shift
66            unittest_run_queues=$1
67            if (( $unittest_run_queues <= 0 )); then
68                echo "Invalid -j option: $unittest_run_queues"
69                exit 2
70            fi
71            ;;
72        -v | --verbose)
73            verbose="yes"
74            ;;
75        -t | --tap13)
76            tap_output="yes"
77            ;;
78        -l | --list)
79            list_tests="yes"
80            ;;
81        --probe-maxsmp)
82            probe_maxsmp
83            ;;
84        --)
85            ;;
86        *)
87            only_tests="$only_tests $1"
88            ;;
89    esac
90    shift
91done
92
93# RUNTIME_log_file will be configured later
94if [[ $tap_output == "no" ]]; then
95    process_test_output() { cat >> $RUNTIME_log_file; }
96    postprocess_suite_output() { cat; }
97else
98    process_test_output() {
99        local testname="$1"
100        CR=$'\r'
101        while read -r line; do
102            line="${line%"$CR"}"
103            case "${line:0:4}" in
104                PASS)
105                    echo "ok TEST_NUMBER - ${testname}: ${line#??????}" >&3
106                    ;;
107                FAIL)
108                    echo "not ok TEST_NUMBER - ${testname}: ${line#??????}" >&3
109                    ;;
110                SKIP)
111                    echo "ok TEST_NUMBER - ${testname}: ${line#??????} # skip" >&3
112                    ;;
113                *)
114                    ;;
115            esac
116            echo "${line}"
117        done >> $RUNTIME_log_file
118    }
119    postprocess_suite_output() {
120        test_number=0
121        while read -r line; do
122            case "${line}" in
123                ok*|"not ok"*)
124                    (( test_number++ ))
125                    echo "${line/TEST_NUMBER/${test_number}}" ;;
126                *) echo "${line}" ;;
127            esac
128        done
129        echo "1..$test_number"
130    }
131fi
132
133RUNTIME_log_stderr () { process_test_output "$1"; }
134RUNTIME_log_stdout () {
135    local testname="$1"
136    if [ "$PRETTY_PRINT_STACKS" = "yes" ]; then
137        local kernel="$2"
138        ./scripts/pretty_print_stacks.py "$kernel" | process_test_output "$testname"
139    else
140        process_test_output "$testname"
141    fi
142}
143
144function run_task()
145{
146	local testname="$1"
147
148	while (( $(jobs | wc -l) == $unittest_run_queues )); do
149		# wait for any background test to finish
150		wait -n 2>/dev/null
151	done
152
153	RUNTIME_log_file="${unittest_log_dir}/${testname}.log"
154	if [ $unittest_run_queues = 1 ]; then
155		run "$@"
156	else
157		run "$@" &
158	fi
159}
160
161: "${unittest_log_dir:=logs}"
162: "${unittest_run_queues:=1}"
163config=$TEST_DIR/unittests.cfg
164
165print_testname()
166{
167    local testname=$1
168    local groups=$2
169    if [ -n "$only_group" ] && ! find_word "$only_group" "$groups"; then
170        return
171    fi
172    echo "$testname"
173}
174if [[ $list_tests == "yes" ]]; then
175    for_each_unittest $config print_testname
176    exit
177fi
178
179rm -rf $unittest_log_dir.old
180[ -d $unittest_log_dir ] && mv $unittest_log_dir $unittest_log_dir.old
181mkdir $unittest_log_dir || exit 2
182
183echo "BUILD_HEAD=$(cat build-head)" > $unittest_log_dir/SUMMARY
184
185if [[ $tap_output == "yes" ]]; then
186    echo "TAP version 13"
187fi
188
189trap "wait; exit 130" SIGINT
190
191(
192   # preserve stdout so that process_test_output output can write TAP to it
193   exec 3>&1
194   test "$tap_output" == "yes" && exec > /dev/null
195   for_each_unittest $config run_task
196) | postprocess_suite_output
197
198# wait until all tasks finish
199wait
200