xref: /kvm-unit-tests/scripts/runtime.bash (revision 4363f1d9a646a5c7ea673bee8fc33ca6f2cddbd8)
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 -3 | 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
35skip_nodefault()
36{
37    [ "$run_all_tests" = "yes" ] && return 1
38    [ "$STANDALONE" != "yes" ] && return 0
39
40    while true; do
41        read -r -p "Test marked not to be run by default, are you sure (y/N)? " yn
42        case $yn in
43            "Y" | "y" | "Yes" | "yes")
44                return 1
45                ;;
46            "" | "N" | "n" | "No" | "no" | "q" | "quit" | "exit")
47                return 0
48                ;;
49        esac
50    done
51}
52
53function run()
54{
55    local testname="$1"
56    local groups="$2"
57    local smp="$3"
58    local kernel="$4"
59    local opts="$5"
60    local arch="$6"
61    local check="${CHECK:-$7}"
62    local accel="${ACCEL:-$8}"
63    local timeout="${9:-$TIMEOUT}" # unittests.cfg overrides the default
64
65    if [ -z "$testname" ]; then
66        return
67    fi
68
69    if [ -n "$only_group" ] && ! grep -qw "$only_group" <<<$groups; then
70        return
71    fi
72
73    if [ -z "$only_group" ] && grep -qw "nodefault" <<<$groups &&
74            skip_nodefault; then
75        echo -e "`SKIP` $testname (test marked as manual run only)"
76        return;
77    fi
78
79    if [ -n "$arch" ] && [ "$arch" != "$ARCH" ]; then
80        echo "`SKIP` $1 ($arch only)"
81        return 2
82    fi
83
84    # check a file for a particular value before running a test
85    # the check line can contain multiple files to check separated by a space
86    # but each check parameter needs to be of the form <path>=<value>
87    for check_param in "${check[@]}"; do
88        path=${check_param%%=*}
89        value=${check_param#*=}
90        if [ "$path" ] && [ "$(cat $path)" != "$value" ]; then
91            echo "`SKIP` $1 ($path not equal to $value)"
92            return 2
93        fi
94    done
95
96    last_line=$(premature_failure > >(tail -1)) && {
97        echo "`SKIP` $1 ($last_line)"
98        return 77
99    }
100
101    cmdline=$(get_cmdline $kernel)
102    if grep -qw "migration" <<<$groups ; then
103        cmdline="MIGRATION=yes $cmdline"
104    fi
105    if [ "$verbose" = "yes" ]; then
106        echo $cmdline
107    fi
108
109    # extra_params in the config file may contain backticks that need to be
110    # expanded, so use eval to start qemu.  Use "> >(foo)" instead of a pipe to
111    # preserve the exit status.
112    summary=$(eval $cmdline 2> >(RUNTIME_log_stderr) \
113                             > >(tee >(RUNTIME_log_stdout $kernel) | extract_summary))
114    ret=$?
115    [ "$STANDALONE" != "yes" ] && echo > >(RUNTIME_log_stdout $kernel)
116
117    if [ $ret -eq 0 ]; then
118        echo "`PASS` $1 $summary"
119    elif [ $ret -eq 77 ]; then
120        echo "`SKIP` $1 $summary"
121    elif [ $ret -eq 124 ]; then
122        echo "`FAIL` $1 (timeout; duration=$timeout)"
123    elif [ $ret -gt 127 ]; then
124        echo "`FAIL` $1 (terminated on SIG$(kill -l $(($ret - 128))))"
125    else
126        echo "`FAIL` $1 $summary"
127    fi
128
129    return $ret
130}
131
132#
133# Probe for MAX_SMP, in case it's less than the number of host cpus.
134#
135# This probing currently only works for ARM, as x86 bails on another
136# error first. Also, this probing isn't necessary for any ARM hosts
137# running kernels later than v4.3, i.e. those including ef748917b52
138# "arm/arm64: KVM: Remove 'config KVM_ARM_MAX_VCPUS'". So, at some
139# point when maintaining the while loop gets too tiresome, we can
140# just remove it...
141while $RUNTIME_arch_run _NO_FILE_4Uhere_ -smp $MAX_SMP \
142		|& grep -qi 'exceeds max CPUs'; do
143	((--MAX_SMP))
144done
145