OSDN Git Service

2008-05-08 Sebastian Pop <sebastian.pop@amd.com>
[pf3gnuchains/gcc-fork.git] / contrib / patch_tester.sh
index 9866b3d..83f3322 100755 (executable)
@@ -1,12 +1,12 @@
 #!/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,
@@ -29,6 +29,7 @@ EOF
 
 args=$@
 
+svnpath=svn://gcc.gnu.org/svn/gcc
 dashj=
 default_standby=1
 standby=$default_standby
@@ -36,10 +37,12 @@ default_watermark=0.60
 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.
@@ -48,14 +51,18 @@ patch_tester.sh [-j<N>] [-standby N] [-watermark N] [-savecompilers] [-nogpg]
     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.
@@ -71,6 +78,15 @@ EOF
     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*)
@@ -90,6 +106,12 @@ while [ $# -ne 0 ]; do
        -nogpg)
            nogpg=true; shift
            ;;
+       -stop)
+           stop=true; shift
+           ;;
+       -svnpath)
+           svnpath=$2; shift; shift
+           ;;
        -*) 
            echo "Invalid option: $1"
            usage
@@ -123,15 +145,25 @@ else
     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
@@ -165,7 +197,7 @@ now () {
 }
 
 report () {
-    echo "Checker: (`now`): $@" >> $REPORT
+    echo "$@" >> $REPORT
 }
 
 freport () {
@@ -178,15 +210,11 @@ 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 () {
@@ -204,15 +232,15 @@ 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"
@@ -222,14 +250,15 @@ update () {
            ;;
 
        *)
-           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
@@ -250,23 +279,24 @@ apply_patch () {
        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 () {
@@ -283,14 +313,17 @@ bootntest () {
     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:"
@@ -300,7 +333,14 @@ bootntest () {
     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
@@ -322,7 +362,7 @@ bootntest_patched () {
 # 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
 
@@ -432,11 +472,22 @@ if [ -d $TESTING ]; then
     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.