namespace eval trd { variable tcltest variable extra variable all_configs variable build # Tcl tests to run for various builds. # set tcltest(linux.Fast-One) veryquick set tcltest(linux.Debug-One) veryquick set tcltest(linux.Debug-Two) veryquick set tcltest(linux.Have-Not) veryquick set tcltest(linux.Secure-Delete) veryquick set tcltest(linux.Unlock-Notify) veryquick set tcltest(linux.User-Auth) veryquick set tcltest(linux.Update-Delete-Limit) veryquick set tcltest(linux.Extra-Robustness) veryquick set tcltest(linux.Device-Two) veryquick set tcltest(linux.No-lookaside) veryquick set tcltest(linux.Devkit) veryquick set tcltest(linux.Apple) veryquick set tcltest(linux.Android) veryquick set tcltest(linux.Sanitize) veryquick set tcltest(linux.Device-One) all set tcltest(linux.Default) all_plus_autovacuum_crash set tcltest(linux.Valgrind) valgrind set tcltest(osx.Locking-Style) veryquick set tcltest(osx.Have-Not) veryquick set tcltest(osx.Apple) all_less_no_mutex_try set tcltest(win.Stdcall) veryquick set tcltest(win.Have-Not) veryquick set tcltest(win.Windows-Memdebug) veryquick set tcltest(win.Windows-Win32Heap) veryquick set tcltest(win.Windows-Sanitize) veryquick set tcltest(win.Default) full # Extra [make xyz] tests that should be run for various builds. # set extra(linux.Check-Symbols) checksymbols set extra(linux.Fast-One) {fuzztest sourcetest} set extra(linux.Debug-One) {fuzztest sourcetest mptest} set extra(linux.Debug-Two) {fuzztest sourcetest} set extra(linux.Have-Not) {fuzztest sourcetest} set extra(linux.Secure-Delete) {fuzztest sourcetest} set extra(linux.Unlock-Notify) {fuzztest sourcetest} set extra(linux.Update-Delete-Limit) {fuzztest sourcetest} set extra(linux.Extra-Robustness) {fuzztest sourcetest} set extra(linux.Device-Two) {fuzztest sourcetest threadtest} set extra(linux.No-lookaside) {fuzztest sourcetest} set extra(linux.Devkit) {fuzztest sourcetest} set extra(linux.Android) {fuzztest sourcetest} set extra(linux.Apple) {fuzztest sourcetest} set extra(linux.Sanitize) {fuzztest sourcetest} set extra(linux.Default) {fuzztest sourcetest threadtest} set extra(osx.Apple) {fuzztest threadtest} set extra(osx.Have-Not) {fuzztest sourcetest} set extra(osx.Locking-Style) {mptest fuzztest sourcetest} set extra(win.Default) mptest set extra(win.Stdcall) {fuzztest sourcetest} set extra(win.Windows-Memdebug) {fuzztest sourcetest} set extra(win.Windows-Win32Heap) {fuzztest sourcetest} set extra(win.Windows-Sanitize) fuzztest set extra(win.Have-Not) {fuzztest sourcetest} # The following mirrors the set of test suites invoked by "all.test". # set all_configs { full no_optimization memsubsys1 memsubsys2 singlethread multithread onefile utf16 exclusive persistent_journal persistent_journal_error no_journal no_journal_error autovacuum_ioerr no_mutex_try fullmutex journaltest inmemory_journal pcache0 pcache10 pcache50 pcache90 pcache100 prepare mmap } #----------------------------------------------------------------------- # Start of build() definitions. # set build(Default) { -O2 --disable-amalgamation --disable-shared --enable-session -DSQLITE_ENABLE_RBU } # These two are used by [testrunner.tcl mdevtest] (All-O0) and # [testrunner.tcl sdevtest] (All-Sanitize). # set build(All-Debug) { --enable-debug --enable-all } set build(All-O0) { -O0 --enable-all } set build(All-Sanitize) { -DSQLITE_OMIT_LOOKASIDE=1 --enable-all -fsanitize=address,undefined -fno-sanitize-recover=undefined } set build(Sanitize) { CC=clang -fsanitize=address,undefined -fno-sanitize-recover=undefined -DSQLITE_ENABLE_STAT4 -DSQLITE_OMIT_LOOKASIDE=1 -DCONFIG_SLOWDOWN_FACTOR=5.0 -DSQLITE_ENABLE_RBU --enable-debug --enable-all } set build(Stdcall) { -DUSE_STDCALL=1 -O2 } # The "Have-Not" configuration sets all possible -UHAVE_feature options # in order to verify that the code works even on platforms that lack # these support services. set build(Have-Not) { -DHAVE_FDATASYNC=0 -DHAVE_GMTIME_R=0 -DHAVE_ISNAN=0 -DHAVE_LOCALTIME_R=0 -DHAVE_LOCALTIME_S=0 -DHAVE_MALLOC_USABLE_SIZE=0 -DHAVE_STRCHRNUL=0 -DHAVE_USLEEP=0 -DHAVE_UTIME=0 } set build(Unlock-Notify) { -O2 -DSQLITE_ENABLE_UNLOCK_NOTIFY -DSQLITE_THREADSAFE -DSQLITE_TCL_DEFAULT_FULLMUTEX=1 } set build(User-Auth) { -O2 -DSQLITE_USER_AUTHENTICATION=1 } set build(Secure-Delete) { -O2 -DSQLITE_SECURE_DELETE=1 -DSQLITE_SOUNDEX=1 } set build(Update-Delete-Limit) { -O2 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 -DSQLITE_ENABLE_STMT_SCANSTATUS -DSQLITE_LIKE_DOESNT_MATCH_BLOBS -DSQLITE_ENABLE_CURSOR_HINTS } set build(Check-Symbols) { -DSQLITE_MEMDEBUG=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_MEMSYS5=1 -DSQLITE_ENABLE_MEMSYS3=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 -DSQLITE_SECURE_DELETE=1 -DSQLITE_SOUNDEX=1 -DSQLITE_ENABLE_ATOMIC_WRITE=1 -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1 -DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_STMT_SCANSTATUS --enable-fts5 --enable-session } set build(Debug-One) { --disable-shared -O2 -funsigned-char -DSQLITE_DEBUG=1 -DSQLITE_MEMDEBUG=1 -DSQLITE_MUTEX_NOOP=1 -DSQLITE_TCL_DEFAULT_FULLMUTEX=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_MEMSYS5=1 -DSQLITE_ENABLE_COLUMN_METADATA=1 -DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_HIDDEN_COLUMNS -DSQLITE_MAX_ATTACHED=125 -DSQLITE_MUTATION_TEST --enable-fts5 } set build(Debug-Two) { -DSQLITE_DEFAULT_MEMSTATUS=0 -DSQLITE_MAX_EXPR_DEPTH=0 --enable-debug } set build(Fast-One) { -O6 -DSQLITE_ENABLE_FTS4=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_RBU -DSQLITE_MAX_ATTACHED=125 -DSQLITE_MAX_MMAP_SIZE=12884901888 -DSQLITE_ENABLE_SORTER_MMAP=1 -DLONGDOUBLE_TYPE=double --enable-session } set build(Device-One) { -O2 -DSQLITE_DEBUG=1 -DSQLITE_DEFAULT_AUTOVACUUM=1 -DSQLITE_DEFAULT_CACHE_SIZE=64 -DSQLITE_DEFAULT_PAGE_SIZE=1024 -DSQLITE_DEFAULT_TEMP_CACHE_SIZE=32 -DSQLITE_DISABLE_LFS=1 -DSQLITE_ENABLE_ATOMIC_WRITE=1 -DSQLITE_ENABLE_IOTRACE=1 -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 -DSQLITE_MAX_PAGE_SIZE=4096 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_OMIT_PROGRESS_CALLBACK=1 -DSQLITE_OMIT_VIRTUALTABLE=1 -DSQLITE_ENABLE_HIDDEN_COLUMNS -DSQLITE_TEMP_STORE=3 } set build(Device-Two) { -DSQLITE_4_BYTE_ALIGNED_MALLOC=1 -DSQLITE_DEFAULT_AUTOVACUUM=1 -DSQLITE_DEFAULT_CACHE_SIZE=1000 -DSQLITE_DEFAULT_LOCKING_MODE=0 -DSQLITE_DEFAULT_PAGE_SIZE=1024 -DSQLITE_DEFAULT_TEMP_CACHE_SIZE=1000 -DSQLITE_DISABLE_LFS=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_MAX_COMPOUND_SELECT=50 -DSQLITE_MAX_PAGE_SIZE=32768 -DSQLITE_OMIT_TRACE=1 -DSQLITE_TEMP_STORE=3 -DSQLITE_THREADSAFE=2 --enable-fts5 --enable-session } set build(Locking-Style) { -O2 -DSQLITE_ENABLE_LOCKING_STYLE=1 } set build(Android) { -Os -DHAVE_USLEEP=1 -DSQLITE_HAVE_ISNAN -DSQLITE_POWERSAFE_OVERWRITE=1 -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_DEFAULT_AUTOVACUUM=1 -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_BACKWARDS -DSQLITE_ENABLE_FTS4 -DSQLITE_SECURE_DELETE -DSQLITE_ENABLE_BATCH_ATOMIC_WRITE -DBIONIC_IOCTL_NO_SIGNEDNESS_OVERLOAD -DSQLITE_ALLOW_ROWID_IN_VIEW -DSQLITE_ENABLE_BYTECODE_VTAB -Wno-unused-parameter -Werror -DUSE_PREAD64 -Dfdatasync=fdatasync -DHAVE_MALLOC_H=1 -DHAVE_MALLOC_USABLE_SIZE -DSQLITE_ENABLE_DBSTAT_VTAB } # Compile-options used by Android but omitted from these # tests: # -DNDEBUG=1 # -DSQLITE_DEFAULT_LEGACY_ALTER_TABLE # -DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 # -DSQLITE_DEFAULT_FILE_PERMISSIONS=0600 # -DSQLITE_OMIT_BUILTIN_TEST # -DSQLITE_OMIT_LOAD_EXTENSION # -DSQLITE_OMIT_COMPILEOPTION_DIAGS # set build(Apple) { -Os -DHAVE_GMTIME_R=1 -DHAVE_ISNAN=1 -DHAVE_LOCALTIME_R=1 -DHAVE_PREAD=1 -DHAVE_PWRITE=1 -DHAVE_UTIME=1 -DSQLITE_DEFAULT_CACHE_SIZE=1000 -DSQLITE_DEFAULT_CKPTFULLFSYNC=1 -DSQLITE_DEFAULT_MEMSTATUS=1 -DSQLITE_DEFAULT_PAGE_SIZE=1024 -DSQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS=1 -DSQLITE_ENABLE_API_ARMOR=1 -DSQLITE_ENABLE_AUTO_PROFILE=1 -DSQLITE_ENABLE_FLOCKTIMEOUT=1 -DSQLITE_ENABLE_FTS3=1 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 -DSQLITE_ENABLE_FTS3_TOKENIZER=1 -DSQLITE_ENABLE_PERSIST_WAL=1 -DSQLITE_ENABLE_PURGEABLE_PCACHE=1 -DSQLITE_ENABLE_RTREE=1 -DSQLITE_ENABLE_SETLK_TIMEOUT=2 -DSQLITE_ENABLE_SNAPSHOT=1 -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 -DSQLITE_MAX_LENGTH=2147483645 -DSQLITE_MAX_VARIABLE_NUMBER=500000 -DSQLITE_NO_SYNC=1 -DSQLITE_OMIT_AUTORESET=1 -DSQLITE_OMIT_LOAD_EXTENSION=1 -DSQLITE_PREFER_PROXY_LOCKING=1 -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 -DSQLITE_THREADSAFE=2 -DSQLITE_USE_URI=1 -DSQLITE_WRITE_WALFRAME_PREBUFFERED=1 -DUSE_GUARDED_FD=1 -DUSE_PREAD=1 --enable-fts5 } set build(Extra-Robustness) { -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1 -DSQLITE_MAX_ATTACHED=62 } set build(Devkit) { -DSQLITE_DEFAULT_FILE_FORMAT=4 -DSQLITE_MAX_ATTACHED=30 -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_FTS4_PARENTHESIS -DSQLITE_DISABLE_FTS4_DEFERRED -DSQLITE_ENABLE_RTREE --enable-fts5 } set build(No-lookaside) { -DSQLITE_TEST_REALLOC_STRESS=1 -DSQLITE_OMIT_LOOKASIDE=1 } set build(Valgrind) { -DSQLITE_ENABLE_STAT4 -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_HIDDEN_COLUMNS -DLONGDOUBLE_TYPE=double -DCONFIG_SLOWDOWN_FACTOR=8.0 } set build(Windows-Memdebug) { MEMDEBUG=1 DEBUG=3 } set build(Windows-Win32Heap) { WIN32HEAP=1 DEBUG=4 } set build(Windows-Sanitize) { ASAN=1 } } #------------------------------------------------------------------------- proc trd_import {} { uplevel { variable ::trd::tcltest variable ::trd::extra variable ::trd::all_configs variable ::trd::build } } proc trd_builds {platform} { trd_import set klist [lsort -uniq [concat \ [array names tcltest ${platform}.*] \ [array names extra ${platform}.*] \ ]] if {[llength $klist]==0} { error "no such platform: $platform" } set ret "" foreach k $klist { foreach {p c} [split $k "."] {} lappend ret $c } set ret } proc trd_configs {platform bld} { trd_import set clist [list] if {[info exists tcltest($platform.$bld)]} { set clist $tcltest($platform.$bld) if {$clist=="all"} { set clist $all_configs } elseif {$clist=="all_plus_autovacuum_crash"} { set clist [concat $all_configs autovacuum_crash] } elseif {$clist=="all_less_no_mutex_try"} { set idx [lsearch $all_configs no_mutex_try] set clist [lreplace $all_configs $idx $idx] } } set clist } proc trd_extras {platform bld} { trd_import if {[info exists extra($platform.$bld)]==0} { return [list] } return $extra($platform.$bld) } # Usage: # # trd_fuzztest_data # # This returns data used by testrunner.tcl to run commands equivalent # to [make fuzztest]. The returned value is a list, which should be # interpreted as a sequence of pairs. The first element of each pair # is an interpreter name. The second element is a list of files. # testrunner.tcl automatically creates one job to build each interpreter, # and one to run each of the files with it once it has been built. # # In practice, the returned value looks like this: # # { # {fuzzcheck {$testdir/fuzzdata1.db $testdir/fuzzdata2.db ...}} # {{sessionfuzz run} $testdir/sessionfuzz-data1.db} # } # # where $testdir is replaced by the full-path to the test-directory (the # directory containing this file). "fuzzcheck" and "sessionfuzz" have .exe # extensions on windows. # proc trd_fuzztest_data {} { set EXE "" set lFuzzDb [glob [file join $::testdir fuzzdata*.db]] set lSessionDb [glob [file join $::testdir sessionfuzz-data*.db]] if {$::tcl_platform(platform)=="windows"} { return [list fuzzcheck.exe $lFuzzDb] } return [list fuzzcheck $lFuzzDb {sessionfuzz run} $lSessionDb] } proc trd_all_configs {} { trd_import set all_configs } proc trimscript {text} { set text [string map {"\n " "\n"} [string trim $text]] } proc make_sh_script {srcdir opts cflags makeOpts configOpts} { set tcldir [::tcl::pkgconfig get libdir,install] set myopts "" if {[info exists ::env(OPTS)]} { append myopts "# From environment variable:\n" append myopts "OPTS=$::env(OPTS)\n\n" } foreach o [lsort $opts] { append myopts "OPTS=\"\$OPTS $o\"\n" } return [trimscript [subst -nocommands { set -e if [ "\$#" -ne 1 ] ; then echo "Usage: \$0 " exit -1 fi SRCDIR="$srcdir" TCLDIR="$tcldir" if [ ! -f Makefile ] ; then \$SRCDIR/configure --with-tcl=\$TCL $configOpts fi $myopts CFLAGS="$cflags" make \$1 "CFLAGS=\$CFLAGS" "OPTS=\$OPTS" $makeOpts }]] } # Generate the text of a *.bat script. # proc make_bat_file {srcdir opts cflags makeOpts} { set srcdir [file nativename [file normalize $srcdir]] return [trimscript [subst -nocommands { set TARGET=%1 set TMP=%CD% nmake /f $srcdir\\Makefile.msc TOP="$srcdir" %TARGET% "CCOPTS=$cflags" "OPTS=$opts" $makeOpts }]] } # Generate the text of a shell script. # proc make_script {cfg srcdir bMsvc} { set opts [list] ;# OPTS value set cflags [expr {$bMsvc ? "-Zi" : "-g"}] ;# CFLAGS value set makeOpts [list] ;# Extra args for [make] set configOpts [list] ;# Extra args for [configure] # Define either SQLITE_OS_WIN or SQLITE_OS_UNIX, as appropriate. if {$::tcl_platform(platform)=="windows"} { lappend opts -DSQLITE_OS_WIN=1 } else { lappend opts -DSQLITE_OS_UNIX=1 } # Unless the configuration specifies -DHAVE_USLEEP=0, set -DHAVE_USLEEP=1. # if {[lsearch $cfg "-DHAVE_USLEEP=0"]<0} { lappend cfg -DHAVE_USLEEP=1 } # Loop through the parameters of the nominated configuration, updating # $opts, $cflags, $makeOpts and $configOpts along the way. Rules are as # follows: # # 1. If the parameter begins with "-D", add it to $opts. # # 2. If the parameter begins with "--" add it to $configOpts. Unless # this command is preparing a script for MSVC - then add an # equivalent to $makeOpts or $opts. # # 3. If the parameter begins with "-" add it to $cflags. If in MSVC # mode and the parameter is an -O option, instead add # an OPTIMIZATIONS= switch to $makeOpts. # # 4. If none of the above apply, add the parameter to $makeOpts # foreach param $cfg { if {[string range $param 0 1]=="-D"} { lappend opts $param continue } if {[string range $param 0 1]=="--"} { if {$bMsvc==0} { lappend configOpts $param } else { switch -- $param { --disable-amalgamation { lappend makeOpts USE_AMALGAMATION=0 } --disable-shared { lappend makeOpts USE_CRT_DLL=0 DYNAMIC_SHELL=0 } --enable-fts5 { lappend opts -DSQLITE_ENABLE_FTS5 } --enable-shared { lappend makeOpts USE_CRT_DLL=1 DYNAMIC_SHELL=1 } --enable-session { lappend opts -DSQLITE_ENABLE_PREUPDATE_HOOK lappend opts -DSQLITE_ENABLE_SESSION } --enable-all { } --enable-debug { # lappend makeOpts OPTIMIZATIONS=0 lappend opts -DSQLITE_DEBUG } default { error "Cannot translate $param for MSVC" } } } continue } if {[string range $param 0 0]=="-"} { if {$bMsvc} { if {[regexp -- {^-O(\d+)$} $param -> level]} { lappend makeOpts OPTIMIZATIONS=$level continue } if {$param eq "-fsanitize=address,undefined"} { lappend makeOpts ASAN=1 continue } } lappend cflags $param continue } lappend makeOpts $param } if {$bMsvc==0} { set zRet [make_sh_script $srcdir $opts $cflags $makeOpts $configOpts] } else { set zRet [make_bat_file $srcdir $opts $cflags $makeOpts] } } # Usage: # # trd_buildscript CONFIG SRCDIR MSVC # # This command returns the full text of a script (either a shell script or # an ms-dos bat file) that may be used to build SQLite source code according # to a nominated configuration. # # Parameter CONFIG must be a configuration defined above in the ::trd::build # array. SRCDIR is the root directory of an SQLite source tree (the parent # directory of that containing this script). MSVC is a boolean - true to # use the MSVC compiler, false otherwise. # proc trd_buildscript {config srcdir bMsvc} { trd_import # Ensure that the named configuration exists. if {![info exists build($config)]} { if {$config!="help"} { puts "No such build config: $config" } puts "Available configurations: [lsort [array names build]]" flush stdout exit 1 } # Generate and return the script. return [make_script $build($config) $srcdir $bMsvc] } # Usage: # # trd_test_script_properties PATH # # The argument must be a path to a Tcl test script. This function scans the # first 100 lines of the script for lines that look like: # # TESTRUNNER: # # where is a list of identifiers, each of which defines a # property of the test script. Example properties are "slow" or "superslow". # proc trd_test_script_properties {path} { # Use this global array as a cache: global trd_test_script_properties_cache if {![info exists trd_test_script_properties_cache($path)]} { set fd [open $path] set ret [list] for {set line 0} {$line < 100 && ![eof $fd]} {incr line} { set text [gets $fd] if {[string match -nocase *testrunner:* $text]} { regexp -nocase {.*testrunner:(.*)} $text -> properties lappend ret {*}$properties } } set trd_test_script_properties_cache($path) $ret close $fd } set trd_test_script_properties_cache($path) }