aboutsummaryrefslogtreecommitdiff
path: root/catapult/telemetry/telemetry/web_perf/metrics/rendering_frame_unittest.py
diff options
context:
space:
mode:
Diffstat (limited to 'catapult/telemetry/telemetry/web_perf/metrics/rendering_frame_unittest.py')
-rw-r--r--catapult/telemetry/telemetry/web_perf/metrics/rendering_frame_unittest.py163
1 files changed, 163 insertions, 0 deletions
diff --git a/catapult/telemetry/telemetry/web_perf/metrics/rendering_frame_unittest.py b/catapult/telemetry/telemetry/web_perf/metrics/rendering_frame_unittest.py
new file mode 100644
index 00000000..95f6d93b
--- /dev/null
+++ b/catapult/telemetry/telemetry/web_perf/metrics/rendering_frame_unittest.py
@@ -0,0 +1,163 @@
+# Copyright 2014 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import unittest
+
+import telemetry.timeline.bounds as timeline_bounds
+from telemetry.timeline import model
+import telemetry.timeline.slice as tracing_slice
+from telemetry.web_perf.metrics. \
+ rendering_frame import GetFrameEventsInsideRange
+from telemetry.web_perf.metrics.rendering_frame import MissingData
+from telemetry.web_perf.metrics.rendering_frame import RenderingFrame
+
+
+class RenderingFrameTestData(object):
+
+ def __init__(self):
+ self._begin_frame_id = 0
+ self._events = []
+ self._renderer_process = model.TimelineModel().GetOrCreateProcess(pid=1)
+ self._main_thread = self._renderer_process.GetOrCreateThread(tid=11)
+ self._compositor_thread = self._renderer_process.GetOrCreateThread(tid=12)
+
+ @property
+ def events(self):
+ return self._events
+
+ @property
+ def renderer_process(self):
+ return self._renderer_process
+
+ def AddSendEvent(self, ts=0, duration=1):
+ self._begin_frame_id += 1
+ event = self._CreateEvent(
+ RenderingFrame.send_begin_frame_event, ts, duration)
+ self._compositor_thread.PushSlice(event)
+
+ def AddBeginMainFrameEvent(self, ts=0, duration=1):
+ event = self._CreateEvent(
+ RenderingFrame.begin_main_frame_event, ts, duration)
+ self._main_thread.PushSlice(event)
+
+ def FinalizeImport(self):
+ self._renderer_process.FinalizeImport()
+
+ def _CreateEvent(self, event_name, ts, duration):
+ event = tracing_slice.Slice(None, 'cc,benchmark', event_name, ts,
+ duration=duration, args={'begin_frame_id': self._begin_frame_id})
+ self._events.append(event)
+ return event
+
+
+def GenerateTimelineRange(start=0, end=100):
+ timeline_range = timeline_bounds.Bounds()
+ timeline_range.AddValue(start)
+ timeline_range.AddValue(end)
+ return timeline_range
+
+
+class RenderingFrameUnitTest(unittest.TestCase):
+
+ def testRenderingFrame(self):
+ d = RenderingFrameTestData()
+ d.AddSendEvent(ts=10)
+ d.AddBeginMainFrameEvent(ts=20)
+ d.FinalizeImport()
+
+ frame = RenderingFrame(d.events)
+ self.assertEquals(10, frame.queueing_duration)
+
+ def testRenderingFrameMissingSendBeginFrameEvents(self):
+ d = RenderingFrameTestData()
+ d.AddBeginMainFrameEvent(ts=10)
+ d.FinalizeImport()
+
+ self.assertRaises(MissingData, RenderingFrame, d.events)
+
+ def testRenderingFrameDuplicateSendBeginFrameEvents(self):
+ d = RenderingFrameTestData()
+ d.AddSendEvent(ts=10)
+ d.AddBeginMainFrameEvent(ts=20)
+ d.AddSendEvent(ts=30)
+ d.FinalizeImport()
+
+ self.assertRaises(MissingData, RenderingFrame, d.events)
+
+ def testRenderingFrameMissingBeginMainFrameEvents(self):
+ d = RenderingFrameTestData()
+ d.AddSendEvent(ts=10)
+ d.FinalizeImport()
+
+ self.assertRaises(MissingData, RenderingFrame, d.events)
+
+ def testRenderingFrameDuplicateBeginMainFrameEvents(self):
+ d = RenderingFrameTestData()
+ d.AddSendEvent(ts=10)
+ d.AddBeginMainFrameEvent(ts=20)
+ d.AddBeginMainFrameEvent(ts=30)
+ d.AddBeginMainFrameEvent(ts=40)
+ d.FinalizeImport()
+
+ frame = RenderingFrame(d.events)
+ self.assertEquals(30, frame.queueing_duration)
+
+ def testFrameEventMissingBeginFrameId(self):
+ timeline = model.TimelineModel()
+ process = timeline.GetOrCreateProcess(pid=1)
+ main_thread = process.GetOrCreateThread(tid=11)
+ timeline_range = timeline_bounds.Bounds()
+
+ # Create an event without the begin_frame_id argument
+ event = tracing_slice.Slice(
+ None, 'cc,benchmark', RenderingFrame.begin_main_frame_event, 0)
+ main_thread.PushSlice(event)
+ process.FinalizeImport()
+ self.assertRaises(Exception, GetFrameEventsInsideRange, process,
+ timeline_range)
+
+ def testGetFrameEventsInsideRange(self):
+ """Test a basic sequenece, with expected frame queueing delays A and B.
+
+ |----A----| |--B--|
+ Main: [1] [1] [2]
+
+ Compositor: [1] [2]
+ """
+ d = RenderingFrameTestData()
+ d.AddSendEvent(ts=10)
+ d.AddBeginMainFrameEvent(ts=20)
+ d.AddBeginMainFrameEvent(ts=30)
+ d.AddSendEvent(ts=40)
+ d.AddBeginMainFrameEvent(ts=50)
+ d.FinalizeImport()
+
+ timeline_range = GenerateTimelineRange()
+ frame_events = GetFrameEventsInsideRange(d.renderer_process, timeline_range)
+
+ self.assertEquals(2, len(frame_events))
+ self.assertEquals(20, frame_events[0].queueing_duration)
+ self.assertEquals(10, frame_events[1].queueing_duration)
+
+ def testFrameEventsMissingDataNotIncluded(self):
+ """Test a sequenece missing an initial SendBeginFrame.
+
+ Only one frame should be returned, with expected frame queueing delay A.
+ |--A--|
+ Main: [0] [0] [2]
+
+ Compositor: [2]
+ """
+ d = RenderingFrameTestData()
+ d.AddBeginMainFrameEvent(ts=20)
+ d.AddBeginMainFrameEvent(ts=30)
+ d.AddSendEvent(ts=40)
+ d.AddBeginMainFrameEvent(ts=50)
+ d.FinalizeImport()
+
+ timeline_range = GenerateTimelineRange()
+ frame_events = GetFrameEventsInsideRange(d.renderer_process, timeline_range)
+
+ self.assertEquals(1, len(frame_events))
+ self.assertEquals(10, frame_events[0].queueing_duration)