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