Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: media/tools/layout_tests/layouttest_analyzer_helpers.py

Issue 8469017: Support CSV output format for analyzer results. (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 #!/usr/bin/python 1 #!/usr/bin/python
2 # Copyright (c) 2011 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2011 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Helper functions for the layout test analyzer.""" 6 """Helper functions for the layout test analyzer."""
7 7
8 from datetime import datetime 8 from datetime import datetime
9 from email.mime.multipart import MIMEMultipart 9 from email.mime.multipart import MIMEMultipart
10 from email.mime.text import MIMEText 10 from email.mime.text import MIMEText
11 import fileinput 11 import fileinput
12 import os 12 import os
13 import pickle 13 import pickle
14 import re
14 import smtplib 15 import smtplib
15 import socket 16 import socket
16 import sys 17 import sys
17 import time 18 import time
18 import urllib 19 import urllib
19 20
20 from bug import Bug 21 from bug import Bug
21 from test_expectations_history import TestExpectationsHistory 22 from test_expectations_history import TestExpectationsHistory
22 23
23 24
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
125 ValueEror when the number of tests in test group "whole" is equal or less 126 ValueEror when the number of tests in test group "whole" is equal or less
126 than that of "skip". 127 than that of "skip".
127 """ 128 """
128 delta = len(self.result_map['whole'].keys()) - ( 129 delta = len(self.result_map['whole'].keys()) - (
129 len(self.result_map['skip'].keys())) 130 len(self.result_map['skip'].keys()))
130 if delta <= 0: 131 if delta <= 0:
131 raise ValueError('The number of tests in test group "whole" is equal or ' 132 raise ValueError('The number of tests in test group "whole" is equal or '
132 'less than that of "skip"') 133 'less than that of "skip"')
133 return 100 - len(self.result_map['nonskip'].keys()) * 100 / delta 134 return 100 - len(self.result_map['nonskip'].keys()) * 100 / delta
134 135
136 def ConvertToCSVText(self, current_time):
137 """Convert result_map into stats and issues text in CSV format.
dennis_jeffrey 2011/11/11 00:01:36 'result_map' --> |self.result_map|
imasaki1 2011/11/11 00:25:52 Done.
138
139 Both are used for inputs for Google spreadsheet.
dennis_jeffrey 2011/11/11 00:01:36 nit: 'for inputs' --> 'as inputs'
imasaki1 2011/11/11 00:25:52 Done.
140
141 Args:
142 current_time: a string shows current time (e.g, 2011-11-08-16)
dennis_jeffrey 2011/11/11 00:01:36 current_time: a string depicting a time in year-mo
imasaki1 2011/11/11 00:25:52 Done.
143
144 Returns:
145 a tuple of stats and issues_txt
146 stats: analyzer result in CSV format that shows:
147 (current_time, the number of tests, the number of skipped tests,
148 the number of failing tests)
149 For example,
150 "2011-11-10-15,204,22,12"
151 issues_txt: issues listed in CSV format that shows:
dennis_jeffrey 2011/11/11 00:01:36 Could this include information for multiple issues
imasaki1 2011/11/11 00:25:52 Done.
152 (BUGWK or BUGCR, bug number, the test expectation entry,
153 the name of the test)
154 For example,
155 "71543,TIMEOUT PASS,media/media-element-play-after-eos.html,"
dennis_jeffrey 2011/11/11 00:01:36 This example seems to be missing the "BUGWK"/"BUGC
imasaki1 2011/11/11 00:25:52 Done.
156 """
157 stats = ','.join([current_time, str(len(self.result_map['whole'].keys())),
158 str(len(self.result_map['skip'].keys())),
dennis_jeffrey 2011/11/11 00:01:36 nit: indent this by 1 more space.
imasaki1 2011/11/11 00:25:52 Done.
159 str(len(self.result_map['nonskip'].keys()))])
dennis_jeffrey 2011/11/11 00:01:36 nit: indent this by 2 more spaces
imasaki1 2011/11/11 00:25:52 Done.
160 issues_txt = ''
161 for (bug_txt, test_info_list) in (
dennis_jeffrey 2011/11/11 00:01:36 I believe the parens are unnecessary in '(bug_txt,
imasaki1 2011/11/11 00:25:52 Done.
162 self.GetListOfBugsForNonSkippedTests().iteritems()):
dennis_jeffrey 2011/11/11 00:01:36 nit: indent this by 2 more spaces
imasaki1 2011/11/11 00:25:52 Done.
163 matches = re.match(r'(BUG(CR|WK))(\d+)', bug_txt)
164 bug_prefix = ''
dennis_jeffrey 2011/11/11 00:01:36 nit: 'bug_prefix' --> 'bug_suffix', since it's the
imasaki1 2011/11/11 00:25:52 Done.
165 bug_no = ''
166 if matches:
167 bug_prefix = matches.group(1)
168 bug_no = matches.group(3)
169 issues_txt += bug_prefix + ',' + bug_no + ','
170 for test_info in test_info_list:
171 (test_name, te_info) = test_info
dennis_jeffrey 2011/11/11 00:01:36 no need for parentheses here
imasaki1 2011/11/11 00:25:52 Done.
172 issues_txt += ' '.join(te_info.keys()) + ',' + test_name + ','
173 issues_txt += '\n'
174 return (stats, issues_txt)
dennis_jeffrey 2011/11/11 00:01:36 no need for parentheses here
imasaki1 2011/11/11 00:25:52 Done.
175
135 def ConvertToString(self, prev_time, diff_map, bug_anno_map): 176 def ConvertToString(self, prev_time, diff_map, bug_anno_map):
136 """Convert this result to HTML display for email. 177 """Convert this result to HTML display for email.
137 178
138 Args: 179 Args:
139 prev_time: the previous time string that are compared against. 180 prev_time: the previous time string that are compared against.
140 diff_map: the compared map generated by |CompareResultMaps()|. 181 diff_map: the compared map generated by |CompareResultMaps()|.
141 bug_anno_map: a annotation map where keys are bug names and values are 182 bug_anno_map: a annotation map where keys are bug names and values are
142 annotations for the bug. 183 annotations for the bug.
143 184
144 Returns: 185 Returns:
145 a analyzer result string in HTML format. 186 a analyzer result string in HTML format.
146 """ 187 """
147 return_str = ('<b>Statistics (Diff Compared to %s):</b><ul>' 188 return_str = ''
148 '<li>The number of tests: %d (%s)</li>' 189 if diff_map:
149 '<li>The number of failing skipped tests: %d (%s)</li>' 190 return_str += ('<b>Statistics (Diff Compared to %s):</b><ul>'
150 '<li>The number of failing non-skipped tests: %d (%s)</li>' 191 '<li>The number of tests: %d (%s)</li>'
151 '<li>Passing rate: %d %%</li></ul>') % ( 192 '<li>The number of failing skipped tests: %d (%s)</li>'
152 prev_time, len(self.result_map['whole'].keys()), 193 '<li>The number of failing non-skipped tests: %d (%s)</li>'
153 AnalyzerResultMap.GetDiffString(diff_map['whole'], 'whole'), 194 '<li>Passing rate: %d %%</li></ul>') % (
154 len(self.result_map['skip'].keys()), 195 prev_time, len(self.result_map['whole'].keys()),
155 AnalyzerResultMap.GetDiffString(diff_map['skip'], 'skip'), 196 AnalyzerResultMap.GetDiffString(diff_map['whole'], 'whole'),
156 len(self.result_map['nonskip'].keys()), 197 len(self.result_map['skip'].keys()),
157 AnalyzerResultMap.GetDiffString(diff_map['nonskip'], 198 AnalyzerResultMap.GetDiffString(diff_map['skip'], 'skip'),
158 'nonskip'), 199 len(self.result_map['nonskip'].keys()),
159 self.GetPassingRate()) 200 AnalyzerResultMap.GetDiffString(diff_map['nonskip'],
201 'nonskip'),
202 self.GetPassingRate())
160 return_str += '<b>Current issues about failing non-skipped tests:</b>' 203 return_str += '<b>Current issues about failing non-skipped tests:</b>'
161 for (bug_txt, test_info_list) in ( 204 for (bug_txt, test_info_list) in (
162 self.GetListOfBugsForNonSkippedTests().iteritems()): 205 self.GetListOfBugsForNonSkippedTests().iteritems()):
163 if not bug_txt in bug_anno_map: 206 if not bug_txt in bug_anno_map:
164 bug_anno_map[bug_txt] = '<font color="red">Needs investigation!</font>' 207 bug_anno_map[bug_txt] = '<font color="red">Needs investigation!</font>'
165 return_str += '<ul>%s (%s)' % (Bug(bug_txt), bug_anno_map[bug_txt]) 208 return_str += '<ul>%s (%s)' % (Bug(bug_txt), bug_anno_map[bug_txt])
166 for test_info in test_info_list: 209 for test_info in test_info_list:
167 (test_name, te_info) = test_info 210 (test_name, te_info) = test_info
168 gpu_link = '' 211 gpu_link = ''
169 if 'GPU' in te_info: 212 if 'GPU' in te_info:
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 if 'Bugs' in te_info: 291 if 'Bugs' in te_info:
249 for bug in te_info['Bugs']: 292 for bug in te_info['Bugs']:
250 if bug not in bug_map: 293 if bug not in bug_map:
251 bug_map[bug] = [] 294 bug_map[bug] = []
252 bug_map[bug].append((name, main_te_info)) 295 bug_map[bug].append((name, main_te_info))
253 return bug_map 296 return bug_map
254 297
255 298
256 def SendStatusEmail(prev_time, analyzer_result_map, diff_map, 299 def SendStatusEmail(prev_time, analyzer_result_map, diff_map,
257 bug_anno_map, receiver_email_address, test_group_name, 300 bug_anno_map, receiver_email_address, test_group_name,
258 appended_text_to_email, email_content, rev_str): 301 appended_text_to_email, email_content, rev_str,
302 email_only_change_mode):
259 """Send status email. 303 """Send status email.
260 304
261 Args: 305 Args:
262 prev_time: the date string such as '2011-10-09-11'. This format has been 306 prev_time: the date string such as '2011-10-09-11'. This format has been
263 used in this analyzer. 307 used in this analyzer.
264 analyzer_result_map: current analyzer result. 308 analyzer_result_map: current analyzer result.
265 diff_map: a map that has 'whole', 'skip' and 'nonskip' as keys. 309 diff_map: a map that has 'whole', 'skip' and 'nonskip' as keys.
266 The values of the map are the result of |GetDiffBetweenMaps()|. 310 The values of the map are the result of |GetDiffBetweenMaps()|.
267 The element has two lists of test cases. One (with index 0) is for 311 The element has two lists of test cases. One (with index 0) is for
268 test names that are in the current result but NOT in the previous 312 test names that are in the current result but NOT in the previous
269 result. The other (with index 1) is for test names that are in the 313 result. The other (with index 1) is for test names that are in the
270 previous results but NOT in the current result. 314 previous results but NOT in the current result.
271 For example (test expectation information is omitted for 315 For example (test expectation information is omitted for
272 simplicity), 316 simplicity),
273 comp_result_map['whole'][0] = ['foo1.html'] 317 comp_result_map['whole'][0] = ['foo1.html']
274 comp_result_map['whole'][1] = ['foo2.html'] 318 comp_result_map['whole'][1] = ['foo2.html']
275 This means that current result has 'foo1.html' but it is NOT in the 319 This means that current result has 'foo1.html' but it is NOT in the
276 previous result. This also means the previous result has 'foo2.html' 320 previous result. This also means the previous result has 'foo2.html'
277 but it is NOT in the current result. 321 but it is NOT in the current result.
278 bug_anno_map: bug annotation map where bug name and annotations are 322 bug_anno_map: bug annotation map where bug name and annotations are
279 stored. 323 stored.
280 receiver_email_address: receiver's email address. 324 receiver_email_address: receiver's email address.
281 test_group_name: string representing the test group name (e.g., 'media'). 325 test_group_name: string representing the test group name (e.g., 'media').
282 appended_text_to_email: a text which is appended at the end of the status 326 appended_text_to_email: a text which is appended at the end of the status
283 email. 327 email.
284 email_content: an email content string that will be shown on the dashboard. 328 email_content: an email content string that will be shown on the dashboard.
285 rev_str: a revision string that contains revision information that is sent 329 rev_str: a revision string that contains revision information that is sent
286 out in the status email. It is obtained by calling 330 out in the status email. It is obtained by calling
287 |GetRevisionString()|. 331 |GetRevisionString()|.
332 email_only_change_mode: please refer to |options|.
288 """ 333 """
289 if rev_str: 334 if rev_str:
290 email_content += '<br><b>Revision Information:</b>' 335 email_content += '<br><b>Revision Information:</b>'
291 email_content += rev_str 336 email_content += rev_str
292 localtime = time.asctime(time.localtime(time.time())) 337 localtime = time.asctime(time.localtime(time.time()))
338 change_str = ''
339 if email_only_change_mode:
340 change_str = 'Status Change'
dennis_jeffrey 2011/11/11 00:01:36 add a space right after the 'e' at the end of this
imasaki1 2011/11/11 00:25:52 Done.
341 subject = 'Layout Test Analyzer Result %s (%s): %s' % (change_str,
dennis_jeffrey 2011/11/11 00:01:36 remove the space right after the first '%s'
imasaki1 2011/11/11 00:25:52 Done.
342 test_group_name,
343 localtime)
293 # TODO(imasaki): remove my name from here. 344 # TODO(imasaki): remove my name from here.
294 subject = 'Layout Test Analyzer Result (%s): %s' % (test_group_name,
295 localtime)
296 SendEmail('imasaki@chromium.org', [receiver_email_address], 345 SendEmail('imasaki@chromium.org', [receiver_email_address],
297 subject, email_content + appended_text_to_email) 346 subject, email_content + appended_text_to_email)
298 347
299 348
300 def GetRevisionString(prev_time, current_time, diff_map): 349 def GetRevisionString(prev_time, current_time, diff_map):
301 """Get a string for revision information during the specified time period. 350 """Get a string for revision information during the specified time period.
302 351
303 Args: 352 Args:
304 prev_time: the previous time as a floating point number expressed 353 prev_time: the previous time as a floating point number expressed
305 in seconds since the epoch, in UTC. 354 in seconds since the epoch, in UTC.
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
495 list2 = map2[name]['te_info'] 544 list2 = map2[name]['te_info']
496 te_diff = [item for item in list1 if not item in list2] 545 te_diff = [item for item in list1 if not item in list2]
497 if te_diff: 546 if te_diff:
498 name_list.append((name, te_diff)) 547 name_list.append((name, te_diff))
499 else: 548 else:
500 name_list.append((name, value1)) 549 name_list.append((name, value1))
501 return name_list 550 return name_list
502 551
503 return (GetDiffBetweenMapsHelper(map1, map2, lookIntoTestExpectationInfo), 552 return (GetDiffBetweenMapsHelper(map1, map2, lookIntoTestExpectationInfo),
504 GetDiffBetweenMapsHelper(map2, map1, lookIntoTestExpectationInfo)) 553 GetDiffBetweenMapsHelper(map2, map1, lookIntoTestExpectationInfo))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698