1#!/bin/sh 2# \ 3exec wapptclsh "$0" ${1+"$@"} 4 5# package required wapp 6source [file join [file dirname [info script]] wapp.tcl] 7 8# Variables set by the "control" form: 9# 10# G(platform) - User selected platform. 11# G(cfgglob) - Glob pattern that all configurations must match 12# G(test) - Set to "Normal", "Veryquick", "Smoketest" or "Build-Only". 13# G(keep) - Boolean. True to delete no files after each test. 14# G(msvc) - Boolean. True to use MSVC as the compiler. 15# G(tcl) - Use Tcl from this directory for builds. 16# G(jobs) - How many sub-processes to run simultaneously. 17# 18set G(platform) $::tcl_platform(os)-$::tcl_platform(machine) 19set G(cfgglob) * 20set G(test) Normal 21set G(keep) 1 22set G(msvc) 0 23set G(tcl) [::tcl::pkgconfig get libdir,install] 24set G(jobs) 3 25set G(debug) 0 26 27set G(noui) 0 28set G(stdout) 0 29 30 31proc wapptest_init {} { 32 global G 33 34 set lSave [list platform test keep msvc tcl jobs debug noui stdout cfgglob] 35 foreach k $lSave { set A($k) $G($k) } 36 array unset G 37 foreach k $lSave { set G($k) $A($k) } 38 39 # The root of the SQLite source tree. 40 set G(srcdir) [file dirname [file dirname [info script]]] 41 42 set G(sqlite_version) "unknown" 43 44 # Either "config", "running" or "stopped": 45 set G(state) "config" 46 47 set G(hostname) "(unknown host)" 48 catch { set G(hostname) [exec hostname] } 49 set G(host) $G(hostname) 50 append G(host) " $::tcl_platform(os) $::tcl_platform(osVersion)" 51 append G(host) " $::tcl_platform(machine) $::tcl_platform(byteOrder)" 52} 53 54proc wapptest_run {} { 55 global G 56 set_test_array 57 set G(state) "running" 58 59 wapptest_openlog 60 61 wapptest_output "Running the following for $G(platform). $G(jobs) jobs." 62 foreach t $G(test_array) { 63 set config [dict get $t config] 64 set target [dict get $t target] 65 wapptest_output [format " %-25s%s" $config $target] 66 } 67 wapptest_output [string repeat * 70] 68} 69 70proc releasetest_data {args} { 71 global G 72 set rtd [file join $G(srcdir) test releasetest_data.tcl] 73 set fd [open "|[info nameofexecutable] $rtd $args" r+] 74 set ret [read $fd] 75 close $fd 76 return $ret 77} 78 79# Generate the text for the box at the top of the UI. The current SQLite 80# version, according to fossil, along with a warning if there are 81# uncommitted changes in the checkout. 82# 83proc generate_fossil_info {} { 84 global G 85 set pwd [pwd] 86 cd $G(srcdir) 87 set rc [catch { 88 set r1 [exec fossil info] 89 set r2 [exec fossil changes] 90 }] 91 cd $pwd 92 if {$rc} return 93 94 foreach line [split $r1 "\n"] { 95 if {[regexp {^checkout: *(.*)$} $line -> co]} { 96 wapp-trim { <br> %html($co) } 97 } 98 } 99 100 if {[string trim $r2]!=""} { 101 wapp-trim { 102 <br><span class=warning> 103 WARNING: Uncommitted changes in checkout 104 </span> 105 } 106 } 107} 108 109# If the application is in "config" state, set the contents of the 110# ::G(test_array) global to reflect the tests that will be run. If the 111# app is in some other state ("running" or "stopped"), this command 112# is a no-op. 113# 114proc set_test_array {} { 115 global G 116 if { $G(state)=="config" } { 117 set G(test_array) [list] 118 set debug "-debug" 119 if {$G(debug)==0} { set debug "-nodebug"} 120 foreach {config target} [releasetest_data tests $debug $G(platform)] { 121 122 # All configuration names must match $g(cfgglob), which defaults to * 123 # 124 if {![string match -nocase $G(cfgglob) $config]} continue 125 126 # If using MSVC, do not run sanitize or valgrind tests. Or the 127 # checksymbols test. 128 if {$G(msvc) && ( 129 "Sanitize" == $config 130 || "checksymbols" in $target 131 || "valgrindtest" in $target 132 )} { 133 continue 134 } 135 136 # If the test mode is not "Normal", override the target. 137 # 138 if {$target!="checksymbols" && $G(platform)!="Failure-Detection"} { 139 switch -- $G(test) { 140 Veryquick { set target quicktest } 141 Smoketest { set target smoketest } 142 Build-Only { 143 set target testfixture 144 if {$::tcl_platform(platform)=="windows"} { 145 set target testfixture.exe 146 } 147 } 148 } 149 } 150 151 lappend G(test_array) [dict create config $config target $target] 152 } 153 } 154} 155 156proc count_tests_and_errors {name logfile} { 157 global G 158 159 set fd [open $logfile rb] 160 set seen 0 161 while {![eof $fd]} { 162 set line [gets $fd] 163 if {[regexp {(\d+) errors out of (\d+) tests} $line all nerr ntest]} { 164 incr G(test.$name.nError) $nerr 165 incr G(test.$name.nTest) $ntest 166 set seen 1 167 if {$nerr>0} { 168 set G(test.$name.errmsg) $line 169 } 170 } 171 if {[regexp {runtime error: +(.*)} $line all msg]} { 172 # skip over "value is outside range" errors 173 if {[regexp {.* is outside the range of representable} $line]} { 174 # noop 175 } else { 176 incr G(test.$name.nError) 177 if {$G(test.$name.errmsg)==""} { 178 set G(test.$name.errmsg) $msg 179 } 180 } 181 } 182 if {[regexp {fatal error +(.*)} $line all msg]} { 183 incr G(test.$name.nError) 184 if {$G(test.$name.errmsg)==""} { 185 set G(test.$name.errmsg) $msg 186 } 187 } 188 if {[regexp {ERROR SUMMARY: (\d+) errors.*} $line all cnt] && $cnt>0} { 189 incr G(test.$name.nError) 190 if {$G(test.$name.errmsg)==""} { 191 set G(test.$name.errmsg) $all 192 } 193 } 194 if {[regexp {^VERSION: 3\.\d+.\d+} $line]} { 195 set v [string range $line 9 end] 196 if {$G(sqlite_version) eq "unknown"} { 197 set G(sqlite_version) $v 198 } elseif {$G(sqlite_version) ne $v} { 199 set G(test.$name.errmsg) "version conflict: {$G(sqlite_version)} vs. {$v}" 200 } 201 } 202 } 203 close $fd 204 if {$G(test) == "Build-Only"} { 205 incr G(test.$name.nTest) 206 if {$G(test.$name.nError)>0} { 207 set errmsg "Build failed" 208 } 209 } elseif {!$seen} { 210 set G(test.$name.errmsg) "Test did not complete" 211 if {[file readable core]} { 212 append G(test.$name.errmsg) " - core file exists" 213 } 214 } 215} 216 217proc wapptest_output {str} { 218 global G 219 if {$G(stdout)} { puts $str } 220 if {[info exists G(log)]} { 221 puts $G(log) $str 222 flush $G(log) 223 } 224} 225proc wapptest_openlog {} { 226 global G 227 set G(log) [open wapptest-out.txt w+] 228} 229proc wapptest_closelog {} { 230 global G 231 close $G(log) 232 unset G(log) 233} 234 235proc format_seconds {seconds} { 236 set min [format %.2d [expr ($seconds / 60) % 60]] 237 set hr [format %.2d [expr $seconds / 3600]] 238 set sec [format %.2d [expr $seconds % 60]] 239 return "$hr:$min:$sec" 240} 241 242# This command is invoked once a slave process has finished running its 243# tests, successfully or otherwise. Parameter $name is the name of the 244# test, $rc the exit code returned by the slave process. 245# 246proc slave_test_done {name rc} { 247 global G 248 set G(test.$name.done) [clock seconds] 249 set G(test.$name.nError) 0 250 set G(test.$name.nTest) 0 251 set G(test.$name.errmsg) "" 252 if {$rc} { 253 incr G(test.$name.nError) 254 } 255 if {[file exists $G(test.$name.log)]} { 256 count_tests_and_errors $name $G(test.$name.log) 257 } 258 259 # If the "keep files" checkbox is clear, delete all files except for 260 # the executables and test logs. And any core file that is present. 261 if {$G(keep)==0} { 262 set keeplist { 263 testfixture testfixture.exe 264 sqlite3 sqlite3.exe 265 test.log test-out.txt 266 core 267 wapptest_make.sh 268 wapptest_configure.sh 269 wapptest_run.tcl 270 } 271 foreach f [glob -nocomplain [file join $G(test.$name.dir) *]] { 272 set t [file tail $f] 273 if {[lsearch $keeplist $t]<0} { 274 catch { file delete -force $f } 275 } 276 } 277 } 278 279 # Format a message regarding the success or failure of hte test. 280 set t [format_seconds [expr $G(test.$name.done) - $G(test.$name.start)]] 281 set res "OK" 282 if {$G(test.$name.nError)} { set res "FAILED" } 283 set dots [string repeat . [expr 60 - [string length $name]]] 284 set msg "$name $dots $res ($t)" 285 286 wapptest_output $msg 287 if {[info exists G(test.$name.errmsg)] && $G(test.$name.errmsg)!=""} { 288 wapptest_output " $G(test.$name.errmsg)" 289 } 290} 291 292# This is a fileevent callback invoked each time a file-descriptor that 293# connects this process to a slave process is readable. 294# 295proc slave_fileevent {name} { 296 global G 297 set fd $G(test.$name.channel) 298 299 if {[eof $fd]} { 300 fconfigure $fd -blocking 1 301 set rc [catch { close $fd }] 302 unset G(test.$name.channel) 303 slave_test_done $name $rc 304 } else { 305 set line [gets $fd] 306 if {[string trim $line] != ""} { puts "Trace : $name - \"$line\"" } 307 } 308 309 do_some_stuff 310} 311 312# Return the contents of the "slave script" - the script run by slave 313# processes to actually perform the test. All it does is execute the 314# test script already written to disk (wapptest_cmd.sh or wapptest_cmd.bat). 315# 316proc wapptest_slave_script {} { 317 global G 318 if {$G(msvc)==0} { 319 set dir [file join .. $G(srcdir)] 320 set res [subst -nocommands { 321 set rc [catch "exec sh wapptest_cmd.sh {$dir} >>& test.log" ] 322 exit [set rc] 323 }] 324 } else { 325 set dir [file nativename [file normalize $G(srcdir)]] 326 set dir [string map [list "\\" "\\\\"] $dir] 327 set res [subst -nocommands { 328 set rc [catch "exec wapptest_cmd.bat {$dir} >>& test.log" ] 329 exit [set rc] 330 }] 331 } 332 333 set res 334} 335 336 337# Launch a slave process to run a test. 338# 339proc slave_launch {name target dir} { 340 global G 341 342 catch { file mkdir $dir } msg 343 foreach f [glob -nocomplain [file join $dir *]] { 344 catch { file delete -force $f } 345 } 346 set G(test.$name.dir) $dir 347 348 # Write the test command to wapptest_cmd.sh|bat. 349 # 350 set ext sh 351 if {$G(msvc)} { set ext bat } 352 set fd1 [open [file join $dir wapptest_cmd.$ext] w] 353 if {$G(msvc)} { 354 puts $fd1 [releasetest_data script -msvc $name $target] 355 } else { 356 puts $fd1 [releasetest_data script $name $target] 357 } 358 close $fd1 359 360 # Write the wapptest_run.tcl script to the test directory. To run the 361 # commands in the other two files. 362 # 363 set fd3 [open [file join $dir wapptest_run.tcl] w] 364 puts $fd3 [wapptest_slave_script] 365 close $fd3 366 367 set pwd [pwd] 368 cd $dir 369 set fd [open "|[info nameofexecutable] wapptest_run.tcl" r+] 370 cd $pwd 371 372 set G(test.$name.channel) $fd 373 fconfigure $fd -blocking 0 374 fileevent $fd readable [list slave_fileevent $name] 375} 376 377proc do_some_stuff {} { 378 global G 379 380 # Count the number of running jobs. A running job has an entry named 381 # "channel" in its dictionary. 382 set nRunning 0 383 set bFinished 1 384 foreach j $G(test_array) { 385 set name [dict get $j config] 386 if { [info exists G(test.$name.channel)]} { incr nRunning } 387 if {![info exists G(test.$name.done)]} { set bFinished 0 } 388 } 389 390 if {$bFinished} { 391 set nError 0 392 set nTest 0 393 set nConfig 0 394 foreach j $G(test_array) { 395 set name [dict get $j config] 396 incr nError $G(test.$name.nError) 397 incr nTest $G(test.$name.nTest) 398 incr nConfig 399 } 400 set G(result) "$nError errors from $nTest tests in $nConfig configurations." 401 wapptest_output [string repeat * 70] 402 wapptest_output $G(result) 403 catch { 404 append G(result) " SQLite version $G(sqlite_version)" 405 wapptest_output " SQLite version $G(sqlite_version)" 406 } 407 set G(state) "stopped" 408 wapptest_closelog 409 if {$G(noui)} { exit 0 } 410 } else { 411 set nLaunch [expr $G(jobs) - $nRunning] 412 foreach j $G(test_array) { 413 if {$nLaunch<=0} break 414 set name [dict get $j config] 415 if { ![info exists G(test.$name.channel)] 416 && ![info exists G(test.$name.done)] 417 } { 418 419 set target [dict get $j target] 420 set dir [string tolower [string map {" " _ "-" _} $name]] 421 set G(test.$name.start) [clock seconds] 422 set G(test.$name.log) [file join $dir test.log] 423 424 slave_launch $name $target $dir 425 426 incr nLaunch -1 427 } 428 } 429 } 430} 431 432proc generate_select_widget {label id lOpt opt} { 433 wapp-trim { 434 <label> %string($label) </label> 435 <select id=%string($id) name=%string($id)> 436 } 437 foreach o $lOpt { 438 set selected "" 439 if {$o==$opt} { set selected " selected=1" } 440 wapp-subst "<option $selected>$o</option>" 441 } 442 wapp-trim { </select> } 443} 444 445proc generate_main_page {{extra {}}} { 446 global G 447 set_test_array 448 449 set hostname $G(hostname) 450 wapp-trim { 451 <html> 452 <head> 453 <title> %html($hostname): wapptest.tcl </title> 454 <link rel="stylesheet" type="text/css" href="style.css"/> 455 </head> 456 <body> 457 } 458 459 set host $G(host) 460 wapp-trim { 461 <div class="border">%string($host) 462 } 463 generate_fossil_info 464 wapp-trim { 465 </div> 466 <div class="border" id=controls> 467 <form action="control" method="post" name="control"> 468 } 469 470 # Build the "platform" select widget. 471 set lOpt [releasetest_data platforms] 472 generate_select_widget Platform control_platform $lOpt $G(platform) 473 474 # Build the "test" select widget. 475 set lOpt [list Normal Veryquick Smoketest Build-Only] 476 generate_select_widget Test control_test $lOpt $G(test) 477 478 # Build the "jobs" select widget. Options are 1 to 8. 479 generate_select_widget Jobs control_jobs {1 2 3 4 5 6 7 8 12 16} $G(jobs) 480 481 switch $G(state) { 482 config { 483 set txt "Run Tests!" 484 set id control_run 485 } 486 running { 487 set txt "STOP Tests!" 488 set id control_stop 489 } 490 stopped { 491 set txt "Reset!" 492 set id control_reset 493 } 494 } 495 wapp-trim { 496 <div class=right> 497 <input id=%string($id) name=%string($id) type=submit value="%string($txt)"> 498 </input> 499 </div> 500 } 501 502 wapp-trim { 503 <br><br> 504 <label> Tcl: </label> 505 <input id="control_tcl" name="control_tcl"></input> 506 <label> Keep files: </label> 507 <input id="control_keep" name="control_keep" type=checkbox value=1> 508 </input> 509 <label> Use MSVC: </label> 510 <input id="control_msvc" name="control_msvc" type=checkbox value=1> 511 <label> Debug tests: </label> 512 <input id="control_debug" name="control_debug" type=checkbox value=1> 513 </input> 514 } 515 wapp-trim { 516 </form> 517 } 518 wapp-trim { 519 </div> 520 <div id=tests> 521 } 522 wapp-page-tests 523 524 set script "script/$G(state).js" 525 wapp-trim { 526 </div> 527 <script src=%string($script)></script> 528 </body> 529 </html> 530 } 531} 532 533proc wapp-default {} { 534 generate_main_page 535} 536 537proc wapp-page-tests {} { 538 global G 539 wapp-trim { <table class="border" width=100%> } 540 foreach t $G(test_array) { 541 set config [dict get $t config] 542 set target [dict get $t target] 543 544 set class "testwait" 545 set seconds "" 546 547 if {[info exists G(test.$config.log)]} { 548 if {[info exists G(test.$config.channel)]} { 549 set class "testrunning" 550 set seconds [expr [clock seconds] - $G(test.$config.start)] 551 } elseif {[info exists G(test.$config.done)]} { 552 if {$G(test.$config.nError)>0} { 553 set class "testfail" 554 } else { 555 set class "testdone" 556 } 557 set seconds [expr $G(test.$config.done) - $G(test.$config.start)] 558 } 559 set seconds [format_seconds $seconds] 560 } 561 562 wapp-trim { 563 <tr class=%string($class)> 564 <td class="nowrap"> %html($config) 565 <td class="padleft nowrap"> %html($target) 566 <td class="padleft nowrap"> %html($seconds) 567 <td class="padleft nowrap"> 568 } 569 if {[info exists G(test.$config.log)]} { 570 set log $G(test.$config.log) 571 set uri "log/$log" 572 wapp-trim { 573 <a href=%url($uri)> %html($log) </a> 574 } 575 } 576 if {[info exists G(test.$config.errmsg)] && $G(test.$config.errmsg)!=""} { 577 set errmsg $G(test.$config.errmsg) 578 wapp-trim { 579 <tr class=testfail> 580 <td> <td class="padleft" colspan=3> %html($errmsg) 581 } 582 } 583 } 584 585 wapp-trim { </table> } 586 587 if {[info exists G(result)]} { 588 set res $G(result) 589 wapp-trim { 590 <div class=border id=result> %string($res) </div> 591 } 592 } 593} 594 595# URI: /control 596# 597# Whenever the form at the top of the application page is submitted, it 598# is submitted here. 599# 600proc wapp-page-control {} { 601 global G 602 if {$::G(state)=="config"} { 603 set lControls [list platform test tcl jobs keep msvc debug] 604 set G(msvc) 0 605 set G(keep) 0 606 set G(debug) 0 607 } else { 608 set lControls [list jobs] 609 } 610 foreach v $lControls { 611 if {[wapp-param-exists control_$v]} { 612 set G($v) [wapp-param control_$v] 613 } 614 } 615 616 if {[wapp-param-exists control_run]} { 617 # This is a "run test" command. 618 wapptest_run 619 } 620 621 if {[wapp-param-exists control_stop]} { 622 # A "STOP tests" command. 623 set G(state) "stopped" 624 set G(result) "Test halted by user" 625 foreach j $G(test_array) { 626 set name [dict get $j config] 627 if { [info exists G(test.$name.channel)] } { 628 close $G(test.$name.channel) 629 unset G(test.$name.channel) 630 slave_test_done $name 1 631 } 632 } 633 wapptest_closelog 634 } 635 636 if {[wapp-param-exists control_reset]} { 637 # A "reset app" command. 638 set G(state) "config" 639 wapptest_init 640 } 641 642 if {$::G(state) == "running"} { 643 do_some_stuff 644 } 645 wapp-redirect / 646} 647 648# URI: /style.css 649# 650# Return the stylesheet for the application main page. 651# 652proc wapp-page-style.css {} { 653 wapp-subst { 654 655 /* The boxes with black borders use this class */ 656 .border { 657 border: 3px groove #444444; 658 padding: 1em; 659 margin-top: 1em; 660 margin-bottom: 1em; 661 } 662 663 /* Float to the right (used for the Run/Stop/Reset button) */ 664 .right { float: right; } 665 666 /* Style for the large red warning at the top of the page */ 667 .warning { 668 color: red; 669 font-weight: bold; 670 } 671 672 /* Styles used by cells in the test table */ 673 .padleft { padding-left: 5ex; } 674 .nowrap { white-space: nowrap; } 675 676 /* Styles for individual tests, depending on the outcome */ 677 .testwait { } 678 .testrunning { color: blue } 679 .testdone { color: green } 680 .testfail { color: red } 681 } 682} 683 684# URI: /script/${state}.js 685# 686# The last part of this URI is always "config.js", "running.js" or 687# "stopped.js", depending on the state of the application. It returns 688# the javascript part of the front-end for the requested state to the 689# browser. 690# 691proc wapp-page-script {} { 692 regexp {[^/]*$} [wapp-param REQUEST_URI] script 693 694 set tcl $::G(tcl) 695 set keep $::G(keep) 696 set msvc $::G(msvc) 697 set debug $::G(debug) 698 699 wapp-subst { 700 var lElem = \["control_platform", "control_test", "control_msvc", 701 "control_jobs", "control_debug" 702 \]; 703 lElem.forEach(function(e) { 704 var elem = document.getElementById(e); 705 elem.addEventListener("change", function() { control.submit() } ); 706 }) 707 708 elem = document.getElementById("control_tcl"); 709 elem.value = "%string($tcl)" 710 711 elem = document.getElementById("control_keep"); 712 elem.checked = %string($keep); 713 714 elem = document.getElementById("control_msvc"); 715 elem.checked = %string($msvc); 716 717 elem = document.getElementById("control_debug"); 718 elem.checked = %string($debug); 719 } 720 721 if {$script != "config.js"} { 722 wapp-subst { 723 var lElem = \["control_platform", "control_test", 724 "control_tcl", "control_keep", "control_msvc", 725 "control_debug" 726 \]; 727 lElem.forEach(function(e) { 728 var elem = document.getElementById(e); 729 elem.disabled = true; 730 }) 731 } 732 } 733 734 if {$script == "running.js"} { 735 wapp-subst { 736 function reload_tests() { 737 fetch('tests') 738 .then( data => data.text() ) 739 .then( data => { 740 document.getElementById("tests").innerHTML = data; 741 }) 742 .then( data => { 743 if( document.getElementById("result") ){ 744 document.location = document.location; 745 } else { 746 setTimeout(reload_tests, 1000) 747 } 748 }); 749 } 750 751 setTimeout(reload_tests, 1000) 752 } 753 } 754} 755 756# URI: /env 757# 758# This is for debugging only. Serves no other purpose. 759# 760proc wapp-page-env {} { 761 wapp-allow-xorigin-params 762 wapp-trim { 763 <h1>Wapp Environment</h1>\n<pre> 764 <pre>%html([wapp-debug-env])</pre> 765 } 766} 767 768# URI: /log/dirname/test.log 769# 770# This URI reads file "dirname/test.log" from disk, wraps it in a <pre> 771# block, and returns it to the browser. Use for viewing log files. 772# 773proc wapp-page-log {} { 774 set log [string range [wapp-param REQUEST_URI] 5 end] 775 set fd [open $log] 776 set data [read $fd] 777 close $fd 778 wapp-trim { 779 <pre> 780 %html($data) 781 </pre> 782 } 783} 784 785# Print out a usage message. Then do [exit 1]. 786# 787proc wapptest_usage {} { 788 puts stderr { 789This Tcl script is used to test various configurations of SQLite. By 790default it uses "wapp" to provide an interactive interface. Supported 791command line options (all optional) are: 792 793 --platform PLATFORM (which tests to run) 794 --config GLOB (only run configurations matching GLOB) 795 --smoketest (run "make smoketest" only) 796 --veryquick (run veryquick.test only) 797 --buildonly (build executables, do not run tests) 798 --jobs N (number of concurrent jobs) 799 --tcl DIR (where to find tclConfig.sh) 800 --deletefiles (delete extra files after each test) 801 --msvc (Use MS Visual C) 802 --debug (Also run [n]debugging versions of tests) 803 --noui (do not use wapp) 804 } 805 exit 1 806} 807 808# Sort command line arguments into two groups: those that belong to wapp, 809# and those that belong to the application. 810set WAPPARG(-server) 1 811set WAPPARG(-local) 1 812set WAPPARG(-scgi) 1 813set WAPPARG(-remote-scgi) 1 814set WAPPARG(-fromip) 1 815set WAPPARG(-nowait) 0 816set WAPPARG(-cgi) 0 817set lWappArg [list] 818set lTestArg [list] 819for {set i 0} {$i < [llength $argv]} {incr i} { 820 set arg [lindex $argv $i] 821 if {[string range $arg 0 1]=="--"} { 822 set arg [string range $arg 1 end] 823 } 824 if {[info exists WAPPARG($arg)]} { 825 lappend lWappArg $arg 826 if {$WAPPARG($arg)} { 827 incr i 828 lappend lWappArg [lindex $argv $i] 829 } 830 } else { 831 lappend lTestArg $arg 832 } 833} 834 835wapptest_init 836for {set i 0} {$i < [llength $lTestArg]} {incr i} { 837 set opt [lindex $lTestArg $i] 838 if {[string range $opt 0 1]=="--"} { 839 set opt [string range $opt 1 end] 840 } 841 switch -- $opt { 842 -platform { 843 if {$i==[llength $lTestArg]-1} { wapptest_usage } 844 incr i 845 set arg [lindex $lTestArg $i] 846 set lPlatform [releasetest_data platforms] 847 if {[lsearch $lPlatform $arg]<0} { 848 puts stderr "No such platform: $arg. Platforms are: $lPlatform" 849 exit -1 850 } 851 set G(platform) $arg 852 } 853 854 -smoketest { set G(test) Smoketest } 855 -veryquick { set G(test) Veryquick } 856 -buildonly { set G(test) Build-Only } 857 -jobs { 858 if {$i==[llength $lTestArg]-1} { wapptest_usage } 859 incr i 860 set G(jobs) [lindex $lTestArg $i] 861 } 862 863 -tcl { 864 if {$i==[llength $lTestArg]-1} { wapptest_usage } 865 incr i 866 set G(tcl) [lindex $lTestArg $i] 867 } 868 869 -deletefiles { 870 set G(keep) 0 871 } 872 873 -msvc { 874 set G(msvc) 1 875 } 876 877 -debug { 878 set G(debug) 1 879 } 880 881 -noui { 882 set G(noui) 1 883 set G(stdout) 1 884 } 885 886 -config { 887 if {$i==[llength $lTestArg]-1} { wapptest_usage } 888 incr i 889 set G(cfgglob) [lindex $lTestArg $i] 890 } 891 892 -stdout { 893 set G(stdout) 1 894 } 895 896 default { 897 puts stderr "Unrecognized option: [lindex $lTestArg $i]" 898 wapptest_usage 899 } 900 } 901} 902 903if {$G(noui)==0} { 904 wapp-start $lWappArg 905} else { 906 wapptest_run 907 do_some_stuff 908 vwait forever 909} 910