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