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. 15get_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 29runcmd () { 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 62valgrind_svn_repo="svn://svn.valgrind.org/valgrind/trunk" 63vex_svn_repo="svn://svn.valgrind.org/vex/trunk" 64 65# Must have exactly two arguments 66if [ $# -ne 2 ] ; then 67 echo "usage: $0 /path/to/valgrind/nightly <tag>" 68 exit 1 69fi 70 71# Get args from command line 72DIR=$1 73TAG=$2 74 75# Get times and date 76START=`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. 80svn_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. 84svn_old_date= 85if [ "z" = "z${svn_old_date}" ] ; then 86 # Linux method. 87 svn_old_date=`date --date=yesterday $svn_date_format 2> /dev/null` 88fi 89if [ "z" = "z${svn_old_date}" ] ; then 90 # Darwin method. 91 svn_old_date=`date -v-24H $svn_date_format 2> /dev/null` 92fi 93if [ "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; 96fi 97 98# The time-and-date for now is easy. 99svn_new_date=`date $svn_date_format` 100 101cd $DIR 102 103# Clean up output files produced by a previous run. 104rm -rf diffs diffs.txt diff.short final new.short new.verbose old.short old.verbose 105rm -rf sendmail.log unchanged.log valgrind-old valgrind-new 106 107# Setup any relevant environment variables from conf/<tag>.conf. 108. conf/$TAG.conf 109if [ "${ABT_JOBS}" = "" ]; then 110 ABT_JOBS=1 111fi 112if [ "${ABT_EVAL}" = "" ]; then 113 ABT_EVAL="eval" 114fi 115if [ "${ABT_RUN_REGTEST}" = "" ]; then 116 ABT_RUN_REGTEST="make regtest" 117fi 118 119if [ "${ABT_PERF_TOOLS}" = "" ]; then 120 ABT_PERF_TOOLS="--tools=none,memcheck,callgrind,helgrind,cachegrind,drd,massif" 121fi 122if [ "${ABT_PERF_REPS}" = "" ]; then 123 ABT_PERF_REPS="--reps=3" 124fi 125 126 127#---------------------------------------------------------------------------- 128# Check out, build, test 129#---------------------------------------------------------------------------- 130 131vg_old_rev="`get_svn_revision ${svn_old_date} ${valgrind_svn_repo}`" 132vg_new_rev="`get_svn_revision ${svn_new_date} ${valgrind_svn_repo}`" 133vex_old_rev="`get_svn_revision ${svn_old_date} ${vex_svn_repo}`" 134vex_new_rev="`get_svn_revision ${svn_new_date} ${vex_svn_repo}`" 135if [ "${vg_old_rev}" = "${vg_new_rev}" -a "${vex_old_rev}" = "${vex_new_rev}" ] 136then 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 140fi 141 142# Do everything twice -- once for the 24 hours old Valgrind, and once 143# for the current one. 144for 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 ) 192done 193 194# if requested, run regression tests and produce results in perflogfile.out 195if [ "${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 .. 200fi 201 202 203#---------------------------------------------------------------------------- 204# Prepare results and send 205#---------------------------------------------------------------------------- 206 207# Get times and date 208END=`date "+%F %H:%M:%S %Z"` 209 210# Gather some information about this run and its environment 211valgrind_revision="`svn info valgrind-new | grep Revision | sed 's/Revision[ ]*:[ ]*//'`" 212vex_revision="`svn info valgrind-new/VEX | grep Revision | sed 's/Revision[ ]*:[ ]*//'`" 213gcc_version="`gcc --version 2> /dev/null | head -1`" 214gdb_version="`gdb --version 2> /dev/null | head -1`" 215as_version="`as --version 2> /dev/null | head -1`" 216libc_so="`ls -1 /lib/libc.so.* | tail -1`" 217libc="unknown" 218if [ "x$libc_so" != "x" ]; then 219 if [ -e "$libc_so" -a -r "$libc_so" ]; then 220 libc="`/lib/libc.so.* | head -1`" 221 fi 222fi 223libc=`echo $libc | sed "s/, by Roland.*//"` 224uname_stuff="`uname -mrs`" 225if [ -e "/etc/issue.net" -a -r "/etc/issue.net" ]; then 226 vendor_stuff="`cat /etc/issue.net | head -1`" 227else 228 vendor_stuff="unknown" 229fi 230 231echo "valgrind revision: $valgrind_revision" > final 232echo "VEX revision: $vex_revision" >> final 233echo "C compiler: $gcc_version" >> final 234echo "GDB: $gdb_version" >> final 235echo "Assembler: $as_version" >> final 236echo "C library: $libc" >> final 237echo "uname -mrs: $uname_stuff" >> final 238echo "Vendor version: $vendor_stuff" >> final 239 240# 'final' shows the difference between the old and new results 241echo >> final 242echo "Nightly build on" $TAG "(" $ABT_DETAILS ")" >> final 243echo "Started at" $START >> final 244echo "Ended at" $END >> final 245 246# If the results differ from 24 hours ago, print extra stuff. 247diff -C1 old.short new.short > diff.short 248changed=$? 249 250if [ $changed != 0 ] ; then 251 echo "Results differ from 24 hours ago" >> final 252 changed_str="" 253else 254 echo "Results unchanged from 24 hours ago" >> final 255 changed_str="(unchanged) " 256fi 257 258# Always show the current results. 259cat new.short >> final 260 261if [ $changed != 0 ] ; then 262 echo "=================================================" >> final 263 echo "== Results from 24 hours ago ==" >> final 264 echo "=================================================" >> final 265 cat old.short >> final 266 267 echo >> final 268 echo "=================================================" >> final 269 echo "== Difference between 24 hours ago and now ==" >> final 270 echo "=================================================" >> final 271 echo >> final 272 cat diff.short >> final 273 echo >> final 274fi 275 276# add perf results if requested 277if [ "${ABT_PERF}" != "" ]; then 278 cat perflogfile >> final 279fi 280 281# Gather up the diffs (at most the first 100 lines for each one) into a 282# single file. 283MAX_LINES=100 284diff_files=`find . -name '*.diff*' | sort` 285if [ z"$diff_files" = z ] ; then 286 echo "Congratulations, all tests passed!" >> diffs 287else 288 for i in $diff_files ; do 289 echo "=================================================" >> diffs 290 echo $i >> diffs 291 echo "=================================================" >> diffs 292 if [ `wc -l < $i` -le $MAX_LINES ] ; then 293 cat $i >> diffs 294 else 295 head -n $MAX_LINES $i >> diffs 296 echo "<truncated beyond $MAX_LINES lines>" >> diffs 297 fi 298 done 299fi 300 301# Rename diffs into diffs.txt such that it can be viewed easily with an 302# e-mail client. 303mv diffs diffs.txt 304 305# Use the conf/<tag>.sendmail script to email the results. 306conf/$TAG.sendmail \ 307 "$changed_str$START nightly build ($TAG, $ABT_DETAILS)" \ 308 final \ 309 diffs.txt > sendmail.log 2>&1 310