Mercurial > hg > CbC > CbC_gcc
annotate contrib/patch_tester.sh @ 67:f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author | nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 22 Mar 2011 17:18:12 +0900 |
parents | a06113de4d67 |
children | 04ced10e8804 |
rev | line source |
---|---|
0 | 1 #!/bin/sh |
2 | |
3 # Tests a set of patches from a directory. | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
4 # Copyright (C) 2007, 2008, 2011 Free Software Foundation, Inc. |
0 | 5 # Contributed by Sebastian Pop <sebastian.pop@amd.com> |
6 | |
7 # This program is free software; you can redistribute it and/or modify | |
8 # it under the terms of the GNU General Public License as published by | |
9 # the Free Software Foundation; either version 3 of the License, or | |
10 # (at your option) any later version. | |
11 | |
12 # This program is distributed in the hope that it will be useful, | |
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
15 # GNU General Public License for more details. | |
16 | |
17 # You should have received a copy of the GNU General Public License | |
18 # along with this program; if not, write to the Free Software | |
19 # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
20 | |
21 cat <<EOF | |
22 | |
23 WARNING: This script should only be fed with patches from known | |
24 authorized and trusted sources. Don't even think about | |
25 hooking it up to a raw feed from the gcc-patches list or | |
26 you'll regret it. | |
27 | |
28 EOF | |
29 | |
30 args=$@ | |
31 | |
32 svnpath=svn://gcc.gnu.org/svn/gcc | |
33 dashj= | |
34 default_standby=1 | |
35 standby=$default_standby | |
36 default_watermark=0.60 | |
37 watermark=$default_watermark | |
38 savecompilers=false | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
39 nopristinecache=false |
0 | 40 nogpg=false |
41 stop=false | |
42 | |
43 usage() { | |
44 cat <<EOF | |
45 patch_tester.sh [-j<N>] [-standby N] [-watermark N] [-savecompilers] [-nogpg] | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
46 [-svnpath URL] [-stop] [-nopristinecache] |
0 | 47 <source_dir> [patches_dir [state_dir [build_dir]]] |
48 | |
49 J is the flag passed to make. Default is empty string. | |
50 | |
51 STANDBY is the number of minutes between checks for new patches in | |
52 PATCHES_DIR. Default is ${default_standby} minutes. | |
53 | |
54 WATERMARK is the 5 minute average system charge under which a new | |
55 compile can start. Default is ${default_watermark}. | |
56 | |
57 SAVECOMPILERS copies the compilers in the same directory as the | |
58 test results for the non patched version. Default is not copy. | |
59 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
60 NOPRISTINECACHE prevents use of cached test results from any earlier |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
61 test runs on the pristine version of the branch and revision under |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
62 test (the default behaviour). This should be used when testing the |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
63 same revision and patch with multiple sets of configure options, as |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
64 these may affect the set of baseline failures. |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
65 |
0 | 66 NOGPG can be used to avoid checking the GPG signature of patches. |
67 | |
68 URL is the location of the GCC SVN repository. The default is | |
69 ${svnpath}. | |
70 | |
71 STOP exits when PATCHES_DIR is empty. | |
72 | |
73 SOURCE_DIR is the directory containing GCC's toplevel configure. | |
74 | |
75 PATCHES_DIR is the directory containing the patches to be tested. | |
76 Default is SOURCE_DIR/patches. | |
77 | |
78 STATE_DIR is where the tester maintains its internal state. | |
79 Default is SOURCE_DIR/state. | |
80 | |
81 BUILD_DIR is the build tree, a temporary directory that this | |
82 script will delete and recreate. Default is SOURCE_DIR/obj. | |
83 | |
84 EOF | |
85 exit 1 | |
86 } | |
87 | |
88 makedir () { | |
89 DIRNAME=$1 | |
90 mkdir -p $DIRNAME | |
91 if [ $? -ne 0 ]; then | |
92 echo "ERROR: could not make directory $DIRNAME" | |
93 exit 1 | |
94 fi | |
95 } | |
96 | |
97 while [ $# -ne 0 ]; do | |
98 case $1 in | |
99 -j*) | |
100 dashj=$1; shift | |
101 ;; | |
102 -standby) | |
103 [[ $# > 2 ]] || usage | |
104 standby=$2; shift; shift | |
105 ;; | |
106 -watermark) | |
107 [[ $# > 2 ]] || usage | |
108 watermark=$2; shift; shift | |
109 ;; | |
110 -savecompilers) | |
111 savecompilers=true; shift | |
112 ;; | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
113 -nopristinecache) |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
114 nopristinecache=true; shift |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
115 ;; |
0 | 116 -nogpg) |
117 nogpg=true; shift | |
118 ;; | |
119 -stop) | |
120 stop=true; shift | |
121 ;; | |
122 -svnpath) | |
123 svnpath=$2; shift; shift | |
124 ;; | |
125 -*) | |
126 echo "Invalid option: $1" | |
127 usage | |
128 ;; | |
129 *) | |
130 break | |
131 ;; | |
132 esac | |
133 done | |
134 | |
135 test $# -eq 0 && usage | |
136 | |
137 SOURCE=$1 | |
138 PATCHES= | |
139 STATE= | |
140 BUILD= | |
141 | |
142 if [[ $# < 2 ]]; then | |
143 PATCHES=$SOURCE/patches | |
144 else | |
145 PATCHES=$2 | |
146 fi | |
147 if [[ $# < 3 ]]; then | |
148 STATE=$SOURCE/state | |
149 else | |
150 STATE=$3 | |
151 fi | |
152 if [[ $# < 4 ]]; then | |
153 BUILD=$SOURCE/obj | |
154 else | |
155 BUILD=$4 | |
156 fi | |
157 | |
158 [ -d $PATCHES ] || makedir $PATCHES | |
159 [ -d $STATE ] || makedir $STATE | |
160 [ -d $STATE/patched ] || makedir $STATE/patched | |
161 [ -d $SOURCE ] || makedir $SOURCE | |
162 [ -f $SOURCE/config.guess ] || { | |
163 cd $SOURCE | |
164 svn -q co $svnpath/trunk . | |
165 if [ $? -ne 0 ]; then | |
166 echo "ERROR: initial svn checkout failed" | |
167 exit 1 | |
168 fi | |
169 } | |
170 | |
171 # This can contain required local settings: | |
172 # default_config configure options, always passed | |
173 # default_make make bootstrap options, always passed | |
174 # default_check make check options, always passed | |
175 [ -f $STATE/defaults ] && . $STATE/defaults | |
176 | |
177 VERSION=`svn info $SOURCE | grep "^Revision:" | sed -e "s/^Revision://g" -e "s/ //g"` | |
178 | |
179 exec >> $STATE/tester.log 2>&1 || exit 1 | |
180 set -x | |
181 | |
182 TESTING=$STATE/testing | |
183 REPORT=$TESTING/report | |
184 PRISTINE=$TESTING/pristine | |
185 PATCHED=$TESTING/patched | |
186 PATCH= | |
187 TARGET=`$SOURCE/config.guess || exit 1` | |
188 TESTLOGS="gcc/testsuite/gcc/gcc.sum | |
189 gcc/testsuite/gfortran/gfortran.sum | |
190 gcc/testsuite/g++/g++.sum | |
191 gcc/testsuite/objc/objc.sum | |
192 $TARGET/libstdc++-v3/testsuite/libstdc++.sum | |
193 $TARGET/libffi/testsuite/libffi.sum | |
194 $TARGET/libjava/testsuite/libjava.sum | |
195 $TARGET/libgomp/testsuite/libgomp.sum | |
196 $TARGET/libmudflap/testsuite/libmudflap.sum" | |
197 COMPILERS="gcc/cc1 | |
198 gcc/cc1obj | |
199 gcc/cc1plus | |
200 gcc/f951 | |
201 gcc/jc1 | |
202 gcc/gnat1 | |
203 gcc/tree1" | |
204 | |
205 now () { | |
206 echo `TZ=UTC date +"%Y_%m_%d_%H_%M_%S"` | |
207 } | |
208 | |
209 report () { | |
210 echo "$@" >> $REPORT | |
211 } | |
212 | |
213 freport () { | |
214 if [ -s $1 ]; then | |
215 report "(cat $1" | |
216 cat $1 >> $REPORT | |
217 report "tac)" | |
218 fi | |
219 } | |
220 | |
221 cleanup () { | |
222 cd $SOURCE | |
223 svn cleanup && svn revert -R . && svn st | cut -d' ' -f5- | xargs rm -v | |
224 } | |
225 | |
226 selfexec () { | |
227 exec ${CONFIG_SHELL-/bin/sh} $0 $args | |
228 } | |
229 | |
230 update () { | |
231 svn_branch=`grep "^branch:" $PATCH | sed -e "s/^branch://g" -e "s/ //g"` | |
232 if [ x$svn_branch = x ]; then | |
233 svn_branch=trunk | |
234 fi | |
235 | |
236 svn_revision=`grep "^revision:" $PATCH | sed -e "s/^revision://g" -e "s/ //g"` | |
237 if [ x$svn_revision = x ]; then | |
238 svn_revision=HEAD | |
239 fi | |
240 | |
241 cleanup | |
242 cd $SOURCE | |
243 case $svn_branch in | |
244 trunk) | |
245 if ! svn switch -r $svn_revision $svnpath/trunk &> $TESTING/svn ; then | |
246 report "failed to update svn sources with" | |
247 report "svn switch -r $svn_revision $svnpath/trunk" | |
248 freport $TESTING/svn | |
249 return 1 | |
250 fi | |
251 ;; | |
252 | |
253 ${svnpath}*) | |
254 if ! svn switch -r $svn_revision $svn_branch &> $TESTING/svn ; then | |
255 report "failed to update svn sources with" | |
256 report "svn switch -r $svn_revision $svn_branch" | |
257 freport $TESTING/svn | |
258 return 1 | |
259 fi | |
260 ;; | |
261 | |
262 *) | |
263 if ! svn switch -r $svn_revision $svnpath/branches/$svn_branch &> $TESTING/svn ; then | |
264 report "failed to update svn sources with" | |
265 report "svn switch -r $svn_revision $svnpath/branches/$svn_branch" | |
266 freport $TESTING/svn | |
267 return 1 | |
268 fi | |
269 ;; | |
270 esac | |
271 contrib/gcc_update --touch | |
272 | |
273 current_version=`svn info $SOURCE | grep "^Revision:" | sed -e "s/^Revision://g" -e "s/ //g"` | |
274 if [[ $VERSION < $current_version ]]; then | |
275 if [ -f $SOURCE/contrib/patch_tester.sh ]; then | |
276 selfexec | |
277 fi | |
278 fi | |
279 | |
280 return 0 | |
281 } | |
282 | |
283 apply_patch () { | |
284 if [ $nogpg = false ]; then | |
285 if ! gpg --batch --verify $PATCH &> $TESTING/gpgverify ; then | |
286 report "your patch failed to verify:" | |
287 freport $TESTING/gpgverify | |
288 return 1 | |
289 fi | |
290 fi | |
291 | |
292 cd $SOURCE | |
293 if ! patch -p0 < $PATCH &> $TESTING/patching ; then | |
294 report "your patch failed to apply:" | |
295 report "(check that the patch was created at the top level)" | |
296 freport $TESTING/patching | |
297 return 1 | |
298 fi | |
299 | |
300 # Just assume indexes for now -- not really great, but svn always | |
301 # makes them. | |
302 grep "^Index: " $PATCH | sed -e 's/Index: //' | while read file; do | |
303 # If the patch resulted in an empty file, delete it. | |
304 # This is how svn reports deletions. | |
305 if [ ! -s $file ]; then | |
306 rm -f $file | |
307 report "Deleting empty file $file" | |
308 fi | |
309 done | |
310 } | |
311 | |
312 save_compilers () { | |
313 for COMPILER in $COMPILERS ; do | |
314 if [ -f $BUILD/$COMPILER ]; then | |
315 cp $BUILD/$COMPILER $PRISTINE | |
316 fi | |
317 done | |
318 } | |
319 | |
320 bootntest () { | |
321 rm -rf $BUILD | |
322 mkdir $BUILD | |
323 cd $BUILD | |
324 | |
325 CONFIG_OPTIONS=`grep "^configure:" $PATCH | sed -e "s/^configure://g"` | |
326 CONFIG_OPTIONS="$default_config $CONFIG_OPTIONS" | |
327 if ! eval $SOURCE/configure $CONFIG_OPTIONS &> $1/configure ; then | |
328 report "configure with `basename $1` version failed with:" | |
329 freport $1/configure | |
330 return 1 | |
331 fi | |
332 | |
333 MAKE_ARGS=`grep "^make:" $PATCH | sed -e "s/^make://g"` | |
334 MAKE_ARGS="$default_make $MAKE_ARGS" | |
335 if ! eval make $dashj $MAKE_ARGS &> $1/bootstrap ; then | |
336 report "bootstrap with `basename $1` version failed with last lines:" | |
337 tail -30 $1/bootstrap > $1/last_bootstrap | |
338 freport $1/last_bootstrap | |
339 report "grep --context=20 Error bootstrap:" | |
340 grep --context=20 Error $1/bootstrap > $1/bootstrap_error | |
341 freport $1/bootstrap_error | |
342 return 1 | |
343 fi | |
344 | |
345 CHECK_OPTIONS=`grep "^check:" $PATCH | sed -e "s/^check://g"` | |
346 CHECK_OPTIONS="$default_check $CHECK_OPTIONS" | |
347 eval make $dashj $CHECK_OPTIONS -k check &> $1/check | |
348 | |
349 SUITESRUN="`grep 'Summary ===' $1/check | cut -d' ' -f 2 | sort`" | |
350 if [ x$SUITESRUN = x ]; then | |
351 report "check with `basename $1` version failed, no testsuites were run" | |
352 return 1 | |
353 fi | |
354 | |
355 for LOG in $TESTLOGS ; do | |
356 if [ -f $BUILD/$LOG ]; then | |
357 mv $BUILD/$LOG $1 | |
358 mv `echo "$BUILD/$LOG" | sed -e "s/\.sum/\.log/g"` $1 | |
359 fi | |
360 done | |
361 | |
362 return 0 | |
363 } | |
364 | |
365 bootntest_patched () { | |
366 cleanup | |
367 mkdir -p $PATCHED | |
368 apply_patch && bootntest $PATCHED | |
369 return $? | |
370 } | |
371 | |
372 # Build the pristine tree with exactly the same options as the patch under test. | |
373 bootntest_pristine () { | |
374 cleanup | |
375 current_branch=`svn info $SOURCE | grep "^URL:" | sed -e "s/URL: //g" -e "s,${svnpath},,g"` | |
376 current_version=`svn info $SOURCE | grep "^Revision:" | sed -e "s/^Revision://g" -e "s/ //g"` | |
377 PRISTINE=$STATE/$current_branch/$current_version | |
378 | |
67
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
379 if [ $nopristinecache = true ]; then |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
380 rm -rf $PRISTINE |
f6334be47118
update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents:
0
diff
changeset
|
381 fi |
0 | 382 if [ -d $PRISTINE ]; then |
383 ln -s $PRISTINE $TESTING/pristine | |
384 return 0 | |
385 else | |
386 mkdir -p $PRISTINE | |
387 ln -s $PRISTINE $TESTING/pristine | |
388 bootntest $PRISTINE | |
389 RETVAL=$? | |
390 if [ $RETVAL = 0 -a $savecompilers = true ]; then | |
391 save_compilers | |
392 fi | |
393 return $RETVAL | |
394 fi | |
395 } | |
396 | |
397 regtest () { | |
398 touch $1/report | |
399 touch $1/passes | |
400 touch $1/failed | |
401 touch $1/regress | |
402 | |
403 for LOG in $TESTLOGS ; do | |
404 NLOG=`basename $LOG` | |
405 if [ -f $1/$NLOG ]; then | |
406 awk '/^FAIL: / { print "'$NLOG'",$2; }' $1/$NLOG | |
407 fi | |
408 done | sort | uniq > $1/failed | |
409 | |
410 comm -12 $1/failed $1/passes >> $1/regress | |
411 NUMREGRESS=`wc -l < $1/regress | tr -d ' '` | |
412 | |
413 if [ $NUMREGRESS -eq 0 ] ; then | |
414 for LOG in $TESTLOGS ; do | |
415 NLOG=`basename $LOG` | |
416 if [ -f $1/$NLOG ] ; then | |
417 awk '/^PASS: / { print "'$NLOG'",$2; }' $1/$NLOG | |
418 fi | |
419 done | sort | uniq | comm -23 - $1/failed > $1/passes | |
420 echo "there are no regressions with your patch." >> $1/report | |
421 else | |
422 echo "with your patch there are $NUMREGRESS regressions." >> $1/report | |
423 echo "list of regressions with your patch:" >> $1/report | |
424 cat $1/regress >> $1/report | |
425 fi | |
426 } | |
427 | |
428 contrib_compare_tests () { | |
429 report "comparing logs with contrib/compare_tests:" | |
430 for LOG in $TESTLOGS ; do | |
431 NLOG=`basename $LOG` | |
432 if [ -f $PRISTINE/$NLOG -a -f $PATCHED/$NLOG ]; then | |
433 $SOURCE/contrib/compare_tests $PRISTINE/$NLOG $PATCHED/$NLOG > $TESTING/compare_$NLOG | |
434 freport $TESTING/compare_$NLOG | |
435 fi | |
436 done | |
437 } | |
438 | |
439 compare_passes () { | |
440 regtest $PRISTINE | |
441 cp $PRISTINE/passes $PATCHED | |
442 regtest $PATCHED | |
443 freport $PATCHED/report | |
444 report "FAILs with patched version:" | |
445 freport $PATCHED/failed | |
446 report "FAILs with pristine version:" | |
447 freport $PRISTINE/failed | |
448 | |
449 # contrib_compare_tests | |
450 } | |
451 | |
452 write_report () { | |
453 backup_patched=$STATE/patched/`now` | |
454 report "The files used for the validation of your patch are stored in $backup_patched on the tester machine." | |
455 | |
456 EMAIL=`grep "^email:" $PATCH | sed -e "s/^email://g" -e "s/ //g"` | |
457 if [ x$EMAIL != x ]; then | |
458 mutt -s "[regtest] Results for `basename $PATCH` on $TARGET" -i $REPORT -a $PATCH $EMAIL | |
459 fi | |
460 | |
461 mv $TESTING $backup_patched | |
462 } | |
463 | |
464 announce () { | |
465 EMAIL=`grep "^email:" $PATCH | sed -e "s/^email://g" -e "s/ //g"` | |
466 if [ x$EMAIL != x ]; then | |
467 | |
468 START_REPORT=$TESTING/start_report | |
469 echo "Hi, " >> $START_REPORT | |
470 echo "I'm the automatic tester running on $TARGET." >> $START_REPORT | |
471 echo "I just started to look at your patch `basename $PATCH`." >> $START_REPORT | |
472 echo "Bye, your automatic tester." >> $START_REPORT | |
473 mutt -s "[regtest] Starting bootstrap for `basename $PATCH` on $TARGET" -i $START_REPORT $EMAIL | |
474 fi | |
475 } | |
476 | |
477 # After selfexec, $TESTING is already set up. | |
478 if [ -d $TESTING ]; then | |
479 # The only file in $TESTING is the patch. | |
480 PATCH=`ls -rt -1 $TESTING | head -1` | |
481 PATCH=$TESTING/$PATCH | |
482 if [ -f $PATCH ]; then | |
483 bootntest_patched && bootntest_pristine && compare_passes | |
484 write_report | |
485 fi | |
486 fi | |
487 | |
488 firstpatch=true | |
489 while true; do | |
490 PATCH=`ls -rt -1 $PATCHES | head -1` | |
491 if [ x$PATCH = x ]; then | |
492 if [ $stop = true ]; then | |
493 if [ $firstpatch = true ]; then | |
494 echo "No patches ready to test, quitting." | |
495 exit 1 | |
496 else | |
497 echo "No more patches to test." | |
498 exit 0 | |
499 fi | |
500 fi | |
501 sleep ${standby}m | |
502 else | |
503 firstpatch=false | |
504 sysload=`uptime | cut -d, -f 5` | |
505 if [[ $sysload > $watermark ]]; then | |
506 # Wait a bit when system load is too high. | |
507 sleep ${standby}m | |
508 else | |
509 mkdir -p $TESTING | |
510 mv $PATCHES/$PATCH $TESTING/ | |
511 PATCH=$TESTING/$PATCH | |
512 | |
513 announce | |
514 update && bootntest_patched && bootntest_pristine && compare_passes | |
515 write_report | |
516 fi | |
517 fi | |
518 done |