1#!/usr/bin/env bash 2 3verbose="no" 4tap_output="no" 5run_all_tests="no" # don't run nodefault tests 6 7if [ ! -f config.mak ]; then 8 echo "run ./configure && make first. See ./configure -h" 9 exit 1 10fi 11source config.mak 12source scripts/common.bash 13 14function usage() 15{ 16cat <<EOF 17 18Usage: $0 [-h] [-v] [-a] [-g group] [-j NUM-TASKS] [-t] [-l] 19 20 -h, --help Output this help text 21 -v, --verbose Enables verbose mode 22 -a, --all Run all tests, including those flagged as 'nodefault' 23 and those guarded by errata. 24 -g, --group Only execute tests in the given group 25 -j, --parallel Execute tests in parallel 26 -t, --tap13 Output test results in TAP format 27 -l, --list Only output all tests list 28 29Set the environment variable QEMU=/path/to/qemu-system-ARCH to 30specify the appropriate qemu binary for ARCH-run. 31 32EOF 33} 34 35RUNTIME_arch_run="./$TEST_SUBDIR/run" 36source scripts/runtime.bash 37 38# require enhanced getopt 39getopt -T > /dev/null 40if [ $? -ne 4 ]; then 41 echo "Enhanced getopt is not available, add it to your PATH?" 42 exit 1 43fi 44 45only_tests="" 46list_tests="" 47args=$(getopt -u -o ag:htj:vl -l all,group:,help,tap13,parallel:,verbose,list,probe-maxsmp -- "$@") 48# Shellcheck likes to test commands directly rather than with $? but sometimes they 49# are too long to put in the same test. 50# shellcheck disable=SC2181 51[ $? -ne 0 ] && exit 2; 52set -- $args; 53while [ $# -gt 0 ]; do 54 case "$1" in 55 -a | --all) 56 run_all_tests="yes" 57 export ERRATA_FORCE=y 58 ;; 59 -g | --group) 60 shift 61 only_group=$1 62 ;; 63 -h | --help) 64 usage 65 exit 66 ;; 67 -j | --parallel) 68 shift 69 unittest_run_queues=$1 70 if (( $unittest_run_queues <= 0 )); then 71 echo "Invalid -j option: $unittest_run_queues" 72 exit 2 73 fi 74 ;; 75 -v | --verbose) 76 verbose="yes" 77 ;; 78 -t | --tap13) 79 tap_output="yes" 80 ;; 81 -l | --list) 82 list_tests="yes" 83 ;; 84 --probe-maxsmp) 85 probe_maxsmp 86 ;; 87 --) 88 ;; 89 *) 90 only_tests="$only_tests $1" 91 ;; 92 esac 93 shift 94done 95 96# RUNTIME_log_file will be configured later 97if [[ $tap_output == "no" ]]; then 98 process_test_output() { cat >> $RUNTIME_log_file; } 99 postprocess_suite_output() { cat; } 100else 101 process_test_output() { 102 local testname="$1" 103 CR=$'\r' 104 while read -r line; do 105 line="${line%"$CR"}" 106 case "${line:0:4}" in 107 PASS) 108 echo "ok TEST_NUMBER - ${testname}: ${line#??????}" >&3 109 ;; 110 FAIL) 111 echo "not ok TEST_NUMBER - ${testname}: ${line#??????}" >&3 112 ;; 113 SKIP) 114 echo "ok TEST_NUMBER - ${testname}: ${line#??????} # skip" >&3 115 ;; 116 *) 117 ;; 118 esac 119 echo "${line}" 120 done >> $RUNTIME_log_file 121 } 122 postprocess_suite_output() { 123 test_number=0 124 while read -r line; do 125 case "${line}" in 126 ok*|"not ok"*) 127 (( test_number++ )) 128 echo "${line/TEST_NUMBER/${test_number}}" ;; 129 *) echo "${line}" ;; 130 esac 131 done 132 echo "1..$test_number" 133 } 134fi 135 136RUNTIME_log_stderr () { process_test_output "$1"; } 137RUNTIME_log_stdout () { 138 local testname="$1" 139 if [ "$PRETTY_PRINT_STACKS" = "yes" ]; then 140 local kernel="$2" 141 ./scripts/pretty_print_stacks.py "$kernel" | process_test_output "$testname" 142 else 143 process_test_output "$testname" 144 fi 145} 146 147function run_task() 148{ 149 local testname="$1" 150 151 while (( $(jobs | wc -l) == $unittest_run_queues )); do 152 # wait for any background test to finish 153 wait -n 2>/dev/null 154 done 155 156 RUNTIME_log_file="${unittest_log_dir}/${testname}.log" 157 if [ $unittest_run_queues = 1 ]; then 158 run "$@" 159 else 160 run "$@" & 161 fi 162} 163 164: "${unittest_log_dir:=logs}" 165: "${unittest_run_queues:=1}" 166config=$TEST_DIR/unittests.cfg 167 168print_testname() 169{ 170 local testname=$1 171 local groups=$2 172 if [ -n "$only_group" ] && ! find_word "$only_group" "$groups"; then 173 return 174 fi 175 echo "$testname" 176} 177if [[ $list_tests == "yes" ]]; then 178 for_each_unittest $config print_testname 179 exit 180fi 181 182rm -rf $unittest_log_dir.old 183[ -d $unittest_log_dir ] && mv $unittest_log_dir $unittest_log_dir.old 184mkdir $unittest_log_dir || exit 2 185 186echo "BUILD_HEAD=$(cat build-head)" > $unittest_log_dir/SUMMARY 187 188if [[ $tap_output == "yes" ]]; then 189 echo "TAP version 13" 190fi 191 192trap "wait; exit 130" SIGINT 193 194( 195 # preserve stdout so that process_test_output output can write TAP to it 196 exec 3>&1 197 test "$tap_output" == "yes" && exec > /dev/null 198 for_each_unittest $config run_task 199) | postprocess_suite_output 200 201# wait until all tasks finish 202wait 203