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