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 235QEMU_IMG -- $QEMU_IMG 236QEMU_IO -- $QEMU_IO 237QEMU_NBD -- $QEMU_NBD 238IMGFMT -- $FULL_IMGFMT_DETAILS 239IMGPROTO -- $FULL_IMGPROTO_DETAILS 240PLATFORM -- $FULL_HOST_DETAILS 241SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER 242 243EOF 244#MKFS_OPTIONS -- $FULL_MKFS_OPTIONS 245#MOUNT_OPTIONS -- $FULL_MOUNT_OPTIONS 246 247seq="check" 248 249[ -n "$TESTS_REMAINING_LOG" ] && echo $list > $TESTS_REMAINING_LOG 250 251for seq in $list 252do 253 err=false 254 echo -n "$seq" 255 if [ -n "$TESTS_REMAINING_LOG" ] ; then 256 sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp 257 mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG 258 sync 259 fi 260 261 if $showme 262 then 263 echo 264 continue 265 elif [ -f expunged ] && $expunge && egrep "^$seq([ ]|\$)" expunged >/dev/null 266 then 267 echo " - expunged" 268 rm -f $seq.out.bad 269 echo "/^$seq\$/d" >>$tmp.expunged 270 elif [ ! -f "$source_iotests/$seq" ] 271 then 272 echo " - no such test?" 273 echo "/^$seq\$/d" >>$tmp.expunged 274 else 275 # really going to try and run this one 276 # 277 rm -f $seq.out.bad 278 lasttime=`sed -n -e "/^$seq /s/.* //p" <check.time` 279 if [ "X$lasttime" != X ]; then 280 echo -n " ${lasttime}s ..." 281 else 282 echo -n " " # prettier output with timestamps. 283 fi 284 rm -f core $seq.notrun 285 286 # for hangcheck ... 287 echo "$seq" >/tmp/check.sts 288 289 start=`_wallclock` 290 $timestamp && echo -n " ["`date "+%T"`"]" 291 292 if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then 293 run_command="$PYTHON $seq" 294 else 295 run_command="./$seq" 296 fi 297 export OUTPUT_DIR=$PWD 298 (cd "$source_iotests"; 299 MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \ 300 $run_command >$tmp.out 2>&1) 301 sts=$? 302 $timestamp && _timestamp 303 stop=`_wallclock` 304 305 if [ -f core ] 306 then 307 echo -n " [dumped core]" 308 mv core $seq.core 309 err=true 310 fi 311 312 if [ -f $seq.notrun ] 313 then 314 $timestamp || echo -n " [not run] " 315 $timestamp && echo " [not run]" && echo -n " $seq -- " 316 cat $seq.notrun 317 notrun="$notrun $seq" 318 else 319 if [ $sts -ne 0 ] 320 then 321 echo -n " [failed, exit status $sts]" 322 err=true 323 fi 324 325 reference="$source_iotests/$seq.out" 326 if [ "$CACHEMODE" = "none" ]; then 327 [ -f "$source_iotests/$seq.out.nocache" ] && reference="$source_iotests/$seq.out.nocache" 328 fi 329 330 if [ ! -f "$reference" ] 331 then 332 echo " - no qualified output" 333 err=true 334 else 335 if diff -w "$reference" $tmp.out >/dev/null 2>&1 336 then 337 echo "" 338 if $err 339 then 340 : 341 else 342 echo "$seq `expr $stop - $start`" >>$tmp.time 343 fi 344 else 345 echo " - output mismatch (see $seq.out.bad)" 346 mv $tmp.out $seq.out.bad 347 $diff -w "$reference" $seq.out.bad 348 err=true 349 fi 350 fi 351 fi 352 353 fi 354 355 # come here for each test, except when $showme is true 356 # 357 if $err 358 then 359 bad="$bad $seq" 360 n_bad=`expr $n_bad + 1` 361 quick=false 362 fi 363 [ -f $seq.notrun ] || try=`expr $try + 1` 364 365 seq="after_$seq" 366done 367 368interrupt=false 369status=`expr $n_bad` 370exit 371