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