Get rid of forward exit on DoubleAsInt32
[WebKit-https.git] / Tools / Scripts / run-javascriptcore-tests
1 #!/usr/bin/perl -w
2
3 # Copyright (C) 2005, 2013 Apple Computer, Inc.  All rights reserved.
4 # Copyright (C) 2007 Eric Seidel <eric@webkit.org>
5 #
6 # Redistribution and use in source and binary forms, with or without
7 # modification, are permitted provided that the following conditions
8 # are met:
9 #
10 # 1.  Redistributions of source code must retain the above copyright
11 #     notice, this list of conditions and the following disclaimer. 
12 # 2.  Redistributions in binary form must reproduce the above copyright
13 #     notice, this list of conditions and the following disclaimer in the
14 #     documentation and/or other materials provided with the distribution. 
15 # 3.  Neither the name of Apple Computer, Inc. ("Apple") nor the names of
16 #     its contributors may be used to endorse or promote products derived
17 #     from this software without specific prior written permission. 
18 #
19 # THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY
20 # EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
21 # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
22 # DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY
23 # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
24 # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
25 # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
26 # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
30 # Script to run the WebKit Open Source Project JavaScriptCore tests (adapted from Mozilla),
31 # as well as other tests: testapi on Mac and LayoutTests/js.
32
33 use strict;
34 use FindBin;
35 use Getopt::Long qw(:config pass_through);
36 use List::Util qw(min max);
37 use lib $FindBin::Bin;
38 use webkitdirs;
39 use POSIX;
40
41 # determine configuration
42 setConfiguration();
43 my $configuration = configuration();
44
45 my @testsToSkip = (
46     # Various ecma/Date tests sometimes fail on Windows (but not Mac) https://bugs.webkit.org/show_bug.cgi?id=25160
47     "ecma/Date/15.9.2.1.js",
48     "ecma/Date/15.9.2.2-1.js",
49     "ecma/Date/15.9.2.2-2.js",
50     "ecma/Date/15.9.2.2-3.js",
51     "ecma/Date/15.9.2.2-4.js",
52     "ecma/Date/15.9.2.2-5.js",
53     "ecma/Date/15.9.2.2-6.js",
54     # ecma_3/Date/15.9.5.7.js fails on Mac (but not Windows) https://bugs.webkit.org/show_bug.cgi?id=25161
55     "ecma_3/Date/15.9.5.6.js",
56     "ecma_3/Date/15.9.5.7.js",
57     # These three fail on Linux in certain time zones, at certain times
58     # of the year (!): https://bugs.webkit.org/show_bug.cgi?id=71371
59     "ecma/Date/15.9.5.14.js",
60     "ecma/Date/15.9.5.31-1.js",
61     "ecma/Date/15.9.5.34-1.js",
62 );
63
64 my $jsDriverArgs = "-L " . join(" ", @testsToSkip);
65 # These variables are intentionally left undefined.
66 my $root;
67 my $showHelp;
68 my $extraTests;
69
70 my $buildJSC = 1;
71
72 my $runTestAPI = isAppleMacWebKit() || isAppleWinWebKit() || isWinCairo();
73
74 my $runMozilla = 0;
75
76 # FIXME: run-jsc-stress-tests should be ported to other platforms.
77 # https://bugs.webkit.org/show_bug.cgi?id=120809
78 my $runJSCStress = !isAppleWinWebKit();
79
80 my $enableFTL = 0;
81
82 my $createTarball = 0;
83 my $remoteHost = 0;
84
85 my $programName = basename($0);
86 my $buildJSCDefault = $buildJSC ? "will check" : "will not check";
87 my $testapiDefault = $runTestAPI ? "will run" : "will not run";
88 my $mozillaDefault = $runMozilla ? "will run" : "will not run";
89 my $jscStressDefault = $runJSCStress ? "will run" : " will not run";
90 my $usage = <<EOF;
91 Usage: $programName [options] [options to pass to build system]
92   --help                        Show this help message
93   --jsDriver-args=              A string of arguments to pass to jsDriver.pl
94   --root=                       Path to pre-built root containing jsc
95   --extra-tests=                Path to a file containing extra tests
96   --[no-]ftl-jit                Turn the FTL JIT on or off
97   --[no-]build                  Check (or don't check) to see if the jsc build is up-to-date (default: $buildJSCDefault)
98   --[no-]testapi                Run (or don't run) testapi (default: $testapiDefault)
99   --[no-]jsc-stress             Run (or don't run) the JSC stress tests (default: $jscStressDefault)
100   --tarball                     Create a tarball of the bundle produced by running the JSC stress tests.
101   --remote=                     Run the JSC stress tests on the specified remote host. Implies --tarball.
102 EOF
103
104 GetOptions(
105     'j|jsDriver-args=s' => \$jsDriverArgs,
106     'root=s' => \$root,
107     'extra-tests=s' => \$extraTests,
108     'build!' => \$buildJSC,
109     'ftl-jit!' => \$enableFTL,
110     'testapi!' => \$runTestAPI,
111     'jsc-stress!' => \$runJSCStress,
112     'tarball!' => \$createTarball,
113     'remote=s' => \$remoteHost,
114     'help' => \$showHelp
115 );
116
117 # Assume any arguments left over from GetOptions are assumed to be build arguments
118 my @buildArgs = @ARGV;
119
120 # The --ftl-jit argument gets passed as a build argument.
121 if ($enableFTL) {
122     push(@buildArgs, '--ftl-jit');
123 }
124
125 # Arguments passed to --jsDriver-args (if any) are passed to jsDriver.pl
126 my @jsArgs = split(" ", $jsDriverArgs);
127
128 if ($showHelp) {
129    print STDERR $usage;
130    exit 1;
131 }
132
133 setConfigurationProductDir(Cwd::abs_path($root)) if (defined($root));
134
135 if (!defined($root) && $buildJSC) {
136     chdirWebKit();
137
138     push(@buildArgs, argumentsForConfiguration());
139     
140     print "Running: build-jsc " . join(" ", @buildArgs) . "\n";
141     my $buildResult = system "perl", "Tools/Scripts/build-jsc", @buildArgs;
142     if ($buildResult) {
143         print STDERR "Compiling jsc failed!\n";
144         exit exitStatus($buildResult);
145     }
146 }
147
148
149 my $productDir = jscProductDir();
150 $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
151 $ENV{JSC_timeout} = 60; # Set a 60 second timeout on all jsc tests.
152 setPathForRunningWebKitApp(\%ENV) if isCygwin();
153
154 sub testapiPath($)
155 {
156     my ($productDir) = @_;
157     my $jscName = "testapi";
158     $jscName .= "_debug" if configuration() eq "Debug_All";
159     return "$productDir/$jscName";
160 }
161
162 #run api tests
163 if ($runTestAPI) {
164     chdirWebKit();
165     chdir($productDir) or die "Failed to switch directory to '$productDir'\n";
166     my @command = (testapiPath($productDir));
167     unshift @command, ("xcrun", "-sdk", xcodeSDK(), "sim") if willUseIOSSimulatorSDKWhenBuilding();
168
169     # Use an "indirect object" so that system() won't get confused if the path
170     # contains spaces (see perldoc -f exec).
171     my $testapiResult = system { $command[0] } @command;
172     exit exitStatus($testapiResult)  if $testapiResult;
173 }
174
175 # Find JavaScriptCore directory
176 chdirWebKit();
177
178 $runMozilla = !$runJSCStress;
179
180 my %mozillaFailures;
181 my %newMozillaFailures;
182
183 if ($runMozilla) {
184     chdir("Source/JavaScriptCore");
185     chdir "tests/mozilla" or die "Failed to switch directory to 'tests/mozilla'\n";
186     my @jsMozillaDriverCmd = ("perl", "jsDriver.pl", "-e", "squirrelfish", "-s", jscPath($productDir), "-f", "actual.html", @jsArgs);
187     if (isGtk() || isEfl()) {
188         my @jhbuildPrefix = sourceDir() . "/Tools/jhbuild/jhbuild-wrapper";
189     
190         if (isEfl()) {
191             push(@jhbuildPrefix, '--efl');
192         } elsif (isGtk()) {
193             push(@jhbuildPrefix, '--gtk');
194         }
195         push(@jhbuildPrefix, 'run');
196     
197         unshift(@jsMozillaDriverCmd, @jhbuildPrefix);
198     } elsif (isIOSWebKit() && willUseIOSSimulatorSDKWhenBuilding()) {
199         push @jsMozillaDriverCmd, ("--sdk", xcodeSDK());
200     }
201     print "Running: " . join(" ", @jsMozillaDriverCmd) . "\n";
202     my $result = system(@jsMozillaDriverCmd);
203     exit exitStatus($result)  if $result;
204     
205     open EXPECTED, "expected.html" or die "Failed to open 'expected.html'\n";
206     while (<EXPECTED>) {
207         last if /failures reported\.$/;
208     }
209     while (<EXPECTED>) {
210         chomp;
211         $mozillaFailures{$_} = 1;
212     }
213     close EXPECTED;
214     
215     open ACTUAL, "actual.html" or die "Failed to open 'actual.html'";
216     while (<ACTUAL>) {
217         last if /failures reported\.$/;
218     }
219     while (<ACTUAL>) {
220         chomp;
221         if ($mozillaFailures{$_}) {
222             delete $mozillaFailures{$_};
223         } else {
224             $newMozillaFailures{$_} = 1;
225         }
226     }
227     close ACTUAL;
228 }
229
230 chdirWebKit();
231 my $jscStressResultsDir = $productDir . "/jsc-stress-results";
232
233 if ($runJSCStress) {
234     # Set LANG environment variable so the stress tests will work with newer ruby (<rdar://problem/15010705>)
235     $ENV{LANG}="en_US.UTF-8";
236     my @jscStressDriverCmd = (
237         "/usr/bin/env", "ruby", "Tools/Scripts/run-jsc-stress-tests",
238         "-j", jscPath($productDir), "-o", $jscStressResultsDir,
239         "PerformanceTests/SunSpider/tests/sunspider-1.0",
240         "PerformanceTests/SunSpider/no-architecture-specific-optimizations.yaml",
241         "PerformanceTests/SunSpider/tests/v8-v6",
242         "Source/JavaScriptCore/tests/mozilla/mozilla-tests.yaml",
243         "Source/JavaScriptCore/tests/stress",
244         "LayoutTests/js/regress/script-tests",
245         "PerformanceTests/SunSpider/profiler-test.yaml",
246         "LayoutTests/jsc-layout-tests.yaml"
247     );
248     if ($enableFTL) {
249         push(@jscStressDriverCmd, "--ftl-jit");
250     }
251     if ($createTarball) {
252         push(@jscStressDriverCmd, "--tarball");
253     }
254     if ($remoteHost) {
255         push(@jscStressDriverCmd, "--remote");
256         push(@jscStressDriverCmd, $remoteHost);
257     }
258     if (defined($extraTests)) {
259         push(@jscStressDriverCmd, $extraTests);
260     }
261     if (defined($ENV{"EXTRA_JSC_TESTS"})) {
262         push(@jscStressDriverCmd, $ENV{"EXTRA_JSC_TESTS"});
263     }
264     print "Running: " . join(" ", @jscStressDriverCmd) . "\n";
265     my $result = system(@jscStressDriverCmd);
266     exit exitStatus($result) if $result;
267 }
268
269 my $numNewMozillaFailures = keys %newMozillaFailures;
270 if ($numNewMozillaFailures) {
271     print "\n** The following Mozilla test failures have been introduced:\n";
272     foreach my $mozillaFailure (sort keys %newMozillaFailures) {
273         print "\t$mozillaFailure\n";
274     }
275 }
276
277 my $numOldMozillaFailures = keys %mozillaFailures;
278 if ($numOldMozillaFailures) {
279     print "\nYou fixed the following test";
280     print "s" if $numOldMozillaFailures != 1;
281     print ":\n";
282     foreach my $mozillaFailure (sort keys %mozillaFailures) {
283         print "\t$mozillaFailure\n";
284     }
285 }
286
287 sub readAllLines
288 {
289     my ($filename) = @_;
290     my @array = ();
291     eval {
292         open FILE, $filename or die;
293         while (<FILE>) {
294             push @array, $_;
295         }
296         close FILE;
297     };
298     return @array;
299 }
300
301 sub printThingsFound
302 {
303     my ($number, $label, $pluralLabel, $verb) = @_;
304     print "    $number ";
305     if ($number == 1) {
306         print $label;
307     } else {
308         print $pluralLabel;
309     }
310     print " $verb.\n";
311 }
312
313 my @jscStressFailList = readAllLines($jscStressResultsDir . "/failed");
314 my $numJSCStressFailures = @jscStressFailList;
315
316 if ($numJSCStressFailures) {
317     print "\n** The following JSC stress test failures have been introduced:\n";
318     foreach my $testFailure (@jscStressFailList) {
319         print "\t$testFailure";
320     }
321 }
322
323 print "\n";
324
325 if ($runMozilla) {
326     print "Results for Mozilla tests:\n";
327     printThingsFound($numNewMozillaFailures, "regression", "regressions", "found");
328     printThingsFound($numOldMozillaFailures, "test", "tests", "fixed");
329     print "    OK.\n" if $numNewMozillaFailures == 0;
330     
331     print "\n";
332 }
333
334 if ($runJSCStress) {
335     print "Results for JSC stress tests:\n";
336     printThingsFound($numJSCStressFailures, "failure", "failures", "found");
337     print "    OK.\n" if $numJSCStressFailures == 0;
338     
339     print "\n";
340 }
341
342 exit(1)  if ($runMozilla && $numNewMozillaFailures) || ($runJSCStress && $numJSCStressFailures);