1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350
|
#!/usr/bin/tclsh
# Copyright (C) 2001-2023 Artifex Software, Inc.
# All Rights Reserved.
#
# This software is provided AS-IS with no warranty, either express or
# implied.
#
# This software is distributed under license and may not be copied,
# modified or distributed except as expressly authorized under the terms
# of the license contained in the file LICENSE in this distribution.
#
# Refer to licensing information at http://www.artifex.com or contact
# Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
# CA 94129, USA, for further information.
#
# Run some or all of a Genoa test suite, optionally checking for memory leaks.
# Command line syntax:
set HELP {Usage:
suite (--[no-]band | --[no-]check | --[no-]debug |
--[no-]display[=<device>] | --[no-]missing | --[no-]pause |
--[no-]print[=<device>] | --[no-]profile | --[no-]remote[=<host>] |
--[no-]sort | --[no-]together | -<switch> |
<dirname>[,<filename>] | <filename>)*
}
# Note: test failure is typically indicated by one or more of the following:
# exit status
# Error:
# fail/FAIL
# wrong:
# *not* Final time
set SW(band) 1 ;# use banding
set SW(check) 0 ;# check for memory leaks
set SW(debug) 0 ;# don't actually execute the test
set SW(display) 0 ;# use display instead of printer
;# (or device if value != 1)
set SW(missing) 0 ;# only run if log file is missing
set SW(pause) 0 ;# pause after each page
set SW(print) 0 ;# don't discard output, print for LJ4
;# (or device if value != 1)
set SW(profile) 0 ;# assume -pg executable, profile execution
set SW(remote) 0 ;# run on remote host
set SW(sort) 1 ;# do in order of increasing file size
set SW(together) 0 ;# run all files together, not individually
#----------------------------------------------------------------
# In addition to the switches, the following globals are used:
# HOSTNAME = the current host name
# REMOTED(remotename) = 1 if the given file has been copied to
# the given host
proc test_args {band display pause print xe switches output} {
set args [list -K40000 -Z@:? -dBATCH]
if {!$pause} {
lappend args -dNOPAUSE
}
if {$display != "0"} {
# Use the default device, or a given device.
if {$display != "1"} {
lappend args -sDEVICE=$display -sOutputFile=/dev/null
}
} elseif {$print == "0"} {
lappend args -r600 -sDEVICE=pbmraw -sOutputFile=/dev/null
} else {
if {$print == "1"} {set print ljet4}
lappend args -r600 -sDEVICE=$print -sOutputFile=${output}.%03d.$print
}
if $band {
lappend args -dMaxBitmap=200000 -dBufferSpace=200000
} else {
lappend args -dMaxBitmap=20000000 -dBufferSpace=20000000
}
set args [concat $args $switches]
if {$xe == "gs"} {
set args [concat $args {-c false 0 startjob pop -f}]
}
return $args
}
proc file_type {file} {
if {[regexp {\.[a-zA-Z0-9]*(ps|PS)[a-zA-Z0-9]*$} $file]} {return ps}
# Look for PJL in the first part of the file.
set in [open $file]
set first [read $in 2000]
close $in
if {[regexp {@PJL[ ]+ENTER[ ]+LANGUAGE[ ]*=[ ]*PCLXL} $first]} {return pclxl}
if {[regexp {@PJL[ ]+ENTER[ ]+LANGUAGE[ ]*=[ ]*PCL} $first]} {return pcl5}
if {[regexp "\033E" $first]} {return pcl5}
# Unknown, assume PS.
return ps
}
proc test_xe {file} {
global SW
switch [file_type $file] {
ps {set cmd gs}
pcl5 {set cmd pcl5}
pclxl {set cmd pclxl}
}
if {$SW(profile)} {
set cmd pgobj/$cmd
} elseif {[file exists bin/$cmd]} {
set cmd bin/$cmd
} elseif {[file exists obj/$cmd]} {
set cmd obj/$cmd
}
return $cmd
}
proc catch_exec {command} {
global SW
puts $command; flush stdout
if {!$SW(debug) && [catch [concat exec $command] msg]} {
puts "*** Non-zero exit code from command:"
puts $command
puts $msg
}
}
proc show_exec {command} {
global SW
puts $command; flush stdout
if {!$SW(debug)} {eval exec $command}
}
proc output_name {fl} {
if {[llength $fl] == 1} {
set output [lindex $fl 0]
} else {
set output "[lindex $fl 0]-[lindex $fl end]"
}
regsub -all / $output - output
# Don't allow the output file name to start with -.
regsub {^[-]+} $output {} output
return $output
}
proc remote_name {file host} {
global HOSTNAME
set local $file
if {![regexp {^/} $local]} {
set local [pwd]/$local
}
while {![catch {set link [file readlink $local]}]} {
set dir [file dirname $local]
switch $dir {
. {set local $link}
/ {set local /$link}
default {set local $dir/$link}
}
}
regsub "^(/home/$HOSTNAME/|/$HOSTNAME/home/)" $local {} local
if {[regexp {^/} $local]} {
return $local
}
return /home/$host/$local
}
proc copy_to_remote {file host {cached 1}} {
global REMOTED
set remote [remote_name $file $host]
set cmd [list rsync -tz -e ssh $file $host:[file dirname $remote]]
if {!$cached} {
show_exec $cmd
} elseif {![info exists REMOTED($remote)]} {
show_exec $cmd
set REMOTED($remote) 1
}
}
proc copy_from_remote {file host} {
set remote [remote_name $file $host]
show_exec [list rsync -tz -e ssh $host:$remote [file dirname $file]]
}
proc suite {filelist switches} {
global SW
set files [list]
if $SW(together) {
set left $filelist
set max_files 100
set max_files1 [expr $max_files - 1]
while {[llength $left] > $max_files} {
lappend files [lrange $left 0 $max_files1]
set left [lreplace $left 0 $max_files1]
}
if {$left != {}} {
lappend files $left
}
} else {
foreach f $filelist {lappend files [list $f]}
}
foreach fl $files {
set test_xe [test_xe [lindex $fl 0]]
set output [output_name $fl]
set test_args [test_args $SW(band) $SW(display) $SW(pause) $SW(print) $test_xe $switches $output]
if $SW(pause) {
set in1 [list]
set in0 [list]
} else {
set in1 [list -_ <]
set in0 [list -_]
}
if {![regexp {gs$} $test_xe]} {
set pre [list]
set post $fl
set lib [glob lib/*.ps]
} elseif {[llength $fl] == 1} {
set pre [list]
set post [concat $in1 [list [lindex $fl 0]]]
set lib [list]
} else {
set pre [concat cat $fl |]
set post $in0
set lib [list]
}
if $SW(check) {
puts $fl
flush stdout
set command [concat $pre $test_xe -ZA $test_args $post > t]
catch_exec $command
exec leaks < t > ${output}.leak
} else {
set log ${output}.log
set main [concat $pre time $test_xe $test_args $post]
set command [concat $main | tee -a $log >@ stdout 2>@ stderr]
if {$SW(missing) && [file exists $log]} {
# Do nothing.
} elseif {$SW(profile)} {
if {$SW(remote) != "0"} {
global HOSTNAME
set remdir [pwd]
regsub "^(/home/$HOSTNAME/|/$HOSTNAME/home/)" $remdir /home/$SW(remote)/ remdir
set command "cd $remdir; export GS_LIB=./lib:./fonts; $main >> $log"
exec echo $command > $log
copy_to_remote $test_xe $SW(remote)
foreach lf $lib {copy_to_remote $lf $SW(remote)}
copy_to_remote $log $SW(remote) 0
catch_exec [list ssh $SW(remote) $command >@ stdout 2>@ stderr]
copy_from_remote gmon.out $SW(remote)
copy_from_remote $log $SW(remote)
} else {
exec echo $command > $log
catch_exec $command
}
show_exec [list gprof $test_xe > ${output}.out]
} else {
exec echo $command > $log
catch_exec $command
}
}
}
}
# Define the suites, sorted by increasing file size.
# We compute the sorted lists lazily.
proc compare_file_size {file1 file2} {
expr [file size $file1] - [file size $file2]
}
proc get_suite {dir {sort 1}} {
global list
set files [glob -nocomplain $dir/*.bin]
if {$files == {}} {
set files [glob -nocomplain $dir/*.ps]
}
if !$sort {
return [lsort $files]
}
if [info exists list($dir)] {
return $list($dir)
}
set files [lsort -command compare_file_size $files]
if {[lindex $files 0] == "0release.bin"} {
set files [lrange $files 1 end]
}
return [set list($dir) $files]
}
# Run the program.
if {$argv == [list --help] || ($argv == "" && [regexp {suite$} $argv0])} {
global HELP
puts -nonewline stderr $HELP
puts -nonewline stderr Defaults:
foreach var [lsort [array names SW]] {
if {$SW($var) != 0} {
puts -nonewline stderr " --$var"
}
}
puts stderr ""
exit
}
regexp {^([^.]+)(\.|$)} [exec hostname] skip HOSTNAME
catch {unset REMOTED}
set switches ""
set files ""
puts "-- [exec date]"
puts "-- $argv0 $argv"
foreach file $argv {
if [regexp {^-} $file] {
if {$files != ""} {suite $files $switches; set files ""}
if {[regexp {^--no-(.*)$} $file all var]} {
if [info exists SW($var)] {
set SW($var) 0
} else {
puts "Unknown switch $file"
exit 1
}
} elseif {[regexp {^--(.*)$} $file all var]} {
if [info exists SW($var)] {
set SW($var) 1
} elseif {[regexp {^(display|print|remote)=(.*)$} $var all var value]} {
set SW($var) $value
} else {
puts "Unknown switch $file"
exit 1
}
} else {
lappend switches $file
}
} elseif {[file isdir $file]} {
if {$files != ""} {suite $files $switches; set files ""}
suite [get_suite $file $SW(sort)] $switches
} elseif {[regexp {(.*),(.*)$} $file all suite from] && [file isdir $suite]} {
if {$files != ""} {suite $files $switches; set files ""}
set sfiles [get_suite $suite $SW(sort)]
set first [lsearch $sfiles $suite/$from]
if {$first < 0} {
puts "No such file: $suite/$from"
} else {
suite [lreplace $sfiles 0 [expr $first - 1]] $switches
}
} else {
lappend files $file
}
}
if {$files != ""} {suite $files $switches; set files ""}
|