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
40 # called from the build tree
41 source_iotests
=$
(dirname "$(readlink "$0")")
42 if [ -z "$source_iotests" ]
44 _init_error
"failed to obtain source tree name from check symlink"
46 source_iotests
=$
(cd "$source_iotests"; pwd) || _init_error
"failed to enter source tree"
47 build_iotests
=$
(cd "$(dirname "$0")"; pwd)
49 # called from the source tree
51 # this may be an in-tree build (note that in the following code we may not
52 # assume that it truly is and have to test whether the build results
57 build_root
="$build_iotests/../.."
60 if ! .
"$build_iotests/common.env"
62 _init_error
"failed to source common.env (make sure the qemu-iotests are run from tests/qemu-iotests in the build tree)"
65 # we need common.config
66 if ! .
"$source_iotests/common.config"
68 _init_error
"failed to source common.config"
71 _full_imgfmt_details
()
73 if [ -n "$IMGOPTS" ]; then
74 echo "$IMGFMT ($IMGOPTS)"
80 _full_platform_details
()
86 echo "$os/$platform $host $kernel"
92 QEMU -- "$QEMU_PROG" $QEMU_OPTIONS
93 QEMU_IMG -- "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS
94 QEMU_IO -- "$QEMU_IO_PROG" $QEMU_IO_OPTIONS
95 QEMU_NBD -- "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS
96 IMGFMT -- $FULL_IMGFMT_DETAILS
98 PLATFORM -- $FULL_HOST_DETAILS
100 SOCK_DIR -- $SOCK_DIR
101 SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER
106 # $1 = prog to look for
109 p
=$
(command -v $1 2> /dev
/null
)
110 if [ -n "$p" -a -x "$p" ]; then
117 if [ -z "$TEST_DIR" ]; then
118 TEST_DIR
=$PWD/scratch
120 mkdir
-p "$TEST_DIR" || _init_error
'Failed to create TEST_DIR'
123 if [ -z "$SOCK_DIR" ]; then
124 SOCK_DIR
=$
(mktemp
-d)
127 mkdir
-p "$SOCK_DIR" || _init_error
'Failed to create SOCK_DIR'
143 rm -f $tmp.list
$tmp.tmp
$tmp.
sed
146 export IMGFMT_GENERIC
=true
149 export CACHEMODE
="writeback"
150 export AIOMODE
="threads"
151 export QEMU_IO_OPTIONS
=""
152 export QEMU_IO_OPTIONS_NO_FMT
=""
153 export CACHEMODE_IS_DEFAULT
=true
154 export VALGRIND_QEMU
=
156 export IMGOPTSSYNTAX
=false
158 # Save current tty settings, since an aborting qemu call may leave things
162 STTY_RESTORE
=$
(stty
-g)
171 group_list
=$
(sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
174 if [ -z "$group_list" ]
176 echo "Group \"$r\" is empty or not defined?"
179 [ ! -s $tmp.list
] && touch $tmp.list
182 if grep -s "^$t\$" $tmp.list
>/dev
/null
186 echo "$t" >>$tmp.list
195 # Populate $tmp.list with all tests
196 awk '/^[0-9]{3,}/ {print $1}' "${source_iotests}/group" > $tmp.list
2>/dev
/null
197 group_list
=$
(sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
200 if [ -z "$group_list" ]
202 echo "Group \"$r\" is empty or not defined?"
209 if [ $numsed -gt 100 ]
211 sed -f $tmp.
sed <$tmp.list
>$tmp.tmp
212 mv $tmp.tmp
$tmp.list
216 echo "/^$t\$/d" >>$tmp.
sed
217 numsed
=$
(expr $numsed + 1)
219 sed -f $tmp.
sed <$tmp.list
>$tmp.tmp
220 mv $tmp.tmp
$tmp.list
232 CACHEMODE_IS_DEFAULT
=false
246 -\? |
-h |
--help) # usage
247 echo "Usage: $0 [options] [testlist]"'
254 -raw test raw (default)
257 -parallels test parallels
268 image protocol options
269 -file test file (default)
271 -sheepdog test sheepdog
278 -xdiff graphical mode diff
279 -nocache use O_DIRECT on backing file
280 -misalign misalign memory allocations
281 -n show me, do not run tests
282 -o options -o options to pass to qemu-img create/convert
285 -makecheck pretty print output for make check
288 -g group[,group...] include tests from these groups
289 -x group[,group...] exclude tests from these groups
291 NNN-NNN include test range (eg. 012-021)
403 CACHEMODE_IS_DEFAULT
=false
408 QEMU_IO_OPTIONS
="$QEMU_IO_OPTIONS --misalign"
417 -g) # -g group ... pick from group file
422 -xdiff) # graphical diff mode
425 if [ ! -z "$DISPLAY" ]
427 command -v xdiff
>/dev
/null
2>&1 && diff=xdiff
428 command -v gdiff
>/dev
/null
2>&1 && diff=gdiff
429 command -v tkdiff
>/dev
/null
2>&1 && diff=tkdiff
430 command -v xxdiff
>/dev
/null
2>&1 && diff=xxdiff
433 -makecheck) # makecheck friendly output
437 -n) # show me, don't do it
453 -T) # deprecated timestamp option
464 -x) # -x group ... exclude from group file
468 '[0-9][0-9][0-9] [0-9][0-9][0-9][0-9]')
475 eval $
(echo $r |
sed -e 's/^/start=/' -e 's/-/ end=/')
479 eval $
(echo $r |
sed -e 's/^/start=/' -e 's/-//')
480 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/.* //')
483 echo "No tests in range \"$r\"?"
496 # get rid of leading 0s as can be interpreted as octal
497 start
=$
(echo $start |
sed 's/^0*//')
498 end
=$
(echo $end |
sed 's/^0*//')
504 BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
507 if grep -s "^$id\( \|\$\)" "$source_iotests/group" >/dev
/null
509 # in group file ... OK
512 if [ -f expunged
] && $expunge && egrep "^$id([ ]|\$)" expunged
>/dev
/null
514 # expunged ... will be reported, but not run, later
518 if [ "$start" == "$end" -a "$id" == "$end" ]
520 echo "$id - unknown test"
523 echo "$id - unknown test, ignored"
532 # Set qemu-io cache mode with $CACHEMODE we have
533 QEMU_IO_OPTIONS
="$QEMU_IO_OPTIONS --cache $CACHEMODE"
534 # Set qemu-io aio mode with $AIOMODE we have
535 QEMU_IO_OPTIONS
="$QEMU_IO_OPTIONS --aio $AIOMODE"
537 QEMU_IO_OPTIONS_NO_FMT
="$QEMU_IO_OPTIONS"
538 if [ "$IMGOPTSSYNTAX" != "true" ]; then
539 QEMU_IO_OPTIONS
="$QEMU_IO_OPTIONS -f $IMGFMT"
542 # Set default options for qemu-img create -o if they were not specified
543 if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" |
grep "compat=" > /dev
/null
); then
544 IMGOPTS
=$
(_optstr_add
"$IMGOPTS" "compat=1.1")
546 if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" |
grep "iter-time=" > /dev
/null
); then
547 IMGOPTS
=$
(_optstr_add
"$IMGOPTS" "iter-time=10")
549 if [ "$IMGFMT" == "vmdk" ] && ! (echo "$IMGOPTS" |
grep "zeroed_grain=" > /dev
/null
); then
550 IMGOPTS
=$
(_optstr_add
"$IMGOPTS" "zeroed_grain=on")
553 if [ -z "$SAMPLE_IMG_DIR" ]; then
554 SAMPLE_IMG_DIR
="$source_iotests/sample_images"
559 export SAMPLE_IMG_DIR
563 # found some valid test numbers ... this is good
568 # had test numbers, but none in group file ... do nothing
571 # no test numbers, do everything from group file
572 sed -n -e '/^[0-9][0-9][0-9]*/s/^\([0-9]*\).*/\1/p' <"$source_iotests/group" >$tmp.list
576 # should be sort -n, but this did not work for Linux when this
577 # was ported from IRIX
579 list
=$
(sort $tmp.list
)
580 rm -f $tmp.list
$tmp.tmp
$tmp.
sed
582 if [ -z "$QEMU_PROG" ]
584 if [ -x "$build_iotests/qemu" ]; then
585 export QEMU_PROG
="$build_iotests/qemu"
586 elif [ -x "$build_root/qemu-system-${qemu_arch}" ]; then
587 export QEMU_PROG
="$build_root/qemu-system-${qemu_arch}"
589 pushd "$build_root" > /dev
/null
590 for binary
in qemu-system-
*
594 export QEMU_PROG
="$build_root/$binary"
599 [ "$QEMU_PROG" = "" ] && _init_error
"qemu not found"
602 export QEMU_PROG
="$(type -p "$QEMU_PROG")"
604 export QEMU_OPTIONS
="-nodefaults -display none -accel qtest"
606 *qemu-system-arm|
*qemu-system-aarch64
)
607 export QEMU_OPTIONS
="$QEMU_OPTIONS -machine virt"
610 export QEMU_OPTIONS
="$QEMU_OPTIONS -machine mega2560"
613 export QEMU_OPTIONS
="$QEMU_OPTIONS -machine gdbsim-r5f562n8"
615 *qemu-system-tricore
)
616 export QEMU_OPTIONS
="-$QEMU_OPTIONS -machine tricore_testboard"
620 if [ -z "$QEMU_IMG_PROG" ]; then
621 if [ -x "$build_iotests/qemu-img" ]; then
622 export QEMU_IMG_PROG
="$build_iotests/qemu-img"
623 elif [ -x "$build_root/qemu-img" ]; then
624 export QEMU_IMG_PROG
="$build_root/qemu-img"
626 _init_error
"qemu-img not found"
629 export QEMU_IMG_PROG
="$(type -p "$QEMU_IMG_PROG")"
631 if [ -z "$QEMU_IO_PROG" ]; then
632 if [ -x "$build_iotests/qemu-io" ]; then
633 export QEMU_IO_PROG
="$build_iotests/qemu-io"
634 elif [ -x "$build_root/qemu-io" ]; then
635 export QEMU_IO_PROG
="$build_root/qemu-io"
637 _init_error
"qemu-io not found"
640 export QEMU_IO_PROG
="$(type -p "$QEMU_IO_PROG")"
642 if [ -z $QEMU_NBD_PROG ]; then
643 if [ -x "$build_iotests/qemu-nbd" ]; then
644 export QEMU_NBD_PROG
="$build_iotests/qemu-nbd"
645 elif [ -x "$build_root/qemu-nbd" ]; then
646 export QEMU_NBD_PROG
="$build_root/qemu-nbd"
648 _init_error
"qemu-nbd not found"
651 export QEMU_NBD_PROG
="$(type -p "$QEMU_NBD_PROG")"
653 if [ -z "$QSD_PROG" ]; then
654 if [ -x "$build_iotests/qemu-storage-daemon" ]; then
655 export QSD_PROG
="$build_iotests/qemu-storage-daemon"
656 elif [ -x "$build_root/storage-daemon/qemu-storage-daemon" ]; then
657 export QSD_PROG
="$build_root/storage-daemon/qemu-storage-daemon"
659 _init_error
"qemu-storage-daemon not found"
662 export QSD_PROG
="$(type -p "$QSD_PROG")"
664 if [ -x "$build_iotests/socket_scm_helper" ]
666 export SOCKET_SCM_HELPER
="$build_iotests/socket_scm_helper"
670 if $PYTHON -c 'import sys; sys.exit(0 if sys.version_info >= (3,6) else 1)'
672 # Our python framework also requires virtio-blk
673 if "$QEMU_PROG" -M none
-device help |
grep -q virtio-blk
>/dev
/null
2>&1
677 python_unusable_because
="Missing virtio-blk in QEMU binary"
680 python_unusable_because
="Unsupported Python version"
683 default_machine
=$
($QEMU_PROG -machine help |
sed -n '/(default)/ s/ .*//p')
684 default_alias_machine
=$
($QEMU_PROG -machine help | \
685 sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
686 if [[ "$default_alias_machine" ]]; then
687 default_machine
="$default_alias_machine"
690 export QEMU_DEFAULT_MACHINE
="$default_machine"
692 TIMESTAMP_FILE
=check.time-
$IMGPROTO-$IMGFMT
696 date "+%H %M %S" |
awk '{ print $1*3600 + $2*60 + $3 }'
706 if [ -f $TIMESTAMP_FILE -a -f $tmp.
time ]
708 cat $TIMESTAMP_FILE $tmp.
time \
712 for (i in t) print i " " t[i]
716 mv $tmp.out
$TIMESTAMP_FILE
719 if [ -f $tmp.expunged
]
721 notrun
=$
(wc -l <$tmp.expunged |
sed -e 's/ *//g')
722 try
=$
(expr $try - $notrun)
723 list
=$
(echo "$list" |
sed -f $tmp.expunged
)
728 echo $list |
fmt |
sed -e 's/^/ /' >>check.log
729 $interrupt && echo "Interrupted!" >>check.log
731 if [ ! -z "$notrun" ]
733 echo "Not run:$notrun"
734 echo "Not run:$notrun" >>check.log
736 if [ ! -z "$casenotrun" ]
738 echo "Some cases not run in:$casenotrun"
739 echo "Some cases not run in:$casenotrun" >>check.log
741 if [ ! -z "$n_bad" -a $n_bad != 0 ]
744 echo "Failed $n_bad of $try iotests"
745 echo "Failures:$bad" |
fmt >>check.log
746 echo "Failed $n_bad of $try iotests" >>check.log
748 echo "Passed all $try iotests"
749 echo "Passed all $try iotests" >>check.log
754 if test -n "$STTY_RESTORE"; then
757 rm -f "${TEST_DIR}"/*.out "${TEST_DIR}"/*.err "${TEST_DIR}"/*.
time
758 rm -f "${TEST_DIR}"/check.pid
"${TEST_DIR}"/check.sts
767 trap "_wrapup; exit \$status" 0 1 2 3 15
769 # Report the test start and results. For makecheck we want to pretty
770 # print the whole report at the end of the execution.
771 # args: $seq, $starttime, $lasttime
774 if ! $makecheck; then
776 local lasttime
=" (last: $3s)"
778 printf "%-8s %-10s [%s] %4s%-14s\r" "$1" "..." "$2" "..." "$lasttime"
781 # args:$seq $status $starttime $lasttime $thistime $details
782 _report_test_result
()
784 local status lasttime thistime
786 if [ -n "$2" ] && [ "$2" != "pass" ]; then
789 printf " TEST iotest-$IMGFMT: %s%s\n" "$1" "$status"
794 lasttime
=" (last: $4s)"
800 "pass") status
=$
(printf "\e[32m%-10s\e[0m" "$2") ;;
801 "fail") status
=$
(printf "\e[1m\e[31m%-10s\e[0m" "$2") ;;
802 "not run") status
=$
(printf "\e[33m%-10s\e[0m" "$2") ;;
803 *) status
=$
(printf "%-10s" "$2") ;;
806 printf "%-8s %s [%s] [%s] %4s%-14s %s\n" "$1" "$status" "$3" "$(date '+%T')" "$thistime" "$lasttime" "$6"
809 [ -f $TIMESTAMP_FILE ] ||
touch $TIMESTAMP_FILE
811 FULL_IMGFMT_DETAILS
=$
(_full_imgfmt_details
)
812 FULL_HOST_DETAILS
=$
(_full_platform_details
)
814 if ! $makecheck; then
820 [ -n "$TESTS_REMAINING_LOG" ] && echo $list > $TESTS_REMAINING_LOG
824 err
=false
# error flag
825 printdiff
=false
# show diff to reference output?
826 status
="" # test result summary
827 results
="" # test result details
828 thistime
="" # time the test took
830 if [ -n "$TESTS_REMAINING_LOG" ] ; then
831 sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp
832 mv $TESTS_REMAINING_LOG.tmp
$TESTS_REMAINING_LOG
836 lasttime
=$
(sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE)
837 starttime
=$
(date "+%T")
838 _report_test_start
$seq $starttime $lasttime
843 elif [ -f expunged
] && $expunge && egrep "^$seq([ ]|\$)" expunged
>/dev
/null
848 echo "/^$seq\$/d" >>$tmp.expunged
849 elif [ ! -f "$source_iotests/$seq" ]
852 results
="no such test?"
853 echo "/^$seq\$/d" >>$tmp.expunged
855 # really going to try and run this one
858 rm -f core
$seq.notrun
859 rm -f $seq.casenotrun
863 if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python3" ]; then
864 if $python_usable; then
865 run_command
="$PYTHON $seq"
868 echo "$python_unusable_because" > $seq.notrun
873 export OUTPUT_DIR
=$PWD
875 (cd "$source_iotests";
876 MALLOC_PERTURB_
=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
877 $run_command -d 2>&1 |
tee $tmp.out
)
879 (cd "$source_iotests";
880 MALLOC_PERTURB_
=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
881 $run_command >$tmp.out
2>&1)
890 results
="[dumped core] $seq.core"
894 if [ -f $seq.notrun
]
896 # overwrites timestamp output
898 results
="$(cat $seq.notrun)"
903 results
=$
(printf %s
"[failed, exit status $sts]")
907 reference
="$source_iotests/$seq.out"
908 reference_machine
="$source_iotests/$seq.$QEMU_DEFAULT_MACHINE.out"
909 if [ -f "$reference_machine" ]; then
910 reference
="$reference_machine"
913 reference_format
="$source_iotests/$seq.out.$IMGFMT"
914 if [ -f "$reference_format" ]; then
915 reference
="$reference_format"
918 if [ "$CACHEMODE" = "none" ]; then
919 [ -f "$source_iotests/$seq.out.nocache" ] && reference
="$source_iotests/$seq.out.nocache"
922 if [ ! -f "$reference" ]
925 results
="no qualified output"
928 if diff -w "$reference" $tmp.out
>/dev
/null
2>&1
932 thistime
=$
(expr $stop - $start)
933 echo "$seq $thistime" >>$tmp.
time
936 mv $tmp.out
$seq.out.bad
938 results
="output mismatch (see $seq.out.bad)"
944 if [ -f $seq.casenotrun
]
947 casenotrun
="$casenotrun $seq"
951 # come here for each test, except when $showme is true
953 _report_test_result
$seq "$status" "$starttime" "$lasttime" "$thistime" "$results"
964 $diff -w "$reference" "$PWD"/$seq.out.bad
967 n_bad
=$
(expr $n_bad + 1)
971 notrun
="$notrun $seq"
979 status
=$
(expr $n_bad)