fstests: Add an auxiliary program to create an AF_UNIX socket
[xfstests-dev.git] / check
1 #!/bin/bash
2 #
3 # Control script for QA
4 #
5 # Copyright (c) 2000-2002,2006 Silicon Graphics, Inc.  All Rights Reserved.
6 #
7 # This program is free software; you can redistribute it and/or
8 # modify it under the terms of the GNU General Public License as
9 # published by the Free Software Foundation.
10 #
11 # This program is distributed in the hope that it would be useful,
12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 # GNU General Public License for more details.
15 #
16 # You should have received a copy of the GNU General Public License
17 # along with this program; if not, write the Free Software Foundation,
18 # Inc.,  51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19 #
20 #
21
22 tmp=/tmp/$$
23 status=0
24 needwrap=true
25 needsum=true
26 n_try=0
27 try=""
28 n_bad=0
29 sum_bad=0
30 bad=""
31 n_notrun=0
32 notrun=""
33 interrupt=true
34 diff="diff -u"
35 showme=false
36 have_test_arg=false
37 randomize=false
38 export here=`pwd`
39 xfile=""
40 brief_test_summary=false
41 err_msg=""
42 do_report=false
43 DUMP_OUTPUT=false
44
45 # start the initialisation work now
46 iam=check
47
48 export MSGVERB="text:action"
49 export QA_CHECK_FS=${QA_CHECK_FS:=true}
50
51 # number of diff lines from a failed test, 0 for whole output
52 export DIFF_LENGTH=${DIFF_LENGTH:=10}
53
54 # by default don't output timestamps
55 timestamp=${TIMESTAMP:=false}
56
57 rm -f $tmp.list $tmp.tmp $tmp.grep $here/$iam.out $tmp.xlist $tmp.report.*
58
59 SRC_GROUPS="generic shared"
60 export SRC_DIR="tests"
61
62 usage()
63 {
64     echo "Usage: $0 [options] [testlist]"'
65
66 check options
67     -nfs                test NFS
68     -glusterfs                test GlusterFS
69     -cifs               test CIFS
70     -overlay            test overlay
71     -pvfs2          test PVFS2
72     -tmpfs              test TMPFS
73     -l                  line mode diff
74     -udiff              show unified diff (default)
75     -n                  show me, do not run tests
76     -T                  output timestamps
77     -r                  randomize test order
78     -d                  dump test output to stdout
79     -b                  brief test summary
80     -R fmt[,fmt]        generate report in formats specified. Supported format: [xunit]
81     --large-fs          optimise scratch device for large filesystems
82     -s section          run only specified section from config file
83     -S section          exclude the specified section from the config file
84
85 testlist options
86     -g group[,group...] include tests from these groups
87     -x group[,group...] exclude tests from these groups
88     -X exclude_file     exclude individual tests
89     -E external_file    exclude individual tests
90     [testlist]          include tests matching names in testlist
91
92 testlist argument is a list of tests in the form of <test dir>/<test name>.
93
94 <test dir> is a directory under tests that contains a group file,
95 with a list of the names of the tests in that directory.
96
97 <test name> may be either a specific test file name (e.g. xfs/001) or
98 a test file name match pattern (e.g. xfs/*).
99
100 group argument is either a name of a tests group to collect from all
101 the test dirs (e.g. quick) or a name of a tests group to collect from
102 a specific tests dir in the form of <test dir>/<group name> (e.g. xfs/quick).
103
104 exclude_file argument refers to a name of a file inside each test directory.
105 for every test dir where this file is found, the listed test names are
106 excluded from the list of tests to run from that test dir.
107
108 external_file argument is a path to a single file containing a list of tests
109 to exclude in the form of <test dir>/<test name>.
110
111 examples:
112  check xfs/001
113  check -g quick
114  check -g xfs/quick
115  check -x stress xfs/*
116  check -X .exclude -g auto
117  check -E ~/.xfstests.exclude
118 '
119             exit 0
120 }
121
122 get_sub_group_list()
123 {
124         local d=$1
125         local grp=$2
126
127         test -s "$SRC_DIR/$d/group" || return 1
128
129         local grpl=$(sed -n < $SRC_DIR/$d/group \
130                 -e 's/#.*//' \
131                 -e 's/$/ /' \
132                 -e "s;^\($VALID_TEST_NAME\).* $grp .*;$SRC_DIR/$d/\1;p")
133         echo $grpl
134 }
135
136 get_group_list()
137 {
138         local grp=$1
139         local grpl=""
140         local sub=$(dirname $grp)
141
142         if [ -n "$sub" -a "$sub" != "." -a -d "$SRC_DIR/$sub" ]; then
143                 # group is given as <subdir>/<group> (e.g. xfs/quick)
144                 grp=$(basename $grp)
145                 get_sub_group_list $sub $grp
146                 return
147         fi
148
149         for d in $SRC_GROUPS $FSTYP; do
150                 if ! test -d "$SRC_DIR/$d" ; then
151                         continue
152                 fi
153                 grpl="$grpl $(get_sub_group_list $d $grp)"
154         done
155         echo $grpl
156 }
157
158 # Find all tests, excluding files that are test metadata such as group files.
159 # It matches test names against $VALID_TEST_NAME defined in common/rc
160 get_all_tests()
161 {
162         touch $tmp.list
163         for d in $SRC_GROUPS $FSTYP; do
164                 if ! test -d "$SRC_DIR/$d" ; then
165                         continue
166                 fi
167                 ls $SRC_DIR/$d/* | \
168                         grep -v "\..*" | \
169                         grep "^$SRC_DIR/$d/$VALID_TEST_NAME"| \
170                         grep -v "group\|Makefile" >> $tmp.list 2>/dev/null
171         done
172 }
173
174 # takes the list of tests to run in $tmp.list, and removes the tests passed to
175 # the function from that list.
176 trim_test_list()
177 {
178         test_list="$*"
179
180         rm -f $tmp.grep
181         numsed=0
182         for t in $test_list
183         do
184             if [ $numsed -gt 100 ]; then
185                 grep -v -f $tmp.grep <$tmp.list >$tmp.tmp
186                 mv $tmp.tmp $tmp.list
187                 numsed=0
188                 rm -f $tmp.grep
189             fi
190             echo "^$t\$" >>$tmp.grep
191             numsed=`expr $numsed + 1`
192         done
193         grep -v -f $tmp.grep <$tmp.list >$tmp.tmp
194         mv $tmp.tmp $tmp.list
195 }
196
197
198 _wallclock()
199 {
200     date "+%s"
201 }
202
203 _timestamp()
204 {
205     now=`date "+%T"`
206     echo -n " [$now]"
207 }
208
209 _prepare_test_list()
210 {
211         unset list
212         # Tests specified on the command line
213         if [ -s $tmp.arglist ]; then
214                 cat $tmp.arglist > $tmp.list
215         else
216                 touch $tmp.list
217         fi
218
219         # Specified groups to include
220         for group in $GROUP_LIST; do
221                 list=$(get_group_list $group)
222                 if [ -z "$list" ]; then
223                         echo "Group \"$group\" is empty or not defined?"
224                         exit 1
225                 fi
226
227                 for t in $list; do
228                         grep -s "^$t\$" $tmp.list >/dev/null || \
229                                                         echo "$t" >>$tmp.list
230                 done
231         done
232
233         if ! $have_test_arg && [ -z "$GROUP_LIST" ]; then
234                 # no test numbers, do everything
235                 get_all_tests
236         fi
237
238         # Specified groups to exclude
239         for xgroup in $XGROUP_LIST; do
240                 list=$(get_group_list $xgroup)
241                 if [ -z "$list" ]; then
242                         echo "Group \"$xgroup\" is empty or not defined?"
243                         exit 1
244                 fi
245
246                 trim_test_list $list
247         done
248
249         # sort the list of tests into numeric order
250         list=`sort -n $tmp.list | uniq`
251         rm -f $tmp.list $tmp.tmp $tmp.grep
252
253         if $randomize
254         then
255                 list=`echo $list | awk -f randomize.awk`
256         fi
257 }
258
259 # Process command arguments first.
260 while [ $# -gt 0 ]; do
261         case "$1" in
262         -\? | -h | --help) usage ;;
263
264         -nfs)           FSTYP=nfs ;;
265         -glusterfs)     FSTYP=glusterfs ;;
266         -cifs)          FSTYP=cifs ;;
267         -overlay)       FSTYP=overlay; export OVERLAY=true ;;
268         -pvfs2)         FSTYP=pvfs2 ;;
269         -tmpfs)         FSTYP=tmpfs ;;
270
271         -g)     group=$2 ; shift ;
272                 GROUP_LIST="$GROUP_LIST ${group//,/ }"
273                 ;;
274
275         -x)     xgroup=$2 ; shift ;
276                 XGROUP_LIST="$XGROUP_LIST ${xgroup//,/ }"
277                 ;;
278
279         -X)     xfile=$2; shift ;
280                 for d in $SRC_GROUPS $FSTYP; do
281                         [ -f $SRC_DIR/$d/$xfile ] || continue
282                         for f in `sed "s/#.*$//" $SRC_DIR/$d/$xfile`; do
283                                 echo $d/$f >> $tmp.xlist
284                         done
285                 done
286                 ;;
287         -E)     xfile=$2; shift ;
288                 if [ -f $xfile ]; then
289                         sed "s/#.*$//" "$xfile" >> $tmp.xlist
290                 fi
291                 ;;
292         -s)     RUN_SECTION="$RUN_SECTION $2"; shift ;;
293         -S)     EXCLUDE_SECTION="$EXCLUDE_SECTION $2"; shift ;;
294         -l)     diff="diff" ;;
295         -udiff) diff="$diff -u" ;;
296
297         -n)     showme=true ;;
298         -r)     randomize=true ;;
299
300         -T)     timestamp=true ;;
301         -d)     DUMP_OUTPUT=true ;;
302         -b)     brief_test_summary=true;;
303         -R)     report_fmt=$2 ; shift ;
304                 REPORT_LIST="$REPORT_LIST ${report_fmt//,/ }"
305                 do_report=true
306                 ;;
307         --large-fs) export LARGE_SCRATCH_DEV=yes ;;
308         --extra-space=*) export SCRATCH_DEV_EMPTY_SPACE=${r#*=} ;;
309
310         -*)     usage ;;
311         *)      # not an argument, we've got tests now.
312                 have_test_arg=true ;;
313         esac
314
315         # if we've found a test specification, the break out of the processing
316         # loop before we shift the arguments so that this is the first argument
317         # that we process in the test arg loop below.
318         if $have_test_arg; then
319                 break;
320         fi
321
322         shift
323 done
324
325 # we need common/config, source it after processing args, overlay needs FSTYP
326 # set before sourcing common/config
327 if ! . ./common/config; then
328         echo "$iam: failed to source common/config"
329         exit 1
330 fi
331
332 # Process tests from command line now.
333 if $have_test_arg; then
334         while [ $# -gt 0 ]; do
335                 case "$1" in
336                 -*)     echo "Arguments before tests, please!"
337                         status=1
338                         exit $status
339                         ;;
340                 *)      # Expand test pattern (e.g. xfs/???, *fs/001)
341                         list=$(cd $SRC_DIR; echo $1)
342                         for t in $list; do
343                                 test_dir=`dirname $t`
344                                 test_dir=${test_dir#$SRC_DIR/*}
345                                 test_name=`basename $t`
346                                 group_file=$SRC_DIR/$test_dir/group
347
348                                 if egrep -q "^$test_name" $group_file; then
349                                         # in group file ... OK
350                                         echo $SRC_DIR/$test_dir/$test_name \
351                                                 >>$tmp.arglist
352                                 else
353                                         # oops
354                                         echo "$t - unknown test, ignored"
355                                 fi
356                         done
357                         ;;
358                 esac
359
360                 shift
361         done
362 fi
363
364 # we need common/rc
365 if ! . ./common/rc
366 then
367     echo "check: failed to source common/rc"
368     exit 1
369 fi
370
371 if [ `id -u` -ne 0 ]
372 then
373     echo "check: QA must be run as root"
374     exit 1
375 fi
376
377 _wipe_counters()
378 {
379         n_try="0"
380         n_bad="0"
381         n_notrun="0"
382         unset try notrun bad
383 }
384
385 _wrapup()
386 {
387         seq="check"
388         check="$RESULT_BASE/check"
389
390         if $showme; then
391                 if $needwrap; then
392                         if $do_report; then
393                                 _make_section_report
394                         fi
395                         needwrap=false
396                 fi
397         elif $needwrap; then
398                 if [ -f $check.time -a -f $tmp.time ]; then
399                         cat $check.time $tmp.time  \
400                                 | $AWK_PROG '
401                                 { t[$1] = $2 }
402                                 END {
403                                         if (NR > 0) {
404                                                 for (i in t) print i " " t[i]
405                                         }
406                                 }' \
407                                 | sort -n >$tmp.out
408                         mv $tmp.out $check.time
409                 fi
410
411                 echo "" >>$check.log
412                 date >>$check.log
413
414                 echo "SECTION       -- $section" >>$tmp.summary
415                 echo "=========================" >>$tmp.summary
416                 if [ ! -z "$n_try" -a $n_try != 0 ]; then
417                         if [ $brief_test_summary == "false" ]; then
418                                 echo "Ran:$try"
419                                 echo "Ran:$try" >>$tmp.summary
420                         fi
421                         echo "Ran:$try" >>$check.log
422                 fi
423
424                 $interrupt && echo "Interrupted!" | tee -a $check.log
425
426                 if [ ! -z "$notrun" ]; then
427                         if [ $brief_test_summary == "false" ]; then
428                                 echo "Not run:$notrun"
429                                 echo "Not run:$notrun" >>$tmp.summary
430                         fi
431                         echo "Not run:$notrun" >>$check.log
432                 fi
433
434                 if [ ! -z "$n_bad" -a $n_bad != 0 ]; then
435                         echo "Failures:$bad"
436                         echo "Failed $n_bad of $n_try tests"
437                         echo "Failures:$bad" >>$check.log
438                         echo "Failed $n_bad of $n_try tests" >>$check.log
439                         echo "Failures:$bad" >>$tmp.summary
440                         echo "Failed $n_bad of $n_try tests" >>$tmp.summary
441                 else
442                         echo "Passed all $n_try tests"
443                         echo "Passed all $n_try tests" >>$check.log
444                         echo "Passed all $n_try tests" >>$tmp.summary
445                 fi
446                 echo "" >>$tmp.summary
447                 if $do_report; then
448                         _make_section_report
449                 fi
450                 needwrap=false
451         fi
452
453         sum_bad=`expr $sum_bad + $n_bad`
454         _wipe_counters
455         rm -f /tmp/*.rawout /tmp/*.out /tmp/*.err /tmp/*.time
456         if ! $OPTIONS_HAVE_SECTIONS; then
457                 rm -f $tmp.*
458         fi
459 }
460
461 _summary()
462 {
463         _wrapup
464         if $showme; then
465                 :
466         elif $needsum; then
467                 count=`wc -L $tmp.summary | cut -f1 -d" "`
468                 cat $tmp.summary
469                 needsum=false
470         fi
471         rm -f $tmp.*
472 }
473
474 _check_filesystems()
475 {
476         if [ -f ${RESULT_DIR}/require_test ]; then
477                 _check_test_fs || err=true
478                 rm -f ${RESULT_DIR}/require_test*
479         fi
480         if [ -f ${RESULT_DIR}/require_scratch ]; then
481                 _check_scratch_fs || err=true
482                 rm -f ${RESULT_DIR}/require_scratch*
483         fi
484 }
485
486 _prepare_test_list
487
488 if $OPTIONS_HAVE_SECTIONS; then
489         trap "_summary; exit \$status" 0 1 2 3 15
490 else
491         trap "_wrapup; exit \$status" 0 1 2 3 15
492 fi
493
494 for section in $HOST_OPTIONS_SECTIONS; do
495         OLD_FSTYP=$FSTYP
496         OLD_TEST_FS_MOUNT_OPTS=$TEST_FS_MOUNT_OPTS
497         get_next_config $section
498
499         # Do we need to run only some sections ?
500         if [ ! -z "$RUN_SECTION" ]; then
501                 skip=true
502                 for s in $RUN_SECTION; do
503                         if [ $section == $s ]; then
504                                 skip=false
505                                 break;
506                         fi
507                 done
508                 if $skip; then
509                         continue
510                 fi
511         fi
512
513         # Did this section get excluded?
514         if [ ! -z "$EXCLUDE_SECTION" ]; then
515                 skip=false
516                 for s in $EXCLUDE_SECTION; do
517                         if [ $section == $s ]; then
518                                 skip=true
519                                 break;
520                         fi
521                 done
522                 if $skip; then
523                         continue
524                 fi
525         fi
526
527         mkdir -p $RESULT_BASE
528         if [ ! -d $RESULT_BASE ]; then
529                 echo "failed to create results directory $RESULT_BASE"
530                 status=1
531                 exit
532         fi
533
534         if $OPTIONS_HAVE_SECTIONS; then
535                 echo "SECTION       -- $section"
536         fi
537
538         sect_start=`_wallclock`
539         if $RECREATE_TEST_DEV || [ "$OLD_FSTYP" != "$FSTYP" ]; then
540                 echo "RECREATING    -- $FSTYP on $TEST_DEV"
541                 _test_unmount 2> /dev/null
542                 if ! _test_mkfs >$tmp.err 2>&1
543                 then
544                         echo "our local _test_mkfs routine ..."
545                         cat $tmp.err
546                         echo "check: failed to mkfs \$TEST_DEV using specified options"
547                         status=1
548                         exit
549                 fi
550                 if ! _test_mount
551                 then
552                         echo "check: failed to mount $TEST_DEV on $TEST_DIR"
553                         status=1
554                         exit
555                 fi
556                 _prepare_test_list
557         elif [ "$OLD_TEST_FS_MOUNT_OPTS" != "$TEST_FS_MOUNT_OPTS" ]; then
558                 _test_unmount 2> /dev/null
559                 if ! _test_mount
560                 then
561                         echo "check: failed to mount $TEST_DEV on $TEST_DIR"
562                         status=1
563                         exit
564                 fi
565         fi
566
567         init_rc
568
569         seq="check"
570         check="$RESULT_BASE/check"
571
572         # don't leave old full output behind on a clean run
573         rm -f $check.full
574
575         [ -f $check.time ] || touch $check.time
576
577         # print out our test configuration
578         echo "FSTYP         -- `_full_fstyp_details`"
579         echo "PLATFORM      -- `_full_platform_details`"
580         if [ ! -z "$SCRATCH_DEV" ]; then
581           echo "MKFS_OPTIONS  -- `_scratch_mkfs_options`"
582           echo "MOUNT_OPTIONS -- `_scratch_mount_options`"
583         fi
584         echo
585         needwrap=true
586
587         if [ ! -z "$SCRATCH_DEV" ]; then
588           _scratch_unmount 2> /dev/null
589           # call the overridden mkfs - make sure the FS is built
590           # the same as we'll create it later.
591
592           if ! _scratch_mkfs >$tmp.err 2>&1
593           then
594               echo "our local _scratch_mkfs routine ..."
595               cat $tmp.err
596               echo "check: failed to mkfs \$SCRATCH_DEV using specified options"
597               status=1
598               exit
599           fi
600
601           # call the overridden mount - make sure the FS mounts with
602           # the same options that we'll mount with later.
603           if ! _scratch_mount >$tmp.err 2>&1
604           then
605               echo "our local mount routine ..."
606               cat $tmp.err
607               echo "check: failed to mount \$SCRATCH_DEV using specified options"
608               status=1
609               exit
610           fi
611         fi
612
613         seqres="$check"
614         _check_test_fs
615
616         for seq in $list
617         do
618             err=false
619             err_msg=""
620             if [ ! -f $seq ]; then
621                 # Try to get full name in case the user supplied only seq id
622                 # and the test has a name. A bit of hassle to find really
623                 # the test and not its sample output or helping files.
624                 bname=$(basename $seq)
625                 full_seq=$(find $(dirname $seq) -name $bname* -executable |
626                     awk '(NR == 1 || length < length(shortest)) { shortest = $0 }\
627                         END { print shortest }')
628                 if [ -f $full_seq ] \
629                     && [ x$(echo $bname | grep -o "^$VALID_TEST_ID") != x ]; then
630                     seq=$full_seq
631                 fi
632             fi
633
634             # the filename for the test and the name output are different.
635             # we don't include the tests/ directory in the name output.
636             export seqnum=`echo $seq | sed -e "s;$SRC_DIR/;;"`
637
638             # Similarly, the result directory needs to replace the tests/
639             # part of the test location.
640             group=`dirname $seq`
641             if $OPTIONS_HAVE_SECTIONS; then
642                 export RESULT_DIR=`echo $group | sed -e "s;$SRC_DIR;${RESULT_BASE}/$section;"`
643                 REPORT_DIR="$RESULT_BASE/$section"
644             else
645                 export RESULT_DIR=`echo $group | sed -e "s;$SRC_DIR;$RESULT_BASE;"`
646                 REPORT_DIR="$RESULT_BASE"
647             fi
648             seqres="$REPORT_DIR/$seqnum"
649
650             mkdir -p $RESULT_DIR
651
652             echo -n "$seqnum"
653
654             if $showme; then
655                 echo
656                 start=0
657                 stop=0
658                 n_notrun=`expr $n_notrun + 1`
659                 if $do_report; then
660                         _make_testcase_report "list"
661                 fi
662                 continue
663             fi
664             tc_status="pass"
665             if [ ! -f $seq ]; then
666                 echo " - no such test?"
667             else
668                 # really going to try and run this one
669                 #
670                 rm -f $seqres.out.bad
671
672                 # check if we really should run it
673                 if [ -s $tmp.xlist ]; then
674                         if grep $seqnum $tmp.xlist > /dev/null 2>&1 ; then
675                                 echo "       [expunged]"
676                                 continue
677                         fi
678                 fi
679
680                 # slashes now in names, sed barfs on them so use grep
681                 lasttime=`grep -w ^$seqnum $check.time | awk '// {print $2}'`
682                 if [ "X$lasttime" != X ]; then
683                         echo -n " ${lasttime}s ..."
684                 else
685                         echo -n "       "       # prettier output with timestamps.
686                 fi
687                 rm -f core $seqres.notrun
688
689                 start=`_wallclock`
690                 $timestamp && echo -n " ["`date "+%T"`"]"
691                 [ ! -x $seq ] && chmod u+x $seq # ensure we can run it
692                 $LOGGER_PROG "run xfstest $seqnum"
693                 if [ -w /dev/kmsg ]; then
694                         export date_time=`date +"%F %T"`
695                         echo "run fstests $seqnum at $date_time" > /dev/kmsg
696                         # _check_dmesg depends on this log in dmesg
697                         touch ${RESULT_DIR}/check_dmesg
698                 fi
699                 if [ "$DUMP_OUTPUT" = true ]; then
700                         ./$seq 2>&1 | tee $tmp.rawout
701                         # Because $? would get tee's return code
702                         sts=${PIPESTATUS[0]}
703                 else
704                         ./$seq >$tmp.rawout 2>&1
705                         sts=$?
706                 fi
707                 $timestamp && _timestamp
708                 stop=`_wallclock`
709
710                 _fix_malloc <$tmp.rawout >$tmp.out
711                 rm -f $tmp.rawout
712
713                 if [ -f core ]
714                 then
715                     err_msg="[dumped core]"
716                     echo -n " $err_msg"
717                     mv core $RESULT_BASE/$seqnum.core
718                     err=true
719                 fi
720
721                 if [ -f $seqres.notrun ]
722                 then
723                     $timestamp || echo -n " [not run] "
724                     $timestamp && echo " [not run]" && echo -n "        $seqnum -- "
725                     cat $seqres.notrun
726                     notrun="$notrun $seqnum"
727                     n_notrun=`expr $n_notrun + 1`
728                     tc_status="notrun"
729                 else
730                     if [ $sts -ne 0 ]
731                     then
732                         err_msg="[failed, exit status $sts]"
733                         echo -n " $err_msg"
734                         err=true
735                     fi
736                     if [ ! -f $seq.out ]
737                     then
738                         _dump_err "no qualified output"
739                         err=true
740                     else
741
742                         # coreutils 8.16+ changed quote formats in error messages from
743                         # `foo' to 'foo'. Filter old versions to match the new version.
744                         sed -i "s/\`/\'/g" $tmp.out
745                         if diff $seq.out $tmp.out >/dev/null 2>&1
746                         then
747                             if $err
748                             then
749                                 :
750                             else
751                                 echo "$seqnum `expr $stop - $start`" >>$tmp.time
752                                 echo -n " `expr $stop - $start`s"
753                             fi
754                             echo ""
755                         else
756                             echo " - output mismatch (see $seqres.out.bad)"
757                             mv $tmp.out $seqres.out.bad
758                             $diff $seq.out $seqres.out.bad | {
759                                 if test "$DIFF_LENGTH" -le 0; then
760                                         cat
761                                 else
762                                         head -n "$DIFF_LENGTH"
763                                         echo "..."
764                                         echo "(Run '$diff $seq.out $seqres.out.bad'" \
765                                                 " to see the entire diff)"
766                                 fi; } | \
767                                 sed -e 's/^\(.\)/    \1/'
768                             err_msg="output mismatch (see $diff $seq.out $seqres.out.bad)"
769                             err=true
770                         fi
771                     fi
772                     try="$try $seqnum"
773                     n_try=`expr $n_try + 1`
774                     _check_filesystems
775                     _check_dmesg || err=true
776                 fi
777
778             fi
779
780             # come here for each test, except when $showme is true
781             #
782             if $err
783             then
784                 bad="$bad $seqnum"
785                 n_bad=`expr $n_bad + 1`
786                 quick=false
787                 tc_status="fail"
788             fi
789             if $do_report; then
790                 _make_testcase_report "$tc_status"
791             fi
792             seq="after_$seqnum"
793         done
794         sect_stop=`_wallclock`
795         interrupt=false
796         _wrapup
797         interrupt=true
798         echo
799
800         _test_unmount 2> /dev/null
801         _scratch_unmount 2> /dev/null
802 done
803
804 interrupt=false
805 status=`expr $sum_bad`
806 exit