#!/bin/sh #---------------------------------------------------------------------------- # Automated build and test for Valgrind. Compares Valgrind from 24 hours # ago with the current one. See the README.txt on how to run it. #---------------------------------------------------------------------------- #---------------------------------------------------------------------------- # Helper functions #---------------------------------------------------------------------------- # Returns the revision number of the source files with date $1. get_svn_revision() { svn info -r "{$1}" "${valgrind_svn_repo}" | sed -n 's/^Revision: //p' } runcmd () { logfile=$1 str=$2 shift 2 # Header in short logfile. # We use "printf" to avoid printing a newline; "echo -n" isn't POSIX and # so isn't supported on all systems. printf " $str ... " >> $logfile.short # Header and command in verbose logfile printf " $str ... " >> $logfile.verbose echo "$*" >> $logfile.verbose # Run the command ("${ABT_EVAL}" "$*") >> $logfile.verbose 2>&1 res=$? # Write result to the short logfile if [ $res = 0 ] then echo "done" >> $logfile.short else echo "failed" >> $logfile.short fi return $res } #---------------------------------------------------------------------------- # Startup #---------------------------------------------------------------------------- valgrind_svn_repo="svn://svn.valgrind.org/valgrind/trunk" # Must have exactly two arguments if [ $# -ne 2 ] ; then echo "usage: $0 /path/to/valgrind/nightly " exit 1 fi # Get args from command line DIR=$1 TAG=$2 # Get times and date START=`date "+%F %H:%M:%S %Z"` # This is one of the formats SVN accepts. Yes, the 'T' appears in the final # string, it's supposed to be like that. svn_date_format="+%Y-%m-%dT%H:%M:%S" # The time-and-date from 24 hours ago is tricky; Linux and Darwin have # different ways of getting it, so we try things until something works. svn_old_date= if [ "z" = "z${svn_old_date}" ] ; then # Linux method. svn_old_date=`date --date=yesterday $svn_date_format 2> /dev/null` fi if [ "z" = "z${svn_old_date}" ] ; then # Darwin method. svn_old_date=`date -v-24H $svn_date_format 2> /dev/null` fi if [ "z" = "z${svn_old_date}" ] ; then echo "Sorry, can't work out the time and date for 24 hours ago, aborting" exit 1; fi # The time-and-date for now is easy. svn_new_date=`date $svn_date_format` cd $DIR # Clean up output files produced by a previous run. rm -rf diffs diff.short final new.short new.verbose old.short old.verbose rm -rf sendmail.log unchanged.log valgrind-old valgrind-new # Setup any relevant environment variables from conf/.conf. . conf/$TAG.conf if [ "${ABT_JOBS}" = "" ]; then ABT_JOBS=1 fi if [ "${ABT_EVAL}" = "" ]; then ABT_EVAL="eval" fi if [ "${ABT_RUN_REGTEST}" = "" ]; then ABT_RUN_REGTEST="make regtest" fi #---------------------------------------------------------------------------- # Check out, build, test #---------------------------------------------------------------------------- svn_old_rev="`get_svn_revision ${svn_old_date}`" svn_new_rev="`get_svn_revision ${svn_new_date}`" if [ "${svn_old_rev}" = "${svn_new_rev}" ]; then echo "Both {$svn_old_date} and {$svn_new_date} correspond to r${svn_new_rev}"\ "-- skipping nightly build." >unchanged.log exit 0 fi # Do everything twice -- once for the 24 hours old Valgrind, and once # for the current one. for logfile in old new ; do # Remove old short and verbose log files, and start the new ones for ext in short verbose ; do echo > $logfile.$ext done # Choose the current Valgrind, or one from 24 hours ago if [ $logfile = "old" ] ; then svn_date=$svn_old_date else svn_date=$svn_new_date fi # Get dates for the old and new versions # Check out, build, run tests runcmd $logfile \ "Checking out valgrind source tree" \ "svn co ${valgrind_svn_repo} -r {$svn_date} valgrind-$logfile" && \ \ runcmd $logfile \ "Configuring valgrind " \ "cd valgrind-$logfile && ./autogen.sh && ./configure --prefix=`pwd`/valgrind-$logfile/Inst ${ABT_CONFIGURE_OPTIONS}" && \ \ runcmd $logfile \ "Building valgrind " \ "cd valgrind-$logfile && make -j ${ABT_JOBS} && make -j ${ABT_JOBS} check && make install" && \ \ runcmd $logfile \ "Running regression tests " \ "cd valgrind-$logfile && ${ABT_RUN_REGTEST}" # Grab some indicative text for the short log file -- if the regtests # succeeded, show their results. If we didn't make it that far, show the # last 20 lines. egrep -q '^== [0-9]+ tests' $logfile.verbose && ( echo >> $logfile.short echo "Regression test results follow" >> $logfile.short echo >> $logfile.short awk '/^== [0-9]+ tests/, /^$/ { print }' $logfile.verbose >> $logfile.short ) || ( echo >> $logfile.short echo "Last 20 lines of verbose log follow" >> $logfile.short \ echo >> $logfile.short tail -20 $logfile.verbose >> $logfile.short ) done #---------------------------------------------------------------------------- # Prepare results and send #---------------------------------------------------------------------------- # Get times and date END=`date "+%F %H:%M:%S %Z"` # 'final' shows the difference between the old and new results echo > final echo "Nightly build on" $TAG "(" $ABT_DETAILS ")" >> final echo "Started at" $START >> final echo "Ended at" $END >> final # If the results differ from 24 hours ago, print extra stuff. diff -C1 old.short new.short > diff.short changed=$? if [ $changed != 0 ] ; then echo "Results differ from 24 hours ago" >> final changed_str="" else echo "Results unchanged from 24 hours ago" >> final changed_str="(unchanged) " fi # Always show the current results. cat new.short >> final if [ $changed != 0 ] ; then echo "=================================================" >> final echo "== Results from 24 hours ago ==" >> final echo "=================================================" >> final cat old.short >> final echo >> final echo "=================================================" >> final echo "== Difference between 24 hours ago and now ==" >> final echo "=================================================" >> final echo >> final cat diff.short >> final echo >> final fi # Gather up the diffs (at most the first 100 lines for each one) into a # single file. MAX_LINES=100 diff_files=`find . -name '*.diff*' | sort` if [ z"$diff_files" = z ] ; then echo "Congratulations, all tests passed!" >> diffs else for i in $diff_files ; do echo "=================================================" >> diffs echo $i >> diffs echo "=================================================" >> diffs if [ `wc -l < $i` -le $MAX_LINES ] ; then cat $i >> diffs else head -n $MAX_LINES $i >> diffs echo "" >> diffs fi done fi # Use the conf/.sendmail script to email the results. conf/$TAG.sendmail \ "$changed_str$START nightly build ($TAG, $ABT_DETAILS)" \ final \ diffs > sendmail.log 2>&1