1
0
mirror of https://github.com/sqlite/sqlite.git synced 2025-08-08 14:02:16 +03:00

Merge the latest trunk enhancements into main reuse-schema branch.

FossilOrigin-Name: 31a71a79bf9bd4737bf4a266056c7a4f4796c9bcc19e35e3f94e1235585cae9d
This commit is contained in:
drh
2024-08-10 20:24:10 +00:00
40 changed files with 1160 additions and 795 deletions

View File

@@ -54,10 +54,11 @@ proc usage {} {
Usage:
$a0 ?SWITCHES? ?PERMUTATION? ?PATTERNS?
$a0 PERMUTATION FILE
$a0 errors ?-v|--verbose?
$a0 help
$a0 njob ?NJOB?
$a0 script ?-msvc? CONFIG
$a0 status
$a0 status ?-d SECS? ?--cls?
where SWITCHES are:
--buildonly Build test exes but do not run tests
@@ -66,6 +67,7 @@ Usage:
--explain Write summary to stdout
--jobs NUM Run tests using NUM separate processes
--omit CONFIGS Omit configs on comma-separated list CONFIGS
--status Show the full "status" report while running
--stop-on-coredump Stop running if any test segfaults
--stop-on-error Stop running after any reported error
--zipvfs ZIPVFSDIR ZIPVFS source directory
@@ -100,13 +102,19 @@ with the specified permutation.
The "status" and "njob" commands are designed to be run from the same
directory as a running testrunner.tcl script that is running tests. The
"status" command prints a report describing the current state and progress
of the tests. The "njob" command may be used to query or modify the number
of sub-processes the test script uses to run tests.
of the tests. Use the "-d N" option to have the status display clear the
screen and repeat every N seconds. The "njob" command may be used to query
or modify the number of sub-processes the test script uses to run tests.
The "script" command outputs the script used to build a configuration.
Add the "-msvc" option for a Windows-compatible script. For a list of
available configurations enter "$a0 script help".
The "errors" commands shows the output of all tests that failed in the
most recent run. Complete output is shown if the -v or --verbose options
are used. Otherwise, an attempt is made to minimize the output to show
only the parts that contain the error messages.
Full documentation here: https://sqlite.org/src/doc/trunk/doc/testrunner.md
}]]
@@ -180,6 +188,7 @@ set TRG(dryrun) 0 ;# True if --dryrun option
set TRG(explain) 0 ;# True for the --explain option
set TRG(stopOnError) 0 ;# Stop running at first failure
set TRG(stopOnCore) 0 ;# Stop on a core-dump
set TRG(fullstatus) 0 ;# Full "status" report while running
switch -nocase -glob -- $tcl_platform(os) {
*darwin* {
@@ -379,34 +388,36 @@ if {[string compare -nocase script [lindex $argv 0]]==0} {
puts [trd_buildscript $config [file dirname $testdir] $bMsvc]
exit
}
#--------------------------------------------------------------------------
# Check if this is the "status" command:
# Helper routine for show_status
#
if {[llength $argv]==1
&& [string compare -nocase status [lindex $argv 0]]==0
} {
proc display_job {jobdict {tm ""}} {
array set job $jobdict
set dfname [format %-60s $job(displayname)]
set dtm ""
if {$tm!=""} { set dtm "\[[expr {$tm-$job(starttime)}]ms\]" }
puts " $dfname $dtm"
proc display_job {jobdict {tm ""}} {
array set job $jobdict
set dfname [format %-60s $job(displayname)]
set dtm ""
if {$tm!=""} {
set dtm [format %-10s "\[[expr {$tm-$job(starttime)}]ms\]"]
}
puts " $dfname $dtm"
}
sqlite3 mydb $TRG(dbname)
mydb timeout 2000
mydb eval BEGIN
set cmdline [mydb one { SELECT value FROM config WHERE name='cmdline' }]
set nJob [mydb one { SELECT value FROM config WHERE name='njob' }]
# This procedure shows the "status" page. It uses the database
# connect passed in as the "db" parameter. If the "cls" parameter
# is true, then VT100 escape codes are used to format the display.
#
proc show_status {db cls} {
global TRG
$db eval BEGIN
if {[catch {
set cmdline [$db one { SELECT value FROM config WHERE name='cmdline' }]
set nJob [$db one { SELECT value FROM config WHERE name='njob' }]
} msg]} {
if {$cls} {puts "\033\[H\033\[2J"}
puts "Cannot read database: $TRG(dbname)"
return
}
set now [clock_milliseconds]
set tm [mydb one {
set tm [$db one {
SELECT
COALESCE((SELECT value FROM config WHERE name='end'), $now) -
(SELECT value FROM config WHERE name='start')
@@ -414,7 +425,7 @@ if {[llength $argv]==1
set total 0
foreach s {"" ready running done failed} { set S($s) 0 }
mydb eval {
$db eval {
SELECT state, count(*) AS cnt FROM jobs GROUP BY 1
} {
incr S($state) $cnt
@@ -423,18 +434,28 @@ if {[llength $argv]==1
set fin [expr $S(done)+$S(failed)]
if {$cmdline!=""} {set cmdline " $cmdline"}
if {$cls} {
# Move the cursor to the top-left corner. Each iteration will simply
# overwrite.
puts -nonewline "\033\[H"
flush stdout
set clreol "\033\[K"
} else {
set clreol ""
}
set f ""
if {$S(failed)>0} {
set f "$S(failed) FAILED, "
}
puts "Command line: \[testrunner.tcl$cmdline\]"
puts "Jobs: $nJob"
puts "Summary: ${tm}ms, ($fin/$total) finished, ${f}$S(running) running"
puts "Command line: \[testrunner.tcl$cmdline\]$clreol"
puts "Jobs: $nJob "
puts "Summary: ${tm}ms, ($fin/$total) finished,\
${f}$S(running) running "
set srcdir [file dirname [file dirname $TRG(info_script)]]
if {$S(running)>0} {
puts "Running: "
mydb eval {
$db eval {
SELECT * FROM jobs WHERE state='running' ORDER BY starttime
} job {
display_job [array get job] $now
@@ -442,21 +463,137 @@ if {[llength $argv]==1
}
if {$S(failed)>0} {
puts "Failures: "
mydb eval {
$db eval {
SELECT * FROM jobs WHERE state='failed' ORDER BY starttime
} job {
display_job [array get job]
}
set nOmit [mydb one {SELECT count(*) FROM jobs WHERE state='omit'}]
set nOmit [$db one {SELECT count(*) FROM jobs WHERE state='omit'}]
if {$nOmit} {
puts "$nOmit jobs omitted due to failures"
puts "$nOmit jobs omitted due to failures$clreol"
}
}
if {$cls} {
# Clear everything else to the bottom of the screen
puts -nonewline "\033\[0J"
flush stdout
}
$db eval COMMIT
}
#--------------------------------------------------------------------------
# Check if this is the "status" command:
#
if {[llength $argv]>=1
&& [string compare -nocase status [lindex $argv 0]]==0
} {
set delay 0
set cls 0
for {set ii 1} {$ii<[llength $argv]} {incr ii} {
set a0 [lindex $argv $ii]
if {$a0=="-d" && $ii+1<[llength $argv]} {
incr ii
set delay [lindex $argv $ii]
if {![string is integer -strict $delay]} {
puts "Argument to -d should be an integer"
exit 1
}
} elseif {$a0=="-cls" || $a0=="--cls"} {
set cls 1
} else {
puts "unknown option: \"$a0\""
exit 1
}
}
if {![file readable $TRG(dbname)]} {
puts "Database missing: $TRG(dbname)"
exit
}
sqlite3 mydb $TRG(dbname)
mydb timeout 2000
# Clear the whole screen initially.
#
if {$delay>0 || $cls} {puts -nonewline "\033\[2J"}
while {1} {
show_status mydb [expr {$delay>0 || $cls}]
if {$delay<=0} break
after [expr {$delay*1000}]
}
mydb close
exit
}
# Scan the output of all jobs looking for the summary lines that
# report the number of test cases and the number of errors.
# Aggregate these numbers and return them.
#
proc aggregate_test_counts {db} {
set ncase 0
set nerr 0
$db eval {SELECT output FROM jobs WHERE displaytype IN ('tcl','fuzz')} {
set n 0
set m 0
if {[regexp {(\d+) errors out of (\d+) tests} $output all n m]
&& [string is integer -strict $n]
&& [string is integer -strict $m]} {
incr ncase $m
incr nerr $n
} elseif {[regexp {sessionfuzz.*: *(\d+) cases, (\d+) crash} $output \
all m n]
&& [string is integer -strict $m]
&& [string is integer -strict $n]} {
incr ncase $m
incr nerr $n
}
}
return [list $nerr $ncase]
}
#--------------------------------------------------------------------------
# Check if this is the "errors" command:
#
if {[llength $argv]>=1 && [llength $argv]<=2
&& ([string compare -nocase errors [lindex $argv 0]]==0 ||
[string match err* [lindex $argv 0]]==1)
} {
set verbose 0
for {set ii 1} {$ii<[llength $argv]} {incr ii} {
set a0 [lindex $argv $ii]
if {$a0=="-v" || $a0=="--verbose" || $a0=="-verbose"} {
set verbose 1
} else {
puts "unknown option: \"$a0\"". Use --help for more info."
exit 1
}
}
set cnt 0
sqlite3 mydb $TRG(dbname)
mydb timeout 2000
mydb eval {SELECT displaytype, displayname, output
FROM jobs WHERE state='failed'} {
puts "**** $displayname ****"
if {$verbose || $displaytype!="tcl"} {
puts $output
} else {
foreach line [split $output \n] {
if {[string match {!*} $line] || [string match *failed* $line]} {
puts $line
}
}
}
incr cnt
}
set summary [aggregate_test_counts mydb]
mydb close
puts "Total [lindex $summary 0] errors out of [lindex $summary 1] tests"
exit
}
#-------------------------------------------------------------------------
# Parse the command line.
#
@@ -490,6 +627,16 @@ for {set ii 0} {$ii < [llength $argv]} {incr ii} {
set TRG(stopOnError) 1
} elseif {[string match "$a*" --stop-on-coredump]} {
set TRG(stopOnCore) 1
} elseif {[string match "$a*" --status]} {
if {$tcl_platform(platform)=="windows"} {
puts stdout \
"The --status option is not available on Windows. A suggested work-around"
puts stdout \
"is to run the following command in a separate window:\n"
puts stdout " [info nameofexe] $argv0 status -d 2\n"
} else {
set TRG(fullstatus) 1
}
} else {
usage
}
@@ -603,12 +750,6 @@ proc r_get_next_job {iJob} {
return $ret
}
#rename r_get_next_job r_get_next_job_r
#proc r_get_next_job {iJob} {
#puts [time { set res [r_get_next_job_r $iJob] }]
#set res
#}
# Usage:
#
# add_job OPTION ARG OPTION ARG...
@@ -1126,49 +1267,58 @@ proc launch_another_job {iJob} {
return 1
}
proc one_line_report {} {
# Show the testing progress report
#
proc progress_report {} {
global TRG
set tm [expr [clock_milliseconds] - $TRG(starttime)]
set tm [format "%d" [expr int($tm/1000.0 + 0.5)]]
r_write_db {
trdb eval {
SELECT displaytype, state, count(*) AS cnt
FROM jobs
GROUP BY 1, 2
} {
set v($state,$displaytype) $cnt
incr t($displaytype) $cnt
if {$TRG(fullstatus)} {
if {$::tcl_platform(platform)=="windows"} {
exec [info nameofexe] $::argv0 status --cls
} else {
show_status trdb 1
}
}
set text ""
foreach j [lsort [array names t]] {
foreach k {done failed running} { incr v($k,$j) 0 }
set fin [expr $v(done,$j) + $v(failed,$j)]
lappend text "${j}($fin/$t($j))"
if {$v(failed,$j)>0} {
lappend text "f$v(failed,$j)"
}
if {$v(running,$j)>0} {
lappend text "r$v(running,$j)"
}
}
if {[info exists TRG(reportlength)]} {
puts -nonewline "[string repeat " " $TRG(reportlength)]\r"
}
set report "${tm} [join $text { }]"
set TRG(reportlength) [string length $report]
if {[string length $report]<100} {
puts -nonewline "$report\r"
flush stdout
} else {
puts $report
set tm [expr [clock_milliseconds] - $TRG(starttime)]
set tm [format "%d" [expr int($tm/1000.0 + 0.5)]]
r_write_db {
trdb eval {
SELECT displaytype, state, count(*) AS cnt
FROM jobs
GROUP BY 1, 2
} {
set v($state,$displaytype) $cnt
incr t($displaytype) $cnt
}
}
set text ""
foreach j [lsort [array names t]] {
foreach k {done failed running} { incr v($k,$j) 0 }
set fin [expr $v(done,$j) + $v(failed,$j)]
lappend text "${j}($fin/$t($j))"
if {$v(failed,$j)>0} {
lappend text "f$v(failed,$j)"
}
if {$v(running,$j)>0} {
lappend text "r$v(running,$j)"
}
}
if {[info exists TRG(reportlength)]} {
puts -nonewline "[string repeat " " $TRG(reportlength)]\r"
}
set report "${tm} [join $text { }]"
set TRG(reportlength) [string length $report]
if {[string length $report]<100} {
puts -nonewline "$report\r"
flush stdout
} else {
puts $report
}
}
after $TRG(reporttime) one_line_report
after $TRG(reporttime) progress_report
}
proc launch_some_jobs {} {
@@ -1193,13 +1343,14 @@ proc run_testset {} {
launch_some_jobs
one_line_report
if {$TRG(fullstatus)} {puts "\033\[2J"}
progress_report
while {[dirs_nHelper]>0} {
after 500 {incr ::wakeup}
vwait ::wakeup
}
close $TRG(log)
one_line_report
progress_report
r_write_db {
set tm [clock_milliseconds]