3 # Control script for QA
5 # Copyright (c) 2000-2002,2006 Silicon Graphics, Inc. All Rights Reserved.
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.
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.
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
32 export QA_CHECK_FS=${QA_CHECK_FS:=true}
33 # number of diff lines from a failed test, 0 for whole output
34 export DIFF_LENGTH=${DIFF_LENGTH:=10}
36 # by default don't output timestamps
37 timestamp=${TIMESTAMP:=false}
39 # generic initialization
42 # we need common.config
43 if ! . ./common.config
45 echo "$iam: failed to source common.config"
49 # argument parsing first - currently very messy, needs cleanup.
58 echo "Usage: $0 [options] [testlist]"'
64 -xfs test XFS (default)
68 -xdiff graphical mode diff
69 -udiff show unified diff (default)
70 -n show me, do not run tests
73 -r randomize test order
74 --large-fs optimise scratch device for large filesystems
77 -g group[,group...] include tests from these groups
78 -x group[,group...] exclude tests from these groups
80 NNN-NNN include test range (eg. 012-021)
100 rm -f $tmp.list $tmp.tmp $tmp.sed
102 # Autodetect fs type based on what's on $TEST_DEV
103 if [ "$HOSTOS" == "Linux" ]
105 export FSTYP=`blkid -c /dev/null -s TYPE -o value $TEST_DEV`
116 group_list=$(sed -n < group \
119 -e "/^[0-9][0-9][0-9].* $r /"'{ s/ .*//p }')
120 if [ -z "$group_list" ]
122 echo "Group \"$r\" is empty or not defined?"
125 [ ! -s $tmp.list ] && touch $tmp.list
128 if grep -s "^$t\$" $tmp.list >/dev/null
132 echo "$t" >>$tmp.list
141 [ ! -s $tmp.list ] && ls [0-9][0-9][0-9] [0-9][0-9][0-9][0-9] >$tmp.list 2>/dev/null
142 group_list=`sed -n <group -e 's/$/ /' -e "/^[0-9][0-9][0-9].* $r /"'{
145 if [ -z "$group_list" ]
147 echo "Group \"$r\" is empty or not defined?"
154 if [ $numsed -gt 100 ]
156 sed -f $tmp.sed <$tmp.list >$tmp.tmp
157 mv $tmp.tmp $tmp.list
161 echo "/^$t\$/d" >>$tmp.sed
162 numsed=`expr $numsed + 1`
164 sed -f $tmp.sed <$tmp.list >$tmp.tmp
165 mv $tmp.tmp $tmp.list
174 -\? | -h | --help) # usage
178 -udf) # -udf ... set FSTYP to udf
183 -xfs) # -xfs ... set FSTYP to xfs
188 -nfs) # -nfs ... set FSTYP to nfs
193 -g) # -g group ... pick from group file
198 -l) # line mode for diff, was default before
203 -xdiff) # graphical diff mode
206 if [ ! -z "$DISPLAY" ]
208 which xdiff >/dev/null 2>&1 && diff=xdiff
209 which gdiff >/dev/null 2>&1 && diff=gdiff
210 which tkdiff >/dev/null 2>&1 && diff=tkdiff
211 which xxdiff >/dev/null 2>&1 && diff=xxdiff
215 -udiff) # show a unified diff, default now, keep for backward compat
220 -q) # "quick", no longer used - always quick :-)
224 -n) # show me, don't do it
228 -r) # randomize test order
233 -T) # turn on timestamp output
242 -x) # -x group ... exclude from group file
246 '[0-9][0-9][0-9] [0-9][0-9][0-9][0-9]')
253 eval `echo $r | sed -e 's/^/start=/' -e 's/-/ end=/'`
257 eval `echo $r | sed -e 's/^/start=/' -e 's/-//'`
258 end=`echo [0-9][0-9][0-9] [0-9][0-9][0-9][0-9] | sed -e 's/\[0-9]//g' -e 's/ *$//' -e 's/.* //'`
261 echo "No tests in range \"$r\"?"
268 export LARGE_SCRATCH_DEV=yes
277 export SCRATCH_DEV_EMPTY_SPACE=${r#*=}
288 # get rid of leading 0s as can be interpreted as octal
289 start=`echo $start | sed 's/^0*//'`
290 end=`echo $end | sed 's/^0*//'`
295 $AWK_PROG </dev/null '
296 BEGIN { for (t='$start'; t<='$end'; t++) printf "%03d\n",t }' \
299 if grep -s "^$id " group >/dev/null
301 # in group file ... OK
304 if [ -f expunged ] && $expunge && egrep "^$id([ ]|\$)" expunged >/dev/null
306 # expunged ... will be reported, but not run, later
310 echo "$id - unknown test, ignored"
320 # found some valid test numbers ... this is good
325 # had test numbers, but none in group file ... do nothing
328 # no test numbers, do everything from group file
329 sed -n -e '/^[0-9][0-9][0-9]*/s/[ ].*//p' <group >$tmp.list
333 # should be sort -n, but this did not work for Linux when this
334 # was ported from IRIX
336 list=`sort $tmp.list`
337 rm -f $tmp.list $tmp.tmp $tmp.sed
341 list=`echo $list | awk -f randomize.awk`
346 [ "$XFS_LOGPRINT_PROG" = "" ] && _fatal "xfs_logprint not found"
347 [ "$XFS_REPAIR_PROG" = "" ] && _fatal "xfs_repair not found"
348 [ "$XFS_CHECK_PROG" = "" ] && _fatal "xfs_check not found"
349 [ "$XFS_DB_PROG" = "" ] && _fatal "xfs_db not found"
350 [ "$MKFS_XFS_PROG" = "" ] && _fatal "mkfs_xfs not found"
353 [ "$MKFS_UDF_PROG" = "" ] && _fatal "mkfs_udf/mkudffs not found"
356 [ "$MKFS_BTRFS_PROG" = "" ] && _fatal "mkfs.btrfs not found"
365 echo "check: failed to source common.rc"
371 echo "check: QA must be run as root"
377 date "+%H %M %S" | $AWK_PROG '{ print $1*3600 + $2*60 + $3 }'
389 # remove files that were used by hangcheck
391 [ -f /tmp/check.pid ] && rm -rf /tmp/check.pid
392 [ -f /tmp/check.sts ] && rm -rf /tmp/check.sts
399 if [ -f check.time -a -f $tmp.time ]
401 cat check.time $tmp.time \
405 for (i in t) print i " " t[i]
409 mv $tmp.out check.time
412 if [ -f $tmp.expunged ]
414 notrun=`wc -l <$tmp.expunged | sed -e 's/ *//g'`
415 n_try=`expr $n_try - $notrun`
416 list=`echo "$list" | sed -f $tmp.expunged`
421 echo $list | fmt | sed -e 's/^/ /' >>check.log
422 $interrupt && echo "Interrupted!" >>check.log
424 if [ ! -z "$n_try" -a $n_try != 0 ]
429 if [ ! -z "$notrun" ]
431 echo "Not run:$notrun"
432 echo "Not run:$notrun" >>check.log
435 if [ ! -z "$n_bad" -a $n_bad != 0 ]
438 echo "Failed $n_bad of $n_try tests"
439 echo "Failures:$bad" | fmt >>check.log
440 echo "Failed $n_bad of $n_try tests" >>check.log
442 echo "Passed all $n_try tests"
443 echo "Passed all $n_try tests" >>check.log
448 rm -f /tmp/*.rawout /tmp/*.out /tmp/*.err /tmp/*.time
449 rm -f /tmp/check.pid /tmp/check.sts
453 trap "_wrapup; exit \$status" 0 1 2 3 15
456 # Save pid of check in a well known place, so that hangcheck can be sure it
457 # has the right pid (getting the pid from ps output is not reliable enough).
459 rm -rf /tmp/check.pid
460 echo $$ >/tmp/check.pid
463 # Save the status of check in a well known place, so that hangcheck can be
464 # sure to know where check is up to (getting test number from ps output is
465 # not reliable enough since the trace stuff has been introduced).
467 rm -rf /tmp/check.sts
468 echo "preamble" >/tmp/check.sts
470 # don't leave old full output behind on a clean run
473 [ -f check.time ] || touch check.time
475 # print out our test configuration
476 echo "FSTYP -- `_full_fstyp_details`"
477 echo "PLATFORM -- `_full_platform_details`"
478 if [ ! -z "$SCRATCH_DEV" ]; then
479 echo "MKFS_OPTIONS -- `_scratch_mkfs_options`"
480 echo "MOUNT_OPTIONS -- `_scratch_mount_options`"
485 if [ ! -z "$SCRATCH_DEV" ]; then
486 umount $SCRATCH_DEV 2>/dev/null
487 # call the overridden mkfs - make sure the FS is built
488 # the same as we'll create it later.
490 if ! _scratch_mkfs $flag >$tmp.err 2>&1
492 echo "our local _scratch_mkfs routine ..."
494 echo "check: failed to mkfs \$SCRATCH_DEV using specified options"
498 # call the overridden mount - make sure the FS mounts with
499 # the same options that we'll mount with later.
500 if ! _scratch_mount >$tmp.err 2>&1
502 echo "our local mount routine ..."
504 echo "check: failed to mount \$SCRATCH_DEV using specified options"
512 [ -n "$TESTS_REMAINING_LOG" ] && echo $list > $TESTS_REMAINING_LOG
518 if [ -n "$TESTS_REMAINING_LOG" ] ; then
519 sed -e "s/$seq//" -e 's/ / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp
520 mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG
528 elif [ -f expunged ] && $expunge && egrep "^$seq([ ]|\$)" expunged >/dev/null
532 echo "/^$seq\$/d" >>$tmp.expunged
535 echo " - no such test?"
536 echo "/^$seq\$/d" >>$tmp.expunged
538 # really going to try and run this one
541 lasttime=`sed -n -e "/^$seq /s/.* //p" <check.time`
542 if [ "X$lasttime" != X ]; then
543 echo -n " ${lasttime}s ..."
545 echo -n " " # prettier output with timestamps.
547 rm -f core $seq.notrun
550 echo "$seq" >/tmp/check.sts
553 $timestamp && echo -n " ["`date "+%T"`"]"
554 [ ! -x $seq ] && chmod u+x $seq # ensure we can run it
555 $LOGGER_PROG "run xfstest $seq"
556 ./$seq >$tmp.rawout 2>&1
558 $timestamp && _timestamp
561 _fix_malloc <$tmp.rawout >$tmp.out
566 echo -n " [dumped core]"
571 if [ -f $seq.notrun ]
573 $timestamp || echo -n " [not run] "
574 $timestamp && echo " [not run]" && echo -n " $seq -- "
576 notrun="$notrun $seq"
580 echo -n " [failed, exit status $sts]"
585 echo " - no qualified output"
588 if diff $seq.out $tmp.out >/dev/null 2>&1
594 echo "$seq `expr $stop - $start`" >>$tmp.time
595 echo -n " `expr $stop - $start`s"
599 echo " - output mismatch (see $seq.out.bad)"
600 mv $tmp.out $seq.out.bad
601 $diff $seq.out $seq.out.bad | {
602 if test "$DIFF_LENGTH" -le 0; then
605 head -n "$DIFF_LENGTH"
607 sed -e 's/^\(.\)/ \1/'
609 echo " (Run '$diff $seq.out $seq.out.bad' to see the" \
618 # come here for each test, except when $showme is true
623 n_bad=`expr $n_bad + 1`
626 if [ ! -f $seq.notrun ]
629 n_try=`expr $n_try + 1`