| 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 |