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
3 # found in the LICENSE file.
7 import telemetry.timeline.bounds as timeline_bounds
8 import telemetry.timeline.slice as tracing_slice
9 from telemetry.timeline import model
10 from telemetry.web_perf.metrics. \
11 rendering_frame import GetFrameEventsInsideRange
12 from telemetry.web_perf.metrics.rendering_frame import MissingData
13 from telemetry.web_perf.metrics.rendering_frame import RenderingFrame
16 class RenderingFrameTestData(object):
19 self._begin_frame_id = 0
21 self._renderer_process = model.TimelineModel().GetOrCreateProcess(pid=1)
22 self._main_thread = self._renderer_process.GetOrCreateThread(tid=11)
23 self._compositor_thread = self._renderer_process.GetOrCreateThread(tid=12)
30 def renderer_process(self):
31 return self._renderer_process
33 def AddSendEvent(self, ts=0, duration=1):
34 self._begin_frame_id += 1
35 event = self._CreateEvent(
36 RenderingFrame.send_begin_frame_event, ts, duration)
37 self._compositor_thread.PushSlice(event)
39 def AddBeginMainFrameEvent(self, ts=0, duration=1):
40 event = self._CreateEvent(
41 RenderingFrame.begin_main_frame_event, ts, duration)
42 self._main_thread.PushSlice(event)
44 def FinalizeImport(self):
45 self._renderer_process.FinalizeImport()
47 def _CreateEvent(self, event_name, ts, duration):
48 event = tracing_slice.Slice(None, 'cc,benchmark', event_name, ts,
49 duration=duration, args={'begin_frame_id': self._begin_frame_id})
50 self._events.append(event)
54 def GenerateTimelineRange(start=0, end=100):
55 timeline_range = timeline_bounds.Bounds()
56 timeline_range.AddValue(start)
57 timeline_range.AddValue(end)
61 class RenderingFrameUnitTest(unittest.TestCase):
63 def testRenderingFrame(self):
64 d = RenderingFrameTestData()
66 d.AddBeginMainFrameEvent(ts=20)
69 frame = RenderingFrame(d.events)
70 self.assertEquals(10, frame.queueing_duration)
72 def testRenderingFrameMissingSendBeginFrameEvents(self):
73 d = RenderingFrameTestData()
74 d.AddBeginMainFrameEvent(ts=10)
77 self.assertRaises(MissingData, RenderingFrame, d.events)
79 def testRenderingFrameDuplicateSendBeginFrameEvents(self):
80 d = RenderingFrameTestData()
82 d.AddBeginMainFrameEvent(ts=20)
86 self.assertRaises(MissingData, RenderingFrame, d.events)
88 def testRenderingFrameMissingBeginMainFrameEvents(self):
89 d = RenderingFrameTestData()
93 self.assertRaises(MissingData, RenderingFrame, d.events)
95 def testRenderingFrameDuplicateBeginMainFrameEvents(self):
96 d = RenderingFrameTestData()
98 d.AddBeginMainFrameEvent(ts=20)
99 d.AddBeginMainFrameEvent(ts=30)
100 d.AddBeginMainFrameEvent(ts=40)
103 frame = RenderingFrame(d.events)
104 self.assertEquals(30, frame.queueing_duration)
106 def testFrameEventMissingBeginFrameId(self):
107 timeline = model.TimelineModel()
108 process = timeline.GetOrCreateProcess(pid=1)
109 main_thread = process.GetOrCreateThread(tid=11)
110 timeline_range = timeline_bounds.Bounds()
112 # Create an event without the begin_frame_id argument
113 event = tracing_slice.Slice(
114 None, 'cc,benchmark', RenderingFrame.begin_main_frame_event, 0)
115 main_thread.PushSlice(event)
116 process.FinalizeImport()
117 self.assertRaises(Exception, GetFrameEventsInsideRange, process,
120 def testGetFrameEventsInsideRange(self):
121 """Test a basic sequenece, with expected frame queueing delays A and B.
128 d = RenderingFrameTestData()
129 d.AddSendEvent(ts=10)
130 d.AddBeginMainFrameEvent(ts=20)
131 d.AddBeginMainFrameEvent(ts=30)
132 d.AddSendEvent(ts=40)
133 d.AddBeginMainFrameEvent(ts=50)
136 timeline_range = GenerateTimelineRange()
137 frame_events = GetFrameEventsInsideRange(d.renderer_process, timeline_range)
139 self.assertEquals(2, len(frame_events))
140 self.assertEquals(20, frame_events[0].queueing_duration)
141 self.assertEquals(10, frame_events[1].queueing_duration)
143 def testFrameEventsMissingDataNotIncluded(self):
144 """Test a sequenece missing an initial SendBeginFrame.
146 Only one frame should be returned, with expected frame queueing delay A.
152 d = RenderingFrameTestData()
153 d.AddBeginMainFrameEvent(ts=20)
154 d.AddBeginMainFrameEvent(ts=30)
155 d.AddSendEvent(ts=40)
156 d.AddBeginMainFrameEvent(ts=50)
159 timeline_range = GenerateTimelineRange()
160 frame_events = GetFrameEventsInsideRange(d.renderer_process, timeline_range)
162 self.assertEquals(1, len(frame_events))
163 self.assertEquals(10, frame_events[0].queueing_duration)