: "${RUNTIME_arch_run?}" : ${MAX_SMP:=$(getconf _NPROCESSORS_CONF)} : ${TIMEOUT:=90s} PASS() { echo -ne "\e[32mPASS\e[0m"; } SKIP() { echo -ne "\e[33mSKIP\e[0m"; } FAIL() { echo -ne "\e[31mFAIL\e[0m"; } extract_summary() { local cr=$'\r' tail -3 | grep '^SUMMARY: ' | sed 's/^SUMMARY: /(/;s/'"$cr"'\{0,1\}$/)/' } # We assume that QEMU is going to work if it tried to load the kernel premature_failure() { local log="$(eval $(get_cmdline _NO_FILE_4Uhere_) 2>&1)" echo "$log" | grep "_NO_FILE_4Uhere_" | grep -q -e "could not load kernel" -e "error loading" && return 1 RUNTIME_log_stderr <<< "$log" echo "$log" return 0 } get_cmdline() { local kernel=$1 echo "TESTNAME=$testname TIMEOUT=$timeout ACCEL=$accel $RUNTIME_arch_run $kernel -smp $smp $opts" } skip_nodefault() { [ "$run_all_tests" = "yes" ] && return 1 [ "$STANDALONE" != "yes" ] && return 0 while true; do read -r -p "Test marked not to be run by default, are you sure (y/N)? " yn case $yn in "Y" | "y" | "Yes" | "yes") return 1 ;; "" | "N" | "n" | "No" | "no" | "q" | "quit" | "exit") return 0 ;; esac done } function run() { local testname="$1" local groups="$2" local smp="$3" local kernel="$4" local opts="$5" local arch="$6" local check="${CHECK:-$7}" local accel="${ACCEL:-$8}" local timeout="${9:-$TIMEOUT}" # unittests.cfg overrides the default if [ -z "$testname" ]; then return fi if [ -n "$only_group" ] && ! grep -qw "$only_group" <<<$groups; then return fi if [ -z "$only_group" ] && grep -qw "nodefault" <<<$groups && skip_nodefault; then echo -e "`SKIP` $testname (test marked as manual run only)" return; fi if [ -n "$arch" ] && [ "$arch" != "$ARCH" ]; then echo "`SKIP` $1 ($arch only)" return 2 fi # check a file for a particular value before running a test # the check line can contain multiple files to check separated by a space # but each check parameter needs to be of the form = for check_param in "${check[@]}"; do path=${check_param%%=*} value=${check_param#*=} if [ "$path" ] && [ "$(cat $path)" != "$value" ]; then echo "`SKIP` $1 ($path not equal to $value)" return 2 fi done last_line=$(premature_failure > >(tail -1)) && { echo "`SKIP` $1 ($last_line)" return 77 } cmdline=$(get_cmdline $kernel) if grep -qw "migration" <<<$groups ; then cmdline="MIGRATION=yes $cmdline" fi if [ "$verbose" = "yes" ]; then echo $cmdline fi # extra_params in the config file may contain backticks that need to be # expanded, so use eval to start qemu. Use "> >(foo)" instead of a pipe to # preserve the exit status. summary=$(eval $cmdline 2> >(RUNTIME_log_stderr) \ > >(tee >(RUNTIME_log_stdout $kernel) | extract_summary)) ret=$? [ "$STANDALONE" != "yes" ] && echo > >(RUNTIME_log_stdout $kernel) if [ $ret -eq 0 ]; then echo "`PASS` $1 $summary" elif [ $ret -eq 77 ]; then echo "`SKIP` $1 $summary" elif [ $ret -eq 124 ]; then echo "`FAIL` $1 (timeout; duration=$timeout)" elif [ $ret -gt 127 ]; then echo "`FAIL` $1 (terminated on SIG$(kill -l $(($ret - 128))))" else echo "`FAIL` $1 $summary" fi return $ret } # # Probe for MAX_SMP, in case it's less than the number of host cpus. # # This probing currently only works for ARM, as x86 bails on another # error first. Also, this probing isn't necessary for any ARM hosts # running kernels later than v4.3, i.e. those including ef748917b52 # "arm/arm64: KVM: Remove 'config KVM_ARM_MAX_VCPUS'". So, at some # point when maintaining the while loop gets too tiresome, we can # just remove it... while $RUNTIME_arch_run _NO_FILE_4Uhere_ -smp $MAX_SMP \ |& grep -qi 'exceeds max CPUs'; do MAX_SMP=$((MAX_SMP >> 1)) done