#!/bin/bash # # Copyright (C) 2009 Red Hat, Inc. # Copyright (c) 2000-2002,2006 Silicon Graphics, Inc. All Rights Reserved. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License as # published by the Free Software Foundation. # # This program is distributed in the hope that it would be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # # Control script for QA # status=0 needwrap=true try=0 n_bad=0 bad="" notrun="" interrupt=true # by default don't output timestamps timestamp=${TIMESTAMP:=false} # generic initialization iam=check _init_error() { echo "$iam: $1" >&2 exit 1 } if [ -L "$0" ] then # called from the build tree source_iotests=$(dirname "$(readlink "$0")") if [ -z "$source_iotests" ] then _init_error "failed to obtain source tree name from check symlink" fi source_iotests=$(cd "$source_iotests"; pwd) || _init_error "failed to enter source tree" build_iotests=$PWD else # called from the source tree source_iotests=$PWD # this may be an in-tree build (note that in the following code we may not # assume that it truly is and have to test whether the build results # actually exist) build_iotests=$PWD fi build_root="$build_iotests/../.." if [ -x "$build_iotests/socket_scm_helper" ] then export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper" fi # if ./qemu exists, it should be prioritized and will be chosen by common.config if [[ -z "$QEMU_PROG" && ! -x './qemu' ]] then arch=$(uname -m 2> /dev/null) if [[ -n $arch && -x "$build_root/$arch-softmmu/qemu-system-$arch" ]] then export QEMU_PROG="$build_root/$arch-softmmu/qemu-system-$arch" else pushd "$build_root" > /dev/null for binary in *-softmmu/qemu-system-* do if [ -x "$binary" ] then export QEMU_PROG="$build_root/$binary" break fi done popd > /dev/null fi fi if [[ -z $QEMU_IMG_PROG && -x "$build_root/qemu-img" && ! -x './qemu-img' ]] then export QEMU_IMG_PROG="$build_root/qemu-img" fi if [[ -z $QEMU_IO_PROG && -x "$build_root/qemu-io" && ! -x './qemu-io' ]] then export QEMU_IO_PROG="$build_root/qemu-io" fi if [[ -z $QEMU_NBD_PROG && -x "$build_root/qemu-nbd" && ! -x './qemu-nbd' ]] then export QEMU_NBD_PROG="$build_root/qemu-nbd" fi # we need common.env if ! . "$build_iotests/common.env" then _init_error "failed to source common.env (make sure the qemu-iotests are run from tests/qemu-iotests in the build tree)" fi # we need common.config if ! . "$source_iotests/common.config" then _init_error "failed to source common.config" fi # we need common.rc if ! . "$source_iotests/common.rc" then _init_error "failed to source common.rc" fi # we need common . "$source_iotests/common" TIMESTAMP_FILE=check.time-$IMGPROTO-$IMGFMT tmp="${TEST_DIR}"/$$ _wallclock() { date "+%H %M %S" | $AWK_PROG '{ print $1*3600 + $2*60 + $3 }' } _timestamp() { now=`date "+%T"` printf %s " [$now]" } _wrapup() { # for hangcheck ... # remove files that were used by hangcheck # [ -f "${TEST_DIR}"/check.pid ] && rm -rf "${TEST_DIR}"/check.pid [ -f "${TEST_DIR}"/check.sts ] && rm -rf "${TEST_DIR}"/check.sts if $showme then : elif $needwrap then if [ -f $TIMESTAMP_FILE -a -f $tmp.time ] then cat $TIMESTAMP_FILE $tmp.time \ | $AWK_PROG ' { t[$1] = $2 } END { if (NR > 0) { for (i in t) print i " " t[i] } }' \ | sort -n >$tmp.out mv $tmp.out $TIMESTAMP_FILE fi if [ -f $tmp.expunged ] then notrun=`wc -l <$tmp.expunged | sed -e 's/ *//g'` try=`expr $try - $notrun` list=`echo "$list" | sed -f $tmp.expunged` fi echo "" >>check.log date >>check.log echo $list | fmt | sed -e 's/^/ /' >>check.log $interrupt && echo "Interrupted!" >>check.log if [ ! -z "$notrun" ] then echo "Not run:$notrun" echo "Not run:$notrun" >>check.log fi if [ ! -z "$n_bad" -a $n_bad != 0 ] then echo "Failures:$bad" echo "Failed $n_bad of $try tests" echo "Failures:$bad" | fmt >>check.log echo "Failed $n_bad of $try tests" >>check.log else echo "Passed all $try tests" echo "Passed all $try tests" >>check.log fi needwrap=false fi rm -f "${TEST_DIR}"/*.out "${TEST_DIR}"/*.err "${TEST_DIR}"/*.time rm -f "${TEST_DIR}"/check.pid "${TEST_DIR}"/check.sts rm -f $tmp.* } trap "_wrapup; exit \$status" 0 1 2 3 15 # for hangcheck ... # Save pid of check in a well known place, so that hangcheck can be sure it # has the right pid (getting the pid from ps output is not reliable enough). # rm -rf "${TEST_DIR}"/check.pid echo $$ > "${TEST_DIR}"/check.pid # for hangcheck ... # Save the status of check in a well known place, so that hangcheck can be # sure to know where check is up to (getting test number from ps output is # not reliable enough since the trace stuff has been introduced). # rm -rf "${TEST_DIR}"/check.sts echo "preamble" > "${TEST_DIR}"/check.sts # don't leave old full output behind on a clean run rm -f check.full [ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE FULL_IMGFMT_DETAILS=`_full_imgfmt_details` FULL_HOST_DETAILS=`_full_platform_details` cat < $TESTS_REMAINING_LOG for seq in $list do err=false printf %s "$seq" if [ -n "$TESTS_REMAINING_LOG" ] ; then sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG sync fi if $showme then echo continue elif [ -f expunged ] && $expunge && egrep "^$seq([ ]|\$)" expunged >/dev/null then echo " - expunged" rm -f $seq.out.bad echo "/^$seq\$/d" >>$tmp.expunged elif [ ! -f "$source_iotests/$seq" ] then echo " - no such test?" echo "/^$seq\$/d" >>$tmp.expunged else # really going to try and run this one # rm -f $seq.out.bad lasttime=`sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE` if [ "X$lasttime" != X ]; then printf %s " ${lasttime}s ..." else printf " " # prettier output with timestamps. fi rm -f core $seq.notrun # for hangcheck ... echo "$seq" > "${TEST_DIR}"/check.sts start=`_wallclock` $timestamp && printf %s " [$(date "+%T")]" if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then run_command="$PYTHON $seq" else run_command="./$seq" fi export OUTPUT_DIR=$PWD if $debug; then (cd "$source_iotests"; MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \ $run_command -d 2>&1 | tee $tmp.out) else (cd "$source_iotests"; MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \ $run_command >$tmp.out 2>&1) fi sts=$? $timestamp && _timestamp stop=`_wallclock` if [ -f core ] then printf " [dumped core]" mv core $seq.core err=true fi if [ -f $seq.notrun ] then $timestamp || printf " [not run] " $timestamp && echo " [not run]" && printf %s " $seq -- " cat $seq.notrun notrun="$notrun $seq" else if [ $sts -ne 0 ] then printf %s " [failed, exit status $sts]" err=true fi reference="$source_iotests/$seq.out" reference_machine="$source_iotests/$seq.$QEMU_DEFAULT_MACHINE.out" if [ -f "$reference_machine" ]; then reference="$reference_machine" fi reference_format="$source_iotests/$seq.out.$IMGFMT" if [ -f "$reference_format" ]; then reference="$reference_format" fi if [ "$CACHEMODE" = "none" ]; then [ -f "$source_iotests/$seq.out.nocache" ] && reference="$source_iotests/$seq.out.nocache" fi if [ ! -f "$reference" ] then echo " - no qualified output" err=true else if diff -w "$reference" $tmp.out >/dev/null 2>&1 then echo "" if $err then : else echo "$seq `expr $stop - $start`" >>$tmp.time fi else echo " - output mismatch (see $seq.out.bad)" mv $tmp.out $seq.out.bad $diff -w "$reference" $(realpath $seq.out.bad) err=true fi fi fi fi # come here for each test, except when $showme is true # if $err then bad="$bad $seq" n_bad=`expr $n_bad + 1` quick=false fi [ -f $seq.notrun ] || try=`expr $try + 1` seq="after_$seq" done interrupt=false status=`expr $n_bad` exit