OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-stable/] [gcc-4.5.1/] [contrib/] [patch_tester.sh] - Blame information for rev 826

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.