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