| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 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 import telemetry.timeline.async_slice as tracing_async_slice | 8 import telemetry.timeline.async_slice as tracing_async_slice |
| 9 import telemetry.timeline.bounds as timeline_bounds | 9 import telemetry.timeline.bounds as timeline_bounds |
| 10 from telemetry.timeline import model | 10 from telemetry.timeline import model |
| 11 from telemetry.util.statistics import DivideIfPossibleOrZero | 11 from telemetry.util.statistics import DivideIfPossibleOrZero |
| 12 from telemetry.web_perf.metrics.rendering_stats import ( | 12 from telemetry.web_perf.metrics.rendering_stats import ( |
| 13 UI_COMP_NAME, BEGIN_COMP_NAME, ORIGINAL_COMP_NAME, | 13 BEGIN_COMP_NAME, |
| 14 BEGIN_SCROLL_UPDATE_COMP_NAME, FORWARD_SCROLL_UPDATE_COMP_NAME, | 14 BEGIN_SCROLL_UPDATE_COMP_NAME, |
| 15 END_COMP_NAME) | 15 END_COMP_NAME, |
| 16 FORWARD_SCROLL_UPDATE_COMP_NAME, |
| 17 GESTURE_SCROLL_UPDATE_EVENT_NAME, |
| 18 ORIGINAL_COMP_NAME, |
| 19 SCROLL_UPDATE_EVENT_NAME, |
| 20 UI_COMP_NAME) |
| 16 from telemetry.web_perf.metrics.rendering_stats import ( | 21 from telemetry.web_perf.metrics.rendering_stats import ( |
| 17 ComputeInputEventLatencies) | 22 ComputeInputEventLatencies) |
| 18 from telemetry.web_perf.metrics.rendering_stats import GetInputLatencyEvents | 23 from telemetry.web_perf.metrics.rendering_stats import GetInputLatencyEvents |
| 19 from telemetry.web_perf.metrics.rendering_stats import HasRenderingStats | 24 from telemetry.web_perf.metrics.rendering_stats import HasRenderingStats |
| 20 from telemetry.web_perf.metrics.rendering_stats import NotEnoughFramesError | 25 from telemetry.web_perf.metrics.rendering_stats import NotEnoughFramesError |
| 21 from telemetry.web_perf.metrics.rendering_stats import RenderingStats | 26 from telemetry.web_perf.metrics.rendering_stats import RenderingStats |
| 22 | 27 |
| 23 | 28 |
| 24 class MockTimer(object): | 29 class MockTimer(object): |
| 25 """A mock timer class which can generate random durations. | 30 """A mock timer class which can generate random durations. |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 62 self.recorded_pixel_counts.append([]) | 67 self.recorded_pixel_counts.append([]) |
| 63 self.rasterize_times.append([]) | 68 self.rasterize_times.append([]) |
| 64 self.rasterized_pixel_counts.append([]) | 69 self.rasterized_pixel_counts.append([]) |
| 65 self.approximated_pixel_percentages.append([]) | 70 self.approximated_pixel_percentages.append([]) |
| 66 | 71 |
| 67 class ReferenceInputLatencyStats(object): | 72 class ReferenceInputLatencyStats(object): |
| 68 """ Stores expected data for comparison with actual input latency stats """ | 73 """ Stores expected data for comparison with actual input latency stats """ |
| 69 def __init__(self): | 74 def __init__(self): |
| 70 self.input_event_latency = [] | 75 self.input_event_latency = [] |
| 71 self.input_event = [] | 76 self.input_event = [] |
| 72 self.scroll_update_latency = [] | |
| 73 | 77 |
| 74 def AddMainThreadRenderingStats(mock_timer, thread, first_frame, | 78 def AddMainThreadRenderingStats(mock_timer, thread, first_frame, |
| 75 ref_stats = None): | 79 ref_stats = None): |
| 76 """ Adds a random main thread rendering stats event. | 80 """ Adds a random main thread rendering stats event. |
| 77 | 81 |
| 78 thread: The timeline model thread to which the event will be added. | 82 thread: The timeline model thread to which the event will be added. |
| 79 first_frame: Is this the first frame within the bounds of an action? | 83 first_frame: Is this the first frame within the bounds of an action? |
| 80 ref_stats: A ReferenceRenderingStats object to record expected values. | 84 ref_stats: A ReferenceRenderingStats object to record expected values. |
| 81 """ | 85 """ |
| 82 # Create randonm data and timestap for main thread rendering stats. | 86 # Create randonm data and timestap for main thread rendering stats. |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 176 UI_COMP_NAME: {'time': ui_comp_time}, | 180 UI_COMP_NAME: {'time': ui_comp_time}, |
| 177 BEGIN_COMP_NAME: {'time': begin_comp_time}, | 181 BEGIN_COMP_NAME: {'time': begin_comp_time}, |
| 178 END_COMP_NAME: {'time': end_comp_time} } | 182 END_COMP_NAME: {'time': end_comp_time} } |
| 179 | 183 |
| 180 timestamp = mock_timer.Get() | 184 timestamp = mock_timer.Get() |
| 181 | 185 |
| 182 async_slice = tracing_async_slice.AsyncSlice( | 186 async_slice = tracing_async_slice.AsyncSlice( |
| 183 'benchmark', 'InputLatency', timestamp) | 187 'benchmark', 'InputLatency', timestamp) |
| 184 | 188 |
| 185 async_sub_slice = tracing_async_slice.AsyncSlice( | 189 async_sub_slice = tracing_async_slice.AsyncSlice( |
| 186 'benchmark', 'InputLatency', timestamp) | 190 'benchmark', GESTURE_SCROLL_UPDATE_EVENT_NAME, timestamp) |
| 187 async_sub_slice.args = {'data': data} | 191 async_sub_slice.args = {'data': data} |
| 188 async_sub_slice.parent_slice = async_slice | 192 async_sub_slice.parent_slice = async_slice |
| 189 async_sub_slice.start_thread = start_thread | 193 async_sub_slice.start_thread = start_thread |
| 190 async_sub_slice.end_thread = end_thread | 194 async_sub_slice.end_thread = end_thread |
| 191 | 195 |
| 192 async_slice.sub_slices.append(async_sub_slice) | 196 async_slice.sub_slices.append(async_sub_slice) |
| 193 async_slice.start_thread = start_thread | 197 async_slice.start_thread = start_thread |
| 194 async_slice.end_thread = end_thread | 198 async_slice.end_thread = end_thread |
| 195 start_thread.AddAsyncSlice(async_slice) | 199 start_thread.AddAsyncSlice(async_slice) |
| 196 | 200 |
| 197 # Add scroll update latency info. | 201 # Add scroll update latency info. |
| 198 scroll_update_data = { | 202 scroll_update_data = { |
| 199 BEGIN_SCROLL_UPDATE_COMP_NAME: {'time': begin_comp_time}, | 203 BEGIN_SCROLL_UPDATE_COMP_NAME: {'time': begin_comp_time}, |
| 200 FORWARD_SCROLL_UPDATE_COMP_NAME: {'time': forward_comp_time}, | 204 FORWARD_SCROLL_UPDATE_COMP_NAME: {'time': forward_comp_time}, |
| 201 END_COMP_NAME: {'time': end_comp_time} } | 205 END_COMP_NAME: {'time': end_comp_time} } |
| 202 | 206 |
| 203 scroll_async_slice = tracing_async_slice.AsyncSlice( | 207 scroll_async_slice = tracing_async_slice.AsyncSlice( |
| 204 'benchmark', 'InputLatency', timestamp) | 208 'benchmark', 'InputLatency', timestamp) |
| 205 | 209 |
| 206 scroll_async_sub_slice = tracing_async_slice.AsyncSlice( | 210 scroll_async_sub_slice = tracing_async_slice.AsyncSlice( |
| 207 'benchmark', 'InputLatency', timestamp) | 211 'benchmark', SCROLL_UPDATE_EVENT_NAME, timestamp) |
| 208 scroll_async_sub_slice.args = {'data': scroll_update_data} | 212 scroll_async_sub_slice.args = {'data': scroll_update_data} |
| 209 scroll_async_sub_slice.parent_slice = scroll_async_slice | 213 scroll_async_sub_slice.parent_slice = scroll_async_slice |
| 210 scroll_async_sub_slice.start_thread = start_thread | 214 scroll_async_sub_slice.start_thread = start_thread |
| 211 scroll_async_sub_slice.end_thread = end_thread | 215 scroll_async_sub_slice.end_thread = end_thread |
| 212 | 216 |
| 213 scroll_async_slice.sub_slices.append(scroll_async_sub_slice) | 217 scroll_async_slice.sub_slices.append(scroll_async_sub_slice) |
| 214 scroll_async_slice.start_thread = start_thread | 218 scroll_async_slice.start_thread = start_thread |
| 215 scroll_async_slice.end_thread = end_thread | 219 scroll_async_slice.end_thread = end_thread |
| 216 start_thread.AddAsyncSlice(scroll_async_slice) | 220 start_thread.AddAsyncSlice(scroll_async_slice) |
| 217 | 221 |
| 218 if not ref_latency_stats: | 222 if not ref_latency_stats: |
| 219 return | 223 return |
| 220 | 224 |
| 221 ref_latency_stats.input_event.append(async_sub_slice) | 225 ref_latency_stats.input_event.append(async_sub_slice) |
| 222 ref_latency_stats.input_event.append(scroll_async_sub_slice) | 226 ref_latency_stats.input_event.append(scroll_async_sub_slice) |
| 223 ref_latency_stats.input_event_latency.append( | 227 ref_latency_stats.input_event_latency.append(( |
| 224 (data[END_COMP_NAME]['time'] - data[ORIGINAL_COMP_NAME]['time']) / 1000.0) | 228 GESTURE_SCROLL_UPDATE_EVENT_NAME, |
| 225 ref_latency_stats.scroll_update_latency.append( | 229 (data[END_COMP_NAME]['time'] - |
| 230 data[ORIGINAL_COMP_NAME]['time']) / 1000.0)) |
| 231 ref_latency_stats.input_event_latency.append(( |
| 232 SCROLL_UPDATE_EVENT_NAME, |
| 226 (scroll_update_data[END_COMP_NAME]['time'] - | 233 (scroll_update_data[END_COMP_NAME]['time'] - |
| 227 scroll_update_data[BEGIN_SCROLL_UPDATE_COMP_NAME]['time']) / 1000.0) | 234 scroll_update_data[BEGIN_SCROLL_UPDATE_COMP_NAME]['time']) / 1000.0)) |
| 228 | 235 |
| 229 | 236 |
| 230 class RenderingStatsUnitTest(unittest.TestCase): | 237 class RenderingStatsUnitTest(unittest.TestCase): |
| 231 def testHasRenderingStats(self): | 238 def testHasRenderingStats(self): |
| 232 timeline = model.TimelineModel() | 239 timeline = model.TimelineModel() |
| 233 timer = MockTimer() | 240 timer = MockTimer() |
| 234 | 241 |
| 235 # A process without rendering stats | 242 # A process without rendering stats |
| 236 process_without_stats = timeline.GetOrCreateProcess(pid = 1) | 243 process_without_stats = timeline.GetOrCreateProcess(pid = 1) |
| 237 thread_without_stats = process_without_stats.GetOrCreateThread(tid = 11) | 244 thread_without_stats = process_without_stats.GetOrCreateThread(tid = 11) |
| (...skipping 205 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 443 | 450 |
| 444 timeline_markers = timeline.FindTimelineMarkers( | 451 timeline_markers = timeline.FindTimelineMarkers( |
| 445 ['ActionA', 'ActionB', 'ActionA']) | 452 ['ActionA', 'ActionB', 'ActionA']) |
| 446 for timeline_range in [ timeline_bounds.Bounds.CreateFromEvent(marker) | 453 for timeline_range in [ timeline_bounds.Bounds.CreateFromEvent(marker) |
| 447 for marker in timeline_markers ]: | 454 for marker in timeline_markers ]: |
| 448 if timeline_range.is_empty: | 455 if timeline_range.is_empty: |
| 449 continue | 456 continue |
| 450 input_events.extend(GetInputLatencyEvents(browser, timeline_range)) | 457 input_events.extend(GetInputLatencyEvents(browser, timeline_range)) |
| 451 | 458 |
| 452 self.assertEquals(input_events, ref_latency.input_event) | 459 self.assertEquals(input_events, ref_latency.input_event) |
| 453 input_event_latency_result, scroll_update_latency_result = ( | 460 input_event_latency_result = ComputeInputEventLatencies(input_events) |
| 454 ComputeInputEventLatencies(input_events)) | |
| 455 self.assertEquals(input_event_latency_result, | 461 self.assertEquals(input_event_latency_result, |
| 456 ref_latency.input_event_latency) | 462 ref_latency.input_event_latency) |
| 457 self.assertEquals(scroll_update_latency_result, | |
| 458 ref_latency.scroll_update_latency) | |
| OLD | NEW |