Remove extension from format-subunit.
[kai/samba-autobuild/.git] / selftest / output / html.pm
1 #!/usr/bin/perl
2 # HTML output for selftest
3 # Copyright (C) 2008 Jelmer Vernooij <jelmer@samba.org>
4 #
5 # This program is free software; you can redistribute it and/or modify
6 # it under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9
10 # This program is distributed in the hope that it will be useful,
11 # but WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 # GNU General Public License for more details.
14
15 # You should have received a copy of the GNU General Public License
16 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 package output::html;
18 use Exporter;
19 @ISA = qw(Exporter);
20
21 use strict;
22 use warnings;
23
24 use FindBin qw($RealBin);
25 use lib "$RealBin/..";
26
27 sub new($$$) {
28         my ($class, $dirname, $statistics) = @_;
29         my $self = { 
30                 dirname => $dirname,
31                 active_test => undef,
32                 local_statistics => {},
33                 statistics => $statistics,
34                 msg => "",
35                 error_summary => { 
36                         skip => [],
37                         expected_success => [],
38                         unexpected_success => [],
39                         expected_failure => [],
40                         unexpected_failure => [],
41                         skip_testsuites => [],
42                         error => []
43                 }
44         };
45
46         link("$RealBin/output/testresults.css", "$dirname/testresults.css");
47
48         open(INDEX, ">$dirname/index.html");
49
50         bless($self, $class);
51
52         $self->print_html_header("Samba Testsuite Run", *INDEX);
53
54         print INDEX "  <center>";
55         print INDEX "  <table>\n";
56         print INDEX "  <tr>\n";
57         print INDEX "    <td class=\"tableHead\">Test</td>\n";
58         print INDEX "    <td class=\"tableHead\">Result</td>\n";
59         print INDEX "  </tr>\n";
60
61         return $self;
62 }
63
64 sub testsuite_count($$)
65 {
66 }
67
68 sub print_html_header($$$)
69 {
70         my ($self, $title, $fh) = @_;
71
72         print $fh "<html lang=\"en\">\n";
73         print $fh "<head>\n";
74         print $fh "  <title>$title</title>\n";
75         print $fh "  <link rel=\"stylesheet\" type=\"text/css\" href=\"testresults.css\"/>\n";
76         print $fh "</head>\n";
77         print $fh "<body>\n";
78         print $fh "<table width=\"100%\" border=\"0\" cellspacing=\"0\">\n";
79         print $fh "  <tr><td class=\"title\">$title</td></tr>\n";
80         print $fh "  <tr><td>\n";
81 }
82
83 sub print_html_footer($$)
84 {
85         my ($self, $fh) = @_;
86
87         print $fh "</td></tr>\n";
88         print $fh "</table>\n";
89         print $fh "</body>\n";
90         print $fh "</html>\n";
91 }
92
93 sub output_msg($$);
94
95 sub start_testsuite($$)
96 {
97         my ($self, $name) = @_;
98
99         $self->{START_TIME} = $self->{last_time};
100
101         $self->{local_statistics} = {
102                 success => 0,
103                 skip => 0,
104                 error => 0,
105                 failure => 0
106         };
107
108         $self->{NAME} = $name;
109         $self->{HTMLFILE} = "$name.html";
110         $self->{HTMLFILE} =~ s/[:\t\n \/]/_/g;
111
112         open(TEST, ">$self->{dirname}/$self->{HTMLFILE}") or die("Unable to open $self->{HTMLFILE} for writing");
113
114         $self->print_html_header("Test Results for $name", *TEST);
115
116         print TEST "<h2>Tests</h2>\n";
117
118         print TEST "  <table>\n";
119 }
120
121 sub control_msg($$)
122 {
123         my ($self, $output) = @_;
124
125         # Perhaps the CSS should hide this by default?
126         $self->{msg} .=  "<span class=\"control\">$output<br/></span>\n";
127 }
128
129 sub output_msg($$)
130 {
131         my ($self, $output) = @_;
132
133         unless (defined($self->{active_test})) {
134                 if (defined($self->{NAME})) {
135                         print TEST "$output<br/>";
136                 }
137         } else {
138                 $self->{msg} .= "$output<br/>";
139         }
140 }
141
142 sub end_testsuite($$$)
143 {
144         my ($self, $name, $result, $reason) = @_;
145
146         print TEST "</table>\n";
147
148         print TEST "<div class=\"duration\">Duration: " . ($self->{last_time} - $self->{START_TIME}) . "s</div>\n";
149
150         $self->print_html_footer(*TEST);
151
152         close(TEST);
153
154         print INDEX "<tr>\n";
155         print INDEX "  <td class=\"testSuite\"><a href=\"$self->{HTMLFILE}\">$name</a></td>\n";
156         my $st = $self->{local_statistics};
157
158         if ($result eq "xfail") {
159                 print INDEX "  <td class=\"resultExpectedFailure\">";
160         } elsif ($result eq "success") {
161                 print INDEX "  <td class=\"resultOk\">";
162         } else {
163                 print INDEX "  <td class=\"resultFailure\">";
164         }
165
166         my $l = 0;
167         if ($st->{success} > 0) {
168                 print INDEX "$st->{success} ok";
169                 $l++;
170         }
171         if ($st->{skip} > 0) {
172                 print INDEX ", " if ($l);
173                 print INDEX "$st->{skip} skipped";
174                 $l++;
175         }
176         if ($st->{failure} > 0) {
177                 print INDEX ", " if ($l);
178                 print INDEX "$st->{failure} failures";
179                 $l++;
180         }
181         if ($st->{error} > 0) {
182                 print INDEX ", " if ($l);
183                 print INDEX "$st->{error} errors";
184                 $l++;
185         }
186
187         if ($l == 0) {
188                 print INDEX uc($result);
189         }
190
191         print INDEX "</td>";
192                 
193         print INDEX "</tr>\n";
194
195         $self->{NAME} = undef;
196 }
197
198 sub report_time($$)
199 {
200         my ($self, $time) = @_;
201         $self->{last_time} = $time;
202 }
203
204 sub start_test($$)
205 {
206         my ($self, $testname) = @_;
207
208         $self->{active_test} = $testname;
209         $self->{msg} = "";
210 }
211
212 sub end_test($$$$)
213 {
214         my ($self, $testname, $result, $unexpected, $reason) = @_;
215
216         print TEST "<tr>";
217
218         $self->{local_statistics}->{$result}++;
219
220         my $track_class;
221
222         if ($result eq "skip") {
223                 print TEST "<td class=\"outputSkipped\">\n";
224                 $track_class = "skip";
225         } elsif ($unexpected) {
226                 print TEST "<td class=\"outputFailure\">\n";
227                 if ($result eq "error") {
228                         $track_class = "error";
229                 } else {
230                         $track_class = "unexpected_$result";
231                 }
232         } else {
233                 if ($result eq "failure") {
234                         print TEST "<td class=\"outputExpectedFailure\">\n";
235                 } else {
236                         print TEST "<td class=\"outputOk\">\n";
237                 }
238                 $track_class = "expected_$result";
239         }
240
241         push(@{$self->{error_summary}->{$track_class}}, ,
242                  [$self->{HTMLFILE}, $testname, $self->{NAME}, 
243                   $reason]);
244
245         print TEST "<a name=\"$testname\"><h3>$testname</h3></a>\n";
246
247         print TEST $self->{msg};
248
249         if (defined($reason)) {
250                 print TEST "<div class=\"reason\">$reason</div>\n";
251         }
252
253         print TEST "</td></tr>\n";
254
255         $self->{active_test} = undef;
256 }
257
258 sub summary($)
259 {
260         my ($self) = @_;
261
262         my $st = $self->{statistics};
263         print INDEX "<tr>\n";
264         print INDEX "  <td class=\"testSuiteTotal\">Total</td>\n";
265
266         if ($st->{TESTS_UNEXPECTED_OK} == 0 and 
267             $st->{TESTS_UNEXPECTED_FAIL} == 0 and
268                 $st->{TESTS_ERROR} == 0) {
269                 print INDEX "  <td class=\"resultOk\">";
270         } else {
271                 print INDEX "  <td class=\"resultFailure\">";
272         }
273         print INDEX ($st->{TESTS_EXPECTED_OK} + $st->{TESTS_UNEXPECTED_OK}) . " ok";
274         if ($st->{TESTS_UNEXPECTED_OK} > 0) {
275                 print INDEX " ($st->{TESTS_UNEXPECTED_OK} unexpected)";
276         }
277         if ($st->{TESTS_SKIP} > 0) {
278                 print INDEX ", $st->{TESTS_SKIP} skipped";
279         }
280         if (($st->{TESTS_UNEXPECTED_FAIL} + $st->{TESTS_EXPECTED_FAIL}) > 0) {
281                 print INDEX ", " . ($st->{TESTS_UNEXPECTED_FAIL} + $st->{TESTS_EXPECTED_FAIL}) . " failures";
282                 if ($st->{TESTS_UNEXPECTED_FAIL} > 0) {
283                         print INDEX " ($st->{TESTS_EXPECTED_FAIL} expected)";
284                 }
285         }
286         if ($st->{TESTS_ERROR} > 0) {
287                 print INDEX ", $st->{TESTS_ERROR} errors";
288         }
289
290         print INDEX "</td>";
291
292         print INDEX "</tr>\n";
293
294         print INDEX "</table>\n";
295         print INDEX "<a href=\"summary.html\">Summary</a>\n";
296         print INDEX "</center>\n";
297         $self->print_html_footer(*INDEX);
298         close(INDEX);
299
300         my $summ = $self->{error_summary};
301         open(SUMMARY, ">$self->{dirname}/summary.html");
302         $self->print_html_header("Summary", *SUMMARY);
303         sub print_table($$) {
304                 my ($title, $list) = @_;
305                 return if ($#$list == -1);
306                 print SUMMARY "<h3>$title</h3>\n";
307                 print SUMMARY "<table>\n";
308                 print SUMMARY "<tr>\n";
309                 print SUMMARY "  <td class=\"tableHead\">Testsuite</td>\n";
310                 print SUMMARY "  <td class=\"tableHead\">Test</td>\n";
311                 print SUMMARY "  <td class=\"tableHead\">Reason</td>\n";
312                 print SUMMARY "</tr>\n";
313
314                 foreach (@$list) {
315                         print SUMMARY "<tr>\n";
316                         print SUMMARY "  <td><a href=\"" . $$_[0] . "\">$$_[2]</a></td>\n";
317                         print SUMMARY "  <td><a href=\"" . $$_[0] . "#$$_[1]\">$$_[1]</a></td>\n";
318                         if (defined($$_[3])) {
319                                 print SUMMARY "  <td>$$_[3]</td>\n";
320                         } else {
321                                 print SUMMARY "  <td></td>\n";
322                         }
323                         print SUMMARY "</tr>\n";
324                 }
325
326                 print SUMMARY "</table>";
327         }
328         print_table("Errors", $summ->{error});
329         print_table("Unexpected successes", $summ->{unexpected_success});
330         print_table("Unexpected failures", $summ->{unexpected_failure});
331         print_table("Skipped tests", $summ->{skip});
332         print_table("Expected failures", $summ->{expected_failure});
333
334         print SUMMARY "<h3>Skipped testsuites</h3>\n";
335         print SUMMARY "<table>\n";
336         print SUMMARY "<tr>\n";
337         print SUMMARY "  <td class=\"tableHead\">Testsuite</td>\n";
338         print SUMMARY "  <td class=\"tableHead\">Reason</td>\n";
339         print SUMMARY "</tr>\n";
340
341         foreach (@{$summ->{skip_testsuites}}) {
342                 print SUMMARY "<tr>\n";
343                 print SUMMARY "  <td>$$_[0]</td>\n";
344                 if (defined($$_[1])) {
345                         print SUMMARY "  <td>$$_[1]</td>\n";
346                 } else {
347                         print SUMMARY "  <td></td>\n";
348                 }
349                 print SUMMARY "</tr>\n";
350         }
351
352         print SUMMARY "</table>";
353
354         $self->print_html_footer(*SUMMARY);
355         close(SUMMARY);
356 }
357
358 sub skip_testsuite($$$$)
359 {
360         my ($self, $name, $reason) = @_;
361
362         push (@{$self->{error_summary}->{skip_testsuites}}, 
363                   [$name, $reason]);
364 }
365
366 1;