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