Update sdk/platform-tools to version 26.0.0.
[android_tools.git] / sdk / platform-tools / systrace / catapult / telemetry / telemetry / internal / results / legacy_html_output_formatter.py
bloba3782c01d39d969c332411e1ad3edcfa65a8b351
1 # Copyright 2016 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.
5 import datetime
6 import json
7 import logging
8 import os
9 import re
11 from telemetry.core import util
12 from telemetry import decorators
13 from telemetry.internal.results import chart_json_output_formatter
14 from telemetry.internal.results import output_formatter
15 from telemetry import value as value_module
16 from telemetry.value import list_of_scalar_values
19 _TEMPLATE_HTML_PATH = os.path.join(
20 util.GetTelemetryDir(), 'support', 'html_output', 'results-template.html')
21 _JS_PLUGINS = [os.path.join('flot', 'jquery.flot.min.js'),
22 os.path.join('WebKit', 'PerformanceTests', 'resources',
23 'jquery.tablesorter.min.js'),
24 os.path.join('WebKit', 'PerformanceTests', 'resources',
25 'statistics.js')]
26 _UNIT_JSON = os.path.join(
27 util.GetTelemetryDir(), 'telemetry', 'value', 'unit-info.json')
30 def _DatetimeInEs5CompatibleFormat(dt):
31 return dt.strftime('%Y-%m-%dT%H:%M:%S.%f')
34 def _ShortDatetimeInEs5CompatibleFormat(dt):
35 return dt.strftime('%Y-%m-%d %H:%M:%S')
38 class LegacyHtmlOutputFormatter(output_formatter.OutputFormatter):
39 def __init__(self, output_stream, metadata, reset_results, browser_type,
40 results_label=None):
41 super(LegacyHtmlOutputFormatter, self).__init__(output_stream)
42 self._metadata = metadata
43 self._reset_results = reset_results
44 self._build_time = self._GetBuildTime()
45 self._combined_results = []
46 if results_label:
47 self._results_label = results_label
48 else:
49 self._results_label = '%s (%s)' % (
50 metadata.name, _ShortDatetimeInEs5CompatibleFormat(self._build_time))
51 self._result = {
52 'buildTime': _DatetimeInEs5CompatibleFormat(self._build_time),
53 'label': self._results_label,
54 'platform': browser_type,
55 'tests': {}
58 def _GetBuildTime(self):
59 return datetime.datetime.utcnow()
61 def _GetHtmlTemplate(self):
62 with open(_TEMPLATE_HTML_PATH) as f:
63 return f.read()
65 def _GetPlugins(self):
66 plugins = ''
67 for p in _JS_PLUGINS:
68 with open(os.path.join(util.GetTelemetryThirdPartyDir(), p)) as f:
69 plugins += f.read()
70 return plugins
72 def _GetUnitJson(self):
73 with open(_UNIT_JSON) as f:
74 return f.read()
76 def _ReadExistingResults(self, output_stream):
77 results_html = output_stream.read()
78 if self._reset_results or not results_html:
79 return []
80 m = re.search(
81 '^<script id="results-json" type="application/json">(.*?)</script>$',
82 results_html, re.MULTILINE | re.DOTALL)
83 if not m:
84 logging.warn('Failed to extract previous results from HTML output')
85 return []
86 return json.loads(m.group(1))[:512]
88 def _SaveResults(self, results):
89 self._output_stream.seek(0)
90 self._output_stream.write(unicode(results, 'utf-8'))
91 self._output_stream.truncate()
93 def _PrintPerfResult(self, measurement, trace, values, units,
94 result_type='default', std=None):
95 metric_name = measurement
96 if trace != measurement:
97 metric_name += '.' + trace
98 self._result['tests'].setdefault(self._test_name, {})
99 self._result['tests'][self._test_name].setdefault('metrics', {})
100 metric_data = {
101 'current': values,
102 'units': units,
103 'important': result_type == 'default'
105 if std is not None:
106 metric_data['std'] = std
107 self._result['tests'][self._test_name]['metrics'][metric_name] = metric_data
109 def _TranslateChartJson(self, chart_json_dict):
110 dummy_dict = dict()
112 for chart_name, traces in chart_json_dict['charts'].iteritems():
113 for trace_name, value_dict in traces.iteritems():
114 # TODO(eakuefner): refactor summarization so we don't have to jump
115 # through hoops like this.
116 if 'page_id' in value_dict:
117 del value_dict['page_id']
118 result_type = 'nondefault'
119 else:
120 result_type = 'default'
122 # Note: we explicitly ignore TraceValues because Buildbot did.
123 if value_dict['type'] == 'trace':
124 continue
125 value = value_module.Value.FromDict(value_dict, dummy_dict)
127 perf_value = value.GetBuildbotValue()
129 if '@@' in chart_name:
130 chart_name_to_print = '%s-%s' % tuple(chart_name.split('@@'))
131 else:
132 chart_name_to_print = str(chart_name)
134 if trace_name == 'summary':
135 trace_name = chart_name_to_print
137 std = None
138 if isinstance(value, list_of_scalar_values.ListOfScalarValues):
139 std = value.std
141 self._PrintPerfResult(chart_name_to_print, trace_name, perf_value,
142 value.units, result_type, std)
144 @property
145 def _test_name(self):
146 return self._metadata.name
148 def GetResults(self):
149 return self._result
151 def GetCombinedResults(self):
152 return self._combined_results
154 @decorators.Deprecated(
155 2017, 1, 7, 'Use HtmlOutputFormatter and file any issues on GitHub at '
156 'https://github.com/catapult-project/catapult/issues/new?labels=Results2&title=[Results2]')
157 def Format(self, page_test_results):
158 chart_json_dict = chart_json_output_formatter.ResultsAsChartDict(
159 self._metadata, page_test_results.all_page_specific_values,
160 page_test_results.all_summary_values)
162 self._TranslateChartJson(chart_json_dict)
163 self._PrintPerfResult('telemetry_page_measurement_results', 'num_failed',
164 [len(page_test_results.failures)], 'count',
165 'unimportant')
167 self._combined_results = self._ReadExistingResults(self._output_stream)
168 self._combined_results.append(self._result)
170 html = self._GetHtmlTemplate()
171 html = html.replace('%json_results%', json.dumps(self.GetCombinedResults()))
172 html = html.replace('%json_units%', self._GetUnitJson())
173 html = html.replace('%plugins%', self._GetPlugins())
174 self._SaveResults(html)