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 -5 | 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 19 20 log="$(eval "$(get_cmdline _NO_FILE_4Uhere_)" 2>&1)" 21 22 echo "$log" | grep "_NO_FILE_4Uhere_" | 23 grep -q -e "[Cc]ould not \(load\|open\) kernel" \ 24 -e "error loading" \ 25 -e "failed to load" && 26 return 1 27 28 RUNTIME_log_stderr <<< "$log" 29 30 echo "$log" 31 return 0 32} 33 34get_cmdline() 35{ 36 local kernel=$1 37 echo "TESTNAME=$testname TIMEOUT=$timeout MACHINE=$machine ACCEL=$accel $RUNTIME_arch_run $kernel -smp $smp $opts" 38} 39 40skip_nodefault() 41{ 42 [ "$run_all_tests" = "yes" ] && return 1 43 [ "$KUT_STANDALONE" != "yes" ] && return 0 44 45 while true; do 46 read -r -p "Test marked not to be run by default, are you sure (y/N)? " yn 47 case $yn in 48 "Y" | "y" | "Yes" | "yes") 49 return 1 50 ;; 51 "" | "N" | "n" | "No" | "no" | "q" | "quit" | "exit") 52 return 0 53 ;; 54 esac 55 done 56} 57 58function print_result() 59{ 60 local status="$1" 61 local testname="$2" 62 local summary="$3" 63 local reason="$4" 64 65 if [ -z "$reason" ]; then 66 echo "$($status) $testname $summary" 67 else 68 echo "$($status) $testname ($reason)" 69 fi 70} 71 72function find_word() 73{ 74 grep -Fq " $1 " <<< " $2 " 75} 76 77function run() 78{ 79 local testname="$1" 80 local groups="$2" 81 local smp="$3" 82 local kernel="$4" 83 local test_args="$5" 84 local opts="$6" 85 local arch="$7" 86 local machine="$8" 87 local check="${CHECK:-$9}" 88 local accel="${10}" 89 local timeout="${11:-$TIMEOUT}" # unittests.cfg overrides the default 90 91 # If $test_args is empty, qemu will interpret the first option after -append 92 # as a test argument instead of a qemu option, so make sure that doesn't 93 # happen. 94 [ -n "$test_args" ] && opts="-append $test_args $opts" 95 96 if [ "${CONFIG_EFI}" == "y" ]; then 97 kernel=${kernel/%.flat/.efi} 98 fi 99 100 if [ -z "$testname" ]; then 101 return 102 fi 103 104 if [ -n "$only_tests" ] && ! find_word "$testname" "$only_tests"; then 105 return 106 fi 107 108 if [ -n "$only_group" ] && ! find_word "$only_group" "$groups"; then 109 return 110 fi 111 112 if [ -z "$GEN_SE_HEADER" ] && find_word "pv-host" "$groups"; then 113 print_result "SKIP" $testname "" "no gen-se-header available for pv-host test" 114 return 115 fi 116 117 if [ -z "$only_group" ] && find_word nodefault "$groups" && 118 skip_nodefault; then 119 print_result "SKIP" $testname "" "test marked as manual run only" 120 return; 121 fi 122 123 if [ -n "$arch" ] && [ "$arch" != "$ARCH" ]; then 124 print_result "SKIP" $testname "" "$arch only" 125 return 2 126 fi 127 128 if [ -n "$machine" ] && [ -n "$MACHINE" ] && [ "$machine" != "$MACHINE" ]; then 129 print_result "SKIP" $testname "" "$machine only" 130 return 2 131 elif [ -n "$MACHINE" ]; then 132 machine="$MACHINE" 133 fi 134 135 if [ -n "$accel" ] && [ -n "$ACCEL" ] && [[ ! "$ACCEL" =~ ^$accel(,|$) ]]; then 136 print_result "SKIP" $testname "" "$accel only, but ACCEL=$ACCEL" 137 return 2 138 elif [ -n "$ACCEL" ]; then 139 accel="$ACCEL" 140 fi 141 142 # check a file for a particular value before running a test 143 # the check line can contain multiple files to check separated by a space 144 # but each check parameter needs to be of the form <path>=<value> 145 if [ "$check" ]; then 146 # There is no globbing or whitespace allowed in check parameters. 147 # shellcheck disable=SC2206 148 check=($check) 149 for check_param in "${check[@]}"; do 150 path=${check_param%%=*} 151 value=${check_param#*=} 152 if ! [ -f "$path" ] || [ "$(cat $path)" != "$value" ]; then 153 print_result "SKIP" $testname "" "$path not equal to $value" 154 return 2 155 fi 156 done 157 fi 158 159 log=$(premature_failure) && { 160 skip=true 161 if [ "${CONFIG_EFI}" == "y" ]; then 162 if [ "$ARCH" == "x86_64" ] && 163 [[ "$(tail -1 <<<"$log")" =~ "Dummy Hello World!" ]]; then 164 skip=false 165 elif [ "$ARCH" == "arm64" ] && 166 [[ "$(tail -2 <<<"$log" | head -1)" =~ "Dummy Hello World!" ]]; then 167 skip=false 168 fi 169 fi 170 171 if [ ${skip} == true ]; then 172 print_result "SKIP" $testname "" "$(tail -1 <<<"$log")" 173 return 77 174 fi 175 } 176 177 cmdline=$(get_cmdline $kernel) 178 if find_word "migration" "$groups"; then 179 cmdline="MIGRATION=yes $cmdline" 180 fi 181 if find_word "panic" "$groups"; then 182 cmdline="PANIC=yes $cmdline" 183 fi 184 if [ "$verbose" = "yes" ]; then 185 echo $cmdline 186 fi 187 188 # qemu_params/extra_params in the config file may contain backticks that 189 # need to be expanded, so use eval to start qemu. Use "> >(foo)" instead of 190 # a pipe to preserve the exit status. 191 summary=$(eval "$cmdline" 2> >(RUNTIME_log_stderr $testname) \ 192 > >(tee >(RUNTIME_log_stdout $testname $kernel) | extract_summary)) 193 ret=$? 194 [ "$KUT_STANDALONE" != "yes" ] && echo > >(RUNTIME_log_stdout $testname $kernel) 195 196 if [ $ret -eq 0 ]; then 197 print_result "PASS" $testname "$summary" 198 elif [ $ret -eq 77 ]; then 199 print_result "SKIP" $testname "$summary" 200 elif [ $ret -eq 124 ]; then 201 print_result "FAIL" $testname "" "timeout; duration=$timeout" 202 if [ "$tap_output" = "yes" ]; then 203 echo "not ok TEST_NUMBER - ${testname}: timeout; duration=$timeout" >&3 204 fi 205 elif [ $ret -gt 127 ]; then 206 signame="SIG"$(kill -l $(($ret - 128))) 207 print_result "FAIL" $testname "" "terminated on $signame" 208 if [ "$tap_output" = "yes" ]; then 209 echo "not ok TEST_NUMBER - ${testname}: terminated on $signame" >&3 210 fi 211 elif [ $ret -eq 127 ] && [ "$tap_output" = "yes" ]; then 212 echo "not ok TEST_NUMBER - ${testname}: aborted" >&3 213 else 214 print_result "FAIL" $testname "$summary" 215 fi 216 217 return $ret 218} 219 220# 221# Probe for MAX_SMP, in case it's less than the number of host cpus. 222# 223function probe_maxsmp() 224{ 225 local smp 226 227 if smp=$($RUNTIME_arch_run _NO_FILE_4Uhere_ -smp $MAX_SMP |& grep 'SMP CPUs'); then 228 smp=${smp##* } 229 smp=${smp/\(} 230 smp=${smp/\)} 231 echo "Restricting MAX_SMP from ($MAX_SMP) to the max supported ($smp)" >&2 232 MAX_SMP=$smp 233 fi 234} 235