blob: b04511dadc6b16625b7beabba69f194e38ff7e43 [file] [log] [blame]
mbligh5f1839e2008-03-28 14:32:36 +00001import os, re, sys, frontend
mblighbfec5222007-09-14 16:58:57 +00002
mblighcfd2d012007-09-19 21:07:34 +00003color_map = {
mbligh1405f4e2007-11-05 19:26:23 +00004 'header' : '#e5e5c0', # greyish yellow
5 'blank' : '#ffffff', # white
6 'plain_text' : '#e5e5c0', # greyish yellow
7 'borders' : '#bbbbbb', # grey
mblighcfd2d012007-09-19 21:07:34 +00008 'white' : '#ffffff', # white
9 'green' : '#66ff66', # green
10 'yellow' : '#fffc00', # yellow
11 'red' : '#ff6666', # red
mbligh439661b2008-02-19 15:57:53 +000012
13 #### additional keys for shaded color of a box
14 #### depending on stats of GOOD/FAIL
mbligh310b59e2008-03-25 23:53:55 +000015 '100pct' : '#80ff80', # green, 94% to 100% of success
16 '95pct' : '#c0ff80', # step twrds yellow, 88% to 94% of success
17 '90pct' : '#ffff80', # yellow, 82% to 88%
18 '85pct' : '#ffc040', # 76% to 82%
19 '75pct' : '#ff4040', # red, 1% to 76%
20 '0pct' : '#d080d0', # violet, <1% of success
mbligh439661b2008-02-19 15:57:53 +000021
mblighcfd2d012007-09-19 21:07:34 +000022}
mblighbfec5222007-09-14 16:58:57 +000023
mblighcfd2d012007-09-19 21:07:34 +000024
mbligh439661b2008-02-19 15:57:53 +000025def color_keys_row():
26 """ Returns one row table with samples of 'NNpct' colors
27 defined in the color_map
28 and numbers of corresponding %%
29 """
30 ### This function does not require maintenance in case of
31 ### color_map augmenting - as long as
32 ### color keys for box shading have names that end with 'pct'
33 keys = filter(lambda key: key.endswith('pct'), color_map.keys())
34 def num_pct(key):
35 return int(key.replace('pct',''))
36 keys.sort(key=num_pct)
37 html = ''
38 for key in keys:
39 html+= "\t\t\t<td bgcolor =%s>&nbsp;&nbsp;&nbsp;</td>\n"\
40 % color_map[key]
41 hint = key.replace('pct',' %')
42 if hint[0]<>'0': ## anything but 0 %
43 hint = 'to ' + hint
44 html+= "\t\t\t<td> %s </td>\n" % hint
45
46 html = """
47<table width = "500" border="0" cellpadding="2" cellspacing="2">\n
48 <tbody>\n
49 <tr>\n
50%s
51 </tr>\n
52 </tbody>
53</table><br>
54""" % html
55 return html
56
jadmanskif9fa4272008-05-02 15:43:33 +000057def hover_html(link, href, hover_text):
58 """ Returns the snippet of html for generating the hover over links.
59 """
60 return '<center><a class="info" href="%s">%s<span>%s</span></a></center>' % \
61 (link, href, hover_text)
mbligh439661b2008-02-19 15:57:53 +000062
mblighcfd2d012007-09-19 21:07:34 +000063class box:
mbligh439661b2008-02-19 15:57:53 +000064 def __init__(self, data, color_key = None, header = False, link = None,
jadmanskif9fa4272008-05-02 15:43:33 +000065 tooltip = None, row_label = None, column_label = None):
mbligh835c0e42008-03-11 21:39:54 +000066 if data:
67 data = "<tt>%s</tt>" % data
mbligh439661b2008-02-19 15:57:53 +000068 if link and tooltip:
jadmanskif9fa4272008-05-02 15:43:33 +000069 self.data = hover_html(link, data, '%s:%s<br>%s' %
70 (row_label, column_label, tooltip))
mbligh439661b2008-02-19 15:57:53 +000071 elif tooltip:
jadmanskif9fa4272008-05-02 15:43:33 +000072 self.data = hover_html('#', data, tooltip)
mbligh439661b2008-02-19 15:57:53 +000073 elif link:
mblighf91b3f52007-10-07 00:47:04 +000074 self.data = '<a href="%s">%s</a>' % (link, data)
75 else:
jadmanskif9fa4272008-05-02 15:43:33 +000076 self.data = hover_html('about:blank',
77 '&nbsp;&nbsp;&nbsp;', '%s:%s' % (row_label, column_label))
mbligh439661b2008-02-19 15:57:53 +000078
mblighcfd2d012007-09-19 21:07:34 +000079 if color_map.has_key(color_key):
80 self.color = color_map[color_key]
mbligh1405f4e2007-11-05 19:26:23 +000081 elif header:
82 self.color = color_map['header']
83 elif data:
84 self.color = color_map['plain_text']
mblighcfd2d012007-09-19 21:07:34 +000085 else:
mbligh1405f4e2007-11-05 19:26:23 +000086 self.color = color_map['blank']
mblighcfd2d012007-09-19 21:07:34 +000087 self.header = header
88
89
mbligh38757e72007-09-30 22:32:13 +000090 def html(self):
mblighcfd2d012007-09-19 21:07:34 +000091 if self.data:
92 data = self.data
93 else:
94 data = '&nbsp'
95
96 if self.header:
97 box_html = 'th'
98 else:
99 box_html = 'td'
100
mbligh38757e72007-09-30 22:32:13 +0000101 return "<%s bgcolor=%s>%s</%s>" % \
102 (box_html, self.color, data, box_html)
mblighcfd2d012007-09-19 21:07:34 +0000103
104
mbligh439661b2008-02-19 15:57:53 +0000105def grade_from_status(status):
106 # % of goodness
107 # GOOD (6) -> 1
mbligh302482e2008-05-01 20:06:16 +0000108 # TEST_NA (8) is not counted
mbligh1b4780e2008-02-21 16:27:52 +0000109 # ## If the test doesn't PASS, it FAILS
mbligh439661b2008-02-19 15:57:53 +0000110 # else -> 0
mbligh439661b2008-02-19 15:57:53 +0000111
112 if status == 6:
113 return 1.0
mbligh1b4780e2008-02-21 16:27:52 +0000114 else:
mbligh439661b2008-02-19 15:57:53 +0000115 return 0.0
116
117
118def average_grade_from_status_count(status_count):
119 average_grade = 0
120 total_count = 0
121 for key in status_count.keys():
mbligh302482e2008-05-01 20:06:16 +0000122 if key != 8: # TEST_NA status
123 average_grade += (grade_from_status(key)
124 * status_count[key])
125 total_count += status_count[key]
126 if total_count != 0:
127 average_grade = average_grade / total_count
128 else:
129 average_grade = 0.0
mbligh439661b2008-02-19 15:57:53 +0000130 return average_grade
131
132
133def shade_from_status_count(status_count):
134 if not status_count:
135 return None
136
137 ## average_grade defines a shade of the box
138 ## 0 -> violet
139 ## 0.76 -> red
140 ## 0.88-> yellow
141 ## 1.0 -> green
142 average_grade = average_grade_from_status_count(status_count)
143
144 ## find appropiate keyword from color_map
145 if average_grade<0.01:
146 shade = '0pct'
mbligh8e7c78e2008-02-20 21:18:49 +0000147 elif average_grade<0.75:
148 shade = '75pct'
149 elif average_grade<0.85:
150 shade = '85pct'
151 elif average_grade<0.90:
152 shade = '90pct'
153 elif average_grade<0.95:
154 shade = '95pct'
mbligh439661b2008-02-19 15:57:53 +0000155 else:
156 shade = '100pct'
157
158 return shade
159
160
mbligh31260692008-04-16 23:12:12 +0000161def status_html(db, box_data, shade):
mbligha997a342007-10-06 22:35:04 +0000162 """
163 status_count: dict mapping from status (integer key) to count
164 eg. { 'GOOD' : 4, 'FAIL' : 1 }
165 """
mbligh31260692008-04-16 23:12:12 +0000166 status_count = box_data.status_count
mbligh439661b2008-02-19 15:57:53 +0000167 if 6 in status_count.keys():
mbligh8e7c78e2008-02-20 21:18:49 +0000168 html = "%d&nbsp;/&nbsp;%d " \
mbligh439661b2008-02-19 15:57:53 +0000169 %(status_count[6],sum(status_count.values()))
170 else:
mbligh8e7c78e2008-02-20 21:18:49 +0000171 html = "%d&nbsp;/&nbsp;%d " % \
mbligh439661b2008-02-19 15:57:53 +0000172 (0, sum(status_count.values()))
mbligh439661b2008-02-19 15:57:53 +0000173
mbligh31260692008-04-16 23:12:12 +0000174 if box_data.reasons_list:
175 box_data.reasons_list.sort()
176 for reason in box_data.reasons_list:
177 reason = reason.replace('<br>','\n')
178 reason = reason.replace('<','[').replace('>',']')
179 reason = reason.replace('|','\n').replace('&',' AND ')
180 reason = reason.replace('\n','<br>')
181 html += '<br>' + reason
182
183 tooltip = ""
mbligha997a342007-10-06 22:35:04 +0000184 for status in sorted(status_count.keys(), reverse = True):
185 status_word = db.status_word[status]
mbligh439661b2008-02-19 15:57:53 +0000186 tooltip += "%d %s " % (status_count[status], status_word)
187 return (html,tooltip)
mbligha997a342007-10-06 22:35:04 +0000188
189
190def status_count_box(db, tests, link = None):
191 """
mbligh835c0e42008-03-11 21:39:54 +0000192 Display a ratio of total number of GOOD tests
193 to total number of all tests in the group of tests.
194 More info (e.g. 10 GOOD, 2 WARN, 3 FAIL) is in tooltips
mbligha997a342007-10-06 22:35:04 +0000195 """
196 if not tests:
197 return box(None, None)
198
199 status_count = {}
200 for test in tests:
201 count = status_count.get(test.status_num, 0)
202 status_count[test.status_num] = count + 1
mbligh83f63a02007-12-12 19:13:04 +0000203 return status_precounted_box(db, status_count, link)
204
205
jadmanskif9fa4272008-05-02 15:43:33 +0000206def status_precounted_box(db, box_data, link = None,
207 x_label = None, y_label = None):
mbligh83f63a02007-12-12 19:13:04 +0000208 """
mbligh835c0e42008-03-11 21:39:54 +0000209 Display a ratio of total number of GOOD tests
210 to total number of all tests in the group of tests.
211 More info (e.g. 10 GOOD, 2 WARN, 3 FAIL) is in tooltips
mbligh31260692008-04-16 23:12:12 +0000212 """
213 status_count = box_data.status_count
mbligh83f63a02007-12-12 19:13:04 +0000214 if not status_count:
215 return box(None, None)
mbligh439661b2008-02-19 15:57:53 +0000216
217 shade = shade_from_status_count(status_count)
mbligh31260692008-04-16 23:12:12 +0000218 html,tooltip = status_html(db, box_data, shade)
jadmanskif9fa4272008-05-02 15:43:33 +0000219 precounted_box = box(html, shade, False, link, tooltip,
220 x_label, y_label)
mbligh439661b2008-02-19 15:57:53 +0000221 return precounted_box
mbligha997a342007-10-06 22:35:04 +0000222
mbligh31260692008-04-16 23:12:12 +0000223
mblighcfd2d012007-09-19 21:07:34 +0000224def print_table(matrix):
225 """
226 matrix: list of lists of boxes, giving a matrix of data
227 Each of the inner lists is a row, not a column.
228
229 Display the given matrix of data as a table.
230 """
231
mbligh1405f4e2007-11-05 19:26:23 +0000232 print '<table bgcolor="%s" cellspacing="1" cellpadding="5">' % (
233 color_map['borders'])
mblighcfd2d012007-09-19 21:07:34 +0000234 for row in matrix:
235 print '<tr>'
236 for element in row:
mbligh38757e72007-09-30 22:32:13 +0000237 print element.html()
mblighcfd2d012007-09-19 21:07:34 +0000238 print '</tr>'
239 print '</table>'
240
241
mblighcfd2d012007-09-19 21:07:34 +0000242def sort_tests(tests):
243 kernel_order = ['patch', 'config', 'build', 'mkinitrd', 'install']
244
245 results = []
246 for kernel_op in kernel_order:
247 test = 'kernel.' + kernel_op
248 if tests.count(test):
249 results.append(test)
250 tests.remove(test)
mbligh7a41a862007-11-30 17:44:24 +0000251 if tests.count('boot'):
252 results.append('boot')
253 tests.remove('boot')
mblighcfd2d012007-09-19 21:07:34 +0000254 return results + sorted(tests)
mblighbfec5222007-09-14 16:58:57 +0000255
mbligh04598752007-10-01 15:49:58 +0000256
257def print_main_header():
jadmanskif9fa4272008-05-02 15:43:33 +0000258 hover_css="""\
259a.info{
260 position:relative; /*this is the key*/
261 z-index:1
262 color:#000;
263 text-decoration:none}
264
265a.info:hover{z-index:25;}
266
267a.info span{display: none}
268
269a.info:hover span{ /*the span will display just on :hover state*/
270 display:block;
271 position:absolute;
272 top:1em; left:1em;
273 min-width: 100px;
274 overflow: visible;
275 border:1px solid #036;
276 background-color:#fff; color:#000;
277 text-align: left
278}
279"""
mbligh1405f4e2007-11-05 19:26:23 +0000280 print '<head><style type="text/css">'
281 print 'a { text-decoration: none }'
jadmanskif9fa4272008-05-02 15:43:33 +0000282 print hover_css
mbligh1405f4e2007-11-05 19:26:23 +0000283 print '</style></head>'
mbligh04598752007-10-01 15:49:58 +0000284 print '<h2>'
mblighdfeee942008-02-07 20:47:39 +0000285 print '<a href="compose_query.cgi">Functional</a>'
mbligh04598752007-10-01 15:49:58 +0000286 print '&nbsp&nbsp&nbsp'
287 print '<a href="machine_benchmark.cgi">Performance</a>'
mblighcb0c38c2008-01-11 16:49:25 +0000288 print '&nbsp&nbsp&nbsp'
289 print '<a href="http://test.kernel.org/autotest">[about Autotest]</a>'
mbligh04598752007-10-01 15:49:58 +0000290 print '</h2><p>'
mbligh7a41a862007-11-30 17:44:24 +0000291
292
293def group_name(group):
294 name = re.sub('_', '<br>', group.name)
295 if re.search('/', name):
296 (owner, machine) = name.split('/', 1)
mbligh7a41a862007-11-30 17:44:24 +0000297 name = owner + '<br>' + machine
298 return name