1#!/usr/bin/perl
2
3use CGI qw(:standard);
4
5# keep a copy of each 'uname -a' string so we don't have to search for it every time.
6%uname_cache = {};
7
8# When something goes wrong before we start output, use this
9# function so there is still output
10sub failure {
11	print header("text/html"),start_html;
12	print "$_[0]\n";
13	print end_html;
14	exit;
15}
16# get the UNAME line for a host, date, suite
17sub get_result_uname {
18	my($inhost, $indate, $insuite, $filename);
19	my(@possible_files, $pf, $line);
20	my($host, $datestr, $suite, $type, $gz);
21	# build a filename
22	$inhost = $_[0];
23	$indate = $_[1];
24	if ($#_ >= 2) {
25		$insuite = $_[2];
26	} else {
27		$insuite = "*";
28	}
29	# check to see if we've done this already
30	if (exists($uname_cache{"$inhost.$indate"})) {
31		return $uname_cache{"$inhost.$indate"};
32	}
33	$filename = "$inhost.$indate.$insuite.*";
34	@possible_files = <${filename}>;
35	if ($#possible_files < 1) {
36		return "";
37	}
38	foreach $pf (@possible_files) {
39		($host, $datestr, $suite, $type, $gz) = split(/\./, $pf);
40		if ($type eq "summary") {
41			next;
42		} elsif ($type eq "scanner") {
43			open (UF, $pf) || next;
44			while ($line = <UF>) {
45				if ($line =~ /^UNAME/) {
46					close(UF);
47					$line =~ s/UNAME *//;
48					$line =~ s/$inhost//;
49					$uname_cache{"$inhost.$indate"} = $line;
50					return $line;
51				}
52			}
53		} elsif ($type eq "driver") {
54			if ($gz) {
55				open (UF, "gunzip -c $pf|") || next;
56			} else {
57				open (UF, "$pf") || next;
58			}
59			while ($line = <UF>) {
60				if ($line =~ /^UNAME/) {
61					close(UF);
62					$line =~ s/UNAME="(.*)"/\1/;
63					$line =~ s/$inhost//;
64					$uname_cache{"$inhost.$indate"} = $line;
65					return $line;
66				}
67			}
68		} else {
69			next;
70		}
71	}
72	return "";
73}
74
75# Create the headers row, adding links for sorting options
76sub print_headers {
77
78	print "\n<tr>";
79
80	for($i = 0; $i <= $#rso; $i++) {
81		print "<th><a href=\"browse.cgi?sort=";
82		for ($j = 0; $j <= $#rso; $j++) {
83			if ($j == $i) { $rsd[$j] = $rsd[$j] * -1; }
84			if ($rsd[$j] == -1) { print "-"; }
85			if ($j == $i) { $rsd[$j] = $rsd[$j] * -1; }
86			print $rso[$j];
87			if ($j < $#rso) { print ","; }
88		}
89		print "\">$rso[$i]</a>\n";
90	}
91
92	print "</tr>\n";
93}
94
95############
96# main()   #
97############
98
99# Most of the work is done in this directory
100unless (chdir("/usr/tests/ltp/results")) {
101	failure("Could not get to the results directory\n");
102}
103
104@extra_path = split(/\//, $ENV{PATH_INFO});
105
106# rso = Result Sort Order
107# rsd = Result Sort Direction
108#@rso = (HOST,SUITE, DATE, UNAME);
109@rso = (SUITE, HOST, DATE, UNAME);
110@rsd = (1, 1, -1, 1);
111
112# allow the user to specify the sort order
113if ($sort_order = param("sort")) {
114	@so = split(/,/, $sort_order);
115	print $so;
116	@rso = ();
117	for($i = 0; $i <= $#so; $i++) {
118		# parse the field
119		if ($so[$i] =~ /host/i) { push(@rso, HOST); }
120		elsif ($so[$i] =~ /date/i) { push(@rso, DATE); }
121		elsif ($so[$i] =~ /suite/i) { push(@rso, SUITE); }
122		elsif ($so[$i] =~ /uname/i) { push(@rso, UNAME); }
123		# parse the direction
124		if ($so[$i] =~ /-/) { $rsd[$i] = -1; }
125		else { $rsd[$i] = 1; }
126	}
127}
128
129if ($#extra_path > 0) {
130
131} else {
132
133	%results = ();
134
135	# run through the files in the results directory
136	@driver_files = <*driver*>;
137	foreach $df (@driver_files) {
138
139		($host, $datestr, $suite, $type, $gz) = split(/\./, $df);
140
141		$a_rec = ();
142		$a_rec->{HOST} = $host;
143		$a_rec->{DATE} = $datestr;
144		$a_rec->{SUITE} = $suite;
145		$a_rec->{DRIVER_FILE} = $df;
146		$a_rec->{UNAME} = get_result_uname($host, $datestr);
147
148		$results{ $a_rec->{DRIVER_FILE} } = $a_rec;
149	}
150
151	# write the HTML file
152	print header("text/html"),start_html;
153	print "This is a demo page for browsing the Linux LTP results.  Select the results you want to compare and click the \"Compare\" button.", p, h2("Warning"), "The results are placed in a large table which may take a long time to render on some browsers", p;
154	@ri = values %results;
155	@ri = sort { ($a->{$rso[0]} cmp $b->{$rso[0]})*$rsd[0]
156			|| ($a->{$rso[1]} cmp $b->{$rso[1]})*$rsd[1]
157			|| ($a->{$rso[2]} cmp $b->{$rso[2]})*$rsd[2]
158			|| ($a->{$rso[3]} cmp $b->{$rso[3]})*$rsd[3] } @ri;
159
160	$last = ();
161	$last->{$rso[0]} = "";
162	$last->{$rso[1]} = "";
163	$last->{$rso[2]} = "";
164	$lasthost = "";
165	$lastdate = "";
166	$lastsuite = "";
167	#$lastindent = 0;
168	$thisindent = 0;
169	print "<form method=get action=\"reconsile.cgi\">";
170	print "<table border=1>\n";
171	#print "<tr><th>Hostname<th>Date<th>Suite</tr>\n";
172	print_headers();
173	foreach $rp ( @ri ) {
174
175		$this = ();
176		$this->{$rso[0]} = $rp->{$rso[0]};
177		$this->{$rso[1]} = $rp->{$rso[1]};
178		$this->{$rso[2]} = $rp->{$rso[2]};
179		$this->{$rso[3]} = $rp->{$rso[3]};
180
181		# figure out the first column that is different
182		for ($i = 0; $i <= $#rso; $i++) {
183			if ($last->{$rso[$i]} ne $this->{$rso[$i]}) {
184				$thisindent = $i;
185				last;
186			}
187		}
188
189		print "<tr>\n";
190		for ($i = 0; $i < $thisindent; $i++) {
191			print "<td>";
192
193		}
194		for ($i = $thisindent; $i <= $#rso; $i++) {
195			print "<td>";
196			if ($i == $#rso) {
197				print "<a href=\"results.cgi?get_df=$this->{HOST}.$this->{DATE}.$this->{SUITE}.scanner\">";
198			}
199			print "$this->{$rso[$i]}";
200			if ($i == $#rso) {
201				print "</a>";
202			}
203			if ($i == $#rso) {
204				# last column
205				print " <input type=checkbox name=results value=\"$this->{HOST}.$this->{DATE}.$this->{SUITE}\">";
206
207			}
208
209
210		}
211		print "</tr>\n";
212
213		# make sure we update the $last... variables
214		$last->{$rso[0]} = $this->{$rso[0]};
215		$last->{$rso[1]} = $this->{$rso[1]};
216		$last->{$rso[2]} = $this->{$rso[2]};
217	}
218	print "</table>\n";
219	print "<input type=submit name=compare value=\"Compare\">\n";
220	print "<input type=reset>\n";
221	print "</form>";
222	print end_html;
223
224}
225
226