| #!/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 <http://www.gnu.org/licenses/>. |
| # |
| # |
| # 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" |
| |
| #if [ `id -u` -ne 0 ] |
| #then |
| # echo "check: QA must be run as root" |
| # exit 1 |
| #fi |
| |
| tmp="${TEST_DIR}"/$$ |
| |
| _wallclock() |
| { |
| date "+%H %M %S" | $AWK_PROG '{ print $1*3600 + $2*60 + $3 }' |
| } |
| |
| _timestamp() |
| { |
| now=`date "+%T"` |
| echo -n " [$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 check.time -a -f $tmp.time ] |
| then |
| cat check.time $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 check.time |
| 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 check.time ] || touch check.time |
| |
| FULL_IMGFMT_DETAILS=`_full_imgfmt_details` |
| FULL_IMGPROTO_DETAILS=`_full_imgproto_details` |
| FULL_HOST_DETAILS=`_full_platform_details` |
| #FULL_MKFS_OPTIONS=`_scratch_mkfs_options` |
| #FULL_MOUNT_OPTIONS=`_scratch_mount_options` |
| |
| cat <<EOF |
| QEMU -- "$QEMU_PROG" $QEMU_OPTIONS |
| QEMU_IMG -- "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS |
| QEMU_IO -- "$QEMU_IO_PROG" $QEMU_IO_OPTIONS |
| QEMU_NBD -- "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS |
| IMGFMT -- $FULL_IMGFMT_DETAILS |
| IMGPROTO -- $FULL_IMGPROTO_DETAILS |
| PLATFORM -- $FULL_HOST_DETAILS |
| TEST_DIR -- $TEST_DIR |
| SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER |
| |
| EOF |
| #MKFS_OPTIONS -- $FULL_MKFS_OPTIONS |
| #MOUNT_OPTIONS -- $FULL_MOUNT_OPTIONS |
| |
| seq="check" |
| |
| [ -n "$TESTS_REMAINING_LOG" ] && echo $list > $TESTS_REMAINING_LOG |
| |
| for seq in $list |
| do |
| err=false |
| echo -n "$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" <check.time` |
| if [ "X$lasttime" != X ]; then |
| echo -n " ${lasttime}s ..." |
| else |
| echo -n " " # prettier output with timestamps. |
| fi |
| rm -f core $seq.notrun |
| |
| # for hangcheck ... |
| echo "$seq" > "${TEST_DIR}"/check.sts |
| |
| start=`_wallclock` |
| $timestamp && echo -n " ["`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 |
| echo -n " [dumped core]" |
| mv core $seq.core |
| err=true |
| fi |
| |
| if [ -f $seq.notrun ] |
| then |
| $timestamp || echo -n " [not run] " |
| $timestamp && echo " [not run]" && echo -n " $seq -- " |
| cat $seq.notrun |
| notrun="$notrun $seq" |
| else |
| if [ $sts -ne 0 ] |
| then |
| echo -n " [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 |
| |
| 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" $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 |