Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 | 4 |
| 5 from collections import defaultdict | 5 from collections import defaultdict |
| 6 | 6 |
| 7 from telemetry.core.platform import tracing_category_filter | 7 from telemetry.core.platform import tracing_category_filter |
| 8 from telemetry.core.platform import tracing_options | 8 from telemetry.core.platform import tracing_options |
| 9 from telemetry.page import page_test | 9 from telemetry.page import page_test |
| 10 from telemetry.timeline import model as model_module | 10 from telemetry.timeline import model as model_module |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 104 if not interactions_with_metric: | 104 if not interactions_with_metric: |
| 105 continue | 105 continue |
| 106 if len(interactions_with_metric) != len(interactions): | 106 if len(interactions_with_metric) != len(interactions): |
| 107 raise InvalidInteractions('Interaction records with the same logical ' | 107 raise InvalidInteractions('Interaction records with the same logical ' |
| 108 'name must have the same flags.') | 108 'name must have the same flags.') |
| 109 metric = self._get_metric_from_metric_type_callback(metric_type) | 109 metric = self._get_metric_from_metric_type_callback(metric_type) |
| 110 metric.AddResults(self._model, self._renderer_thread, | 110 metric.AddResults(self._model, self._renderer_thread, |
| 111 interactions, wrapped_results) | 111 interactions, wrapped_results) |
| 112 | 112 |
| 113 | 113 |
| 114 class TimelineBasedMeasurement(page_test.PageTest): | 114 class Options(object): |
| 115 """Collects multiple metrics pages based on their interaction records. | 115 """A class to be used to configure TimelineBasedMeasurement. |
| 116 | 116 |
| 117 A timeline measurement shifts the burden of what metrics to collect onto the | 117 This is created and returned by |
| 118 page under test, or the pageset running that page. Instead of the measurement | 118 Benchmark.CreateTimelineBasedMeasurementOptions. |
| 119 having a fixed set of values it collects about the page, the page being tested | 119 """ |
| 120 | |
| 121 def __init__(self, overhead_level=NO_OVERHEAD_LEVEL): | |
| 122 """Save the overhead level. | |
| 123 | |
| 124 As the amount of instrumentation increases, so does the overhead. | |
| 125 The user of the measurement chooses the overhead level that is appropriate, | |
| 126 and the tracing is filtered accordingly. | |
| 127 | |
| 128 overhead_level: one of NO_OVERHEAD_LEVEL, V8_OVERHEAD_LEVEL, | |
| 129 MINIMAL_OVERHEAD_LEVEL, or DEBUG_OVERHEAD_LEVEL. | |
| 130 The v8 overhead level is a temporary solution that may be removed. | |
| 131 """ | |
| 132 self._overhead_level = overhead_level | |
| 133 | |
| 134 | |
| 135 class TimelineBasedMeasurement(object): | |
| 136 """Collects multiple metrics based on their interaction records. | |
| 137 | |
| 138 A timeline based measurement shifts the burden of what metrics to collect onto | |
| 139 the user story under test. Instead of the measurement | |
| 140 having a fixed set of values it collects, the user story being tested | |
| 120 issues (via javascript) an Interaction record into the user timing API that | 141 issues (via javascript) an Interaction record into the user timing API that |
| 121 describing what the page is doing at that time, as well as a standardized set | 142 describing what is happening at that time, as well as a standardized set |
| 122 of flags describing the semantics of the work being done. The | 143 of flags describing the semantics of the work being done. The |
| 123 TimelineBasedMeasurement object collects a trace that includes both these | 144 TimelineBasedMeasurement object collects a trace that includes both these |
| 124 interaction recorsd, and a user-chosen amount of performance data using | 145 interaction records, and a user-chosen amount of performance data using |
| 125 Telemetry's various timeline-producing APIs, tracing especially. | 146 Telemetry's various timeline-producing APIs, tracing especially. |
| 126 | 147 |
| 127 It then passes the recorded timeline to different TimelineBasedMetrics based | 148 It then passes the recorded timeline to different TimelineBasedMetrics based |
| 128 on those flags. This allows a single run through a page to produce load timing | 149 on those flags. As an example, this allows a single user story run to produce |
| 129 data, smoothness data, critical jank information and overall cpu usage | 150 load timing data, smoothness data, critical jank information and overall cpu |
| 130 information. | 151 usage information. |
| 131 | 152 |
| 132 For information on how to mark up a page to work with | 153 For information on how to mark up a page to work with |
| 133 TimelineBasedMeasurement, refer to the | 154 TimelineBasedMeasurement, refer to the |
| 134 perf.metrics.timeline_interaction_record module. | 155 perf.metrics.timeline_interaction_record module. |
| 156 """ | |
| 157 def __init__(self, options): | |
| 158 self._overhead_level = options._overhead_level | |
| 135 | 159 |
| 136 """ | 160 def StartTracing(self, app, synthetic_delay_categories=None): |
|
nednguyen
2014/12/19 01:16:21
s/StartTracing/WillRunTest
also
s/StopTracing/DidR
slamm
2015/01/02 23:47:20
Done.
| |
| 137 def __init__(self, overhead_level=NO_OVERHEAD_LEVEL): | 161 """Configure and start tracing. |
| 138 super(TimelineBasedMeasurement, self).__init__('RunPageInteractions') | |
| 139 self._overhead_level = overhead_level | |
| 140 | 162 |
| 141 def WillNavigateToPage(self, page, tab): | 163 Args: |
| 142 if not tab.browser.platform.tracing_controller.IsChromeTracingSupported( | 164 app: an app.App subclass instance. |
| 143 tab.browser): | 165 synthetic_delay_categories: iterable of delays. For example: |
| 166 ['DELAY(cc.BeginMainFrame;0.014;alternating)'] | |
| 167 where 'cc.BeginMainFrame' is a timeline event, 0.014 is the delay, | |
| 168 and 'alternating' is the mode. | |
| 169 """ | |
| 170 if not app.platform.tracing_controller.IsChromeTracingSupported(app): | |
| 144 raise Exception('Not supported') | 171 raise Exception('Not supported') |
| 145 | 172 |
| 146 assert self._overhead_level in ALL_OVERHEAD_LEVELS | 173 assert self._overhead_level in ALL_OVERHEAD_LEVELS |
| 147 if self._overhead_level == NO_OVERHEAD_LEVEL: | 174 if self._overhead_level == NO_OVERHEAD_LEVEL: |
| 148 category_filter = tracing_category_filter.CreateNoOverheadFilter() | 175 category_filter = tracing_category_filter.CreateNoOverheadFilter() |
| 149 # TODO(ernstm): Remove this overhead level when benchmark relevant v8 events | 176 # TODO(ernstm): Remove this overhead level when benchmark relevant v8 events |
| 150 # become available in the 'benchmark' category. | 177 # become available in the 'benchmark' category. |
| 151 elif self._overhead_level == V8_OVERHEAD_LEVEL: | 178 elif self._overhead_level == V8_OVERHEAD_LEVEL: |
| 152 category_filter = tracing_category_filter.CreateNoOverheadFilter() | 179 category_filter = tracing_category_filter.CreateNoOverheadFilter() |
| 153 category_filter.AddIncludedCategory('v8') | 180 category_filter.AddIncludedCategory('v8') |
| 154 elif self._overhead_level == MINIMAL_OVERHEAD_LEVEL: | 181 elif self._overhead_level == MINIMAL_OVERHEAD_LEVEL: |
| 155 category_filter = tracing_category_filter.CreateMinimalOverheadFilter() | 182 category_filter = tracing_category_filter.CreateMinimalOverheadFilter() |
| 156 else: | 183 else: |
| 157 category_filter = tracing_category_filter.CreateDebugOverheadFilter() | 184 category_filter = tracing_category_filter.CreateDebugOverheadFilter() |
| 158 | 185 |
| 159 for delay in page.GetSyntheticDelayCategories(): | 186 # TODO(slamm): Move synthetic_delay_categories to the TBM options. |
| 187 for delay in synthetic_delay_categories or []: | |
| 160 category_filter.AddSyntheticDelay(delay) | 188 category_filter.AddSyntheticDelay(delay) |
| 161 options = tracing_options.TracingOptions() | 189 options = tracing_options.TracingOptions() |
| 162 options.enable_chrome_trace = True | 190 options.enable_chrome_trace = True |
| 163 tab.browser.platform.tracing_controller.Start(options, category_filter) | 191 app.platform.tracing_controller.Start(options, category_filter) |
| 164 | 192 |
| 165 def ValidateAndMeasurePage(self, page, tab, results): | 193 def Measure(self, app, renderer_thread_tab_id, results): |
| 166 """ Collect all possible metrics and added them to results. """ | 194 """Collect all possible metrics and added them to results.""" |
| 167 trace_result = tab.browser.platform.tracing_controller.Stop() | 195 trace_result = app.platform.tracing_controller.Stop() |
| 168 results.AddValue(trace.TraceValue(results.current_page, trace_result)) | 196 results.AddValue(trace.TraceValue(results.current_page, trace_result)) |
| 169 model = model_module.TimelineModel(trace_result) | 197 model = model_module.TimelineModel(trace_result) |
| 170 renderer_thread = model.GetRendererThreadFromTabId(tab.id) | 198 renderer_thread = model.GetRendererThreadFromTabId(renderer_thread_tab_id) |
| 171 meta_metrics = _TimelineBasedMetrics( | 199 meta_metrics = _TimelineBasedMetrics( |
| 172 model, renderer_thread, _GetMetricFromMetricType) | 200 model, renderer_thread, _GetMetricFromMetricType) |
| 173 meta_metrics.AddResults(results) | 201 meta_metrics.AddResults(results) |
| 174 | 202 |
| 203 def StopTracing(self, app): | |
| 204 if app.platform.tracing_controller.is_tracing_running: | |
| 205 app.platform.tracing_controller.Stop() | |
| 206 | |
| 207 | |
| 208 class TimelineBasedPageTest(page_test.PageTest): | |
| 209 """Page test that collects metrics with TimelineBasedMeasurement.""" | |
| 210 def __init__(self, tbm): | |
| 211 super(TimelineBasedPageTest, self).__init__('RunPageInteractions') | |
| 212 self._measurement = tbm | |
| 213 | |
| 214 @property | |
| 215 def measurement(self): | |
| 216 return self._measurement | |
| 217 | |
| 218 def WillNavigateToPage(self, page, tab): | |
| 219 self._measurement.StartTracing( | |
| 220 tab.browser, page.GetSyntheticDelayCategories()) | |
| 221 | |
| 222 def ValidateAndMeasurePage(self, page, tab, results): | |
| 223 """Collect all possible metrics and added them to results.""" | |
| 224 self._measurement.Measure(tab.browser, tab.id, results) | |
| 175 | 225 |
| 176 def CleanUpAfterPage(self, page, tab): | 226 def CleanUpAfterPage(self, page, tab): |
| 177 if tab.browser.platform.tracing_controller.is_tracing_running: | 227 self._measurement.StopTracing(tab.browser) |
| 178 tab.browser.platform.tracing_controller.Stop() | |
| OLD | NEW |