blob: a4681a88e296ec2a05c516008c76f31e27da48f4 [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
57
mblighcfd2d012007-09-19 21:07:34 +000058class box:
mbligh439661b2008-02-19 15:57:53 +000059 def __init__(self, data, color_key = None, header = False, link = None,
60 tooltip = None ):
mbligh835c0e42008-03-11 21:39:54 +000061 if data:
62 data = "<tt>%s</tt>" % data
mbligh439661b2008-02-19 15:57:53 +000063 if link and tooltip:
64 self.data = '<a href="%s" title="%s">%s</a>' \
65 % (link, tooltip, data)
66 elif tooltip:
67 self.data = '<a href="%s" title="%s">%s</a>' \
68 % ('#', tooltip, data)
69 elif link:
mblighf91b3f52007-10-07 00:47:04 +000070 self.data = '<a href="%s">%s</a>' % (link, data)
71 else:
72 self.data = data
mbligh439661b2008-02-19 15:57:53 +000073
mblighcfd2d012007-09-19 21:07:34 +000074 if color_map.has_key(color_key):
75 self.color = color_map[color_key]
mbligh1405f4e2007-11-05 19:26:23 +000076 elif header:
77 self.color = color_map['header']
78 elif data:
79 self.color = color_map['plain_text']
mblighcfd2d012007-09-19 21:07:34 +000080 else:
mbligh1405f4e2007-11-05 19:26:23 +000081 self.color = color_map['blank']
mblighcfd2d012007-09-19 21:07:34 +000082 self.header = header
83
84
mbligh38757e72007-09-30 22:32:13 +000085 def html(self):
mblighcfd2d012007-09-19 21:07:34 +000086 if self.data:
87 data = self.data
88 else:
89 data = '&nbsp'
90
91 if self.header:
92 box_html = 'th'
93 else:
94 box_html = 'td'
95
mbligh38757e72007-09-30 22:32:13 +000096 return "<%s bgcolor=%s>%s</%s>" % \
97 (box_html, self.color, data, box_html)
mblighcfd2d012007-09-19 21:07:34 +000098
99
mbligh439661b2008-02-19 15:57:53 +0000100def grade_from_status(status):
101 # % of goodness
102 # GOOD (6) -> 1
mbligh302482e2008-05-01 20:06:16 +0000103 # TEST_NA (8) is not counted
mbligh1b4780e2008-02-21 16:27:52 +0000104 # ## If the test doesn't PASS, it FAILS
mbligh439661b2008-02-19 15:57:53 +0000105 # else -> 0
mbligh439661b2008-02-19 15:57:53 +0000106
107 if status == 6:
108 return 1.0
mbligh1b4780e2008-02-21 16:27:52 +0000109 else:
mbligh439661b2008-02-19 15:57:53 +0000110 return 0.0
111
112
113def average_grade_from_status_count(status_count):
114 average_grade = 0
115 total_count = 0
116 for key in status_count.keys():
mbligh302482e2008-05-01 20:06:16 +0000117 if key != 8: # TEST_NA status
118 average_grade += (grade_from_status(key)
119 * status_count[key])
120 total_count += status_count[key]
121 if total_count != 0:
122 average_grade = average_grade / total_count
123 else:
124 average_grade = 0.0
mbligh439661b2008-02-19 15:57:53 +0000125 return average_grade
126
127
128def shade_from_status_count(status_count):
129 if not status_count:
130 return None
131
132 ## average_grade defines a shade of the box
133 ## 0 -> violet
134 ## 0.76 -> red
135 ## 0.88-> yellow
136 ## 1.0 -> green
137 average_grade = average_grade_from_status_count(status_count)
138
139 ## find appropiate keyword from color_map
140 if average_grade<0.01:
141 shade = '0pct'
mbligh8e7c78e2008-02-20 21:18:49 +0000142 elif average_grade<0.75:
143 shade = '75pct'
144 elif average_grade<0.85:
145 shade = '85pct'
146 elif average_grade<0.90:
147 shade = '90pct'
148 elif average_grade<0.95:
149 shade = '95pct'
mbligh439661b2008-02-19 15:57:53 +0000150 else:
151 shade = '100pct'
152
153 return shade
154
155
mbligh31260692008-04-16 23:12:12 +0000156def status_html(db, box_data, shade):
mbligha997a342007-10-06 22:35:04 +0000157 """
158 status_count: dict mapping from status (integer key) to count
159 eg. { 'GOOD' : 4, 'FAIL' : 1 }
160 """
mbligh31260692008-04-16 23:12:12 +0000161 status_count = box_data.status_count
mbligh439661b2008-02-19 15:57:53 +0000162 if 6 in status_count.keys():
mbligh8e7c78e2008-02-20 21:18:49 +0000163 html = "%d&nbsp;/&nbsp;%d " \
mbligh439661b2008-02-19 15:57:53 +0000164 %(status_count[6],sum(status_count.values()))
165 else:
mbligh8e7c78e2008-02-20 21:18:49 +0000166 html = "%d&nbsp;/&nbsp;%d " % \
mbligh439661b2008-02-19 15:57:53 +0000167 (0, sum(status_count.values()))
mbligh439661b2008-02-19 15:57:53 +0000168
mbligh31260692008-04-16 23:12:12 +0000169 if box_data.reasons_list:
170 box_data.reasons_list.sort()
171 for reason in box_data.reasons_list:
172 reason = reason.replace('<br>','\n')
173 reason = reason.replace('<','[').replace('>',']')
174 reason = reason.replace('|','\n').replace('&',' AND ')
175 reason = reason.replace('\n','<br>')
176 html += '<br>' + reason
177
178 tooltip = ""
mbligha997a342007-10-06 22:35:04 +0000179 for status in sorted(status_count.keys(), reverse = True):
180 status_word = db.status_word[status]
mbligh439661b2008-02-19 15:57:53 +0000181 tooltip += "%d %s " % (status_count[status], status_word)
182 return (html,tooltip)
mbligha997a342007-10-06 22:35:04 +0000183
184
185def status_count_box(db, tests, link = None):
186 """
mbligh835c0e42008-03-11 21:39:54 +0000187 Display a ratio of total number of GOOD tests
188 to total number of all tests in the group of tests.
189 More info (e.g. 10 GOOD, 2 WARN, 3 FAIL) is in tooltips
mbligha997a342007-10-06 22:35:04 +0000190 """
191 if not tests:
192 return box(None, None)
193
194 status_count = {}
195 for test in tests:
196 count = status_count.get(test.status_num, 0)
197 status_count[test.status_num] = count + 1
mbligh83f63a02007-12-12 19:13:04 +0000198 return status_precounted_box(db, status_count, link)
199
200
mbligh31260692008-04-16 23:12:12 +0000201def status_precounted_box(db, box_data, link = None):
mbligh83f63a02007-12-12 19:13:04 +0000202 """
mbligh835c0e42008-03-11 21:39:54 +0000203 Display a ratio of total number of GOOD tests
204 to total number of all tests in the group of tests.
205 More info (e.g. 10 GOOD, 2 WARN, 3 FAIL) is in tooltips
mbligh31260692008-04-16 23:12:12 +0000206 """
207 status_count = box_data.status_count
mbligh83f63a02007-12-12 19:13:04 +0000208 if not status_count:
209 return box(None, None)
mbligh439661b2008-02-19 15:57:53 +0000210
211 shade = shade_from_status_count(status_count)
mbligh31260692008-04-16 23:12:12 +0000212 html,tooltip = status_html(db, box_data, shade)
mbligh439661b2008-02-19 15:57:53 +0000213 precounted_box = box(html, shade, False, link, tooltip)
214 return precounted_box
mbligha997a342007-10-06 22:35:04 +0000215
mbligh31260692008-04-16 23:12:12 +0000216
mblighcfd2d012007-09-19 21:07:34 +0000217def print_table(matrix):
218 """
219 matrix: list of lists of boxes, giving a matrix of data
220 Each of the inner lists is a row, not a column.
221
222 Display the given matrix of data as a table.
223 """
224
mbligh1405f4e2007-11-05 19:26:23 +0000225 print '<table bgcolor="%s" cellspacing="1" cellpadding="5">' % (
226 color_map['borders'])
mblighcfd2d012007-09-19 21:07:34 +0000227 for row in matrix:
228 print '<tr>'
229 for element in row:
mbligh38757e72007-09-30 22:32:13 +0000230 print element.html()
mblighcfd2d012007-09-19 21:07:34 +0000231 print '</tr>'
232 print '</table>'
233
234
mblighcfd2d012007-09-19 21:07:34 +0000235def sort_tests(tests):
236 kernel_order = ['patch', 'config', 'build', 'mkinitrd', 'install']
237
238 results = []
239 for kernel_op in kernel_order:
240 test = 'kernel.' + kernel_op
241 if tests.count(test):
242 results.append(test)
243 tests.remove(test)
mbligh7a41a862007-11-30 17:44:24 +0000244 if tests.count('boot'):
245 results.append('boot')
246 tests.remove('boot')
mblighcfd2d012007-09-19 21:07:34 +0000247 return results + sorted(tests)
mblighbfec5222007-09-14 16:58:57 +0000248
mbligh04598752007-10-01 15:49:58 +0000249
250def print_main_header():
mbligh1405f4e2007-11-05 19:26:23 +0000251 print '<head><style type="text/css">'
252 print 'a { text-decoration: none }'
253 print '</style></head>'
mbligh04598752007-10-01 15:49:58 +0000254 print '<h2>'
mblighdfeee942008-02-07 20:47:39 +0000255 print '<a href="compose_query.cgi">Functional</a>'
mbligh04598752007-10-01 15:49:58 +0000256 print '&nbsp&nbsp&nbsp'
257 print '<a href="machine_benchmark.cgi">Performance</a>'
mblighcb0c38c2008-01-11 16:49:25 +0000258 print '&nbsp&nbsp&nbsp'
259 print '<a href="http://test.kernel.org/autotest">[about Autotest]</a>'
mbligh04598752007-10-01 15:49:58 +0000260 print '</h2><p>'
mbligh7a41a862007-11-30 17:44:24 +0000261
262
263def group_name(group):
264 name = re.sub('_', '<br>', group.name)
265 if re.search('/', name):
266 (owner, machine) = name.split('/', 1)
mbligh7a41a862007-11-30 17:44:24 +0000267 name = owner + '<br>' + machine
268 return name