[CherryPick] Input Method upversion
[framework/web/webkit-efl.git] / Tools / Scripts / run-api-tests
1 #!/usr/bin/perl -w
2
3 # Copyright (C) 2010, 2011, 2012 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 use strict;
27 use warnings;
28
29 use File::Basename;
30 use FindBin;
31 use Getopt::Long qw(:config pass_through);
32 use IPC::Open3;
33 use lib $FindBin::Bin;
34 use webkitdirs;
35 use VCSUtils;
36
37 sub buildTestTool();
38 sub dumpTestsBySuite(\@);
39 sub listAllTests();
40 sub runTest($$$);
41 sub runTestsBySuite(\@$);
42 sub prepareEnvironmentForRunningTestTool();
43 sub testToolPath();
44
45 # Defined in VCSUtils.
46 sub possiblyColored($$);
47
48 # Timeout for individual test, in sec
49 my $timeout = 10;
50
51 my $showHelp = 0;
52 my $verbose = 0;
53 my $dumpTests = 0;
54 my $build = 1;
55 my $buildDefault = $build ? "build" : "do not build";
56 my @testsFailed;
57 my @testsTimedOut;
58
59 my $programName = basename($0);
60 my $usage = <<EOF;
61 Usage: $programName [options] [suite or test prefixes]
62   --help                Show this help message
63   -v|--verbose          Verbose output
64   -d|--dump-tests       Dump the names of testcases without running them
65   --[no-]build          Build (or do not build) unit tests prior to running (default: $buildDefault)
66   --chromium            Run the Chromium port on Mac/Win/Linux
67 EOF
68
69 GetOptions(
70     'help' => \$showHelp,
71     'verbose|v' => \$verbose,
72     'dump|d' => \$dumpTests,
73     'build!' => \$build
74 );
75
76 if ($showHelp) {
77    print STDERR $usage;
78    exit 1;
79 }
80
81 setConfiguration();
82 buildTestTool() if $build;
83 setPathForRunningWebKitApp(\%ENV);
84 my @testsToRun = listAllTests();
85
86 @testsToRun = grep { my $test = $_; grep { $test =~ m/^\Q$_\E/ } @ARGV; } @testsToRun if @ARGV;
87
88 if ($dumpTests) {
89     dumpTestsBySuite(@testsToRun);
90     exit 0;
91 }
92
93 exit runTestsBySuite(@testsToRun, $verbose);
94
95 sub isSupportedPlatform()
96 {
97     return isAppleMacWebKit() || isAppleWinWebKit() || isChromium();
98 }
99
100 sub dumpTestsBySuite(\@)
101 {
102     my ($tests) = @_;
103     print "Dumping test cases\n";
104     print "------------------\n";
105     my $lastSuite = "";
106     for my $suiteAndTest (sort @$tests) {
107         my ($suite, $test) = split(/\./, $suiteAndTest);
108         if ($lastSuite ne $suite) {
109             $lastSuite = $suite;
110             print "$suite:\n";
111         }
112         print "   $test\n";
113     }
114     print "------------------\n";
115 }
116
117 sub runTestsBySuite(\@$)
118 {
119     my ($tests, $verbose) = @_;
120     my $anyFailures = 0;
121     my $lastSuite = "";
122     for my $suiteAndTest (sort @$tests) {
123         my ($suite, $test) = split(/\./, $suiteAndTest);
124         if ($lastSuite ne $suite) {
125             $lastSuite = $suite;
126             print "Suite: $suite\n" unless $verbose;
127         }
128         my $failed = runTest($suite, $test, $verbose);
129         $anyFailures ||= $failed;
130     }
131     
132     if ($verbose) {
133         if (@testsFailed) {
134             print "Tests that failed:\n";
135             for my $test (@testsFailed) {
136                 print "  $test\n";
137             }
138         }
139         if (@testsTimedOut) {
140             print "Tests that timed out:\n";
141             for my $test (@testsTimedOut) {
142                 print "  $test\n";
143             }
144         }
145     }
146     return $anyFailures;
147 }
148
149 sub runTest($$$)
150 {
151     my ($suite, $testName, $verbose) = @_;
152     my $test = $suite . "." . $testName;
153
154     my $gtestArg = "--gtest_filter=" . $test;
155
156     print "    Test: $testName -> " unless $verbose;
157
158     my $result = 0;
159     my $timedOut = 0;
160
161     die "run-api-tests is not supported on this platform.\n" unless isSupportedPlatform();
162
163     prepareEnvironmentForRunningTestTool();
164
165     local *DEVNULL;
166     my ($childIn, $childOut, $childErr);
167     if ($verbose) {
168         $childOut = ">&STDERR";
169         $childErr = ">&STDERR";
170     } else {
171         open(DEVNULL, ">", File::Spec->devnull()) or die "Failed to open /dev/null";
172         $childOut = ">&DEVNULL";
173         $childErr = ">&DEVNULL";
174     }
175
176     my $pid;
177     if (isAppleMacWebKit() && architecture()) {
178         $pid = open3($childIn, $childOut, $childErr, "arch", "-" . architecture(), testToolPath(), $gtestArg, @ARGV) or die "Failed to run test: $test.";
179     } else {
180         $pid = open3($childIn, $childOut, $childErr, testToolPath(), $gtestArg, @ARGV) or die "Failed to run test: $test.";
181     }
182
183     close($childIn);
184     close($childOut);
185     close($childErr);
186     close(DEVNULL) unless ($verbose);
187     eval {
188         local $SIG{ALRM} = sub { die "alarm\n" };
189         alarm $timeout;
190         waitpid($pid, 0);
191         alarm 0;
192         $result = $?;
193     };
194     if ($@) {
195         die unless $@ eq "alarm\n";
196         kill SIGTERM, $pid or kill SIGKILL, $pid;
197         $timedOut = 1;
198     }
199
200     if ($result) {
201         push @testsFailed, $test;
202     }
203     if ($timedOut) {
204         push @testsTimedOut, $test;
205         print possiblyColored("bold yellow", "Timeout"), "\n";
206     } elsif (!$verbose) {
207         if ($result) {
208             print possiblyColored("bold red", "Failed"), "\n";
209         } else {
210             print possiblyColored("bold green", "Passed"), "\n";
211         }
212     }
213
214     return $timedOut || $result;
215 }
216
217 sub listAllTests()
218 {
219     my @toolOutput;
220     my $timedOut;
221
222     die "run-api-tests is not supported on this platform.\n" unless isSupportedPlatform();
223
224     prepareEnvironmentForRunningTestTool();
225
226     local *DEVNULL;
227     my ($childIn, $childOut, $childErr);
228     if ($verbose) {
229         $childErr = ">&STDERR";
230     } else {
231         open(DEVNULL, ">", File::Spec->devnull()) or die "Failed to open /dev/null";
232         $childErr = ">&DEVNULL";
233     }
234
235     my $pid;
236     if (isAppleMacWebKit() && architecture()) {
237         $pid = open3($childIn, $childOut, $childErr, "arch", "-" . architecture(), testToolPath(), "--gtest_list_tests") or die "Failed to build list of tests!";
238     } else {
239         $pid = open3($childIn, $childOut, $childErr, testToolPath(), "--gtest_list_tests") or die "Failed to build list of tests!";
240     }
241
242     close($childIn);
243     @toolOutput = <$childOut>;
244     close($childOut);
245     close($childErr);
246     close(DEVNULL) unless ($verbose);
247
248     waitpid($pid, 0);
249     my $result = $?;
250
251     if ($result) {
252         print STDERR "Failed to build list of tests!\n";
253         exit exitStatus($result);
254     }
255
256     my @tests = ();
257     my $suite;
258     for my $line (@toolOutput) {
259        $line =~ s/[\r\n]*$//;
260        if ($line =~ m/\.$/) {
261           $suite = $line; # "SuiteName."
262        } else {
263           $line =~ s/^\s*//; # "TestName"
264           push @tests, $suite . $line; # "SuiteName.TestName"
265         }
266     }
267
268     return @tests;
269 }
270
271 sub buildTestTool()
272 {
273     my $originalCwd = getcwd();
274
275     chdirWebKit();
276
277     my $buildTestTool = "build-api-tests";
278     print STDERR "Running $buildTestTool\n";
279
280     local *DEVNULL;
281     my ($childIn, $childOut, $childErr);
282     if ($verbose) {
283         # When not quiet, let the child use our stdout/stderr.
284         $childOut = ">&STDOUT";
285         $childErr = ">&STDERR";
286     } else {
287         open(DEVNULL, ">", File::Spec->devnull()) or die "Failed to open /dev/null";
288         $childOut = ">&DEVNULL";
289         $childErr = ">&DEVNULL";
290     }
291
292     my @args = argumentsForConfiguration();
293     my $pathToBuildTestTool = File::Spec->catfile("Tools", "Scripts", $buildTestTool);
294     my $buildProcess = open3($childIn, $childOut, $childErr, "perl", $pathToBuildTestTool, @args) or die "Failed to run " . $buildTestTool;
295
296     close($childIn);
297     close($childOut);
298     close($childErr);
299     close(DEVNULL) unless ($verbose);
300
301     waitpid($buildProcess, 0);
302     my $buildResult = $?;
303
304     if ($buildResult) {
305         print STDERR "Compiling TestWebKitAPI failed!\n";
306         exit exitStatus($buildResult);
307     }
308
309     chdir $originalCwd;
310 }
311
312 sub prepareEnvironmentForRunningTestTool()
313 {
314     return unless isAppleMacWebKit();
315
316     $ENV{DYLD_FRAMEWORK_PATH} = productDir();
317     $ENV{WEBKIT_UNSET_DYLD_FRAMEWORK_PATH} = "YES";
318 }
319
320 sub testToolPath()
321 {
322     my $path = File::Spec->catfile(productDir(), "TestWebKitAPI");
323     return $path unless isAppleWinWebKit();
324
325     my $suffix;
326     if (configurationForVisualStudio() eq "Debug_All") {
327         $suffix = "_debug";
328     } else {
329         $suffix = "";
330     }
331     return "$path$suffix.exe";
332 }