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 import logging | 5 import logging |
6 import os | 6 import os |
7 | 7 |
8 from collections import defaultdict | 8 from collections import defaultdict |
9 from telemetry.core import util | 9 from telemetry.core import util |
10 from telemetry.core.backends.chrome import tracing_backend | 10 from telemetry.core.backends.chrome import tracing_backend |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
58 return self._results.current_page | 58 return self._results.current_page |
59 | 59 |
60 def _GetResultName(self, trace_name): | 60 def _GetResultName(self, trace_name): |
61 return '%s-%s' % (self._result_prefix, trace_name) | 61 return '%s-%s' % (self._result_prefix, trace_name) |
62 | 62 |
63 def AddValue(self, value): | 63 def AddValue(self, value): |
64 value.name = self._GetResultName(value.name) | 64 value.name = self._GetResultName(value.name) |
65 self._results.AddValue(value) | 65 self._results.AddValue(value) |
66 | 66 |
67 class _TimelineBasedMetrics(object): | 67 class _TimelineBasedMetrics(object): |
68 def __init__(self, model, renderer_thread, | 68 def __init__(self, model, get_metric_from_metric_type_callback): |
69 get_metric_from_metric_type_callback): | |
70 self._model = model | 69 self._model = model |
71 self._renderer_thread = renderer_thread | |
72 self._get_metric_from_metric_type_callback = \ | 70 self._get_metric_from_metric_type_callback = \ |
73 get_metric_from_metric_type_callback | 71 get_metric_from_metric_type_callback |
74 | 72 |
75 def FindTimelineInteractionRecords(self): | 73 def FindTimelineInteractionRecords(self): |
76 # TODO(nduca): Add support for page-load interaction record. | 74 # TODO(nduca): Add support for page-load interaction record. |
77 return [tir_module.TimelineInteractionRecord.FromAsyncEvent(event) for | 75 threads_to_records_map = ( |
78 event in self._renderer_thread.async_slices | 76 tir_module.GetThreadToInteractionRecordsMapsFromModel(self._model)) |
79 if tir_module.IsTimelineInteractionRecord(event.name)] | 77 #TODO(nednguyen) support multiple records on multiple threads |
| 78 assert len(threads_to_records_map) == 1, ( |
| 79 'TimelineBasedMeasurement only support interaction records issued' |
| 80 ' from a single thread.') |
| 81 return threads_to_records_map.values[0] |
80 | 82 |
81 def AddResults(self, results): | 83 def AddResults(self, results): |
82 all_interactions = self.FindTimelineInteractionRecords() | 84 all_interactions = self.FindTimelineInteractionRecords() |
83 if len(all_interactions) == 0: | 85 if len(all_interactions) == 0: |
84 raise InvalidInteractions('Expected at least one interaction record on ' | 86 raise InvalidInteractions('Expected at least one interaction record on ' |
85 'the page') | 87 'the page') |
86 | 88 |
87 interactions_by_label = defaultdict(list) | 89 interactions_by_label = defaultdict(list) |
88 for i in all_interactions: | 90 for i in all_interactions: |
89 interactions_by_label[i.label].append(i) | 91 interactions_by_label[i.label].append(i) |
(...skipping 11 matching lines...) Expand all Loading... |
101 # For each metric type, either all or none of the interactions should | 103 # For each metric type, either all or none of the interactions should |
102 # have that metric. | 104 # have that metric. |
103 interactions_with_metric = [i for i in interactions if | 105 interactions_with_metric = [i for i in interactions if |
104 i.HasMetric(metric_type)] | 106 i.HasMetric(metric_type)] |
105 if not interactions_with_metric: | 107 if not interactions_with_metric: |
106 continue | 108 continue |
107 if len(interactions_with_metric) != len(interactions): | 109 if len(interactions_with_metric) != len(interactions): |
108 raise InvalidInteractions('Interaction records with the same logical ' | 110 raise InvalidInteractions('Interaction records with the same logical ' |
109 'name must have the same flags.') | 111 'name must have the same flags.') |
110 metric = self._get_metric_from_metric_type_callback(metric_type) | 112 metric = self._get_metric_from_metric_type_callback(metric_type) |
111 metric.AddResults(self._model, self._renderer_thread, | 113 metric.AddResults(self._model, interactions, wrapped_results) |
112 interactions, wrapped_results) | |
113 | 114 |
114 | 115 |
115 class TimelineBasedMeasurement(page_measurement.PageMeasurement): | 116 class TimelineBasedMeasurement(page_measurement.PageMeasurement): |
116 """Collects multiple metrics pages based on their interaction records. | 117 """Collects multiple metrics pages based on their interaction records. |
117 | 118 |
118 A timeline measurement shifts the burden of what metrics to collect onto the | 119 A timeline measurement shifts the burden of what metrics to collect onto the |
119 page under test, or the pageset running that page. Instead of the measurement | 120 page under test, or the pageset running that page. Instead of the measurement |
120 having a fixed set of values it collects about the page, the page being tested | 121 having a fixed set of values it collects about the page, the page being tested |
121 issues (via javascript) an Interaction record into the user timing API that | 122 issues (via javascript) an Interaction record into the user timing API that |
122 describing what the page is doing at that time, as well as a standardized set | 123 describing what the page is doing at that time, as well as a standardized set |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 os.path.join(trace_dir, 'trace')) + '.json' | 174 os.path.join(trace_dir, 'trace')) + '.json' |
174 try: | 175 try: |
175 with open(trace_file_path, 'w') as f: | 176 with open(trace_file_path, 'w') as f: |
176 trace_result.Serialize(f) | 177 trace_result.Serialize(f) |
177 results.AddValue(string_value_module.StringValue( | 178 results.AddValue(string_value_module.StringValue( |
178 page, 'trace_path', 'string', trace_file_path)) | 179 page, 'trace_path', 'string', trace_file_path)) |
179 except IOError, e: | 180 except IOError, e: |
180 logging.error('Cannot open %s. %s' % (trace_file_path, e)) | 181 logging.error('Cannot open %s. %s' % (trace_file_path, e)) |
181 | 182 |
182 model = model_module.TimelineModel(trace_result) | 183 model = model_module.TimelineModel(trace_result) |
183 renderer_thread = model.GetRendererThreadFromTabId(tab.id) | 184 meta_metrics = _TimelineBasedMetrics(model, _GetMetricFromMetricType) |
184 meta_metrics = _TimelineBasedMetrics( | |
185 model, renderer_thread, _GetMetricFromMetricType) | |
186 meta_metrics.AddResults(results) | 185 meta_metrics.AddResults(results) |
187 | 186 |
188 def CleanUpAfterPage(self, page, tab): | 187 def CleanUpAfterPage(self, page, tab): |
189 if tab.browser.is_tracing_running: | 188 if tab.browser.is_tracing_running: |
190 tab.browser.StopTracing() | 189 tab.browser.StopTracing() |
OLD | NEW |