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 collections
6import itertools
7import json
8
9from telemetry.internal.results import output_formatter
10from telemetry.value import summary as summary_module
11
12def ResultsAsChartDict(benchmark_metadata, page_specific_values,
13                       summary_values):
14  """Produces a dict for serialization to Chart JSON format from raw values.
15
16  Chart JSON is a transformation of the basic Telemetry JSON format that
17  removes the page map, summarizes the raw values, and organizes the results
18  by chart and trace name. This function takes the key pieces of data needed to
19  perform this transformation (namely, lists of values and a benchmark metadata
20  object) and processes them into a dict which can be serialized using the json
21  module.
22
23  Design doc for schema: http://goo.gl/kOtf1Y
24
25  Args:
26    page_specific_values: list of page-specific values
27    summary_values: list of summary values
28    benchmark_metadata: a benchmark.BenchmarkMetadata object
29
30  Returns:
31    A Chart JSON dict corresponding to the given data.
32  """
33  summary = summary_module.Summary(page_specific_values)
34  values = itertools.chain(
35      summary.interleaved_computed_per_page_values_and_summaries,
36      summary_values)
37  charts = collections.defaultdict(dict)
38
39  for value in values:
40    if value.page:
41      chart_name, trace_name = (value.GetChartAndTraceNameForPerPageResult())
42    else:
43      chart_name, trace_name = (
44          value.GetChartAndTraceNameForComputedSummaryResult(None))
45      if chart_name == trace_name:
46        trace_name = 'summary'
47
48    if value.tir_label:
49      chart_name = value.tir_label + '@@' + chart_name
50
51    # This intentionally overwrites the trace if it already exists because this
52    # is expected of output from the buildbots currently.
53    # See: crbug.com/413393
54    charts[chart_name][trace_name] = value.AsDict()
55
56  result_dict = {
57    'format_version': '0.1',
58    'next_version': '0.2',
59    # TODO(sullivan): benchmark_name, benchmark_description, and
60    # trace_rerun_options should be removed when incrementing format_version
61    # to 0.1.
62    'benchmark_name': benchmark_metadata.name,
63    'benchmark_description': benchmark_metadata.description,
64    'trace_rerun_options': benchmark_metadata.rerun_options,
65    'benchmark_metadata': benchmark_metadata.AsDict(),
66    'charts': charts,
67  }
68
69  return result_dict
70
71# TODO(eakuefner): Transition this to translate Telemetry JSON.
72class ChartJsonOutputFormatter(output_formatter.OutputFormatter):
73  def __init__(self, output_stream, benchmark_metadata):
74    super(ChartJsonOutputFormatter, self).__init__(output_stream)
75    self._benchmark_metadata = benchmark_metadata
76
77  def Format(self, page_test_results):
78    json.dump(ResultsAsChartDict(
79        self._benchmark_metadata,
80        page_test_results.all_page_specific_values,
81        page_test_results.all_summary_values),
82              self.output_stream, indent=2)
83    self.output_stream.write('\n')
84