1#!/bin/bash 2# 3# Copyright (C) 2009 Red Hat, Inc. 4# Copyright (c) 2000-2002,2006 Silicon Graphics, Inc. All Rights Reserved. 5# 6# This program is free software; you can redistribute it and/or 7# modify it under the terms of the GNU General Public License as 8# published by the Free Software Foundation. 9# 10# This program is distributed in the hope that it would be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program. If not, see <http://www.gnu.org/licenses/>. 17# 18# 19# Control script for QA 20# 21 22status=0 23needwrap=true 24try=0 25n_bad=0 26bad="" 27notrun="" 28interrupt=true 29 30# by default don't output timestamps 31timestamp=${TIMESTAMP:=false} 32 33# generic initialization 34iam=check 35 36_init_error() 37{ 38 echo "$iam: $1" >&2 39 exit 1 40} 41 42if [ -L "$0" ] 43then 44 # called from the build tree 45 source_iotests=$(dirname "$(readlink "$0")") 46 if [ -z "$source_iotests" ] 47 then 48 _init_error "failed to obtain source tree name from check symlink" 49 fi 50 source_iotests=$(cd "$source_iotests"; pwd) || _init_error "failed to enter source tree" 51 build_iotests=$PWD 52else 53 # called from the source tree 54 source_iotests=$PWD 55 # this may be an in-tree build (note that in the following code we may not 56 # assume that it truly is and have to test whether the build results 57 # actually exist) 58 build_iotests=$PWD 59fi 60 61build_root="$build_iotests/../.." 62 63if [ -x "$build_iotests/socket_scm_helper" ] 64then 65 export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper" 66fi 67 68# if ./qemu exists, it should be prioritized and will be chosen by common.config 69if [[ -z "$QEMU_PROG" && ! -x './qemu' ]] 70then 71 arch=$(uname -m 2> /dev/null) 72 73 if [[ -n $arch && -x "$build_root/$arch-softmmu/qemu-system-$arch" ]] 74 then 75 export QEMU_PROG="$build_root/$arch-softmmu/qemu-system-$arch" 76 else 77 pushd "$build_root" > /dev/null 78 for binary in *-softmmu/qemu-system-* 79 do 80 if [ -x "$binary" ] 81 then 82 export QEMU_PROG="$build_root/$binary" 83 break 84 fi 85 done 86 popd > /dev/null 87 fi 88fi 89 90if [[ -z $QEMU_IMG_PROG && -x "$build_root/qemu-img" && ! -x './qemu-img' ]] 91then 92 export QEMU_IMG_PROG="$build_root/qemu-img" 93fi 94 95if [[ -z $QEMU_IO_PROG && -x "$build_root/qemu-io" && ! -x './qemu-io' ]] 96then 97 export QEMU_IO_PROG="$build_root/qemu-io" 98fi 99 100if [[ -z $QEMU_NBD_PROG && -x "$build_root/qemu-nbd" && ! -x './qemu-nbd' ]] 101then 102 export QEMU_NBD_PROG="$build_root/qemu-nbd" 103fi 104 105# we need common.env 106if ! . "$build_iotests/common.env" 107then 108 _init_error "failed to source common.env (make sure the qemu-iotests are run from tests/qemu-iotests in the build tree)" 109fi 110 111# we need common.config 112if ! . "$source_iotests/common.config" 113then 114 _init_error "failed to source common.config" 115fi 116 117# we need common.rc 118if ! . "$source_iotests/common.rc" 119then 120 _init_error "failed to source common.rc" 121fi 122 123# we need common 124. "$source_iotests/common" 125 126TIMESTAMP_FILE=check.time-$IMGPROTO-$IMGFMT 127 128tmp="${TEST_DIR}"/$$ 129 130_wallclock() 131{ 132 date "+%H %M %S" | $AWK_PROG '{ print $1*3600 + $2*60 + $3 }' 133} 134 135_timestamp() 136{ 137 now=`date "+%T"` 138 printf %s " [$now]" 139} 140 141_wrapup() 142{ 143 # for hangcheck ... 144 # remove files that were used by hangcheck 145 # 146 [ -f "${TEST_DIR}"/check.pid ] && rm -rf "${TEST_DIR}"/check.pid 147 [ -f "${TEST_DIR}"/check.sts ] && rm -rf "${TEST_DIR}"/check.sts 148 149 if $showme 150 then 151 : 152 elif $needwrap 153 then 154 if [ -f $TIMESTAMP_FILE -a -f $tmp.time ] 155 then 156 cat $TIMESTAMP_FILE $tmp.time \ 157 | $AWK_PROG ' 158 { t[$1] = $2 } 159END { if (NR > 0) { 160 for (i in t) print i " " t[i] 161 } 162 }' \ 163 | sort -n >$tmp.out 164 mv $tmp.out $TIMESTAMP_FILE 165 fi 166 167 if [ -f $tmp.expunged ] 168 then 169 notrun=`wc -l <$tmp.expunged | sed -e 's/ *//g'` 170 try=`expr $try - $notrun` 171 list=`echo "$list" | sed -f $tmp.expunged` 172 fi 173 174 echo "" >>check.log 175 date >>check.log 176 echo $list | fmt | sed -e 's/^/ /' >>check.log 177 $interrupt && echo "Interrupted!" >>check.log 178 179 if [ ! -z "$notrun" ] 180 then 181 echo "Not run:$notrun" 182 echo "Not run:$notrun" >>check.log 183 fi 184 if [ ! -z "$n_bad" -a $n_bad != 0 ] 185 then 186 echo "Failures:$bad" 187 echo "Failed $n_bad of $try tests" 188 echo "Failures:$bad" | fmt >>check.log 189 echo "Failed $n_bad of $try tests" >>check.log 190 else 191 echo "Passed all $try tests" 192 echo "Passed all $try tests" >>check.log 193 fi 194 needwrap=false 195 fi 196 197 rm -f "${TEST_DIR}"/*.out "${TEST_DIR}"/*.err "${TEST_DIR}"/*.time 198 rm -f "${TEST_DIR}"/check.pid "${TEST_DIR}"/check.sts 199 rm -f $tmp.* 200} 201 202trap "_wrapup; exit \$status" 0 1 2 3 15 203 204# for hangcheck ... 205# Save pid of check in a well known place, so that hangcheck can be sure it 206# has the right pid (getting the pid from ps output is not reliable enough). 207# 208rm -rf "${TEST_DIR}"/check.pid 209echo $$ > "${TEST_DIR}"/check.pid 210 211# for hangcheck ... 212# Save the status of check in a well known place, so that hangcheck can be 213# sure to know where check is up to (getting test number from ps output is 214# not reliable enough since the trace stuff has been introduced). 215# 216rm -rf "${TEST_DIR}"/check.sts 217echo "preamble" > "${TEST_DIR}"/check.sts 218 219# don't leave old full output behind on a clean run 220rm -f check.full 221 222[ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE 223 224FULL_IMGFMT_DETAILS=`_full_imgfmt_details` 225FULL_HOST_DETAILS=`_full_platform_details` 226 227cat <<EOF 228QEMU -- "$QEMU_PROG" $QEMU_OPTIONS 229QEMU_IMG -- "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS 230QEMU_IO -- "$QEMU_IO_PROG" $QEMU_IO_OPTIONS 231QEMU_NBD -- "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS 232IMGFMT -- $FULL_IMGFMT_DETAILS 233IMGPROTO -- $IMGPROTO 234PLATFORM -- $FULL_HOST_DETAILS 235TEST_DIR -- $TEST_DIR 236SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER 237 238EOF 239 240seq="check" 241 242[ -n "$TESTS_REMAINING_LOG" ] && echo $list > $TESTS_REMAINING_LOG 243 244for seq in $list 245do 246 err=false 247 printf %s "$seq" 248 if [ -n "$TESTS_REMAINING_LOG" ] ; then 249 sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp 250 mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG 251 sync 252 fi 253 254 if $showme 255 then 256 echo 257 continue 258 elif [ -f expunged ] && $expunge && egrep "^$seq([ ]|\$)" expunged >/dev/null 259 then 260 echo " - expunged" 261 rm -f $seq.out.bad 262 echo "/^$seq\$/d" >>$tmp.expunged 263 elif [ ! -f "$source_iotests/$seq" ] 264 then 265 echo " - no such test?" 266 echo "/^$seq\$/d" >>$tmp.expunged 267 else 268 # really going to try and run this one 269 # 270 rm -f $seq.out.bad 271 lasttime=`sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE` 272 if [ "X$lasttime" != X ]; then 273 printf %s " ${lasttime}s ..." 274 else 275 printf " " # prettier output with timestamps. 276 fi 277 rm -f core $seq.notrun 278 279 # for hangcheck ... 280 echo "$seq" > "${TEST_DIR}"/check.sts 281 282 start=`_wallclock` 283 $timestamp && printf %s " [$(date "+%T")]" 284 285 if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then 286 run_command="$PYTHON $seq" 287 else 288 run_command="./$seq" 289 fi 290 export OUTPUT_DIR=$PWD 291 if $debug; then 292 (cd "$source_iotests"; 293 MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \ 294 $run_command -d 2>&1 | tee $tmp.out) 295 else 296 (cd "$source_iotests"; 297 MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \ 298 $run_command >$tmp.out 2>&1) 299 fi 300 sts=$? 301 $timestamp && _timestamp 302 stop=`_wallclock` 303 304 if [ -f core ] 305 then 306 printf " [dumped core]" 307 mv core $seq.core 308 err=true 309 fi 310 311 if [ -f $seq.notrun ] 312 then 313 $timestamp || printf " [not run] " 314 $timestamp && echo " [not run]" && printf %s " $seq -- " 315 cat $seq.notrun 316 notrun="$notrun $seq" 317 else 318 if [ $sts -ne 0 ] 319 then 320 printf %s " [failed, exit status $sts]" 321 err=true 322 fi 323 324 reference="$source_iotests/$seq.out" 325 reference_machine="$source_iotests/$seq.$QEMU_DEFAULT_MACHINE.out" 326 if [ -f "$reference_machine" ]; then 327 reference="$reference_machine" 328 fi 329 330 reference_format="$source_iotests/$seq.out.$IMGFMT" 331 if [ -f "$reference_format" ]; then 332 reference="$reference_format" 333 fi 334 335 if [ "$CACHEMODE" = "none" ]; then 336 [ -f "$source_iotests/$seq.out.nocache" ] && reference="$source_iotests/$seq.out.nocache" 337 fi 338 339 if [ ! -f "$reference" ] 340 then 341 echo " - no qualified output" 342 err=true 343 else 344 if diff -w "$reference" $tmp.out >/dev/null 2>&1 345 then 346 echo "" 347 if $err 348 then 349 : 350 else 351 echo "$seq `expr $stop - $start`" >>$tmp.time 352 fi 353 else 354 echo " - output mismatch (see $seq.out.bad)" 355 mv $tmp.out $seq.out.bad 356 $diff -w "$reference" $(realpath $seq.out.bad) 357 err=true 358 fi 359 fi 360 fi 361 362 fi 363 364 # come here for each test, except when $showme is true 365 # 366 if $err 367 then 368 bad="$bad $seq" 369 n_bad=`expr $n_bad + 1` 370 quick=false 371 fi 372 [ -f $seq.notrun ] || try=`expr $try + 1` 373 374 seq="after_$seq" 375done 376 377interrupt=false 378status=`expr $n_bad` 379exit 380