3 # Copyright (C) 2009 Red Hat, Inc.
4 # Copyright (c) 2000-2002,2006 Silicon Graphics, Inc. All Rights Reserved.
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.
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.
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/>.
19 # Control script for QA
30 # by default don't output timestamps
31 timestamp=${TIMESTAMP:=false}
41 # called from the build tree
42 source_iotests=$(dirname "$(readlink "$0")")
43 if [ -z "$source_iotests" ]
45 _init_error "failed to obtain source tree name from check symlink"
47 source_iotests=$(cd "$source_iotests"; pwd) || _init_error "failed to enter source tree"
50 # called from the source tree
52 # this may be an in-tree build (note that in the following code we may not
53 # assume that it truly is and have to test whether the build results
58 build_root="$build_iotests/../.."
61 if ! . "$build_iotests/common.env"
63 _init_error "failed to source common.env (make sure the qemu-iotests are run from tests/qemu-iotests in the build tree)"
66 # we need common.config
67 if ! . "$source_iotests/common.config"
69 _init_error "failed to source common.config"
72 _full_imgfmt_details()
74 if [ -n "$IMGOPTS" ]; then
75 echo "$IMGFMT ($IMGOPTS)"
81 _full_platform_details()
87 echo "$os/$platform $host $kernel"
90 # $1 = prog to look for
93 p=$(command -v $1 2> /dev/null)
94 if [ -n "$p" -a -x "$p" ]; then
101 if [ -z "$TEST_DIR" ]; then
102 TEST_DIR=$PWD/scratch
105 if [ ! -e "$TEST_DIR" ]; then
122 rm -f $tmp.list $tmp.tmp $tmp.sed
125 export IMGFMT_GENERIC=true
128 export CACHEMODE="writeback"
129 export QEMU_IO_OPTIONS=""
130 export QEMU_IO_OPTIONS_NO_FMT=""
131 export CACHEMODE_IS_DEFAULT=true
132 export QEMU_OPTIONS="-nodefaults -machine accel=qtest"
133 export VALGRIND_QEMU=
135 export IMGOPTSSYNTAX=false
137 # Save current tty settings, since an aborting qemu call may leave things
141 STTY_RESTORE=$(stty -g)
150 group_list=$(sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
153 if [ -z "$group_list" ]
155 echo "Group \"$r\" is empty or not defined?"
158 [ ! -s $tmp.list ] && touch $tmp.list
161 if grep -s "^$t\$" $tmp.list >/dev/null
165 echo "$t" >>$tmp.list
174 # Populate $tmp.list with all tests
175 awk '/^[0-9]{3,}/ {print $1}' "${source_iotests}/group" > $tmp.list 2>/dev/null
176 group_list=$(sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
179 if [ -z "$group_list" ]
181 echo "Group \"$r\" is empty or not defined?"
188 if [ $numsed -gt 100 ]
190 sed -f $tmp.sed <$tmp.list >$tmp.tmp
191 mv $tmp.tmp $tmp.list
195 echo "/^$t\$/d" >>$tmp.sed
196 numsed=$(expr $numsed + 1)
198 sed -f $tmp.sed <$tmp.list >$tmp.tmp
199 mv $tmp.tmp $tmp.list
211 CACHEMODE_IS_DEFAULT=false
220 -\? | -h | --help) # usage
221 echo "Usage: $0 [options] [testlist]"'
228 -raw test raw (default)
231 -parallels test parallels
242 image protocol options
243 -file test file (default)
245 -sheepdog test sheepdog
252 -xdiff graphical mode diff
253 -nocache use O_DIRECT on backing file
254 -misalign misalign memory allocations
255 -n show me, do not run tests
256 -o options -o options to pass to qemu-img create/convert
261 -g group[,group...] include tests from these groups
262 -x group[,group...] exclude tests from these groups
264 NNN-NNN include test range (eg. 012-021)
376 CACHEMODE_IS_DEFAULT=false
381 QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --misalign"
390 -g) # -g group ... pick from group file
395 -xdiff) # graphical diff mode
398 if [ ! -z "$DISPLAY" ]
400 command -v xdiff >/dev/null 2>&1 && diff=xdiff
401 command -v gdiff >/dev/null 2>&1 && diff=gdiff
402 command -v tkdiff >/dev/null 2>&1 && diff=tkdiff
403 command -v xxdiff >/dev/null 2>&1 && diff=xxdiff
407 -n) # show me, don't do it
419 -T) # turn on timestamp output
432 -x) # -x group ... exclude from group file
436 '[0-9][0-9][0-9] [0-9][0-9][0-9][0-9]')
443 eval $(echo $r | sed -e 's/^/start=/' -e 's/-/ end=/')
447 eval $(echo $r | sed -e 's/^/start=/' -e 's/-//')
448 end=$(echo [0-9][0-9][0-9] [0-9][0-9][0-9][0-9] | sed -e 's/\[0-9]//g' -e 's/ *$//' -e 's/.* //')
451 echo "No tests in range \"$r\"?"
464 # get rid of leading 0s as can be interpreted as octal
465 start=$(echo $start | sed 's/^0*//')
466 end=$(echo $end | sed 's/^0*//')
472 BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
475 if grep -s "^$id " "$source_iotests/group" >/dev/null
477 # in group file ... OK
480 if [ -f expunged ] && $expunge && egrep "^$id([ ]|\$)" expunged >/dev/null
482 # expunged ... will be reported, but not run, later
486 if [ "$start" == "$end" -a "$id" == "$end" ]
488 echo "$id - unknown test"
491 echo "$id - unknown test, ignored"
500 # Set qemu-io cache mode with $CACHEMODE we have
501 QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE"
503 QEMU_IO_OPTIONS_NO_FMT="$QEMU_IO_OPTIONS"
504 if [ "$IMGOPTSSYNTAX" != "true" ]; then
505 QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT"
508 # Set default options for qemu-img create -o if they were not specified
509 if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" | grep "compat=" > /dev/null); then
510 IMGOPTS=$(_optstr_add "$IMGOPTS" "compat=1.1")
512 if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" | grep "iter-time=" > /dev/null); then
513 IMGOPTS=$(_optstr_add "$IMGOPTS" "iter-time=10")
516 if [ -z "$SAMPLE_IMG_DIR" ]; then
517 SAMPLE_IMG_DIR="$source_iotests/sample_images"
521 export SAMPLE_IMG_DIR
525 # found some valid test numbers ... this is good
530 # had test numbers, but none in group file ... do nothing
533 # no test numbers, do everything from group file
534 sed -n -e '/^[0-9][0-9][0-9]*/s/[ ].*//p' <"$source_iotests/group" >$tmp.list
538 # should be sort -n, but this did not work for Linux when this
539 # was ported from IRIX
541 list=$(sort $tmp.list)
542 rm -f $tmp.list $tmp.tmp $tmp.sed
544 if [ -z "$QEMU_PROG" ]
546 if [ -x "$build_iotests/qemu" ]; then
547 export QEMU_PROG="$build_iotests/qemu"
548 elif [ -x "$build_root/${qemu_arch}-softmmu/qemu-system-${qemu_arch}" ]; then
549 export QEMU_PROG="$build_root/${qemu_arch}-softmmu/qemu-system-${qemu_arch}"
551 pushd "$build_root" > /dev/null
552 for binary in *-softmmu/qemu-system-*
556 export QEMU_PROG="$build_root/$binary"
561 [ "$QEMU_PROG" = "" ] && _init_error "qemu not found"
564 export QEMU_PROG="$(type -p "$QEMU_PROG")"
566 if [ -z "$QEMU_IMG_PROG" ]; then
567 if [ -x "$build_iotests/qemu-img" ]; then
568 export QEMU_IMG_PROG="$build_iotests/qemu-img"
569 elif [ -x "$build_root/qemu-img" ]; then
570 export QEMU_IMG_PROG="$build_root/qemu-img"
572 _init_error "qemu-img not found"
575 export QEMU_IMG_PROG="$(type -p "$QEMU_IMG_PROG")"
577 if [ -z "$QEMU_IO_PROG" ]; then
578 if [ -x "$build_iotests/qemu-io" ]; then
579 export QEMU_IO_PROG="$build_iotests/qemu-io"
580 elif [ -x "$build_root/qemu-io" ]; then
581 export QEMU_IO_PROG="$build_root/qemu-io"
583 _init_error "qemu-io not found"
586 export QEMU_IO_PROG="$(type -p "$QEMU_IO_PROG")"
588 if [ -z $QEMU_NBD_PROG ]; then
589 if [ -x "$build_iotests/qemu-nbd" ]; then
590 export QEMU_NBD_PROG="$build_iotests/qemu-nbd"
591 elif [ -x "$build_root/qemu-nbd" ]; then
592 export QEMU_NBD_PROG="$build_root/qemu-nbd"
594 _init_error "qemu-nbd not found"
597 export QEMU_NBD_PROG="$(type -p "$QEMU_NBD_PROG")"
599 if [ -z "$QEMU_VXHS_PROG" ]; then
600 export QEMU_VXHS_PROG="$(set_prog_path qnio_server)"
603 if [ -x "$build_iotests/socket_scm_helper" ]
605 export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
608 default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p')
609 default_alias_machine=$($QEMU_PROG -machine help | \
610 sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
611 if [[ "$default_alias_machine" ]]; then
612 default_machine="$default_alias_machine"
615 export QEMU_DEFAULT_MACHINE="$default_machine"
617 TIMESTAMP_FILE=check.time-$IMGPROTO-$IMGFMT
621 date "+%H %M %S" | awk '{ print $1*3600 + $2*60 + $3 }'
637 if [ -f $TIMESTAMP_FILE -a -f $tmp.time ]
639 cat $TIMESTAMP_FILE $tmp.time \
643 for (i in t) print i " " t[i]
647 mv $tmp.out $TIMESTAMP_FILE
650 if [ -f $tmp.expunged ]
652 notrun=$(wc -l <$tmp.expunged | sed -e 's/ *//g')
653 try=$(expr $try - $notrun)
654 list=$(echo "$list" | sed -f $tmp.expunged)
659 echo $list | fmt | sed -e 's/^/ /' >>check.log
660 $interrupt && echo "Interrupted!" >>check.log
662 if [ ! -z "$notrun" ]
664 echo "Not run:$notrun"
665 echo "Not run:$notrun" >>check.log
667 if [ ! -z "$n_bad" -a $n_bad != 0 ]
670 echo "Failed $n_bad of $try tests"
671 echo "Failures:$bad" | fmt >>check.log
672 echo "Failed $n_bad of $try tests" >>check.log
674 echo "Passed all $try tests"
675 echo "Passed all $try tests" >>check.log
680 if test -n "$STTY_RESTORE"; then
683 rm -f "${TEST_DIR}"/*.out "${TEST_DIR}"/*.err "${TEST_DIR}"/*.time
684 rm -f "${TEST_DIR}"/check.pid "${TEST_DIR}"/check.sts
688 trap "_wrapup; exit \$status" 0 1 2 3 15
690 [ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE
692 FULL_IMGFMT_DETAILS=$(_full_imgfmt_details)
693 FULL_HOST_DETAILS=$(_full_platform_details)
696 QEMU -- "$QEMU_PROG" $QEMU_OPTIONS
697 QEMU_IMG -- "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS
698 QEMU_IO -- "$QEMU_IO_PROG" $QEMU_IO_OPTIONS
699 QEMU_NBD -- "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS
700 IMGFMT -- $FULL_IMGFMT_DETAILS
701 IMGPROTO -- $IMGPROTO
702 PLATFORM -- $FULL_HOST_DETAILS
703 TEST_DIR -- $TEST_DIR
704 SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER
710 [ -n "$TESTS_REMAINING_LOG" ] && echo $list > $TESTS_REMAINING_LOG
716 if [ -n "$TESTS_REMAINING_LOG" ] ; then
717 sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp
718 mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG
726 elif [ -f expunged ] && $expunge && egrep "^$seq([ ]|\$)" expunged >/dev/null
730 echo "/^$seq\$/d" >>$tmp.expunged
731 elif [ ! -f "$source_iotests/$seq" ]
733 echo " - no such test?"
734 echo "/^$seq\$/d" >>$tmp.expunged
736 # really going to try and run this one
739 lasttime=$(sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE)
740 if [ "X$lasttime" != X ]; then
741 printf %s " ${lasttime}s ..."
743 printf " " # prettier output with timestamps.
745 rm -f core $seq.notrun
748 $timestamp && printf %s " [$(date "+%T")]"
750 if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then
751 run_command="$PYTHON $seq"
755 export OUTPUT_DIR=$PWD
757 (cd "$source_iotests";
758 MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
759 $run_command -d 2>&1 | tee $tmp.out)
761 (cd "$source_iotests";
762 MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
763 $run_command >$tmp.out 2>&1)
766 $timestamp && _timestamp
771 printf " [dumped core]"
776 if [ -f $seq.notrun ]
778 $timestamp || printf " [not run] "
779 $timestamp && echo " [not run]" && printf %s " $seq -- "
781 notrun="$notrun $seq"
785 printf %s " [failed, exit status $sts]"
789 reference="$source_iotests/$seq.out"
790 reference_machine="$source_iotests/$seq.$QEMU_DEFAULT_MACHINE.out"
791 if [ -f "$reference_machine" ]; then
792 reference="$reference_machine"
795 reference_format="$source_iotests/$seq.out.$IMGFMT"
796 if [ -f "$reference_format" ]; then
797 reference="$reference_format"
800 if [ "$CACHEMODE" = "none" ]; then
801 [ -f "$source_iotests/$seq.out.nocache" ] && reference="$source_iotests/$seq.out.nocache"
804 if [ ! -f "$reference" ]
806 echo " - no qualified output"
809 if diff -w "$reference" $tmp.out >/dev/null 2>&1
816 echo "$seq $(expr $stop - $start)" >>$tmp.time
819 echo " - output mismatch (see $seq.out.bad)"
820 mv $tmp.out $seq.out.bad
821 $diff -w "$reference" "$PWD"/$seq.out.bad
829 # come here for each test, except when $showme is true
834 n_bad=$(expr $n_bad + 1)
837 [ -f $seq.notrun ] || try=$(expr $try + 1)
843 status=$(expr $n_bad)