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