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