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