fstests: Make ./new work for non-root user
[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/rc, that also sources common/config. We need to source it
335 # after processing args, overlay needs FSTYP set before sourcing common/config
336 if ! . ./common/rc; then
337         echo "check: failed to source common/rc"
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 if [ `id -u` -ne 0 ]
378 then
379     echo "check: QA must be run as root"
380     exit 1
381 fi
382
383 _wipe_counters()
384 {
385         n_try="0"
386         n_bad="0"
387         n_notrun="0"
388         unset try notrun bad
389 }
390
391 _wrapup()
392 {
393         seq="check"
394         check="$RESULT_BASE/check"
395
396         if $showme; then
397                 if $needwrap; then
398                         if $do_report; then
399                                 _make_section_report
400                         fi
401                         needwrap=false
402                 fi
403         elif $needwrap; then
404                 if [ -f $check.time -a -f $tmp.time ]; then
405                         cat $check.time $tmp.time  \
406                                 | $AWK_PROG '
407                                 { t[$1] = $2 }
408                                 END {
409                                         if (NR > 0) {
410                                                 for (i in t) print i " " t[i]
411                                         }
412                                 }' \
413                                 | sort -n >$tmp.out
414                         mv $tmp.out $check.time
415                 fi
416
417                 echo "" >>$check.log
418                 date >>$check.log
419
420                 echo "SECTION       -- $section" >>$tmp.summary
421                 echo "=========================" >>$tmp.summary
422                 if [ ! -z "$n_try" -a $n_try != 0 ]; then
423                         if [ $brief_test_summary == "false" ]; then
424                                 echo "Ran:$try"
425                                 echo "Ran:$try" >>$tmp.summary
426                         fi
427                         echo "Ran:$try" >>$check.log
428                 fi
429
430                 $interrupt && echo "Interrupted!" | tee -a $check.log
431
432                 if [ ! -z "$notrun" ]; then
433                         if [ $brief_test_summary == "false" ]; then
434                                 echo "Not run:$notrun"
435                                 echo "Not run:$notrun" >>$tmp.summary
436                         fi
437                         echo "Not run:$notrun" >>$check.log
438                 fi
439
440                 if [ ! -z "$n_bad" -a $n_bad != 0 ]; then
441                         echo "Failures:$bad"
442                         echo "Failed $n_bad of $n_try tests"
443                         echo "Failures:$bad" >>$check.log
444                         echo "Failed $n_bad of $n_try tests" >>$check.log
445                         echo "Failures:$bad" >>$tmp.summary
446                         echo "Failed $n_bad of $n_try tests" >>$tmp.summary
447                 else
448                         echo "Passed all $n_try tests"
449                         echo "Passed all $n_try tests" >>$check.log
450                         echo "Passed all $n_try tests" >>$tmp.summary
451                 fi
452                 echo "" >>$tmp.summary
453                 if $do_report; then
454                         _make_section_report
455                 fi
456                 needwrap=false
457         fi
458
459         sum_bad=`expr $sum_bad + $n_bad`
460         _wipe_counters
461         rm -f /tmp/*.rawout /tmp/*.out /tmp/*.err /tmp/*.time
462         if ! $OPTIONS_HAVE_SECTIONS; then
463                 rm -f $tmp.*
464         fi
465 }
466
467 _summary()
468 {
469         _wrapup
470         if $showme; then
471                 :
472         elif $needsum; then
473                 count=`wc -L $tmp.summary | cut -f1 -d" "`
474                 cat $tmp.summary
475                 needsum=false
476         fi
477         rm -f $tmp.*
478 }
479
480 _check_filesystems()
481 {
482         if [ -f ${RESULT_DIR}/require_test ]; then
483                 _check_test_fs || err=true
484                 rm -f ${RESULT_DIR}/require_test*
485         else
486                 _test_unmount 2> /dev/null
487         fi
488         if [ -f ${RESULT_DIR}/require_scratch ]; then
489                 _check_scratch_fs || err=true
490                 rm -f ${RESULT_DIR}/require_scratch*
491         else
492                 _scratch_unmount 2> /dev/null
493         fi
494 }
495
496 _expunge_test()
497 {
498         local TEST_ID="$1"
499         if [ -s $tmp.xlist ]; then
500                 if grep -q $TEST_ID $tmp.xlist; then
501                         echo "       [expunged]"
502                         return 1
503                 fi
504         fi
505         return 0
506 }
507
508 _init_kmemleak
509 _prepare_test_list
510
511 if $OPTIONS_HAVE_SECTIONS; then
512         trap "_summary; exit \$status" 0 1 2 3 15
513 else
514         trap "_wrapup; exit \$status" 0 1 2 3 15
515 fi
516
517 for section in $HOST_OPTIONS_SECTIONS; do
518         OLD_FSTYP=$FSTYP
519         OLD_TEST_FS_MOUNT_OPTS=$TEST_FS_MOUNT_OPTS
520         get_next_config $section
521
522         # Do we need to run only some sections ?
523         if [ ! -z "$RUN_SECTION" ]; then
524                 skip=true
525                 for s in $RUN_SECTION; do
526                         if [ $section == $s ]; then
527                                 skip=false
528                                 break;
529                         fi
530                 done
531                 if $skip; then
532                         continue
533                 fi
534         fi
535
536         # Did this section get excluded?
537         if [ ! -z "$EXCLUDE_SECTION" ]; then
538                 skip=false
539                 for s in $EXCLUDE_SECTION; do
540                         if [ $section == $s ]; then
541                                 skip=true
542                                 break;
543                         fi
544                 done
545                 if $skip; then
546                         continue
547                 fi
548         fi
549
550         mkdir -p $RESULT_BASE
551         if [ ! -d $RESULT_BASE ]; then
552                 echo "failed to create results directory $RESULT_BASE"
553                 status=1
554                 exit
555         fi
556
557         if $OPTIONS_HAVE_SECTIONS; then
558                 echo "SECTION       -- $section"
559         fi
560
561         sect_start=`_wallclock`
562         if $RECREATE_TEST_DEV || [ "$OLD_FSTYP" != "$FSTYP" ]; then
563                 echo "RECREATING    -- $FSTYP on $TEST_DEV"
564                 _test_unmount 2> /dev/null
565                 if ! _test_mkfs >$tmp.err 2>&1
566                 then
567                         echo "our local _test_mkfs routine ..."
568                         cat $tmp.err
569                         echo "check: failed to mkfs \$TEST_DEV using specified options"
570                         status=1
571                         exit
572                 fi
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                 _prepare_test_list
580         elif [ "$OLD_TEST_FS_MOUNT_OPTS" != "$TEST_FS_MOUNT_OPTS" ]; then
581                 _test_unmount 2> /dev/null
582                 if ! _test_mount
583                 then
584                         echo "check: failed to mount $TEST_DEV on $TEST_DIR"
585                         status=1
586                         exit
587                 fi
588         fi
589
590         init_rc
591
592         seq="check"
593         check="$RESULT_BASE/check"
594
595         # don't leave old full output behind on a clean run
596         rm -f $check.full
597
598         [ -f $check.time ] || touch $check.time
599
600         # print out our test configuration
601         echo "FSTYP         -- `_full_fstyp_details`"
602         echo "PLATFORM      -- `_full_platform_details`"
603         if [ ! -z "$SCRATCH_DEV" ]; then
604           echo "MKFS_OPTIONS  -- `_scratch_mkfs_options`"
605           echo "MOUNT_OPTIONS -- `_scratch_mount_options`"
606         fi
607         echo
608         needwrap=true
609
610         if [ ! -z "$SCRATCH_DEV" ]; then
611           _scratch_unmount 2> /dev/null
612           # call the overridden mkfs - make sure the FS is built
613           # the same as we'll create it later.
614
615           if ! _scratch_mkfs >$tmp.err 2>&1
616           then
617               echo "our local _scratch_mkfs routine ..."
618               cat $tmp.err
619               echo "check: failed to mkfs \$SCRATCH_DEV using specified options"
620               status=1
621               exit
622           fi
623
624           # call the overridden mount - make sure the FS mounts with
625           # the same options that we'll mount with later.
626           if ! _scratch_mount >$tmp.err 2>&1
627           then
628               echo "our local mount routine ..."
629               cat $tmp.err
630               echo "check: failed to mount \$SCRATCH_DEV using specified options"
631               status=1
632               exit
633           fi
634         fi
635
636         seqres="$check"
637         _check_test_fs
638
639         for seq in $list
640         do
641             err=false
642             _err_msg=""
643             if [ ! -f $seq ]; then
644                 # Try to get full name in case the user supplied only seq id
645                 # and the test has a name. A bit of hassle to find really
646                 # the test and not its sample output or helping files.
647                 bname=$(basename $seq)
648                 full_seq=$(find $(dirname $seq) -name $bname* -executable |
649                     awk '(NR == 1 || length < length(shortest)) { shortest = $0 }\
650                         END { print shortest }')
651                 if [ -f $full_seq ] \
652                     && [ x$(echo $bname | grep -o "^$VALID_TEST_ID") != x ]; then
653                     seq=$full_seq
654                 fi
655             fi
656
657             # the filename for the test and the name output are different.
658             # we don't include the tests/ directory in the name output.
659             export seqnum=`echo $seq | sed -e "s;$SRC_DIR/;;"`
660
661             # Similarly, the result directory needs to replace the tests/
662             # part of the test location.
663             group=`dirname $seq`
664             if $OPTIONS_HAVE_SECTIONS; then
665                 export RESULT_DIR=`echo $group | sed -e "s;$SRC_DIR;${RESULT_BASE}/$section;"`
666                 REPORT_DIR="$RESULT_BASE/$section"
667             else
668                 export RESULT_DIR=`echo $group | sed -e "s;$SRC_DIR;$RESULT_BASE;"`
669                 REPORT_DIR="$RESULT_BASE"
670             fi
671             seqres="$REPORT_DIR/$seqnum"
672
673             mkdir -p $RESULT_DIR
674
675             echo -n "$seqnum"
676
677             if $showme; then
678                 _expunge_test $seqnum
679                 if [ $? -eq 1 ]; then
680                         continue
681                 fi
682                 echo
683                 start=0
684                 stop=0
685                 n_notrun=`expr $n_notrun + 1`
686                 if $do_report; then
687                         _make_testcase_report "list"
688                 fi
689                 continue
690             fi
691             tc_status="pass"
692             if [ ! -f $seq ]; then
693                 echo " - no such test?"
694             else
695                 # really going to try and run this one
696                 #
697                 rm -f $seqres.out.bad
698
699                 # check if we really should run it
700                 _expunge_test $seqnum
701                 if [ $? -eq 1 ]; then
702                         continue
703                 fi
704
705                 # slashes now in names, sed barfs on them so use grep
706                 lasttime=`grep -w ^$seqnum $check.time | awk '// {print $2}'`
707                 if [ "X$lasttime" != X ]; then
708                         echo -n " ${lasttime}s ..."
709                 else
710                         echo -n "       "       # prettier output with timestamps.
711                 fi
712                 rm -f core $seqres.notrun
713
714                 start=`_wallclock`
715                 $timestamp && echo -n " ["`date "+%T"`"]"
716                 [ ! -x $seq ] && chmod u+x $seq # ensure we can run it
717                 $LOGGER_PROG "run xfstest $seqnum"
718                 if [ -w /dev/kmsg ]; then
719                         export date_time=`date +"%F %T"`
720                         echo "run fstests $seqnum at $date_time" > /dev/kmsg
721                         # _check_dmesg depends on this log in dmesg
722                         touch ${RESULT_DIR}/check_dmesg
723                 fi
724                 if [ "$DUMP_OUTPUT" = true ]; then
725                         ./$seq 2>&1 | tee $tmp.out
726                         # Because $? would get tee's return code
727                         sts=${PIPESTATUS[0]}
728                 else
729                         ./$seq >$tmp.out 2>&1
730                         sts=$?
731                 fi
732                 $timestamp && _timestamp
733                 stop=`_wallclock`
734
735                 if [ -f core ]
736                 then
737                     _err_msg="[dumped core]"
738                     echo -n " $_err_msg"
739                     mv core $RESULT_BASE/$seqnum.core
740                     err=true
741                 fi
742
743                 if [ -f $seqres.notrun ]
744                 then
745                     $timestamp || echo -n " [not run] "
746                     $timestamp && echo " [not run]" && echo -n "        $seqnum -- "
747                     cat $seqres.notrun
748                     notrun="$notrun $seqnum"
749                     n_notrun=`expr $n_notrun + 1`
750                     tc_status="notrun"
751                 else
752                     if [ $sts -ne 0 ]
753                     then
754                         _err_msg="[failed, exit status $sts]"
755                         echo -n " $_err_msg"
756                         err=true
757                     fi
758                     if [ ! -f $seq.out ]
759                     then
760                         _dump_err "no qualified output"
761                         err=true
762                     else
763
764                         # coreutils 8.16+ changed quote formats in error messages from
765                         # `foo' to 'foo'. Filter old versions to match the new version.
766                         sed -i "s/\`/\'/g" $tmp.out
767                         if diff $seq.out $tmp.out >/dev/null 2>&1
768                         then
769                             if $err
770                             then
771                                 :
772                             else
773                                 echo "$seqnum `expr $stop - $start`" >>$tmp.time
774                                 echo -n " `expr $stop - $start`s"
775                             fi
776                             echo ""
777                         else
778                             echo " - output mismatch (see $seqres.out.bad)"
779                             mv $tmp.out $seqres.out.bad
780                             $diff $seq.out $seqres.out.bad | {
781                                 if test "$DIFF_LENGTH" -le 0; then
782                                         cat
783                                 else
784                                         head -n "$DIFF_LENGTH"
785                                         echo "..."
786                                         echo "(Run '$diff $seq.out $seqres.out.bad'" \
787                                                 " to see the entire diff)"
788                                 fi; } | \
789                                 sed -e 's/^\(.\)/    \1/'
790                             _err_msg="output mismatch (see $diff $seq.out $seqres.out.bad)"
791                             err=true
792                         fi
793                     fi
794                     try="$try $seqnum"
795                     n_try=`expr $n_try + 1`
796                     _check_filesystems
797                     _check_dmesg || err=true
798                     _check_kmemleak || err=true
799                 fi
800
801             fi
802
803             # come here for each test, except when $showme is true
804             #
805             if $err
806             then
807                 bad="$bad $seqnum"
808                 n_bad=`expr $n_bad + 1`
809                 tc_status="fail"
810             fi
811             if $do_report; then
812                 _make_testcase_report "$tc_status"
813             fi
814             seq="after_$seqnum"
815         done
816         sect_stop=`_wallclock`
817         interrupt=false
818         _wrapup
819         interrupt=true
820         echo
821
822         _test_unmount 2> /dev/null
823         _scratch_unmount 2> /dev/null
824 done
825
826 interrupt=false
827 status=`expr $sum_bad != 0`
828 exit