| 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 metrics import timeline as timeline_module | 5 from metrics import timeline as timeline_module |
| 6 from metrics import timeline_interaction_record as tir_module | 6 from metrics import timeline_interaction_record as tir_module |
| 7 from metrics import smoothness |
| 7 from telemetry.page import page_measurement | 8 from telemetry.page import page_measurement |
| 8 from telemetry.core.timeline import model as model_module | 9 from telemetry.core.timeline import model as model_module |
| 9 | 10 |
| 10 | 11 |
| 11 | |
| 12 # TimelineBasedMeasurement considers all instrumentation as producing a single | 12 # TimelineBasedMeasurement considers all instrumentation as producing a single |
| 13 # timeline. But, depending on the amount of instrumentation that is enabled, | 13 # timeline. But, depending on the amount of instrumentation that is enabled, |
| 14 # overhead increases. The user of the measurement must therefore chose between | 14 # overhead increases. The user of the measurement must therefore chose between |
| 15 # a few levels of instrumentation. | 15 # a few levels of instrumentation. |
| 16 NO_OVERHEAD_LEVEL = 'no-overhead' | 16 NO_OVERHEAD_LEVEL = 'no-overhead' |
| 17 MINIMAL_OVERHEAD_LEVEL = 'minimal-overhead' | 17 MINIMAL_OVERHEAD_LEVEL = 'minimal-overhead' |
| 18 DEBUG_OVERHEAD_LEVEL = 'debug-overhead' | 18 DEBUG_OVERHEAD_LEVEL = 'debug-overhead' |
| 19 | 19 |
| 20 ALL_OVERHEAD_LEVELS = [ | 20 ALL_OVERHEAD_LEVELS = [ |
| 21 NO_OVERHEAD_LEVEL, | 21 NO_OVERHEAD_LEVEL, |
| 22 MINIMAL_OVERHEAD_LEVEL, | 22 MINIMAL_OVERHEAD_LEVEL, |
| 23 DEBUG_OVERHEAD_LEVEL | 23 DEBUG_OVERHEAD_LEVEL |
| 24 ] | 24 ] |
| 25 | 25 |
| 26 | 26 |
| 27 class _ResultsWrapper(object): |
| 28 def __init__(self, results, interaction_record): |
| 29 self._results = results |
| 30 self._interaction_record = interaction_record |
| 31 |
| 32 def Add(self, trace_name, units, value, chart_name=None, data_type='default'): |
| 33 trace_name = self._interaction_record.GetResultNameFor(trace_name) |
| 34 self._results.Add(trace_name, units, value, chart_name, data_type) |
| 35 |
| 36 def AddSummary(self, trace_name, units, value, chart_name=None, |
| 37 data_type='default'): |
| 38 trace_name = self._interaction_record.GetResultNameFor(trace_name) |
| 39 self._results.AddSummary(trace_name, units, value, chart_name, data_type) |
| 40 |
| 41 |
| 27 class _TimelineBasedMetrics(object): | 42 class _TimelineBasedMetrics(object): |
| 28 def __init__(self, model, renderer_thread): | 43 def __init__(self, model, renderer_thread): |
| 29 self._model = model | 44 self._model = model |
| 30 self._renderer_thread = renderer_thread | 45 self._renderer_thread = renderer_thread |
| 31 | 46 |
| 32 def FindTimelineInteractionRecords(self): | 47 def FindTimelineInteractionRecords(self): |
| 33 # TODO(nduca): Add support for page-load interaction record. | 48 # TODO(nduca): Add support for page-load interaction record. |
| 34 return [tir_module.TimelineInteractionRecord(event) for | 49 return [tir_module.TimelineInteractionRecord.FromEvent(event) for |
| 35 event in self._renderer_thread.IterAllAsyncSlices() | 50 event in self._renderer_thread.IterAllAsyncSlices() |
| 36 if tir_module.IsTimelineInteractionRecord(event.name)] | 51 if tir_module.IsTimelineInteractionRecord(event.name)] |
| 37 | 52 |
| 38 def CreateMetricsForTimelineInteractionRecord(self, interaction): | 53 def CreateMetricsForTimelineInteractionRecord(self, interaction): |
| 39 res = [] | 54 res = [] |
| 40 if interaction.is_smooth: | 55 if interaction.is_smooth: |
| 41 pass # TODO(nduca): res.append smoothness metric instance. | 56 res.append(smoothness.SmoothnessMetric()) |
| 42 return res | 57 return res |
| 43 | 58 |
| 44 def AddResults(self, results): | 59 def AddResults(self, results): |
| 45 interactions = self.FindTimelineInteractionRecords() | 60 interactions = self.FindTimelineInteractionRecords() |
| 46 if len(interactions) == 0: | 61 if len(interactions) == 0: |
| 47 raise Exception('Expected at least one Interaction on the page') | 62 raise Exception('Expected at least one Interaction on the page') |
| 48 for interaction in interactions: | 63 for interaction in interactions: |
| 49 metrics = self.CreateMetricsForTimelineInteractionRecord(interaction) | 64 metrics = self.CreateMetricsForTimelineInteractionRecord(interaction) |
| 65 wrapped_results = _ResultsWrapper(results, interaction) |
| 50 for m in metrics: | 66 for m in metrics: |
| 51 m.AddResults(self._model, self._renderer_thread, | 67 m.AddResults(self._model, self._renderer_thread, |
| 52 interaction, results) | 68 interaction, wrapped_results) |
| 53 | 69 |
| 54 | 70 |
| 55 class TimelineBasedMeasurement(page_measurement.PageMeasurement): | 71 class TimelineBasedMeasurement(page_measurement.PageMeasurement): |
| 56 """Collects multiple metrics pages based on their interaction records. | 72 """Collects multiple metrics pages based on their interaction records. |
| 57 | 73 |
| 58 A timeline measurement shifts the burden of what metrics to collect onto the | 74 A timeline measurement shifts the burden of what metrics to collect onto the |
| 59 page under test, or the pageset running that page. Instead of the measurement | 75 page under test, or the pageset running that page. Instead of the measurement |
| 60 having a fixed set of values it collects about the page, the page being tested | 76 having a fixed set of values it collects about the page, the page being tested |
| 61 issues (via javascript) an Interaction record into the user timing API that | 77 issues (via javascript) an Interaction record into the user timing API that |
| 62 describing what the page is doing at that time, as well as a standardized set | 78 describing what the page is doing at that time, as well as a standardized set |
| (...skipping 29 matching lines...) Expand all Loading... |
| 92 if not tab.browser.supports_tracing: | 108 if not tab.browser.supports_tracing: |
| 93 raise Exception('Not supported') | 109 raise Exception('Not supported') |
| 94 assert self.options.overhead_level in ALL_OVERHEAD_LEVELS | 110 assert self.options.overhead_level in ALL_OVERHEAD_LEVELS |
| 95 if self.options.overhead_level == NO_OVERHEAD_LEVEL: | 111 if self.options.overhead_level == NO_OVERHEAD_LEVEL: |
| 96 categories = timeline_module.MINIMAL_TRACE_CATEGORIES | 112 categories = timeline_module.MINIMAL_TRACE_CATEGORIES |
| 97 elif self.options.overhead_level == \ | 113 elif self.options.overhead_level == \ |
| 98 MINIMAL_OVERHEAD_LEVEL: | 114 MINIMAL_OVERHEAD_LEVEL: |
| 99 categories = '' | 115 categories = '' |
| 100 else: | 116 else: |
| 101 categories = '*,disabled-by-default-cc.debug' | 117 categories = '*,disabled-by-default-cc.debug' |
| 118 categories = ','.join([categories] + page.GetSyntheticDelayCategories()) |
| 102 tab.browser.StartTracing(categories) | 119 tab.browser.StartTracing(categories) |
| 103 | 120 |
| 104 def MeasurePage(self, page, tab, results): | 121 def MeasurePage(self, page, tab, results): |
| 105 """ Collect all possible metrics and added them to results. """ | 122 """ Collect all possible metrics and added them to results. """ |
| 106 trace_result = tab.browser.StopTracing() | 123 trace_result = tab.browser.StopTracing() |
| 107 model = model_module.TimelineModel(trace_result) | 124 model = model_module.TimelineModel(trace_result) |
| 108 renderer_thread = model.GetRendererThreadFromTab(tab) | 125 renderer_thread = model.GetRendererThreadFromTab(tab) |
| 109 meta_metrics = _TimelineBasedMetrics(model, renderer_thread) | 126 meta_metrics = _TimelineBasedMetrics(model, renderer_thread) |
| 110 meta_metrics.AddResults(results) | 127 meta_metrics.AddResults(results) |
| OLD | NEW |