1116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch# Copyright 2014 The Chromium Authors. All rights reserved. 2116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch# Use of this source code is governed by a BSD-style license that can be 3116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch# found in the LICENSE file. 4116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 5116680a4aac90f2aa7413d9095a592090648e557Ben Murdochimport unittest 6116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 7116680a4aac90f2aa7413d9095a592090648e557Ben Murdochimport telemetry.timeline.bounds as timeline_bounds 8116680a4aac90f2aa7413d9095a592090648e557Ben Murdochimport telemetry.timeline.slice as tracing_slice 96e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)from telemetry.timeline import model 106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)from telemetry.web_perf.metrics. \ 116e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) rendering_frame import GetFrameEventsInsideRange 12116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfrom telemetry.web_perf.metrics.rendering_frame import MissingData 13116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfrom telemetry.web_perf.metrics.rendering_frame import RenderingFrame 14116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 15116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 16116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass RenderingFrameTestData(object): 17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 18116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def __init__(self): 19116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self._begin_frame_id = 0 20116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self._events = [] 21116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self._renderer_process = model.TimelineModel().GetOrCreateProcess(pid=1) 22116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self._main_thread = self._renderer_process.GetOrCreateThread(tid=11) 23116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self._compositor_thread = self._renderer_process.GetOrCreateThread(tid=12) 24116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 25116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch @property 26116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def events(self): 27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return self._events 28116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 29116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch @property 30116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def renderer_process(self): 31116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return self._renderer_process 32116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def AddSendEvent(self, ts=0, duration=1): 34116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self._begin_frame_id += 1 35116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch event = self._CreateEvent( 36116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RenderingFrame.send_begin_frame_event, ts, duration) 37116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self._compositor_thread.PushSlice(event) 38116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 39116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def AddBeginMainFrameEvent(self, ts=0, duration=1): 40116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch event = self._CreateEvent( 41116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch RenderingFrame.begin_main_frame_event, ts, duration) 42116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self._main_thread.PushSlice(event) 43116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 44116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def FinalizeImport(self): 45116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self._renderer_process.FinalizeImport() 46116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 47116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def _CreateEvent(self, event_name, ts, duration): 48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch event = tracing_slice.Slice(None, 'cc,benchmark', event_name, ts, 49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch duration=duration, args={'begin_frame_id': self._begin_frame_id}) 50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self._events.append(event) 51116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return event 52116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 53116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 54116680a4aac90f2aa7413d9095a592090648e557Ben Murdochdef GenerateTimelineRange(start=0, end=100): 55116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch timeline_range = timeline_bounds.Bounds() 56116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch timeline_range.AddValue(start) 57116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch timeline_range.AddValue(end) 58116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch return timeline_range 59116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 60116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 61116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass RenderingFrameUnitTest(unittest.TestCase): 62116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 63116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def testRenderingFrame(self): 64116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d = RenderingFrameTestData() 65116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddSendEvent(ts=10) 66116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddBeginMainFrameEvent(ts=20) 67116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.FinalizeImport() 68116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch frame = RenderingFrame(d.events) 70116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self.assertEquals(10, frame.queueing_duration) 71116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 72116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def testRenderingFrameMissingSendBeginFrameEvents(self): 73116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d = RenderingFrameTestData() 74116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddBeginMainFrameEvent(ts=10) 75116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.FinalizeImport() 76116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 77116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self.assertRaises(MissingData, RenderingFrame, d.events) 78116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 79116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def testRenderingFrameDuplicateSendBeginFrameEvents(self): 80116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d = RenderingFrameTestData() 81116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddSendEvent(ts=10) 82116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddBeginMainFrameEvent(ts=20) 83116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddSendEvent(ts=30) 84116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.FinalizeImport() 85116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 86116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self.assertRaises(MissingData, RenderingFrame, d.events) 87116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 88116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def testRenderingFrameMissingBeginMainFrameEvents(self): 89116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d = RenderingFrameTestData() 90116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddSendEvent(ts=10) 91116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.FinalizeImport() 92116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 93116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self.assertRaises(MissingData, RenderingFrame, d.events) 94116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 95116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def testRenderingFrameDuplicateBeginMainFrameEvents(self): 96116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d = RenderingFrameTestData() 97116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddSendEvent(ts=10) 98116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddBeginMainFrameEvent(ts=20) 99116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddBeginMainFrameEvent(ts=30) 100116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddBeginMainFrameEvent(ts=40) 101116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.FinalizeImport() 102116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 103116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch frame = RenderingFrame(d.events) 104116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self.assertEquals(30, frame.queueing_duration) 105116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 106116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def testFrameEventMissingBeginFrameId(self): 107116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch timeline = model.TimelineModel() 108116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch process = timeline.GetOrCreateProcess(pid=1) 109116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch main_thread = process.GetOrCreateThread(tid=11) 110116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch timeline_range = timeline_bounds.Bounds() 111116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 112116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch # Create an event without the begin_frame_id argument 113116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch event = tracing_slice.Slice( 114116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch None, 'cc,benchmark', RenderingFrame.begin_main_frame_event, 0) 115116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch main_thread.PushSlice(event) 116116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch process.FinalizeImport() 117116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self.assertRaises(Exception, GetFrameEventsInsideRange, process, 118116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch timeline_range) 119116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 120116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def testGetFrameEventsInsideRange(self): 121116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch """Test a basic sequenece, with expected frame queueing delays A and B. 122116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 123116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch |----A----| |--B--| 124116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Main: [1] [1] [2] 125116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 126116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Compositor: [1] [2] 127116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch """ 128116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d = RenderingFrameTestData() 129116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddSendEvent(ts=10) 130116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddBeginMainFrameEvent(ts=20) 131116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddBeginMainFrameEvent(ts=30) 132116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddSendEvent(ts=40) 133116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddBeginMainFrameEvent(ts=50) 134116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.FinalizeImport() 135116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 136116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch timeline_range = GenerateTimelineRange() 137116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch frame_events = GetFrameEventsInsideRange(d.renderer_process, timeline_range) 138116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 139116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self.assertEquals(2, len(frame_events)) 140116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self.assertEquals(20, frame_events[0].queueing_duration) 141116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self.assertEquals(10, frame_events[1].queueing_duration) 142116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 143116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch def testFrameEventsMissingDataNotIncluded(self): 144116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch """Test a sequenece missing an initial SendBeginFrame. 145116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 146116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Only one frame should be returned, with expected frame queueing delay A. 147116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch |--A--| 148116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Main: [0] [0] [2] 149116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 150116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch Compositor: [2] 151116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch """ 152116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d = RenderingFrameTestData() 153116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddBeginMainFrameEvent(ts=20) 154116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddBeginMainFrameEvent(ts=30) 155116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddSendEvent(ts=40) 156116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.AddBeginMainFrameEvent(ts=50) 157116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch d.FinalizeImport() 158116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 159116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch timeline_range = GenerateTimelineRange() 160116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch frame_events = GetFrameEventsInsideRange(d.renderer_process, timeline_range) 161116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 162116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self.assertEquals(1, len(frame_events)) 163116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch self.assertEquals(10, frame_events[0].queueing_duration) 164