Home | History | Annotate | Download | only in bin
      1 #!/bin/sh
      2 
      3 #----------------------------------------------------------------------------
      4 # Automated build and test for Valgrind.  Compares Valgrind from 24 hours
      5 # ago with the current one.  See the README.txt on how to run it.
      6 #----------------------------------------------------------------------------
      7 
      8 #----------------------------------------------------------------------------
      9 # Helper functions
     10 #----------------------------------------------------------------------------
     11 
     12 # Returns the revision number of the source files with date $1.
     13 get_svn_revision() {
     14   (cd $DIR; rm -rf infodir;
     15    svn co -r "{$1}" "${valgrind_svn_repo}/nightly" infodir > /dev/null;
     16    revno=`svn info infodir | sed -n 's/^Revision: //p'`;
     17    rm -rf infodir;
     18    echo $revno)
     19 }
     20 
     21 runcmd () {
     22    logfile=$1
     23    str=$2
     24    shift 2
     25 
     26    # Header in short logfile.
     27    # We use "printf" to avoid printing a newline;  "echo -n" isn't POSIX and
     28    # so isn't supported on all systems.
     29    printf "   $str  ... " >> $logfile.short
     30 
     31    # Header and command in verbose logfile
     32    printf "   $str  ... " >> $logfile.verbose
     33    echo "$*" >> $logfile.verbose
     34 
     35    # Run the command
     36    ("${ABT_EVAL}" "$*") >> $logfile.verbose 2>&1
     37    res=$?
     38 
     39    # Write result to the short logfile
     40    if [ $res = 0 ]
     41    then
     42       echo "done"   >> $logfile.short
     43    else
     44       echo "failed" >> $logfile.short
     45    fi
     46 
     47    return $res
     48 }
     49 
     50 #----------------------------------------------------------------------------
     51 # Startup
     52 #----------------------------------------------------------------------------
     53 
     54 valgrind_svn_repo="svn://svn.valgrind.org/valgrind/trunk"
     55 
     56 # Must have exactly two arguments
     57 if [ $# -ne 2 ] ; then
     58     echo "usage: $0 /path/to/valgrind/nightly <tag>"
     59     exit 1
     60 fi
     61 
     62 # Get args from command line
     63 DIR=$1
     64 TAG=$2
     65 
     66 # Get times and date
     67 START=`date "+%F %H:%M:%S %Z"`
     68 
     69 # This is one of the formats SVN accepts.  Yes, the 'T' appears in the final
     70 # string, it's supposed to be like that.
     71 svn_date_format="+%Y-%m-%dT%H:%M:%S"
     72 
     73 # The time-and-date from 24 hours ago is tricky;  Linux and Darwin have
     74 # different ways of getting it, so we try things until something works.
     75 svn_old_date=
     76 if [ "z" = "z${svn_old_date}" ] ; then
     77     # Linux method.
     78     svn_old_date=`date --date=yesterday $svn_date_format 2> /dev/null`
     79 fi
     80 if [ "z" = "z${svn_old_date}" ] ; then
     81     # Darwin method.
     82     svn_old_date=`date -v-24H $svn_date_format 2> /dev/null`
     83 fi
     84 if [ "z" = "z${svn_old_date}" ] ; then
     85     echo "Sorry, can't work out the time and date for 24 hours ago, aborting"
     86     exit 1;
     87 fi
     88 
     89 # The time-and-date for now is easy.
     90 svn_new_date=`date $svn_date_format`
     91 
     92 cd $DIR
     93 
     94 # Clean up output files produced by a previous run.
     95 rm -rf diffs diffs.txt diff.short final new.short new.verbose old.short old.verbose
     96 rm -rf sendmail.log unchanged.log valgrind-old valgrind-new
     97 
     98 # Setup any relevant environment variables from conf/<tag>.conf.
     99 . conf/$TAG.conf
    100 if [ "${ABT_JOBS}" = "" ]; then
    101   ABT_JOBS=1
    102 fi
    103 if [ "${ABT_EVAL}" = "" ]; then
    104   ABT_EVAL="eval"
    105 fi
    106 if [ "${ABT_RUN_REGTEST}" = "" ]; then
    107   ABT_RUN_REGTEST="make regtest"
    108 fi
    109 
    110 
    111 #----------------------------------------------------------------------------
    112 # Check out, build, test
    113 #----------------------------------------------------------------------------
    114 
    115 svn_old_rev="`get_svn_revision ${svn_old_date}`"
    116 svn_new_rev="`get_svn_revision ${svn_new_date}`"
    117 if [ "${svn_old_rev}" = "${svn_new_rev}" ]; then
    118   echo "Both {$svn_old_date} and {$svn_new_date} correspond to r${svn_new_rev}"\
    119        "-- skipping nightly build." >unchanged.log
    120   exit 0
    121 fi
    122 
    123 # Do everything twice -- once for the 24 hours old Valgrind, and once 
    124 # for the current one.
    125 for logfile in old new ; do
    126 
    127    # Remove old short and verbose log files, and start the new ones
    128    for ext in short verbose ; do
    129       echo > $logfile.$ext
    130    done
    131 
    132    # Choose the current Valgrind, or one from 24 hours ago
    133    if [ $logfile = "old" ] ; then
    134       svn_date=$svn_old_date
    135    else
    136       svn_date=$svn_new_date
    137    fi
    138 
    139    # Get dates for the old and new versions
    140 
    141    # Check out, build, run tests
    142    runcmd $logfile \
    143           "Checking out valgrind source tree" \
    144           "svn co ${valgrind_svn_repo} -r {$svn_date} valgrind-$logfile" && \
    145    \
    146    runcmd $logfile \
    147           "Configuring valgrind             " \
    148           "cd valgrind-$logfile && ./autogen.sh  && ./configure --prefix=`pwd`/valgrind-$logfile/Inst ${ABT_CONFIGURE_OPTIONS}" && \
    149    \
    150    runcmd $logfile \
    151           "Building valgrind                " \
    152           "cd valgrind-$logfile && make -j ${ABT_JOBS} && make -j ${ABT_JOBS} check && make install" && \
    153    \
    154    runcmd $logfile \
    155           "Running regression tests         " \
    156           "cd valgrind-$logfile && ${ABT_RUN_REGTEST}"
    157 
    158    # Grab some indicative text for the short log file -- if the regtests
    159    # succeeded, show their results.  If we didn't make it that far, show the
    160    # last 20 lines.
    161    egrep -q '^== [0-9]+ tests' $logfile.verbose && (
    162       echo >> $logfile.short
    163       echo "Regression test results follow" >> $logfile.short
    164       echo >> $logfile.short
    165       awk '/^== [0-9]+ tests/, /^$/ { print }' $logfile.verbose >> $logfile.short
    166    ) || (
    167       echo >> $logfile.short
    168       echo "Last 20 lines of verbose log follow" >> $logfile.short \
    169       echo >> $logfile.short
    170       tail -20 $logfile.verbose >> $logfile.short
    171    )
    172 done
    173 
    174 #----------------------------------------------------------------------------
    175 # Prepare results and send
    176 #----------------------------------------------------------------------------
    177 
    178 # Get times and date
    179 END=`date "+%F %H:%M:%S %Z"`
    180 
    181 # Gather some information about this run and its environment
    182 valgrind_revision="`svn info valgrind-new | grep Revision | sed 's/Revision[ ]*:[ ]*//'`"
    183 vex_revision="`svn info valgrind-new/VEX | grep Revision | sed 's/Revision[ ]*:[ ]*//'`"
    184 gcc_version="`gcc --version | head -1`"
    185 libc_so="`ls -1 /lib/libc.so.* | tail -1`"
    186 libc="unknown"
    187 if [ "x$libc_so" != "x" ]; then
    188   if [ -e "$libc_so" -a -r "$libc_so" ]; then
    189     libc="`/lib/libc.so.* | head -1`"
    190   fi
    191 fi
    192 uname_stuff="`uname -mrs`"
    193 if [ -e "/etc/issue.net" -a -r "/etc/issue.net" ]; then
    194   vendor_stuff="`cat /etc/issue.net | head -1`"
    195 else
    196   vendor_stuff="unknown"
    197 fi
    198 
    199 echo "valgrind revision: $valgrind_revision" >  final
    200 echo "VEX revision:      $vex_revision"      >> final
    201 echo "GCC version:       $gcc_version"       >> final
    202 echo "C library:         $libc"              >> final
    203 echo "uname -mrs:        $uname_stuff"       >> final
    204 echo "Vendor version:    $vendor_stuff"      >> final
    205 
    206 # 'final' shows the difference between the old and new results
    207 echo                                              >> final
    208 echo "Nightly build on" $TAG "(" $ABT_DETAILS ")" >> final
    209 echo "Started at" $START                          >> final
    210 echo "Ended   at" $END                            >> final
    211 
    212 # If the results differ from 24 hours ago, print extra stuff.
    213 diff -C1 old.short new.short > diff.short
    214 changed=$?
    215 
    216 if [ $changed != 0 ] ; then
    217    echo "Results differ from 24 hours ago"      >> final
    218    changed_str=""
    219 else
    220    echo "Results unchanged from 24 hours ago"   >> final
    221    changed_str="(unchanged) "
    222 fi
    223 
    224 # Always show the current results.
    225 cat new.short >> final
    226 
    227 if [ $changed != 0 ] ; then
    228    echo "=================================================" >> final
    229    echo "== Results from 24 hours ago                   ==" >> final
    230    echo "=================================================" >> final
    231    cat old.short                                            >> final
    232 
    233    echo                                                     >> final
    234    echo "=================================================" >> final
    235    echo "== Difference between 24 hours ago and now     ==" >> final
    236    echo "=================================================" >> final
    237    echo                                                     >> final
    238    cat diff.short                                           >> final
    239    echo                                                     >> final
    240 fi
    241 
    242 # Gather up the diffs (at most the first 100 lines for each one) into a
    243 # single file.
    244 MAX_LINES=100
    245 diff_files=`find . -name '*.diff*' | sort`
    246 if [ z"$diff_files" = z ] ; then
    247    echo "Congratulations, all tests passed!" >> diffs
    248 else
    249    for i in $diff_files ; do
    250       echo "=================================================" >> diffs
    251       echo $i                                                  >> diffs 
    252       echo "=================================================" >> diffs
    253       if [ `wc -l < $i` -le $MAX_LINES ] ; then
    254          cat $i                                                >> diffs
    255       else
    256          head -n $MAX_LINES $i                                 >> diffs
    257          echo "<truncated beyond $MAX_LINES lines>"            >> diffs
    258       fi
    259    done
    260 fi
    261 
    262 # Rename diffs into diffs.txt such that it can be viewed easily with an
    263 # e-mail client.
    264 mv diffs diffs.txt
    265 
    266 # Use the conf/<tag>.sendmail script to email the results.
    267 conf/$TAG.sendmail \
    268    "$changed_str$START nightly build ($TAG, $ABT_DETAILS)" \
    269    final \
    270    diffs.txt > sendmail.log 2>&1
    271