Posted to tcl by de at Wed Feb 27 21:37:41 GMT 2013view raw
- set options(-testapp) tcltest
- set options(-file) *.test
- set options(-notfile) ""
- set options(-tcltestdir) "../tests"
- set options(-testmain) "all.tcl"
- set options(-outfile) "singletests_out_[clock format [clock seconds] \
- -format "%Y-%m-%dT%T"].txt"
- set options(-overwriteoutfile) 0
- set options(-timeout) 10000
- set options(-progress) 100
- proc readArgs {} {
- global argv
- global options
- foreach {option arg} $argv {
- if {![info exists options($option)]} {
- puts stderr "Unknown option '$option'"
- exit 1
- }
- set options($option) $arg
- }
- }
- proc getTestFiles {} {
- global options
- set matchFileList [list]
- foreach pattern $options(-file) {
- set tmp [glob -nocomplain -tails \
- -directory $options(-tcltestdir) $pattern]
- set matchFileList [concat $matchFileList $tmp]
- }
- set matchFileList [lsort -unique $matchFileList]
- set skipFileList [list]
- foreach pattern $options(-notfile) {
- set tmp [glob -nocomplain -tails \
- -directory $options(-tcltestdir) $pattern]
- set skipFileList [concat $skipFileList $tmp]
- }
- set skipFileList [lsort -unique $skipFileList]
- set matchingFiles [list]
- foreach file $matchFileList {
- if {[lsearch -exact $skipFileList $file] == -1} {
- lappend matchingFiles $file
- }
- }
- if {[llength $matchingFiles] == 0} {
- puts stderr "No test files remain after applying match and\
- skip patterns!"
- exit 1
- }
- return $matchingFiles
- }
- proc getTestNames {file} {
- global options
- global gettestnamesCmd
- set cmd "$options(-testapp) $options(-tcltestdir)/$options(-testmain) \
- -verbose error -singleproc 1 "
- set namesCmd "$gettestnamesCmd $options(-tcltestdir) $file"
- set rawtestnameslist [eval exec $namesCmd]
- set testnameslist [lindex [split $rawtestnameslist \n] end]
- foreach test $testnameslist {
- if {[info exists tmp($test)]} {
- puts "File '$file': not unique test name '$test'"
- }
- incr tmp($test)
- }
- return $testnameslist
- }
- # From: http://wiki.tcl.tk/880
- proc isReadable { f } {
- global tcltestOutput
- # The channel is readable; try to read it.
- set status [catch { gets $f line } result]
- if { $status != 0 } {
- # Error on the channel
- set ::DONE 2
- } elseif { $result >= 0 } {
- # Successfully read the channel
- append tcltestOutput $line\n
- } elseif { [eof $f] } {
- # End of file on the channel
- set ::DONE 1
- } elseif { [fblocked $f] } {
- # Read blocked. Just return
- } else {
- # Something else
- set ::DONE 3
- }
- }
- proc testTimeout {} {
- global runningTest
- global testfile
- global test
- global summaryfd
- global options
- puts $summaryfd "file $testfile test $test: Not finished after\
- $options(-timeout) milliseconds. Canceling the\
- test."
- set ::DONE 4
- }
- proc testOneFile {file} {
- global options
- global gettestnamesCmd
- global testrun
- global timeoutID
- global testfile
- global test
- global summaryfd
- global tcltestOutput
- set testfile $file
- puts $file
- set testcounter 0
- foreach test [getTestNames $file] {
- incr testcounter
- # Show, you're alive. Report progress.
- if {$testcounter >= $options(-progress)} {
- puts -nonewline "#"
- flush stdout
- set testcounter 0
- }
- set test $test
- set ::DONE 0
- set tcltestOutput ""
- set cmd "$options(-testapp) "
- append cmd " $options(-tcltestdir)/$options(-testmain) "
- append cmd " -file $file -match $test "
- append cmd " -verbose error "
- append cmd " -singleproc 1 "
- set runningTest [open "| $cmd"]
- fconfigure $runningTest -blocking false
- fileevent $runningTest readable [list isReadable $runningTest]
- set timeoutID [after $options(-timeout) testTimeout]
- vwait ::DONE
- after cancel $timeoutID
- set logmsg "\n\n****************\nfile $testfile test $test: "
- switch $::DONE {
- 1 {
- foreach line [split $tcltestOutput "\n"] {
- if {[string first $options(-testmain) $line] == 0} {
- # This sets the variables Total, Passed,
- # Skipped and Failed, as of tcltest 2.3.5.
- foreach {what nrOf} [lrange $line 1 end] {
- set $what $nrOf
- }
- if {$Failed != 0} {
- append logmsg "Test failed.\n$tcltestOutput"
- } else {
- set logmsg ""
- }
- }
- }
- }
- 2 {
- append logmsg "Error.\n$tcltestOutput"
- }
- 3 {
- append logmsg "Irregular read from subprocess\n$tcltestOutput"
- }
- 4 {
- # Test cancled after timeout. Already reported,
- # don't mess up log.
- set logmsg ""
- }
- default {
- # can't happen
- append logmsg "Reached 'can't happen' case in testOneFile."
- }
- }
- puts -nonewline $summaryfd $logmsg
- close $runningTest
- }
- puts ""
- }
- proc init {} {
- global options
- global gettestnamesCmd
- global summaryfd
- readArgs
- if {![file exists $options(-testapp)]} {
- puts stderr "No $::options(-testapp) app in the run dir. Aborting."
- exit 1
- }
- if {![string is boolean -strict $options(-overwriteoutfile)]} {
- puts stderr "The option -overwriteoutfile expects a boolean value.\
- Aborting."
- exit 1
- }
- if {![string is integer -strict $options(-timeout)]
- || $options(-timeout) <= 0} {
- puts string "The option -timeout expects a positive integer as value.\
- Aborting."
- exit 1
- }
- if {![string is integer -strict $options(-progress)]} {
- puts string "The options -progress expects a positive integer as\
- value. Aborting."
- exit 1
- }
- set options(-testapp) [file join [pwd] $options(-testapp)]
- set gettestnamesCmd "$::options(-testapp) \
- [file join [file dirname [info script]] test-names.tcl]"
- if {[file exists $options(-outfile)] && !$options(-overwriteoutfile)} {
- puts stderr "Out file '$options(-outfile)' already exists\
- and -overwriteoutfile not true. Aborting."
- exit 1
- }
- set summaryfd [open $options(-outfile) w+]
- fconfigure $summaryfd -buffering line
- puts $summaryfd "Started\
- [clock format [clock seconds] -format "%Y-%m-%dT%T"]"
- puts $summaryfd "Test file pattern: $options(-file)\n"
- }
- proc runEveryTestAlone {} {
- init
- foreach testfile [getTestFiles] {
- testOneFile $testfile
- }
- }
- runEveryTestAlone