3 set testdir
[file normalize
[file dirname
$argv0]]
6 source [file join $testdir testrunner_data.tcl
]
7 source [file join $testdir permutations.test
]
11 # This script requires an interpreter that supports [package require sqlite3]
12 # to run. If this is not such an intepreter, see if there is a [testfixture]
13 # in the current directory. If so, run the command using it. If not,
14 # recommend that the user build one.
16 proc find_interpreter
{} {
17 set interpreter
[file tail
[info nameofexec
]]
18 set rc
[catch { package require sqlite3
}]
20 if { [string match
-nocase testfixture
* $interpreter]==0
21 && [file executable .
/testfixture
]
23 puts "Failed to find tcl package sqlite3. Restarting with ./testfixture.."
25 exec .
/testfixture
[info script
] {*}$::argv >@ stdout
31 puts stderr
"Failed to find tcl package sqlite3"
32 puts stderr
"Run \"make testfixture\" and then try again..."
38 # Usually this script is run by [testfixture]. But it can also be run
39 # by a regular [tclsh]. For these cases, emulate the [clock_milliseconds]
41 if {[info commands clock_milliseconds
]==""} {
42 proc clock_milliseconds
{} {
47 #-------------------------------------------------------------------------
51 set a0
[file tail
$::argv0]
53 puts stderr
[string trim
[subst -nocommands {
55 $a0 ?SWITCHES? ?PERMUTATION? ?PATTERNS?
64 --zipvfs ZIPVFS-SOURCE-DIR
66 Interesting values
for PERMUTATION are
:
68 veryquick
- a fast subset of the tcl test scripts. This is the
default.
69 full
- all tcl test scripts.
70 all
- all tcl test scripts
, plus a subset of test scripts rerun
71 with various permutations.
72 release
- full release test with various builds.
74 If no PATTERN arguments are present
, all tests specified by the PERMUTATION
75 are run. Otherwise
, each pattern is interpreted as a
glob pattern. Only
76 those tcl tests
for which the final component of the
filename matches at
77 least one specified pattern are run.
79 If no PATTERN arguments are present
, then various fuzztest
, threadtest
80 and other tests are run as part of the
"release" permutation. These are
81 omitted
if any PATTERN arguments are specified on the command line.
83 If a PERMUTATION is specified and is followed by the path to a
Tcl script
84 instead of a
list of patterns
, then that single
Tcl test script is run
85 with the specified permutation.
87 The
"status" and
"njob" commands are designed to be run from the same
88 directory as a running testrunner.tcl script that is running tests. The
89 "status" command prints a report describing the current state and progress
90 of the tests. The
"njob" command may be used to query or modify the number
91 of sub-processes the test script uses to run tests.
96 #-------------------------------------------------------------------------
98 #-------------------------------------------------------------------------
99 # Try to estimate a the number of processes to use.
101 # Command [guess_number_of_cores] attempts to glean the number of logical
102 # cores. Command [default_njob] returns the default value for the --jobs
105 proc guess_number_of_cores
{} {
106 if {[catch {number_of_cores
} ret
]} {
109 if {$::tcl_platform(platform
)=="windows"} {
110 catch { set ret
$::env(NUMBER_OF_PROCESSORS
) }
112 if {$::tcl_platform(os
)=="Darwin"} {
113 set cmd
"sysctl -n hw.logicalcpu"
118 set fd
[open "|$cmd" r
]
128 proc default_njob
{} {
129 set nCore
[guess_number_of_cores
]
133 set nHelper
[expr int
($nCore*0.5)]
137 #-------------------------------------------------------------------------
139 #-------------------------------------------------------------------------
140 # Setup various default values in the global TRG() array.
142 set TRG
(dbname
) [file normalize testrunner.db
]
143 set TRG
(logname
) [file normalize testrunner.log
]
144 set TRG
(build.logname
) [file normalize testrunner_build.log
]
145 set TRG
(info_script
) [file normalize
[info script
]]
146 set TRG
(timeout
) 10000 ;# Default busy-timeout for testrunner.db
147 set TRG
(nJob
) [default_njob
] ;# Default number of helper processes
148 set TRG
(patternlist
) [list]
149 set TRG
(cmdline
) $argv
150 set TRG
(reporttime
) 2000
151 set TRG
(fuzztest
) 0 ;# is the fuzztest option present.
152 set TRG
(zipvfs
) "" ;# -zipvfs option, if any
153 set TRG
(buildonly
) 0 ;# True if --buildonly option
154 set TRG
(dryrun
) 0 ;# True if --dryrun option
156 switch -nocase -glob -- $tcl_platform(os
) {
158 set TRG
(platform
) osx
159 set TRG
(make
) make.sh
160 set TRG
(makecmd
) "bash make.sh"
161 set TRG
(testfixture
) testfixture
163 set TRG
(runcmd
) "bash run.sh"
166 set TRG
(platform
) linux
167 set TRG
(make
) make.sh
168 set TRG
(makecmd
) "bash make.sh"
169 set TRG
(testfixture
) testfixture
171 set TRG
(runcmd
) "bash run.sh"
174 set TRG
(platform
) win
175 set TRG
(make
) make.bat
176 set TRG
(makecmd
) make.bat
177 set TRG
(testfixture
) testfixture.exe
179 set TRG
(runcmd
) "run.bat"
182 error "cannot determine platform!"
185 #-------------------------------------------------------------------------
187 #-------------------------------------------------------------------------
188 # The database schema used by the testrunner.db database.
191 DROP TABLE IF EXISTS jobs
;
192 DROP TABLE IF EXISTS config
;
195 ** This table contains one row
for each job that testrunner.tcl must run
196 ** before the entire test run is finished.
199 ** Unique identifier
for each job. Must be a
+ve non-zero number.
202 ** 3 or
4 letter mnemonic
for the class of tests this belongs to e.g.
203 ** "fuzz", "tcl", "make" etc.
206 ** Name
/description of job. For display purposes.
209 ** If the job requires a make.bat
/make.sh make wrapper
(i.e. to build
210 ** something
), the name of the build configuration it uses. See
211 ** testrunner_data.tcl
for a
list of build configs. e.g.
"Win32-MemDebug".
214 ** If the job should use a well-known directory name
for its
215 ** sub-directory instead of an anonymous
"testdir[1234...]" sub-dir
216 ** that is deleted
after the job is finished.
219 ** Bash or batch script to run the job.
222 ** The jobid value of a job that this job depends on. This job may not
223 ** be run before its depid job has finished successfully.
226 ** Higher values run first. Sometimes.
229 /* Fields populated when db is initialized
*/
230 jobid INTEGER PRIMARY KEY
, -- id to identify job
231 displaytype TEXT NOT NULL
, -- Type of test
(for one line report
)
232 displayname TEXT NOT NULL
, -- Human readable job name
233 build TEXT NOT NULL DEFAULT ''
, -- make.sh
/make.bat
file request
, if any
234 dirname TEXT NOT NULL DEFAULT ''
, -- directory name
, if required
235 cmd TEXT NOT NULL
, -- shell command to run
236 depid INTEGER
, -- identifier of dependency
(or ''
)
237 priority INTEGER NOT NULL
, -- higher priority jobs may run earlier
239 /* Fields updated as jobs run
*/
242 state TEXT CHECK
( state IN
(''
, 'ready'
, 'running'
, 'done'
, 'failed'
) ),
247 name TEXT COLLATE nocase PRIMARY KEY
,
251 CREATE INDEX i1 ON jobs
(state
, priority
);
252 CREATE INDEX i2 ON jobs
(depid
);
254 #-------------------------------------------------------------------------
256 #--------------------------------------------------------------------------
257 # Check if this script is being invoked to run a single file. If so,
260 if {[llength $argv]==2
261 && ([lindex $argv 0]=="" ||
[info exists
::testspec([lindex $argv 0])])
262 && [file exists
[lindex $argv 1]]
264 set permutation
[lindex $argv 0]
265 set script
[file normalize
[lindex $argv 1]]
268 set testdir
[file dirname
$argv0]
269 source $::testdir/tester.tcl
271 if {$permutation=="full"} {
273 unset -nocomplain ::G(isquick
)
276 } elseif
{$permutation!="default" && $permutation!=""} {
278 if {[info exists
::testspec($permutation)]==0} {
279 error "no such permutation: $permutation"
282 array set O
$::testspec($permutation)
283 set ::G(perm
:name
) $permutation
284 set ::G(perm
:prefix
) $O(-prefix)
286 set ::G(perm
:dbconfig
) $O(-dbconfig)
287 set ::G(perm
:presql
) $O(-presql)
289 rename finish_test helper_finish_test
290 proc finish_test
{} "
304 #--------------------------------------------------------------------------
306 #--------------------------------------------------------------------------
307 # Check if this is the "njob" command:
309 if {([llength $argv]==2 ||
[llength $argv]==1)
310 && [string compare
-nocase njob
[lindex $argv 0]]==0
312 sqlite3 mydb
$TRG(dbname
)
313 if {[llength $argv]==2} {
314 set param
[lindex $argv 1]
315 if {[string is integer
$param]==0 ||
$param<1 ||
$param>128} {
316 puts stderr
"parameter must be an integer between 1 and 128"
320 mydb
eval { REPLACE INTO config VALUES
('njob'
, $param); }
322 set res
[mydb one
{ SELECT value FROM config WHERE name
='njob'
}]
327 #--------------------------------------------------------------------------
329 #--------------------------------------------------------------------------
330 # Check if this is the "script" command:
332 if {[string compare
-nocase script
[lindex $argv 0]]==0} {
333 if {[llength $argv]!=2 && !([llength $argv]==3&&[lindex $argv 1]=="-msvc")} {
337 set bMsvc
[expr ([llength $argv]==3)]
338 set config
[lindex $argv [expr [llength $argv]-1]]
340 puts [trd_buildscript
$config [file dirname
$testdir] $bMsvc]
345 #--------------------------------------------------------------------------
346 # Check if this is the "status" command:
348 if {[llength $argv]==1
349 && [string compare
-nocase status
[lindex $argv 0]]==0
352 proc display_job
{jobdict
{tm
""}} {
353 array set job
$jobdict
355 set dfname
[format %-60s $job(displayname
)]
358 if {$tm!=""} { set dtm
"\[[expr {$tm-$job(starttime)}]ms\]" }
362 sqlite3 mydb
$TRG(dbname
)
366 set cmdline
[mydb one
{ SELECT value FROM config WHERE name
='cmdline'
}]
367 set nJob
[mydb one
{ SELECT value FROM config WHERE name
='njob'
}]
369 set now
[clock_milliseconds
]
372 COALESCE
((SELECT value FROM config WHERE name
='end'
), $now) -
373 (SELECT value FROM config WHERE name
='start'
)
377 foreach s
{"" ready running done failed
} { set S
($s) 0 }
379 SELECT state
, count
(*) AS cnt FROM jobs GROUP BY
1
384 set fin
[expr $S(done
)+$S(failed
)]
385 if {$cmdline!=""} {set cmdline
" $cmdline"}
389 set f
"$S(failed) FAILED, "
391 puts "Command line: \[testrunner.tcl$cmdline\]"
393 puts "Summary: ${tm}ms, ($fin/$total) finished, ${f}$S(running) running"
395 set srcdir
[file dirname
[file dirname
$TRG(info_script
)]]
399 SELECT
* FROM jobs WHERE state
='running' ORDER BY starttime
401 display_job
[array get job
] $now
407 SELECT
* FROM jobs WHERE state
='failed' ORDER BY starttime
409 display_job
[array get job
]
417 #-------------------------------------------------------------------------
418 # Parse the command line.
420 for {set ii
0} {$ii < [llength $argv]} {incr ii
} {
421 set isLast
[expr $ii==([llength $argv]-1)]
422 set a
[lindex $argv $ii]
423 set n
[string length
$a]
425 if {[string range
$a 0 0]=="-"} {
426 if {($n>2 && [string match
"$a*" --jobs]) ||
$a=="-j"} {
428 set TRG
(nJob
) [lindex $argv $ii]
429 if {$isLast} { usage
}
430 } elseif
{($n>2 && [string match
"$a*" --zipvfs]) ||
$a=="-z"} {
432 set TRG
(zipvfs
) [file normalize
[lindex $argv $ii]]
433 if {$isLast} { usage
}
434 } elseif
{($n>2 && [string match
"$a*" --buildonly]) ||
$a=="-b"} {
436 } elseif
{($n>2 && [string match
"$a*" --dryrun]) ||
$a=="-d"} {
442 lappend TRG
(patternlist
) [string map
{% *} $a]
449 # This script runs individual tests - tcl scripts or [make xyz] commands -
450 # in directories named "testdir$N", where $N is an integer. This variable
451 # contains a list of integers indicating the directories in use.
453 # This variable is accessed only via the following commands:
456 # Return the number of entries currently in the list.
459 # Remove value IDIR from the list. It is an error if it is not present.
462 # Select a value that is not already in the list. Add it to the list
465 set TRG
(dirs_in_use
) [list]
467 proc dirs_nHelper
{} {
469 llength $TRG(dirs_in_use
)
471 proc dirs_freeDir
{iDir
} {
474 foreach d
$TRG(dirs_in_use
) {
475 if {$iDir!=$d} { lappend out
$d }
477 if {[llength $out]!=[llength $TRG(dirs_in_use
)]-1} {
478 error "dirs_freeDir could not find $iDir"
480 set TRG
(dirs_in_use
) $out
482 proc dirs_allocDir
{} {
484 array set inuse
[list]
485 foreach d
$TRG(dirs_in_use
) {
488 for {set iRet
0} {[info exists inuse
($iRet)]} {incr iRet
} { }
489 lappend TRG
(dirs_in_use
) $iRet
493 # Check that directory $dir exists. If it does not, create it. If
494 # it does, delete its contents.
496 proc create_or_clear_dir
{dir
} {
497 set dir
[file normalize
$dir]
498 catch { file mkdir
$dir }
499 foreach f
[glob -nocomplain [file join $dir *]] {
500 catch { file delete
-force $f }
504 proc build_to_dirname
{bname
} {
505 set fold
[string tolower
[string map
{- _
} $bname]]
506 return "testrunner_build_$fold"
509 #-------------------------------------------------------------------------
511 proc r_write_db
{tcl
} {
512 trdb
eval { BEGIN EXCLUSIVE
}
517 # Obtain a new job to be run by worker $iJob (an integer). A job is
518 # returned as a three element list:
520 # {$build $config $file}
522 proc r_get_next_job
{iJob
} {
526 set orderby
"ORDER BY priority ASC"
528 set orderby
"ORDER BY priority DESC"
535 SELECT * FROM jobs AS j WHERE state='ready' $orderby LIMIT 1
537 trdb
eval $query job
{
538 set tm
[clock_milliseconds
]
540 set jobid
$job(jobid
)
543 UPDATE jobs SET starttime
=$tm, state
='running' WHERE jobid
=$jobid
546 set ret
[array get job
]
553 #rename r_get_next_job r_get_next_job_r
554 #proc r_get_next_job {iJob} {
555 #puts [time { set res [r_get_next_job_r $iJob] }]
561 # add_job OPTION ARG OPTION ARG...
563 # where available OPTIONS are:
573 # Returns the jobid value for the new job.
575 proc add_job
{args
} {
578 -displaytype -displayname -build -dirname
579 -cmd -depid -priority
582 # Set default values of options.
590 # Check all required options are present. And that no extras are present.
592 if {[info exists A
($o)]==0} { error "missing required option $o" }
594 foreach o
[array names A
] {
595 if {[lsearch -exact $options $o]<0} { error "unrecognized option: $o" }
599 if {$A(-depid)==""} { set state ready
}
603 displaytype
, displayname
, build
, dirname
, cmd
, depid
, priority
,
617 trdb last_insert_rowid
620 proc add_tcl_jobs
{build config patternlist
} {
623 set topdir
[file dirname
$::testdir]
624 set testrunner_tcl
[file normalize
[info script
]]
627 set testfixture
[info nameofexec
]
629 set testfixture
[file join [lindex $build 1] $TRG(testfixture
)]
631 if {[lindex $build 2]=="Valgrind"} {
632 set setvar
"export OMIT_MISUSE=1\n"
633 set testfixture
"${setvar}valgrind -v --error-exitcode=1 $testfixture"
636 # The ::testspec array is populated by permutations.test
637 foreach f
[dict get
$::testspec($config) -files] {
639 if {[llength $patternlist]>0} {
641 foreach p
$patternlist {
642 if {[string match
$p [file tail
$f]]} {
647 if {$bMatch==0} continue
650 if {[file pathtype
$f]!="absolute"} { set f
[file join $::testdir $f] }
651 set f
[file normalize
$f]
653 set displayname
[string map
[list $topdir/ {}] $f]
654 if {$config=="full" ||
$config=="veryquick"} {
655 set cmd
"$testfixture $f"
657 set cmd
"$testfixture $testrunner_tcl $config $f"
658 set displayname
"config=$config $displayname"
661 set displayname
"[lindex $build 2] $displayname"
664 set lProp
[trd_test_script_properties
$f]
666 if {[lsearch $lProp slow
]>=0} { set priority
2 }
667 if {[lsearch $lProp superslow
]>=0} { set priority
4 }
671 -displayname $displayname \
673 -depid [lindex $build 0] \
679 proc add_build_job
{buildname target
} {
682 set dirname
"[string tolower [string map {- _} $buildname]]_$target"
683 set dirname
"testrunner_bld_$dirname"
687 -displayname "Build $buildname ($target)" \
690 -cmd "$TRG(makecmd) $target" \
694 list $id [file normalize
$dirname] $buildname
697 proc add_make_job
{bld target
} {
700 if {$TRG(platform
)=="win"} {
701 set path
[string map
{/ \\} [lindex $bld 1]]
702 set cmd
"xcopy /S $path\\* ."
704 set cmd
"cp -r [lindex $bld 1]/* ."
706 append cmd
"\n$TRG(makecmd) $target"
710 -displayname "[lindex $bld 2] make $target" \
712 -depid [lindex $bld 0] \
716 proc add_fuzztest_jobs
{buildname
} {
718 foreach {interpreter scripts
} [trd_fuzztest_data
] {
719 set subcmd
[lrange $interpreter 1 end
]
720 set interpreter
[lindex $interpreter 0]
722 set bld
[add_build_job
$buildname $interpreter]
723 foreach {depid dirname displayname
} $bld {}
727 # Fuzz data files fuzzdata1.db and fuzzdata2.db are larger than
728 # the others. So ensure that these are run as a higher priority.
729 set tail
[file tail
$s]
730 if {$tail=="fuzzdata1.db" ||
$tail=="fuzzdata2.db"} {
738 -displayname "$buildname $interpreter $tail" \
740 -cmd "[file join $dirname $interpreter] $subcmd $s" \
746 proc add_zipvfs_jobs
{} {
748 source [file join $TRG(zipvfs
) test zipvfs_testrunner.tcl
]
750 set bld
[add_build_job Zipvfs
$TRG(testfixture
)]
751 foreach s
[zipvfs_testrunner_files
] {
752 set cmd
"[file join [lindex $bld 1] $TRG(testfixture)] $s"
755 -displayname "Zipvfs [file tail $s]" \
757 -depid [lindex $bld 0]
760 set ::env(SQLITE_TEST_DIR
) $::testdir
763 # Used to add jobs for "mdevtest" and "sdevtest".
765 proc add_devtest_jobs
{lBld patternlist
} {
769 set bld
[add_build_job
$b $TRG(testfixture
)]
770 add_tcl_jobs
$bld veryquick
$patternlist
771 if {$patternlist==""} {
777 proc add_jobs_from_cmdline
{patternlist
} {
780 if {$TRG(zipvfs
)!=""} {
782 if {[llength $patternlist]==0} return
785 if {[llength $patternlist]==0} {
786 set patternlist
[list veryquick
]
789 set first
[lindex $patternlist 0]
792 set patternlist
[lrange $patternlist 1 end
]
793 set clist
[trd_all_configs
]
795 add_tcl_jobs
"" $c $patternlist
800 add_devtest_jobs
{All-O0 All-Debug
} [lrange $patternlist 1 end
]
804 add_devtest_jobs
{All-Sanitize All-Debug
} [lrange $patternlist 1 end
]
808 set patternlist
[lrange $patternlist 1 end
]
809 foreach b
[trd_builds
$TRG(platform
)] {
810 set bld
[add_build_job
$b $TRG(testfixture
)]
811 foreach c
[trd_configs
$TRG(platform
) $b] {
812 add_tcl_jobs
$bld $c $patternlist
815 if {$patternlist==""} {
816 foreach e
[trd_extras
$TRG(platform
) $b] {
817 if {$e=="fuzztest"} {
828 if {[info exists
::testspec($first)]} {
829 add_tcl_jobs
"" $first [lrange $patternlist 1 end
]
831 add_tcl_jobs
"" full
$patternlist
837 proc make_new_testset
{} {
841 trdb
eval $TRG(schema
)
843 set cmdline
$TRG(cmdline
)
844 set tm
[clock_milliseconds
]
845 trdb
eval { REPLACE INTO config VALUES
('njob'
, $nJob ); }
846 trdb
eval { REPLACE INTO config VALUES
('cmdline'
, $cmdline ); }
847 trdb
eval { REPLACE INTO config VALUES
('start'
, $tm ); }
849 add_jobs_from_cmdline
$TRG(patternlist
)
854 proc mark_job_as_finished
{jobid output state endtm
} {
858 SET output
=$output, state
=$state, endtime
=$endtm
860 UPDATE jobs SET state
='ready' WHERE depid
=$jobid;
865 proc script_input_ready
{fd iJob jobid
} {
871 trdb
eval { SELECT
* FROM jobs WHERE jobid
=$jobid } job
{}
873 # If this job specified a directory name, then delete the run.sh/run.bat
874 # file from it before continuing. This is because the contents of this
875 # directory might be copied by some other job, and we don't want to copy
876 # the run.sh file in this case.
877 if {$job(dirname
)!=""} {
878 file delete
-force [file join $job(dirname
) $TRG(run
)]
882 fconfigure $fd -blocking 1
884 set rc
[catch { close $fd } msg
]
886 if {[info exists TRG
(reportlength
)]} {
887 puts -nonewline "[string repeat " " $TRG(reportlength)]\r"
889 puts "FAILED: $job(displayname) ($iJob)"
893 set tm
[clock_milliseconds
]
894 set jobtm
[expr {$tm - $job(starttime
)}]
896 puts $TRG(log
) "### $job(displayname) ${jobtm}ms ($state)"
897 puts $TRG(log
) [string trim
$O($iJob)]
899 mark_job_as_finished
$jobid $O($iJob) $state $tm
905 set rc
[catch { gets $fd line
} res
]
910 append O
($iJob) "$line\n"
920 proc launch_another_job
{iJob
} {
925 set testfixture
[info nameofexec
]
926 set script
$TRG(info_script
)
930 set jobdict
[r_get_next_job
$iJob]
931 if {$jobdict==""} { return 0 }
932 array set job
$jobdict
934 set dir
$job(dirname
)
935 if {$dir==""} { set dir
[dirname
$iJob] }
936 create_or_clear_dir
$dir
938 if {$job(build
)!=""} {
939 set srcdir
[file dirname
$::testdir]
940 if {$job(build
)=="Zipvfs"} {
941 set script
[zipvfs_testrunner_script
]
943 set bWin
[expr {$TRG(platform
)=="win"}]
944 set script
[trd_buildscript
$job(build
) $srcdir $bWin]
946 set fd
[open [file join $dir $TRG(make
)] w
]
951 if { $TRG(dryrun
) } {
953 mark_job_as_finished
$job(jobid
) "" done
0
955 if {$job(build
)!=""} {
956 puts $TRG(log
) "(cd $dir ; $job(cmd) )"
958 puts $TRG(log
) "$job(cmd)"
964 set fd
[open $TRG(run
) w
]
967 set fd
[open "|$TRG(runcmd) 2>@1" r
]
970 fconfigure $fd -blocking false
971 fileevent $fd readable
[list script_input_ready
$fd $iJob $job(jobid
)]
977 proc one_line_report
{} {
980 set tm
[expr [clock_milliseconds
] - $TRG(starttime
)]
981 set tm
[format "%d" [expr int
($tm/1000.0 + 0.5)]]
985 SELECT displaytype
, state
, count
(*) AS cnt
989 set v
($state,$displaytype) $cnt
990 incr t
($displaytype) $cnt
995 foreach j
[lsort [array names t
]] {
996 foreach k
{done failed running
} { incr v
($k,$j) 0 }
997 set fin
[expr $v(done
,$j) + $v(failed
,$j)]
998 lappend text "${j}($fin/$t($j))"
999 if {$v(failed
,$j)>0} {
1000 lappend text "f$v(failed,$j)"
1002 if {$v(running
,$j)>0} {
1003 lappend text "r$v(running,$j)"
1007 if {[info exists TRG
(reportlength
)]} {
1008 puts -nonewline "[string repeat " " $TRG(reportlength)]\r"
1010 set report
"${tm} [join $text { }]"
1011 set TRG
(reportlength
) [string length
$report]
1012 if {[string length
$report]<100} {
1013 puts -nonewline "$report\r"
1019 after $TRG(reporttime
) one_line_report
1022 proc launch_some_jobs
{} {
1024 set nJob
[trdb one
{ SELECT value FROM config WHERE name
='njob'
}]
1026 while {[dirs_nHelper
]<$nJob} {
1027 set iDir
[dirs_allocDir
]
1028 if {0==[launch_another_job
$iDir]} {
1035 proc run_testset
{} {
1039 set TRG
(starttime
) [clock_milliseconds
]
1040 set TRG
(log
) [open $TRG(logname
) w
]
1045 while {[dirs_nHelper
]>0} {
1046 after 500 {incr ::wakeup}
1053 set tm
[clock_milliseconds
]
1054 trdb
eval { REPLACE INTO config VALUES
('end'
, $tm ); }
1055 set nErr
[trdb one
{SELECT count
(*) FROM jobs WHERE state
='failed'
}]
1057 puts "$nErr failures:"
1059 SELECT displayname FROM jobs WHERE state
='failed'
1061 puts "FAILED: $displayname"
1066 puts "\nTest database is $TRG(dbname)"
1067 puts "Test log is $TRG(logname)"
1070 # Handle the --buildonly option, if it was specified.
1072 proc handle_buildonly
{} {
1074 if {$TRG(buildonly
)} {
1076 trdb
eval { DELETE FROM jobs WHERE displaytype
!='bld'
}
1081 sqlite3 trdb
$TRG(dbname
)
1082 trdb timeout
$TRG(timeout
)
1083 set tm
[lindex [time { make_new_testset
}] 0]
1085 puts "splitting work across $TRG(nJob) jobs"
1087 puts "built testset in [expr $tm/1000]ms.."