Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / tools / telemetry / telemetry / web_perf / metrics / rendering_frame_unittest.py
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.
4
5 import unittest
6
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
14
15
16 class RenderingFrameTestData(object):
17
18   def __init__(self):
19     self._begin_frame_id = 0
20     self._events = []
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)
24
25   @property
26   def events(self):
27     return self._events
28
29   @property
30   def renderer_process(self):
31     return self._renderer_process
32
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)
38
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)
43
44   def FinalizeImport(self):
45     self._renderer_process.FinalizeImport()
46
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)
51     return event
52
53
54 def GenerateTimelineRange(start=0, end=100):
55   timeline_range = timeline_bounds.Bounds()
56   timeline_range.AddValue(start)
57   timeline_range.AddValue(end)
58   return timeline_range
59
60
61 class RenderingFrameUnitTest(unittest.TestCase):
62
63   def testRenderingFrame(self):
64     d = RenderingFrameTestData()
65     d.AddSendEvent(ts=10)
66     d.AddBeginMainFrameEvent(ts=20)
67     d.FinalizeImport()
68
69     frame = RenderingFrame(d.events)
70     self.assertEquals(10, frame.queueing_duration)
71
72   def testRenderingFrameMissingSendBeginFrameEvents(self):
73     d = RenderingFrameTestData()
74     d.AddBeginMainFrameEvent(ts=10)
75     d.FinalizeImport()
76
77     self.assertRaises(MissingData, RenderingFrame, d.events)
78
79   def testRenderingFrameDuplicateSendBeginFrameEvents(self):
80     d = RenderingFrameTestData()
81     d.AddSendEvent(ts=10)
82     d.AddBeginMainFrameEvent(ts=20)
83     d.AddSendEvent(ts=30)
84     d.FinalizeImport()
85
86     self.assertRaises(MissingData, RenderingFrame, d.events)
87
88   def testRenderingFrameMissingBeginMainFrameEvents(self):
89     d = RenderingFrameTestData()
90     d.AddSendEvent(ts=10)
91     d.FinalizeImport()
92
93     self.assertRaises(MissingData, RenderingFrame, d.events)
94
95   def testRenderingFrameDuplicateBeginMainFrameEvents(self):
96     d = RenderingFrameTestData()
97     d.AddSendEvent(ts=10)
98     d.AddBeginMainFrameEvent(ts=20)
99     d.AddBeginMainFrameEvent(ts=30)
100     d.AddBeginMainFrameEvent(ts=40)
101     d.FinalizeImport()
102
103     frame = RenderingFrame(d.events)
104     self.assertEquals(30, frame.queueing_duration)
105
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()
111
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,
118                       timeline_range)
119
120   def testGetFrameEventsInsideRange(self):
121     """Test a basic sequenece, with expected frame queueing delays A and B.
122
123                  |----A----|    |--B--|
124          Main:        [1]  [1]        [2]
125
126     Compositor:  [1]            [2]
127     """
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)
134     d.FinalizeImport()
135
136     timeline_range = GenerateTimelineRange()
137     frame_events = GetFrameEventsInsideRange(d.renderer_process, timeline_range)
138
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)
142
143   def testFrameEventsMissingDataNotIncluded(self):
144     """Test a sequenece missing an initial SendBeginFrame.
145
146     Only one frame should be returned, with expected frame queueing delay A.
147                            |--A--|
148           Main:  [0]  [0]        [2]
149
150     Compositor:            [2]
151     """
152     d = RenderingFrameTestData()
153     d.AddBeginMainFrameEvent(ts=20)
154     d.AddBeginMainFrameEvent(ts=30)
155     d.AddSendEvent(ts=40)
156     d.AddBeginMainFrameEvent(ts=50)
157     d.FinalizeImport()
158
159     timeline_range = GenerateTimelineRange()
160     frame_events = GetFrameEventsInsideRange(d.renderer_process, timeline_range)
161
162     self.assertEquals(1, len(frame_events))
163     self.assertEquals(10, frame_events[0].queueing_duration)