commit: Make base read-only if there is an early failure
[qemu/ar7.git] / tests / qemu-iotests / check
blobf9c24b6753c3c3c3a47c7393962396a8fd088668
1 #!/usr/bin/env bash
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
22 status=0
23 needwrap=true
24 try=0
25 n_bad=0
26 bad=""
27 notrun=""
28 casenotrun=""
29 interrupt=true
31 # by default don't output timestamps
32 timestamp=${TIMESTAMP:=false}
34 _init_error()
36 echo "check: $1" >&2
37 exit 1
40 if [ -L "$0" ]
41 then
42 # called from the build tree
43 source_iotests=$(dirname "$(readlink "$0")")
44 if [ -z "$source_iotests" ]
45 then
46 _init_error "failed to obtain source tree name from check symlink"
48 source_iotests=$(cd "$source_iotests"; pwd) || _init_error "failed to enter source tree"
49 build_iotests=$PWD
50 else
51 # called from the source tree
52 source_iotests=$PWD
53 # this may be an in-tree build (note that in the following code we may not
54 # assume that it truly is and have to test whether the build results
55 # actually exist)
56 build_iotests=$PWD
59 build_root="$build_iotests/../.."
61 # we need common.env
62 if ! . "$build_iotests/common.env"
63 then
64 _init_error "failed to source common.env (make sure the qemu-iotests are run from tests/qemu-iotests in the build tree)"
67 # we need common.config
68 if ! . "$source_iotests/common.config"
69 then
70 _init_error "failed to source common.config"
73 _full_imgfmt_details()
75 if [ -n "$IMGOPTS" ]; then
76 echo "$IMGFMT ($IMGOPTS)"
77 else
78 echo "$IMGFMT"
82 _full_platform_details()
84 os=$(uname -s)
85 host=$(hostname -s)
86 kernel=$(uname -r)
87 platform=$(uname -m)
88 echo "$os/$platform $host $kernel"
91 # $1 = prog to look for
92 set_prog_path()
94 p=$(command -v $1 2> /dev/null)
95 if [ -n "$p" -a -x "$p" ]; then
96 type -p "$p"
97 else
98 return 1
102 if [ -z "$TEST_DIR" ]; then
103 TEST_DIR=$PWD/scratch
106 if [ ! -e "$TEST_DIR" ]; then
107 mkdir "$TEST_DIR"
110 diff="diff -u"
111 verbose=false
112 debug=false
113 group=false
114 xgroup=false
115 imgopts=false
116 showme=false
117 sortme=false
118 expunge=true
119 have_test_arg=false
120 cachemode=false
122 tmp="${TEST_DIR}"/$$
123 rm -f $tmp.list $tmp.tmp $tmp.sed
125 export IMGFMT=raw
126 export IMGFMT_GENERIC=true
127 export IMGPROTO=file
128 export IMGOPTS=""
129 export CACHEMODE="writeback"
130 export QEMU_IO_OPTIONS=""
131 export QEMU_IO_OPTIONS_NO_FMT=""
132 export CACHEMODE_IS_DEFAULT=true
133 export QEMU_OPTIONS="-nodefaults -machine accel=qtest"
134 export VALGRIND_QEMU=
135 export IMGKEYSECRET=
136 export IMGOPTSSYNTAX=false
138 # Save current tty settings, since an aborting qemu call may leave things
139 # screwed up
140 STTY_RESTORE=
141 if test -t 0; then
142 STTY_RESTORE=$(stty -g)
145 for r
148 if $group
149 then
150 # arg after -g
151 group_list=$(sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
152 s/ .*//p
154 if [ -z "$group_list" ]
155 then
156 echo "Group \"$r\" is empty or not defined?"
157 exit 1
159 [ ! -s $tmp.list ] && touch $tmp.list
160 for t in $group_list
162 if grep -s "^$t\$" $tmp.list >/dev/null
163 then
165 else
166 echo "$t" >>$tmp.list
168 done
169 group=false
170 continue
172 elif $xgroup
173 then
174 # arg after -x
175 # Populate $tmp.list with all tests
176 awk '/^[0-9]{3,}/ {print $1}' "${source_iotests}/group" > $tmp.list 2>/dev/null
177 group_list=$(sed -n <"$source_iotests/group" -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
178 s/ .*//p
180 if [ -z "$group_list" ]
181 then
182 echo "Group \"$r\" is empty or not defined?"
183 exit 1
185 numsed=0
186 rm -f $tmp.sed
187 for t in $group_list
189 if [ $numsed -gt 100 ]
190 then
191 sed -f $tmp.sed <$tmp.list >$tmp.tmp
192 mv $tmp.tmp $tmp.list
193 numsed=0
194 rm -f $tmp.sed
196 echo "/^$t\$/d" >>$tmp.sed
197 numsed=$(expr $numsed + 1)
198 done
199 sed -f $tmp.sed <$tmp.list >$tmp.tmp
200 mv $tmp.tmp $tmp.list
201 xgroup=false
202 continue
204 elif $imgopts
205 then
206 IMGOPTS="$r"
207 imgopts=false
208 continue
209 elif $cachemode
210 then
211 CACHEMODE="$r"
212 CACHEMODE_IS_DEFAULT=false
213 cachemode=false
214 continue
217 xpand=true
218 case "$r"
221 -\? | -h | --help) # usage
222 echo "Usage: $0 [options] [testlist]"'
224 common options
225 -v verbose
226 -d debug
228 image format options
229 -raw test raw (default)
230 -bochs test bochs
231 -cloop test cloop
232 -parallels test parallels
233 -qcow test qcow
234 -qcow2 test qcow2
235 -qed test qed
236 -vdi test vdi
237 -vpc test vpc
238 -vhdx test vhdx
239 -vmdk test vmdk
240 -luks test luks
241 -dmg test dmg
243 image protocol options
244 -file test file (default)
245 -rbd test rbd
246 -sheepdog test sheepdog
247 -nbd test nbd
248 -ssh test ssh
249 -nfs test nfs
250 -vxhs test vxhs
252 other options
253 -xdiff graphical mode diff
254 -nocache use O_DIRECT on backing file
255 -misalign misalign memory allocations
256 -n show me, do not run tests
257 -o options -o options to pass to qemu-img create/convert
258 -T output timestamps
259 -c mode cache mode
261 testlist options
262 -g group[,group...] include tests from these groups
263 -x group[,group...] exclude tests from these groups
264 NNN include test NNN
265 NNN-NNN include test range (eg. 012-021)
267 exit 0
270 -raw)
271 IMGFMT=raw
272 xpand=false
275 -bochs)
276 IMGFMT=bochs
277 IMGFMT_GENERIC=false
278 xpand=false
281 -cloop)
282 IMGFMT=cloop
283 IMGFMT_GENERIC=false
284 xpand=false
287 -parallels)
288 IMGFMT=parallels
289 xpand=false
292 -qcow)
293 IMGFMT=qcow
294 xpand=false
297 -qcow2)
298 IMGFMT=qcow2
299 xpand=false
302 -luks)
303 IMGOPTSSYNTAX=true
304 IMGFMT=luks
305 IMGKEYSECRET=123456
306 xpand=false
309 -dmg)
310 IMGFMT=dmg
311 IMGFMT_GENERIC=false
312 xpand=false
315 -qed)
316 IMGFMT=qed
317 xpand=false
320 -vdi)
321 IMGFMT=vdi
322 xpand=false
325 -vmdk)
326 IMGFMT=vmdk
327 xpand=false
330 -vpc)
331 IMGFMT=vpc
332 xpand=false
335 -vhdx)
336 IMGFMT=vhdx
337 xpand=false
340 -file)
341 IMGPROTO=file
342 xpand=false
345 -rbd)
346 IMGPROTO=rbd
347 xpand=false
350 -sheepdog)
351 IMGPROTO=sheepdog
352 xpand=false
355 -nbd)
356 IMGPROTO=nbd
357 xpand=false
360 -vxhs)
361 IMGPROTO=vxhs
362 xpand=false
365 -ssh)
366 IMGPROTO=ssh
367 xpand=false
370 -nfs)
371 IMGPROTO=nfs
372 xpand=false
375 -nocache)
376 CACHEMODE="none"
377 CACHEMODE_IS_DEFAULT=false
378 xpand=false
381 -misalign)
382 QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --misalign"
383 xpand=false
386 -valgrind)
387 VALGRIND_QEMU='y'
388 xpand=false
391 -g) # -g group ... pick from group file
392 group=true
393 xpand=false
396 -xdiff) # graphical diff mode
397 xpand=false
399 if [ ! -z "$DISPLAY" ]
400 then
401 command -v xdiff >/dev/null 2>&1 && diff=xdiff
402 command -v gdiff >/dev/null 2>&1 && diff=gdiff
403 command -v tkdiff >/dev/null 2>&1 && diff=tkdiff
404 command -v xxdiff >/dev/null 2>&1 && diff=xxdiff
408 -n) # show me, don't do it
409 showme=true
410 xpand=false
413 imgopts=true
414 xpand=false
417 cachemode=true
418 xpand=false
420 -T) # turn on timestamp output
421 timestamp=true
422 xpand=false
426 verbose=true
427 xpand=false
430 debug=true
431 xpand=false
433 -x) # -x group ... exclude from group file
434 xgroup=true
435 xpand=false
437 '[0-9][0-9][0-9] [0-9][0-9][0-9][0-9]')
438 echo "No tests?"
439 status=1
440 exit $status
443 [0-9]*-[0-9]*)
444 eval $(echo $r | sed -e 's/^/start=/' -e 's/-/ end=/')
447 [0-9]*-)
448 eval $(echo $r | sed -e 's/^/start=/' -e 's/-//')
449 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/.* //')
450 if [ -z "$end" ]
451 then
452 echo "No tests in range \"$r\"?"
453 status=1
454 exit $status
459 start=$r
460 end=$r
463 esac
465 # get rid of leading 0s as can be interpreted as octal
466 start=$(echo $start | sed 's/^0*//')
467 end=$(echo $end | sed 's/^0*//')
469 if $xpand
470 then
471 have_test_arg=true
472 awk </dev/null '
473 BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
474 | while read id
476 if grep -s "^$id " "$source_iotests/group" >/dev/null
477 then
478 # in group file ... OK
479 echo $id >>$tmp.list
480 else
481 if [ -f expunged ] && $expunge && egrep "^$id([ ]|\$)" expunged >/dev/null
482 then
483 # expunged ... will be reported, but not run, later
484 echo $id >>$tmp.list
485 else
486 # oops
487 if [ "$start" == "$end" -a "$id" == "$end" ]
488 then
489 echo "$id - unknown test"
490 exit 1
491 else
492 echo "$id - unknown test, ignored"
496 done || exit 1
499 done
501 # Set qemu-io cache mode with $CACHEMODE we have
502 QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE"
504 QEMU_IO_OPTIONS_NO_FMT="$QEMU_IO_OPTIONS"
505 if [ "$IMGOPTSSYNTAX" != "true" ]; then
506 QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT"
509 # Set default options for qemu-img create -o if they were not specified
510 if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" | grep "compat=" > /dev/null); then
511 IMGOPTS=$(_optstr_add "$IMGOPTS" "compat=1.1")
513 if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" | grep "iter-time=" > /dev/null); then
514 IMGOPTS=$(_optstr_add "$IMGOPTS" "iter-time=10")
517 if [ -z "$SAMPLE_IMG_DIR" ]; then
518 SAMPLE_IMG_DIR="$source_iotests/sample_images"
521 export TEST_DIR
522 export SAMPLE_IMG_DIR
524 if [ -s $tmp.list ]
525 then
526 # found some valid test numbers ... this is good
528 else
529 if $have_test_arg
530 then
531 # had test numbers, but none in group file ... do nothing
532 touch $tmp.list
533 else
534 # no test numbers, do everything from group file
535 sed -n -e '/^[0-9][0-9][0-9]*/s/[ ].*//p' <"$source_iotests/group" >$tmp.list
539 # should be sort -n, but this did not work for Linux when this
540 # was ported from IRIX
542 list=$(sort $tmp.list)
543 rm -f $tmp.list $tmp.tmp $tmp.sed
545 if [ -z "$QEMU_PROG" ]
546 then
547 if [ -x "$build_iotests/qemu" ]; then
548 export QEMU_PROG="$build_iotests/qemu"
549 elif [ -x "$build_root/${qemu_arch}-softmmu/qemu-system-${qemu_arch}" ]; then
550 export QEMU_PROG="$build_root/${qemu_arch}-softmmu/qemu-system-${qemu_arch}"
551 else
552 pushd "$build_root" > /dev/null
553 for binary in *-softmmu/qemu-system-*
555 if [ -x "$binary" ]
556 then
557 export QEMU_PROG="$build_root/$binary"
558 break
560 done
561 popd > /dev/null
562 [ "$QEMU_PROG" = "" ] && _init_error "qemu not found"
565 export QEMU_PROG="$(type -p "$QEMU_PROG")"
567 if [ -z "$QEMU_IMG_PROG" ]; then
568 if [ -x "$build_iotests/qemu-img" ]; then
569 export QEMU_IMG_PROG="$build_iotests/qemu-img"
570 elif [ -x "$build_root/qemu-img" ]; then
571 export QEMU_IMG_PROG="$build_root/qemu-img"
572 else
573 _init_error "qemu-img not found"
576 export QEMU_IMG_PROG="$(type -p "$QEMU_IMG_PROG")"
578 if [ -z "$QEMU_IO_PROG" ]; then
579 if [ -x "$build_iotests/qemu-io" ]; then
580 export QEMU_IO_PROG="$build_iotests/qemu-io"
581 elif [ -x "$build_root/qemu-io" ]; then
582 export QEMU_IO_PROG="$build_root/qemu-io"
583 else
584 _init_error "qemu-io not found"
587 export QEMU_IO_PROG="$(type -p "$QEMU_IO_PROG")"
589 if [ -z $QEMU_NBD_PROG ]; then
590 if [ -x "$build_iotests/qemu-nbd" ]; then
591 export QEMU_NBD_PROG="$build_iotests/qemu-nbd"
592 elif [ -x "$build_root/qemu-nbd" ]; then
593 export QEMU_NBD_PROG="$build_root/qemu-nbd"
594 else
595 _init_error "qemu-nbd not found"
598 export QEMU_NBD_PROG="$(type -p "$QEMU_NBD_PROG")"
600 if [ -z "$QEMU_VXHS_PROG" ]; then
601 export QEMU_VXHS_PROG="$(set_prog_path qnio_server)"
604 if [ -x "$build_iotests/socket_scm_helper" ]
605 then
606 export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
609 default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p')
610 default_alias_machine=$($QEMU_PROG -machine help | \
611 sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
612 if [[ "$default_alias_machine" ]]; then
613 default_machine="$default_alias_machine"
616 export QEMU_DEFAULT_MACHINE="$default_machine"
618 TIMESTAMP_FILE=check.time-$IMGPROTO-$IMGFMT
620 _wallclock()
622 date "+%H %M %S" | awk '{ print $1*3600 + $2*60 + $3 }'
625 _timestamp()
627 now=$(date "+%T")
628 printf %s " [$now]"
631 _wrapup()
633 if $showme
634 then
636 elif $needwrap
637 then
638 if [ -f $TIMESTAMP_FILE -a -f $tmp.time ]
639 then
640 cat $TIMESTAMP_FILE $tmp.time \
641 | awk '
642 { t[$1] = $2 }
643 END { if (NR > 0) {
644 for (i in t) print i " " t[i]
646 }' \
647 | sort -n >$tmp.out
648 mv $tmp.out $TIMESTAMP_FILE
651 if [ -f $tmp.expunged ]
652 then
653 notrun=$(wc -l <$tmp.expunged | sed -e 's/ *//g')
654 try=$(expr $try - $notrun)
655 list=$(echo "$list" | sed -f $tmp.expunged)
658 echo "" >>check.log
659 date >>check.log
660 echo $list | fmt | sed -e 's/^/ /' >>check.log
661 $interrupt && echo "Interrupted!" >>check.log
663 if [ ! -z "$notrun" ]
664 then
665 echo "Not run:$notrun"
666 echo "Not run:$notrun" >>check.log
668 if [ ! -z "$casenotrun" ]
669 then
670 echo "Some cases not run in:$casenotrun"
671 echo "Some cases not run in:$casenotrun" >>check.log
673 if [ ! -z "$n_bad" -a $n_bad != 0 ]
674 then
675 echo "Failures:$bad"
676 echo "Failed $n_bad of $try tests"
677 echo "Failures:$bad" | fmt >>check.log
678 echo "Failed $n_bad of $try tests" >>check.log
679 else
680 echo "Passed all $try tests"
681 echo "Passed all $try tests" >>check.log
683 needwrap=false
686 if test -n "$STTY_RESTORE"; then
687 stty $STTY_RESTORE
689 rm -f "${TEST_DIR}"/*.out "${TEST_DIR}"/*.err "${TEST_DIR}"/*.time
690 rm -f "${TEST_DIR}"/check.pid "${TEST_DIR}"/check.sts
691 rm -f $tmp.*
694 trap "_wrapup; exit \$status" 0 1 2 3 15
696 [ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE
698 FULL_IMGFMT_DETAILS=$(_full_imgfmt_details)
699 FULL_HOST_DETAILS=$(_full_platform_details)
701 cat <<EOF
702 QEMU -- "$QEMU_PROG" $QEMU_OPTIONS
703 QEMU_IMG -- "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS
704 QEMU_IO -- "$QEMU_IO_PROG" $QEMU_IO_OPTIONS
705 QEMU_NBD -- "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS
706 IMGFMT -- $FULL_IMGFMT_DETAILS
707 IMGPROTO -- $IMGPROTO
708 PLATFORM -- $FULL_HOST_DETAILS
709 TEST_DIR -- $TEST_DIR
710 SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER
714 seq="check"
716 [ -n "$TESTS_REMAINING_LOG" ] && echo $list > $TESTS_REMAINING_LOG
718 for seq in $list
720 err=false
721 printf %s "$seq"
722 if [ -n "$TESTS_REMAINING_LOG" ] ; then
723 sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp
724 mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG
725 sync
728 if $showme
729 then
730 echo
731 continue
732 elif [ -f expunged ] && $expunge && egrep "^$seq([ ]|\$)" expunged >/dev/null
733 then
734 echo " - expunged"
735 rm -f $seq.out.bad
736 echo "/^$seq\$/d" >>$tmp.expunged
737 elif [ ! -f "$source_iotests/$seq" ]
738 then
739 echo " - no such test?"
740 echo "/^$seq\$/d" >>$tmp.expunged
741 else
742 # really going to try and run this one
744 rm -f $seq.out.bad
745 lasttime=$(sed -n -e "/^$seq /s/.* //p" <$TIMESTAMP_FILE)
746 if [ "X$lasttime" != X ]; then
747 printf %s " ${lasttime}s ..."
748 else
749 printf " " # prettier output with timestamps.
751 rm -f core $seq.notrun
752 rm -f $seq.casenotrun
754 start=$(_wallclock)
755 $timestamp && printf %s " [$(date "+%T")]"
757 if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then
758 run_command="$PYTHON $seq"
759 else
760 run_command="./$seq"
762 export OUTPUT_DIR=$PWD
763 if $debug; then
764 (cd "$source_iotests";
765 MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
766 $run_command -d 2>&1 | tee $tmp.out)
767 else
768 (cd "$source_iotests";
769 MALLOC_PERTURB_=${MALLOC_PERTURB_:-$(($RANDOM % 255 + 1))} \
770 $run_command >$tmp.out 2>&1)
772 sts=$?
773 $timestamp && _timestamp
774 stop=$(_wallclock)
776 if [ -f core ]
777 then
778 printf " [dumped core]"
779 mv core $seq.core
780 err=true
783 if [ -f $seq.notrun ]
784 then
785 $timestamp || printf " [not run] "
786 $timestamp && echo " [not run]" && printf %s " $seq -- "
787 cat $seq.notrun
788 notrun="$notrun $seq"
789 else
790 if [ $sts -ne 0 ]
791 then
792 printf %s " [failed, exit status $sts]"
793 err=true
796 reference="$source_iotests/$seq.out"
797 reference_machine="$source_iotests/$seq.$QEMU_DEFAULT_MACHINE.out"
798 if [ -f "$reference_machine" ]; then
799 reference="$reference_machine"
802 reference_format="$source_iotests/$seq.out.$IMGFMT"
803 if [ -f "$reference_format" ]; then
804 reference="$reference_format"
807 if [ "$CACHEMODE" = "none" ]; then
808 [ -f "$source_iotests/$seq.out.nocache" ] && reference="$source_iotests/$seq.out.nocache"
811 if [ ! -f "$reference" ]
812 then
813 echo " - no qualified output"
814 err=true
815 else
816 if diff -w "$reference" $tmp.out >/dev/null 2>&1
817 then
818 echo ""
819 if $err
820 then
822 else
823 echo "$seq $(expr $stop - $start)" >>$tmp.time
825 else
826 echo " - output mismatch (see $seq.out.bad)"
827 mv $tmp.out $seq.out.bad
828 $diff -w "$reference" "$PWD"/$seq.out.bad
829 err=true
833 if [ -f $seq.casenotrun ]
834 then
835 cat $seq.casenotrun
836 casenotrun="$casenotrun $seq"
840 # come here for each test, except when $showme is true
842 if $err
843 then
844 bad="$bad $seq"
845 n_bad=$(expr $n_bad + 1)
846 quick=false
848 [ -f $seq.notrun ] || try=$(expr $try + 1)
850 seq="after_$seq"
851 done
853 interrupt=false
854 status=$(expr $n_bad)
855 exit