1: "${RUNTIME_arch_run?}" 2: ${MAX_SMP:=$(getconf _NPROCESSORS_ONLN)} 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 local cr=$'\r' 12 tail -3 | grep '^SUMMARY: ' | sed 's/^SUMMARY: /(/;s/'"$cr"'\{0,1\}$/)/' 13} 14 15# We assume that QEMU is going to work if it tried to load the kernel 16premature_failure() 17{ 18 local log="$(eval $(get_cmdline _NO_FILE_4Uhere_) 2>&1)" 19 20 echo "$log" | grep "_NO_FILE_4Uhere_" | 21 grep -q -e "could not \(load\|open\) kernel" -e "error loading" && 22 return 1 23 24 RUNTIME_log_stderr <<< "$log" 25 26 echo "$log" 27 return 0 28} 29 30get_cmdline() 31{ 32 local kernel=$1 33 echo "TESTNAME=$testname TIMEOUT=$timeout ACCEL=$accel $RUNTIME_arch_run $kernel -smp $smp $opts" 34} 35 36skip_nodefault() 37{ 38 [ "$run_all_tests" = "yes" ] && return 1 39 [ "$STANDALONE" != "yes" ] && return 0 40 41 while true; do 42 read -r -p "Test marked not to be run by default, are you sure (y/N)? " yn 43 case $yn in 44 "Y" | "y" | "Yes" | "yes") 45 return 1 46 ;; 47 "" | "N" | "n" | "No" | "no" | "q" | "quit" | "exit") 48 return 0 49 ;; 50 esac 51 done 52} 53 54function print_result() 55{ 56 # output test results in a TAP format 57 # https://testanything.org/tap-version-13-specification.html 58 59 local status="$1" 60 local testname="$2" 61 local summary="$3" 62 local reason="$4" 63 64 if [ -z "$reason" ]; then 65 echo "`$status` $testname $summary" 66 else 67 echo "`$status` $testname ($reason)" 68 fi 69} 70 71function find_word() 72{ 73 grep -Fq " $1 " <<< " $2 " 74} 75 76function run() 77{ 78 local testname="$1" 79 local groups="$2" 80 local smp="$3" 81 local kernel="$4" 82 local opts="$5" 83 local arch="$6" 84 local check="${CHECK:-$7}" 85 local accel="$8" 86 local timeout="${9:-$TIMEOUT}" # unittests.cfg overrides the default 87 88 if [ -z "$testname" ]; then 89 return 90 fi 91 92 if [ -n "$only_tests" ] && ! find_word "$testname" "$only_tests"; then 93 return 94 fi 95 96 if [ -n "$only_group" ] && ! find_word "$only_group" "$groups"; then 97 return 98 fi 99 100 if [ -z "$only_group" ] && find_word nodefault "$groups" && 101 skip_nodefault; then 102 print_result "SKIP" $testname "" "test marked as manual run only" 103 return; 104 fi 105 106 if [ -n "$arch" ] && [ "$arch" != "$ARCH" ]; then 107 print_result "SKIP" $testname "" "$arch only" 108 return 2 109 fi 110 111 if [ -n "$accel" ] && [ -n "$ACCEL" ] && [ "$accel" != "$ACCEL" ]; then 112 print_result "SKIP" $testname "" "$accel only, but ACCEL=$ACCEL" 113 return 2 114 elif [ -n "$ACCEL" ]; then 115 accel="$ACCEL" 116 fi 117 118 # check a file for a particular value before running a test 119 # the check line can contain multiple files to check separated by a space 120 # but each check parameter needs to be of the form <path>=<value> 121 for check_param in "${check[@]}"; do 122 path=${check_param%%=*} 123 value=${check_param#*=} 124 if [ "$path" ] && [ "$(cat $path)" != "$value" ]; then 125 print_result "SKIP" $testname "" "$path not equal to $value" 126 return 2 127 fi 128 done 129 130 last_line=$(premature_failure > >(tail -1)) && { 131 print_result "SKIP" $testname "" "$last_line" 132 return 77 133 } 134 135 cmdline=$(get_cmdline $kernel) 136 if grep -qw "migration" <<<$groups ; then 137 cmdline="MIGRATION=yes $cmdline" 138 fi 139 if [ "$verbose" = "yes" ]; then 140 echo $cmdline 141 fi 142 143 # extra_params in the config file may contain backticks that need to be 144 # expanded, so use eval to start qemu. Use "> >(foo)" instead of a pipe to 145 # preserve the exit status. 146 summary=$(eval $cmdline 2> >(RUNTIME_log_stderr) \ 147 > >(tee >(RUNTIME_log_stdout $kernel) | extract_summary)) 148 ret=$? 149 [ "$STANDALONE" != "yes" ] && echo > >(RUNTIME_log_stdout $kernel) 150 151 if [ $ret -eq 0 ]; then 152 print_result "PASS" $testname "$summary" 153 elif [ $ret -eq 77 ]; then 154 print_result "SKIP" $testname "$summary" 155 elif [ $ret -eq 124 ]; then 156 print_result "FAIL" $testname "" "timeout; duration=$timeout" 157 elif [ $ret -gt 127 ]; then 158 print_result "FAIL" $testname "" "terminated on SIG$(kill -l $(($ret - 128)))" 159 else 160 print_result "FAIL" $testname "$summary" 161 fi 162 163 return $ret 164} 165 166# 167# Probe for MAX_SMP, in case it's less than the number of host cpus. 168# 169# This probing currently only works for ARM, as x86 bails on another 170# error first. Also, this probing isn't necessary for any ARM hosts 171# running kernels later than v4.3, i.e. those including ef748917b52 172# "arm/arm64: KVM: Remove 'config KVM_ARM_MAX_VCPUS'". So, at some 173# point when maintaining the while loop gets too tiresome, we can 174# just remove it... 175while $RUNTIME_arch_run _NO_FILE_4Uhere_ -smp $MAX_SMP \ 176 |& grep -qi 'exceeds max CPUs'; do 177 MAX_SMP=$((MAX_SMP >> 1)) 178done 179