OLD | NEW |
| (Empty) |
1 #!/usr/bin/tclsh | |
2 # | |
3 # Documentation for this script. This may be output to stderr | |
4 # if the script is invoked incorrectly. See the [process_options] | |
5 # proc below. | |
6 # | |
7 set ::USAGE_MESSAGE { | |
8 This Tcl script is used to test the various configurations required | |
9 before releasing a new version. Supported command line options (all | |
10 optional) are: | |
11 | |
12 --srcdir TOP-OF-SQLITE-TREE (see below) | |
13 --platform PLATFORM (see below) | |
14 --config CONFIGNAME (Run only CONFIGNAME) | |
15 --quick (Run "veryquick.test" only) | |
16 --veryquick (Run "make smoketest" only) | |
17 --msvc (Use MSVC as the compiler) | |
18 --buildonly (Just build testfixture - do not run) | |
19 --dryrun (Print what would have happened) | |
20 --info (Show diagnostic info) | |
21 --with-tcl=DIR (Use TCL build at DIR) | |
22 --jobs N (Use N processes - default 1) | |
23 --progress (Show progress messages) | |
24 | |
25 The default value for --srcdir is the parent of the directory holding | |
26 this script. | |
27 | |
28 The script determines the default value for --platform using the | |
29 $tcl_platform(os) and $tcl_platform(machine) variables. Supported | |
30 platforms are "Linux-x86", "Linux-x86_64", "Darwin-i386", | |
31 "Darwin-x86_64", "Windows NT-intel", and "Windows NT-amd64". | |
32 | |
33 Every test begins with a fresh run of the configure script at the top | |
34 of the SQLite source tree. | |
35 } | |
36 | |
37 # Return a timestamp of the form HH:MM:SS | |
38 # | |
39 proc now {} { | |
40 return [clock format [clock seconds] -format %H:%M:%S] | |
41 } | |
42 | |
43 # Omit comments (text between # and \n) in a long multi-line string. | |
44 # | |
45 proc strip_comments {in} { | |
46 regsub -all {#[^\n]*\n} $in {} out | |
47 return $out | |
48 } | |
49 | |
50 array set ::Configs [strip_comments { | |
51 "Default" { | |
52 -O2 | |
53 --disable-amalgamation --disable-shared | |
54 } | |
55 "Sanitize" { | |
56 CC=clang -fsanitize=undefined | |
57 -DSQLITE_ENABLE_STAT4 | |
58 } | |
59 "Have-Not" { | |
60 # The "Have-Not" configuration sets all possible -UHAVE_feature options | |
61 # in order to verify that the code works even on platforms that lack | |
62 # these support services. | |
63 -DHAVE_FDATASYNC=0 | |
64 -DHAVE_GMTIME_R=0 | |
65 -DHAVE_ISNAN=0 | |
66 -DHAVE_LOCALTIME_R=0 | |
67 -DHAVE_LOCALTIME_S=0 | |
68 -DHAVE_MALLOC_USABLE_SIZE=0 | |
69 -DHAVE_STRCHRNUL=0 | |
70 -DHAVE_USLEEP=0 | |
71 -DHAVE_UTIME=0 | |
72 } | |
73 "Unlock-Notify" { | |
74 -O2 | |
75 -DSQLITE_ENABLE_UNLOCK_NOTIFY | |
76 -DSQLITE_THREADSAFE | |
77 -DSQLITE_TCL_DEFAULT_FULLMUTEX=1 | |
78 } | |
79 "Secure-Delete" { | |
80 -O2 | |
81 -DSQLITE_SECURE_DELETE=1 | |
82 -DSQLITE_SOUNDEX=1 | |
83 } | |
84 "Update-Delete-Limit" { | |
85 -O2 | |
86 -DSQLITE_DEFAULT_FILE_FORMAT=4 | |
87 -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 | |
88 -DSQLITE_ENABLE_STMT_SCANSTATUS | |
89 -DSQLITE_LIKE_DOESNT_MATCH_BLOBS | |
90 -DSQLITE_ENABLE_CURSOR_HINTS | |
91 --enable-json1 | |
92 } | |
93 "Check-Symbols" { | |
94 -DSQLITE_MEMDEBUG=1 | |
95 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 | |
96 -DSQLITE_ENABLE_FTS3=1 | |
97 -DSQLITE_ENABLE_RTREE=1 | |
98 -DSQLITE_ENABLE_MEMSYS5=1 | |
99 -DSQLITE_ENABLE_MEMSYS3=1 | |
100 -DSQLITE_ENABLE_COLUMN_METADATA=1 | |
101 -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 | |
102 -DSQLITE_SECURE_DELETE=1 | |
103 -DSQLITE_SOUNDEX=1 | |
104 -DSQLITE_ENABLE_ATOMIC_WRITE=1 | |
105 -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 | |
106 -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1 | |
107 -DSQLITE_ENABLE_STAT4 | |
108 -DSQLITE_ENABLE_STMT_SCANSTATUS | |
109 --enable-json1 --enable-fts5 | |
110 } | |
111 "Debug-One" { | |
112 --disable-shared | |
113 -O2 | |
114 -DSQLITE_DEBUG=1 | |
115 -DSQLITE_MEMDEBUG=1 | |
116 -DSQLITE_MUTEX_NOOP=1 | |
117 -DSQLITE_TCL_DEFAULT_FULLMUTEX=1 | |
118 -DSQLITE_ENABLE_FTS3=1 | |
119 -DSQLITE_ENABLE_RTREE=1 | |
120 -DSQLITE_ENABLE_MEMSYS5=1 | |
121 -DSQLITE_ENABLE_MEMSYS3=1 | |
122 -DSQLITE_ENABLE_COLUMN_METADATA=1 | |
123 -DSQLITE_ENABLE_STAT4 | |
124 -DSQLITE_ENABLE_HIDDEN_COLUMNS | |
125 -DSQLITE_MAX_ATTACHED=125 | |
126 } | |
127 "Fast-One" { | |
128 -O6 | |
129 -DSQLITE_ENABLE_FTS4=1 | |
130 -DSQLITE_ENABLE_RTREE=1 | |
131 -DSQLITE_ENABLE_STAT4 | |
132 -DSQLITE_ENABLE_RBU | |
133 -DSQLITE_MAX_ATTACHED=125 | |
134 -DLONGDOUBLE_TYPE=double | |
135 } | |
136 "Device-One" { | |
137 -O2 | |
138 -DSQLITE_DEBUG=1 | |
139 -DSQLITE_DEFAULT_AUTOVACUUM=1 | |
140 -DSQLITE_DEFAULT_CACHE_SIZE=64 | |
141 -DSQLITE_DEFAULT_PAGE_SIZE=1024 | |
142 -DSQLITE_DEFAULT_TEMP_CACHE_SIZE=32 | |
143 -DSQLITE_DISABLE_LFS=1 | |
144 -DSQLITE_ENABLE_ATOMIC_WRITE=1 | |
145 -DSQLITE_ENABLE_IOTRACE=1 | |
146 -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 | |
147 -DSQLITE_MAX_PAGE_SIZE=4096 | |
148 -DSQLITE_OMIT_LOAD_EXTENSION=1 | |
149 -DSQLITE_OMIT_PROGRESS_CALLBACK=1 | |
150 -DSQLITE_OMIT_VIRTUALTABLE=1 | |
151 -DSQLITE_ENABLE_HIDDEN_COLUMNS | |
152 -DSQLITE_TEMP_STORE=3 | |
153 --enable-json1 | |
154 } | |
155 "Device-Two" { | |
156 -DSQLITE_4_BYTE_ALIGNED_MALLOC=1 | |
157 -DSQLITE_DEFAULT_AUTOVACUUM=1 | |
158 -DSQLITE_DEFAULT_CACHE_SIZE=1000 | |
159 -DSQLITE_DEFAULT_LOCKING_MODE=0 | |
160 -DSQLITE_DEFAULT_PAGE_SIZE=1024 | |
161 -DSQLITE_DEFAULT_TEMP_CACHE_SIZE=1000 | |
162 -DSQLITE_DISABLE_LFS=1 | |
163 -DSQLITE_ENABLE_FTS3=1 | |
164 -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 | |
165 -DSQLITE_ENABLE_RTREE=1 | |
166 -DSQLITE_MAX_COMPOUND_SELECT=50 | |
167 -DSQLITE_MAX_PAGE_SIZE=32768 | |
168 -DSQLITE_OMIT_TRACE=1 | |
169 -DSQLITE_TEMP_STORE=3 | |
170 -DSQLITE_THREADSAFE=2 | |
171 --enable-json1 --enable-fts5 | |
172 } | |
173 "Locking-Style" { | |
174 -O2 | |
175 -DSQLITE_ENABLE_LOCKING_STYLE=1 | |
176 } | |
177 "OS-X" { | |
178 -O1 # Avoid a compiler bug in gcc 4.2.1 build 5658 | |
179 -DSQLITE_OMIT_LOAD_EXTENSION=1 | |
180 -DSQLITE_DEFAULT_MEMSTATUS=0 | |
181 -DSQLITE_THREADSAFE=2 | |
182 -DSQLITE_OS_UNIX=1 | |
183 -DSQLITE_ENABLE_JSON1=1 | |
184 -DSQLITE_ENABLE_LOCKING_STYLE=1 | |
185 -DUSE_PREAD=1 | |
186 -DSQLITE_ENABLE_RTREE=1 | |
187 -DSQLITE_ENABLE_FTS3=1 | |
188 -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 | |
189 -DSQLITE_DEFAULT_CACHE_SIZE=1000 | |
190 -DSQLITE_MAX_LENGTH=2147483645 | |
191 -DSQLITE_MAX_VARIABLE_NUMBER=500000 | |
192 -DSQLITE_DEBUG=1 | |
193 -DSQLITE_PREFER_PROXY_LOCKING=1 | |
194 -DSQLITE_ENABLE_API_ARMOR=1 | |
195 --enable-json1 --enable-fts5 | |
196 } | |
197 "Extra-Robustness" { | |
198 -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1 | |
199 -DSQLITE_MAX_ATTACHED=62 | |
200 } | |
201 "Devkit" { | |
202 -DSQLITE_DEFAULT_FILE_FORMAT=4 | |
203 -DSQLITE_MAX_ATTACHED=30 | |
204 -DSQLITE_ENABLE_COLUMN_METADATA | |
205 -DSQLITE_ENABLE_FTS4 | |
206 -DSQLITE_ENABLE_FTS4_PARENTHESIS | |
207 -DSQLITE_DISABLE_FTS4_DEFERRED | |
208 -DSQLITE_ENABLE_RTREE | |
209 --enable-json1 --enable-fts5 | |
210 } | |
211 "No-lookaside" { | |
212 -DSQLITE_TEST_REALLOC_STRESS=1 | |
213 -DSQLITE_OMIT_LOOKASIDE=1 | |
214 -DHAVE_USLEEP=1 | |
215 } | |
216 "Valgrind" { | |
217 -DSQLITE_ENABLE_STAT4 | |
218 -DSQLITE_ENABLE_FTS4 | |
219 -DSQLITE_ENABLE_RTREE | |
220 -DSQLITE_ENABLE_HIDDEN_COLUMNS | |
221 --enable-json1 | |
222 } | |
223 | |
224 # The next group of configurations are used only by the | |
225 # Failure-Detection platform. They are all the same, but we need | |
226 # different names for them all so that they results appear in separate | |
227 # subdirectories. | |
228 # | |
229 Fail0 {-O0} | |
230 Fail2 {-O0} | |
231 Fail3 {-O0} | |
232 Fail4 {-O0} | |
233 FuzzFail1 {-O0} | |
234 FuzzFail2 {-O0} | |
235 }] | |
236 | |
237 array set ::Platforms [strip_comments { | |
238 Linux-x86_64 { | |
239 "Check-Symbols" checksymbols | |
240 "Fast-One" fuzztest | |
241 "Debug-One" "mptest test" | |
242 "Have-Not" test | |
243 "Secure-Delete" test | |
244 "Unlock-Notify" "QUICKTEST_INCLUDE=notify2.test test" | |
245 "Update-Delete-Limit" test | |
246 "Extra-Robustness" test | |
247 "Device-Two" test | |
248 "No-lookaside" test | |
249 "Devkit" test | |
250 "Sanitize" {QUICKTEST_OMIT=func4.test,nan.test test} | |
251 "Device-One" fulltest | |
252 "Default" "threadtest fulltest" | |
253 "Valgrind" valgrindtest | |
254 } | |
255 Linux-i686 { | |
256 "Devkit" test | |
257 "Have-Not" test | |
258 "Unlock-Notify" "QUICKTEST_INCLUDE=notify2.test test" | |
259 "Device-One" test | |
260 "Device-Two" test | |
261 "Default" "threadtest fulltest" | |
262 } | |
263 Darwin-i386 { | |
264 "Locking-Style" "mptest test" | |
265 "Have-Not" test | |
266 "OS-X" "threadtest fulltest" | |
267 } | |
268 Darwin-x86_64 { | |
269 "Locking-Style" "mptest test" | |
270 "Have-Not" test | |
271 "OS-X" "threadtest fulltest" | |
272 } | |
273 "Windows NT-intel" { | |
274 "Have-Not" test | |
275 "Default" "mptest fulltestonly" | |
276 } | |
277 "Windows NT-amd64" { | |
278 "Have-Not" test | |
279 "Default" "mptest fulltestonly" | |
280 } | |
281 | |
282 # The Failure-Detection platform runs various tests that deliberately | |
283 # fail. This is used as a test of this script to verify that this script | |
284 # correctly identifies failures. | |
285 # | |
286 Failure-Detection { | |
287 Fail0 "TEST_FAILURE=0 test" | |
288 Sanitize "TEST_FAILURE=1 test" | |
289 Fail2 "TEST_FAILURE=2 valgrindtest" | |
290 Fail3 "TEST_FAILURE=3 valgrindtest" | |
291 Fail4 "TEST_FAILURE=4 test" | |
292 FuzzFail1 "TEST_FAILURE=5 test" | |
293 FuzzFail2 "TEST_FAILURE=5 valgrindtest" | |
294 } | |
295 }] | |
296 | |
297 | |
298 # End of configuration section. | |
299 ######################################################################### | |
300 ######################################################################### | |
301 | |
302 # Configuration verification: Check that each entry in the list of configs | |
303 # specified for each platforms exists. | |
304 # | |
305 foreach {key value} [array get ::Platforms] { | |
306 foreach {v t} $value { | |
307 if {0==[info exists ::Configs($v)]} { | |
308 puts stderr "No such configuration: \"$v\"" | |
309 exit -1 | |
310 } | |
311 } | |
312 } | |
313 | |
314 # Output log. Disabled for slave interpreters. | |
315 # | |
316 if {[lindex $argv end]!="--slave"} { | |
317 set LOG [open releasetest-out.txt w] | |
318 proc PUTS {txt} { | |
319 puts $txt | |
320 puts $::LOG $txt | |
321 flush $::LOG | |
322 } | |
323 proc PUTSNNL {txt} { | |
324 puts -nonewline $txt | |
325 puts -nonewline $::LOG $txt | |
326 flush $::LOG | |
327 } | |
328 proc PUTSERR {txt} { | |
329 puts stderr $txt | |
330 puts $::LOG $txt | |
331 flush $::LOG | |
332 } | |
333 puts $LOG "$argv0 $argv" | |
334 set tm0 [clock format [clock seconds] -format {%Y-%m-%d %H:%M:%S} -gmt 1] | |
335 puts $LOG "start-time: $tm0 UTC" | |
336 } else { | |
337 proc PUTS {txt} { | |
338 puts $txt | |
339 } | |
340 proc PUTSNNL {txt} { | |
341 puts -nonewline $txt | |
342 } | |
343 proc PUTSERR {txt} { | |
344 puts stderr $txt | |
345 } | |
346 } | |
347 | |
348 # Open the file $logfile and look for a report on the number of errors | |
349 # and the number of test cases run. Add these values to the global | |
350 # $::NERRCASE and $::NTESTCASE variables. | |
351 # | |
352 # If any errors occur, then write into $errmsgVar the text of an appropriate | |
353 # one-line error message to show on the output. | |
354 # | |
355 proc count_tests_and_errors {logfile rcVar errmsgVar} { | |
356 if {$::DRYRUN} return | |
357 upvar 1 $rcVar rc $errmsgVar errmsg | |
358 set fd [open $logfile rb] | |
359 set seen 0 | |
360 while {![eof $fd]} { | |
361 set line [gets $fd] | |
362 if {[regexp {(\d+) errors out of (\d+) tests} $line all nerr ntest]} { | |
363 incr ::NERRCASE $nerr | |
364 incr ::NTESTCASE $ntest | |
365 set seen 1 | |
366 if {$nerr>0} { | |
367 set rc 1 | |
368 set errmsg $line | |
369 } | |
370 } | |
371 if {[regexp {runtime error: +(.*)} $line all msg]} { | |
372 # skip over "value is outside range" errors | |
373 if {[regexp {value .* is outside the range of representable} $line]} { | |
374 # noop | |
375 } else { | |
376 incr ::NERRCASE | |
377 if {$rc==0} { | |
378 set rc 1 | |
379 set errmsg $msg | |
380 } | |
381 } | |
382 } | |
383 if {[regexp {fatal error +(.*)} $line all msg]} { | |
384 incr ::NERRCASE | |
385 if {$rc==0} { | |
386 set rc 1 | |
387 set errmsg $msg | |
388 } | |
389 } | |
390 if {[regexp {ERROR SUMMARY: (\d+) errors.*} $line all cnt] && $cnt>0} { | |
391 incr ::NERRCASE | |
392 if {$rc==0} { | |
393 set rc 1 | |
394 set errmsg $all | |
395 } | |
396 } | |
397 if {[regexp {^VERSION: 3\.\d+.\d+} $line]} { | |
398 set v [string range $line 9 end] | |
399 if {$::SQLITE_VERSION eq ""} { | |
400 set ::SQLITE_VERSION $v | |
401 } elseif {$::SQLITE_VERSION ne $v} { | |
402 set rc 1 | |
403 set errmsg "version conflict: {$::SQLITE_VERSION} vs. {$v}" | |
404 } | |
405 } | |
406 } | |
407 close $fd | |
408 if {$::BUILDONLY} { | |
409 incr ::NTESTCASE | |
410 if {$rc!=0} { | |
411 set errmsg "Build failed" | |
412 } | |
413 } elseif {!$seen} { | |
414 set rc 1 | |
415 set errmsg "Test did not complete" | |
416 if {[file readable core]} { | |
417 append errmsg " - core file exists" | |
418 } | |
419 } | |
420 } | |
421 | |
422 #-------------------------------------------------------------------------- | |
423 # This command is invoked as the [main] routine for scripts run with the | |
424 # "--slave" option. | |
425 # | |
426 # For each test (i.e. "configure && make test" execution), the master | |
427 # process spawns a process with the --slave option. It writes two lines | |
428 # to the slaves stdin. The first contains a single boolean value - the | |
429 # value of ::TRACE to use in the slave script. The second line contains a | |
430 # list in the same format as each element of the list passed to the | |
431 # [run_all_test_suites] command in the master process. | |
432 # | |
433 # The slave then runs the "configure && make test" commands specified. It | |
434 # exits successfully if the tests passes, or with a non-zero error code | |
435 # otherwise. | |
436 # | |
437 proc run_slave_test {} { | |
438 # Read global vars configuration from stdin. | |
439 set V [gets stdin] | |
440 foreach {::TRACE ::MSVC ::DRYRUN} $V {} | |
441 | |
442 # Read the test-suite configuration from stdin. | |
443 set T [gets stdin] | |
444 foreach {title dir configOpts testtarget makeOpts cflags opts} $T {} | |
445 | |
446 # Create and switch to the test directory. | |
447 set ::env(SQLITE_TMPDIR) [file normalize $dir] | |
448 trace_cmd file mkdir $dir | |
449 trace_cmd cd $dir | |
450 catch {file delete core} | |
451 catch {file delete test.log} | |
452 | |
453 # Run the "./configure && make" commands. | |
454 set rc 0 | |
455 set rc [catch [configureCommand $configOpts]] | |
456 if {!$rc} { | |
457 if {[info exists ::env(TCLSH_CMD)]} { | |
458 set savedEnv(TCLSH_CMD) $::env(TCLSH_CMD) | |
459 } else { | |
460 unset -nocomplain savedEnv(TCLSH_CMD) | |
461 } | |
462 set ::env(TCLSH_CMD) [file nativename [info nameofexecutable]] | |
463 set rc [catch [makeCommand $testtarget $makeOpts $cflags $opts]] | |
464 if {[info exists savedEnv(TCLSH_CMD)]} { | |
465 set ::env(TCLSH_CMD) $savedEnv(TCLSH_CMD) | |
466 } else { | |
467 unset -nocomplain ::env(TCLSH_CMD) | |
468 } | |
469 } | |
470 | |
471 # Exis successfully if the test passed, or with a non-zero error code | |
472 # otherwise. | |
473 exit $rc | |
474 } | |
475 | |
476 # This command is invoked in the master process each time a slave | |
477 # file-descriptor is readable. | |
478 # | |
479 proc slave_fileevent {fd T tm1} { | |
480 global G | |
481 foreach {title dir configOpts testtarget makeOpts cflags opts} $T {} | |
482 | |
483 if {[eof $fd]} { | |
484 fconfigure $fd -blocking 1 | |
485 set rc [catch { close $fd }] | |
486 | |
487 set errmsg {} | |
488 set logfile [file join $dir test.log] | |
489 if {[file exists $logfile]} { | |
490 count_tests_and_errors [file join $dir test.log] rc errmsg | |
491 } elseif {$rc==0 && !$::DRYRUN} { | |
492 set rc 1 | |
493 set errmsg "no test.log file..." | |
494 } | |
495 | |
496 if {!$::TRACE} { | |
497 set tm2 [clock seconds] | |
498 set hours [expr {($tm2-$tm1)/3600}] | |
499 set minutes [expr {(($tm2-$tm1)/60)%60}] | |
500 set seconds [expr {($tm2-$tm1)%60}] | |
501 set tm [format (%02d:%02d:%02d) $hours $minutes $seconds] | |
502 | |
503 if {$rc} { | |
504 set status FAIL | |
505 incr ::NERR | |
506 } else { | |
507 set status Ok | |
508 } | |
509 | |
510 set n [string length $title] | |
511 if {$::PROGRESS_MSGS} { | |
512 PUTS "finished: ${title}[string repeat . [expr {53-$n}]] $status $tm" | |
513 } else { | |
514 PUTS "${title}[string repeat . [expr {63-$n}]] $status $tm" | |
515 } | |
516 if {$errmsg!=""} {PUTS " $errmsg"} | |
517 flush stdout | |
518 } | |
519 | |
520 incr G(nJob) -1 | |
521 } else { | |
522 set line [gets $fd] | |
523 if {[string trim $line] != ""} { | |
524 puts "Trace : $title - \"$line\"" | |
525 } | |
526 } | |
527 } | |
528 | |
529 #-------------------------------------------------------------------------- | |
530 # The only argument passed to this function is a list of test-suites to | |
531 # run. Each "test-suite" is itself a list consisting of the following | |
532 # elements: | |
533 # | |
534 # * Test title (for display). | |
535 # * The name of the directory to run the test in. | |
536 # * The argument for [configureCommand] | |
537 # * The first argument for [makeCommand] | |
538 # * The second argument for [makeCommand] | |
539 # * The third argument for [makeCommand] | |
540 # | |
541 proc run_all_test_suites {alltests} { | |
542 global G | |
543 set tests $alltests | |
544 | |
545 set G(nJob) 0 | |
546 | |
547 while {[llength $tests]>0 || $G(nJob)>0} { | |
548 if {$G(nJob)>=$::JOBS || [llength $tests]==0} { | |
549 vwait G(nJob) | |
550 } | |
551 | |
552 if {[llength $tests]>0} { | |
553 set T [lindex $tests 0] | |
554 set tests [lrange $tests 1 end] | |
555 foreach {title dir configOpts testtarget makeOpts cflags opts} $T {} | |
556 if {$::PROGRESS_MSGS && !$::TRACE} { | |
557 set n [string length $title] | |
558 PUTS "starting: ${title} at [now]" | |
559 flush stdout | |
560 } | |
561 | |
562 # Run the job. | |
563 # | |
564 set tm1 [clock seconds] | |
565 incr G(nJob) | |
566 set script [file normalize [info script]] | |
567 set fd [open "|[info nameofexecutable] $script --slave" r+] | |
568 fconfigure $fd -blocking 0 | |
569 fileevent $fd readable [list slave_fileevent $fd $T $tm1] | |
570 puts $fd [list $::TRACE $::MSVC $::DRYRUN] | |
571 puts $fd [list {*}$T] | |
572 flush $fd | |
573 } | |
574 } | |
575 } | |
576 | |
577 proc add_test_suite {listvar name testtarget config} { | |
578 upvar $listvar alltests | |
579 | |
580 # Tcl variable $opts is used to build up the value used to set the | |
581 # OPTS Makefile variable. Variable $cflags holds the value for | |
582 # CFLAGS. The makefile will pass OPTS to both gcc and lemon, but | |
583 # CFLAGS is only passed to gcc. | |
584 # | |
585 set makeOpts "" | |
586 set cflags [expr {$::MSVC ? "-Zi" : "-g"}] | |
587 set opts "" | |
588 set title ${name}($testtarget) | |
589 set configOpts $::WITHTCL | |
590 | |
591 regsub -all {#[^\n]*\n} $config \n config | |
592 foreach arg $config { | |
593 if {[regexp {^-[UD]} $arg]} { | |
594 lappend opts $arg | |
595 } elseif {[regexp {^[A-Z]+=} $arg]} { | |
596 lappend testtarget $arg | |
597 } elseif {[regexp {^--(enable|disable)-} $arg]} { | |
598 if {$::MSVC} { | |
599 if {$arg eq "--disable-amalgamation"} { | |
600 lappend makeOpts USE_AMALGAMATION=0 | |
601 continue | |
602 } | |
603 if {$arg eq "--disable-shared"} { | |
604 lappend makeOpts USE_CRT_DLL=0 DYNAMIC_SHELL=0 | |
605 continue | |
606 } | |
607 if {$arg eq "--enable-fts5"} { | |
608 lappend opts -DSQLITE_ENABLE_FTS5 | |
609 continue | |
610 } | |
611 if {$arg eq "--enable-json1"} { | |
612 lappend opts -DSQLITE_ENABLE_JSON1 | |
613 continue | |
614 } | |
615 if {$arg eq "--enable-shared"} { | |
616 lappend makeOpts USE_CRT_DLL=1 DYNAMIC_SHELL=1 | |
617 continue | |
618 } | |
619 } | |
620 lappend configOpts $arg | |
621 } else { | |
622 if {$::MSVC} { | |
623 if {$arg eq "-g"} { | |
624 lappend cflags -Zi | |
625 continue | |
626 } | |
627 if {[regexp -- {^-O(\d+)$} $arg all level]} then { | |
628 lappend makeOpts OPTIMIZATIONS=$level | |
629 continue | |
630 } | |
631 } | |
632 lappend cflags $arg | |
633 } | |
634 } | |
635 | |
636 # Disable sync to make testing faster. | |
637 # | |
638 lappend opts -DSQLITE_NO_SYNC=1 | |
639 | |
640 # Some configurations already set HAVE_USLEEP; in that case, skip it. | |
641 # | |
642 if {[lsearch -regexp $opts {^-DHAVE_USLEEP(?:=|$)}]==-1} { | |
643 lappend opts -DHAVE_USLEEP=1 | |
644 } | |
645 | |
646 # Add the define for this platform. | |
647 # | |
648 if {$::tcl_platform(platform)=="windows"} { | |
649 lappend opts -DSQLITE_OS_WIN=1 | |
650 } else { | |
651 lappend opts -DSQLITE_OS_UNIX=1 | |
652 } | |
653 | |
654 # Set the sub-directory to use. | |
655 # | |
656 set dir [string tolower [string map {- _ " " _} $name]] | |
657 | |
658 # Join option lists into strings, using space as delimiter. | |
659 # | |
660 set makeOpts [join $makeOpts " "] | |
661 set cflags [join $cflags " "] | |
662 set opts [join $opts " "] | |
663 | |
664 lappend alltests [list \ | |
665 $title $dir $configOpts $testtarget $makeOpts $cflags $opts] | |
666 } | |
667 | |
668 # The following procedure returns the "configure" command to be exectued for | |
669 # the current platform, which may be Windows (via MinGW, etc). | |
670 # | |
671 proc configureCommand {opts} { | |
672 if {$::MSVC} return [list]; # This is not needed for MSVC. | |
673 set result [list trace_cmd exec] | |
674 if {$::tcl_platform(platform)=="windows"} { | |
675 lappend result sh | |
676 } | |
677 lappend result $::SRCDIR/configure --enable-load-extension | |
678 foreach x $opts {lappend result $x} | |
679 lappend result >& test.log | |
680 } | |
681 | |
682 # The following procedure returns the "make" command to be executed for the | |
683 # specified targets, compiler flags, and options. | |
684 # | |
685 proc makeCommand { targets makeOpts cflags opts } { | |
686 set result [list trace_cmd exec] | |
687 if {$::MSVC} { | |
688 set nmakeDir [file nativename $::SRCDIR] | |
689 set nmakeFile [file nativename [file join $nmakeDir Makefile.msc]] | |
690 lappend result nmake /f $nmakeFile TOP=$nmakeDir | |
691 } else { | |
692 lappend result make | |
693 } | |
694 foreach makeOpt $makeOpts { | |
695 lappend result $makeOpt | |
696 } | |
697 lappend result clean | |
698 foreach target $targets { | |
699 lappend result $target | |
700 } | |
701 lappend result CFLAGS=$cflags OPTS=$opts >>& test.log | |
702 } | |
703 | |
704 # The following procedure prints its arguments if ::TRACE is true. | |
705 # And it executes the command of its arguments in the calling context | |
706 # if ::DRYRUN is false. | |
707 # | |
708 proc trace_cmd {args} { | |
709 if {$::TRACE} { | |
710 PUTS $args | |
711 } | |
712 set res "" | |
713 if {!$::DRYRUN} { | |
714 set res [uplevel 1 $args] | |
715 } | |
716 return $res | |
717 } | |
718 | |
719 | |
720 # This proc processes the command line options passed to this script. | |
721 # Currently the only option supported is "-makefile", default | |
722 # "releasetest.mk". Set the ::MAKEFILE variable to the value of this | |
723 # option. | |
724 # | |
725 proc process_options {argv} { | |
726 set ::SRCDIR [file normalize [file dirname [file dirname $::argv0]]] | |
727 set ::QUICK 0 | |
728 set ::MSVC 0 | |
729 set ::BUILDONLY 0 | |
730 set ::DRYRUN 0 | |
731 set ::TRACE 0 | |
732 set ::JOBS 1 | |
733 set ::PROGRESS_MSGS 0 | |
734 set ::WITHTCL {} | |
735 set config {} | |
736 set platform $::tcl_platform(os)-$::tcl_platform(machine) | |
737 | |
738 for {set i 0} {$i < [llength $argv]} {incr i} { | |
739 set x [lindex $argv $i] | |
740 if {[regexp {^--[a-z]} $x]} {set x [string range $x 1 end]} | |
741 switch -glob -- $x { | |
742 -slave { | |
743 run_slave_test | |
744 exit | |
745 } | |
746 | |
747 -srcdir { | |
748 incr i | |
749 set ::SRCDIR [file normalize [lindex $argv $i]] | |
750 } | |
751 | |
752 -platform { | |
753 incr i | |
754 set platform [lindex $argv $i] | |
755 } | |
756 | |
757 -jobs { | |
758 incr i | |
759 set ::JOBS [lindex $argv $i] | |
760 } | |
761 | |
762 -progress { | |
763 set ::PROGRESS_MSGS 1 | |
764 } | |
765 | |
766 -quick { | |
767 set ::QUICK 1 | |
768 } | |
769 -veryquick { | |
770 set ::QUICK 2 | |
771 } | |
772 | |
773 -config { | |
774 incr i | |
775 set config [lindex $argv $i] | |
776 } | |
777 | |
778 -msvc { | |
779 set ::MSVC 1 | |
780 } | |
781 | |
782 -buildonly { | |
783 set ::BUILDONLY 1 | |
784 } | |
785 | |
786 -dryrun { | |
787 set ::DRYRUN 1 | |
788 } | |
789 | |
790 -trace { | |
791 set ::TRACE 1 | |
792 } | |
793 | |
794 -info { | |
795 PUTS "Command-line Options:" | |
796 PUTS " --srcdir $::SRCDIR" | |
797 PUTS " --platform [list $platform]" | |
798 PUTS " --config [list $config]" | |
799 if {$::QUICK} { | |
800 if {$::QUICK==1} {PUTS " --quick"} | |
801 if {$::QUICK==2} {PUTS " --veryquick"} | |
802 } | |
803 if {$::MSVC} {PUTS " --msvc"} | |
804 if {$::BUILDONLY} {PUTS " --buildonly"} | |
805 if {$::DRYRUN} {PUTS " --dryrun"} | |
806 if {$::TRACE} {PUTS " --trace"} | |
807 PUTS "\nAvailable --platform options:" | |
808 foreach y [lsort [array names ::Platforms]] { | |
809 PUTS " [list $y]" | |
810 } | |
811 PUTS "\nAvailable --config options:" | |
812 foreach y [lsort [array names ::Configs]] { | |
813 PUTS " [list $y]" | |
814 } | |
815 exit | |
816 } | |
817 | |
818 -g { | |
819 lappend ::EXTRACONFIG [lindex $argv $i] | |
820 } | |
821 | |
822 -with-tcl=* { | |
823 set ::WITHTCL -$x | |
824 } | |
825 | |
826 -D* - | |
827 -O* - | |
828 -enable-* - | |
829 -disable-* - | |
830 *=* { | |
831 lappend ::EXTRACONFIG [lindex $argv $i] | |
832 } | |
833 | |
834 default { | |
835 PUTSERR "" | |
836 PUTSERR [string trim $::USAGE_MESSAGE] | |
837 exit -1 | |
838 } | |
839 } | |
840 } | |
841 | |
842 if {0==[info exists ::Platforms($platform)]} { | |
843 PUTS "Unknown platform: $platform" | |
844 PUTSNNL "Set the -platform option to " | |
845 set print [list] | |
846 foreach p [array names ::Platforms] { | |
847 lappend print "\"$p\"" | |
848 } | |
849 lset print end "or [lindex $print end]" | |
850 PUTS "[join $print {, }]." | |
851 exit | |
852 } | |
853 | |
854 if {$config!=""} { | |
855 if {[llength $config]==1} {lappend config fulltest} | |
856 set ::CONFIGLIST $config | |
857 } else { | |
858 if {$::JOBS>1} { | |
859 set ::CONFIGLIST {} | |
860 foreach {target zConfig} [lreverse $::Platforms($platform)] { | |
861 append ::CONFIGLIST [format " %-25s %s\n" \ | |
862 [list $zConfig] [list $target]] | |
863 } | |
864 } else { | |
865 set ::CONFIGLIST $::Platforms($platform) | |
866 } | |
867 } | |
868 PUTS "Running the following test configurations for $platform:" | |
869 PUTS " [string trim $::CONFIGLIST]" | |
870 PUTSNNL "Flags:" | |
871 if {$::PROGRESS_MSGS} {PUTSNNL " --progress"} | |
872 if {$::DRYRUN} {PUTSNNL " --dryrun"} | |
873 if {$::BUILDONLY} {PUTSNNL " --buildonly"} | |
874 if {$::MSVC} {PUTSNNL " --msvc"} | |
875 switch -- $::QUICK { | |
876 1 {PUTSNNL " --quick"} | |
877 2 {PUTSNNL " --veryquick"} | |
878 } | |
879 if {$::JOBS>1} {PUTSNNL " --jobs $::JOBS"} | |
880 PUTS "" | |
881 } | |
882 | |
883 # Main routine. | |
884 # | |
885 proc main {argv} { | |
886 | |
887 # Process any command line options. | |
888 set ::EXTRACONFIG {} | |
889 process_options $argv | |
890 PUTS [string repeat * 79] | |
891 | |
892 set ::NERR 0 | |
893 set ::NTEST 0 | |
894 set ::NTESTCASE 0 | |
895 set ::NERRCASE 0 | |
896 set ::SQLITE_VERSION {} | |
897 set STARTTIME [clock seconds] | |
898 foreach {zConfig target} $::CONFIGLIST { | |
899 if {$::MSVC && ($zConfig eq "Sanitize" || "checksymbols" in $target | |
900 || "valgrindtest" in $target)} { | |
901 PUTS "Skipping $zConfig / $target for MSVC..." | |
902 continue | |
903 } | |
904 if {$target ne "checksymbols"} { | |
905 switch -- $::QUICK { | |
906 1 {set target quicktest} | |
907 2 {set target smoketest} | |
908 } | |
909 if {$::BUILDONLY} { | |
910 set target testfixture | |
911 if {$::tcl_platform(platform)=="windows"} { | |
912 append target .exe | |
913 } | |
914 } | |
915 } | |
916 set config_options [concat $::Configs($zConfig) $::EXTRACONFIG] | |
917 | |
918 incr NTEST | |
919 add_test_suite all $zConfig $target $config_options | |
920 | |
921 # If the configuration included the SQLITE_DEBUG option, then remove | |
922 # it and run veryquick.test. If it did not include the SQLITE_DEBUG option | |
923 # add it and run veryquick.test. | |
924 if {$target!="checksymbols" && $target!="valgrindtest" | |
925 && $target!="fuzzoomtest" && !$::BUILDONLY && $::QUICK<2} { | |
926 set debug_idx [lsearch -glob $config_options -DSQLITE_DEBUG*] | |
927 set xtarget $target | |
928 regsub -all {fulltest[a-z]*} $xtarget test xtarget | |
929 regsub -all {fuzzoomtest} $xtarget fuzztest xtarget | |
930 if {$debug_idx < 0} { | |
931 incr NTEST | |
932 append config_options " -DSQLITE_DEBUG=1" | |
933 add_test_suite all "${zConfig}_debug" $xtarget $config_options | |
934 } else { | |
935 incr NTEST | |
936 regsub { *-DSQLITE_MEMDEBUG[^ ]* *} $config_options { } config_options | |
937 regsub { *-DSQLITE_DEBUG[^ ]* *} $config_options { } config_options | |
938 add_test_suite all "${zConfig}_ndebug" $xtarget $config_options | |
939 } | |
940 } | |
941 } | |
942 | |
943 run_all_test_suites $all | |
944 | |
945 set elapsetime [expr {[clock seconds]-$STARTTIME}] | |
946 set hr [expr {$elapsetime/3600}] | |
947 set min [expr {($elapsetime/60)%60}] | |
948 set sec [expr {$elapsetime%60}] | |
949 set etime [format (%02d:%02d:%02d) $hr $min $sec] | |
950 if {$::JOBS>1} {append etime " $::JOBS cores"} | |
951 if {[catch {exec hostname} HNAME]==0} {append etime " on $HNAME"} | |
952 PUTS [string repeat * 79] | |
953 incr ::NERRCASE $::NERR | |
954 PUTS "$::NERRCASE failures out of $::NTESTCASE tests in $etime" | |
955 if {$::SQLITE_VERSION ne ""} { | |
956 PUTS "SQLite $::SQLITE_VERSION" | |
957 } | |
958 } | |
959 | |
960 main $argv | |
OLD | NEW |