Bug 435739 Poor performance of Firefox 3 with no X RENDER extension
[wine-gecko.git] / testing / mochitest / runtests.pl.in
blob85d18f9acafe19d90e3b450e1f5fb5607b8345ca
2 # ***** BEGIN LICENSE BLOCK *****
3 # Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 # The contents of this file are subject to the Mozilla Public License Version
6 # 1.1 (the "License"); you may not use this file except in compliance with
7 # the License. You may obtain a copy of the License at
8 # http://www.mozilla.org/MPL/
10 # Software distributed under the License is distributed on an "AS IS" basis,
11 # WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 # for the specific language governing rights and limitations under the
13 # License.
15 # The Original Code is mozilla.org code.
17 # The Initial Developer of the Original Code is
18 # Mozilla Foundation.
19 # Portions created by the Initial Developer are Copyright (C) 1998
20 # the Initial Developer. All Rights Reserved.
22 # Contributor(s):
23 # Robert Sayre <sayrer@gmail.com>
24 # Jeff Walden <jwalden+bmo@mit.edu>
26 # Alternatively, the contents of this file may be used under the terms of
27 # either the GNU General Public License Version 2 or later (the "GPL"), or
28 # the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 # in which case the provisions of the GPL or the LGPL are applicable instead
30 # of those above. If you wish to allow use of your version of this file only
31 # under the terms of either the GPL or the LGPL, and not to allow others to
32 # use your version of this file under the terms of the MPL, indicate your
33 # decision by deleting the provisions above and replace them with the notice
34 # and other provisions required by the GPL or the LGPL. If you do not delete
35 # the provisions above, a recipient may use your version of this file under
36 # the terms of any one of the MPL, the GPL or the LGPL.
38 # ***** END LICENSE BLOCK *****
40 # Win32 path munging for msys courtesy the Curl project under an
41 # MIT/X license http://curl.haxx.se/
43 # Copyright (c) 1996 - 2007, Daniel Stenberg, <daniel@haxx.se>.
44 # All rights reserved.
46 # Permission to use, copy, modify, and distribute this software for
47 # any purpose with or without fee is hereby granted, provided that the
48 # above copyright notice and this permission notice appear in all
49 # copies.
51 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
52 # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
53 # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
54 # NONINFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL THE AUTHORS
55 # OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
56 # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
57 # ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
58 # OR OTHER DEALINGS IN THE SOFTWARE.
60 # Except as contained in this notice, the name of a copyright holder
61 # shall not be used in advertising or otherwise to promote the sale,
62 # use or other dealings in this Software without prior written
63 # authorization of the copyright holder.
65 # Perl script to start server and browser
66 # For usage instructions, run:
67 # perl runtests.pl --help
69 use FindBin;
70 use File::Path;
71 use File::Spec;
72 use File::Basename;
73 use Getopt::Long;
74 use Cwd 'abs_path';
75 use POSIX qw(sys_wait_h strftime);
77 use strict;
79 # URL parameters to test URL:
81 # autorun -- kick off tests automatically
82 # closeWhenDone -- runs quit.js after tests
83 # logFile -- logs test run to an absolute path
86 # consoleLevel, fileLevel: set the logging level of the console and
87 # file logs, if activated.
88 # <http://mochikit.com/doc/html/MochiKit/Logging.html>
90 # Path to the test script on the server
91 use constant TEST_SERVER_HOST => "localhost:8888";
92 use constant TEST_PATH => "/tests/";
93 use constant CHROME_PATH => "/redirect.html";
94 use constant A11Y_PATH => "/redirect-a11y.html";
95 use constant TESTS_URL => "http://" . TEST_SERVER_HOST . TEST_PATH;
96 use constant CHROMETESTS_URL => "http://" . TEST_SERVER_HOST . CHROME_PATH;
97 use constant A11YTESTS_URL => "http://" . TEST_SERVER_HOST . A11Y_PATH;
98 # main browser chrome URL, same as browser.chromeURL pref
99 #ifdef MOZ_SUITE
100 use constant BROWSER_CHROME_URL => "chrome://navigator/content/navigator.xul";
101 #else
102 use constant BROWSER_CHROME_URL => "chrome://browser/content/browser.xul";
103 #endif
105 # Max time in seconds to wait for server startup before tests will fail -- if
106 # this seems big, it's mostly for debug machines where cold startup
107 # (particularly after a build) takes forever.
108 use constant SERVER_STARTUP_TIMEOUT => 45;
111 # Since some tests require cross-domain support in Mochitest, across ports,
112 # domains, subdomains, etc. we use a proxy autoconfig hack to map a bunch of
113 # servers onto localhost:8888. We have to grant them the same privileges as
114 # localhost:8888 here, since the browser only knows them as the URLs they're
115 # pretending to be.
116 my @servers = (
117 "localhost:8888", # MUST be first -- see PAC pref-setting code
118 "example.org:80",
119 "test1.example.org:80",
120 "test2.example.org:80",
121 "sub1.test1.example.org:80",
122 "sub1.test2.example.org:80",
123 "sub2.test1.example.org:80",
124 "sub2.test2.example.org:80",
125 "example.org:8000",
126 "test1.example.org:8000",
127 "test2.example.org:8000",
128 "sub1.test1.example.org:8000",
129 "sub1.test2.example.org:8000",
130 "sub2.test1.example.org:8000",
131 "sub2.test2.example.org:8000",
132 "example.com:80",
133 "test1.example.com:80",
134 "test2.example.com:80",
135 "sub1.test1.example.com:80",
136 "sub1.test2.example.com:80",
137 "sub2.test1.example.com:80",
138 "sub2.test2.example.com:80",
139 "sectest1.example.org:80",
140 "sub.sectest2.example.org:80",
141 "sub1.xn--lt-uia.example.org:8000", # U+00E4 U+006C U+0074
142 "sub2.xn--lt-uia.example.org:80", # U+00E4 U+006C U+0074
143 "xn--exmple-cua.test:80",
144 "sub1.xn--exmple-cua.test:80",
145 "xn--hxajbheg2az3al.xn--jxalpdlp:80", # Greek IDN for example.test
146 "sub1.xn--hxajbheg2az3al.xn--jxalpdlp:80",
150 my $profile = "mochitesttestingprofile";
151 my $profile_dir = "$FindBin::Bin/$profile";
153 # These are generated in mozilla/testing/mochitest/Makefile.in
154 #expand my $app = "$FindBin::Bin/" . __BROWSER_PATH__;
155 #expand my $dist_bin = "$FindBin::Bin/" . __XPC_BIN_PATH__;
156 #ifdef WIN32
157 #expand my $is_win32 = __WIN32__;
158 #else
159 my $is_win32 = 0;
160 #endif
161 my $is_mac = ($^O =~ m/darwin/);
162 my $unixish = (!($is_win32) && !($is_mac));
164 # Do everything.
165 main();
168 #################
169 # MAIN FUNCTION #
170 #################
172 sub main {
173 my ($close_when_done, $appoverride, $log_path, $autorun,
174 $console_level, $file_level, $help, $do_chrome, $test_path,
175 $do_browser_chrome, $do_a11y, %browser_env, %browser_args);
176 GetOptions("close-when-done!"=> \$close_when_done,
177 "appname:s"=> \$appoverride,
178 "log-file:s" => \$log_path,
179 "autorun!" => \$autorun,
180 "console-level:s" => \$console_level,
181 "file-level:s" => \$file_level,
182 "chrome!" => \$do_chrome,
183 "test-path:s" => \$test_path,
184 "browser-chrome!" => \$do_browser_chrome,
185 "a11y!" => \$do_a11y,
186 "setenv=s%" => \%browser_env,
187 "browser-arg=s%" => \%browser_args,
188 "help!" => \$help);
190 # if the switches include --help, exit and print directions
191 if ($help) {
192 usage_and_exit();
195 # we were passed an explicit path to the app
196 if ($appoverride) {
197 $app = $appoverride;
200 # make sure the application we're going to use exists
201 unless (-e $app) {
202 my $error_message = "\nError: Path \"$app\" doesn't exist.\n";
203 $error_message .= "Are you executing ";
204 $error_message .= "\$objdir/_tests/testing/mochitest/runtests.pl?\n\n";
205 die $error_message;
208 my $manifest = initializeProfile($app, $do_browser_chrome);
209 my $serverPid = startServer($close_when_done);
211 # If we're lucky, the server has fully started by now, and all paths are
212 # ready, etc. However, xpcshell cold start times suck, at least for debug
213 # builds. We'll try to connect to the server for 30 seconds or until we
214 # succeed, whichever is first. If we succeed, then we continue with
215 # execution. If we fail, we try to kill the server and exit with an error.
216 wait_for_server_startup($serverPid, SERVER_STARTUP_TIMEOUT);
218 my $url;
219 if ($do_chrome) {
220 $url = CHROMETESTS_URL . "?" . ($test_path ? "testPath=" . $test_path : "");
221 } elsif ($do_browser_chrome) {
222 # Tests will run from an overlay, no need to load any URL. We'll include
223 # the test path in the config file so the browser chrome harness can use it.
224 $url = "about:blank";
225 } elsif ($do_a11y) {
226 $url = A11YTESTS_URL . "?" . ($test_path ? "testPath=" . $test_path : "");
227 } else {
228 $url = TESTS_URL . ($test_path ? $test_path : "") . "?";
231 if ($do_browser_chrome) {
232 generate_test_config($autorun, $close_when_done, $log_path, $test_path);
233 } else {
234 if ($autorun) {
235 $url .= "&autorun=1";
237 if ($close_when_done) {
238 $url .= "&closeWhenDone=1";
240 if ($log_path) {
241 $url .= "&logFile=$log_path";
243 if ($file_level) {
244 $url .= "&fileLevel=$file_level";
246 if ($console_level) {
247 $url .= "&consoleLevel=$console_level";
251 my $test_start = runTests($url, \%browser_env, \%browser_args);
253 shutdownServer($serverPid);
255 # print test run times
256 my $test_finish = localtime();
257 print " started: $test_start\n";
258 print "finished: $test_finish\n";
260 # delete the profile and manifest
261 # rmtree($profile_dir, 0, 0);
262 unlink($manifest);
265 #######################
266 # COMMANDLINE USAGE #
267 #######################
269 sub usage_and_exit {
270 print "\n";
271 print "Usage instructons for runtests.pl.\n";
272 print "If --log-file is specified, --file-level must be specified as well.\n";
273 print "If --chrome is specified, chrome tests will be run instead of web content tests.\n";
274 print "If --browser-chrome is specified, browser-chrome tests will be run instead of web content tests.\n";
275 print "If --a11y is specified, a11y tests will be run instead of web content tests.";
276 print "\n\n";
277 print "Syntax:\n";
278 print " runtests.pl \\\n";
279 print " [--autorun] \\\n";
280 print " [--chrome] \\\n";
281 print " [--browser-chrome] \\\n";
282 print " [--a11y] \\\n";
283 print " [--close-when-done] \\\n";
284 print " [--appname=/path/to/app] \\\n";
285 print " [--log-file=/path/to/logfile] \\\n";
286 print " [--test-path=relative/path/to/tests] \\\n";
287 print " [--setenv=VAR=value] \\\n";
288 print " [--browser-arg=VAR=value] \\\n";
289 print " [--file-level=DEBUG|INFO|ERROR|FATAL|WARNING] \\\n";
290 print " [--console-level=DEBUG|INFO|ERROR|FATAL|WARNING] \n\n";
291 exit(1);
294 #######################
295 # MAKE A WINDOWS PATH #
296 #######################
298 #ifdef IS_CYGWIN
300 sub winPathFromDir {
301 my ($path) = abs_path(@_);
303 # Use external cygpath command to get the windows-like path
304 $path = `cygpath -w $path`;
306 # Just remove the traling CR char
307 chop($path);
308 return $path;
311 #else
312 # Non-cygwin version
314 sub winPathFromDir {
315 my ($path) = abs_path(@_);
317 # This is a windows mingw32 build, we need to translate the
318 # given path to the "actual" windows path.
320 my @m = `mount`;
321 my $matchlen;
322 my $bestmatch;
323 my $mount;
325 #example mount output:
326 # C:\DOCUME~1\Temp on /tmp type user (binmode,noumount)
327 # c:\ActiveState\perl on /perl type user (binmode)
328 # C:\msys\1.0\bin on /usr/bin type user (binmode,cygexec,noumount)
329 # C:\msys\1.0\bin on /bin type user (binmode,cygexec,noumount)
330 foreach $mount (@m) {
331 if ( $mount =~ /(.*) on ([^ ]*) type /) {
332 my ($mingw, $real)=($2, $1);
333 if ($path =~ /^$mingw/i) {
334 # the path starts with the path we
335 # found on this line in the mount output
336 my $len = length($mingw);
337 if ($len > $matchlen) {
338 # we remember the match that is the longest
339 $matchlen = $len;
340 $bestmatch = $real;
345 if (!$matchlen) {
346 die "Serious error, can't find our \"real\" path!\n";
349 my ($volume,$directories,$file) =
350 File::Spec->splitpath(substr($path, $matchlen), 1);
351 my @dirs = File::Spec->splitdir( $directories );
352 return $bestmatch . "\\" . join "\\", @dirs;
355 # End of non-cygwin version
356 #endif
358 ##################
359 # SERVER STARTUP #
360 ##################
362 # Start up the server, and let the server script handle shutdown if
363 # we're closing when done. (We'll kill it later if it goes zombie
364 # somehow, but that shouldn't be the way it happens except if
365 # something really breaks.)
367 sub startServer {
368 my ($close_when_done) = @_;
369 my $pid = fork();
370 if ($pid == 0) {
371 # Run the server
372 my $status = 0;
374 if ($close_when_done) {
375 $ENV{'CLOSE_WHEN_DONE'} = '1';
378 if ($unixish) {
379 $ENV{'LD_LIBRARY_PATH'} = $dist_bin;
380 $ENV{'MOZILLA_FIVE_HOME'} = $dist_bin;
383 my @runargs = ("$dist_bin/xpcshell", "-v", "170");
385 # this path is passed as a string, so we need to convert it on win32
386 if ($is_win32) {
387 push(@runargs, "-f", winPathFromDir($FindBin::Bin) . "\\httpd.js");
388 push(@runargs, "-f", winPathFromDir($FindBin::Bin) . "\\server.js");
389 } else {
390 push(@runargs, "-f", $FindBin::Bin . "/httpd.js");
391 push(@runargs, "-f", $FindBin::Bin . "/server.js");
393 print "@runargs\n";
394 exec @runargs or die("Error running server: $!\n");
397 return ($pid);
401 ##############
402 # TEST SETUP #
403 ##############
405 sub generate_test_config {
406 my ($autorun, $close_when_done, $log_path, $test_path) = @_;
407 $autorun = $autorun || 0;
408 $close_when_done = $close_when_done || 0;
409 $log_path = $log_path || "";
410 $log_path =~ s/\\/\\\\/g;
411 $test_path = $test_path || "";
412 $test_path =~ s/\\/\\\\/g;
414 my $config_content = <<CONFIGEND;
416 autoRun: $autorun,
417 closeWhenDone: $close_when_done,
418 logPath: "$log_path",
419 testPath: "$test_path"
421 CONFIGEND
423 open(CONFIGOUTFILE, ">$profile_dir/testConfig.js") ||
424 die("Could not open testConfig.js file $!");
425 print CONFIGOUTFILE ($config_content);
426 close(CONFIGOUTFILE);
429 sub initializeProfile {
430 my ($app_path, $do_browser_tests) = @_;
431 my $pref_content = <<PREFEND;
432 user_pref("browser.dom.window.dump.enabled", true);
433 user_pref("dom.disable_open_during_load", false);
434 user_pref("dom.max_script_run_time", 0); // no slow script dialogs
435 user_pref("signed.applets.codebase_principal_support", true);
436 user_pref("security.warn_submit_insecure", false);
437 user_pref("browser.shell.checkDefaultBrowser", false);
438 user_pref("browser.warnOnQuit", false);
439 user_pref("accessibility.typeaheadfind.autostart", false);
440 user_pref("javascript.options.showInConsole", true);
441 user_pref("layout.debug.enable_data_xbl", true);
442 user_pref("browser.EULA.override", true);
443 PREFEND
445 # Grant God-power to all the servers on which tests can run.
446 my $i = 1;
447 my $server;
448 foreach $server (@servers) {
449 $pref_content .= <<SERVERPREFEND;
450 user_pref("capability.principal.codebase.p$i.granted", "UniversalXPConnect UniversalBrowserRead UniversalBrowserWrite UniversalPreferencesRead UniversalPreferencesWrite UniversalFileRead");
451 user_pref("capability.principal.codebase.p$i.id", "http://$server");
452 user_pref("capability.principal.codebase.p$i.subjectName", "");
453 SERVERPREFEND
454 $i++;
457 # Now add the two servers that do NOT have God-power so we can properly test
458 # the granting and receiving of God-power
459 push(@servers,
460 "sectest2.example.org:80",
461 "sub.sectest1.example.org:80");
464 # Now actually create the preference to make the proxying happen, stripping
465 # off the first server because it's the one to which we proxy all the others.
466 my $quotedServers = join(", ", map("'" . $_ . "'", @servers[1 .. $#servers]));
468 my $pacURL = "data:text/plain,";
469 $pacURL .= "function FindProxyForURL(url, host) ";
470 $pacURL .= "{ ";
471 $pacURL .= " var servers = [$quotedServers]; ";
472 $pacURL .= " var regex = ";
473 $pacURL .= " new RegExp('http://(?:[^/@]*@)?(.*?(:\\\\\\\\d+)?)/'); ";
474 $pacURL .= " var matches = regex.exec(url); ";
475 $pacURL .= " if (!matches) ";
476 $pacURL .= " return 'DIRECT'; ";
477 $pacURL .= " var hostport = matches[1], port = matches[2]; ";
478 $pacURL .= " if (!port) ";
479 $pacURL .= " hostport += ':80'; ";
480 $pacURL .= " if (servers.indexOf(hostport) >= 0) ";
481 $pacURL .= " return 'PROXY localhost:8888'; ";
482 $pacURL .= " return 'DIRECT'; ";
483 $pacURL .= "}";
485 $pref_content .= <<PROXYPREFEND;
486 user_pref("network.proxy.type", 2);
487 user_pref("network.proxy.autoconfig_url", "$pacURL");
488 PROXYPREFEND
491 my $chrome_content = <<CHROMEEND;
492 \@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"); /* set default namespace to XUL */
493 toolbar,
494 toolbarpalette {
495 background-color: rgb(235, 235, 235) !important;
497 toolbar#nav-bar {
498 background-image: none !important;
500 CHROMEEND
502 # in case we died for some reason on the last run
503 rmtree($profile_dir, 0, 0);
505 my $chrome_dir = "$profile_dir/chrome";
506 mkdir($profile_dir);
507 mkdir($chrome_dir);
509 # append magic prefs to user.js
510 open(PREFOUTFILE, ">>$profile_dir/user.js") ||
511 die("Could not open user.js file $!\n");
512 print PREFOUTFILE ($pref_content);
513 close(PREFOUTFILE) or die("Couldn't close user.js file: $!\n");
515 # add userChrome.css
516 open(CHROMEOUTFILE, ">>$chrome_dir/userChrome.css") ||
517 die("Could not open userChrome.css file $!");
518 print CHROMEOUTFILE ($chrome_content);
519 close(CHROMEOUTFILE);
521 # register our chrome dir
522 my $chrometest_dir = "$FindBin::Bin/";
523 if ($is_win32) {
524 # we don't have LWP, so we can't use its file url stuff
525 $chrometest_dir = winPathFromDir($chrometest_dir) . "\\";
526 $chrometest_dir =~ s/\\/\//g;
527 $chrometest_dir = "file:///$chrometest_dir";
530 my($filename, $directories, $suffix) = fileparse($app_path);
531 my $manifest = $directories . "chrome/mochikit.manifest";
532 open(MANIFEST, ">$manifest") ||
533 die("Could not open manifest file $!");
534 print MANIFEST ("content mochikit $chrometest_dir contentaccessible=yes\n");
535 if ($do_browser_tests) {
536 print MANIFEST ("overlay " . BROWSER_CHROME_URL . " chrome://mochikit/content/browser-test-overlay.xul\n");
538 close(MANIFEST);
540 return $manifest;
543 ###################
544 # WAIT FOR SERVER #
545 ###################
547 sub wait_for_server_startup {
548 my ($pid, $timeout) = @_;
550 die ("Invalid timeout value passed to wait_for_server_startup()\n")
551 if ($timeout <= 0);
553 eval {
554 my $loop_count = 0;
555 while ($loop_count++ < $timeout) {
556 last if (-e "$profile_dir/server_alive.txt");
557 sleep 1;
560 die "timeout" if ($loop_count >= $timeout);
561 return "done";
564 my $time_out_message;
565 if ($@) {
566 if ($@ =~ /timeout/) {
567 $time_out_message = "\nError: ";
568 $time_out_message = "Timed out while waiting for server startup.\n";
569 } else {
570 # Died for some other reason.
571 $time_out_message = "An unknown error occurred ";
572 $time_out_message .= "while waiting for server startup.\n";
576 if ($time_out_message) {
577 kill_process($pid);
578 print $time_out_message;
579 exit(1);
583 sub kill_process {
584 my ($target_pid) = @_;
585 my $start_time = time();
587 # Try to kill and wait 10 seconds, then try a kill -9
588 my $sig;
589 for $sig ('TERM', 'KILL') {
590 print "kill $sig $target_pid\n";
591 kill $sig => $target_pid;
592 my $interval_start = time;
593 while (time - $interval_start < 10) {
594 # the following will work with 'cygwin' perl on win32, but not
595 # with 'MSWin32' (ActiveState) perl
596 my $pid = waitpid($target_pid, POSIX::WNOHANG());
597 if (($pid == $target_pid and POSIX::WIFEXITED($?)) or $pid == -1) {
598 my $secs = time - $start_time;
599 $secs = $secs == 1 ? '1 second' : "$secs seconds";
600 print "Process killed. Took $secs to die.\n";
601 return;
603 sleep 1;
606 die "Unable to kill process: $target_pid";
609 ##################
610 # TEST EXECUTION #
611 ##################
613 sub runTests {
614 my ($test_url, $browser_env, $browser_args) = @_;
616 # mark the start
617 my $test_start = localtime();
619 # set env vars so Firefox doesn't quit weirdly and break the script
620 $ENV{'NO_EM_RESTART'} = '1';
621 $ENV{'XPCOM_DEBUG_BREAK'} = 'warn';
623 if ($unixish) {
624 $ENV{'LD_LIBRARY_PATH'} = $dist_bin;
625 $ENV{'MOZILLA_FIVE_HOME'} = $dist_bin;
628 for my $key (keys(%{$browser_env})) {
629 $ENV{$key} = $browser_env->{$key};
632 my $profile_arg = "$profile_dir";
633 if ($is_win32) {
634 $profile_arg = winPathFromDir($profile_dir);
637 # now run with the profile we created
639 # On Windows and Linux, the application is focused for us. On OS X, we
640 # need to use applescript to focus the app and then set the url.
641 my $rc = -1;
642 if (!$is_mac) {
643 my @runargs = ($app, '-no-remote', '-profile', $profile_arg);
644 if ($browser_args) {
645 foreach my $key (keys %$browser_args) {
646 push(@runargs, ($key,
647 $browser_args->{$key})
651 push(@runargs, $test_url);
652 $rc = 0xffff & system @runargs;
653 } else {
654 $rc = executeMac($profile_arg, $test_url, $browser_args);
657 if ($rc != 0) {
658 print "FAIL Exited with code $rc during test run\n";
661 return $test_start;
664 sub executeMac {
665 my ($profile_arg, $test_url, $browser_args) = @_;
666 my $pid = fork();
667 if (not defined $pid) {
668 die "cannot fork: $!";
669 } elsif ($pid == 0) {
670 # run only the executable so we get a pid we can focus
671 if ($app !~ /-bin$/) {
672 $app .= "-bin";
674 my @runargs = ($app, '-foreground', '-no-remote', '-profile', $profile_arg);
675 if ($browser_args) {
676 foreach my $key (keys %$browser_args) {
677 push(@runargs, ($key,
678 $browser_args->{$key})
682 push(@runargs, $test_url);
684 # redirect stderr to stdout for easier buildbot / tinderbox logging
685 #$ENV{'XPCOM_DEBUG_BREAK'} = 'stack';
686 open (STDERR, '>&', \*STDOUT) || die $!;
687 exec @runargs or die("Error starting application: $!\n");
688 } else {
689 waitpid($pid,0);
692 # return the exit code we received from waitpid
693 return $?;
696 ##################
697 # SHUT DOWN #
698 ##################
700 sub shutdownServer {
701 my ($pid) = @_;
702 kill_process($pid);