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

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: add blankline. 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 |self.result_map| into stats and issues text in CSV format.
138
139 Both are used as inputs for Google spreadsheet.
140
141 Args:
142 current_time: a string depicting a time in year-month-day-hour
143 format (e.g., 2011-11-08-16).
144
145 Returns:
146 a tuple of stats and issues_txt
147 stats: analyzer result in CSV format that shows:
148 (current_time, the number of tests, the number of skipped tests,
149 the number of failing tests)
150 For example,
151 "2011-11-10-15,204,22,12"
152 issues_txt: issues listed in CSV format that shows:
153 (BUGWK or BUGCR, bug number, the test expectation entry,
154 the name of the test)
155 For example,
156 "BUGWK,71543,TIMEOUT PASS,media/media-element-play-after-eos.html,
157 BUGCR,97657,IMAGE CPU MAC TIMEOUT PASS,media/audio-repaint.html,"
158 """
159 stats = ','.join([current_time, str(len(self.result_map['whole'].keys())),
160 str(len(self.result_map['skip'].keys())),
161 str(len(self.result_map['nonskip'].keys()))])
162 issues_txt = ''
163 for bug_txt, test_info_list in (
164 self.GetListOfBugsForNonSkippedTests().iteritems()):
165 matches = re.match(r'(BUG(CR|WK))(\d+)', bug_txt)
166 bug_suffix = ''
167 bug_no = ''
168 if matches:
169 bug_suffix = matches.group(1)
170 bug_no = matches.group(3)
171 issues_txt += bug_suffix + ',' + bug_no + ','
172 for test_info in test_info_list:
173 test_name, te_info = test_info
174 issues_txt += ' '.join(te_info.keys()) + ',' + test_name + ','
175 issues_txt += '\n'
176 return stats, issues_txt
177
135 def ConvertToString(self, prev_time, diff_map, bug_anno_map): 178 def ConvertToString(self, prev_time, diff_map, bug_anno_map):
136 """Convert this result to HTML display for email. 179 """Convert this result to HTML display for email.
137 180
138 Args: 181 Args:
139 prev_time: the previous time string that are compared against. 182 prev_time: the previous time string that are compared against.
140 diff_map: the compared map generated by |CompareResultMaps()|. 183 diff_map: the compared map generated by |CompareResultMaps()|.
141 bug_anno_map: a annotation map where keys are bug names and values are 184 bug_anno_map: a annotation map where keys are bug names and values are
142 annotations for the bug. 185 annotations for the bug.
143 186
144 Returns: 187 Returns:
145 a analyzer result string in HTML format. 188 a analyzer result string in HTML format.
146 """ 189 """
147 return_str = ('<b>Statistics (Diff Compared to %s):</b><ul>' 190 return_str = ''
148 '<li>The number of tests: %d (%s)</li>' 191 if diff_map:
149 '<li>The number of failing skipped tests: %d (%s)</li>' 192 return_str += ('<b>Statistics (Diff Compared to %s):</b><ul>'
150 '<li>The number of failing non-skipped tests: %d (%s)</li>' 193 '<li>The number of tests: %d (%s)</li>'
151 '<li>Passing rate: %d %%</li></ul>') % ( 194 '<li>The number of failing skipped tests: %d (%s)</li>'
152 prev_time, len(self.result_map['whole'].keys()), 195 '<li>The number of failing non-skipped tests: %d (%s)</li>'
153 AnalyzerResultMap.GetDiffString(diff_map['whole'], 'whole'), 196 '<li>Passing rate: %d %%</li></ul>') % (
154 len(self.result_map['skip'].keys()), 197 prev_time, len(self.result_map['whole'].keys()),
155 AnalyzerResultMap.GetDiffString(diff_map['skip'], 'skip'), 198 AnalyzerResultMap.GetDiffString(diff_map['whole'], 'whole'),
156 len(self.result_map['nonskip'].keys()), 199 len(self.result_map['skip'].keys()),
157 AnalyzerResultMap.GetDiffString(diff_map['nonskip'], 200 AnalyzerResultMap.GetDiffString(diff_map['skip'], 'skip'),
158 'nonskip'), 201 len(self.result_map['nonskip'].keys()),
159 self.GetPassingRate()) 202 AnalyzerResultMap.GetDiffString(diff_map['nonskip'],
203 'nonskip'),
204 self.GetPassingRate())
160 return_str += '<b>Current issues about failing non-skipped tests:</b>' 205 return_str += '<b>Current issues about failing non-skipped tests:</b>'
161 for (bug_txt, test_info_list) in ( 206 for (bug_txt, test_info_list) in (
162 self.GetListOfBugsForNonSkippedTests().iteritems()): 207 self.GetListOfBugsForNonSkippedTests().iteritems()):
163 if not bug_txt in bug_anno_map: 208 if not bug_txt in bug_anno_map:
164 bug_anno_map[bug_txt] = '<font color="red">Needs investigation!</font>' 209 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]) 210 return_str += '<ul>%s (%s)' % (Bug(bug_txt), bug_anno_map[bug_txt])
166 for test_info in test_info_list: 211 for test_info in test_info_list:
167 (test_name, te_info) = test_info 212 (test_name, te_info) = test_info
168 gpu_link = '' 213 gpu_link = ''
169 if 'GPU' in te_info: 214 if 'GPU' in te_info:
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 if 'Bugs' in te_info: 293 if 'Bugs' in te_info:
249 for bug in te_info['Bugs']: 294 for bug in te_info['Bugs']:
250 if bug not in bug_map: 295 if bug not in bug_map:
251 bug_map[bug] = [] 296 bug_map[bug] = []
252 bug_map[bug].append((name, main_te_info)) 297 bug_map[bug].append((name, main_te_info))
253 return bug_map 298 return bug_map
254 299
255 300
256 def SendStatusEmail(prev_time, analyzer_result_map, diff_map, 301 def SendStatusEmail(prev_time, analyzer_result_map, diff_map,
257 bug_anno_map, receiver_email_address, test_group_name, 302 bug_anno_map, receiver_email_address, test_group_name,
258 appended_text_to_email, email_content, rev_str): 303 appended_text_to_email, email_content, rev_str,
304 email_only_change_mode):
259 """Send status email. 305 """Send status email.
260 306
261 Args: 307 Args:
262 prev_time: the date string such as '2011-10-09-11'. This format has been 308 prev_time: the date string such as '2011-10-09-11'. This format has been
263 used in this analyzer. 309 used in this analyzer.
264 analyzer_result_map: current analyzer result. 310 analyzer_result_map: current analyzer result.
265 diff_map: a map that has 'whole', 'skip' and 'nonskip' as keys. 311 diff_map: a map that has 'whole', 'skip' and 'nonskip' as keys.
266 The values of the map are the result of |GetDiffBetweenMaps()|. 312 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 313 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 314 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 315 result. The other (with index 1) is for test names that are in the
270 previous results but NOT in the current result. 316 previous results but NOT in the current result.
271 For example (test expectation information is omitted for 317 For example (test expectation information is omitted for
272 simplicity), 318 simplicity),
273 comp_result_map['whole'][0] = ['foo1.html'] 319 comp_result_map['whole'][0] = ['foo1.html']
274 comp_result_map['whole'][1] = ['foo2.html'] 320 comp_result_map['whole'][1] = ['foo2.html']
275 This means that current result has 'foo1.html' but it is NOT in the 321 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' 322 previous result. This also means the previous result has 'foo2.html'
277 but it is NOT in the current result. 323 but it is NOT in the current result.
278 bug_anno_map: bug annotation map where bug name and annotations are 324 bug_anno_map: bug annotation map where bug name and annotations are
279 stored. 325 stored.
280 receiver_email_address: receiver's email address. 326 receiver_email_address: receiver's email address.
281 test_group_name: string representing the test group name (e.g., 'media'). 327 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 328 appended_text_to_email: a text which is appended at the end of the status
283 email. 329 email.
284 email_content: an email content string that will be shown on the dashboard. 330 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 331 rev_str: a revision string that contains revision information that is sent
286 out in the status email. It is obtained by calling 332 out in the status email. It is obtained by calling
287 |GetRevisionString()|. 333 |GetRevisionString()|.
334 email_only_change_mode: please refer to |options|.
288 """ 335 """
289 if rev_str: 336 if rev_str:
290 email_content += '<br><b>Revision Information:</b>' 337 email_content += '<br><b>Revision Information:</b>'
291 email_content += rev_str 338 email_content += rev_str
292 localtime = time.asctime(time.localtime(time.time())) 339 localtime = time.asctime(time.localtime(time.time()))
340 change_str = ''
341 if email_only_change_mode:
342 change_str = 'Status Change '
343 subject = 'Layout Test Analyzer Result %s(%s): %s' % (change_str,
344 test_group_name,
345 localtime)
293 # TODO(imasaki): remove my name from here. 346 # 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], 347 SendEmail('imasaki@chromium.org', [receiver_email_address],
297 subject, email_content + appended_text_to_email) 348 subject, email_content + appended_text_to_email)
298 349
299 350
300 def GetRevisionString(prev_time, current_time, diff_map): 351 def GetRevisionString(prev_time, current_time, diff_map):
301 """Get a string for revision information during the specified time period. 352 """Get a string for revision information during the specified time period.
302 353
303 Args: 354 Args:
304 prev_time: the previous time as a floating point number expressed 355 prev_time: the previous time as a floating point number expressed
305 in seconds since the epoch, in UTC. 356 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'] 546 list2 = map2[name]['te_info']
496 te_diff = [item for item in list1 if not item in list2] 547 te_diff = [item for item in list1 if not item in list2]
497 if te_diff: 548 if te_diff:
498 name_list.append((name, te_diff)) 549 name_list.append((name, te_diff))
499 else: 550 else:
500 name_list.append((name, value1)) 551 name_list.append((name, value1))
501 return name_list 552 return name_list
502 553
503 return (GetDiffBetweenMapsHelper(map1, map2, lookIntoTestExpectationInfo), 554 return (GetDiffBetweenMapsHelper(map1, map2, lookIntoTestExpectationInfo),
504 GetDiffBetweenMapsHelper(map2, map1, lookIntoTestExpectationInfo)) 555 GetDiffBetweenMapsHelper(map2, map1, lookIntoTestExpectationInfo))
OLDNEW
« no previous file with comments | « media/tools/layout_tests/layouttest_analyzer.py ('k') | media/tools/layout_tests/layouttest_analyzer_helpers_unittest.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698