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 vmm_parse_premature_failure "$log" || 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 MACHINE=$machine ACCEL=$accel $RUNTIME_arch_run $kernel $smp $test_args $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 test_args="$5" 80 local opts="$6" 81 local arch="$7" 82 local machine="$8" 83 local check="${CHECK:-$9}" 84 local accel="${10}" 85 local timeout="${11:-$TIMEOUT}" # unittests.cfg overrides the default 86 local disabled_if="${12}" 87 88 if [ "${CONFIG_EFI}" == "y" ]; then 89 kernel=${kernel/%.flat/.efi} 90 fi 91 92 if [ -z "$testname" ]; then 93 return 94 fi 95 96 if [ -n "$only_tests" ] && ! find_word "$testname" "$only_tests"; then 97 return 98 fi 99 100 if [ -n "$only_group" ] && ! find_word "$only_group" "$groups"; then 101 return 102 fi 103 104 if [ -z "$GEN_SE_HEADER" ] && find_word "pv-host" "$groups"; then 105 print_result "SKIP" $testname "" "no gen-se-header available for pv-host test" 106 return 107 fi 108 109 if [ -z "$only_group" ] && find_word nodefault "$groups" && 110 skip_nodefault; then 111 print_result "SKIP" $testname "" "test marked as manual run only" 112 return; 113 fi 114 115 if [ -n "$arch" ] && [ "$arch" != "$ARCH" ]; then 116 print_result "SKIP" $testname "" "$arch only" 117 return 2 118 fi 119 120 if [ -n "$machine" ] && [ -n "$MACHINE" ] && [ "$machine" != "$MACHINE" ]; then 121 print_result "SKIP" $testname "" "$machine only" 122 return 2 123 elif [ -n "$MACHINE" ]; then 124 machine="$MACHINE" 125 fi 126 127 if [ -n "$accel" ] && [ -n "$ACCEL" ] && [[ ! "$ACCEL" =~ ^$accel(,|$) ]]; then 128 print_result "SKIP" $testname "" "$accel only, but ACCEL=$ACCEL" 129 return 2 130 elif [ -n "$ACCEL" ]; then 131 accel="$ACCEL" 132 fi 133 134 if [[ "$disabled_if" ]] && (eval $disabled_if); then 135 print_result "SKIP" $testname "" "disabled because: $disabled_if" 136 return 2 137 fi 138 139 # check a file for a particular value before running a test 140 # the check line can contain multiple files to check separated by a space 141 # but each check parameter needs to be of the form <path>=<value> 142 if [ "$check" ]; then 143 # There is no globbing or whitespace allowed in check parameters. 144 # shellcheck disable=SC2206 145 check=($check) 146 for check_param in "${check[@]}"; do 147 path=${check_param%%=*} 148 value=${check_param#*=} 149 if ! [ -f "$path" ] || [ "$(cat $path)" != "$value" ]; then 150 print_result "SKIP" $testname "" "$path not equal to $value" 151 return 2 152 fi 153 done 154 fi 155 156 if [ ! -f "$kernel" ]; then 157 print_result "SKIP" $testname "" "Test file '$kernel' not found"; 158 return 2; 159 fi 160 161 log=$(premature_failure) && { 162 skip=true 163 if [ "${CONFIG_EFI}" == "y" ]; then 164 if [ "$ARCH" == "x86_64" ] && 165 [[ "$(tail -1 <<<"$log")" =~ "Dummy Hello World!" ]]; then 166 skip=false 167 elif [ "$ARCH" == "arm64" ] && 168 [[ "$(tail -2 <<<"$log" | head -1)" =~ "Dummy Hello World!" ]]; then 169 skip=false 170 fi 171 fi 172 173 if [ ${skip} == true ]; then 174 print_result "SKIP" $testname "" "$(tail -1 <<<"$log")" 175 return 77 176 fi 177 } 178 179 cmdline=$(get_cmdline $kernel) 180 if find_word "migration" "$groups"; then 181 cmdline="MIGRATION=yes $cmdline" 182 fi 183 if find_word "panic" "$groups"; then 184 cmdline="PANIC=yes $cmdline" 185 fi 186 if [ "$verbose" = "yes" ]; then 187 echo $cmdline 188 fi 189 190 # qemu_params/extra_params in the config file may contain backticks that 191 # need to be expanded, so use eval to start qemu. Use "> >(foo)" instead of 192 # a pipe to preserve the exit status. 193 summary=$(eval "$cmdline" 2> >(RUNTIME_log_stderr $testname) \ 194 > >(tee >(RUNTIME_log_stdout $testname $kernel) | extract_summary)) 195 ret=$? 196 [ "$KUT_STANDALONE" != "yes" ] && echo > >(RUNTIME_log_stdout $testname $kernel) 197 198 if [ $ret -eq 0 ]; then 199 print_result "PASS" $testname "$summary" 200 elif [ $ret -eq 77 ]; then 201 print_result "SKIP" $testname "$summary" 202 elif [ $ret -eq 124 ]; then 203 print_result "FAIL" $testname "" "timeout; duration=$timeout" 204 if [ "$tap_output" = "yes" ]; then 205 echo "not ok TEST_NUMBER - ${testname}: timeout; duration=$timeout" >&3 206 fi 207 elif [ $ret -gt 127 ]; then 208 signame="SIG"$(kill -l $(($ret - 128))) 209 print_result "FAIL" $testname "" "terminated on $signame" 210 if [ "$tap_output" = "yes" ]; then 211 echo "not ok TEST_NUMBER - ${testname}: terminated on $signame" >&3 212 fi 213 elif [ $ret -eq 127 ] && [ "$tap_output" = "yes" ]; then 214 echo "not ok TEST_NUMBER - ${testname}: aborted" >&3 215 else 216 print_result "FAIL" $testname "$summary" 217 fi 218 219 return $ret 220} 221