xref: /openbmc/qemu/tests/qemu-iotests/check (revision 58ea30f5)
1#!/usr/bin/env bash
2#
3# Copyright (C) 2009 Red Hat, Inc.
4# Copyright (c) 2000-2002,2006 Silicon Graphics, Inc.  All Rights Reserved.
5#
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.
9#
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.
14#
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/>.
17#
18#
19# Control script for QA
20#
21
22status=0
23needwrap=true
24try=0
25n_bad=0
26bad=""
27notrun=""
28casenotrun=""
29interrupt=true
30
31# by default don't output timestamps
32timestamp=${TIMESTAMP:=false}
33
34_init_error()
35{
36    echo "check: $1" >&2
37    exit 1
38}
39
40if [ -L "$0" ]
41then
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"
47    fi
48    source_iotests=$(cd "$source_iotests"; pwd) || _init_error "failed to enter source tree"
49    build_iotests=$PWD
50else
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
57fi
58
59build_root="$build_iotests/../.."
60
61# we need common.env
62if ! . "$build_iotests/common.env"
63then
64    _init_error "failed to source common.env (make sure the qemu-iotests are run from tests/qemu-iotests in the build tree)"
65fi
66
67# we need common.config
68if ! . "$source_iotests/common.config"
69then
70    _init_error "failed to source common.config"
71fi
72
73_full_imgfmt_details()
74{
75    if [ -n "$IMGOPTS" ]; then
76        echo "$IMGFMT ($IMGOPTS)"
77    else
78        echo "$IMGFMT"
79    fi
80}
81
82_full_platform_details()
83{
84    os=$(uname -s)
85    host=$(hostname -s)
86    kernel=$(uname -r)
87    platform=$(uname -m)
88    echo "$os/$platform $host $kernel"
89}
90
91# $1 = prog to look for
92set_prog_path()
93{
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
99    fi
100}
101
102if [ -z "$TEST_DIR" ]; then
103        TEST_DIR=$PWD/scratch
104fi
105
106if [ ! -e "$TEST_DIR" ]; then
107        mkdir "$TEST_DIR"
108fi
109
110diff="diff -u"
111verbose=false
112debug=false
113group=false
114xgroup=false
115imgopts=false
116showme=false
117sortme=false
118expunge=true
119have_test_arg=false
120cachemode=false
121
122tmp="${TEST_DIR}"/$$
123rm -f $tmp.list $tmp.tmp $tmp.sed
124
125export IMGFMT=raw
126export IMGFMT_GENERIC=true
127export IMGPROTO=file
128export IMGOPTS=""
129export CACHEMODE="writeback"
130export QEMU_IO_OPTIONS=""
131export QEMU_IO_OPTIONS_NO_FMT=""
132export CACHEMODE_IS_DEFAULT=true
133export QEMU_OPTIONS="-nodefaults -machine accel=qtest"
134export VALGRIND_QEMU=
135export IMGKEYSECRET=
136export IMGOPTSSYNTAX=false
137
138# Save current tty settings, since an aborting qemu call may leave things
139# screwed up
140STTY_RESTORE=
141if test -t 0; then
142    STTY_RESTORE=$(stty -g)
143fi
144
145for r
146do
147
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 /"'{
152s/ .*//p
153}')
154        if [ -z "$group_list" ]
155        then
156            echo "Group \"$r\" is empty or not defined?"
157            exit 1
158        fi
159        [ ! -s $tmp.list ] && touch $tmp.list
160        for t in $group_list
161        do
162            if grep -s "^$t\$" $tmp.list >/dev/null
163            then
164                :
165            else
166                echo "$t" >>$tmp.list
167            fi
168        done
169        group=false
170        continue
171
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 /"'{
178s/ .*//p
179}')
180        if [ -z "$group_list" ]
181        then
182            echo "Group \"$r\" is empty or not defined?"
183            exit 1
184        fi
185        numsed=0
186        rm -f $tmp.sed
187        for t in $group_list
188        do
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
195            fi
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
203
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
215    fi
216
217    xpand=true
218    case "$r"
219    in
220
221        -\? | -h | --help)        # usage
222            echo "Usage: $0 [options] [testlist]"'
223
224common options
225    -v                  verbose
226    -d                  debug
227
228image 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
242
243image 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
251
252other 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
260
261testlist 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)
266'
267            exit 0
268            ;;
269
270        -raw)
271            IMGFMT=raw
272            xpand=false
273            ;;
274
275        -bochs)
276            IMGFMT=bochs
277            IMGFMT_GENERIC=false
278            xpand=false
279            ;;
280
281        -cloop)
282            IMGFMT=cloop
283            IMGFMT_GENERIC=false
284            xpand=false
285            ;;
286
287        -parallels)
288            IMGFMT=parallels
289            xpand=false
290            ;;
291
292        -qcow)
293            IMGFMT=qcow
294            xpand=false
295            ;;
296
297        -qcow2)
298            IMGFMT=qcow2
299            xpand=false
300            ;;
301
302        -luks)
303            IMGOPTSSYNTAX=true
304            IMGFMT=luks
305            IMGKEYSECRET=123456
306            xpand=false
307            ;;
308
309        -dmg)
310            IMGFMT=dmg
311            IMGFMT_GENERIC=false
312            xpand=false
313            ;;
314
315        -qed)
316            IMGFMT=qed
317            xpand=false
318            ;;
319
320        -vdi)
321            IMGFMT=vdi
322            xpand=false
323            ;;
324
325        -vmdk)
326            IMGFMT=vmdk
327            xpand=false
328            ;;
329
330        -vpc)
331            IMGFMT=vpc
332            xpand=false
333            ;;
334
335        -vhdx)
336            IMGFMT=vhdx
337            xpand=false
338            ;;
339
340        -file)
341            IMGPROTO=file
342            xpand=false
343            ;;
344
345        -rbd)
346            IMGPROTO=rbd
347            xpand=false
348            ;;
349
350        -sheepdog)
351            IMGPROTO=sheepdog
352            xpand=false
353            ;;
354
355        -nbd)
356            IMGPROTO=nbd
357            xpand=false
358            ;;
359
360        -vxhs)
361            IMGPROTO=vxhs
362            xpand=false
363            ;;
364
365        -ssh)
366            IMGPROTO=ssh
367            xpand=false
368            ;;
369
370        -nfs)
371            IMGPROTO=nfs
372            xpand=false
373            ;;
374
375        -nocache)
376            CACHEMODE="none"
377            CACHEMODE_IS_DEFAULT=false
378            xpand=false
379            ;;
380
381        -misalign)
382            QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --misalign"
383            xpand=false
384            ;;
385
386        -valgrind)
387            VALGRIND_QEMU='y'
388            xpand=false
389            ;;
390
391        -g)        # -g group ... pick from group file
392            group=true
393            xpand=false
394            ;;
395
396        -xdiff)        # graphical diff mode
397            xpand=false
398
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
405            fi
406            ;;
407
408        -n)        # show me, don't do it
409            showme=true
410            xpand=false
411            ;;
412        -o)
413            imgopts=true
414            xpand=false
415            ;;
416        -c)
417            cachemode=true
418            xpand=false
419            ;;
420        -T)        # turn on timestamp output
421            timestamp=true
422            xpand=false
423            ;;
424
425        -v)
426            verbose=true
427            xpand=false
428            ;;
429        -d)
430            debug=true
431            xpand=false
432            ;;
433        -x)        # -x group ... exclude from group file
434            xgroup=true
435            xpand=false
436            ;;
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
441            ;;
442
443        [0-9]*-[0-9]*)
444            eval $(echo $r | sed -e 's/^/start=/' -e 's/-/ end=/')
445            ;;
446
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
455            fi
456            ;;
457
458        *)
459            start=$r
460            end=$r
461            ;;
462
463    esac
464
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*//')
468
469    if $xpand
470    then
471        have_test_arg=true
472        awk </dev/null '
473BEGIN        { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
474        | while read id
475        do
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"
493                    fi
494                fi
495            fi
496        done || exit 1
497    fi
498
499done
500
501# Set qemu-io cache mode with $CACHEMODE we have
502QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS --cache $CACHEMODE"
503
504QEMU_IO_OPTIONS_NO_FMT="$QEMU_IO_OPTIONS"
505if [ "$IMGOPTSSYNTAX" != "true" ]; then
506    QEMU_IO_OPTIONS="$QEMU_IO_OPTIONS -f $IMGFMT"
507fi
508
509# Set default options for qemu-img create -o if they were not specified
510if [ "$IMGFMT" == "qcow2" ] && ! (echo "$IMGOPTS" | grep "compat=" > /dev/null); then
511    IMGOPTS=$(_optstr_add "$IMGOPTS" "compat=1.1")
512fi
513if [ "$IMGFMT" == "luks" ] && ! (echo "$IMGOPTS" | grep "iter-time=" > /dev/null); then
514    IMGOPTS=$(_optstr_add "$IMGOPTS" "iter-time=10")
515fi
516
517if [ -z "$SAMPLE_IMG_DIR" ]; then
518        SAMPLE_IMG_DIR="$source_iotests/sample_images"
519fi
520
521export TEST_DIR
522export SAMPLE_IMG_DIR
523
524if [ -s $tmp.list ]
525then
526    # found some valid test numbers ... this is good
527    :
528else
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
536    fi
537fi
538
539# should be sort -n, but this did not work for Linux when this
540# was ported from IRIX
541#
542list=$(sort $tmp.list)
543rm -f $tmp.list $tmp.tmp $tmp.sed
544
545if [ -z "$QEMU_PROG" ]
546then
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-*
554        do
555            if [ -x "$binary" ]
556            then
557                export QEMU_PROG="$build_root/$binary"
558                break
559            fi
560        done
561        popd > /dev/null
562        [ "$QEMU_PROG" = "" ] && _init_error "qemu not found"
563    fi
564fi
565export QEMU_PROG="$(type -p "$QEMU_PROG")"
566
567if [ -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"
574    fi
575fi
576export QEMU_IMG_PROG="$(type -p "$QEMU_IMG_PROG")"
577
578if [ -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"
585    fi
586fi
587export QEMU_IO_PROG="$(type -p "$QEMU_IO_PROG")"
588
589if [ -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"
596    fi
597fi
598export QEMU_NBD_PROG="$(type -p "$QEMU_NBD_PROG")"
599
600if [ -z "$QEMU_VXHS_PROG" ]; then
601    export QEMU_VXHS_PROG="$(set_prog_path qnio_server)"
602fi
603
604if [ -x "$build_iotests/socket_scm_helper" ]
605then
606    export SOCKET_SCM_HELPER="$build_iotests/socket_scm_helper"
607fi
608
609default_machine=$($QEMU_PROG -machine help | sed -n '/(default)/ s/ .*//p')
610default_alias_machine=$($QEMU_PROG -machine help | \
611   sed -n "/(alias of $default_machine)/ { s/ .*//p; q; }")
612if [[ "$default_alias_machine" ]]; then
613    default_machine="$default_alias_machine"
614fi
615
616export QEMU_DEFAULT_MACHINE="$default_machine"
617
618TIMESTAMP_FILE=check.time-$IMGPROTO-$IMGFMT
619
620_wallclock()
621{
622    date "+%H %M %S" | awk '{ print $1*3600 + $2*60 + $3 }'
623}
624
625_timestamp()
626{
627    now=$(date "+%T")
628    printf %s " [$now]"
629}
630
631_wrapup()
632{
633    if $showme
634    then
635        :
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 }
643END        { if (NR > 0) {
644            for (i in t) print i " " t[i]
645          }
646        }' \
647            | sort -n >$tmp.out
648            mv $tmp.out $TIMESTAMP_FILE
649        fi
650
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)
656        fi
657
658        echo "" >>check.log
659        date >>check.log
660        echo $list | fmt | sed -e 's/^/    /' >>check.log
661        $interrupt && echo "Interrupted!" >>check.log
662
663        if [ ! -z "$notrun" ]
664        then
665            echo "Not run:$notrun"
666            echo "Not run:$notrun" >>check.log
667        fi
668        if [ ! -z "$casenotrun" ]
669        then
670            echo "Some cases not run in:$casenotrun"
671            echo "Some cases not run in:$casenotrun" >>check.log
672        fi
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
682        fi
683        needwrap=false
684    fi
685
686    if test -n "$STTY_RESTORE"; then
687        stty $STTY_RESTORE
688    fi
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.*
692}
693
694trap "_wrapup; exit \$status" 0 1 2 3 15
695
696[ -f $TIMESTAMP_FILE ] || touch $TIMESTAMP_FILE
697
698FULL_IMGFMT_DETAILS=$(_full_imgfmt_details)
699FULL_HOST_DETAILS=$(_full_platform_details)
700
701cat <<EOF
702QEMU          -- "$QEMU_PROG" $QEMU_OPTIONS
703QEMU_IMG      -- "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS
704QEMU_IO       -- "$QEMU_IO_PROG" $QEMU_IO_OPTIONS
705QEMU_NBD      -- "$QEMU_NBD_PROG" $QEMU_NBD_OPTIONS
706IMGFMT        -- $FULL_IMGFMT_DETAILS
707IMGPROTO      -- $IMGPROTO
708PLATFORM      -- $FULL_HOST_DETAILS
709TEST_DIR      -- $TEST_DIR
710SOCKET_SCM_HELPER -- $SOCKET_SCM_HELPER
711
712EOF
713
714seq="check"
715
716[ -n "$TESTS_REMAINING_LOG" ] && echo $list > $TESTS_REMAINING_LOG
717
718for seq in $list
719do
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
726    fi
727
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
743        #
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.
750        fi
751        rm -f core $seq.notrun
752        rm -f $seq.casenotrun
753
754        start=$(_wallclock)
755        $timestamp && printf %s "        [$(date "+%T")]"
756
757        if [ "$(head -n 1 "$source_iotests/$seq")" == "#!/usr/bin/env python" ]; then
758            run_command="$PYTHON $seq"
759        else
760            run_command="./$seq"
761        fi
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)
771        fi
772        sts=$?
773        $timestamp && _timestamp
774        stop=$(_wallclock)
775
776        if [ -f core ]
777        then
778            printf " [dumped core]"
779            mv core $seq.core
780            err=true
781        fi
782
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
794            fi
795
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"
800            fi
801
802            reference_format="$source_iotests/$seq.out.$IMGFMT"
803            if [ -f "$reference_format" ]; then
804                reference="$reference_format"
805            fi
806
807            if [ "$CACHEMODE" = "none" ]; then
808                [ -f "$source_iotests/$seq.out.nocache" ] && reference="$source_iotests/$seq.out.nocache"
809            fi
810
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
821                        :
822                    else
823                        echo "$seq $(expr $stop - $start)" >>$tmp.time
824                    fi
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
830                fi
831            fi
832        fi
833        if [ -f $seq.casenotrun ]
834        then
835            cat $seq.casenotrun
836            casenotrun="$casenotrun $seq"
837        fi
838    fi
839
840    # come here for each test, except when $showme is true
841    #
842    if $err
843    then
844        bad="$bad $seq"
845        n_bad=$(expr $n_bad + 1)
846        quick=false
847    fi
848    [ -f $seq.notrun ] || try=$(expr $try + 1)
849
850    seq="after_$seq"
851done
852
853interrupt=false
854status=$(expr $n_bad)
855exit
856