1 import os
, re
, string
, sys
2 import frontend
, reason_qualifier
5 'header' : '#e5e5c0', # greyish yellow
6 'blank' : '#ffffff', # white
7 'plain_text' : '#e5e5c0', # greyish yellow
8 'borders' : '#bbbbbb', # grey
9 'white' : '#ffffff', # white
10 'green' : '#66ff66', # green
11 'yellow' : '#fffc00', # yellow
12 'red' : '#ff6666', # red
14 #### additional keys for shaded color of a box
15 #### depending on stats of GOOD/FAIL
16 '100pct' : '#32CD32', # green, 94% to 100% of success
17 '95pct' : '#c0ff80', # step twrds yellow, 88% to 94% of success
18 '90pct' : '#ffff00', # yellow, 82% to 88%
19 '85pct' : '#ffc040', # 76% to 82%
20 '75pct' : '#ff4040', # red, 1% to 76%
21 '0pct' : '#d080d0', # violet, <1% of success
38 """ Returns one row table with samples of 'NNpct' colors
39 defined in the color_map
40 and numbers of corresponding %%
42 ### This function does not require maintenance in case of
43 ### color_map augmenting - as long as
44 ### color keys for box shading have names that end with 'pct'
45 keys
= filter(lambda key
: key
.endswith('pct'), color_map
.keys())
47 return int(key
.replace('pct',''))
48 keys
.sort(key
=num_pct
)
51 html
+= "\t\t\t<td bgcolor =%s> </td>\n"\
53 hint
= key
.replace('pct',' %')
54 if hint
[0]<>'0': ## anything but 0 %
56 html
+= "\t\t\t<td> %s </td>\n" % hint
59 <table width = "500" border="0" cellpadding="2" cellspacing="2">\n
70 def calculate_html(link
, data
, tooltip
=None, row_label
=None, column_label
=None):
71 if not is_brief_mode():
72 hover_text
= '%s:%s' % (row_label
, column_label
)
73 if data
: ## cell is not empty
74 hover_text
+= '<br>%s' % tooltip
76 ## avoid "None" printed in empty cells
78 html
= ('<center><a class="info" href="%s">'
79 '%s<span>%s</span></a></center>' %
80 (link
, data
, hover_text
))
82 # no hover if embedded into AFE but links shall redirect to new window
83 if data
: ## cell is non empty
84 html
= '<a href="%s" target="_blank">%s</a>' % (link
, data
)
86 else: ## cell is empty
91 def __init__(self
, data
, color_key
= None, header
= False, link
= None,
92 tooltip
= None, row_label
= None, column_label
= None):
94 ## in brief mode we display grid table only and nothing more
95 ## - mouse hovering feature is stubbed in brief mode
96 ## - any link opens new window or tab
100 ## we are acting under AFE
101 ## any link shall open new window
102 redirect
= " target=NEW"
105 data
= "<tt>%s</tt>" % data
107 if link
and not tooltip
:
108 ## FlipAxis corner, column and row headers
109 self
.data
= ('<a href="%s"%s>%s</a>' %
110 (link
, redirect
, data
))
112 self
.data
= calculate_html(link
, data
, tooltip
,
113 row_label
, column_label
)
115 if color_map
.has_key(color_key
):
116 self
.color
= color_map
[color_key
]
118 self
.color
= color_map
['header']
120 self
.color
= color_map
['plain_text']
122 self
.color
= color_map
['blank']
137 return "<%s bgcolor=%s>%s</%s>" % \
138 (box_html
, self
.color
, data
, box_html
)
141 def grade_from_status(status_idx
, status
):
144 # TEST_NA (8) is not counted
145 # ## If the test doesn't PASS, it FAILS
148 if status
== status_idx
['GOOD']:
154 def average_grade_from_status_count(status_idx
, status_count
):
157 for key
in status_count
.keys():
158 if key
not in (status_idx
['TEST_NA'], status_idx
['RUNNING']):
159 average_grade
+= (grade_from_status(status_idx
, key
)
161 total_count
+= status_count
[key
]
163 average_grade
= average_grade
/ total_count
169 def shade_from_status_count(status_idx
, status_count
):
173 ## average_grade defines a shade of the box
178 average_grade
= average_grade_from_status_count(status_idx
, status_count
)
180 ## find appropiate keyword from color_map
181 if average_grade
<0.01:
183 elif average_grade
<0.75:
185 elif average_grade
<0.85:
187 elif average_grade
<0.90:
189 elif average_grade
<0.95:
197 def status_html(db
, box_data
, shade
):
199 status_count: dict mapping from status (integer key) to count
200 eg. { 'GOOD' : 4, 'FAIL' : 1 }
202 status_count_subset
= box_data
.status_count
.copy()
203 test_na
= db
.status_idx
['TEST_NA']
204 running
= db
.status_idx
['RUNNING']
205 good
= db
.status_idx
['GOOD']
207 status_count_subset
[test_na
] = 0 # Don't count TEST_NA
208 status_count_subset
[running
] = 0 # Don't count RUNNING
209 html
= "%d / %d " % (status_count_subset
.get(good
, 0),
210 sum(status_count_subset
.values()))
211 if test_na
in box_data
.status_count
.keys():
212 html
+= ' (%d N/A)' % box_data
.status_count
[test_na
]
213 if running
in box_data
.status_count
.keys():
214 html
+= ' (%d running)' % box_data
.status_count
[running
]
216 if box_data
.reasons_list
:
217 reasons_list
= box_data
.reasons_list
218 aggregated_reasons_list
= \
219 reason_qualifier
.aggregate_reason_fields(reasons_list
)
220 for reason
in aggregated_reasons_list
:
221 ## a bit of more postprocessing
222 ## to look nicer in a cell
223 ## in future: to do subtable within the cell
224 reason
= reason
.replace('<br>','\n')
225 reason
= reason
.replace('<','[').replace('>',']')
226 reason
= reason
.replace('|','\n').replace('&',' AND ')
227 reason
= reason
.replace('\n','<br>')
228 html
+= '<br>' + reason
231 for status
in sorted(box_data
.status_count
.keys(), reverse
= True):
232 status_word
= db
.status_word
[status
]
233 tooltip
+= "%d %s " % (box_data
.status_count
[status
], status_word
)
234 return (html
,tooltip
)
237 def status_count_box(db
, tests
, link
= None):
239 Display a ratio of total number of GOOD tests
240 to total number of all tests in the group of tests.
241 More info (e.g. 10 GOOD, 2 WARN, 3 FAIL) is in tooltips
244 return box(None, None)
248 count
= status_count
.get(test
.status_num
, 0)
249 status_count
[test
.status_num
] = count
+ 1
250 return status_precounted_box(db
, status_count
, link
)
253 def status_precounted_box(db
, box_data
, link
= None,
254 x_label
= None, y_label
= None):
256 Display a ratio of total number of GOOD tests
257 to total number of all tests in the group of tests.
258 More info (e.g. 10 GOOD, 2 WARN, 3 FAIL) is in tooltips
260 status_count
= box_data
.status_count
262 return box(None, None)
264 shade
= shade_from_status_count(db
.status_idx
, status_count
)
265 html
,tooltip
= status_html(db
, box_data
, shade
)
266 precounted_box
= box(html
, shade
, False, link
, tooltip
,
268 return precounted_box
271 def print_table(matrix
):
273 matrix: list of lists of boxes, giving a matrix of data
274 Each of the inner lists is a row, not a column.
276 Display the given matrix of data as a table.
279 print ('<table bgcolor="%s" cellspacing="1" cellpadding="5" '
280 'style="margin-right: 200px;">') % (
281 color_map
['borders'])
290 def sort_tests(tests
):
291 kernel_order
= ['patch', 'config', 'build', 'mkinitrd', 'install']
294 for kernel_op
in kernel_order
:
295 test
= 'kernel.' + kernel_op
296 if tests
.count(test
):
299 if tests
.count('boot'):
300 results
.append('boot')
302 return results
+ sorted(tests
)
305 def print_main_header():
308 position:relative; /*this is the key*/
311 text-decoration:none}
313 a.info:hover{z-index:25;}
315 a.info span{display: none}
317 a.info:hover span{ /*the span will display just on :hover state*/
323 border:1px solid #036;
324 background-color:#fff; color:#000;
328 print '<head><style type="text/css">'
329 print 'a { text-decoration: none }'
331 print '</style></head>'
333 print '<a href="compose_query.cgi">Functional</a>'
334 print '   '
335 print '<a href="machine_benchmark.cgi">Performance</a>'
336 print '   '
337 print '<a href="http://ossipedia.ipa.go.jp/crackerjack/compare_results.html">Crackerjack</a>'
338 print '   '
339 print '<a href="http://autotest.kernel.org">[About Page]</a>'
343 def group_name(group
):
344 name
= re
.sub('_', '<br>', group
.name
)
345 if re
.search('/', name
):
346 (owner
, machine
) = name
.split('/', 1)
347 name
= owner
+ '<br>' + machine
350 def print_add_test_form(available_params
, attributes
, cleared
):
351 print '<form method="post">'
352 print '<input type="hidden" name="attributes" value="%s" />' % attributes
353 print '<input type="hidden" name="cleared" value="%s" />' % cleared
354 print '<select name="key">'
355 for text
in available_params
:
356 print '<option value="%s">%s</option>' % (text
, text
)
358 print '<input type="submit" name="add" value="Add test" />'
359 print '<input type="submit" name="clear" value="Clear all tests" />'
360 print '<input type="submit" name="reset" value="Reset" />'