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 126#if [ `id -u` -ne 0 ] 127#then 128# echo "check: QA must be run as root" 129# exit 1 130#fi 131 132TIMESTAMP_FILE=check.time-$IMGPROTO-$IMGFMT 133 134tmp="${TEST_DIR}"/$$ 135 136_wallclock() 137{ 138 date "+%H %M %S" | $AWK_PROG '{ print $1*3600 + $2*60 + $3 }' 139} 140 141_timestamp() 142{ 143 now=`date "+%T"` 144 printf %s " [$now]" 145} 146 147_wrapup() 148{ 149 # for hangcheck ... 150 # remove files that were used by hangcheck 151 # 152 [ -f "${TEST_DIR}"/check.pid ] && rm -rf "${TEST_DIR}"/check.pid 153 [ -f "${TEST_DIR}"/check.sts ] && rm -rf "${TEST_DIR}"/check.sts 154 155 if $showme 156 then 157 : 158 elif $needwrap 159 then 160 if [ -f $TIMESTAMP_FILE -a -f $tmp.time ] 161 then 162 cat $TIMESTAMP_FILE $tmp.time \ 163 | $AWK_PROG ' 164 { t[$1] = $2 } 165END { if (NR > 0) { 166 for (i in t) print i " " t[i] 167 } 168 }' \ 169 | sort -n >$tmp.out 170 mv $tmp.out $TIMESTAMP_FILE 171 fi 172 173 if [ -f $tmp.expunged ] 174 then 175 notrun=`wc -l <$tmp.expunged | sed -e 's/ *//g'` 176 try=`expr $try - $notrun` 177 list=`echo "$list" | sed -f $tmp.expunged` 178 fi 179 180 echo "" >>check.log 181 date >>check.log 182 echo $list | fmt | sed -e 's/^/ /' >>check.log 183 $interrupt && echo "Interrupted!" >>check.log 184 185 if [ ! -z "$notrun" ] 186 then 187 echo "Not run:$notrun" 188 echo "Not run:$notrun" >>check.log 189 fi 190 if [ ! -z "$n_bad" -a $n_bad != 0 ] 191 then 192 echo "Failures:$bad" 193 echo "Failed $n_bad of $try tests" 194 echo "Failures:$bad" | fmt >>check.log 195 echo "Failed $n_bad of $try tests" >>check.log 196 else 197 echo "Passed all $try tests" 198 echo "Passed all $try tests" >>check.log 199 fi 200 needwrap=false 201 fi 202 203 rm -f "${TEST_DIR}"/*.out "${TEST_DIR}"/*.err "${TEST_DIR}"/*.time 204 rm -f "${TEST_DIR}"/check.pid "${TEST_DIR}"/check.sts 205 rm -f $tmp.* 206} 207 208trap "_wrapup; exit \$status" 0 1 2 3 15 209 210# for hangcheck ... 211# Save pid of check in a well known place, so that hangcheck can be sure it 212# has the right pid (getting the pid from ps output is not reliable enough). 213# 214rm -rf "${TEST_DIR}"/check.pid 215echo $$ > "${TEST_DIR}"/check.pid 216 217# for hangcheck ... 218# Save the status of check in a well known place, so that hangcheck can be 219# sure to know where check is up to (getting test number from ps output is 220# not reliable enough since the trace stuff has been introduced). 221# 222rm -rf "${TEST_DIR}"/check.sts 223echo "preamble" > "${TEST_DIR}"/check.sts 224 225# don't leave old full output behind on a clean run 226rm -f check.full 227 228[ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE 229 230FULL_IMGFMT_DETAILS=`_full_imgfmt_details` 231FULL_IMGPROTO_DETAILS=`_full_imgproto_details` 232FULL_HOST_DETAILS=`_full_platform_details` 233#FULL_MKFS_OPTIONS=`_scratch_mkfs_options` 234#FULL_MOUNT_OPTIONS=`_scratch_mount_options` 235 236cat <<EOF 237QEMU -- "$QEMU_PROG" $QEMU_OPTIONS 238QEMU_IMG -- "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS 239QEMU_IO -- "$QEMU_IO_PROG" $QEMU_IO_OPTIONS 240QEMU_NBD -- "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS 241IMGFMT -- $FULL_IMGFMT_DETAILS 242IMGPROTO -- $FULL_IMGPROTO_DETAILS 243PLATFORM -- $FULL_HOST_DETAILS 244TEST_DIR -- $TEST_DIR 245SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER 246 247EOF 248#MKFS_OPTIONS -- $FULL_MKFS_OPTIONS 249#MOUNT_OPTIONS -- $FULL_MOUNT_OPTIONS 250 251seq="check" 252 253[ -n "$TESTS_REMAINING_LOG" ] && echo $list > $TESTS_REMAINING_LOG 254 255for seq in $list 256do 257 err=false 258 printf %s "$seq" 259 if [ -n "$TESTS_REMAINING_LOG" ] ; then 260 sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp 261 mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG 262 sync 263 fi 264 265 if $showme 266 then 267 echo 268 continue 269 elif [ -f expunged ] && $expunge && egrep "^$seq([ ]|\$)" expunged >/dev/null 270 then 271 echo " - expunged" 272 rm -f $seq.out.bad 273 echo "/^$seq\$/d" >>$tmp.expunged 274 elif [ ! -f "$source_iotests/$seq" ] 275 then 276 echo " - no such test?" 277 echo "/^$seq\$/d" >>$tmp.expunged 278 else 279 # really going to try and run this one 280 # 281 rm -f $seq.out.bad 282 lasttime=`sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE` 283 if [ "X$lasttime" != X ]; then 284 printf %s " ${lasttime}s ..." 285 else 286 printf " " # prettier output with timestamps. 287 fi 288 rm -f core $seq.notrun 289 290 # for hangcheck ... 291 echo "$seq" > "${TEST_DIR}"/check.sts 292 293 start=`_wallclock` 294 $timestamp && printf %s " [$(date "+%T")]" 295 296 if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then 297 run_command="$PYTHON $seq" 298 else 299 run_command="./$seq" 300 fi 301 export OUTPUT_DIR=$PWD 302 if $debug; then 303 (cd "$source_iotests"; 304 MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \ 305 $run_command -d 2>&1 | tee $tmp.out) 306 else 307 (cd "$source_iotests"; 308 MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \ 309 $run_command >$tmp.out 2>&1) 310 fi 311 sts=$? 312 $timestamp && _timestamp 313 stop=`_wallclock` 314 315 if [ -f core ] 316 then 317 printf " [dumped core]" 318 mv core $seq.core 319 err=true 320 fi 321 322 if [ -f $seq.notrun ] 323 then 324 $timestamp || printf " [not run] " 325 $timestamp && echo " [not run]" && printf %s " $seq -- " 326 cat $seq.notrun 327 notrun="$notrun $seq" 328 else 329 if [ $sts -ne 0 ] 330 then 331 printf %s " [failed, exit status $sts]" 332 err=true 333 fi 334 335 reference="$source_iotests/$seq.out" 336 reference_machine="$source_iotests/$seq.$QEMU_DEFAULT_MACHINE.out" 337 if [ -f "$reference_machine" ]; then 338 reference="$reference_machine" 339 fi 340 341 reference_format="$source_iotests/$seq.out.$IMGFMT" 342 if [ -f "$reference_format" ]; then 343 reference="$reference_format" 344 fi 345 346 if [ "$CACHEMODE" = "none" ]; then 347 [ -f "$source_iotests/$seq.out.nocache" ] && reference="$source_iotests/$seq.out.nocache" 348 fi 349 350 if [ ! -f "$reference" ] 351 then 352 echo " - no qualified output" 353 err=true 354 else 355 if diff -w "$reference" $tmp.out >/dev/null 2>&1 356 then 357 echo "" 358 if $err 359 then 360 : 361 else 362 echo "$seq `expr $stop - $start`" >>$tmp.time 363 fi 364 else 365 echo " - output mismatch (see $seq.out.bad)" 366 mv $tmp.out $seq.out.bad 367 $diff -w "$reference" $seq.out.bad 368 err=true 369 fi 370 fi 371 fi 372 373 fi 374 375 # come here for each test, except when $showme is true 376 # 377 if $err 378 then 379 bad="$bad $seq" 380 n_bad=`expr $n_bad + 1` 381 quick=false 382 fi 383 [ -f $seq.notrun ] || try=`expr $try + 1` 384 385 seq="after_$seq" 386done 387 388interrupt=false 389status=`expr $n_bad` 390exit 391