shared/051: remove ACL count subtest
[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 notrun=""
32 interrupt=true
33 diff="diff -u"
34 showme=false
35 have_test_arg=false
36 randomize=false
37 export here=`pwd`
38 xfile=""
39
40 # start the initialisation work now
41 iam=check
42
43 export MSGVERB="text:action"
44 export QA_CHECK_FS=${QA_CHECK_FS:=true}
45
46 # number of diff lines from a failed test, 0 for whole output
47 export DIFF_LENGTH=${DIFF_LENGTH:=10}
48
49 # by default don't output timestamps
50 timestamp=${TIMESTAMP:=false}
51
52 rm -f $tmp.list $tmp.tmp $tmp.grep $here/$iam.out $tmp.xlist
53
54 # we need common/config
55 if ! . ./common/config
56 then
57     echo "$iam: failed to source common/config"
58     exit 1
59 fi
60
61 SUPPORTED_TESTS="[0-9][0-9][0-9] [0-9][0-9][0-9][0-9]"
62 SRC_GROUPS="generic shared"
63 export SRC_DIR="tests"
64
65 usage()
66 {
67     echo "Usage: $0 [options] [testlist]"'
68
69 check options
70     -nfs                test NFS
71     -tmpfs              test TMPFS
72     -l                  line mode diff
73     -udiff              show unified diff (default)
74     -n                  show me, do not run tests
75     -T                  output timestamps
76     -r                  randomize test order
77     --large-fs          optimise scratch device for large filesystems
78     -s section          run only specified section from config file
79
80 testlist options
81     -g group[,group...] include tests from these groups
82     -x group[,group...] exclude tests from these groups
83     -X file             exclude individual tests
84     [testlist]          include tests matching names in testlist
85 '
86             exit 0
87 }
88
89 get_group_list()
90 {
91         grp=$1
92
93         for d in $SRC_GROUPS $FSTYP; do
94                 l=$(sed -n < $SRC_DIR/$d/group \
95                         -e 's/#.*//' \
96                         -e 's/$/ /' \
97                         -e "s;\(^[0-9][0-9][0-9]\).* $grp .*;$SRC_DIR/$d/\1;p")
98                 grpl="$grpl $l"
99         done
100         echo $grpl
101 }
102
103 # find all tests, excluding files that are test metadata such as group files.
104 # This assumes that tests are defined purely by alphanumeric filenames with no
105 # ".xyz" extensions in the name.
106 get_all_tests()
107 {
108         touch $tmp.list
109         for d in $SRC_GROUPS $FSTYP; do
110                 ls $SRC_DIR/$d/* | \
111                         grep -v "\..*" | \
112                         grep -v "group\|Makefile" >> $tmp.list 2>/dev/null
113         done
114 }
115
116 # takes the list of tests to run in $tmp.list, and removes the tests passed to
117 # the function from that list.
118 trim_test_list()
119 {
120         test_list="$*"
121
122         rm -f $tmp.grep
123         numsed=0
124         for t in $test_list
125         do
126             if [ $numsed -gt 100 ]; then
127                 grep -v -f $tmp.grep <$tmp.list >$tmp.tmp
128                 mv $tmp.tmp $tmp.list
129                 numsed=0
130                 rm -f $tmp.grep
131             fi
132             echo "^$t\$" >>$tmp.grep
133             numsed=`expr $numsed + 1`
134         done
135         grep -v -f $tmp.grep <$tmp.list >$tmp.tmp
136         mv $tmp.tmp $tmp.list
137 }
138
139
140 _wallclock()
141 {
142     date "+%s"
143 }
144
145 _timestamp()
146 {
147     now=`date "+%T"`
148     echo -n " [$now]"
149 }
150
151 _prepare_test_list()
152 {
153         unset list
154         # Tests specified on the command line
155         if [ -s $tmp.arglist ]; then
156                 cat $tmp.arglist > $tmp.list
157         else
158                 touch $tmp.list
159         fi
160
161         # Specified groups to include
162         for group in $GROUP_LIST; do
163                 list=$(get_group_list $group)
164                 if [ -z "$list" ]; then
165                         echo "Group \"$group\" is empty or not defined?"
166                         exit 1
167                 fi
168
169                 for t in $list; do
170                         grep -s "^$t\$" $tmp.list >/dev/null || \
171                                                         echo "$t" >>$tmp.list
172                 done
173         done
174
175         if ! $have_test_arg && [ -z "$GROUP_LIST" ]; then
176                 # no test numbers, do everything
177                 get_all_tests
178         fi
179
180         # Specified groups to exclude
181         for xgroup in $XGROUP_LIST; do
182                 list=$(get_group_list $xgroup)
183                 if [ -z "$list" ]; then
184                         echo "Group \"$xgroup\" is empty or not defined?"
185                         exit 1
186                 fi
187
188                 trim_test_list $list
189         done
190
191         # sort the list of tests into numeric order
192         list=`sort -n $tmp.list | uniq`
193         rm -f $tmp.list $tmp.tmp $tmp.grep
194
195         if $randomize
196         then
197                 list=`echo $list | awk -f randomize.awk`
198         fi
199 }
200
201 # Process command arguments first.
202 while [ $# -gt 0 ]; do
203         case "$1" in
204         -\? | -h | --help) usage ;;
205
206         -nfs)   FSTYP=nfs ;;
207         -tmpfs) FSTYP=tmpfs ;;
208
209         -g)     group=$2 ; shift ;
210                 GROUP_LIST="$GROUP_LIST $group"
211                 ;;
212
213         -x)     xgroup=$2 ; shift ;
214                 XGROUP_LIST="$XGROUP_LIST $xgroup"
215                 ;;
216
217         -X)     xfile=$2; shift ;
218                 for d in $SRC_GROUPS $FSTYP; do
219                         [ -f $SRC_DIR/$d/$xfile ] || continue
220                         for f in `cat $SRC_DIR/$d/$xfile`; do
221                                 echo $d/$f >> $tmp.xlist
222                         done
223                 done
224                 ;;
225         -s)     RUN_SECTION="$RUN_SECTION $2"; shift ;;
226         -l)     diff="diff" ;;
227         -udiff) diff="$diff -u" ;;
228
229         -n)     showme=true ;;
230         -r)     randomize=true ;;
231
232         -T)     timestamp=true ;;
233
234         --large-fs) export LARGE_SCRATCH_DEV=yes ;;
235         --extra-space=*) export SCRATCH_DEV_EMPTY_SPACE=${r#*=} ;;
236
237         -*)     usage ;;
238         *)      # not an argument, we've got tests now.
239                 have_test_arg=true ;;
240         esac
241
242         # if we've found a test specification, the break out of the processing
243         # loop before we shift the arguments so that this is the first argument
244         # that we process in the test arg loop below.
245         if $have_test_arg; then
246                 break;
247         fi
248
249         shift
250 done
251
252 # Process tests from command line now.
253 if $have_test_arg; then
254         while [ $# -gt 0 ]; do
255                 case "$1" in
256                 -*)     echo "Argments before tests, please!"
257                         status=1
258                         exit $status
259                         ;;
260                 *)      test_dir=`dirname $1`
261                         test_dir=${test_dir#$SRC_DIR/*}
262                         test_name=`basename $1`
263                         group_file=$SRC_DIR/$test_dir/group
264
265                         if egrep "^$test_name" $group_file >/dev/null ; then
266                                 # in group file ... OK
267                                 echo $SRC_DIR/$test_dir/$test_name >>$tmp.arglist
268                         else
269                                 # oops
270                                 echo "$1 - unknown test, ignored"
271                         fi
272                         ;;
273                 esac
274
275                 shift
276         done
277 fi
278
279 # we need common/rc
280 if ! . ./common/rc
281 then
282     echo "check: failed to source common/rc"
283     exit 1
284 fi
285
286 if [ `id -u` -ne 0 ]
287 then
288     echo "check: QA must be run as root"
289     exit 1
290 fi
291
292 _wipe_counters()
293 {
294         n_try="0"
295         n_bad="0"
296         unset try notrun bad
297 }
298
299 _wrapup()
300 {
301     seq="check"
302     check="$RESULT_BASE/check"
303
304     if $showme
305     then
306         :
307     elif $needwrap
308     then
309         if [ -f $check.time -a -f $tmp.time ]
310         then
311             cat $check.time $tmp.time \
312             | $AWK_PROG '
313         { t[$1] = $2 }
314 END     { if (NR > 0) {
315             for (i in t) print i " " t[i]
316           }
317         }' \
318             | sort -n >$tmp.out
319             mv $tmp.out $check.time
320         fi
321
322         echo "" >>$check.log
323         date >>$check.log
324         echo $list | fmt | sed -e 's/^/    /' -e "s;$SRC_DIR/;;g" >>$check.log
325         $interrupt && echo "Interrupted!" >>$check.log
326
327         echo "SECTION       -- $section" >>$tmp.summary
328         echo "=========================" >>$tmp.summary
329         if [ ! -z "$n_try" -a $n_try != 0 ]
330         then
331             echo "Ran:$try"
332             echo "Ran:$try" >>$tmp.summary
333         fi
334
335         if [ ! -z "$notrun" ]
336         then
337             echo "Not run:$notrun"
338             echo "Not run:$notrun" >>$check.log
339             echo "Not run:$notrun" >>$tmp.summary
340         fi
341
342         if [ ! -z "$n_bad" -a $n_bad != 0 ]
343         then
344             echo "Failures:$bad"
345             echo "Failed $n_bad of $n_try tests"
346             echo "Failures:$bad" | fmt >>$check.log
347             echo "Failed $n_bad of $n_try tests" >>$check.log
348             echo "Failures:$bad" >>$tmp.summary
349             echo "Failed $n_bad of $n_try tests" >>$tmp.summary
350         else
351             echo "Passed all $n_try tests"
352             echo "Passed all $n_try tests" >>$check.log
353             echo "Passed all $n_try tests" >>$tmp.summary
354         fi
355         echo "" >>$tmp.summary
356         needwrap=false
357     fi
358
359     sum_bad=`expr $sum_bad + $n_bad`
360     _wipe_counters
361     rm -f /tmp/*.rawout /tmp/*.out /tmp/*.err /tmp/*.time
362     if ! $OPTIONS_HAVE_SECTIONS; then
363         rm -f $tmp.*
364     fi
365 }
366
367 _summary()
368 {
369         _wrapup
370         if $showme; then
371                 :
372         elif $needsum; then
373                 count=`wc -L $tmp.summary | cut -f1 -d" "`
374                 cat $tmp.summary
375                 needsum=false
376         fi
377         rm -f $tmp.*
378 }
379
380 _prepare_test_list
381
382 if $OPTIONS_HAVE_SECTIONS; then
383         trap "_summary; exit \$status" 0 1 2 3 15
384 else
385         trap "_wrapup; exit \$status" 0 1 2 3 15
386 fi
387
388 for section in $HOST_OPTIONS_SECTIONS; do
389         OLD_FSTYP=$FSTYP
390         OLD_MOUNT_OPTIONS=$MOUNT_OPTIONS
391         get_next_config $section
392
393         # Do we need to run only some sections ?
394         if [ ! -z "$RUN_SECTION" ]; then
395                 skip=true
396                 for s in $RUN_SECTION; do
397                         if [ $section == $s ]; then
398                                 skip=false
399                         fi
400                 done
401                 if $skip; then
402                         continue
403                 fi
404         fi
405
406         mkdir -p $RESULT_BASE
407         if [ ! -d $RESULT_BASE ]; then
408                 echo "failed to create results directory $RESULT_BASE"
409                 exit 1;
410         fi
411
412         if $OPTIONS_HAVE_SECTIONS; then
413                 echo "SECTION       -- $section"
414         fi
415
416         if $RECREATE_TEST_DEV || [ "$OLD_FSTYP" != "$FSTYP" ]; then
417                 echo "RECREATING    -- $FSTYP on $TEST_DEV"
418                 umount $TEST_DEV 2> /dev/null
419                 if ! _test_mkfs >$tmp.err 2>&1
420                 then
421                         echo "our local _test_mkfs routine ..."
422                         cat $tmp.err
423                         echo "check: failed to mkfs \$TEST_DEV using specified options"
424                         exit 1
425                 fi
426                 out=`_mount_or_remount_rw "$MOUNT_OPTIONS" $TEST_DEV $TEST_DIR`
427                 if [ $? -ne 1 ]; then
428                         echo $out
429                         exit 1
430                 fi
431                 _prepare_test_list
432         elif [ "$OLD_MOUNT_OPTIONS" != "$MOUNT_OPTIONS" ]; then
433                 umount $TEST_DEV 2> /dev/null
434                 out=`_mount_or_remount_rw "$MOUNT_OPTIONS" $TEST_DEV $TEST_DIR`
435                 if [ $? -ne 1 ]; then
436                         echo $out
437                         exit 1
438                 fi
439         fi
440
441         init_rc
442
443         seq="check"
444         check="$RESULT_BASE/check"
445
446         # don't leave old full output behind on a clean run
447         rm -f $check.full
448
449         [ -f $check.time ] || touch $check.time
450
451         # print out our test configuration
452         echo "FSTYP         -- `_full_fstyp_details`"
453         echo "PLATFORM      -- `_full_platform_details`"
454         if [ ! -z "$SCRATCH_DEV" ]; then
455           echo "MKFS_OPTIONS  -- `_scratch_mkfs_options`"
456           echo "MOUNT_OPTIONS -- `_scratch_mount_options`"
457         fi
458         echo
459         needwrap=true
460
461         if [ ! -z "$SCRATCH_DEV" ]; then
462           umount $SCRATCH_DEV 2>/dev/null
463           # call the overridden mkfs - make sure the FS is built
464           # the same as we'll create it later.
465
466           if ! _scratch_mkfs $flag >$tmp.err 2>&1
467           then
468               echo "our local _scratch_mkfs routine ..."
469               cat $tmp.err
470               echo "check: failed to mkfs \$SCRATCH_DEV using specified options"
471               exit 1
472           fi
473
474           # call the overridden mount - make sure the FS mounts with
475           # the same options that we'll mount with later.
476           if ! _scratch_mount >$tmp.err 2>&1
477           then
478               echo "our local mount routine ..."
479               cat $tmp.err
480               echo "check: failed to mount \$SCRATCH_DEV using specified options"
481               exit 1
482           fi
483         fi
484
485         seqres="$check"
486         _check_test_fs
487
488         for seq in $list
489         do
490             err=false
491
492             # the filename for the test and the name output are different.
493             # we don't include the tests/ directory in the name output.
494             seqnum=`echo $seq | sed -e "s;$SRC_DIR/;;"`
495
496             # Similarly, the result directory needs to replace the tests/
497             # part of the test location.
498             group=`dirname $seq`
499             if $OPTIONS_HAVE_SECTIONS; then
500                 export RESULT_DIR=`echo $group | sed -e "s;$SRC_DIR;${RESULT_BASE}/$section;"`
501                 seqres="$RESULT_BASE/$section/$seqnum"
502             else
503                 export RESULT_DIR=`echo $group | sed -e "s;$SRC_DIR;$RESULT_BASE;"`
504                 seqres="$RESULT_BASE/$seqnum"
505             fi
506
507             mkdir -p $RESULT_DIR
508
509             echo -n "$seqnum"
510
511             if $showme
512             then
513                 echo
514                 continue
515             elif [ ! -f $seq ]
516             then
517                 echo " - no such test?"
518             else
519                 # really going to try and run this one
520                 #
521                 rm -f $seqres.out.bad
522
523                 # check if we really should run it
524                 if [ -s $tmp.xlist ]; then
525                         if grep $seqnum $tmp.xlist > /dev/null 2>&1 ; then
526                                 echo "       [expunged]"
527                                 continue
528                         fi
529                 fi
530
531                 # slashes now in names, sed barfs on them so use grep
532                 lasttime=`grep -w ^$seqnum $check.time | awk '// {print $2}'`
533                 if [ "X$lasttime" != X ]; then
534                         echo -n " ${lasttime}s ..."
535                 else
536                         echo -n "       "       # prettier output with timestamps.
537                 fi
538                 rm -f core $seqres.notrun
539
540                 start=`_wallclock`
541                 $timestamp && echo -n " ["`date "+%T"`"]"
542                 [ ! -x $seq ] && chmod u+x $seq # ensure we can run it
543                 $LOGGER_PROG "run xfstest $seqnum"
544                 ./$seq >$tmp.rawout 2>&1
545                 sts=$?
546                 $timestamp && _timestamp
547                 stop=`_wallclock`
548
549                 _fix_malloc <$tmp.rawout >$tmp.out
550                 rm -f $tmp.rawout
551
552                 if [ -f core ]
553                 then
554                     echo -n " [dumped core]"
555                     mv core $RESULT_BASE/$seqnum.core
556                     err=true
557                 fi
558
559                 if [ -f $seqres.notrun ]
560                 then
561                     $timestamp || echo -n " [not run] "
562                     $timestamp && echo " [not run]" && echo -n "        $seqnum -- "
563                     cat $seqres.notrun
564                     notrun="$notrun $seqnum"
565                 else
566                     if [ $sts -ne 0 ]
567                     then
568                         echo -n " [failed, exit status $sts]"
569                         err=true
570                     fi
571                     if [ ! -f $seq.out ]
572                     then
573                         echo " - no qualified output"
574                         err=true
575                     else
576
577                         # coreutils 8.16+ changed quote formats in error messages from
578                         # `foo' to 'foo'. Filter old versions to match the new version.
579                         sed -i "s/\`/\'/g" $tmp.out
580                         if diff $seq.out $tmp.out >/dev/null 2>&1
581                         then
582                             if $err
583                             then
584                                 :
585                             else
586                                 echo "$seqnum `expr $stop - $start`" >>$tmp.time
587                                 echo -n " `expr $stop - $start`s"
588                             fi
589                             echo ""
590                         else
591                             echo " - output mismatch (see $seqres.out.bad)"
592                             mv $tmp.out $seqres.out.bad
593                             $diff $seq.out $seqres.out.bad | {
594                                 if test "$DIFF_LENGTH" -le 0; then
595                                         cat
596                                 else
597                                         head -n "$DIFF_LENGTH"
598                                         echo "..."
599                                         echo "(Run '$diff $seq.out $seqres.out.bad'" \
600                                                 " to see the entire diff)"
601                                 fi; } | \
602                                 sed -e 's/^\(.\)/    \1/'
603                             err=true
604                         fi
605                     fi
606                 fi
607
608             fi
609
610             # come here for each test, except when $showme is true
611             #
612             if $err
613             then
614                 bad="$bad $seqnum"
615                 n_bad=`expr $n_bad + 1`
616                 quick=false
617             fi
618             if [ ! -f $seqres.notrun ]
619             then
620                 try="$try $seqnum"
621                 n_try=`expr $n_try + 1`
622                 _check_test_fs
623             fi
624
625             seq="after_$seqnum"
626         done
627         _wrapup
628         echo
629
630         umount $TEST_DEV 2> /dev/null
631         umount $SCRATCH_DEV 2> /dev/null
632 done
633
634 interrupt=false
635 status=`expr $sum_bad`
636 exit