xref: /kvm-unit-tests/run_tests.sh (revision 61ff990187ed8d2f29b648609f1b4e5791366600)
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
13source scripts/vmm.bash
14
15function usage()
16{
17cat <<EOF
18
19Usage: $0 [-h] [-v] [-a] [-g group] [-j NUM-TASKS] [-t] [-l]
20
21    -h, --help          Output this help text
22    -v, --verbose       Enables verbose mode
23    -a, --all           Run all tests, including those flagged as 'nodefault'
24                        and those guarded by errata.
25    -g, --group         Only execute tests in the given group
26    -j, --parallel      Execute tests in parallel
27    -t, --tap13         Output test results in TAP format
28    -l, --list          Only output all tests list
29        --probe-maxsmp  Update the maximum number of VCPUs supported by host
30
31The following environment variables are used:
32
33    QEMU            Path to QEMU binary for ARCH-run
34    ACCEL           QEMU accelerator to use, e.g. 'kvm', 'hvf' or 'tcg'
35    ACCEL_PROPS     Extra argument(s) to ACCEL
36    MACHINE         QEMU machine type
37    TIMEOUT         Timeout duration for the timeout(1) command
38    CHECK           Overwrites the 'check' unit test parameter (see
39                    docs/unittests.txt)
40    KVMTOOL         Path to kvmtool binary for ARCH-run
41EOF
42}
43
44RUNTIME_arch_run="./$TEST_SUBDIR/run"
45source scripts/runtime.bash
46
47# require enhanced getopt
48getopt -T > /dev/null
49if [ $? -ne 4 ]; then
50    echo "Enhanced getopt is not available, add it to your PATH?"
51    exit 1
52fi
53
54only_tests=""
55list_tests=""
56args=$(getopt -u -o ag:htj:vl -l all,group:,help,tap13,parallel:,verbose,list,probe-maxsmp -- "$@")
57# Shellcheck likes to test commands directly rather than with $? but sometimes they
58# are too long to put in the same test.
59# shellcheck disable=SC2181
60[ $? -ne 0 ] && exit 2;
61set -- $args;
62while [ $# -gt 0 ]; do
63    case "$1" in
64        -a | --all)
65            run_all_tests="yes"
66            export ERRATA_FORCE=y
67            ;;
68        -g | --group)
69            shift
70            only_group=$1
71            ;;
72        -h | --help)
73            usage
74            exit
75            ;;
76        -j | --parallel)
77            shift
78            unittest_run_queues=$1
79            if (( $unittest_run_queues <= 0 )); then
80                echo "Invalid -j option: $unittest_run_queues"
81                exit 2
82            fi
83            ;;
84        -v | --verbose)
85            verbose="yes"
86            ;;
87        -t | --tap13)
88            tap_output="yes"
89            ;;
90        -l | --list)
91            list_tests="yes"
92            ;;
93        --probe-maxsmp)
94            vmm_probe_maxsmp $RUNTIME_arch_run
95            ;;
96        --)
97            ;;
98        *)
99            only_tests="$only_tests $1"
100            ;;
101    esac
102    shift
103done
104
105# RUNTIME_log_file will be configured later
106if [[ $tap_output == "no" ]]; then
107    process_test_output() { cat >> $RUNTIME_log_file; }
108    postprocess_suite_output() { cat; }
109else
110    process_test_output() {
111        local testname="$1"
112        CR=$'\r'
113        while read -r line; do
114            line="${line%"$CR"}"
115            case "${line:0:4}" in
116                PASS)
117                    echo "ok TEST_NUMBER - ${testname}: ${line#??????}" >&3
118                    ;;
119                FAIL)
120                    echo "not ok TEST_NUMBER - ${testname}: ${line#??????}" >&3
121                    ;;
122                SKIP)
123                    echo "ok TEST_NUMBER - ${testname}: ${line#??????} # skip" >&3
124                    ;;
125                *)
126                    ;;
127            esac
128            echo "${line}"
129        done >> $RUNTIME_log_file
130    }
131    postprocess_suite_output() {
132        test_number=0
133        while read -r line; do
134            case "${line}" in
135                ok*|"not ok"*)
136                    (( test_number++ ))
137                    echo "${line/TEST_NUMBER/${test_number}}" ;;
138                *) echo "${line}" ;;
139            esac
140        done
141        echo "1..$test_number"
142    }
143fi
144
145RUNTIME_log_stderr () { process_test_output "$1"; }
146RUNTIME_log_stdout () {
147    local testname="$1"
148    if [ "$PRETTY_PRINT_STACKS" = "yes" ]; then
149        local kernel="$2"
150        ./scripts/pretty_print_stacks.py "$kernel" | process_test_output "$testname"
151    else
152        process_test_output "$testname"
153    fi
154}
155
156function run_task()
157{
158	local testname="$1"
159
160	while (( $(jobs | wc -l) == $unittest_run_queues )); do
161		# wait for any background test to finish
162		wait -n 2>/dev/null
163	done
164
165	RUNTIME_log_file="${unittest_log_dir}/${testname}.log"
166	if [ $unittest_run_queues = 1 ]; then
167		run "$@"
168	else
169		run "$@" &
170	fi
171}
172
173: "${unittest_log_dir:=logs}"
174: "${unittest_run_queues:=1}"
175config=$TEST_DIR/unittests.cfg
176
177print_testname()
178{
179    local testname=$1
180    local groups=$2
181    if [ -n "$only_group" ] && ! find_word "$only_group" "$groups"; then
182        return
183    fi
184    echo "$testname"
185}
186if [[ $list_tests == "yes" ]]; then
187    for_each_unittest $config print_testname
188    exit
189fi
190
191rm -rf $unittest_log_dir.old
192[ -d $unittest_log_dir ] && mv $unittest_log_dir $unittest_log_dir.old
193mkdir $unittest_log_dir || exit 2
194
195echo "BUILD_HEAD=$(cat build-head)" > $unittest_log_dir/SUMMARY
196
197if [[ $tap_output == "yes" ]]; then
198    echo "TAP version 13"
199fi
200
201trap "wait; exit 130" SIGINT
202
203(
204   # preserve stdout so that process_test_output output can write TAP to it
205   exec 3>&1
206   test "$tap_output" == "yes" && exec > /dev/null
207   for_each_unittest $config run_task
208) | postprocess_suite_output
209
210# wait until all tasks finish
211wait
212