Make run-api-tests less chatty.
[WebKit-https.git] / Tools / Scripts / run-api-tests
1 #!/usr/bin/perl -w
2
3 # Copyright (C) 2010, 2011 Apple Inc. All rights reserved.
4 #
5 # Redistribution and use in source and binary forms, with or without
6 # modification, are permitted provided that the following conditions
7 # are met:
8 # 1. Redistributions of source code must retain the above copyright
9 #    notice, this list of conditions and the following disclaimer.
10 # 2. Redistributions in binary form must reproduce the above copyright
11 #    notice, this list of conditions and the following disclaimer in the
12 #    documentation and/or other materials provided with the distribution.
13 #
14 # THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
15 # AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
16 # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
17 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
18 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
24 # THE POSSIBILITY OF SUCH DAMAGE.
25
26 # Features to add:
27 #   - Command line option to run a single test.
28 #   - Command line option to run all tests in a suite.
29
30 use strict;
31 use warnings;
32
33 use File::Basename;
34 use FindBin;
35 use Getopt::Long qw(:config pass_through);
36 use IPC::Open3;
37 use lib $FindBin::Bin;
38 use webkitdirs;
39 use Term::ANSIColor qw(:constants);
40
41 sub dumpAllTests();
42 sub runAllTests();
43 sub runAllTestsInSuite($);
44 sub runTest($$);
45 sub populateTests();
46 sub buildTestTool();
47
48 my $showHelp = 0;
49 my $verbose = 0;
50 my $dump = 0;
51
52 my $programName = basename($0);
53 my $usage = <<EOF;
54 Usage: $programName [options]
55   --help                Show this help message
56   -v|--verbose          Verbose output
57   -d|--dump-tests       Dump the names of testcases without running them
58 EOF
59
60 GetOptions(
61     'help' => \$showHelp,
62     'verbose|v' => \$verbose,
63     'dump|d' => \$dump,
64 );
65
66 if ($showHelp) {
67    print STDERR $usage;
68    exit 1;
69 }
70
71 setConfiguration();
72 buildTestTool();
73 setPathForRunningWebKitApp(\%ENV);
74 my %testsToRun = populateTests();
75
76 if ($dump) {
77     dumpAllTests();
78     exit 0;
79 }
80
81 runAllTests();
82
83 sub dumpAllTests()
84 {
85     print "Dumping test cases\n";
86     print "------------------\n";
87     for my $suite (keys %testsToRun) {
88         print $suite . ":\n";
89         print map { "    " . $_ . "\n" } @{ $testsToRun{$suite} };
90     }
91     print "------------------\n";
92 }
93
94 sub runAllTests()
95 {
96     my $anyFailures = 0;
97     for my $suite (keys %testsToRun) {
98         my $failed = runAllTestsInSuite($suite);
99         if ($failed) {
100             $anyFailures = 1;
101         }
102     }
103     return $anyFailures;
104 }
105
106 sub runAllTestsInSuite($)
107 {
108     my ($suite) = @_;
109     print "Suite: $suite\n";
110
111     my $anyFailures = 0;
112     for my $test (@{$testsToRun{$suite}}) {
113         my $failed = runTest($suite, $test);
114         if ($failed) {
115             $anyFailures = 1;
116         }
117     }
118     
119     return $anyFailures;
120 }
121
122 sub runTest($$)
123 {
124     my ($suite, $testName) = @_;
125     my $test = $suite . "/" . $testName;
126
127     print "    Test: $testName -> ";
128
129     my $result = 0;
130     if (isAppleMacWebKit()) {
131         my $productDir = productDir();
132         $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
133         $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
134         my $apiTesterPath = "$productDir/TestWebKitAPI";
135
136         local *DEVNULL;
137         my ($childIn, $childOut, $childErr);
138         unless ($verbose) {
139             open(DEVNULL, ">", File::Spec->devnull()) or die "Failed to open /dev/null";
140             $childOut = ">&DEVNULL";
141             $childErr = ">&DEVNULL";
142         } else {
143             $childOut = ">&STDOUT";
144             $childErr = ">&STDERR";
145         }
146
147         my $pid;
148         if (architecture()) {
149             $pid = open3($childIn, $childOut, $childErr, "arch", "-" . architecture(), $apiTesterPath, $test, @ARGV) or die "Failed to run test: $test.";
150         } else {
151             $pid = open3($childIn, $childOut, $childErr, $apiTesterPath, $test, @ARGV) or die "Failed to run test: $test.";
152         }
153
154         close($childIn);
155         close($childOut);
156         close($childErr);
157         close(DEVNULL) unless ($verbose);
158
159         waitpid($pid, 0);
160         my $result = $?;
161     } elsif (isAppleWinWebKit()) {
162         my $apiTesterNameSuffix;
163         if (configurationForVisualStudio() ne "Debug_All") {
164             $apiTesterNameSuffix = "";
165         } else {
166             $apiTesterNameSuffix = "_debug";
167         }
168         my $apiTesterPath = File::Spec->catfile(productDir(), "TestWebKitAPI$apiTesterNameSuffix.exe");
169         $result = system $apiTesterPath, $test, @ARGV;
170     } else {
171         die "run-api-tests is not supported on this platform.\n"
172     }
173     
174     if ($result == 0) {
175         print BOLD GREEN, "Passed", RESET, "\n";
176     } else {
177         print BOLD RED, "Failed", RESET, "\n";
178     }
179 }
180
181
182 sub populateTests()
183 {
184     my @tests;
185
186     if (isAppleMacWebKit()) {
187         my $productDir = productDir();
188         $ENV{DYLD_FRAMEWORK_PATH} = $productDir;
189         $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
190         my $apiTesterPath = "$productDir/TestWebKitAPI";
191
192         local *DEVNULL;
193         my ($childIn, $childOut, $childErr);
194         unless ($verbose) {
195             open(DEVNULL, ">", File::Spec->devnull()) or die "Failed to open /dev/null";
196             $childErr = ">&DEVNULL";
197         } else {
198             $childErr = ">&STDERR";
199         }
200
201         my $pid;
202         if (architecture()) {
203             $pid = open3($childIn, $childOut, $childErr, "arch", "-" . architecture(), $apiTesterPath, "--dump-tests") or die "Failed to build list of tests!";
204         } else {
205             $pid = open3($childIn, $childOut, $childErr, $apiTesterPath, "--dump-tests") or die "Failed to build list of tests!";
206         }
207
208         close($childIn);
209         @tests = <$childOut>;
210         close($childOut);
211         close($childErr);
212         close(DEVNULL) unless ($verbose);
213
214         waitpid($pid, 0);
215         my $result = $?;
216
217         if ($result) {
218             print STDERR "Failed to build list of tests!\n";
219             exit exitStatus($result);
220         }
221     } elsif (isAppleWinWebKit()) {
222         my $apiTesterNameSuffix;
223         if (configurationForVisualStudio() ne "Debug_All") {
224             $apiTesterNameSuffix = "";
225         } else {
226             $apiTesterNameSuffix = "_debug";
227         }
228         my $apiTesterPath = File::Spec->catfile(productDir(), "TestWebKitAPI$apiTesterNameSuffix.exe");
229         open(TESTS, "-|", $apiTesterPath, "--dump-tests") or die $!;
230         @tests = <TESTS>;
231         close(TESTS) or die $!;
232     } else {
233         die "run-api-tests is not supported on this platform.\n"
234     }
235
236     my %keyedTests = ();
237     for my $test (@tests) {
238         $test =~ s/[\r\n]*$//;
239         my ($suite, $testName) = split(/\//, $test);
240         push @{$keyedTests{$suite}}, $testName;
241     }
242     
243     return %keyedTests;
244 }
245
246 sub buildTestTool()
247 {
248     chdirWebKit();
249
250     my $buildTestTool = "build-api-tests";
251     print STDERR "Running $buildTestTool\n";
252
253     local *DEVNULL;
254     my ($childIn, $childOut, $childErr);
255     unless ($verbose) {
256         open(DEVNULL, ">", File::Spec->devnull()) or die "Failed to open /dev/null";
257         $childOut = ">&DEVNULL";
258         $childErr = ">&DEVNULL";
259     } else {
260         # When not quiet, let the child use our stdout/stderr.
261         $childOut = ">&STDOUT";
262         $childErr = ">&STDERR";
263     }
264
265     my @args = argumentsForConfiguration();
266     my $buildProcess = open3($childIn, $childOut, $childErr, "Tools/Scripts/$buildTestTool", @args) or die "Failed to run " . $buildTestTool;
267
268     close($childIn);
269     close($childOut);
270     close($childErr);
271     close(DEVNULL) unless ($verbose);
272
273     waitpid($buildProcess, 0);
274     my $buildResult = $?;
275
276     if ($buildResult) {
277         print STDERR "Compiling TestWebKitAPI failed!\n";
278         exit exitStatus($buildResult);
279     }
280 }