e5c8e255f91f31cfa35f1d0038fe25ff72c0b6ea
[WebKit-https.git] / WebKitTools / Scripts / run-webkit-tests
1 #!/usr/bin/perl -w
2
3 # Script to run the Web Kit Open Source Project layout tests.
4
5 use strict;
6 use IPC::Open2;
7
8 # Run all the tests passed in on the command line.
9 # If no tests are passed, find all the .html, .xml, and .xhtml files in the test directory.
10
11 # Run each text.
12 # Compare against the existing file xxx-expected.txt.
13 # If there is a mismatch, generate xxx-actual.txt and xxx-diffs.txt.
14
15 # At the end, report:
16 #   the number of tests that got the expected results
17 #   the number of tests that ran, but did not get the expected results
18 #   the number of tests that failed to run
19 #   the number of tests that were run but had no expected results to compare against
20
21 # Check that we're in the right directory.
22 if (! -d "WebKitTools") {
23     if (-d "../WebKitTools") {
24         chdir ".." or die;
25     }
26     if (! -d "WebKitTools") {
27         die "No WebKitTools directory found. Please run this script from the directory containing WebKitTools.\n";
28     }
29 }
30
31 # Check that an Xcode product directory is set.
32 open PRODUCT, "defaults read com.apple.Xcode PBXProductDirectory 2> /dev/null |" or die;
33 my $productDir = <PRODUCT>;
34 chomp $productDir;
35 close PRODUCT;
36 if (!$productDir) {
37     die "No product directory set. Please set the 'Place Build Products' preference to 'Customized location' in XCode Building Preferences.\n";
38 }
39
40 my $result = system "WebKitTools/Scripts/build-dumprendertree";
41 exit $result if $result;
42
43 my $tool = "$productDir/DumpRenderTree";
44
45 die "can't find executable DumpRenderTree tool (looked in $productDir)\n" if !-x $tool;
46
47 my $workingDir = `pwd`;
48 chomp $workingDir;
49 my $WebCoreDirectory = "$workingDir/WebCore";
50 my $testDirectory = "$WebCoreDirectory/layout-tests";
51 my $testResultsDirectory = "/tmp/layout-test-results";
52 my $testResults = "$testResultsDirectory/results.html";
53
54 $ENV{"DYLD_FRAMEWORK_PATH"} = $productDir;
55
56 my @tests;
57
58 my $findArguments = "\\( -name resources \\! -prune \\) -or -name '*.html' -or -name '*.xml' -or -name '*.xhtml'";
59 if (@ARGV) {
60     for my $test (@ARGV) {
61         $test =~ s/^$testDirectory\///;
62         if ($test =~ /^\//) {
63             print "can't run test outside $testDirectory\n";
64         } elsif (-f "$testDirectory/$test") {
65             if ($test !~ /\.(html|xml|xhtml)$/) {
66                 print "test $test does not have an .html extension\n";
67             } else {
68                 push @tests, $test;
69             }
70         } elsif (-d "$testDirectory/$test") {
71             push @tests, map { chomp; s-^$testDirectory/--; $_; } `find -s $testDirectory/$test $findArguments`;
72         } else {
73             print "test $test not found\n";
74         }
75     }
76 } else {
77     @tests = map { chomp; s-^$testDirectory/--; $_; } `find -s $testDirectory $findArguments`;
78 }
79
80 die "no tests to run\n" if !@tests;
81
82 my %counts;
83 my %tests;
84 my $count;
85
86 open2(\*IN, \*OUT, $tool, "-") or die;
87
88 $| = 1;
89
90 for my $test (@tests) {
91     next if $test eq 'results.html';
92     
93     my $base = $test;
94     $base =~ s/\.(html|xml|xhtml)$//;
95     
96     print "running $base test";
97     
98     my $result;
99
100     print OUT "$testDirectory/$test\n";
101
102     my $actual = "";
103     while (<IN>) {
104         last if /#EOF$/;
105         $actual .= $_;
106     }
107     
108     my $expected;
109     if (open EXPECTED, "<", "$testDirectory/$base-expected.txt") {
110         $expected = "";
111         while (<EXPECTED>) {
112             $expected .= $_;
113         }
114         close EXPECTED;
115     }
116     if (!defined $expected) {
117         print " -> new test\n";        
118         $result = "new";
119         open EXPECTED, ">", "$testDirectory/$base-expected.txt" or die "could not create $testDirectory/$base-expected.txt\n";
120         print EXPECTED $actual;
121         close EXPECTED;
122         unlink "$testResultsDirectory/$base-actual.txt";
123         unlink "$testResultsDirectory/$base-diffs.txt";
124     } elsif ($actual eq $expected) {
125         print " -> succeeded\n";        
126         $result = "match";
127         unlink "$testResultsDirectory/$base-actual.txt";
128         unlink "$testResultsDirectory/$base-diffs.txt";
129     } else {
130         print " -> failed\n";        
131         $result = "mismatch";
132         my $dir = "$testResultsDirectory/$base";
133         $dir =~ s|/[^/]+$||;
134         system "mkdir", "-p", $dir;
135         open ACTUAL, ">", "$testResultsDirectory/$base-actual.txt" or die;
136         print ACTUAL $actual;
137         close ACTUAL;
138         system "diff -u $testDirectory/$base-expected.txt $testResultsDirectory/$base-actual.txt > $testResultsDirectory/$base-diffs.txt";
139     }
140     
141     $count += 1;
142     $counts{$result} += 1;
143     push @{$tests{$result}}, $test;
144 }
145
146 close IN;
147 close OUT;
148
149 my %text = (
150     match => "succeeded",
151     mismatch => "had incorrect layout",
152     new => "were new",
153     fail => "failed (tool did not execute successfully)",
154 );
155
156 print "\n";
157
158 if ($counts{match} && $counts{match} == $count) {
159     print "all test cases succeeded\n";
160     unlink $testResults;
161 } else {
162     for my $type ("match", "mismatch", "new", "fail") {
163         my $c = $counts{$type};
164         if ($c) {
165             my $t = $text{$type};
166             my $message;
167             if ($c == 1) {
168                 $t =~ s/were/was/;
169                 $message = sprintf "1 test case (%d%%) %s\n", 1 * 100 / $count, $t;
170             } else {
171                 $message = sprintf "%d test cases (%d%%) %s\n", $c, $c * 100 / $count, $t;
172             }
173             $message =~ s-\(0%\)-(<1%)-;
174             print $message;
175         }
176     }
177     
178     system "mkdir", "-p", $testResultsDirectory;
179
180     open HTML, ">", $testResults or die;
181     print HTML "<html>\n";
182     print HTML "<head>\n";
183     print HTML "<title>Layout Test Results</title>\n";
184     print HTML "</head>\n";
185     print HTML "<body>\n";
186
187     if ($counts{mismatch}) {
188         print HTML "<p>Tests where results did not match expected results:</p>\n";
189         print HTML "<table>\n";
190         for my $test (@{$tests{mismatch}}) {
191             my $base = $test;
192             $base =~ s/\.(html|xml|xhtml)$//;
193             print HTML "<tr>\n";
194             print HTML "<td><a href=\"$testDirectory/$test\">$base</a></td>\n";
195             print HTML "<td><a href=\"$testDirectory/$base-expected.txt\">expected</a></td>\n";
196             print HTML "<td><a href=\"$base-actual.txt\">actual</a></td>\n";
197             print HTML "<td><a href=\"$base-diffs.txt\">diffs</a></td>\n";
198             print HTML "</tr>\n";
199         }
200         print HTML "</table>\n";
201     }
202
203     if ($counts{fail}) {
204         print HTML "<p>Tests that caused the DumpRenderTree tool to fail:</p>\n";
205         print HTML "<table>\n";
206         for my $test (@{$tests{fail}}) {
207             my $base = $test;
208             $base =~ s/\.(html|xml|xhtml)$//;
209             print HTML "<tr>\n";
210             print HTML "<td><a href=\"$testDirectory/$test\">$base</a></td>\n";
211             print HTML "</tr>\n";
212         }
213         print HTML "</table>\n";
214     }
215
216     if ($counts{new}) {
217         print HTML "<p>Tests that had no expected results (probably new):</p>\n";
218         print HTML "<table>\n";
219         for my $test (@{$tests{new}}) {
220             my $base = $test;
221             $base =~ s/\.(html|xml|xhtml)$//;
222             print HTML "<tr>\n";
223             print HTML "<td><a href=\"$testDirectory/$test\">$base</a></td>\n";
224             print HTML "<td><a href=\"$testDirectory/$base-expected.txt\">results</a></td>\n";
225             print HTML "</tr>\n";
226         }
227         print HTML "</table>\n";
228     }
229
230     print HTML "</body>\n";
231     print HTML "</html>\n";
232     close HTML;
233     
234     system "open", $testResults;
235 }