15f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved.
25f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
35f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)# found in the LICENSE file.
45f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
55f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)import json
65f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
75f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)from telemetry.results import output_formatter
85f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)def ResultsAsDict(page_test_results, benchmark_metadata):
1003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  """Takes PageTestResults to a dict serializable to JSON.
1103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  To serialize results as JSON we first convert them to a dict that can be
1303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  serialized by the json module. It also requires a benchmark_metadat object
1403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  for metadata to be integrated into the results (currently the benchmark
1503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  name).
1603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  Args:
1803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    page_test_results: a PageTestResults object
1903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    benchmark_metadata: a benchmark.BenchmarkMetadata object
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  """
215f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  result_dict = {
225f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    'format_version': '0.2',
2303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    'benchmark_name': benchmark_metadata.name,
245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    'summary_values': [v.AsDict() for v in
255f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                       page_test_results.all_summary_values],
265f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    'per_page_values': [v.AsDict() for v in
275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)                        page_test_results.all_page_specific_values],
2803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    'pages': {p.id: p.AsDict() for p in _GetAllPages(page_test_results)}
295f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  }
305f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
315f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return result_dict
325f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)def _GetAllPages(page_test_results):
345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  pages = set(page_run.page for page_run in
355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)              page_test_results.all_page_runs)
365f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  return pages
375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)class JsonOutputFormatter(output_formatter.OutputFormatter):
3903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  def __init__(self, output_stream, benchmark_metadata):
405f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    super(JsonOutputFormatter, self).__init__(output_stream)
4103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    self._benchmark_metadata = benchmark_metadata
425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  @property
4403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)  def benchmark_metadata(self):
4503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    return self._benchmark_metadata
465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)
475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)  def Format(self, page_test_results):
4803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    json.dump(ResultsAsDict(page_test_results, self.benchmark_metadata),
495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)        self.output_stream)
505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles)    self.output_stream.write('\n')
51