xfstests: make length of diff output configurable
[jlayton/xfstests.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 n_try=0
26 try=""
27 n_bad=0
28 bad=""
29 notrun=""
30 interrupt=true
31
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}
35
36 # by default don't output timestamps
37 timestamp=${TIMESTAMP:=false}
38
39 # generic initialization
40 iam=check
41
42 # we need common.config
43 if ! . ./common.config
44 then
45     echo "$iam: failed to source common.config"
46     exit 1
47 fi
48
49 # we need common
50 . ./common
51
52
53 # we need common.rc
54 if ! . ./common.rc
55 then
56     echo "check: failed to source common.rc"
57     exit 1
58 fi
59
60 if [ `id -u` -ne 0 ]
61 then
62     echo "check: QA must be run as root"
63     exit 1
64 fi
65
66 _wallclock()
67 {
68     date "+%H %M %S" | $AWK_PROG '{ print $1*3600 + $2*60 + $3 }'
69 }
70
71 _timestamp()
72 {
73     now=`date "+%T"`
74     echo -n " [$now]"
75 }
76
77 _wrapup()
78 {
79     # for hangcheck ...
80     # remove files that were used by hangcheck
81     #
82     [ -f /tmp/check.pid ] && rm -rf /tmp/check.pid
83     [ -f /tmp/check.sts ] && rm -rf /tmp/check.sts
84
85     if $showme
86     then
87         :
88     elif $needwrap
89     then
90         if [ -f check.time -a -f $tmp.time ]
91         then
92             cat check.time $tmp.time \
93             | $AWK_PROG '
94         { t[$1] = $2 }
95 END     { if (NR > 0) {
96             for (i in t) print i " " t[i]
97           }
98         }' \
99             | sort -n >$tmp.out
100             mv $tmp.out check.time
101         fi
102
103         if [ -f $tmp.expunged ]
104         then
105             notrun=`wc -l <$tmp.expunged | sed -e 's/  *//g'`
106             n_try=`expr $n_try - $notrun`
107             list=`echo "$list" | sed -f $tmp.expunged`
108         fi
109
110         echo "" >>check.log
111         date >>check.log
112         echo $list | fmt | sed -e 's/^/    /' >>check.log
113         $interrupt && echo "Interrupted!" >>check.log
114         
115         if [ ! -z "$n_try" -a $n_try != 0 ]
116         then
117             echo "Ran:$try"
118         fi
119
120         if [ ! -z "$notrun" ]
121         then
122             echo "Not run:$notrun"
123             echo "Not run:$notrun" >>check.log
124         fi
125
126         if [ ! -z "$n_bad" -a $n_bad != 0 ]
127         then
128             echo "Failures:$bad"
129             echo "Failed $n_bad of $n_try tests"
130             echo "Failures:$bad" | fmt >>check.log
131             echo "Failed $n_bad of $n_try tests" >>check.log
132         else
133             echo "Passed all $n_try tests"
134             echo "Passed all $n_try tests" >>check.log
135         fi
136         needwrap=false
137     fi
138
139     rm -f /tmp/*.rawout /tmp/*.out /tmp/*.err /tmp/*.time
140     rm -f /tmp/check.pid /tmp/check.sts
141     rm -f $tmp.*
142 }
143
144 trap "_wrapup; exit \$status" 0 1 2 3 15
145
146 # for hangcheck ...
147 # Save pid of check in a well known place, so that hangcheck can be sure it
148 # has the right pid (getting the pid from ps output is not reliable enough).
149 #
150 rm -rf /tmp/check.pid
151 echo $$ >/tmp/check.pid
152
153 # for hangcheck ...
154 # Save the status of check in a well known place, so that hangcheck can be
155 # sure to know where check is up to (getting test number from ps output is
156 # not reliable enough since the trace stuff has been introduced).
157 #
158 rm -rf /tmp/check.sts
159 echo "preamble" >/tmp/check.sts
160
161 # don't leave old full output behind on a clean run
162 rm -f check.full
163
164 [ -f check.time ] || touch check.time
165
166 # print out our test configuration
167 echo "FSTYP         -- `_full_fstyp_details`"
168 echo "PLATFORM      -- `_full_platform_details`"
169 if [ ! -z "$SCRATCH_DEV" ]; then
170   echo "MKFS_OPTIONS  -- `_scratch_mkfs_options`"
171   echo "MOUNT_OPTIONS -- `_scratch_mount_options`"
172 fi
173 echo
174
175
176 if [ ! -z "$SCRATCH_DEV" ]; then
177   umount $SCRATCH_DEV 2>/dev/null
178   # call the overridden mkfs - make sure the FS is built
179   # the same as we'll create it later.
180
181   if ! _scratch_mkfs $flag >$tmp.err 2>&1
182   then
183       echo "our local _scratch_mkfs routine ..."
184       cat $tmp.err
185       echo "check: failed to mkfs \$SCRATCH_DEV using specified options"
186       exit 1
187   fi
188
189   # call the overridden mount - make sure the FS mounts with
190   # the same options that we'll mount with later.
191   if ! _scratch_mount >$tmp.err 2>&1
192   then
193       echo "our local mount routine ..."
194       cat $tmp.err
195       echo "check: failed to mount \$SCRATCH_DEV using specified options"
196       exit 1
197   fi
198 fi
199
200 seq="check"
201 _check_test_fs
202
203 [ -n "$TESTS_REMAINING_LOG" ] && echo $list > $TESTS_REMAINING_LOG
204
205 for seq in $list
206 do
207     err=false
208     echo -n "$seq"
209     if [ -n "$TESTS_REMAINING_LOG" ] ; then
210         sed -e "s/$seq//" -e 's/  / /' -e 's/^ *//' $TESTS_REMAINING_LOG > $TESTS_REMAINING_LOG.tmp
211         mv $TESTS_REMAINING_LOG.tmp $TESTS_REMAINING_LOG
212         sync
213     fi
214
215     if $showme
216     then
217         echo
218         continue
219     elif [ -f expunged ] && $expunge && egrep "^$seq([  ]|\$)" expunged >/dev/null
220     then
221         echo " - expunged"
222         rm -f $seq.out.bad
223         echo "/^$seq\$/d" >>$tmp.expunged
224     elif [ ! -f $seq ]
225     then
226         echo " - no such test?"
227         echo "/^$seq\$/d" >>$tmp.expunged
228     else
229         # really going to try and run this one
230         #
231         rm -f $seq.out.bad
232         lasttime=`sed -n -e "/^$seq /s/.* //p" <check.time`
233         if [ "X$lasttime" != X ]; then
234                 echo -n " ${lasttime}s ..."
235         else
236                 echo -n "       "       # prettier output with timestamps.
237         fi
238         rm -f core $seq.notrun
239
240         # for hangcheck ...
241         echo "$seq" >/tmp/check.sts
242
243         start=`_wallclock`
244         $timestamp && echo -n " ["`date "+%T"`"]"
245         [ ! -x $seq ] && chmod u+x $seq # ensure we can run it
246         [ -x /usr/bin/logger ] && /usr/bin/logger "run xfstest $seq"
247         ./$seq >$tmp.rawout 2>&1
248         sts=$?
249         $timestamp && _timestamp
250         stop=`_wallclock`
251
252         _fix_malloc <$tmp.rawout >$tmp.out
253         rm -f $tmp.rawout
254
255         if [ -f core ]
256         then
257             echo -n " [dumped core]"
258             mv core $seq.core
259             err=true
260         fi
261
262         if [ -f $seq.notrun ]
263         then
264             $timestamp || echo -n " [not run] "
265             $timestamp && echo " [not run]" && echo -n "        $seq -- "
266             cat $seq.notrun
267             notrun="$notrun $seq"
268         else
269             if [ $sts -ne 0 ]
270             then
271                 echo -n " [failed, exit status $sts]"
272                 err=true
273             fi
274             if [ ! -f $seq.out ]
275             then
276                 echo " - no qualified output"
277                 err=true
278             else
279                 if diff $seq.out $tmp.out >/dev/null 2>&1
280                 then
281                     if $err
282                     then
283                         :
284                     else
285                         echo "$seq `expr $stop - $start`" >>$tmp.time
286                         echo -n " `expr $stop - $start`s"
287                     fi
288                     echo ""
289                 else
290                     echo " - output mismatch (see $seq.out.bad)"
291                     mv $tmp.out $seq.out.bad
292                     $diff $seq.out $seq.out.bad | {
293                         if test "$DIFF_LENGTH" -le 0; then
294                                 cat
295                         else
296                                 head -n "$DIFF_LENGTH"
297                         fi; } | \
298                         sed -e 's/^\(.\)/    \1/'
299                     echo "     ..."
300                     echo "     (Run '$diff $seq.out $seq.out.bad' to see the" \
301                          "entire diff)"
302                     err=true
303                 fi
304             fi
305         fi
306
307     fi
308
309     # come here for each test, except when $showme is true
310     #
311     if $err
312     then
313         bad="$bad $seq"
314         n_bad=`expr $n_bad + 1`
315         quick=false
316     fi
317     if [ ! -f $seq.notrun ]
318     then
319         try="$try $seq"
320         n_try=`expr $n_try + 1`
321         _check_test_fs
322     fi
323     
324     seq="after_$seq"
325 done
326
327 interrupt=false
328 status=`expr $n_bad`
329 exit