OLD | NEW |
| (Empty) |
1 # Copyright 2015 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 from measurements import v8_gc_times | |
6 from telemetry.core import wpr_modes | |
7 from telemetry.page import page as page_module | |
8 from telemetry.results import page_test_results | |
9 from telemetry.timeline import model as model_module | |
10 from telemetry.unittest_util import options_for_unittests | |
11 from telemetry.unittest_util import page_test_test_case | |
12 | |
13 | |
14 class V8GCTimesTestPageHelper(object): | |
15 | |
16 def __init__(self, page_set): | |
17 self._page_set = page_set | |
18 self._model = model_module.TimelineModel() | |
19 self._renderer_process = self._model.GetOrCreateProcess(1) | |
20 self._renderer_thread = self._renderer_process.GetOrCreateThread(2) | |
21 self._renderer_thread.name = 'CrRendererMain' | |
22 | |
23 def AddEvent(self, category, name, thread_start, thread_duration, | |
24 args=None, wall_start=None, wall_duration=None): | |
25 wall_start = wall_start or thread_start | |
26 wall_duration = wall_duration or thread_duration | |
27 self._renderer_thread.BeginSlice(category, name, wall_start, thread_start, | |
28 args=args) | |
29 self._renderer_thread.EndSlice(wall_start + wall_duration, | |
30 thread_start + thread_duration) | |
31 | |
32 class MockV8GCTimesPage(page_module.Page): | |
33 | |
34 def __init__(self, page_set): | |
35 super(V8GCTimesTestPageHelper.MockV8GCTimesPage, self).__init__( | |
36 'file://blank.html', page_set, page_set.base_dir) | |
37 | |
38 def MeasureFakePage(self): | |
39 # Create a fake page and add it to the page set. | |
40 results = page_test_results.PageTestResults() | |
41 page = V8GCTimesTestPageHelper.MockV8GCTimesPage(self._page_set) | |
42 self._page_set.AddUserStory(page) | |
43 | |
44 # Pretend we're about to run the tests to silence lower level asserts. | |
45 results.WillRunPage(page) | |
46 | |
47 v8_gc_times_metric = v8_gc_times.V8GCTimes() | |
48 v8_gc_times_metric._renderer_process = self._renderer_process | |
49 | |
50 # Finalize the timeline import. | |
51 self._model.FinalizeImport() | |
52 | |
53 # Measure the V8GCTimes metric and return the results | |
54 v8_gc_times_metric.ValidateAndMeasurePage(page, None, results) | |
55 results.DidRunPage(page) | |
56 return results | |
57 | |
58 | |
59 class V8GCTimesTests(page_test_test_case.PageTestTestCase): | |
60 | |
61 def setUp(self): | |
62 self._options = options_for_unittests.GetCopy() | |
63 self._options.browser_options.wpr_mode = wpr_modes.WPR_OFF | |
64 | |
65 def testWithNoTraceEvents(self): | |
66 test_page_helper = V8GCTimesTestPageHelper( | |
67 self.CreateEmptyPageSet()) | |
68 | |
69 results = test_page_helper.MeasureFakePage() | |
70 self._AssertResultsEqual(_GetEmptyResults(), _ActualValues(results)) | |
71 | |
72 def testWithNoGarbageCollectionEvents(self): | |
73 test_page_helper = V8GCTimesTestPageHelper( | |
74 self.CreateEmptyPageSet()) | |
75 | |
76 test_page_helper.AddEvent('toplevel', 'PostMessage', | |
77 thread_start=0, thread_duration=14, wall_start=5, wall_duration=35) | |
78 | |
79 results = test_page_helper.MeasureFakePage() | |
80 expected = _GetEmptyResults() | |
81 expected['duration'] = ('ms', 35) | |
82 expected['cpu_time'] = ('ms', 14) | |
83 | |
84 self._AssertResultsEqual(expected, _ActualValues(results)) | |
85 | |
86 def testWithGarbageCollectionEvents(self): | |
87 test_page_helper = V8GCTimesTestPageHelper( | |
88 self.CreateEmptyPageSet()) | |
89 | |
90 test_page_helper.AddEvent('toplevel', 'PostMessage', | |
91 thread_start=0, thread_duration=57, wall_start=5, wall_duration=68) | |
92 test_page_helper.AddEvent('v8', 'V8.GCScavenger', 5, 4) | |
93 test_page_helper.AddEvent('v8', 'V8.GCScavenger', 15, 3) | |
94 test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 23, 4) | |
95 test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 34, 2) | |
96 test_page_helper.AddEvent('v8', 'V8.GCCompactor', 42, 4) | |
97 test_page_helper.AddEvent('v8', 'V8.GCCompactor', 52, 5) | |
98 | |
99 results = test_page_helper.MeasureFakePage() | |
100 expected = _GetEmptyResults() | |
101 expected['duration'] = ('ms', 68) | |
102 expected['cpu_time'] = ('ms', 57) | |
103 expected['v8_gc_incremental_marking'] = ('ms', 6.0) | |
104 expected['v8_gc_incremental_marking_outside_idle'] = ('ms', 6.0) | |
105 expected['v8_gc_scavenger'] = ('ms', 7.0) | |
106 expected['v8_gc_scavenger_outside_idle'] = ('ms', 7.0) | |
107 expected['v8_gc_mark_compactor'] = ('ms', 9.0) | |
108 expected['v8_gc_mark_compactor_outside_idle'] = ('ms', 9.0) | |
109 expected['v8_gc_total'] = ('ms', 22.0) | |
110 expected['v8_gc_total_outside_idle'] = ('ms', 22.0) | |
111 | |
112 self._AssertResultsEqual(expected, _ActualValues(results)) | |
113 | |
114 def testWithIdleTaskGarbageCollectionEvents(self): | |
115 test_page_helper = V8GCTimesTestPageHelper( | |
116 self.CreateEmptyPageSet()) | |
117 | |
118 test_page_helper.AddEvent('toplevel', 'PostMessage', | |
119 thread_start=0, thread_duration=57, wall_start=5, wall_duration=68) | |
120 | |
121 test_page_helper.AddEvent('v8', 'V8.GCScavenger', 5, 4) | |
122 test_page_helper.AddEvent('renderer.scheduler', | |
123 'SingleThreadIdleTaskRunner::RunTask', 15, 4, {'allotted_time_ms': 12}) | |
124 test_page_helper.AddEvent('v8', 'V8.GCScavenger', 15, 3) | |
125 | |
126 test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 23, 4) | |
127 test_page_helper.AddEvent('renderer.scheduler', | |
128 'SingleThreadIdleTaskRunner::RunTask', 34, 3, {'allotted_time_ms': 12}) | |
129 test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 34, 2) | |
130 | |
131 test_page_helper.AddEvent('v8', 'V8.GCCompactor', 42, 4) | |
132 test_page_helper.AddEvent('renderer.scheduler', | |
133 'SingleThreadIdleTaskRunner::RunTask', 52, 6, {'allotted_time_ms': 12}) | |
134 test_page_helper.AddEvent('v8', 'V8.GCCompactor', 52, 5) | |
135 | |
136 results = test_page_helper.MeasureFakePage() | |
137 expected = _GetEmptyResults() | |
138 expected['duration'] = ('ms', 68) | |
139 expected['cpu_time'] = ('ms', 57) | |
140 expected['v8_gc_incremental_marking'] = ('ms', 6.0) | |
141 expected['v8_gc_incremental_marking_outside_idle'] = ('ms', 4.0) | |
142 expected['v8_gc_incremental_marking_percentage_idle'] = ('%', 100 * 2 / 6.0) | |
143 expected['v8_gc_scavenger'] = ('ms', 7.0) | |
144 expected['v8_gc_scavenger_outside_idle'] = ('ms', 4.0) | |
145 expected['v8_gc_scavenger_percentage_idle'] = ('%', 100 * 3 / 7.0) | |
146 expected['v8_gc_mark_compactor'] = ('ms', 9.0) | |
147 expected['v8_gc_mark_compactor_outside_idle'] = ('ms', 4.0) | |
148 expected['v8_gc_mark_compactor_percentage_idle'] = ('%', 100 * 5 / 9.0) | |
149 expected['v8_gc_total'] = ('ms', 22.0) | |
150 expected['v8_gc_total_outside_idle'] = ('ms', 12.0) | |
151 expected['v8_gc_total_percentage_idle'] = ('%', 100 * 10 / 22.0) | |
152 | |
153 self._AssertResultsEqual(expected, _ActualValues(results)) | |
154 | |
155 def testWithIdleTaskOverruns(self): | |
156 test_page_helper = V8GCTimesTestPageHelper( | |
157 self.CreateEmptyPageSet()) | |
158 | |
159 test_page_helper.AddEvent('toplevel', 'PostMessage', | |
160 thread_start=0, thread_duration=80, wall_start=5, wall_duration=92) | |
161 | |
162 test_page_helper.AddEvent('renderer.scheduler', | |
163 'SingleThreadIdleTaskRunner::RunTask', 15, 15, {'allotted_time_ms': 8}) | |
164 test_page_helper.AddEvent('v8', 'V8.GCScavenger', 15, 14) | |
165 | |
166 test_page_helper.AddEvent('renderer.scheduler', | |
167 'SingleThreadIdleTaskRunner::RunTask', 34, 15, {'allotted_time_ms': 6}) | |
168 test_page_helper.AddEvent('v8', 'V8.GCIncrementalMarking', 34, 14) | |
169 | |
170 test_page_helper.AddEvent('renderer.scheduler', | |
171 'SingleThreadIdleTaskRunner::RunTask', 52, 23, {'allotted_time_ms': 9}) | |
172 test_page_helper.AddEvent('v8', 'V8.GCCompactor', 52, 22) | |
173 | |
174 results = test_page_helper.MeasureFakePage() | |
175 expected = _GetEmptyResults() | |
176 expected['duration'] = ('ms', 92) | |
177 expected['cpu_time'] = ('ms', 80) | |
178 expected['v8_gc_incremental_marking'] = ('ms', 14.0) | |
179 expected['v8_gc_incremental_marking_outside_idle'] = ('ms', 8.0) | |
180 expected['v8_gc_incremental_marking_idle_deadline_overrun'] = ('ms', 8.0) | |
181 expected['v8_gc_incremental_marking_percentage_idle'] = \ | |
182 ('%', 100 * 6 / 14.0) | |
183 expected['v8_gc_scavenger'] = ('ms', 14.0) | |
184 expected['v8_gc_scavenger_outside_idle'] = ('ms', 6.0) | |
185 expected['v8_gc_scavenger_idle_deadline_overrun'] = ('ms', 6.0) | |
186 expected['v8_gc_scavenger_percentage_idle'] = ('%', 100 * 8 / 14.0) | |
187 expected['v8_gc_mark_compactor'] = ('ms', 22.0) | |
188 expected['v8_gc_mark_compactor_outside_idle'] = ('ms', 13.0) | |
189 expected['v8_gc_mark_compactor_idle_deadline_overrun'] = ('ms', 13.0) | |
190 expected['v8_gc_mark_compactor_percentage_idle'] = ('%', 100 * 9 / 22.0) | |
191 expected['v8_gc_total'] = ('ms', 50.0) | |
192 expected['v8_gc_total_outside_idle'] = ('ms', 27.0) | |
193 expected['v8_gc_total_idle_deadline_overrun'] = ('ms', 27.0) | |
194 expected['v8_gc_total_percentage_idle'] = ('%', 100 * 23 / 50.0) | |
195 | |
196 self._AssertResultsEqual(expected, _ActualValues(results)) | |
197 | |
198 def testWithIdleTaskWallDurationOverruns(self): | |
199 test_page_helper = V8GCTimesTestPageHelper( | |
200 self.CreateEmptyPageSet()) | |
201 | |
202 test_page_helper.AddEvent('toplevel', 'PostMessage', | |
203 thread_start=0, thread_duration=80, wall_start=5, wall_duration=92) | |
204 | |
205 test_page_helper.AddEvent('renderer.scheduler', | |
206 'SingleThreadIdleTaskRunner::RunTask', 15, 15, {'allotted_time_ms': 8}) | |
207 test_page_helper.AddEvent('v8', 'V8.GCScavenger', | |
208 thread_start=15, thread_duration=4, wall_start=15, wall_duration=14) | |
209 | |
210 results = test_page_helper.MeasureFakePage() | |
211 expected = _GetEmptyResults() | |
212 expected['duration'] = ('ms', 92) | |
213 expected['cpu_time'] = ('ms', 80) | |
214 expected['v8_gc_scavenger'] = ('ms', 4.0) | |
215 expected_outside_idle = 4.0 - (4.0 * 8 / 14) | |
216 expected['v8_gc_scavenger_outside_idle'] = ('ms', expected_outside_idle) | |
217 expected['v8_gc_scavenger_idle_deadline_overrun'] = ('ms', 6.0) | |
218 expected['v8_gc_scavenger_percentage_idle'] = \ | |
219 ('%', 100 * (4.0 - expected_outside_idle) / 4.0) | |
220 expected['v8_gc_total'] = expected['v8_gc_scavenger'] | |
221 expected['v8_gc_total_outside_idle'] = \ | |
222 expected['v8_gc_scavenger_outside_idle'] | |
223 expected['v8_gc_total_idle_deadline_overrun'] = \ | |
224 expected['v8_gc_scavenger_idle_deadline_overrun'] | |
225 expected['v8_gc_total_percentage_idle'] = \ | |
226 expected['v8_gc_scavenger_percentage_idle'] | |
227 | |
228 self._AssertResultsEqual(expected, _ActualValues(results)) | |
229 | |
230 def _AssertResultsEqual(self, expected, actual): | |
231 for key in expected.iterkeys(): | |
232 self.assertIn(key, actual.keys()) | |
233 self.assertEqual(expected[key], actual[key], | |
234 'Result for [' + key + '] - expected ' + str(expected[key]) + | |
235 ' but got ' + str(actual[key])) | |
236 | |
237 | |
238 def _ActualValues(results): | |
239 return dict(list( | |
240 (v.name, (v.units, v.value)) | |
241 for v in results.all_page_specific_values | |
242 )) | |
243 | |
244 | |
245 def _GetEmptyResults(): | |
246 return {'cpu_time': ('ms', 0.0), | |
247 'duration': ('ms', 0.0), | |
248 'v8_gc_incremental_marking': ('ms', 0.0), | |
249 'v8_gc_incremental_marking_idle_deadline_overrun': ('ms', 0.0), | |
250 'v8_gc_incremental_marking_outside_idle': ('ms', 0.0), | |
251 'v8_gc_incremental_marking_percentage_idle': ('%', 0.0), | |
252 'v8_gc_mark_compactor': ('ms', 0.0), | |
253 'v8_gc_mark_compactor_idle_deadline_overrun': ('ms', 0.0), | |
254 'v8_gc_mark_compactor_outside_idle': ('ms', 0.0), | |
255 'v8_gc_mark_compactor_percentage_idle': ('%', 0.0), | |
256 'v8_gc_scavenger': ('ms', 0.0), | |
257 'v8_gc_scavenger_idle_deadline_overrun': ('ms', 0.0), | |
258 'v8_gc_scavenger_outside_idle': ('ms', 0.0), | |
259 'v8_gc_scavenger_percentage_idle': ('%', 0.0), | |
260 'v8_gc_total': ('ms', 0.0), | |
261 'v8_gc_total_idle_deadline_overrun': ('ms', 0.0), | |
262 'v8_gc_total_outside_idle': ('ms', 0.0)} | |
OLD | NEW |