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 the reuse-schema branch.

FossilOrigin-Name: f9ce1ababbd62c579658c737059f6992bdb32909e7a06282fe6a359d10ad1272
This commit is contained in:
drh
2024-09-06 15:52:48 +00:00
35 changed files with 1538 additions and 711 deletions

190
test/testrunner.tcl Normal file → Executable file
View File

@@ -1,3 +1,6 @@
#!/bin/sh
# Script to runs tests for SQLite. Run with option "help" for more info. \
exec tclsh "$0" "$@"
set dir [pwd]
set testdir [file normalize [file dirname $argv0]]
@@ -14,8 +17,14 @@ cd $dir
# recommend that the user build one.
#
proc find_interpreter {} {
global dir
set interpreter [file tail [info nameofexec]]
set rc [catch { package require sqlite3 }]
if {$rc} {
if {[file readable pkgIndex.tcl] && [catch {source pkgIndex.tcl}]==0} {
set rc [catch { package require sqlite3 }]
}
}
if {$rc} {
if { [string match -nocase testfixture* $interpreter]==0
&& [file executable ./testfixture]
@@ -28,8 +37,30 @@ proc find_interpreter {} {
}
}
if {$rc} {
puts stderr "Failed to find tcl package sqlite3"
puts stderr "Run \"make testfixture\" and then try again..."
puts "Cannot find tcl package sqlite3: Trying to build it now..."
if {$::tcl_platform(platform)=="windows"} {
set bat [open make-tcl-extension.bat w]
puts $bat "nmake /f Makefile.msc tclextension"
close $bat
catch {exec -ignorestderr -- make-tcl-extension.bat}
} else {
catch {exec make tclextension}
}
if {[file readable pkgIndex.tcl] && [catch {source pkgIndex.tcl}]==0} {
set rc [catch { package require sqlite3 }]
}
if {$rc==0} {
puts "The SQLite tcl extension was successfully built and loaded."
puts "Run \"make tclextension-install\" to avoid having to rebuild\
it in the future."
} else {
puts "Unable to build the SQLite tcl extension"
}
}
if {$rc} {
puts stderr "Cannot find a working instance of the SQLite tcl extension."
puts stderr "Run \"make tclextension\" or \"make testfixture\" and\
try again..."
exit 1
}
}
@@ -54,8 +85,9 @@ proc usage {} {
Usage:
$a0 ?SWITCHES? ?PERMUTATION? ?PATTERNS?
$a0 PERMUTATION FILE
$a0 errors ?-v|--verbose?
$a0 errors ?-v|--verbose? ?-s|--summary? ?PATTERN?
$a0 help
$a0 joblist ?PATTERN?
$a0 njob ?NJOB?
$a0 script ?-msvc? CONFIG
$a0 status ?-d SECS? ?--cls?
@@ -112,10 +144,12 @@ 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
The "errors" commands shows the output of 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.
only the parts that contain the error messages. The --summary option just
shows the jobs that failed. If PATTERN are provided, the error information
is only provided for jobs that match PATTERN.
Full documentation here: https://sqlite.org/src/doc/trunk/doc/testrunner.md
}]]
@@ -284,6 +318,8 @@ set TRG(schema) {
state TEXT CHECK( state IN ('','ready','running','done','failed','omit') ),
ntest INT, -- Number of test cases run
nerr INT, -- Number of errors reported
svers TEXT, -- Reported SQLite version
pltfm TEXT, -- Host platform reported
output TEXT -- test output
);
@@ -356,8 +392,8 @@ if {([llength $argv]==2 || [llength $argv]==1)
sqlite3 mydb $TRG(dbname)
if {[llength $argv]==2} {
set param [lindex $argv 1]
if {[string is integer $param]==0 || $param<1 || $param>128} {
puts stderr "parameter must be an integer between 1 and 128"
if {[string is integer $param]==0 || $param<0 || $param>128} {
puts stderr "parameter must be an integer between 0 and 128"
exit 1
}
@@ -476,13 +512,22 @@ proc show_status {db cls} {
$ne errors, $nt tests"]
set srcdir [file dirname [file dirname $TRG(info_script)]]
set nrun 0
puts [format %-79s "Running: $S(running) (max: $nJob)"]
set line "Running: $S(running) (max: $nJob)"
if {$S(running)>0 && $fin>100 && $fin>0.05*$total} {
# Only estimate the time remaining after completing at least 100
# jobs amounting to 10% of the total. Never estimate less than
# 2% of the total time used so far.
set tmleft [expr {($tm/$fin)*($total-$fin)}]
if {$tmleft<0.02*$tm} {
set tmleft [expr {$tm*0.02}]
}
append line " est time left [elapsetime $tmleft]"
}
puts [format %-79.79s $line]
if {$S(running)>0} {
$db eval {
SELECT * FROM jobs WHERE state='running' ORDER BY starttime
} job {
incr nrun
display_job [array get job] $now
}
}
@@ -568,44 +613,80 @@ if {[llength $argv]>=1
exit
}
#--------------------------------------------------------------------------
# Check if this is the "joblist" command:
#
if {[llength $argv]>=1
&& [string compare -nocase "joblist" [lindex $argv 0]]==0
} {
set pattern {}
for {set ii 1} {$ii<[llength $argv]} {incr ii} {
set a0 [lindex $argv $ii]
if {$pattern==""} {
set pattern [string trim $a0 *]
} else {
puts "unknown option: \"$a0\""
exit 1
}
}
set SQL {SELECT displaytype, displayname, state FROM jobs}
if {$pattern!=""} {
regsub -all {[^a-zA-Z0-9*.-/]} $pattern ? pattern
append SQL " WHERE displayname GLOB '*$pattern*'"
}
append SQL " ORDER BY starttime"
if {![file readable $TRG(dbname)]} {
puts "Database missing: $TRG(dbname)"
exit
}
sqlite3 mydb $TRG(dbname)
mydb timeout 2000
mydb eval $SQL {
set label UNKNOWN
switch -- $state {
ready {set label READY}
done {set label DONE}
failed {set label FAILED}
omit {set label OMIT}
running {set label RUNNING}
}
puts [format {%-7s %-5s %s} $label $displaytype $displayname]
}
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]
set ne 0
set nt 0
$db eval {SELECT sum(nerr) AS ne, sum(ntest) as nt FROM jobs} break
return [list $ne $nt]
}
#--------------------------------------------------------------------------
# Check if this is the "errors" command:
#
if {[llength $argv]>=1 && [llength $argv]<=2
if {[llength $argv]>=1
&& ([string compare -nocase errors [lindex $argv 0]]==0 ||
[string match err* [lindex $argv 0]]==1)
} {
set verbose 0
set pattern {}
set summary 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
} elseif {$a0=="-s" || $a0=="--summary" || $a0=="-summary"} {
set summary 1
} elseif {$pattern==""} {
set pattern *[string trim $a0 *]*
} else {
puts "unknown option: \"$a0\"". Use --help for more info."
exit 1
@@ -613,9 +694,22 @@ if {[llength $argv]>=1 && [llength $argv]<=2
}
set cnt 0
sqlite3 mydb $TRG(dbname)
mydb timeout 2000
mydb eval {SELECT displaytype, displayname, output
FROM jobs WHERE state='failed'} {
mydb timeout 5000
if {$summary} {
set sql "SELECT displayname FROM jobs WHERE state='failed'"
} else {
set sql "SELECT displaytype, displayname, output FROM jobs \
WHERE state='failed'"
}
if {$pattern!=""} {
regsub -all {[^a-zA-Z0-9*/ ?]} $pattern . pattern
append sql " AND displayname GLOB '$pattern'"
}
mydb eval $sql {
if {$summary} {
puts "FAILED: $displayname"
continue
}
puts "**** $displayname ****"
if {$verbose || $displaytype!="tcl"} {
puts $output
@@ -628,9 +722,13 @@ if {[llength $argv]>=1 && [llength $argv]<=2
}
incr cnt
}
set summary [aggregate_test_counts mydb]
mydb close
puts "Total [lindex $summary 0] errors out of [lindex $summary 1] tests"
if {$pattern==""} {
set summary [aggregate_test_counts mydb]
mydb close
puts "Total [lindex $summary 0] errors out of [lindex $summary 1] tests"
} else {
mydb close
}
exit
}
@@ -1096,6 +1194,7 @@ proc add_jobs_from_cmdline {patternlist} {
}
}
devtest -
mdevtest {
set config_set {
ReuseSchema-O0
@@ -1184,10 +1283,13 @@ proc mark_job_as_finished {jobid output state endtm} {
set ntest 1
set nerr 0
if {$endtm>0} {
if {[regexp {\y(\d+) errors out of (\d+) tests} $output all a b]} {
set re {\y(\d+) errors out of (\d+) tests( on [^\n]+\n)?}
if {[regexp $re $output all a b pltfm]} {
set nerr $a
set ntest $b
}
regexp {\ySQLite \d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d [0-9a-fA-F]+} \
$output svers
}
r_write_db {
if {$state=="failed"} {
@@ -1196,10 +1298,11 @@ proc mark_job_as_finished {jobid output state endtm} {
} else {
set childstate ready
}
if {[info exists pltfm]} {set pltfm [string trim $pltfm]}
trdb eval {
UPDATE jobs
SET output=$output, state=$state, endtime=$endtm,
ntest=$ntest, nerr=$nerr
ntest=$ntest, nerr=$nerr, svers=$svers, pltfm=$pltfm
WHERE jobid=$jobid;
UPDATE jobs SET state=$childstate WHERE depid=$jobid;
}
@@ -1452,7 +1555,16 @@ proc run_testset {} {
FROM jobs WHERE endtime>0
} break;
set et [elapsetime $totaltime]
puts "$totalerr errors out of $totaltest tests in about $et"
set pltfm {}
trdb eval {
SELECT pltfm, count(*) FROM jobs WHERE pltfm IS NOT NULL
ORDER BY 2 DESC LIMIT 1
} break
puts "$totalerr errors out of $totaltest tests in $et $pltfm"
trdb eval {
SELECT DISTINCT substr(svers,1,79) as v1 FROM jobs WHERE svers IS NOT NULL
} {puts $v1}
}
# Handle the --buildonly option, if it was specified.