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 import smoothness | 8 from metrics import smoothness |
9 from metrics import statistics | 9 from metrics import statistics |
10 from metrics import rendering_stats | 10 from metrics import rendering_stats |
11 from telemetry.core.backends.chrome.tracing_backend import RawTraceResultImpl | 11 from telemetry.core.backends.chrome.tracing_backend import RawTraceResult |
nduca
2013/10/31 07:32:02
this is a no-no.
you should be able to construct
ernstm
2013/11/05 00:25:05
crbug.com/314877
| |
12 from telemetry.core.backends.chrome.trace_result import TraceResult | |
13 from telemetry.page import page | 12 from telemetry.page import page |
14 from telemetry.page.page_measurement_results import PageMeasurementResults | 13 from telemetry.page.page_measurement_results import PageMeasurementResults |
15 | 14 |
16 SYNTHETIC_GESTURE_MARKER = 'SyntheticGestureController::running' | 15 SYNTHETIC_GESTURE_MARKER = 'SyntheticGestureController::running' |
16 RENDERER_PROCESS_MARKER = 'RendererProcessMarker' | |
17 | 17 |
18 | 18 |
19 class MockTimer(object): | 19 class MockTimer(object): |
20 """A mock timer class which can generate random durations. | 20 """A mock timer class which can generate random durations. |
21 | 21 |
22 An instance of this class is used as a global timer to generate random | 22 An instance of this class is used as a global timer to generate random |
23 durations for stats and consistent timestamps for all mock trace events. | 23 durations for stats and consistent timestamps for all mock trace events. |
24 """ | 24 """ |
25 def __init__(self): | 25 def __init__(self): |
26 self.microseconds = 0 | 26 self.microseconds = 0 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
84 'ts': self.end, | 84 'ts': self.end, |
85 'cat': 'benchmark', | 85 'cat': 'benchmark', |
86 's': 't', | 86 's': 't', |
87 'tid': 11, | 87 'tid': 11, |
88 'ph': 'i', | 88 'ph': 'i', |
89 'args': {'data': self.impl_stats}} | 89 'args': {'data': self.impl_stats}} |
90 trace_events.append(event) | 90 trace_events.append(event) |
91 | 91 |
92 | 92 |
93 class SmoothnessMetricUnitTest(unittest.TestCase): | 93 class SmoothnessMetricUnitTest(unittest.TestCase): |
94 def testCalcResultsTraceEvents(self): | 94 def testCalcResultsTraceEvents(self): |
nduca
2013/10/31 07:32:02
there's something confusing here. This is a test t
ernstm
2013/11/05 00:25:05
Yes, the unittest has a pasta flavor -> crbug.com/
| |
95 # Make the test repeatable by seeding the random number generator | 95 # Make the test repeatable by seeding the random number generator |
96 # (which is used by the mock timer) with a constant number. | 96 # (which is used by the mock timer) with a constant number. |
97 random.seed(1234567) | 97 random.seed(1234567) |
98 mock_timer = MockTimer() | 98 mock_timer = MockTimer() |
99 trace_events = [] | 99 trace_events = [] |
100 total_time_seconds = 0.0 | 100 total_time_seconds = 0.0 |
101 num_frames_sent = 0.0 | 101 num_frames_sent = 0.0 |
nduca
2013/10/31 07:32:02
as a bit of a comment, I think possibly the test i
ernstm
2013/11/05 00:25:05
crbug.com/314877
| |
102 first_frame = True | 102 first_frame = True |
103 previous_frame_time = None | 103 previous_frame_time = None |
104 # This list represents time differences between frames in milliseconds. | 104 # This list represents time differences between frames in milliseconds. |
105 expected_frame_times = [] | 105 expected_frame_times = [] |
106 | 106 |
107 # Append start trace events for the timeline marker and gesture marker, | 107 # Append start trace events for the timeline marker and gesture marker, |
108 # with some amount of time in between them. | 108 # with some amount of time in between them. |
109 trace_events.append({'name': rendering_stats.RENDER_PROCESS_MARKER, | 109 trace_events.append({'name': RENDERER_PROCESS_MARKER, |
110 'tts': mock_timer.microseconds, | 110 'tts': mock_timer.microseconds, |
111 'args': {}, | 111 'args': {}, |
112 'pid': 20978, | 112 'pid': 20978, |
113 'ts': mock_timer.microseconds, | 113 'ts': mock_timer.microseconds, |
114 'cat': 'webkit', | 114 'cat': 'webkit', |
115 'tid': 11, | 115 'tid': 11, |
116 'ph': 'S', # Phase: start. | 116 'ph': 'S', # Phase: start. |
117 'id': '0x12345'}) | 117 'id': '0x12345'}) |
118 mock_timer.Advance() | 118 mock_timer.Advance() |
119 trace_events.append({'name': SYNTHETIC_GESTURE_MARKER, | 119 trace_events.append({'name': SYNTHETIC_GESTURE_MARKER, |
(...skipping 30 matching lines...) Expand all Loading... | |
150 trace_events.append({'name': SYNTHETIC_GESTURE_MARKER, | 150 trace_events.append({'name': SYNTHETIC_GESTURE_MARKER, |
151 'tts': mock_timer.microseconds, | 151 'tts': mock_timer.microseconds, |
152 'args': {}, | 152 'args': {}, |
153 'pid': 20978, | 153 'pid': 20978, |
154 'ts': mock_timer.microseconds, | 154 'ts': mock_timer.microseconds, |
155 'cat': 'webkit', | 155 'cat': 'webkit', |
156 'tid': 11, | 156 'tid': 11, |
157 'ph': 'F', # Phase: finish. | 157 'ph': 'F', # Phase: finish. |
158 'id': '0xabcde'}) | 158 'id': '0xabcde'}) |
159 mock_timer.Advance() | 159 mock_timer.Advance() |
160 trace_events.append({'name': rendering_stats.RENDER_PROCESS_MARKER, | 160 trace_events.append({'name': RENDERER_PROCESS_MARKER, |
161 'tts': mock_timer.microseconds, | 161 'tts': mock_timer.microseconds, |
162 'args': {}, | 162 'args': {}, |
163 'pid': 20978, | 163 'pid': 20978, |
164 'ts': mock_timer.microseconds, | 164 'ts': mock_timer.microseconds, |
165 'cat': 'webkit', | 165 'cat': 'webkit', |
166 'tid': 11, | 166 'tid': 11, |
167 'ph': 'F', | 167 'ph': 'F', |
168 'id': '0x12345'}) | 168 'id': '0x12345'}) |
169 | 169 |
170 # Create a timeline object from the trace. | 170 # Create a timeline object from the trace. |
171 trace_impl = RawTraceResultImpl(trace_events) | 171 trace_result = RawTraceResult(trace_events) |
172 trace_result = TraceResult(trace_impl) | |
173 timeline = trace_result.AsTimelineModel() | 172 timeline = trace_result.AsTimelineModel() |
174 | 173 |
175 # Find the timeline marker and gesture marker in the timeline, | 174 # Find the timeline marker and gesture marker in the timeline, |
176 # and create a RenderingStats object. | 175 # and create a RenderingStats object. |
177 render_process_marker = timeline.FindTimelineMarkers( | 176 renderer_process_markers = timeline.FindTimelineMarkers( |
178 rendering_stats.RENDER_PROCESS_MARKER) | 177 RENDERER_PROCESS_MARKER) |
178 self.assertEquals(len(renderer_process_markers), 1) | |
179 renderer_process = renderer_process_markers[0].start_thread.parent | |
179 timeline_markers = timeline.FindTimelineMarkers( | 180 timeline_markers = timeline.FindTimelineMarkers( |
180 SYNTHETIC_GESTURE_MARKER) | 181 SYNTHETIC_GESTURE_MARKER) |
181 stats = rendering_stats.RenderingStats( | 182 stats = rendering_stats.RenderingStats(renderer_process, timeline_markers) |
182 render_process_marker, timeline_markers) | |
183 | 183 |
184 # Make a results object and add results to it from the smoothness metric. | 184 # Make a results object and add results to it from the smoothness metric. |
185 results = PageMeasurementResults() | 185 results = PageMeasurementResults() |
186 results.WillMeasurePage(page.Page('http://foo.com/', None)) | 186 results.WillMeasurePage(page.Page('http://foo.com/', None)) |
187 smoothness_metric = smoothness.SmoothnessMetric(stats) | 187 smoothness_metric = smoothness.SmoothnessMetric(None) |
188 smoothness_metric.SetStats(stats) | |
188 smoothness_metric.AddResults(None, results) | 189 smoothness_metric.AddResults(None, results) |
189 results.DidMeasurePage() | 190 results.DidMeasurePage() |
190 | 191 |
191 self.assertEquals( | 192 self.assertEquals( |
192 expected_frame_times, | 193 expected_frame_times, |
193 results.page_results[0]['frame_times'].value) | 194 results.page_results[0]['frame_times'].value) |
194 self.assertAlmostEquals( | 195 self.assertAlmostEquals( |
195 1000.0 * (total_time_seconds / num_frames_sent), | 196 1000.0 * (total_time_seconds / num_frames_sent), |
196 results.page_results[0]['mean_frame_time'].value, | 197 results.page_results[0]['mean_frame_time'].value, |
197 places=2) | 198 places=2) |
198 | 199 |
199 # We don't verify the correctness of the discrepancy computation itself, | 200 # We don't verify the correctness of the discrepancy computation itself, |
200 # because we have a separate unit test for that purpose. | 201 # because we have a separate unit test for that purpose. |
201 self.assertAlmostEquals( | 202 self.assertAlmostEquals( |
202 statistics.FrameDiscrepancy(stats.frame_timestamps, True), | 203 statistics.FrameDiscrepancy(stats.frame_timestamps, True), |
203 results.page_results[0]['jank'].value, | 204 results.page_results[0]['jank'].value, |
204 places=4) | 205 places=4) |
205 | 206 |
206 # We do not verify the correctness of Percentile here; Percentile should | 207 # We do not verify the correctness of Percentile here; Percentile should |
207 # have its own test. | 208 # have its own test. |
208 # The 17 here represents a threshold of 17 ms; this should match the value | 209 # The 17 here represents a threshold of 17 ms; this should match the value |
209 # in the smoothness metric. | 210 # in the smoothness metric. |
210 self.assertEquals( | 211 self.assertEquals( |
211 statistics.Percentile(expected_frame_times, 95.0) < 17.0, | 212 statistics.Percentile(expected_frame_times, 95.0) < 17.0, |
212 results.page_results[0]['mostly_smooth'].value) | 213 results.page_results[0]['mostly_smooth'].value) |
OLD | NEW |