Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(211)

Unified Diff: tools/telemetry/telemetry/web_perf/timeline_based_measurement.py

Issue 367523002: Handle multiple duplicate timeline interaction records. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: update unittests Created 6 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: tools/telemetry/telemetry/web_perf/timeline_based_measurement.py
diff --git a/tools/telemetry/telemetry/web_perf/timeline_based_measurement.py b/tools/telemetry/telemetry/web_perf/timeline_based_measurement.py
index 631ada3dba76d6a71e93b0f82f95c7ce45d8d113..e7cd2b9da5dfdb4c118111fdf85a2505c1f34398 100644
--- a/tools/telemetry/telemetry/web_perf/timeline_based_measurement.py
+++ b/tools/telemetry/telemetry/web_perf/timeline_based_measurement.py
@@ -5,12 +5,13 @@
import logging
import os
+from collections import defaultdict
from telemetry.core import util
from telemetry.core.backends.chrome import tracing_backend
from telemetry.timeline import model as model_module
from telemetry.web_perf import timeline_interaction_record as tir_module
-from telemetry.web_perf.metrics import smoothness
from telemetry.web_perf.metrics import responsiveness_metric
+from telemetry.web_perf.metrics import smoothness
from telemetry.page import page_measurement
from telemetry.value import string as string_value_module
@@ -30,28 +31,43 @@ ALL_OVERHEAD_LEVELS = [
]
+class InvalidInteractions(Exception):
+ pass
+
+
+def _GetMetricFromMetricType(metric_type):
+ if metric_type == tir_module.IS_SMOOTH:
+ return smoothness.SmoothnessMetric()
+ if metric_type == tir_module.IS_RESPONSIVE:
+ return responsiveness_metric.ResponsivenessMetric()
+ raise Exception('Unrecognized metric type: %s' % metric_type)
+
+
class _ResultsWrapper(object):
- def __init__(self, results, interaction_record):
+ def __init__(self, results, logical_name):
self._results = results
- self._interaction_record = interaction_record
+ self._result_prefix = logical_name
+
+ def _GetResultName(self, trace_name):
+ return '%s-%s' % (self._result_prefix, trace_name)
def Add(self, trace_name, units, value, chart_name=None, data_type='default'):
- trace_name = self._interaction_record.GetResultNameFor(trace_name)
- self._results.Add(trace_name, units, value, chart_name, data_type)
+ result_name = self._GetResultName(trace_name)
+ self._results.Add(result_name, units, value, chart_name, data_type)
def AddSummary(self, trace_name, units, value, chart_name=None,
- data_type='default'):
- trace_name = self._interaction_record.GetResultNameFor(trace_name)
- self._results.AddSummary(trace_name, units, value, chart_name, data_type)
+ data_type='default'):
+ result_name = self._GetResultName(trace_name)
+ self._results.AddSummary(result_name, units, value, chart_name, data_type)
class _TimelineBasedMetrics(object):
def __init__(self, model, renderer_thread,
- create_metrics_for_interaction_record_callback):
+ get_metric_from_metric_type_callback):
self._model = model
self._renderer_thread = renderer_thread
- self._create_metrics_for_interaction_record_callback = \
- create_metrics_for_interaction_record_callback
+ self._get_metric_from_metric_type_callback = \
+ get_metric_from_metric_type_callback
def FindTimelineInteractionRecords(self):
# TODO(nduca): Add support for page-load interaction record.
@@ -60,16 +76,37 @@ class _TimelineBasedMetrics(object):
if tir_module.IsTimelineInteractionRecord(event.name)]
def AddResults(self, results):
- interactions = self.FindTimelineInteractionRecords()
- if len(interactions) == 0:
- raise Exception('Expected at least one Interaction on the page')
- for interaction in interactions:
- metrics = \
- self._create_metrics_for_interaction_record_callback(interaction)
- wrapped_results = _ResultsWrapper(results, interaction)
- for m in metrics:
- m.AddResults(self._model, self._renderer_thread,
- [interaction], wrapped_results)
+ all_interactions = self.FindTimelineInteractionRecords()
+ if len(all_interactions) == 0:
+ raise InvalidInteractions('Expected at least one interaction record on '
+ 'the page')
+
+ interactions_by_logical_name = defaultdict(list)
+ for i in all_interactions:
+ interactions_by_logical_name[i.logical_name].append(i)
+
+ for logical_name, interactions in interactions_by_logical_name.iteritems():
+ are_repeatable = [i.repeatable for i in interactions]
+ if not all(are_repeatable) and len(interactions) > 1:
+ raise InvalidInteractions('Duplicate unrepeatable interaction records '
+ 'on the page')
+ wrapped_results = _ResultsWrapper(results, logical_name)
+ self.UpdateResultsByMetric(interactions, wrapped_results)
+
+ def UpdateResultsByMetric(self, interactions, wrapped_results):
+ for metric_type in tir_module.METRICS:
+ # For each metric type, either all or none of the interactions should
+ # have that metric.
+ interactions_with_metric = [i for i in interactions if
+ i.HasMetric(metric_type)]
+ if not interactions_with_metric:
+ continue
+ if len(interactions_with_metric) != len(interactions):
+ raise InvalidInteractions('Interaction records with the same logical '
+ 'name must have the same flags.')
+ metric = self._get_metric_from_metric_type_callback(metric_type)
+ metric.AddResults(self._model, self._renderer_thread,
+ interactions, wrapped_results)
class TimelineBasedMeasurement(page_measurement.PageMeasurement):
@@ -124,17 +161,6 @@ class TimelineBasedMeasurement(page_measurement.PageMeasurement):
categories = ','.join([categories] + page.GetSyntheticDelayCategories())
tab.browser.StartTracing(categories)
- def CreateMetricsForTimelineInteractionRecord(self, interaction):
- """ Subclass of TimelineBasedMeasurement overrides this method to customize
- the binding of interaction's flags to metrics.
- """
- res = []
- if interaction.is_smooth:
- res.append(smoothness.SmoothnessMetric())
- if interaction.is_responsive:
- res.append(responsiveness_metric.ResponsivenessMetric())
- return res
-
def MeasurePage(self, page, tab, results):
""" Collect all possible metrics and added them to results. """
trace_result = tab.browser.StopTracing()
@@ -153,7 +179,7 @@ class TimelineBasedMeasurement(page_measurement.PageMeasurement):
model = model_module.TimelineModel(trace_result)
renderer_thread = model.GetRendererThreadFromTabId(tab.id)
meta_metrics = _TimelineBasedMetrics(
- model, renderer_thread, self.CreateMetricsForTimelineInteractionRecord)
+ model, renderer_thread, _GetMetricFromMetricType)
meta_metrics.AddResults(results)
def CleanUpAfterPage(self, page, tab):

Powered by Google App Engine
This is Rietveld 408576698