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