OLD | NEW |
---|---|
1 # Copyright 2013 The Chromium Authors. All rights reserved. | 1 # Copyright 2013 The Chromium Authors. All rights reserved. |
2 # Use of this source code is governed by a BSD-style license that can be | 2 # Use of this source code is governed by a BSD-style license that can be |
3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
4 | 4 |
5 import random | 5 import random |
6 import unittest | 6 import unittest |
7 | 7 |
8 from metrics.rendering_stats import RenderingStats | 8 from metrics.rendering_stats import RenderingStats |
9 import telemetry.core.timeline.bounds as timeline_bounds | 9 import telemetry.core.timeline.bounds as timeline_bounds |
10 from telemetry.core.timeline import model | 10 from telemetry.core.timeline import model |
11 import telemetry.core.timeline.async_slice as tracing_async_slice | |
11 | 12 |
12 | 13 |
13 class MockTimer(object): | 14 class MockTimer(object): |
14 """A mock timer class which can generate random durations. | 15 """A mock timer class which can generate random durations. |
15 | 16 |
16 An instance of this class is used as a global timer to generate random | 17 An instance of this class is used as a global timer to generate random |
17 durations for stats and consistent timestamps for all mock trace events. | 18 durations for stats and consistent timestamps for all mock trace events. |
18 The unit of time is milliseconds. | 19 The unit of time is milliseconds. |
19 """ | 20 """ |
20 def __init__(self): | 21 def __init__(self): |
(...skipping 12 matching lines...) Expand all Loading... | |
33 """ Stores expected data for comparison with actual RenderingStats """ | 34 """ Stores expected data for comparison with actual RenderingStats """ |
34 def __init__(self): | 35 def __init__(self): |
35 self.frame_timestamps = [] | 36 self.frame_timestamps = [] |
36 self.frame_times = [] | 37 self.frame_times = [] |
37 self.paint_time = [] | 38 self.paint_time = [] |
38 self.painted_pixel_count = [] | 39 self.painted_pixel_count = [] |
39 self.record_time = [] | 40 self.record_time = [] |
40 self.recorded_pixel_count = [] | 41 self.recorded_pixel_count = [] |
41 self.rasterize_time = [] | 42 self.rasterize_time = [] |
42 self.rasterized_pixel_count = [] | 43 self.rasterized_pixel_count = [] |
44 self.mouse_wheel_latency = [] | |
45 self.gesture_scroll_latency = [] | |
nduca
2014/01/23 18:34:45
these member variable names should be chosen to cl
| |
46 self.touch_scroll_latency = [] | |
43 | 47 |
48 def AddBrowserInputLatencyStats(mock_timer, input_type, start_thread, | |
49 end_thread, ref_stats = None): | |
50 """ Adds a random browser process input latency stats event. | |
51 | |
52 input_type: The input type for which the latency slice is generated. | |
53 start_thread: The start thread on which the async slice is added. | |
54 end_thread: The end thread on which the async slice is ended. | |
55 ref_stats: A ReferenceRenderingStats object to record expected values. | |
56 """ | |
57 ui_comp_name = 'INPUT_EVENT_LATENCY_UI_COMPONENT' | |
58 begin_comp_name = 'INPUT_EVENT_LATENCY_BEGIN_RWH_COMPONENT' | |
59 end_comp_name = 'INPUT_EVENT_LATENCY_TERMINATED_FRAME_SWAP_COMPONENT' | |
60 | |
61 mock_timer.Advance() | |
62 ui_comp_time = mock_timer.Get() * 1000.0 | |
63 mock_timer.Advance() | |
64 begin_comp_time = mock_timer.Get() * 1000.0 | |
65 mock_timer.Advance(10, 20) | |
66 end_comp_time = mock_timer.Get() * 1000.0 | |
67 | |
68 data = { ui_comp_name: {'time': ui_comp_time}, | |
69 begin_comp_name: {'time': begin_comp_time}, | |
70 end_comp_name: {'time': end_comp_time} } | |
71 | |
72 timestamp = mock_timer.Get() | |
73 | |
74 async_slice = tracing_async_slice.AsyncSlice( | |
75 'benchmark', 'InputLatency', timestamp) | |
76 | |
77 async_sub_slice = tracing_async_slice.AsyncSlice( | |
78 'benchmark', 'InputLatency', timestamp) | |
79 async_sub_slice.args = {'data': data, 'step': input_type} | |
80 async_sub_slice.parent_slice = async_slice | |
81 async_sub_slice.start_thread = start_thread | |
82 async_sub_slice.end_thread = end_thread | |
83 | |
84 async_slice.sub_slices.append(async_sub_slice) | |
85 async_slice.start_thread = start_thread | |
86 async_slice.end_thread = end_thread | |
87 start_thread.AddAsyncSlice(async_slice) | |
88 | |
89 if not ref_stats: | |
90 return | |
91 | |
92 if input_type == 'MouseWheel': | |
93 ref_stats.mouse_wheel_latency.append( | |
94 (data[end_comp_name]['time'] - data[begin_comp_name]['time']) / 1000.0) | |
95 elif input_type == 'GestureScrollUpdate': | |
96 ref_stats.gesture_scroll_latency.append( | |
97 (data[end_comp_name]['time'] - data[begin_comp_name]['time']) / 1000.0) | |
98 ref_stats.touch_scroll_latency.append( | |
99 (data[end_comp_name]['time'] - data[ui_comp_name]['time']) / 1000.0) | |
44 | 100 |
45 def AddMainThreadRenderingStats(mock_timer, thread, first_frame, | 101 def AddMainThreadRenderingStats(mock_timer, thread, first_frame, |
46 ref_stats = None): | 102 ref_stats = None): |
47 """ Adds a random main thread rendering stats event. | 103 """ Adds a random main thread rendering stats event. |
48 | 104 |
49 thread: The timeline model thread to which the event will be added. | 105 thread: The timeline model thread to which the event will be added. |
50 first_frame: Is this the first frame within the bounds of an action? | 106 first_frame: Is this the first frame within the bounds of an action? |
51 ref_stats: A ReferenceRenderingStats object to record expected values. | 107 ref_stats: A ReferenceRenderingStats object to record expected values. |
52 """ | 108 """ |
53 # Create randonm data and timestap for main thread rendering stats. | 109 # Create randonm data and timestap for main thread rendering stats. |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
136 | 192 |
137 # Create 10 main and impl rendering stats events for Action A. | 193 # Create 10 main and impl rendering stats events for Action A. |
138 timer.Advance() | 194 timer.Advance() |
139 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') | 195 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') |
140 for i in xrange(0, 10): | 196 for i in xrange(0, 10): |
141 first = (i == 0) | 197 first = (i == 0) |
142 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) | 198 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) |
143 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) | 199 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) |
144 AddMainThreadRenderingStats(timer, browser_main, first, None) | 200 AddMainThreadRenderingStats(timer, browser_main, first, None) |
145 AddImplThreadRenderingStats(timer, browser_compositor, first, None) | 201 AddImplThreadRenderingStats(timer, browser_compositor, first, None) |
202 AddBrowserInputLatencyStats(timer, 'MouseWheel', browser_main, | |
203 renderer_main, ref_stats) | |
204 AddBrowserInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, | |
205 renderer_main, ref_stats) | |
146 renderer_main.EndSlice(timer.Get()) | 206 renderer_main.EndSlice(timer.Get()) |
147 | 207 |
148 # Create 5 main and impl rendering stats events not within any action. | 208 # Create 5 main and impl rendering stats events not within any action. |
149 for i in xrange(0, 5): | 209 for i in xrange(0, 5): |
150 first = (i == 0) | 210 first = (i == 0) |
151 AddMainThreadRenderingStats(timer, renderer_main, first, None) | 211 AddMainThreadRenderingStats(timer, renderer_main, first, None) |
152 AddImplThreadRenderingStats(timer, renderer_compositor, first, None) | 212 AddImplThreadRenderingStats(timer, renderer_compositor, first, None) |
153 AddMainThreadRenderingStats(timer, browser_main, first, None) | 213 AddMainThreadRenderingStats(timer, browser_main, first, None) |
154 AddImplThreadRenderingStats(timer, browser_compositor, first, None) | 214 AddImplThreadRenderingStats(timer, browser_compositor, first, None) |
215 AddBrowserInputLatencyStats(timer, 'MouseWheel', browser_main, | |
216 renderer_main, None) | |
217 AddBrowserInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, | |
218 renderer_main, None) | |
155 | 219 |
156 # Create 10 main and impl rendering stats events for Action B. | 220 # Create 10 main and impl rendering stats events for Action B. |
157 timer.Advance() | 221 timer.Advance() |
158 renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '') | 222 renderer_main.BeginSlice('webkit.console', 'ActionB', timer.Get(), '') |
159 for i in xrange(0, 10): | 223 for i in xrange(0, 10): |
160 first = (i == 0) | 224 first = (i == 0) |
161 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) | 225 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) |
162 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) | 226 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) |
163 AddMainThreadRenderingStats(timer, browser_main, first, None) | 227 AddMainThreadRenderingStats(timer, browser_main, first, None) |
164 AddImplThreadRenderingStats(timer, browser_compositor, first, None) | 228 AddImplThreadRenderingStats(timer, browser_compositor, first, None) |
229 AddBrowserInputLatencyStats(timer, 'MouseWheel', browser_main, | |
230 renderer_main, ref_stats) | |
231 AddBrowserInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, | |
232 renderer_main, ref_stats) | |
165 renderer_main.EndSlice(timer.Get()) | 233 renderer_main.EndSlice(timer.Get()) |
166 | 234 |
167 # Create 10 main and impl rendering stats events for Action A. | 235 # Create 10 main and impl rendering stats events for Action A. |
168 timer.Advance() | 236 timer.Advance() |
169 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') | 237 renderer_main.BeginSlice('webkit.console', 'ActionA', timer.Get(), '') |
170 for i in xrange(0, 10): | 238 for i in xrange(0, 10): |
171 first = (i == 0) | 239 first = (i == 0) |
172 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) | 240 AddMainThreadRenderingStats(timer, renderer_main, first, ref_stats) |
173 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) | 241 AddImplThreadRenderingStats(timer, renderer_compositor, first, ref_stats) |
174 AddMainThreadRenderingStats(timer, browser_main, first, None) | 242 AddMainThreadRenderingStats(timer, browser_main, first, None) |
175 AddImplThreadRenderingStats(timer, browser_compositor, first, None) | 243 AddImplThreadRenderingStats(timer, browser_compositor, first, None) |
244 AddBrowserInputLatencyStats(timer, 'MouseWheel', browser_main, | |
nduca
2014/01/23 18:34:45
it worries me that this is one huge unit test. Can
Yufeng Shen (Slow to review)
2014/01/30 01:16:05
Done.
| |
245 renderer_main, ref_stats) | |
246 AddBrowserInputLatencyStats(timer, 'GestureScrollUpdate', browser_main, | |
247 renderer_main, ref_stats) | |
176 renderer_main.EndSlice(timer.Get()) | 248 renderer_main.EndSlice(timer.Get()) |
177 | 249 |
178 renderer_main.FinalizeImport() | 250 renderer_main.FinalizeImport() |
179 renderer_compositor.FinalizeImport() | 251 renderer_compositor.FinalizeImport() |
180 | 252 |
181 timeline_markers = timeline.FindTimelineMarkers( | 253 timeline_markers = timeline.FindTimelineMarkers( |
182 ['ActionA', 'ActionB', 'ActionA']) | 254 ['ActionA', 'ActionB', 'ActionA']) |
183 timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker) | 255 timeline_ranges = [ timeline_bounds.Bounds.CreateFromEvent(marker) |
184 for marker in timeline_markers ] | 256 for marker in timeline_markers ] |
185 stats = RenderingStats(renderer, timeline_ranges) | 257 stats = RenderingStats(renderer, browser_main, timeline_ranges) |
186 | 258 |
187 # Compare rendering stats to reference. | 259 # Compare rendering stats to reference. |
188 self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps) | 260 self.assertEquals(stats.frame_timestamps, ref_stats.frame_timestamps) |
189 self.assertEquals(stats.frame_times, ref_stats.frame_times) | 261 self.assertEquals(stats.frame_times, ref_stats.frame_times) |
190 self.assertEquals(stats.rasterize_time, ref_stats.rasterize_time) | 262 self.assertEquals(stats.rasterize_time, ref_stats.rasterize_time) |
191 self.assertEquals(stats.rasterized_pixel_count, | 263 self.assertEquals(stats.rasterized_pixel_count, |
192 ref_stats.rasterized_pixel_count) | 264 ref_stats.rasterized_pixel_count) |
193 self.assertEquals(stats.paint_time, ref_stats.paint_time) | 265 self.assertEquals(stats.paint_time, ref_stats.paint_time) |
194 self.assertEquals(stats.painted_pixel_count, ref_stats.painted_pixel_count) | 266 self.assertEquals(stats.painted_pixel_count, ref_stats.painted_pixel_count) |
195 self.assertEquals(stats.record_time, ref_stats.record_time) | 267 self.assertEquals(stats.record_time, ref_stats.record_time) |
196 self.assertEquals(stats.recorded_pixel_count, | 268 self.assertEquals(stats.mouse_wheel_latency, |
197 ref_stats.recorded_pixel_count) | 269 ref_stats.mouse_wheel_latency) |
270 self.assertEquals(stats.gesture_scroll_latency, | |
271 ref_stats.gesture_scroll_latency) | |
272 self.assertEquals(stats.touch_scroll_latency, | |
273 ref_stats.touch_scroll_latency) | |
OLD | NEW |