133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Copyright 2014 The Chromium Authors. All rights reserved. 233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# Use of this source code is governed by a BSD-style license that can be 333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck# found in the LICENSE file. 433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckimport csv 633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom telemetry.internal.results import output_formatter 833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom telemetry.value import scalar 933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckfrom telemetry.value import trace 1033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 1133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 1233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reckclass CsvPivotTableOutputFormatter(output_formatter.OutputFormatter): 1333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """Output the results as CSV suitable for reading into a spreadsheet. 1433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 1533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck This will write a header row, and one row for each value. Each value row 1633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck contains the value and unit, identifies the value (story_set, page, name), and 1733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck (optionally) data from --output-trace-tag. This format matches what 1833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck spreadsheet programs expect as input for a "pivot table". 1933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 2033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck A trace tag (--output-trace-tag) can be used to tag each value, to allow 2133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck easy combination of the resulting CSVs from several runs. 2233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck If the trace_tag contains a comma, it will be written as several 2333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck comma-separated values. 2433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 2533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck This class only processes scalar values. 2633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck """ 2733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 2833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck FIELDS = ['story_set', 'page', 'name', 'value', 'units', 'run_index'] 2933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 3033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def __init__(self, output_stream, trace_tag=''): 3133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck super(CsvPivotTableOutputFormatter, self).__init__(output_stream) 3233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck self._trace_tag = trace_tag 3333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 3433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck def Format(self, page_test_results): 3533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck csv_writer = csv.writer(self.output_stream) 3633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 3733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Observe trace_tag. Use comma to split up the trace tag. 3833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck tag_values = self._trace_tag.split(',') 3933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck tag_values = [x for x in tag_values if x] # filter empty list entries 4033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck tag_headers = ['trace_tag_%d' % i for i in range(len(tag_values))] 4133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 4233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Write header. 4333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck csv_writer.writerow(self.FIELDS + tag_headers) 4433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 4533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck # Write all values. Each row contains a value + page-level metadata. 4633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for run in page_test_results.all_page_runs: 4733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck run_index = page_test_results.all_page_runs.index(run) 4833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck page_dict = { 4933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'page': run.story.display_name, 5033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'story_set': run.story.page_set.Name(), 5133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'run_index': run_index, 5233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck } 5333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck for value in run.values: 5433259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck if (isinstance(value, scalar.ScalarValue) or 5533259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck isinstance(value, trace.TraceValue)): 5633259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck value_dict = { 5733259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'name': value.name, 5833259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'value': value.value, 5933259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck 'units': value.units, 6033259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck } 6133259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck value_dict.update(page_dict.items()) 6233259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck csv_writer.writerow( 6333259e44c8229f70ffe0cf3bb5ca9375c4feb2f9John Reck [value_dict[field] for field in self.FIELDS] + tag_values) 64