35e6c532bc57fad20c2ae56c7a430f871baad9cb
[xfstests-dev.git] / tools / auto-qa
1 #!/bin/sh
2 #
3 # Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
4
5 # This program is free software; you can redistribute it and/or modify it
6 # under the terms of version 2 of the GNU General Public License as
7 # published by the Free Software Foundation.
8
9 # This program is distributed in the hope that it would be useful, but
10 # WITHOUT ANY WARRANTY; without even the implied warranty of
11 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12
13 # Further, this software is distributed without any warranty that it is
14 # free of the rightful claim of any third person regarding infringement
15 # or the like.  Any license provided herein, whether implied or
16 # otherwise, applies only to this software file.  Patent licenses, if
17 # any, provided herein do not apply to combinations of this program with
18 # other software, or any other product whatsoever.
19
20 # You should have received a copy of the GNU General Public License along
21 # with this program; if not, write the Free Software Foundation, Inc., 59
22 # Temple Place - Suite 330, Boston MA 02111-1307, USA.
23
24 # Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
25 # Mountain View, CA  94043, or:
26
27 # http://www.sgi.com 
28
29 # For further information regarding this notice, see: 
30
31 # http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
32 #
33
34 # automatic qa system. 31/08/00 dxm@sgi.com
35 #
36 # Usage: auto_qa start-state [stop-state]
37 # Do auto_qa from start-state up to stop-state inclusive
38 # or if no stop-state given then do it until reach "done" state.
39 #
40
41 _log()
42 {
43     echo "$*" >&2
44     echo "$*" >> $LOG
45     sync
46 }
47
48 _fail()
49 {
50     if [ "$started" = "1" ] 
51     then
52         echo "auto-qa stopped" | wall
53         started=0
54     fi
55
56     _log "$*"
57     
58     # send special email if a cron'd qa run fails
59     case $state
60     in
61         cron*)
62             mail -s "XFS QA status report" $EMAIL < $LOG 2>&1
63         ;;
64     esac
65
66     status=1
67     exit 1
68 }
69
70 _get_kernel_version()
71 {
72     [ -x "$KWORKAREA" ] || return
73     [ -r "$KWORKAREA/Makefile" ] \
74         || _fail "can't read kernel makefile $KWORKAREA/Makefile"
75
76     eval `awk '
77         BEGIN { FS = "[ \t=]+" }
78         /^VERSION =/ { a=$2 }
79         /^PATCHLEVEL =/ { b=$2 }
80         /^SUBLEVEL =/ { c=$2 }
81         /^EXTRAVERSION =/ { d=$2 }
82         END { 
83             print "VERSION=" a "." b "." c d " ; SVERSION=" a "." b "." c
84         }
85    ' < $KWORKAREA/Makefile`
86 }
87
88 # this should be constant
89
90 ROOT="$HOME/qa"
91 HOST=`hostname -s`
92 if [ ! -z "$CVSROOT" ]; then
93     export WORKAREA="$ROOT/xfs-cmds"
94 else
95     [ -z "$WORKAREA" ] && export WORKAREA="$ROOT/xfs-cmds"
96 fi
97
98
99 export PATH="/bin:/usr/bin:/sbin:/usr/sbin:/usr/local/bin/ptools:/usr/local/bin"
100 STATE=$ROOT/qa.state
101 QADIR="$WORKAREA/xfstests"
102 SUDO="su -c"
103 CONFIG="$ROOT/$HOST.config"
104 COMMON_CONFIG="$QADIR/common.config"
105 SH="/bin/sh"
106 LOG="$ROOT/qa.log"
107
108 # do some cleanup on exit
109
110 _cleanup()
111 {
112     umount $SCRATCH_DEV &> /dev/null
113     umount $TEST_DEV &> /dev/null
114     if [ "$started" = 1 ]
115     then
116         echo "auto-qa stopped" | wall
117         started=0
118     fi
119 }
120 status=1
121 trap "_cleanup; exit \$status" 0 1 2 3 15
122
123 # clean exit
124
125 _success()
126 {
127     status=0
128     exit 0
129 }
130
131 _get_state()
132 {
133     state=`cat $STATE`
134 }
135
136 _set_state()
137 {
138     echo $1 > $STATE
139     _get_state
140 }
141
142 _change_state()
143 {
144     new=$1
145
146     # if have state XXXX-state then preserve XXXX-newstate
147     
148     case $state
149     in
150         *-*)
151             case $new
152             in
153                 *-*)
154                     _set_state $new
155                     ;;
156                 *)
157                     _set_state `echo $state | sed "s/-.*$/-$new/"`
158                     ;;
159             esac
160             ;;
161         *)
162             _set_state $new
163             ;;
164     esac
165 }
166
167 _sudo()
168 {
169     $ROOT/su -c "$*" < /dev/null ;# HACK - we need a hacked su at the mo
170 }
171
172 _restart()
173 {
174     exec $ROOT/su -c "(shutdown -r now \"auto-qa rebooting\" )&" < /dev/null
175 }
176
177 _update_workarea()
178 {
179     if [ -z "$CVSROOT" ]; then
180         _log "  *** p_tupdate"
181         cd "$1"
182         WORKAREA="$1" p_tupdate 2>&1 \
183                         || _fail "          !!! p_tupdate failed"
184
185         _log "  *** non-trunk files"
186         cd "$1"
187         WORKAREA="$1" p_list -c 2>&1 \
188                         || _fail "          !!! p_list failed"
189     else
190         _log "  *** cvs update"
191         cd "$1"
192         cvs -z3 update -d
193     fi
194 }
195
196 _test_mkfs_xfs()
197 {
198     TEST_OPTIONS=""
199     [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \
200         TEST_OPTIONS="$TEST_OPTIONS -rrtdev=$TEST_RTDEV"
201     [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
202         TEST_OPTIONS="$TEST_OPTIONS -llogdev=$TEST_LOGDEV"
203     _sudo /sbin/mkfs.xfs -f $TEST_OPTIONS $MKFS_OPTIONS $* $TEST_DEV
204     mkfs_status=$?
205     if [ "$USE_BIG_LOOPFS" = yes ]; then
206         [ -z "$RETAIN_AG_BYTES" ] && RETAIN_AG_BYTES=0
207         _sudo $QADIR/tools/ag-wipe -q -r $RETAIN_AG_BYTES $TEST_DEV
208     fi
209     return $mkfs_status
210 }
211
212 _test_mount()
213 {
214     TEST_OPTIONS=""
215     [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_RTDEV" ] && \
216         TEST_OPTIONS="$TEST_OPTIONS -ortdev=$TEST_RTDEV"
217     [ "$USE_EXTERNAL" = yes -a ! -z "$TEST_LOGDEV" ] && \
218         TEST_OPTIONS="$TEST_OPTIONS -ologdev=$TEST_LOGDEV"
219     _sudo mount -t xfs $TEST_OPTIONS $* $TEST_DEV $TEST_DIR
220 }
221
222 _i386_install()
223 {
224     _sudo cp -f "$KWORKAREA/arch/i386/boot/bzImage" "$IMAGE" 2>&1 \
225                 || _fail "          !!! install kernel failed"
226     _sudo cp -f "$KWORKAREA/System.map" "$SYSTEMMAP" 2>&1 \
227                 || _fail "          !!! install kernel failed"
228     if [ -z "$KMODULES" -o "$KMODULES" = yes ]; then
229         _sudo make EXTRAVERSION=-$EXTRA modules_install 2>&1 \
230                 || _fail "          !!! install modules failed"
231     fi
232
233
234     if [ -z "$KINSTALL" -o "$KINSTALL" = lilo ]; then
235         _log "  *** reinit lilo"
236         _sudo /sbin/lilo 2>&1 \
237                 || _fail "          !!! reinit lilo failed"
238     fi
239 }
240
241 _i386_restart()
242 {
243     if [ -z "$KINSTALL" -o "$KINSTALL" = lilo ]; then
244         _sudo /sbin/lilo -R $EXTRA $KERNEL_OPTIONS 2>&1 \
245                 || _fail "          !!! lilo failed"
246     fi
247 }
248
249 _ia64_install()
250 {
251     echo not yet implemented
252 }
253
254 _ia64_restart()
255 {
256     echo not yet implemented
257 }
258
259 _check_kernel()
260 {
261     [ -d "$KWORKAREA" ] || _fail "    !!! QA kernel workarea \"$KWORKAREA\" not found"
262     [ -r "$CONFIG" ]    || _fail "    !!! Can't read config file $CONFIG"
263 }
264
265
266 _log "*** XFS QA (`date`)"
267
268 _get_state
269
270 # check preconditions for starting state
271 case $1
272 in
273     cron-init)
274         case $state
275         in
276             *done)
277                 ;;
278             *)
279                 _fail "    !!! cron-init while not in \"*done\" state"
280                 ;;
281         esac
282         ;;
283     cron-restarted)
284         # we don't auto restart after reboot, but cron the restart
285         # to happen a bit later - it's much easier and safer that way
286         if [ "$state" != "cron-restarted" ]
287         then
288             _fail "    !!! cron-restarted while not in \"cron-restarted\" state"
289         fi
290         ;;
291 esac
292
293 [ -n "$1" ] && _set_state $1
294 [ -n "$2" ] && stop_state=$2
295
296 [ "$UID" -eq 0 ]        && _fail "    !!! QA most be run as a normal user"
297 [ -d "$ROOT" ]          || _fail "    !!! QA root \"$ROOT\" not found"
298 [ -d "$WORKAREA" ]      || _fail "    !!! QA workarea \"$WORKAREA\" not found"
299 cd $QADIR
300 . "$COMMON_CONFIG"      || _fail "    !!! Couldn't source $COMMON_CONFIG"
301
302 _get_kernel_version
303 IMAGE="$BOOT/vmlinuz-$EXTRA"
304 SYSTEMMAP="$BOOT/System.map-$VERSION-$EXTRA"
305 MODULES="/lib/modules/$SVERSION"
306
307 cd $ROOT
308
309 started=1
310 echo "auto-qa started" | wall
311
312 while true
313 do
314     _get_state
315
316     _log "    *** state $state start (`date`)"
317     _log "      (user=$USER, host=$HOST)"
318     new_state=""
319
320     case $state
321     in
322         *init)
323             echo "" > $ROOT/qa.log
324             echo "" > $ROOT/qa.full
325             _log "******************************************************"
326             _log "QA init $VERSION (`date`)"
327             _log "******************************************************"
328             new_state="updatetools"
329             ;;
330         
331         *updatetools)
332             _update_workarea "$WORKAREA"
333             new_state="cleantools"
334             ;;
335
336         *cleantools)
337             # we need to configure or else we might fail to clean
338             for pkg in attr acl xfsprogs dmapi xfsdump xfstests
339             do
340                 [ -d $WORKAREA/$pkg ] || continue
341                 cd $WORKAREA/$pkg
342                 _log "  *** clean $pkg tools"
343                 make realclean 2>&1 \
344                         || _fail "          !!! clean $pkg failed"
345             done
346             new_state="buildtools"
347             ;;
348
349         *buildtools)
350             _log "      *** build and install tools"
351             for pkg in attr acl xfsprogs dmapi xfsdump xfstests 
352             do
353                 [ -d $WORKAREA/$pkg ] || continue
354                 cd $WORKAREA/$pkg
355
356                 # use e-fence - but this will only take effect on configure
357                 make configure 2>&1 \
358                         || _fail "          !!! configure $pkg failed"
359                 make default 2>&1 \
360                         || _fail "          !!! build $pkg failed"
361
362                 _sudo make install install-dev 2>&1 \
363                         || _fail "          !!! install $pkg failed"
364
365                 # attr and acl now have install-lib targets as well
366                 [ "$pkg" = "attr" -o "$pkg" = "acl" ] || continue
367                 _sudo make install-lib 2>&1 \
368                         || _fail "          !!! install $pkg failed"
369             done
370
371             new_state="updatekernel"
372             ;;
373
374         *updatekernel)
375             _check_kernel
376             _update_workarea "$KWORKAREA"
377             new_state="cleankernel"
378             ;;
379
380         *cleankernel)
381             _check_kernel
382             _log "      *** clean kernel"
383             cd "$KWORKAREA"
384             make mrproper 2>&1 \
385                         || _fail "          !!! clean kernel failed"
386
387             _log "      *** install configuration file"
388             cp -f $CONFIG "$KWORKAREA/.config" 2>&1 \
389                         || _fail "          !!! failed to install config"
390             
391             _log "      *** remove version file"
392             rm -f include/linux/version.h 2>&1 \
393                         || _fail "          !!! failed to clean version"
394
395             new_state="reconfig"
396             ;;
397             
398         *reconfig)
399             _check_kernel
400             _log "      *** reconfig kernel"
401             
402             # we better start from scratch if this fails
403             _change_state "cleankernel"
404             
405             cd "$KWORKAREA"
406             # we want to use default options for any new config options.
407             echo -e "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n" | \
408                 make EXTRAVERSION=-$EXTRA oldconfig 2>&1 \
409                         || _fail "          !!! reconfig oldconfig failed"
410             make EXTRAVERSION=-$EXTRA dep 2>&1 \
411                         || _fail "          !!! reconfig dep failed"
412
413             new_state="buildkernel"
414             ;;
415             
416         *buildkernel)
417             _check_kernel
418             _log "      *** build kernel"
419             _log "          --- kernel ($IMAGE)"
420             [ -z "$KMODULES" -o "$KMODULES" = yes ] && \
421             _log "          --- modules ($MODULES)"
422             
423             _change_state "cleankernel" ; # we better start from scratch if this fails
424             
425             cd "$KWORKAREA"
426             [ -z "$KTARGET" ] && KTARGET=bzImage
427             [ -z "$KMODULES" -o "$KMODULES" = yes ] && \
428                 KTARGET="$KTARGET modules"
429             make -j4 EXTRAVERSION=-$EXTRA $KTARGET 2>&1 \
430                         || _fail "          !!! build $KTARGET failed"
431             new_state="install"
432             ;;
433
434         *install)
435             _check_kernel
436             _log "      *** blat old modules"
437             _sudo rm -rf $MODULES
438             
439             _log "      *** install kernel"
440             cd "$KWORKAREA"
441             case `uname -m`
442             in
443                 i386|i686)      _i386_install ;;
444                 ia64)           _ia64_install ;;
445             esac
446
447             new_state="restart"
448             ;;
449             
450         *restart)
451             _log "          *** select qa kernel"
452             case `uname -m`
453             in
454                 i386|i686)      _i386_restart ;;
455                 ia64)           _ia64_restart ;;
456             esac
457
458             _log "          *** prepare to restart"
459             _change_state "restarted"
460             
461             _log "          *** restarting"
462
463             _restart # doesn't return
464             ;;
465             
466         *restarted)
467             _log "          *** QA reentered after restart"
468             
469             new_state="check"
470             ;;
471           
472         *check)
473             uname=`uname -a`
474             _log "          *** uname $uname"
475
476             if [ "$MODULAR" -eq 0 ]; then
477                 new_state="reset"
478             else
479                 new_state="probe"
480             fi
481             ;;
482             
483         *probe)
484             _log "          *** modules dependencies"
485             _sudo depmod -a  2>&1 \
486                         || _fail "          !!! failed to depmod -a" 
487             
488             _log "          *** unmounting XFS mounts"
489             _sudo umount -a -t xfs 2>&1
490             
491             _log "          *** removing modules"
492             for m in xfsidbg xfs kdbm_pg kdbm_vm
493             do
494                 _sudo rmmod $m 2> /dev/null
495             done
496             
497             _log "          *** installing modules"
498             _sudo modprobe xfs 2>&1 \
499                         || _fail "          !!! failed to modprobe xfs"
500
501             new_state="reset"
502             ;;
503             
504         *reset)
505             
506             _log "          *** unmounting TEST_DEV"
507             _sudo umount $TEST_DEV 2>&1
508             
509             _log "          *** unmounting SCRATCH_DEV"
510             _sudo umount $SCRATCH_DEV 2>&1
511             
512             _log "          *** clean TEST_DEV"
513             _test_mkfs_xfs 2>&1 \
514                         || _fail "          !!! failed to mkfs TEST_DEV"
515             
516             _log "          *** mounting TEST_DEV"
517             _test_mount 2>&1 \
518                         || _fail "          !!! failed to mount"
519                                     
520             new_state="run"
521             ;;
522             
523         soak-run)
524             cd $QADIR
525             
526             _log "          *** run soak test"
527             _sudo ./soak $SOAK_PASSES $SOAK_STRESS $SOAK_PROC \
528                         || _fail "          !!! failed to run soak test"
529
530             new_state="done"
531             ;;
532             
533         bench-run)
534             cd $QADIR
535             
536             # $BENCHMARK is typically unset, which equates to "all"
537             #
538             _log "          *** run benchmarks"
539             _sudo ./bench $BENCH_PASSES `id -nu && id -ng` $BENCHMARK \
540                         || _fail "          !!! failed to run benchmarks"
541
542             _log ""
543             _log "          *** send results mail"
544             mail -s "XFS QA benchmark results" $EMAIL < $QADIR/bench.out 2>&1
545         
546             new_state="done"
547             ;;
548             
549         *run)
550             cd $QADIR
551             
552             _log "          *** run tests ($CHECK_OPTIONS)"
553             _sudo ./check -l $CHECK_OPTIONS 2>&1 | tee $ROOT/qa.out
554             
555             _log ""
556             _log "          *** send status mail"
557             mail -s "XFS QA status report" $EMAIL < $ROOT/qa.out 2>&1
558         
559             new_state="done"
560             ;;
561             
562         *done)
563             _log "*** requested QA state transitions complete"
564
565             _success
566             ;;
567             
568         *nothing)
569             new_state="done"
570             _log "    *** do nothing"
571             ;;
572             
573         *)
574             _fail "        !!! unknown state $state"
575             ;;
576     esac
577
578     _log "    *** state $state done (`date`)"
579     [ "$new_state" = "" ] && _fail "    !!! no new state set"
580
581     if [ -n "$stop_state" ]
582     then
583         # remove hyphen prefixes
584         s1=`echo $state | sed 's/.*-//'`
585         s2=`echo $stop_state | sed 's/.*-//'`
586
587         if [ $s1 = $s2 ]
588         then
589             # we have been requested to stop here and not go on
590             new_state="done"
591         fi
592     fi
593
594     _change_state $new_state
595     
596 done