1# Copyright 2014 The Chromium Authors. All rights reserved.
2# Use of this source code is governed by a BSD-style license that can be
3# found in the LICENSE file.
4
5import csv
6
7from telemetry.internal.results import output_formatter
8from telemetry.value import scalar
9from telemetry.value import trace
10
11
12class CsvPivotTableOutputFormatter(output_formatter.OutputFormatter):
13  """Output the results as CSV suitable for reading into a spreadsheet.
14
15  This will write a header row, and one row for each value. Each value row
16  contains the value and unit, identifies the value (story_set, page, name), and
17  (optionally) data from --output-trace-tag. This format matches what
18  spreadsheet programs expect as input for a "pivot table".
19
20  A trace tag (--output-trace-tag) can be used to tag each value, to allow
21  easy combination of the resulting CSVs from several runs.
22  If the trace_tag contains a comma, it will be written as several
23  comma-separated values.
24
25  This class only processes scalar values.
26  """
27
28  FIELDS = ['story_set', 'page', 'name', 'value', 'units', 'run_index']
29
30  def __init__(self, output_stream, trace_tag=''):
31    super(CsvPivotTableOutputFormatter, self).__init__(output_stream)
32    self._trace_tag = trace_tag
33
34  def Format(self, page_test_results):
35    csv_writer = csv.writer(self.output_stream)
36
37    # Observe trace_tag. Use comma to split up the trace tag.
38    tag_values = self._trace_tag.split(',')
39    tag_values = [x for x in tag_values if x] # filter empty list entries
40    tag_headers = ['trace_tag_%d' % i for i in range(len(tag_values))]
41
42    # Write header.
43    csv_writer.writerow(self.FIELDS + tag_headers)
44
45    # Write all values. Each row contains a value + page-level metadata.
46    for run in page_test_results.all_page_runs:
47      run_index = page_test_results.all_page_runs.index(run)
48      page_dict = {
49          'page': run.story.display_name,
50          'story_set': run.story.page_set.Name(),
51          'run_index': run_index,
52      }
53      for value in run.values:
54        if (isinstance(value, scalar.ScalarValue) or
55            isinstance(value, trace.TraceValue)):
56          value_dict = {
57            'name': value.name,
58            'value': value.value,
59            'units': value.units,
60          }
61          value_dict.update(page_dict.items())
62          csv_writer.writerow(
63              [value_dict[field] for field in self.FIELDS] + tag_values)
64