1#!/bin/ksh 2# 3# Graphviz regression test driver 4# 5# Also relies on strps.awk. 6# 7# TODO: 8# Report differences with shared version and with new output. 9 10# bsh, linux-ksh filter 11bar=1;echo foo | read bar<<- \! 122 13! 14if ((bar==1)) 15then 16 echo "Graphviz test suite requires ksh93" 17 exit 1 18fi 19# csh, ksh88 filter 20#(( 1.5 == 1 )) && { echo "Graphviz test suite requires ksh93"; exit 1; } 21 22TESTFILE=tests.txt # Test specifications 23GRAPHDIR=graphs # Directory of input graphs and data 24OUTDIR=ndata # Directory for test output 25OUTHTML=nhtml # Directory for html test report 26REFDIR=${REFDIR-""} # Directory for expected test output 27GENERATE= # If set, generate test data 28VERBOSE= # If set, give verbose output 29NOOP= # If set, just print list of tests 30DOT=${DOT-$(whence dot)} # should be $(top_builddir)/cmd/dot/dot_static 31DIFFIMG=${DIFFIMG-$(whence diffimg)} 32 33TESTNAME= # name of test 34GRAPH= # graph specification 35IDX= 36typeset -i i j SUBTESTCNT 37typeset -i CRASH_CNT=0 DIFF_CNT=0 TOT_CNT=0 38typeset -i LINECNT=0 39typeset -A TESTTYPES 40typeset -a ALG 41typeset -a FMT 42typeset -a FLAGS 43TMPINFILE=tmp$$.gv 44TMPFILE1=tmpnew$$ 45TMPFILE2=tmpref$$ 46 47# Read single line, storing it in LINE and update count. 48# Return 0 on success. 49function readLine 50{ 51 if read -u 3 LINE 52 then 53 (( LINECNT+=1 )) 54 return 0 55 else 56 return 1 57 fi 58} 59 60# Skip blank lines and comments (lines starting with #) 61# Use first real line as the test name 62function skipLines 63{ 64 while readLine 65 do 66 if [[ -n $LINE && ${LINE:0:1} != \# ]] 67 then 68 return 0 69 fi 70 done 71 return 1 72} 73 74# Subtests have the form: layout format optional_flags 75# Store the 3 parts in the arrays ALG, FMT, FLAGS. 76# Stop at a blank line 77function readSubtests 78{ 79 (( SUBTESTCNT=0 )) 80 while readLine 81 do 82 if [[ -z "$LINE" ]] 83 then 84 return 85 fi 86 if [[ ${LINE:0:1} != \# ]] 87 then 88 echo $LINE | read ALG0 FMT0 FLAGS0 89 ALG[$SUBTESTCNT]=$ALG0 90 FMT[$SUBTESTCNT]=$FMT0 91 FLAGS[$SUBTESTCNT]=$FLAGS0 92 (( SUBTESTCNT+=1 )) 93 fi 94 done 95} 96 97function readTest 98{ 99 # read test name 100 if skipLines 101 then 102 TESTNAME=$LINE 103 else 104 return 1 105 fi 106 107 # read input graph 108 if skipLines 109 then 110 GRAPH=$LINE 111 else 112 return 1 113 fi 114 115 readSubtests 116 return 0 117} 118 119# newfile = $1 120# oldfile = $2 121# assume subscript indicates file type 122function strip { 123 case $1 in 124 *.ps ) 125 awk -f strps.awk $1 > $TFILE1 126 awk -f strps.awk $2 > $TFILE2 127 ;; 128 *.svg ) 129 sed '/^<!--/d' < $1 | sed '/-->$/d' > $TFILE1 130 sed '/^<!--/d' < $2 | sed '/-->$/d' > $TFILE2 131 ;; 132 * ) 133 cp $1 $TFILE1 134 cp $2 $TFILE2 135 ;; 136 esac 137 138} 139 140# Compare old and new output and report if different. 141# Args: testname index fmt 142function doDiff 143{ 144 FILE1=$OUTDIR/$OUTFILE 145 FILE2=$REFDIR/$OUTFILE 146 F=${3%%:*} 147 case $F in 148 ps | ps2 ) 149 awk -f strps.awk $FILE1 > $TMPFILE1 150 awk -f strps.awk $FILE2 > $TMPFILE2 151 diff -q $TMPFILE2 $TMPFILE1 > /dev/null 152 if [[ $? != 0 ]] 153 then 154 print -u 2 "Test $1:$2 : == Failed == $OUTFILE" 155 (( DIFF_CNT+=1 )) 156 else 157 if [[ -n "$VERBOSE" ]] 158 then 159 print -u 2 "Test $1:$2 : == OK == $OUTFILE" 160 fi 161 fi 162 ;; 163 svg ) 164 sed '/^<!--/d' < $FILE1 | sed '/-->$/d' > $TMPFILE1 165 sed '/^<!--/d' < $FILE2 | sed '/-->$/d' > $TMPFILE2 166 diff -q $TMPFILE2 $TMPFILE1 > /dev/null 167 if [[ $? != 0 ]] 168 then 169 print -u 2 "Test $1:$2 : == Failed == $OUTFILE" 170 (( DIFF_CNT+=1 )) 171 else 172 if [[ -n "$VERBOSE" ]] 173 then 174 print -u 2 "Test $1:$2 : == OK == $OUTFILE" 175 fi 176 fi 177 ;; 178 png ) 179 $DIFFIMG $FILE2 $FILE1 >$OUTHTML/dif_$OUTFILE 180 if [[ $? != 0 ]] 181 then 182 echo "<p>" >>$OUTHTML/index.html 183 cp $FILE2 $OUTHTML/old_$OUTFILE 184 echo "<img src=\"old_$OUTFILE\" width=\"192\" height=\"192\">" >>$OUTHTML/index.html 185 cp $FILE1 $OUTHTML/new_$OUTFILE 186 echo "<img src=\"new_$OUTFILE\" width=\"192\" height=\"192\">" >>$OUTHTML/index.html 187 echo "<img src=\"dif_$OUTFILE\" width=\"192\" height=\"192\">" >>$OUTHTML/index.html 188 print -u 2 "Test $1:$2 : == Failed == $OUTFILE" 189 (( DIFF_CNT+=1 )) 190 else 191 if [[ -n "$VERBOSE" ]] 192 then 193 print -u 2 "Test $1:$2 : == OK == $OUTFILE" 194 fi 195 rm $OUTHTML/dif_$OUTFILE 196 fi 197 ;; 198 * ) 199 diff -q $FILE2 $FILE1 > /dev/null 200 if [[ $? != 0 ]] 201 then 202 print -u 2 "Test $1:$2 : == Failed == $OUTFILE" 203 (( DIFF_CNT+=1 )) 204 else 205 if [[ -n "$VERBOSE" ]] 206 then 207 print -u 2 "Test $1:$2 : == OK == $OUTFILE" 208 fi 209 fi 210 ;; 211 esac 212} 213 214# Generate output file name given 3 parameters. 215# testname layout format 216# If format ends in :*, remove this, change the colons to underscores, 217# and append to basename 218# If the last two parameters have been used before, add numeric suffix. 219function genOutname 220{ 221 if [[ $3 == *:* ]] 222 then 223 F=${3%%:*} 224 XFMT=${3#$F} 225 XFMT=${XFMT/:/_} 226 else 227 F=$3 228 XFMT="" 229 fi 230 231 IDX="$2$XFMT$F" 232 j=${TESTTYPES[$IDX]} 233 if (( j == 0 )) 234 then 235 TESTTYPES[$IDX]=1 236 J="" 237 else 238 TESTTYPES[$IDX]=$(( j+1 )) 239 J=$j 240 fi 241 OUTFILE="$1_$2$XFMT$J.$F" 242} 243 244# clear out all entries of associated array 245function aunset #name 246{ 247 typeset i 248 nameref v=$1 249 for i in ${!v[@]} 250 do unset v[$i] 251 done 252} 253 254function doTest 255{ 256 if (( SUBTESTCNT == 0 )) 257 then 258 return 259 fi 260 case $GRAPH in 261 = ) 262 INFILE=$GRAPHDIR/$TESTNAME.gv 263 ;; 264 graph* | digraph* ) 265 INFILE=$TMPINFILE 266 echo "$GRAPH" > $INFILE 267 ;; 268 *.gv ) 269 INFILE=$GRAPHDIR/$GRAPH 270 ;; 271 * ) 272 echo "Unknown graph spec, test $TESTNAME - ignoring" 273 return 274 ;; 275 esac 276 277 for ((i=0;i<SUBTESTCNT;i++)) 278 do 279 (( TOT_CNT+=1 )) 280 genOutname $TESTNAME ${ALG[$i]} ${FMT[$i]} 281 OUTPATH=$OUTDIR/$OUTFILE 282 KFLAGS=${ALG[$i]} 283 TFLAGS=${FMT[$i]} 284 test -z "$KFLAGS" || KFLAGS="-K$KFLAGS" 285 test -z "$TFLAGS" || TFLAGS="-T$TFLAGS" 286 testcmd="$DOT $KFLAGS $TFLAGS ${FLAGS[$i]} -o$OUTPATH $INFILE" 287 if [[ -n "$VERBOSE" ]] 288 then 289 print $testcmd 290 fi 291 if [[ $NOOP == 1 ]] 292 then 293 continue 294 fi 295 296 $testcmd 2> errout 297 RVAL=$? 298 299 if [[ -s errout ]] 300 then 301 cat errout 302 fi 303 304 if [[ $RVAL != 0 || ! -s $OUTPATH ]] 305 then 306 (( CRASH_CNT+=1 )) 307 print -u 2 "Test $TESTNAME:$i : == Layout failed ==" 308 print -u 2 " $testcmd" 309 elif [[ $GENERATE == 1 ]] 310 then 311 continue 312 elif [[ -r $REFDIR/$OUTFILE ]] 313 then 314 doDiff $TESTNAME $i ${FMT[$i]} 315 else 316 print -u 2 "Test $TESTNAME:$i : == No file $REFDIR/$OUTFILE for comparison ==" 317 fi 318 done 319 320 # clear TESTTYPES 321 aunset TESTTYPES 322# for W in ${!TESTTYPES[@]} 323# do 324# TESTTYPES[$W]=0 325# done 326} 327 328trap 'rm -f $TMPFILE1 $TMPFILE2 $TMPINFILE errout; exit' 0 1 2 3 15 329 330Usage='rtest [-gvn] [TESTFILE]\n 331 -g : generate test data\n 332 -v : verbose\n 333 -n : print test' 334 335# Set REFDIR 336if [[ ! "$REFDIR" ]] 337then 338 SYSTYPE=$(uname -s) 339 case "$SYSTYPE" in 340 Linux*) 341 REFDIR=linux.x86 342 ;; 343 Darwin*) 344 REFDIR=macosx 345 ;; 346 *) 347 print "Unrecognized system \"$SYSTYPE\"" 348 REFDIR=nshare 349 ;; 350 esac 351fi 352 353while getopts :gnv c 354do 355 case $c in 356 n ) 357 VERBOSE=1 358 NOOP=1 359 ;; 360 v ) 361 VERBOSE=1 362 ;; 363 g ) 364 GENERATE=1 365 if [[ ! -d "$REFDIR" ]] 366 then 367 mkdir $REFDIR 368 fi 369 OUTDIR=$REFDIR 370 ;; 371 :) 372 echo $OPTARG requires a value 373 exit 2 374 ;; 375 \? ) 376 if [[ "$OPTARG" == '?' ]] 377 then 378 print $Usage 379 exit 0 380 else 381 echo "rtest: unknown flag $OPTARG - ignored" 382 fi 383 ;; 384 esac 385done 386shift $((OPTIND-1)) 387 388if [[ $# > 0 ]] 389then 390 if [[ -r $1 ]] 391 then 392 TESTFILE=$1 393 else 394 print -u 2 "Test file $1 does not exist" 395 exit 1 396 fi 397fi 398 399# Check environment and initialize 400 401if [[ $NOOP != 1 ]] 402then 403if [[ ! -d "$REFDIR" ]] 404then 405 print -u 2 "Test data directory $REFDIR does not exist" 406 exit 1 407fi 408 409if [[ ! -d "$OUTDIR" ]] 410then 411 mkdir $OUTDIR 412fi 413 414if [[ ! -d "$OUTHTML" ]] 415then 416 mkdir $OUTHTML 417fi 418rm -f $OUTHTML/* 419 420if [[ ! "$DOT" ]] 421then 422 print -u 2 "Could not find a value for DOT" 423 exit 424fi 425if [[ ! -x $DOT ]] 426then 427 print -u 2 "$DOT program is not executable" 428 exit 1 429fi 430 431if [[ $GENERATE != 1 && ! -x $DIFFIMG ]] 432then 433 print -u 2 "$DIFFIMG program is not executable" 434 exit 1 435fi 436fi 437 438 439exec 3< $TESTFILE 440while readTest 441do 442 doTest 443done 444if [[ $NOOP == 1 ]] 445then 446print -u 2 "No. tests: $TOT_CNT" 447elif [[ $GENERATE == 1 ]] 448then 449print -u 2 "No. tests: $TOT_CNT Layout failures: $CRASH_CNT" 450else 451print -u 2 "No. tests: $TOT_CNT Layout failures: $CRASH_CNT Changes: $DIFF_CNT" 452fi 453(( EXIT_STATUS=CRASH_CNT+DIFF_CNT )) 454exit $EXIT_STATUS 455