Commit 1a94beaf authored by chrishenry@google.com's avatar chrishenry@google.com

Cleanup while reading code: Move GetJavaScriptMarker to be a free function...

Cleanup while reading code: Move GetJavaScriptMarker to be a free function instead of static function.

Rename logical_name -> label (matching ActionRunner API).

Improve documentation.

BUG=

Review URL: https://codereview.chromium.org/386023004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@282807 0039d316-1c4b-4281-b951-d872f2087c98
parent ddef62e7
...@@ -18,7 +18,7 @@ def GetAdjustedInteractionIfContainGesture(timeline, interaction_record): ...@@ -18,7 +18,7 @@ def GetAdjustedInteractionIfContainGesture(timeline, interaction_record):
markers. markers.
""" """
# Only adjust the range for gestures. # Only adjust the range for gestures.
if not interaction_record.logical_name.startswith('Gesture_'): if not interaction_record.label.startswith('Gesture_'):
return copy.copy(interaction_record) return copy.copy(interaction_record)
gesture_events = [ gesture_events = [
ev for ev ev for ev
...@@ -30,7 +30,7 @@ def GetAdjustedInteractionIfContainGesture(timeline, interaction_record): ...@@ -30,7 +30,7 @@ def GetAdjustedInteractionIfContainGesture(timeline, interaction_record):
return copy.copy(interaction_record) return copy.copy(interaction_record)
if len(gesture_events) > 1: if len(gesture_events) > 1:
raise Exception('More than one possible synthetic gesture marker found in ' raise Exception('More than one possible synthetic gesture marker found in '
'interaction_record %s.' % interaction_record.logical_name) 'interaction_record %s.' % interaction_record.label)
return tir_module.TimelineInteractionRecord(interaction_record.logical_name, return tir_module.TimelineInteractionRecord(interaction_record.label,
gesture_events[0].start, gesture_events[0].start,
gesture_events[0].end) gesture_events[0].end)
...@@ -63,7 +63,7 @@ class SmoothnessController(object): ...@@ -63,7 +63,7 @@ class SmoothnessController(object):
if not tir_module.IsTimelineInteractionRecord(event.name): if not tir_module.IsTimelineInteractionRecord(event.name):
continue continue
r = tir_module.TimelineInteractionRecord.FromAsyncEvent(event) r = tir_module.TimelineInteractionRecord.FromAsyncEvent(event)
if r.logical_name == RUN_SMOOTH_ACTIONS: if r.label == RUN_SMOOTH_ACTIONS:
assert run_smooth_actions_record is None, ( assert run_smooth_actions_record is None, (
'SmoothnessController cannot issue more than 1 %s record' % 'SmoothnessController cannot issue more than 1 %s record' %
RUN_SMOOTH_ACTIONS) RUN_SMOOTH_ACTIONS)
...@@ -88,7 +88,7 @@ class SmoothnessController(object): ...@@ -88,7 +88,7 @@ class SmoothnessController(object):
smooth_records = [run_smooth_actions_record] smooth_records = [run_smooth_actions_record]
# Create an interaction_record for this legacy measurement. Since we don't # Create an interaction_record for this legacy measurement. Since we don't
# wrap the results that is sent to smoothnes metric, the logical_name will # wrap the results that is sent to smoothnes metric, the label will
# not be used. # not be used.
smoothness_metric = smoothness.SmoothnessMetric() smoothness_metric = smoothness.SmoothnessMetric()
smoothness_metric.AddResults( smoothness_metric.AddResults(
......
...@@ -56,7 +56,7 @@ class TimelineController(object): ...@@ -56,7 +56,7 @@ class TimelineController(object):
if not tir_module.IsTimelineInteractionRecord(event.name): if not tir_module.IsTimelineInteractionRecord(event.name):
continue continue
r = tir_module.TimelineInteractionRecord.FromAsyncEvent(event) r = tir_module.TimelineInteractionRecord.FromAsyncEvent(event)
if r.logical_name == RUN_SMOOTH_ACTIONS: if r.label == RUN_SMOOTH_ACTIONS:
assert run_smooth_actions_record is None, ( assert run_smooth_actions_record is None, (
'TimelineController cannot issue more than 1 %s record' % 'TimelineController cannot issue more than 1 %s record' %
RUN_SMOOTH_ACTIONS) RUN_SMOOTH_ACTIONS)
......
...@@ -17,7 +17,7 @@ from telemetry.page.actions.seek import SeekAction ...@@ -17,7 +17,7 @@ from telemetry.page.actions.seek import SeekAction
from telemetry.page.actions.swipe import SwipeAction from telemetry.page.actions.swipe import SwipeAction
from telemetry.page.actions.tap import TapAction from telemetry.page.actions.tap import TapAction
from telemetry.page.actions.wait import WaitForElementAction from telemetry.page.actions.wait import WaitForElementAction
from telemetry.web_perf import timeline_interaction_record as tir_module from telemetry.web_perf import timeline_interaction_record
class ActionRunner(object): class ActionRunner(object):
...@@ -51,11 +51,11 @@ class ActionRunner(object): ...@@ -51,11 +51,11 @@ class ActionRunner(object):
""" """
flags = [] flags = []
if is_smooth: if is_smooth:
flags.append(tir_module.IS_SMOOTH) flags.append(timeline_interaction_record.IS_SMOOTH)
if is_responsive: if is_responsive:
flags.append(tir_module.IS_RESPONSIVE) flags.append(timeline_interaction_record.IS_RESPONSIVE)
if repeatable: if repeatable:
flags.append(tir_module.REPEATABLE) flags.append(timeline_interaction_record.REPEATABLE)
interaction = Interaction(self._tab, label, flags) interaction = Interaction(self._tab, label, flags)
interaction.Begin() interaction.Begin()
...@@ -572,12 +572,12 @@ class Interaction(object): ...@@ -572,12 +572,12 @@ class Interaction(object):
assert not self._started assert not self._started
self._started = True self._started = True
self._action_runner.ExecuteJavaScript('console.time("%s");' % self._action_runner.ExecuteJavaScript('console.time("%s");' %
tir_module.TimelineInteractionRecord.GetJavaScriptMarker( timeline_interaction_record.GetJavaScriptMarker(
self._label, self._flags)) self._label, self._flags))
def End(self): def End(self):
assert self._started assert self._started
self._started = False self._started = False
self._action_runner.ExecuteJavaScript('console.timeEnd("%s");' % self._action_runner.ExecuteJavaScript('console.timeEnd("%s");' %
tir_module.TimelineInteractionRecord.GetJavaScriptMarker( timeline_interaction_record.GetJavaScriptMarker(
self._label, self._flags)) self._label, self._flags))
...@@ -34,7 +34,7 @@ class ActionRunnerTest(tab_test_case.TabTestCase): ...@@ -34,7 +34,7 @@ class ActionRunnerTest(tab_test_case.TabTestCase):
self.assertEqual(1, len(records), self.assertEqual(1, len(records),
'Fail to issue the interaction record on tracing timeline.' 'Fail to issue the interaction record on tracing timeline.'
' Trace data:\n%s' % repr(trace_data.EventData())) ' Trace data:\n%s' % repr(trace_data.EventData()))
self.assertEqual('TestInteraction', records[0].logical_name) self.assertEqual('TestInteraction', records[0].label)
self.assertTrue(records[0].is_smooth) self.assertTrue(records[0].is_smooth)
def testExecuteJavaScript(self): def testExecuteJavaScript(self):
......
...@@ -44,9 +44,9 @@ def _GetMetricFromMetricType(metric_type): ...@@ -44,9 +44,9 @@ def _GetMetricFromMetricType(metric_type):
class _ResultsWrapper(object): class _ResultsWrapper(object):
def __init__(self, results, logical_name): def __init__(self, results, label):
self._results = results self._results = results
self._result_prefix = logical_name self._result_prefix = label
def _GetResultName(self, trace_name): def _GetResultName(self, trace_name):
return '%s-%s' % (self._result_prefix, trace_name) return '%s-%s' % (self._result_prefix, trace_name)
...@@ -81,16 +81,16 @@ class _TimelineBasedMetrics(object): ...@@ -81,16 +81,16 @@ class _TimelineBasedMetrics(object):
raise InvalidInteractions('Expected at least one interaction record on ' raise InvalidInteractions('Expected at least one interaction record on '
'the page') 'the page')
interactions_by_logical_name = defaultdict(list) interactions_by_label = defaultdict(list)
for i in all_interactions: for i in all_interactions:
interactions_by_logical_name[i.logical_name].append(i) interactions_by_label[i.label].append(i)
for logical_name, interactions in interactions_by_logical_name.iteritems(): for label, interactions in interactions_by_label.iteritems():
are_repeatable = [i.repeatable for i in interactions] are_repeatable = [i.repeatable for i in interactions]
if not all(are_repeatable) and len(interactions) > 1: if not all(are_repeatable) and len(interactions) > 1:
raise InvalidInteractions('Duplicate unrepeatable interaction records ' raise InvalidInteractions('Duplicate unrepeatable interaction records '
'on the page') 'on the page')
wrapped_results = _ResultsWrapper(results, logical_name) wrapped_results = _ResultsWrapper(results, label)
self.UpdateResultsByMetric(interactions, wrapped_results) self.UpdateResultsByMetric(interactions, wrapped_results)
def UpdateResultsByMetric(self, interactions, wrapped_results): def UpdateResultsByMetric(self, interactions, wrapped_results):
......
...@@ -39,7 +39,27 @@ def _AssertFlagsAreValid(flags): ...@@ -39,7 +39,27 @@ def _AssertFlagsAreValid(flags):
for f in flags: for f in flags:
if f not in FLAGS: if f not in FLAGS:
raise AssertionError( raise AssertionError(
'Unrecognized flag for a timeline Interaction record: %s' % f) 'Unrecognized flag for a timeline interaction record: %s' % f)
def GetJavaScriptMarker(label, flags):
"""Computes the marker string of an interaction record.
This marker string can be used with JavaScript API console.time()
and console.timeEnd() to mark the beginning and end of the
interaction record..
Args:
label: The label used to identify the interaction record.
flags: the flags for the interaction record see FLAGS above.
Returns:
The interaction record marker string (e.g., Interaction.Label/flag1,flag2).
Raises:
AssertionError: If one or more of the flags is unrecognized.
"""
_AssertFlagsAreValid(flags)
return 'Interaction.%s/%s' % (label, ','.join(flags))
class TimelineInteractionRecord(object): class TimelineInteractionRecord(object):
"""Represents an interaction that took place during a timeline recording. """Represents an interaction that took place during a timeline recording.
...@@ -51,8 +71,8 @@ class TimelineInteractionRecord(object): ...@@ -51,8 +71,8 @@ class TimelineInteractionRecord(object):
interactions. interactions.
From the point of view of the page, each interaction might have a different From the point of view of the page, each interaction might have a different
logical name: ClickComposeButton and SendEmail, for instance. From the point label: ClickComposeButton and SendEmail, for instance. From the point
of view of the benchmarking harness, the names aren't so interesting as what of view of the benchmarking harness, the labels aren't so interesting as what
the performance expectations are for that interaction: was it loading the performance expectations are for that interaction: was it loading
resources from the network? was there an animation? resources from the network? was there an animation?
...@@ -62,7 +82,7 @@ class TimelineInteractionRecord(object): ...@@ -62,7 +82,7 @@ class TimelineInteractionRecord(object):
story. story.
Instead, we expect pages to mark up the timeline what they are doing, with Instead, we expect pages to mark up the timeline what they are doing, with
logical names, and flags indicating the semantics of that interaction. This label and flags indicating the semantics of that interaction. This
is currently done by pushing markers into the console.time/timeEnd API: this is currently done by pushing markers into the console.time/timeEnd API: this
for instance can be issued in JS: for instance can be issued in JS:
...@@ -83,9 +103,9 @@ class TimelineInteractionRecord(object): ...@@ -83,9 +103,9 @@ class TimelineInteractionRecord(object):
* repeatable: Allows other interactions to use the same logical name * repeatable: Allows other interactions to use the same logical name
""" """
def __init__(self, logical_name, start, end, async_event=None): def __init__(self, label, start, end, async_event=None):
assert logical_name assert label
self.logical_name = logical_name self.label = label
self.start = start self.start = start
self.end = end self.end = end
self.is_smooth = False self.is_smooth = False
...@@ -108,7 +128,7 @@ class TimelineInteractionRecord(object): ...@@ -108,7 +128,7 @@ class TimelineInteractionRecord(object):
'end thread') 'end thread')
m = re.match('Interaction\.(.+)\/(.+)', async_event.name) m = re.match('Interaction\.(.+)\/(.+)', async_event.name)
if m: if m:
logical_name = m.group(1) label = m.group(1)
if m.group(1) != '': if m.group(1) != '':
flags = m.group(2).split(',') flags = m.group(2).split(',')
else: else:
...@@ -116,10 +136,10 @@ class TimelineInteractionRecord(object): ...@@ -116,10 +136,10 @@ class TimelineInteractionRecord(object):
else: else:
m = re.match('Interaction\.(.+)', async_event.name) m = re.match('Interaction\.(.+)', async_event.name)
assert m assert m
logical_name = m.group(1) label = m.group(1)
flags = [] flags = []
record = TimelineInteractionRecord(logical_name, async_event.start, record = TimelineInteractionRecord(label, async_event.start,
async_event.end, async_event) async_event.end, async_event)
_AssertFlagsAreValid(flags) _AssertFlagsAreValid(flags)
record.is_smooth = IS_SMOOTH in flags record.is_smooth = IS_SMOOTH in flags
...@@ -134,14 +154,6 @@ class TimelineInteractionRecord(object): ...@@ -134,14 +154,6 @@ class TimelineInteractionRecord(object):
bounds.AddValue(self.end) bounds.AddValue(self.end)
return bounds return bounds
@staticmethod
def GetJavaScriptMarker(logical_name, flags):
""" Get the marker string of an interaction record with logical_name
and flags.
"""
_AssertFlagsAreValid(flags)
return 'Interaction.%s/%s' % (logical_name, ','.join(flags))
def HasMetric(self, metric_type): def HasMetric(self, metric_type):
if metric_type not in METRICS: if metric_type not in METRICS:
raise AssertionError('Unrecognized metric type for a timeline ' raise AssertionError('Unrecognized metric type for a timeline '
...@@ -234,9 +246,9 @@ class TimelineInteractionRecord(object): ...@@ -234,9 +246,9 @@ class TimelineInteractionRecord(object):
flags.append(IS_RESPONSIVE) flags.append(IS_RESPONSIVE)
flags_str = ','.join(flags) flags_str = ','.join(flags)
return ('TimelineInteractionRecord(logical_name=\'%s\', start=%f, end=%f,' + return ('TimelineInteractionRecord(label=\'%s\', start=%f, end=%f,' +
' flags=%s, async_event=%s)') % ( ' flags=%s, async_event=%s)') % (
self.logical_name, self.label,
self.start, self.start,
self.end, self.end,
flags_str, flags_str,
......
...@@ -38,35 +38,34 @@ class TimelineInteractionRecordTests(unittest.TestCase): ...@@ -38,35 +38,34 @@ class TimelineInteractionRecordTests(unittest.TestCase):
def testCreate(self): def testCreate(self):
r = self.CreateSimpleRecordWithName('Interaction.LogicalName') r = self.CreateSimpleRecordWithName('Interaction.LogicalName')
self.assertEquals('LogicalName', r.logical_name) self.assertEquals('LogicalName', r.label)
self.assertEquals(False, r.is_smooth) self.assertEquals(False, r.is_smooth)
self.assertEquals(False, r.is_responsive) self.assertEquals(False, r.is_responsive)
r = self.CreateSimpleRecordWithName('Interaction.LogicalName/is_smooth') r = self.CreateSimpleRecordWithName('Interaction.LogicalName/is_smooth')
self.assertEquals('LogicalName', r.logical_name) self.assertEquals('LogicalName', r.label)
self.assertEquals(True, r.is_smooth) self.assertEquals(True, r.is_smooth)
self.assertEquals(False, r.is_responsive) self.assertEquals(False, r.is_responsive)
r = self.CreateSimpleRecordWithName( r = self.CreateSimpleRecordWithName(
'Interaction.LogicalNameWith/Slash/is_smooth') 'Interaction.LogicalNameWith/Slash/is_smooth')
self.assertEquals('LogicalNameWith/Slash', r.logical_name) self.assertEquals('LogicalNameWith/Slash', r.label)
self.assertEquals(True, r.is_smooth) self.assertEquals(True, r.is_smooth)
self.assertEquals(False, r.is_responsive) self.assertEquals(False, r.is_responsive)
r = self.CreateSimpleRecordWithName( r = self.CreateSimpleRecordWithName(
'Interaction.LogicalNameWith/Slash/is_smooth,is_responsive') 'Interaction.LogicalNameWith/Slash/is_smooth,is_responsive')
self.assertEquals('LogicalNameWith/Slash', r.logical_name) self.assertEquals('LogicalNameWith/Slash', r.label)
self.assertEquals(True, r.is_smooth) self.assertEquals(True, r.is_smooth)
self.assertEquals(True, r.is_responsive) self.assertEquals(True, r.is_responsive)
def testGetJavaScriptMarker(self): def testGetJavaScriptMarker(self):
smooth_marker = tir_module.TimelineInteractionRecord.GetJavaScriptMarker( smooth_marker = tir_module.GetJavaScriptMarker(
'LogicalName', [tir_module.IS_SMOOTH]) 'MyLabel', [tir_module.IS_SMOOTH])
self.assertEquals('Interaction.LogicalName/is_smooth', smooth_marker) self.assertEquals('Interaction.MyLabel/is_smooth', smooth_marker)
slr_marker = tir_module.TimelineInteractionRecord.GetJavaScriptMarker( slr_marker = tir_module.GetJavaScriptMarker(
'LogicalName', [tir_module.IS_SMOOTH, tir_module.IS_RESPONSIVE]) 'MyLabel', [tir_module.IS_SMOOTH, tir_module.IS_RESPONSIVE])
self.assertEquals('Interaction.LogicalName/is_smooth,is_responsive', self.assertEquals('Interaction.MyLabel/is_smooth,is_responsive', slr_marker)
slr_marker)
def testGetOverlappedThreadTimeForSliceInSameThread(self): def testGetOverlappedThreadTimeForSliceInSameThread(self):
# Create a renderer thread. # Create a renderer thread.
...@@ -113,7 +112,7 @@ class TimelineInteractionRecordTests(unittest.TestCase): ...@@ -113,7 +112,7 @@ class TimelineInteractionRecordTests(unittest.TestCase):
end_thread=renderer_main, thread_start=30, thread_duration=30) end_thread=renderer_main, thread_start=30, thread_duration=30)
record = tir_module.TimelineInteractionRecord.FromAsyncEvent(s) record = tir_module.TimelineInteractionRecord.FromAsyncEvent(s)
expected_repr = ( expected_repr = (
'TimelineInteractionRecord(logical_name=\'Test\', ' 'TimelineInteractionRecord(label=\'Test\', '
'start=0.000000, end=200.000000, flags=is_smooth, ' 'start=0.000000, end=200.000000, flags=is_smooth, '
'async_event=TimelineEvent(name=\'Interaction.Test/is_smooth\',' 'async_event=TimelineEvent(name=\'Interaction.Test/is_smooth\','
' start=0.000000, duration=200, thread_start=30, thread_duration=30))') ' start=0.000000, duration=200, thread_start=30, thread_duration=30))')
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment