xref: /kvm-unit-tests/scripts/runtime.bash (revision df477983d896be6e657eecc75a0cf7805e349905)
1: "${RUNTIME_arch_run?}"
2: ${MAX_SMP:=$(getconf _NPROCESSORS_CONF)}
3: ${TIMEOUT:=90s}
4
5PASS() { echo -ne "\e[32mPASS\e[0m"; }
6SKIP() { echo -ne "\e[33mSKIP\e[0m"; }
7FAIL() { echo -ne "\e[31mFAIL\e[0m"; }
8
9extract_summary()
10{
11    tail -1 | grep '^SUMMARY: ' | sed 's/^SUMMARY: /(/;s/$/)/'
12}
13
14# We assume that QEMU is going to work if it tried to load the kernel
15premature_failure()
16{
17    local log="$(eval $(get_cmdline _NO_FILE_4Uhere_) 2>&1)"
18
19    echo "$log" | grep "_NO_FILE_4Uhere_" |
20        grep -q -e "could not load kernel" -e "error loading" &&
21        return 1
22
23    RUNTIME_log_stderr <<< "$log"
24
25    echo "$log"
26    return 0
27}
28
29get_cmdline()
30{
31    local kernel=$1
32    echo "TESTNAME=$testname TIMEOUT=$timeout ACCEL=$accel $RUNTIME_arch_run $kernel -smp $smp $opts"
33}
34
35function run()
36{
37    local testname="$1"
38    local groups="$2"
39    local smp="$3"
40    local kernel="$4"
41    local opts="$5"
42    local arch="$6"
43    local check="${CHECK:-$7}"
44    local accel="${ACCEL:-$8}"
45    local timeout="${9:-$TIMEOUT}" # unittests.cfg overrides the default
46
47    if [ -z "$testname" ]; then
48        return
49    fi
50
51    if [ -n "$only_group" ] && ! grep -q "$only_group" <<<$groups; then
52        return
53    fi
54
55    if [ -n "$arch" ] && [ "$arch" != "$ARCH" ]; then
56        echo "`SKIP` $1 ($arch only)"
57        return 2
58    fi
59
60    # check a file for a particular value before running a test
61    # the check line can contain multiple files to check separated by a space
62    # but each check parameter needs to be of the form <path>=<value>
63    for check_param in ${check[@]}; do
64        path=${check_param%%=*}
65        value=${check_param#*=}
66        if [ "$path" ] && [ "$(cat $path)" != "$value" ]; then
67            echo "`SKIP` $1 ($path not equal to $value)"
68            return 2
69        fi
70    done
71
72    last_line=$(premature_failure) && {
73        echo "`SKIP` $1 ($last_line)"
74        return 77
75    }
76
77    cmdline=$(get_cmdline $kernel)
78    if [ "$verbose" = "yes" ]; then
79        echo $cmdline
80    fi
81
82    # extra_params in the config file may contain backticks that need to be
83    # expanded, so use eval to start qemu.  Use "> >(foo)" instead of a pipe to
84    # preserve the exit status.
85    summary=$(eval $cmdline 2> >(RUNTIME_log_stderr) \
86                             > >(tee >(RUNTIME_log_stdout $kernel) | extract_summary))
87    ret=$?
88
89    if [ $ret -eq 0 ]; then
90        echo "`PASS` $1 $summary"
91    elif [ $ret -eq 77 ]; then
92        echo "`SKIP` $1 $summary"
93    elif [ $ret -eq 124 ]; then
94        echo "`FAIL` $1 (timeout; duration=$timeout)"
95    else
96        echo "`FAIL` $1 $summary"
97    fi
98
99    return $ret
100}
101
102#
103# Probe for MAX_SMP, in case it's less than the number of host cpus.
104#
105# This probing currently only works for ARM, as x86 bails on another
106# error first. Also, this probing isn't necessary for any ARM hosts
107# running kernels later than v4.3, i.e. those including ef748917b52
108# "arm/arm64: KVM: Remove 'config KVM_ARM_MAX_VCPUS'". So, at some
109# point when maintaining the while loop gets too tiresome, we can
110# just remove it...
111while $RUNTIME_arch_run _NO_FILE_4Uhere_ -smp $MAX_SMP \
112		|& grep -qi 'exceeds max CPUs'; do
113	((--MAX_SMP))
114done
115