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

Side by Side Diff: chrome/test/functional/perf/endure_result_parser.py

Issue 10965007: Accept contents from stdin in endure_result_parser.py. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed. Created 8 years, 2 months 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
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2012 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 """Script to parse perf data from Chrome Endure test executions, to be graphed. 6 """Script to parse perf data from Chrome Endure test executions, to be graphed.
7 7
8 This script connects via HTTP to a buildbot master in order to scrape and parse 8 This script connects via HTTP to a buildbot master in order to scrape and parse
9 perf data from Chrome Endure tests that have been run. The perf data is then 9 perf data from Chrome Endure tests that have been run. The perf data is then
10 stored in local text files to be graphed by the Chrome Endure graphing code. 10 stored in local text files to be graphed by the Chrome Endure graphing code.
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 new_events[description] = value_list 211 new_events[description] = value_list
212 212
213 new_line = { 213 new_line = {
214 'rev': revision, 214 'rev': revision,
215 'events': new_events 215 'events': new_events
216 } 216 }
217 217
218 WriteToDataFile(new_line, existing_lines, revision, data_file) 218 WriteToDataFile(new_line, existing_lines, revision, data_file)
219 219
220 220
221 def UpdatePerfDataFromFetchedContent(revision, content, webapp_name, test_name):
222 """Update perf data from fetched stdio data.
223
224 Args:
225 revision: The string revision number associated with the new perf entry.
226 content: Fetched stdio data.
227 webapp_name: A name of the webapp.
228 test_name: A name of the test.
229 """
230 perf_data_raw = []
231
232 def AppendRawPerfData(graph_name, description, value, units, units_x,
233 webapp_name, test_name, is_stacked=False):
234 perf_data_raw.append({
235 'graph_name': graph_name,
236 'description': description,
237 'value': value,
238 'units': units,
239 'units_x': units_x,
240 'webapp_name': webapp_name,
241 'test_name': test_name,
242 'stack': is_stacked,
243 })
244
245 # First scan for short-running perf test results.
246 for match in re.findall(
247 r'RESULT ([^:]+): ([^=]+)= ([-\d\.]+) (\S+)', content):
248 AppendRawPerfData(match[0], match[1], eval(match[2]), match[3], None,
249 webapp_name, webapp_name)
250
251 # Next scan for long-running perf test results.
252 for match in re.findall(
253 r'RESULT ([^:]+): ([^=]+)= (\[[^\]]+\]) (\S+) (\S+)', content):
254 # TODO(dmikurube): Change the condition to use stacked graph when we
255 # determine how to specify it.
256 AppendRawPerfData(match[0], match[1], eval(match[2]), match[3], match[4],
257 webapp_name, test_name, match[0].endswith('-DMP'))
258
259 # Next scan for events in the test results.
260 for match in re.findall(
261 r'RESULT _EVENT_: ([^=]+)= (\[[^\]]+\])', content):
262 AppendRawPerfData('_EVENT_', match[0], eval(match[1]), None, None,
263 webapp_name, test_name)
264
265 # For each graph_name/description pair that refers to a long-running test
266 # result or an event, concatenate all the results together (assume results
267 # in the input file are in the correct order). For short-running test
268 # results, keep just one if more than one is specified.
269 perf_data = {} # Maps a graph-line key to a perf data dictionary.
270 for data in perf_data_raw:
271 key_graph = data['graph_name']
272 key_description = data['description']
273 if not key_graph in perf_data:
274 perf_data[key_graph] = {
275 'graph_name': data['graph_name'],
276 'value': {},
277 'units': data['units'],
278 'units_x': data['units_x'],
279 'webapp_name': data['webapp_name'],
280 'test_name': data['test_name'],
281 }
282 perf_data[key_graph]['stack'] = data['stack']
283 if 'stack_order' not in perf_data[key_graph]:
284 perf_data[key_graph]['stack_order'] = []
285 if (data['stack'] and
286 data['description'] not in perf_data[key_graph]['stack_order']):
287 perf_data[key_graph]['stack_order'].append(data['description'])
288
289 if data['graph_name'] != '_EVENT_' and not data['units_x']:
290 # Short-running test result.
291 perf_data[key_graph]['value'][key_description] = data['value']
292 else:
293 # Long-running test result or event.
294 if key_description in perf_data[key_graph]['value']:
295 perf_data[key_graph]['value'][key_description] += data['value']
296 else:
297 perf_data[key_graph]['value'][key_description] = data['value']
298
299 # Finally, for each graph-line in |perf_data|, update the associated local
300 # graph data files if necessary.
301 for perf_data_key in perf_data:
302 perf_data_dict = perf_data[perf_data_key]
303
304 dest_dir = os.path.join(LOCAL_GRAPH_DIR, perf_data_dict['webapp_name'])
305 if not os.path.exists(dest_dir):
306 os.mkdir(dest_dir) # Webapp name directory.
307 os.chmod(dest_dir, 0755)
308 dest_dir = os.path.join(dest_dir, perf_data_dict['test_name'])
309
310 SetupBaseGraphDirIfNeeded(perf_data_dict['webapp_name'],
311 perf_data_dict['test_name'], dest_dir)
312 if perf_data_dict['graph_name'] == '_EVENT_':
313 OutputEventData(revision, perf_data_dict['value'], dest_dir)
314 else:
315 OutputPerfData(revision, perf_data_dict['graph_name'],
316 perf_data_dict['value'],
317 perf_data_dict['units'], perf_data_dict['units_x'],
318 dest_dir,
319 perf_data_dict['stack'], perf_data_dict['stack_order'])
320
321
221 def UpdatePerfDataForSlaveAndBuild(slave_info, build_num): 322 def UpdatePerfDataForSlaveAndBuild(slave_info, build_num):
222 """Process updated perf data for a particular slave and build number. 323 """Process updated perf data for a particular slave and build number.
223 324
224 Args: 325 Args:
225 slave_info: A dictionary containing information about the slave to process. 326 slave_info: A dictionary containing information about the slave to process.
226 build_num: The particular build number on the slave to process. 327 build_num: The particular build number on the slave to process.
227 328
228 Returns: 329 Returns:
229 True if the perf data for the given slave/build is updated properly, or 330 True if the perf data for the given slave/build is updated properly, or
230 False if any critical error occurred. 331 False if any critical error occurred.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 if time.time() - start_time >= 30: # Read for at most 30 seconds. 399 if time.time() - start_time >= 30: # Read for at most 30 seconds.
299 break 400 break
300 except (urllib2.URLError, socket.error), e: 401 except (urllib2.URLError, socket.error), e:
301 # Issue warning but continue to the next stdio link. 402 # Issue warning but continue to the next stdio link.
302 logging.warning('Error reading test stdio URL "%s": %s', stdio_url, 403 logging.warning('Error reading test stdio URL "%s": %s', stdio_url,
303 str(e)) 404 str(e))
304 finally: 405 finally:
305 if fp: 406 if fp:
306 fp.close() 407 fp.close()
307 408
308 perf_data_raw = [] 409 UpdatePerfDataFromFetchedContent(revision, url_contents,
309 410 stdio_url_data['webapp_name'],
310 def AppendRawPerfData(graph_name, description, value, units, units_x, 411 stdio_url_data['test_name'])
311 webapp_name, test_name, is_stacked=False):
312 perf_data_raw.append({
313 'graph_name': graph_name,
314 'description': description,
315 'value': value,
316 'units': units,
317 'units_x': units_x,
318 'webapp_name': webapp_name,
319 'test_name': test_name,
320 'stack': is_stacked,
321 })
322
323 # First scan for short-running perf test results.
324 for match in re.findall(
325 r'RESULT ([^:]+): ([^=]+)= ([-\d\.]+) (\S+)', url_contents):
326 AppendRawPerfData(match[0], match[1], eval(match[2]), match[3], None,
327 stdio_url_data['webapp_name'],
328 stdio_url_data['webapp_name'])
329
330 # Next scan for long-running perf test results.
331 for match in re.findall(
332 r'RESULT ([^:]+): ([^=]+)= (\[[^\]]+\]) (\S+) (\S+)', url_contents):
333 # TODO(dmikurube): Change the condition to use stacked graph when we
334 # determine how to specify it.
335 AppendRawPerfData(match[0], match[1], eval(match[2]), match[3], match[4],
336 stdio_url_data['webapp_name'],
337 stdio_url_data['test_name'],
338 match[0].endswith('-DMP'))
339
340 # Next scan for events in the test results.
341 for match in re.findall(
342 r'RESULT _EVENT_: ([^=]+)= (\[[^\]]+\])', url_contents):
343 AppendRawPerfData('_EVENT_', match[0], eval(match[1]), None, None,
344 stdio_url_data['webapp_name'],
345 stdio_url_data['test_name'])
346
347 # For each graph_name/description pair that refers to a long-running test
348 # result or an event, concatenate all the results together (assume results
349 # in the input file are in the correct order). For short-running test
350 # results, keep just one if more than one is specified.
351 perf_data = {} # Maps a graph-line key to a perf data dictionary.
352 for data in perf_data_raw:
353 key_graph = data['graph_name']
354 key_description = data['description']
355 if not key_graph in perf_data:
356 perf_data[key_graph] = {
357 'graph_name': data['graph_name'],
358 'value': {},
359 'units': data['units'],
360 'units_x': data['units_x'],
361 'webapp_name': data['webapp_name'],
362 'test_name': data['test_name'],
363 }
364 perf_data[key_graph]['stack'] = data['stack']
365 if 'stack_order' not in perf_data[key_graph]:
366 perf_data[key_graph]['stack_order'] = []
367 if (data['stack'] and
368 data['description'] not in perf_data[key_graph]['stack_order']):
369 perf_data[key_graph]['stack_order'].append(data['description'])
370
371 if data['graph_name'] != '_EVENT_' and not data['units_x']:
372 # Short-running test result.
373 perf_data[key_graph]['value'][key_description] = data['value']
374 else:
375 # Long-running test result or event.
376 if key_description in perf_data[key_graph]['value']:
377 perf_data[key_graph]['value'][key_description] += data['value']
378 else:
379 perf_data[key_graph]['value'][key_description] = data['value']
380
381 # Finally, for each graph-line in |perf_data|, update the associated local
382 # graph data files if necessary.
383 for perf_data_key in perf_data:
384 perf_data_dict = perf_data[perf_data_key]
385
386 dest_dir = os.path.join(LOCAL_GRAPH_DIR, perf_data_dict['webapp_name'])
387 if not os.path.exists(dest_dir):
388 os.mkdir(dest_dir) # Webapp name directory.
389 os.chmod(dest_dir, 0755)
390 dest_dir = os.path.join(dest_dir, perf_data_dict['test_name'])
391
392 SetupBaseGraphDirIfNeeded(perf_data_dict['webapp_name'],
393 perf_data_dict['test_name'], dest_dir)
394 if perf_data_dict['graph_name'] == '_EVENT_':
395 OutputEventData(revision, perf_data_dict['value'], dest_dir)
396 else:
397 OutputPerfData(revision, perf_data_dict['graph_name'],
398 perf_data_dict['value'],
399 perf_data_dict['units'], perf_data_dict['units_x'],
400 dest_dir,
401 perf_data_dict['stack'], perf_data_dict['stack_order'])
402 412
403 return True 413 return True
404 414
405 415
406 def UpdatePerfDataFiles(): 416 def UpdatePerfDataFiles():
407 """Updates the Chrome Endure graph data files with the latest test results. 417 """Updates the Chrome Endure graph data files with the latest test results.
408 418
409 For each known Chrome Endure slave, we scan its latest test results looking 419 For each known Chrome Endure slave, we scan its latest test results looking
410 for any new test data. Any new data that is found is then appended to the 420 for any new test data. Any new data that is found is then appended to the
411 data files used to display the Chrome Endure graphs. 421 data files used to display the Chrome Endure graphs.
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
598 with open(index_file, 'w') as f: 608 with open(index_file, 'w') as f:
599 f.write(page) 609 f.write(page)
600 os.chmod(index_file, 0755) 610 os.chmod(index_file, 0755)
601 611
602 612
603 def main(): 613 def main():
604 parser = optparse.OptionParser() 614 parser = optparse.OptionParser()
605 parser.add_option( 615 parser.add_option(
606 '-v', '--verbose', action='store_true', default=False, 616 '-v', '--verbose', action='store_true', default=False,
607 help='Use verbose logging.') 617 help='Use verbose logging.')
618 parser.add_option(
619 '-s', '--stdin', action='store_true', default=False,
620 help='Input from stdin instead of slaves for testing this script.')
608 options, _ = parser.parse_args(sys.argv) 621 options, _ = parser.parse_args(sys.argv)
609 622
610 logging_level = logging.DEBUG if options.verbose else logging.INFO 623 logging_level = logging.DEBUG if options.verbose else logging.INFO
611 logging.basicConfig(level=logging_level, 624 logging.basicConfig(level=logging_level,
612 format='[%(asctime)s] %(levelname)s: %(message)s') 625 format='[%(asctime)s] %(levelname)s: %(message)s')
613 626
614 success = UpdatePerfDataFiles() 627 if options.stdin:
615 if not success: 628 content = sys.stdin.read()
616 logging.error('Failed to update perf data files.') 629 UpdatePerfDataFromFetchedContent('12345', content, 'webapp', 'test')
617 sys.exit(0) 630 else:
631 success = UpdatePerfDataFiles()
632 if not success:
633 logging.error('Failed to update perf data files.')
634 sys.exit(0)
618 635
619 GenerateIndexPage() 636 GenerateIndexPage()
620 logging.debug('All done!') 637 logging.debug('All done!')
621 638
622 639
623 if __name__ == '__main__': 640 if __name__ == '__main__':
624 main() 641 main()
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698