summaryrefslogtreecommitdiffstats
path: root/test/wapptest.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'test/wapptest.tcl')
-rwxr-xr-xtest/wapptest.tcl909
1 files changed, 909 insertions, 0 deletions
diff --git a/test/wapptest.tcl b/test/wapptest.tcl
new file mode 100755
index 0000000..d37b2e4
--- /dev/null
+++ b/test/wapptest.tcl
@@ -0,0 +1,909 @@
+#!/bin/sh
+# \
+exec wapptclsh "$0" ${1+"$@"}
+
+# package required wapp
+source [file join [file dirname [info script]] wapp.tcl]
+
+# Variables set by the "control" form:
+#
+# G(platform) - User selected platform.
+# G(cfgglob) - Glob pattern that all configurations must match
+# G(test) - Set to "Normal", "Veryquick", "Smoketest" or "Build-Only".
+# G(keep) - Boolean. True to delete no files after each test.
+# G(msvc) - Boolean. True to use MSVC as the compiler.
+# G(tcl) - Use Tcl from this directory for builds.
+# G(jobs) - How many sub-processes to run simultaneously.
+#
+set G(platform) $::tcl_platform(os)-$::tcl_platform(machine)
+set G(cfgglob) *
+set G(test) Normal
+set G(keep) 1
+set G(msvc) 0
+set G(tcl) [::tcl::pkgconfig get libdir,install]
+set G(jobs) 3
+set G(debug) 0
+
+set G(noui) 0
+set G(stdout) 0
+
+
+proc wapptest_init {} {
+ global G
+
+ set lSave [list platform test keep msvc tcl jobs debug noui stdout cfgglob]
+ foreach k $lSave { set A($k) $G($k) }
+ array unset G
+ foreach k $lSave { set G($k) $A($k) }
+
+ # The root of the SQLite source tree.
+ set G(srcdir) [file dirname [file dirname [info script]]]
+
+ set G(sqlite_version) "unknown"
+
+ # Either "config", "running" or "stopped":
+ set G(state) "config"
+
+ set G(hostname) "(unknown host)"
+ catch { set G(hostname) [exec hostname] }
+ set G(host) $G(hostname)
+ append G(host) " $::tcl_platform(os) $::tcl_platform(osVersion)"
+ append G(host) " $::tcl_platform(machine) $::tcl_platform(byteOrder)"
+}
+
+proc wapptest_run {} {
+ global G
+ set_test_array
+ set G(state) "running"
+
+ wapptest_openlog
+
+ wapptest_output "Running the following for $G(platform). $G(jobs) jobs."
+ foreach t $G(test_array) {
+ set config [dict get $t config]
+ set target [dict get $t target]
+ wapptest_output [format " %-25s%s" $config $target]
+ }
+ wapptest_output [string repeat * 70]
+}
+
+proc releasetest_data {args} {
+ global G
+ set rtd [file join $G(srcdir) test releasetest_data.tcl]
+ set fd [open "|[info nameofexecutable] $rtd $args" r+]
+ set ret [read $fd]
+ close $fd
+ return $ret
+}
+
+# Generate the text for the box at the top of the UI. The current SQLite
+# version, according to fossil, along with a warning if there are
+# uncommitted changes in the checkout.
+#
+proc generate_fossil_info {} {
+ global G
+ set pwd [pwd]
+ cd $G(srcdir)
+ set rc [catch {
+ set r1 [exec fossil info]
+ set r2 [exec fossil changes]
+ }]
+ cd $pwd
+ if {$rc} return
+
+ foreach line [split $r1 "\n"] {
+ if {[regexp {^checkout: *(.*)$} $line -> co]} {
+ wapp-trim { <br> %html($co) }
+ }
+ }
+
+ if {[string trim $r2]!=""} {
+ wapp-trim {
+ <br><span class=warning>
+ WARNING: Uncommitted changes in checkout
+ </span>
+ }
+ }
+}
+
+# If the application is in "config" state, set the contents of the
+# ::G(test_array) global to reflect the tests that will be run. If the
+# app is in some other state ("running" or "stopped"), this command
+# is a no-op.
+#
+proc set_test_array {} {
+ global G
+ if { $G(state)=="config" } {
+ set G(test_array) [list]
+ set debug "-debug"
+ if {$G(debug)==0} { set debug "-nodebug"}
+ foreach {config target} [releasetest_data tests $debug $G(platform)] {
+
+ # All configuration names must match $g(cfgglob), which defaults to *
+ #
+ if {![string match -nocase $G(cfgglob) $config]} continue
+
+ # If using MSVC, do not run sanitize or valgrind tests. Or the
+ # checksymbols test.
+ if {$G(msvc) && (
+ "Sanitize" == $config
+ || "checksymbols" in $target
+ || "valgrindtest" in $target
+ )} {
+ continue
+ }
+
+ # If the test mode is not "Normal", override the target.
+ #
+ if {$target!="checksymbols" && $G(platform)!="Failure-Detection"} {
+ switch -- $G(test) {
+ Veryquick { set target quicktest }
+ Smoketest { set target smoketest }
+ Build-Only {
+ set target testfixture
+ if {$::tcl_platform(platform)=="windows"} {
+ set target testfixture.exe
+ }
+ }
+ }
+ }
+
+ lappend G(test_array) [dict create config $config target $target]
+ }
+ }
+}
+
+proc count_tests_and_errors {name logfile} {
+ global G
+
+ set fd [open $logfile rb]
+ set seen 0
+ while {![eof $fd]} {
+ set line [gets $fd]
+ if {[regexp {(\d+) errors out of (\d+) tests} $line all nerr ntest]} {
+ incr G(test.$name.nError) $nerr
+ incr G(test.$name.nTest) $ntest
+ set seen 1
+ if {$nerr>0} {
+ set G(test.$name.errmsg) $line
+ }
+ }
+ if {[regexp {runtime error: +(.*)} $line all msg]} {
+ # skip over "value is outside range" errors
+ if {[regexp {.* is outside the range of representable} $line]} {
+ # noop
+ } else {
+ incr G(test.$name.nError)
+ if {$G(test.$name.errmsg)==""} {
+ set G(test.$name.errmsg) $msg
+ }
+ }
+ }
+ if {[regexp {fatal error +(.*)} $line all msg]} {
+ incr G(test.$name.nError)
+ if {$G(test.$name.errmsg)==""} {
+ set G(test.$name.errmsg) $msg
+ }
+ }
+ if {[regexp {ERROR SUMMARY: (\d+) errors.*} $line all cnt] && $cnt>0} {
+ incr G(test.$name.nError)
+ if {$G(test.$name.errmsg)==""} {
+ set G(test.$name.errmsg) $all
+ }
+ }
+ if {[regexp {^VERSION: 3\.\d+.\d+} $line]} {
+ set v [string range $line 9 end]
+ if {$G(sqlite_version) eq "unknown"} {
+ set G(sqlite_version) $v
+ } elseif {$G(sqlite_version) ne $v} {
+ set G(test.$name.errmsg) "version conflict: {$G(sqlite_version)} vs. {$v}"
+ }
+ }
+ }
+ close $fd
+ if {$G(test) == "Build-Only"} {
+ incr G(test.$name.nTest)
+ if {$G(test.$name.nError)>0} {
+ set errmsg "Build failed"
+ }
+ } elseif {!$seen} {
+ set G(test.$name.errmsg) "Test did not complete"
+ if {[file readable core]} {
+ append G(test.$name.errmsg) " - core file exists"
+ }
+ }
+}
+
+proc wapptest_output {str} {
+ global G
+ if {$G(stdout)} { puts $str }
+ if {[info exists G(log)]} {
+ puts $G(log) $str
+ flush $G(log)
+ }
+}
+proc wapptest_openlog {} {
+ global G
+ set G(log) [open wapptest-out.txt w+]
+}
+proc wapptest_closelog {} {
+ global G
+ close $G(log)
+ unset G(log)
+}
+
+proc format_seconds {seconds} {
+ set min [format %.2d [expr ($seconds / 60) % 60]]
+ set hr [format %.2d [expr $seconds / 3600]]
+ set sec [format %.2d [expr $seconds % 60]]
+ return "$hr:$min:$sec"
+}
+
+# This command is invoked once a slave process has finished running its
+# tests, successfully or otherwise. Parameter $name is the name of the
+# test, $rc the exit code returned by the slave process.
+#
+proc slave_test_done {name rc} {
+ global G
+ set G(test.$name.done) [clock seconds]
+ set G(test.$name.nError) 0
+ set G(test.$name.nTest) 0
+ set G(test.$name.errmsg) ""
+ if {$rc} {
+ incr G(test.$name.nError)
+ }
+ if {[file exists $G(test.$name.log)]} {
+ count_tests_and_errors $name $G(test.$name.log)
+ }
+
+ # If the "keep files" checkbox is clear, delete all files except for
+ # the executables and test logs. And any core file that is present.
+ if {$G(keep)==0} {
+ set keeplist {
+ testfixture testfixture.exe
+ sqlite3 sqlite3.exe
+ test.log test-out.txt
+ core
+ wapptest_make.sh
+ wapptest_configure.sh
+ wapptest_run.tcl
+ }
+ foreach f [glob -nocomplain [file join $G(test.$name.dir) *]] {
+ set t [file tail $f]
+ if {[lsearch $keeplist $t]<0} {
+ catch { file delete -force $f }
+ }
+ }
+ }
+
+ # Format a message regarding the success or failure of hte test.
+ set t [format_seconds [expr $G(test.$name.done) - $G(test.$name.start)]]
+ set res "OK"
+ if {$G(test.$name.nError)} { set res "FAILED" }
+ set dots [string repeat . [expr 60 - [string length $name]]]
+ set msg "$name $dots $res ($t)"
+
+ wapptest_output $msg
+ if {[info exists G(test.$name.errmsg)] && $G(test.$name.errmsg)!=""} {
+ wapptest_output " $G(test.$name.errmsg)"
+ }
+}
+
+# This is a fileevent callback invoked each time a file-descriptor that
+# connects this process to a slave process is readable.
+#
+proc slave_fileevent {name} {
+ global G
+ set fd $G(test.$name.channel)
+
+ if {[eof $fd]} {
+ fconfigure $fd -blocking 1
+ set rc [catch { close $fd }]
+ unset G(test.$name.channel)
+ slave_test_done $name $rc
+ } else {
+ set line [gets $fd]
+ if {[string trim $line] != ""} { puts "Trace : $name - \"$line\"" }
+ }
+
+ do_some_stuff
+}
+
+# Return the contents of the "slave script" - the script run by slave
+# processes to actually perform the test. All it does is execute the
+# test script already written to disk (wapptest_cmd.sh or wapptest_cmd.bat).
+#
+proc wapptest_slave_script {} {
+ global G
+ if {$G(msvc)==0} {
+ set dir [file join .. $G(srcdir)]
+ set res [subst -nocommands {
+ set rc [catch "exec sh wapptest_cmd.sh {$dir} >>& test.log" ]
+ exit [set rc]
+ }]
+ } else {
+ set dir [file nativename [file normalize $G(srcdir)]]
+ set dir [string map [list "\\" "\\\\"] $dir]
+ set res [subst -nocommands {
+ set rc [catch "exec wapptest_cmd.bat {$dir} >>& test.log" ]
+ exit [set rc]
+ }]
+ }
+
+ set res
+}
+
+
+# Launch a slave process to run a test.
+#
+proc slave_launch {name target dir} {
+ global G
+
+ catch { file mkdir $dir } msg
+ foreach f [glob -nocomplain [file join $dir *]] {
+ catch { file delete -force $f }
+ }
+ set G(test.$name.dir) $dir
+
+ # Write the test command to wapptest_cmd.sh|bat.
+ #
+ set ext sh
+ if {$G(msvc)} { set ext bat }
+ set fd1 [open [file join $dir wapptest_cmd.$ext] w]
+ if {$G(msvc)} {
+ puts $fd1 [releasetest_data script -msvc $name $target]
+ } else {
+ puts $fd1 [releasetest_data script $name $target]
+ }
+ close $fd1
+
+ # Write the wapptest_run.tcl script to the test directory. To run the
+ # commands in the other two files.
+ #
+ set fd3 [open [file join $dir wapptest_run.tcl] w]
+ puts $fd3 [wapptest_slave_script]
+ close $fd3
+
+ set pwd [pwd]
+ cd $dir
+ set fd [open "|[info nameofexecutable] wapptest_run.tcl" r+]
+ cd $pwd
+
+ set G(test.$name.channel) $fd
+ fconfigure $fd -blocking 0
+ fileevent $fd readable [list slave_fileevent $name]
+}
+
+proc do_some_stuff {} {
+ global G
+
+ # Count the number of running jobs. A running job has an entry named
+ # "channel" in its dictionary.
+ set nRunning 0
+ set bFinished 1
+ foreach j $G(test_array) {
+ set name [dict get $j config]
+ if { [info exists G(test.$name.channel)]} { incr nRunning }
+ if {![info exists G(test.$name.done)]} { set bFinished 0 }
+ }
+
+ if {$bFinished} {
+ set nError 0
+ set nTest 0
+ set nConfig 0
+ foreach j $G(test_array) {
+ set name [dict get $j config]
+ incr nError $G(test.$name.nError)
+ incr nTest $G(test.$name.nTest)
+ incr nConfig
+ }
+ set G(result) "$nError errors from $nTest tests in $nConfig configurations."
+ wapptest_output [string repeat * 70]
+ wapptest_output $G(result)
+ catch {
+ append G(result) " SQLite version $G(sqlite_version)"
+ wapptest_output " SQLite version $G(sqlite_version)"
+ }
+ set G(state) "stopped"
+ wapptest_closelog
+ if {$G(noui)} { exit 0 }
+ } else {
+ set nLaunch [expr $G(jobs) - $nRunning]
+ foreach j $G(test_array) {
+ if {$nLaunch<=0} break
+ set name [dict get $j config]
+ if { ![info exists G(test.$name.channel)]
+ && ![info exists G(test.$name.done)]
+ } {
+
+ set target [dict get $j target]
+ set dir [string tolower [string map {" " _ "-" _} $name]]
+ set G(test.$name.start) [clock seconds]
+ set G(test.$name.log) [file join $dir test.log]
+
+ slave_launch $name $target $dir
+
+ incr nLaunch -1
+ }
+ }
+ }
+}
+
+proc generate_select_widget {label id lOpt opt} {
+ wapp-trim {
+ <label> %string($label) </label>
+ <select id=%string($id) name=%string($id)>
+ }
+ foreach o $lOpt {
+ set selected ""
+ if {$o==$opt} { set selected " selected=1" }
+ wapp-subst "<option $selected>$o</option>"
+ }
+ wapp-trim { </select> }
+}
+
+proc generate_main_page {{extra {}}} {
+ global G
+ set_test_array
+
+ set hostname $G(hostname)
+ wapp-trim {
+ <html>
+ <head>
+ <title> %html($hostname): wapptest.tcl </title>
+ <link rel="stylesheet" type="text/css" href="style.css"/>
+ </head>
+ <body>
+ }
+
+ set host $G(host)
+ wapp-trim {
+ <div class="border">%string($host)
+ }
+ generate_fossil_info
+ wapp-trim {
+ </div>
+ <div class="border" id=controls>
+ <form action="control" method="post" name="control">
+ }
+
+ # Build the "platform" select widget.
+ set lOpt [releasetest_data platforms]
+ generate_select_widget Platform control_platform $lOpt $G(platform)
+
+ # Build the "test" select widget.
+ set lOpt [list Normal Veryquick Smoketest Build-Only]
+ generate_select_widget Test control_test $lOpt $G(test)
+
+ # Build the "jobs" select widget. Options are 1 to 8.
+ generate_select_widget Jobs control_jobs {1 2 3 4 5 6 7 8 12 16} $G(jobs)
+
+ switch $G(state) {
+ config {
+ set txt "Run Tests!"
+ set id control_run
+ }
+ running {
+ set txt "STOP Tests!"
+ set id control_stop
+ }
+ stopped {
+ set txt "Reset!"
+ set id control_reset
+ }
+ }
+ wapp-trim {
+ <div class=right>
+ <input id=%string($id) name=%string($id) type=submit value="%string($txt)">
+ </input>
+ </div>
+ }
+
+ wapp-trim {
+ <br><br>
+ <label> Tcl: </label>
+ <input id="control_tcl" name="control_tcl"></input>
+ <label> Keep files: </label>
+ <input id="control_keep" name="control_keep" type=checkbox value=1>
+ </input>
+ <label> Use MSVC: </label>
+ <input id="control_msvc" name="control_msvc" type=checkbox value=1>
+ <label> Debug tests: </label>
+ <input id="control_debug" name="control_debug" type=checkbox value=1>
+ </input>
+ }
+ wapp-trim {
+ </form>
+ }
+ wapp-trim {
+ </div>
+ <div id=tests>
+ }
+ wapp-page-tests
+
+ set script "script/$G(state).js"
+ wapp-trim {
+ </div>
+ <script src=%string($script)></script>
+ </body>
+ </html>
+ }
+}
+
+proc wapp-default {} {
+ generate_main_page
+}
+
+proc wapp-page-tests {} {
+ global G
+ wapp-trim { <table class="border" width=100%> }
+ foreach t $G(test_array) {
+ set config [dict get $t config]
+ set target [dict get $t target]
+
+ set class "testwait"
+ set seconds ""
+
+ if {[info exists G(test.$config.log)]} {
+ if {[info exists G(test.$config.channel)]} {
+ set class "testrunning"
+ set seconds [expr [clock seconds] - $G(test.$config.start)]
+ } elseif {[info exists G(test.$config.done)]} {
+ if {$G(test.$config.nError)>0} {
+ set class "testfail"
+ } else {
+ set class "testdone"
+ }
+ set seconds [expr $G(test.$config.done) - $G(test.$config.start)]
+ }
+ set seconds [format_seconds $seconds]
+ }
+
+ wapp-trim {
+ <tr class=%string($class)>
+ <td class="nowrap"> %html($config)
+ <td class="padleft nowrap"> %html($target)
+ <td class="padleft nowrap"> %html($seconds)
+ <td class="padleft nowrap">
+ }
+ if {[info exists G(test.$config.log)]} {
+ set log $G(test.$config.log)
+ set uri "log/$log"
+ wapp-trim {
+ <a href=%url($uri)> %html($log) </a>
+ }
+ }
+ if {[info exists G(test.$config.errmsg)] && $G(test.$config.errmsg)!=""} {
+ set errmsg $G(test.$config.errmsg)
+ wapp-trim {
+ <tr class=testfail>
+ <td> <td class="padleft" colspan=3> %html($errmsg)
+ }
+ }
+ }
+
+ wapp-trim { </table> }
+
+ if {[info exists G(result)]} {
+ set res $G(result)
+ wapp-trim {
+ <div class=border id=result> %string($res) </div>
+ }
+ }
+}
+
+# URI: /control
+#
+# Whenever the form at the top of the application page is submitted, it
+# is submitted here.
+#
+proc wapp-page-control {} {
+ global G
+ if {$::G(state)=="config"} {
+ set lControls [list platform test tcl jobs keep msvc debug]
+ set G(msvc) 0
+ set G(keep) 0
+ set G(debug) 0
+ } else {
+ set lControls [list jobs]
+ }
+ foreach v $lControls {
+ if {[wapp-param-exists control_$v]} {
+ set G($v) [wapp-param control_$v]
+ }
+ }
+
+ if {[wapp-param-exists control_run]} {
+ # This is a "run test" command.
+ wapptest_run
+ }
+
+ if {[wapp-param-exists control_stop]} {
+ # A "STOP tests" command.
+ set G(state) "stopped"
+ set G(result) "Test halted by user"
+ foreach j $G(test_array) {
+ set name [dict get $j config]
+ if { [info exists G(test.$name.channel)] } {
+ close $G(test.$name.channel)
+ unset G(test.$name.channel)
+ slave_test_done $name 1
+ }
+ }
+ wapptest_closelog
+ }
+
+ if {[wapp-param-exists control_reset]} {
+ # A "reset app" command.
+ set G(state) "config"
+ wapptest_init
+ }
+
+ if {$::G(state) == "running"} {
+ do_some_stuff
+ }
+ wapp-redirect /
+}
+
+# URI: /style.css
+#
+# Return the stylesheet for the application main page.
+#
+proc wapp-page-style.css {} {
+ wapp-subst {
+
+ /* The boxes with black borders use this class */
+ .border {
+ border: 3px groove #444444;
+ padding: 1em;
+ margin-top: 1em;
+ margin-bottom: 1em;
+ }
+
+ /* Float to the right (used for the Run/Stop/Reset button) */
+ .right { float: right; }
+
+ /* Style for the large red warning at the top of the page */
+ .warning {
+ color: red;
+ font-weight: bold;
+ }
+
+ /* Styles used by cells in the test table */
+ .padleft { padding-left: 5ex; }
+ .nowrap { white-space: nowrap; }
+
+ /* Styles for individual tests, depending on the outcome */
+ .testwait { }
+ .testrunning { color: blue }
+ .testdone { color: green }
+ .testfail { color: red }
+ }
+}
+
+# URI: /script/${state}.js
+#
+# The last part of this URI is always "config.js", "running.js" or
+# "stopped.js", depending on the state of the application. It returns
+# the javascript part of the front-end for the requested state to the
+# browser.
+#
+proc wapp-page-script {} {
+ regexp {[^/]*$} [wapp-param REQUEST_URI] script
+
+ set tcl $::G(tcl)
+ set keep $::G(keep)
+ set msvc $::G(msvc)
+ set debug $::G(debug)
+
+ wapp-subst {
+ var lElem = \["control_platform", "control_test", "control_msvc",
+ "control_jobs", "control_debug"
+ \];
+ lElem.forEach(function(e) {
+ var elem = document.getElementById(e);
+ elem.addEventListener("change", function() { control.submit() } );
+ })
+
+ elem = document.getElementById("control_tcl");
+ elem.value = "%string($tcl)"
+
+ elem = document.getElementById("control_keep");
+ elem.checked = %string($keep);
+
+ elem = document.getElementById("control_msvc");
+ elem.checked = %string($msvc);
+
+ elem = document.getElementById("control_debug");
+ elem.checked = %string($debug);
+ }
+
+ if {$script != "config.js"} {
+ wapp-subst {
+ var lElem = \["control_platform", "control_test",
+ "control_tcl", "control_keep", "control_msvc",
+ "control_debug"
+ \];
+ lElem.forEach(function(e) {
+ var elem = document.getElementById(e);
+ elem.disabled = true;
+ })
+ }
+ }
+
+ if {$script == "running.js"} {
+ wapp-subst {
+ function reload_tests() {
+ fetch('tests')
+ .then( data => data.text() )
+ .then( data => {
+ document.getElementById("tests").innerHTML = data;
+ })
+ .then( data => {
+ if( document.getElementById("result") ){
+ document.location = document.location;
+ } else {
+ setTimeout(reload_tests, 1000)
+ }
+ });
+ }
+
+ setTimeout(reload_tests, 1000)
+ }
+ }
+}
+
+# URI: /env
+#
+# This is for debugging only. Serves no other purpose.
+#
+proc wapp-page-env {} {
+ wapp-allow-xorigin-params
+ wapp-trim {
+ <h1>Wapp Environment</h1>\n<pre>
+ <pre>%html([wapp-debug-env])</pre>
+ }
+}
+
+# URI: /log/dirname/test.log
+#
+# This URI reads file "dirname/test.log" from disk, wraps it in a <pre>
+# block, and returns it to the browser. Use for viewing log files.
+#
+proc wapp-page-log {} {
+ set log [string range [wapp-param REQUEST_URI] 5 end]
+ set fd [open $log]
+ set data [read $fd]
+ close $fd
+ wapp-trim {
+ <pre>
+ %html($data)
+ </pre>
+ }
+}
+
+# Print out a usage message. Then do [exit 1].
+#
+proc wapptest_usage {} {
+ puts stderr {
+This Tcl script is used to test various configurations of SQLite. By
+default it uses "wapp" to provide an interactive interface. Supported
+command line options (all optional) are:
+
+ --platform PLATFORM (which tests to run)
+ --config GLOB (only run configurations matching GLOB)
+ --smoketest (run "make smoketest" only)
+ --veryquick (run veryquick.test only)
+ --buildonly (build executables, do not run tests)
+ --jobs N (number of concurrent jobs)
+ --tcl DIR (where to find tclConfig.sh)
+ --deletefiles (delete extra files after each test)
+ --msvc (Use MS Visual C)
+ --debug (Also run [n]debugging versions of tests)
+ --noui (do not use wapp)
+ }
+ exit 1
+}
+
+# Sort command line arguments into two groups: those that belong to wapp,
+# and those that belong to the application.
+set WAPPARG(-server) 1
+set WAPPARG(-local) 1
+set WAPPARG(-scgi) 1
+set WAPPARG(-remote-scgi) 1
+set WAPPARG(-fromip) 1
+set WAPPARG(-nowait) 0
+set WAPPARG(-cgi) 0
+set lWappArg [list]
+set lTestArg [list]
+for {set i 0} {$i < [llength $argv]} {incr i} {
+ set arg [lindex $argv $i]
+ if {[string range $arg 0 1]=="--"} {
+ set arg [string range $arg 1 end]
+ }
+ if {[info exists WAPPARG($arg)]} {
+ lappend lWappArg $arg
+ if {$WAPPARG($arg)} {
+ incr i
+ lappend lWappArg [lindex $argv $i]
+ }
+ } else {
+ lappend lTestArg $arg
+ }
+}
+
+wapptest_init
+for {set i 0} {$i < [llength $lTestArg]} {incr i} {
+ set opt [lindex $lTestArg $i]
+ if {[string range $opt 0 1]=="--"} {
+ set opt [string range $opt 1 end]
+ }
+ switch -- $opt {
+ -platform {
+ if {$i==[llength $lTestArg]-1} { wapptest_usage }
+ incr i
+ set arg [lindex $lTestArg $i]
+ set lPlatform [releasetest_data platforms]
+ if {[lsearch $lPlatform $arg]<0} {
+ puts stderr "No such platform: $arg. Platforms are: $lPlatform"
+ exit -1
+ }
+ set G(platform) $arg
+ }
+
+ -smoketest { set G(test) Smoketest }
+ -veryquick { set G(test) Veryquick }
+ -buildonly { set G(test) Build-Only }
+ -jobs {
+ if {$i==[llength $lTestArg]-1} { wapptest_usage }
+ incr i
+ set G(jobs) [lindex $lTestArg $i]
+ }
+
+ -tcl {
+ if {$i==[llength $lTestArg]-1} { wapptest_usage }
+ incr i
+ set G(tcl) [lindex $lTestArg $i]
+ }
+
+ -deletefiles {
+ set G(keep) 0
+ }
+
+ -msvc {
+ set G(msvc) 1
+ }
+
+ -debug {
+ set G(debug) 1
+ }
+
+ -noui {
+ set G(noui) 1
+ set G(stdout) 1
+ }
+
+ -config {
+ if {$i==[llength $lTestArg]-1} { wapptest_usage }
+ incr i
+ set G(cfgglob) [lindex $lTestArg $i]
+ }
+
+ -stdout {
+ set G(stdout) 1
+ }
+
+ default {
+ puts stderr "Unrecognized option: [lindex $lTestArg $i]"
+ wapptest_usage
+ }
+ }
+}
+
+if {$G(noui)==0} {
+ wapp-start $lWappArg
+} else {
+ wapptest_run
+ do_some_stuff
+ vwait forever
+}