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

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

Issue 10961012: Dump JSON data for stacked graphs in endure_result_parser.py. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fixed for the comments. 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 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
105 elif int(line_dict['rev']) < int(revision): 105 elif int(line_dict['rev']) < int(revision):
106 break 106 break
107 if not overwritten: 107 if not overwritten:
108 existing_lines.insert(0, simplejson.dumps(new_line)) 108 existing_lines.insert(0, simplejson.dumps(new_line))
109 109
110 with open(data_file, 'w') as f: 110 with open(data_file, 'w') as f:
111 f.write('\n'.join(existing_lines)) 111 f.write('\n'.join(existing_lines))
112 os.chmod(data_file, 0755) 112 os.chmod(data_file, 0755)
113 113
114 114
115 def OutputPerfData(revision, graph_name, values, units, units_x, dest_dir): 115 def OutputPerfData(revision, graph_name, values, units, units_x, dest_dir,
116 is_stacked=False, stack_order=[]):
116 """Outputs perf data to a local text file to be graphed. 117 """Outputs perf data to a local text file to be graphed.
117 118
118 Args: 119 Args:
119 revision: The string revision number associated with the perf data. 120 revision: The string revision number associated with the perf data.
120 graph_name: The string name of the graph on which to plot the data. 121 graph_name: The string name of the graph on which to plot the data.
121 values: A dict which maps a description to a value. A value is either a 122 values: A dict which maps a description to a value. A value is either a
122 single data value to be graphed, or a list of 2-tuples 123 single data value to be graphed, or a list of 2-tuples
123 representing (x, y) points to be graphed for long-running tests. 124 representing (x, y) points to be graphed for long-running tests.
124 units: The string description for the y-axis units on the graph. 125 units: The string description for the y-axis units on the graph.
125 units_x: The string description for the x-axis units on the graph. Should 126 units_x: The string description for the x-axis units on the graph. Should
126 be set to None if the results are not for long-running graphs. 127 be set to None if the results are not for long-running graphs.
127 dest_dir: The name of the destination directory to which to write. 128 dest_dir: The name of the destination directory to which to write.
129 is_stacked: True to draw a "stacked" graph. First-come values are
130 stacked at bottom by default.
131 stack_order: A list that contains key strings in the order to stack values
132 in the graph.
128 """ 133 """
129 # Update graphs.dat, which contains metadata associated with each graph. 134 # Update graphs.dat, which contains metadata associated with each graph.
130 existing_graphs = [] 135 existing_graphs = []
131 graphs_file = os.path.join(dest_dir, 'graphs.dat') 136 graphs_file = os.path.join(dest_dir, 'graphs.dat')
132 if os.path.exists(graphs_file): 137 if os.path.exists(graphs_file):
133 with open(graphs_file, 'r') as f: 138 with open(graphs_file, 'r') as f:
134 existing_graphs = simplejson.loads(f.read()) 139 existing_graphs = simplejson.loads(f.read())
135 is_new_graph = True 140 is_new_graph = True
136 for graph in existing_graphs: 141 for graph in existing_graphs:
137 if graph['name'] == graph_name: 142 if graph['name'] == graph_name:
(...skipping 28 matching lines...) Expand all
166 points = [] 171 points = []
167 for point in value: 172 for point in value:
168 points.append([str(point[0]), str(point[1])]) 173 points.append([str(point[0]), str(point[1])])
169 new_traces[description] = points 174 new_traces[description] = points
170 else: 175 else:
171 new_traces[description] = [str(value), str(0.0)] 176 new_traces[description] = [str(value), str(0.0)]
172 new_line = { 177 new_line = {
173 'traces': new_traces, 178 'traces': new_traces,
174 'rev': revision 179 'rev': revision
175 } 180 }
181 if is_stacked:
182 new_line['stack'] = True
183 new_line['stack_order'] = stack_order
176 184
177 WriteToDataFile(new_line, existing_lines, revision, data_file) 185 WriteToDataFile(new_line, existing_lines, revision, data_file)
178 186
179 187
180 def OutputEventData(revision, event_dict, dest_dir): 188 def OutputEventData(revision, event_dict, dest_dir):
181 """Outputs event data to a local text file to be graphed. 189 """Outputs event data to a local text file to be graphed.
182 190
183 Args: 191 Args:
184 revision: The string revision number associated with the event data. 192 revision: The string revision number associated with the event data.
185 event_dict: A dict which maps a description to an array of tuples 193 event_dict: A dict which maps a description to an array of tuples
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
293 # Issue warning but continue to the next stdio link. 301 # Issue warning but continue to the next stdio link.
294 logging.warning('Error reading test stdio URL "%s": %s', stdio_url, 302 logging.warning('Error reading test stdio URL "%s": %s', stdio_url,
295 str(e)) 303 str(e))
296 finally: 304 finally:
297 if fp: 305 if fp:
298 fp.close() 306 fp.close()
299 307
300 perf_data_raw = [] 308 perf_data_raw = []
301 309
302 def AppendRawPerfData(graph_name, description, value, units, units_x, 310 def AppendRawPerfData(graph_name, description, value, units, units_x,
303 webapp_name, test_name): 311 webapp_name, test_name, is_stacked=False):
304 perf_data_raw.append({ 312 perf_data_raw.append({
305 'graph_name': graph_name, 313 'graph_name': graph_name,
306 'description': description, 314 'description': description,
307 'value': value, 315 'value': value,
308 'units': units, 316 'units': units,
309 'units_x': units_x, 317 'units_x': units_x,
310 'webapp_name': webapp_name, 318 'webapp_name': webapp_name,
311 'test_name': test_name, 319 'test_name': test_name,
320 'stack': is_stacked,
312 }) 321 })
313 322
314 # First scan for short-running perf test results. 323 # First scan for short-running perf test results.
315 for match in re.findall( 324 for match in re.findall(
316 r'RESULT ([^:]+): ([^=]+)= ([-\d\.]+) (\S+)', url_contents): 325 r'RESULT ([^:]+): ([^=]+)= ([-\d\.]+) (\S+)', url_contents):
317 AppendRawPerfData(match[0], match[1], eval(match[2]), match[3], None, 326 AppendRawPerfData(match[0], match[1], eval(match[2]), match[3], None,
318 stdio_url_data['webapp_name'], 327 stdio_url_data['webapp_name'],
319 stdio_url_data['webapp_name']) 328 stdio_url_data['webapp_name'])
320 329
321 # Next scan for long-running perf test results. 330 # Next scan for long-running perf test results.
322 for match in re.findall( 331 for match in re.findall(
323 r'RESULT ([^:]+): ([^=]+)= (\[[^\]]+\]) (\S+) (\S+)', url_contents): 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.
324 AppendRawPerfData(match[0], match[1], eval(match[2]), match[3], match[4], 335 AppendRawPerfData(match[0], match[1], eval(match[2]), match[3], match[4],
325 stdio_url_data['webapp_name'], 336 stdio_url_data['webapp_name'],
326 stdio_url_data['test_name']) 337 stdio_url_data['test_name'],
338 match[0].endswith('-DMP'))
327 339
328 # Next scan for events in the test results. 340 # Next scan for events in the test results.
329 for match in re.findall( 341 for match in re.findall(
330 r'RESULT _EVENT_: ([^=]+)= (\[[^\]]+\])', url_contents): 342 r'RESULT _EVENT_: ([^=]+)= (\[[^\]]+\])', url_contents):
331 AppendRawPerfData('_EVENT_', match[0], eval(match[1]), None, None, 343 AppendRawPerfData('_EVENT_', match[0], eval(match[1]), None, None,
332 stdio_url_data['webapp_name'], 344 stdio_url_data['webapp_name'],
333 stdio_url_data['test_name']) 345 stdio_url_data['test_name'])
334 346
335 # For each graph_name/description pair that refers to a long-running test 347 # For each graph_name/description pair that refers to a long-running test
336 # result or an event, concatenate all the results together (assume results 348 # result or an event, concatenate all the results together (assume results
337 # in the input file are in the correct order). For short-running test 349 # in the input file are in the correct order). For short-running test
338 # results, keep just one if more than one is specified. 350 # results, keep just one if more than one is specified.
339 perf_data = {} # Maps a graph-line key to a perf data dictionary. 351 perf_data = {} # Maps a graph-line key to a perf data dictionary.
340 for data in perf_data_raw: 352 for data in perf_data_raw:
341 key_graph = data['graph_name'] 353 key_graph = data['graph_name']
342 key_description = data['description'] 354 key_description = data['description']
343 if not key_graph in perf_data: 355 if not key_graph in perf_data:
344 perf_data[key_graph] = { 356 perf_data[key_graph] = {
345 'graph_name': data['graph_name'], 357 'graph_name': data['graph_name'],
346 'value': {}, 358 'value': {},
347 'units': data['units'], 359 'units': data['units'],
348 'units_x': data['units_x'], 360 'units_x': data['units_x'],
349 'webapp_name': data['webapp_name'], 361 'webapp_name': data['webapp_name'],
350 'test_name': data['test_name'], 362 'test_name': data['test_name'],
351 } 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
352 if data['graph_name'] != '_EVENT_' and not data['units_x']: 371 if data['graph_name'] != '_EVENT_' and not data['units_x']:
353 # Short-running test result. 372 # Short-running test result.
354 perf_data[key_graph]['value'][key_description] = data['value'] 373 perf_data[key_graph]['value'][key_description] = data['value']
355 else: 374 else:
356 # Long-running test result or event. 375 # Long-running test result or event.
357 if key_description in perf_data[key_graph]['value']: 376 if key_description in perf_data[key_graph]['value']:
358 perf_data[key_graph]['value'][key_description] += data['value'] 377 perf_data[key_graph]['value'][key_description] += data['value']
359 else: 378 else:
360 perf_data[key_graph]['value'][key_description] = data['value'] 379 perf_data[key_graph]['value'][key_description] = data['value']
361 380
362 # Finally, for each graph-line in |perf_data|, update the associated local 381 # Finally, for each graph-line in |perf_data|, update the associated local
363 # graph data files if necessary. 382 # graph data files if necessary.
364 for perf_data_key in perf_data: 383 for perf_data_key in perf_data:
365 perf_data_dict = perf_data[perf_data_key] 384 perf_data_dict = perf_data[perf_data_key]
366 385
367 dest_dir = os.path.join(LOCAL_GRAPH_DIR, perf_data_dict['webapp_name']) 386 dest_dir = os.path.join(LOCAL_GRAPH_DIR, perf_data_dict['webapp_name'])
368 if not os.path.exists(dest_dir): 387 if not os.path.exists(dest_dir):
369 os.mkdir(dest_dir) # Webapp name directory. 388 os.mkdir(dest_dir) # Webapp name directory.
370 os.chmod(dest_dir, 0755) 389 os.chmod(dest_dir, 0755)
371 dest_dir = os.path.join(dest_dir, perf_data_dict['test_name']) 390 dest_dir = os.path.join(dest_dir, perf_data_dict['test_name'])
372 391
373 SetupBaseGraphDirIfNeeded(perf_data_dict['webapp_name'], 392 SetupBaseGraphDirIfNeeded(perf_data_dict['webapp_name'],
374 perf_data_dict['test_name'], dest_dir) 393 perf_data_dict['test_name'], dest_dir)
375 if perf_data_dict['graph_name'] == '_EVENT_': 394 if perf_data_dict['graph_name'] == '_EVENT_':
376 OutputEventData(revision, perf_data_dict['value'], dest_dir) 395 OutputEventData(revision, perf_data_dict['value'], dest_dir)
377 else: 396 else:
378 OutputPerfData(revision, perf_data_dict['graph_name'], 397 OutputPerfData(revision, perf_data_dict['graph_name'],
379 perf_data_dict['value'], 398 perf_data_dict['value'],
380 perf_data_dict['units'], perf_data_dict['units_x'], 399 perf_data_dict['units'], perf_data_dict['units_x'],
381 dest_dir) 400 dest_dir,
401 perf_data_dict['stack'], perf_data_dict['stack_order'])
382 402
383 return True 403 return True
384 404
385 405
386 def UpdatePerfDataFiles(): 406 def UpdatePerfDataFiles():
387 """Updates the Chrome Endure graph data files with the latest test results. 407 """Updates the Chrome Endure graph data files with the latest test results.
388 408
389 For each known Chrome Endure slave, we scan its latest test results looking 409 For each known Chrome Endure slave, we scan its latest test results looking
390 for any new test data. Any new data that is found is then appended to the 410 for any new test data. Any new data that is found is then appended to the
391 data files used to display the Chrome Endure graphs. 411 data files used to display the Chrome Endure graphs.
(...skipping 203 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 if not success: 615 if not success:
596 logging.error('Failed to update perf data files.') 616 logging.error('Failed to update perf data files.')
597 sys.exit(0) 617 sys.exit(0)
598 618
599 GenerateIndexPage() 619 GenerateIndexPage()
600 logging.debug('All done!') 620 logging.debug('All done!')
601 621
602 622
603 if __name__ == '__main__': 623 if __name__ == '__main__':
604 main() 624 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