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