#!/bin/sh
# Tests a set of patches from a directory.
-# Copyright (C) 2007 Free Software Foundation, Inc.
+# Copyright (C) 2007, 2008 Free Software Foundation, Inc.
# Contributed by Sebastian Pop <sebastian.pop@amd.com>
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation; either version 2 of the License, or
+# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
args=$@
+svnpath=svn://gcc.gnu.org/svn/gcc
dashj=
default_standby=1
standby=$default_standby
watermark=$default_watermark
savecompilers=false
nogpg=false
+stop=false
usage() {
cat <<EOF
patch_tester.sh [-j<N>] [-standby N] [-watermark N] [-savecompilers] [-nogpg]
+ [-svnpath URL] [-stop]
<source_dir> [patches_dir [state_dir [build_dir]]]
J is the flag passed to make. Default is empty string.
PATCHES_DIR. Default is ${default_standby} minutes.
WATERMARK is the 5 minute average system charge under which a new
- compile can start. Default is ${default_watermark}. Note that the comparison
- is done in lexicographical order, so don't forget the leading 0.
+ compile can start. Default is ${default_watermark}.
SAVECOMPILERS copies the compilers in the same directory as the
test results for the non patched version. Default is not copy.
NOGPG can be used to avoid checking the GPG signature of patches.
+ URL is the location of the GCC SVN repository. The default is
+ ${svnpath}.
+
+ STOP exits when PATCHES_DIR is empty.
+
SOURCE_DIR is the directory containing GCC's toplevel configure.
PATCHES_DIR is the directory containing the patches to be tested.
exit 1
}
+makedir () {
+ DIRNAME=$1
+ mkdir -p $DIRNAME
+ if [ $? -ne 0 ]; then
+ echo "ERROR: could not make directory $DIRNAME"
+ exit 1
+ fi
+}
+
while [ $# -ne 0 ]; do
case $1 in
-j*)
-nogpg)
nogpg=true; shift
;;
+ -stop)
+ stop=true; shift
+ ;;
+ -svnpath)
+ svnpath=$2; shift; shift
+ ;;
-*)
echo "Invalid option: $1"
usage
BUILD=$4
fi
-[ -d $PATCHES ] || mkdir -p $PATCHES
-[ -d $STATE ] || mkdir -p $STATE
-[ -d $STATE/patched ] || mkdir -p $STATE/patched
-[ -d $SOURCE ] || mkdir -p $SOURCE
+[ -d $PATCHES ] || makedir $PATCHES
+[ -d $STATE ] || makedir $STATE
+[ -d $STATE/patched ] || makedir $STATE/patched
+[ -d $SOURCE ] || makedir $SOURCE
[ -f $SOURCE/config.guess ] || {
cd $SOURCE
- svn -q co svn://gcc.gnu.org/svn/gcc/trunk .
+ svn -q co $svnpath/trunk .
+ if [ $? -ne 0 ]; then
+ echo "ERROR: initial svn checkout failed"
+ exit 1
+ fi
}
+# This can contain required local settings:
+# default_config configure options, always passed
+# default_make make bootstrap options, always passed
+# default_check make check options, always passed
+[ -f $STATE/defaults ] && . $STATE/defaults
+
VERSION=`svn info $SOURCE | grep "^Revision:" | sed -e "s/^Revision://g" -e "s/ //g"`
exec >> $STATE/tester.log 2>&1 || exit 1
}
report () {
- echo "Checker: (`now`): $@" >> $REPORT
+ echo "$@" >> $REPORT
}
freport () {
cleanup () {
cd $SOURCE
-
- # FORNOW: Until this script is not committed to trunk, save and restore it.
- mv $SOURCE/contrib/patch_tester.sh $STATE
svn cleanup && svn revert -R . && svn st | cut -d' ' -f5- | xargs rm -v
- mv $STATE/patch_tester.sh $SOURCE/contrib/
}
selfexec () {
- exec ${CONFIG_SHELL-/bin/sh} $SOURCE/contrib/patch_tester.sh $args
+ exec ${CONFIG_SHELL-/bin/sh} $0 $args
}
update () {
cd $SOURCE
case $svn_branch in
trunk)
- if ! svn switch -r $svn_revision svn://gcc.gnu.org/svn/gcc/trunk &> $TESTING/svn ; then
+ if ! svn switch -r $svn_revision $svnpath/trunk &> $TESTING/svn ; then
report "failed to update svn sources with"
- report "svn switch -r $svn_revision svn://gcc.gnu.org/svn/gcc/trunk"
+ report "svn switch -r $svn_revision $svnpath/trunk"
freport $TESTING/svn
return 1
fi
;;
- svn://gcc.gnu.org/svn/gcc/*)
+ ${svnpath}*)
if ! svn switch -r $svn_revision $svn_branch &> $TESTING/svn ; then
report "failed to update svn sources with"
report "svn switch -r $svn_revision $svn_branch"
;;
*)
- if ! svn switch -r $svn_revision svn://gcc.gnu.org/svn/gcc/branches/$svn_branch &> $TESTING/svn ; then
+ if ! svn switch -r $svn_revision $svnpath/branches/$svn_branch &> $TESTING/svn ; then
report "failed to update svn sources with"
- report "svn switch -r $svn_revision svn://gcc.gnu.org/svn/gcc/branches/$svn_branch"
+ report "svn switch -r $svn_revision $svnpath/branches/$svn_branch"
freport $TESTING/svn
return 1
fi
;;
esac
+ contrib/gcc_update --touch
current_version=`svn info $SOURCE | grep "^Revision:" | sed -e "s/^Revision://g" -e "s/ //g"`
if [[ $VERSION < $current_version ]]; then
fi
fi
- # Detect if the patch was created in toplev GCC.
- grep "^Index: " $PATCH | grep "gcc/"
- if [ $? = 0 ]; then
- cd $SOURCE
- if ! patch -p0 < $PATCH &> $TESTING/patching ; then
- report "your patch failed to apply:"
- freport $TESTING/patching
- return 1
- fi
- else
- cd $SOURCE/gcc
- if ! patch -p0 < $PATCH &> $TESTING/patching ; then
- report "your patch failed to apply:"
- freport $TESTING/patching
- return 1
- fi
+ cd $SOURCE
+ if ! patch -p0 < $PATCH &> $TESTING/patching ; then
+ report "your patch failed to apply:"
+ report "(check that the patch was created at the top level)"
+ freport $TESTING/patching
+ return 1
fi
+
+ # Just assume indexes for now -- not really great, but svn always
+ # makes them.
+ grep "^Index: " $PATCH | sed -e 's/Index: //' | while read file; do
+ # If the patch resulted in an empty file, delete it.
+ # This is how svn reports deletions.
+ if [ ! -s $file ]; then
+ rm -f $file
+ report "Deleting empty file $file"
+ fi
+ done
}
save_compilers () {
cd $BUILD
CONFIG_OPTIONS=`grep "^configure:" $PATCH | sed -e "s/^configure://g"`
- if ! $SOURCE/configure $CONFIG_OPTIONS &> $1/configure ; then
- report "configure failed with:"
+ CONFIG_OPTIONS="$default_config $CONFIG_OPTIONS"
+ if ! eval $SOURCE/configure $CONFIG_OPTIONS &> $1/configure ; then
+ report "configure with `basename $1` version failed with:"
freport $1/configure
return 1
fi
- if ! make $dashj `grep "^make:" $PATCH | sed -e "s/^make://g"` bootstrap &> $1/bootstrap ; then
- report "bootstrap failed with last lines:"
+ MAKE_ARGS=`grep "^make:" $PATCH | sed -e "s/^make://g"`
+ MAKE_ARGS="$default_make $MAKE_ARGS"
+ if ! eval make $dashj $MAKE_ARGS &> $1/bootstrap ; then
+ report "bootstrap with `basename $1` version failed with last lines:"
tail -30 $1/bootstrap > $1/last_bootstrap
freport $1/last_bootstrap
report "grep --context=20 Error bootstrap:"
fi
CHECK_OPTIONS=`grep "^check:" $PATCH | sed -e "s/^check://g"`
- make $dashj $CHECK_OPTIONS -k check &> $1/check
+ CHECK_OPTIONS="$default_check $CHECK_OPTIONS"
+ eval make $dashj $CHECK_OPTIONS -k check &> $1/check
+
+ SUITESRUN="`grep 'Summary ===' $1/check | cut -d' ' -f 2 | sort`"
+ if [ x$SUITESRUN = x ]; then
+ report "check with `basename $1` version failed, no testsuites were run"
+ return 1
+ fi
for LOG in $TESTLOGS ; do
if [ -f $BUILD/$LOG ]; then
# Build the pristine tree with exactly the same options as the patch under test.
bootntest_pristine () {
cleanup
- current_branch=`svn info $SOURCE | grep "^URL:" | sed -e "s/URL: //g" -e "s/svn:\/\/gcc.gnu.org\/svn\/gcc\///g"`
+ current_branch=`svn info $SOURCE | grep "^URL:" | sed -e "s/URL: //g" -e "s,${svnpath},,g"`
current_version=`svn info $SOURCE | grep "^Revision:" | sed -e "s/^Revision://g" -e "s/ //g"`
PRISTINE=$STATE/$current_branch/$current_version
fi
fi
+firstpatch=true
while true; do
PATCH=`ls -rt -1 $PATCHES | head -1`
if [ x$PATCH = x ]; then
+ if [ $stop = true ]; then
+ if [ $firstpatch = true ]; then
+ echo "No patches ready to test, quitting."
+ exit 1
+ else
+ echo "No more patches to test."
+ exit 0
+ fi
+ fi
sleep ${standby}m
else
+ firstpatch=false
sysload=`uptime | cut -d, -f 5`
if [[ $sysload > $watermark ]]; then
# Wait a bit when system load is too high.