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 [ "$KUT_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 local status="$1" 57 local testname="$2" 58 local summary="$3" 59 local reason="$4" 60 61 if [ -z "$reason" ]; then 62 echo "`$status` $testname $summary" 63 else 64 echo "`$status` $testname ($reason)" 65 fi 66} 67 68function find_word() 69{ 70 grep -Fq " $1 " <<< " $2 " 71} 72 73function run() 74{ 75 local testname="$1" 76 local groups="$2" 77 local smp="$3" 78 local kernel="$4" 79 local opts="$5" 80 local arch="$6" 81 local check="${CHECK:-$7}" 82 local accel="$8" 83 local timeout="${9:-$TIMEOUT}" # unittests.cfg overrides the default 84 85 if [ "${CONFIG_EFI}" == "y" ]; then 86 kernel=${kernel/%.flat/.efi} 87 fi 88 89 if [ -z "$testname" ]; then 90 return 91 fi 92 93 if [ -n "$only_tests" ] && ! find_word "$testname" "$only_tests"; then 94 return 95 fi 96 97 if [ -n "$only_group" ] && ! find_word "$only_group" "$groups"; then 98 return 99 fi 100 101 if [ -z "$GEN_SE_HEADER" ] && find_word "pv-host" "$groups"; then 102 print_result "SKIP" $testname "" "no gen-se-header available for pv-host test" 103 return 104 fi 105 106 if [ -z "$only_group" ] && find_word nodefault "$groups" && 107 skip_nodefault; then 108 print_result "SKIP" $testname "" "test marked as manual run only" 109 return; 110 fi 111 112 if [ -n "$arch" ] && [ "$arch" != "$ARCH" ]; then 113 print_result "SKIP" $testname "" "$arch only" 114 return 2 115 fi 116 117 if [ -n "$accel" ] && [ -n "$ACCEL" ] && [ "$accel" != "$ACCEL" ]; then 118 print_result "SKIP" $testname "" "$accel only, but ACCEL=$ACCEL" 119 return 2 120 elif [ -n "$ACCEL" ]; then 121 accel="$ACCEL" 122 fi 123 124 # check a file for a particular value before running a test 125 # the check line can contain multiple files to check separated by a space 126 # but each check parameter needs to be of the form <path>=<value> 127 if [ "$check" ]; then 128 for check_param in "${check[@]}"; do 129 path=${check_param%%=*} 130 value=${check_param#*=} 131 if ! [ -f "$path" ] || [ "$(cat $path)" != "$value" ]; then 132 print_result "SKIP" $testname "" "$path not equal to $value" 133 return 2 134 fi 135 done 136 fi 137 138 log=$(premature_failure) && { 139 skip=true 140 if [ "${CONFIG_EFI}" == "y" ]; then 141 if [ "$ARCH" == "x86_64" ] && 142 [[ "$(tail -1 <<<"$log")" =~ "Dummy Hello World!" ]]; then 143 skip=false 144 elif [ "$ARCH" == "arm64" ] && 145 [[ "$(tail -2 <<<"$log" | head -1)" =~ "Dummy Hello World!" ]]; then 146 skip=false 147 fi 148 fi 149 150 if [ ${skip} == true ]; then 151 print_result "SKIP" $testname "" "$last_line" 152 return 77 153 fi 154 } 155 156 cmdline=$(get_cmdline $kernel) 157 if find_word "migration" "$groups"; then 158 cmdline="MIGRATION=yes $cmdline" 159 fi 160 if find_word "panic" "$groups"; then 161 cmdline="PANIC=yes $cmdline" 162 fi 163 if [ "$verbose" = "yes" ]; then 164 echo $cmdline 165 fi 166 167 # extra_params in the config file may contain backticks that need to be 168 # expanded, so use eval to start qemu. Use "> >(foo)" instead of a pipe to 169 # preserve the exit status. 170 summary=$(eval $cmdline 2> >(RUNTIME_log_stderr $testname) \ 171 > >(tee >(RUNTIME_log_stdout $testname $kernel) | extract_summary)) 172 ret=$? 173 [ "$KUT_STANDALONE" != "yes" ] && echo > >(RUNTIME_log_stdout $testname $kernel) 174 175 if [ $ret -eq 0 ]; then 176 print_result "PASS" $testname "$summary" 177 elif [ $ret -eq 77 ]; then 178 print_result "SKIP" $testname "$summary" 179 elif [ $ret -eq 124 ]; then 180 print_result "FAIL" $testname "" "timeout; duration=$timeout" 181 if [ "$tap_output" = "yes" ]; then 182 echo "not ok TEST_NUMBER - ${testname}: timeout; duration=$timeout" >&3 183 fi 184 elif [ $ret -gt 127 ]; then 185 signame="SIG"$(kill -l $(($ret - 128))) 186 print_result "FAIL" $testname "" "terminated on $signame" 187 if [ "$tap_output" = "yes" ]; then 188 echo "not ok TEST_NUMBER - ${testname}: terminated on $signame" >&3 189 fi 190 elif [ $ret -eq 127 ] && [ "$tap_output" = "yes" ]; then 191 echo "not ok TEST_NUMBER - ${testname}: aborted" >&3 192 else 193 print_result "FAIL" $testname "$summary" 194 fi 195 196 return $ret 197} 198 199# 200# Probe for MAX_SMP, in case it's less than the number of host cpus. 201# 202# This probing currently only works for ARM, as x86 bails on another 203# error first, so this check is only run for ARM and ARM64. The 204# parameter expansion takes the last number from the QEMU error 205# message, which gives the allowable MAX_SMP. 206if [[ $ARCH == 'arm' || $ARCH == 'arm64' ]] && 207 smp=$($RUNTIME_arch_run _NO_FILE_4Uhere_ -smp $MAX_SMP |& grep 'exceeds max CPUs'); then 208 smp=${smp##*(} 209 MAX_SMP=${smp:0:-1} 210fi 211