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.
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',
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
,
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
= []
47 self
._results
_label
= results_label
49 self
._results
_label
= '%s (%s)' % (
50 metadata
.name
, _ShortDatetimeInEs5CompatibleFormat(self
._build
_time
))
52 'buildTime': _DatetimeInEs5CompatibleFormat(self
._build
_time
),
53 'label': self
._results
_label
,
54 'platform': browser_type
,
58 def _GetBuildTime(self
):
59 return datetime
.datetime
.utcnow()
61 def _GetHtmlTemplate(self
):
62 with
open(_TEMPLATE_HTML_PATH
) as f
:
65 def _GetPlugins(self
):
68 with
open(os
.path
.join(util
.GetTelemetryThirdPartyDir(), p
)) as f
:
72 def _GetUnitJson(self
):
73 with
open(_UNIT_JSON
) as f
:
76 def _ReadExistingResults(self
, output_stream
):
77 results_html
= output_stream
.read()
78 if self
._reset
_results
or not results_html
:
81 '^<script id="results-json" type="application/json">(.*?)</script>$',
82 results_html
, re
.MULTILINE | re
.DOTALL
)
84 logging
.warn('Failed to extract previous results from HTML output')
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', {})
103 'important': result_type
== 'default'
106 metric_data
['std'] = std
107 self
._result
['tests'][self
._test
_name
]['metrics'][metric_name
] = metric_data
109 def _TranslateChartJson(self
, chart_json_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'
120 result_type
= 'default'
122 # Note: we explicitly ignore TraceValues because Buildbot did.
123 if value_dict
['type'] == 'trace':
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('@@'))
132 chart_name_to_print
= str(chart_name
)
134 if trace_name
== 'summary':
135 trace_name
= chart_name_to_print
138 if isinstance(value
, list_of_scalar_values
.ListOfScalarValues
):
141 self
._PrintPerfResult
(chart_name_to_print
, trace_name
, perf_value
,
142 value
.units
, result_type
, std
)
145 def _test_name(self
):
146 return self
._metadata
.name
148 def GetResults(self
):
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',
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
)