Move StartsWith[ASCII] to base namespace.
[chromium-blink-merge.git] / tools / perf / measurements / oilpan_gc_times_unittest.py
blob87e1bcda9318e49ce384261a3fbd4a08a5558575
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.
5 from measurements import oilpan_gc_times
7 from telemetry.core import util
8 from telemetry.results import page_test_results
9 from telemetry.timeline import model
10 from telemetry.timeline import slice as slice_data
11 from telemetry.unittest_util import options_for_unittests
12 from telemetry.unittest_util import page_test_test_case
13 from telemetry.page import page as page_module
15 util.AddDirToPythonPath(util.GetTelemetryDir(), 'third_party', 'mock')
16 import mock # pylint: disable=import-error
19 class TestOilpanGCTimesPage(page_module.Page):
20 def __init__(self, page_set):
21 super(TestOilpanGCTimesPage, self).__init__(
22 'file://blank.html', page_set, page_set.base_dir)
24 def RunPageInteractions(self, action_runner):
25 with action_runner.CreateGestureInteraction('ScrollAction'):
26 action_runner.ScrollPage()
29 class OilpanGCTimesTestData(object):
30 def __init__(self, thread_name):
31 self._model = model.TimelineModel()
32 self._renderer_process = self._model.GetOrCreateProcess(1)
33 self._renderer_thread = self._renderer_process.GetOrCreateThread(2)
34 self._renderer_thread.name = thread_name
35 self._results = page_test_results.PageTestResults()
37 @property
38 def results(self):
39 return self._results
41 def AddSlice(self, name, timestamp, duration, args):
42 new_slice = slice_data.Slice(
43 None,
44 'category',
45 name,
46 timestamp,
47 duration,
48 timestamp,
49 duration,
50 args)
51 self._renderer_thread.all_slices.append(new_slice)
52 return new_slice
54 def AddAsyncSlice(self, name, timestamp, duration, args):
55 new_slice = slice_data.Slice(
56 None,
57 'category',
58 name,
59 timestamp,
60 duration,
61 timestamp,
62 duration,
63 args)
64 self._renderer_thread.async_slices.append(new_slice)
65 return new_slice
67 def ClearResults(self):
68 self._results = page_test_results.PageTestResults()
70 class OilpanGCTimesTest(page_test_test_case.PageTestTestCase):
71 """Smoke test for Oilpan GC pause time measurements.
73 Runs OilpanGCTimes measurement on some simple pages and verifies
74 that all metrics were added to the results. The test is purely functional,
75 i.e. it only checks if the metrics are present and non-zero.
76 """
77 _KEY_MARK = 'Heap::collectGarbage'
78 _KEY_LAZY_SWEEP = 'ThreadHeap::lazySweepPages'
79 _KEY_COMPLETE_SWEEP = 'ThreadState::completeSweep'
80 _KEY_COALESCE = 'ThreadHeap::coalesce'
81 _KEY_MEASURE = 'BlinkGCTimeMeasurement'
83 def setUp(self):
84 self._options = options_for_unittests.GetCopy()
86 # Disable for accessing private API of _OilpanGCTimesBase.
87 # pylint: disable=protected-access
88 def testForParsingOldFormat(self):
89 def getMetric(results, name):
90 metrics = results.FindAllPageSpecificValuesNamed(name)
91 self.assertEquals(1, len(metrics))
92 return metrics[0].GetBuildbotValue()
94 data = self._GenerateDataForParsingOldFormat()
96 measurement = oilpan_gc_times._OilpanGCTimesBase()
98 tab = mock.MagicMock()
99 with mock.patch(
100 'measurements.oilpan_gc_times.TimelineModel') as MockTimelineModel:
101 MockTimelineModel.return_value = data._model
102 measurement.ValidateAndMeasurePage(None, tab, data.results)
104 results = data.results
105 self.assertEquals(7, len(getMetric(results, 'oilpan_coalesce')))
106 self.assertEquals(3, len(getMetric(results, 'oilpan_precise_mark')))
107 self.assertEquals(3, len(getMetric(results, 'oilpan_precise_lazy_sweep')))
108 self.assertEquals(3, len(getMetric(results,
109 'oilpan_precise_complete_sweep')))
110 self.assertEquals(1, len(getMetric(results, 'oilpan_conservative_mark')))
111 self.assertEquals(1, len(getMetric(results,
112 'oilpan_conservative_lazy_sweep')))
113 self.assertEquals(1, len(getMetric(results,
114 'oilpan_conservative_complete_sweep')))
115 self.assertEquals(2, len(getMetric(results, 'oilpan_forced_mark')))
116 self.assertEquals(2, len(getMetric(results, 'oilpan_forced_lazy_sweep')))
117 self.assertEquals(2, len(getMetric(results,
118 'oilpan_forced_complete_sweep')))
120 # Disable for accessing private API of _OilpanGCTimesBase.
121 # pylint: disable=protected-access
122 def testForParsing(self):
123 def getMetric(results, name):
124 metrics = results.FindAllPageSpecificValuesNamed(name)
125 self.assertEquals(1, len(metrics))
126 return metrics[0].GetBuildbotValue()
128 data = self._GenerateDataForParsing()
130 measurement = oilpan_gc_times._OilpanGCTimesBase()
131 measurement._timeline_model = data._model
132 tab = mock.MagicMock()
133 with mock.patch(
134 'measurements.oilpan_gc_times.TimelineModel') as MockTimelineModel:
135 MockTimelineModel.return_value = data._model
136 measurement.ValidateAndMeasurePage(None, tab, data.results)
138 results = data.results
139 self.assertEquals(8, len(getMetric(results, 'oilpan_coalesce')))
140 self.assertEquals(4, len(getMetric(results, 'oilpan_precise_mark')))
141 self.assertEquals(4, len(getMetric(results, 'oilpan_precise_lazy_sweep')))
142 self.assertEquals(4, len(getMetric(results,
143 'oilpan_precise_complete_sweep')))
144 self.assertEquals(4, len(getMetric(results, 'oilpan_conservative_mark')))
145 self.assertEquals(4, len(getMetric(results,
146 'oilpan_conservative_lazy_sweep')))
147 self.assertEquals(4, len(getMetric(results,
148 'oilpan_conservative_complete_sweep')))
149 self.assertEquals(1, len(getMetric(results, 'oilpan_forced_mark')))
150 self.assertEquals(1, len(getMetric(results, 'oilpan_forced_lazy_sweep')))
151 self.assertEquals(1, len(getMetric(results,
152 'oilpan_forced_complete_sweep')))
153 self.assertEquals(2, len(getMetric(results, 'oilpan_idle_mark')))
154 self.assertEquals(2, len(getMetric(results, 'oilpan_idle_lazy_sweep')))
155 self.assertEquals(2, len(getMetric(results,
156 'oilpan_idle_complete_sweep')))
158 def testForSmoothness(self):
159 ps = self.CreatePageSetFromFileInUnittestDataDir('create_many_objects.html')
160 measurement = oilpan_gc_times.OilpanGCTimesForSmoothness()
161 results = self.RunMeasurement(measurement, ps, options=self._options)
162 self.assertEquals(0, len(results.failures))
164 precise = results.FindAllPageSpecificValuesNamed('oilpan_precise_mark')
165 conservative = results.FindAllPageSpecificValuesNamed(
166 'oilpan_conservative_mark')
167 self.assertLess(0, len(precise) + len(conservative))
169 def testForBlinkPerf(self):
170 ps = self.CreatePageSetFromFileInUnittestDataDir('create_many_objects.html')
171 measurement = oilpan_gc_times.OilpanGCTimesForBlinkPerf()
172 results = self.RunMeasurement(measurement, ps, options=self._options)
173 self.assertEquals(0, len(results.failures))
175 precise = results.FindAllPageSpecificValuesNamed('oilpan_precise_mark')
176 conservative = results.FindAllPageSpecificValuesNamed(
177 'oilpan_conservative_mark')
178 self.assertLess(0, len(precise) + len(conservative))
180 def _GenerateDataForEmptyPageSet(self):
181 page_set = self.CreateEmptyPageSet()
182 page = TestOilpanGCTimesPage(page_set)
183 page_set.AddUserStory(page)
185 data = OilpanGCTimesTestData('CrRendererMain')
186 # Pretend we are about to run the tests to silence lower level asserts.
187 data.results.WillRunPage(page)
189 return data
191 def _GenerateDataForParsingOldFormat(self):
192 data = self._GenerateDataForEmptyPageSet()
193 data.AddSlice(self._KEY_MARK, 1, 1, {'precise': True, 'forced': False})
194 data.AddSlice(self._KEY_LAZY_SWEEP, 2, 2, {})
195 data.AddSlice(self._KEY_COALESCE, 4, 3, {})
196 data.AddSlice(self._KEY_LAZY_SWEEP, 7, 4, {})
197 data.AddSlice(self._KEY_COALESCE, 11, 5, {})
198 data.AddSlice(self._KEY_COMPLETE_SWEEP, 16, 6, {})
199 data.AddSlice(self._KEY_MARK, 22, 7, {'precise': True, 'forced': False})
200 data.AddSlice(self._KEY_LAZY_SWEEP, 29, 8, {})
201 data.AddSlice(self._KEY_COALESCE, 37, 9, {})
202 data.AddSlice(self._KEY_COMPLETE_SWEEP, 46, 10, {})
203 data.AddSlice(self._KEY_MARK, 56, 11, {'precise': False, 'forced': False})
204 data.AddSlice(self._KEY_LAZY_SWEEP, 67, 12, {})
205 data.AddSlice(self._KEY_COALESCE, 79, 13, {})
206 data.AddSlice(self._KEY_COMPLETE_SWEEP, 92, 14, {})
207 data.AddSlice(self._KEY_MARK, 106, 15, {'precise': True, 'forced': False})
208 data.AddSlice(self._KEY_LAZY_SWEEP, 121, 16, {})
209 data.AddSlice(self._KEY_COALESCE, 137, 17, {})
210 data.AddSlice(self._KEY_COMPLETE_SWEEP, 154, 18, {})
211 data.AddSlice(self._KEY_MARK, 172, 19, {'precise': False, 'forced': True})
212 data.AddSlice(self._KEY_COALESCE, 191, 20, {})
213 data.AddSlice(self._KEY_LAZY_SWEEP, 211, 21, {})
214 data.AddSlice(self._KEY_COMPLETE_SWEEP, 232, 22, {})
215 data.AddSlice(self._KEY_MARK, 254, 23, {'precise': True, 'forced': True})
216 data.AddSlice(self._KEY_COALESCE, 277, 24, {})
217 data.AddSlice(self._KEY_LAZY_SWEEP, 301, 25, {})
218 data.AddSlice(self._KEY_COMPLETE_SWEEP, 326, 26, {})
219 return data
221 def _GenerateDataForParsing(self):
222 data = self._GenerateDataForEmptyPageSet()
223 data.AddSlice(self._KEY_MARK, 1, 1,
224 {'lazySweeping': True, 'gcReason': 'ConservativeGC'})
225 data.AddSlice(self._KEY_LAZY_SWEEP, 2, 2, {})
226 data.AddSlice(self._KEY_COALESCE, 4, 3, {})
227 data.AddSlice(self._KEY_LAZY_SWEEP, 7, 4, {})
228 data.AddSlice(self._KEY_COALESCE, 11, 5, {})
229 data.AddSlice(self._KEY_COMPLETE_SWEEP, 16, 6, {})
230 data.AddSlice(self._KEY_MARK, 22, 7,
231 {'lazySweeping': True, 'gcReason': 'PreciseGC'})
232 data.AddSlice(self._KEY_LAZY_SWEEP, 29, 8, {})
233 data.AddSlice(self._KEY_COALESCE, 37, 9, {})
234 data.AddSlice(self._KEY_COMPLETE_SWEEP, 46, 10, {})
235 data.AddSlice(self._KEY_MARK, 56, 11,
236 {'lazySweeping': False, 'gcReason': 'ConservativeGC'})
237 data.AddSlice(self._KEY_LAZY_SWEEP, 67, 12, {})
238 data.AddSlice(self._KEY_COALESCE, 79, 13, {})
239 data.AddSlice(self._KEY_COMPLETE_SWEEP, 92, 14, {})
240 data.AddSlice(self._KEY_MARK, 106, 15,
241 {'lazySweeping': False, 'gcReason': 'PreciseGC'})
242 data.AddSlice(self._KEY_LAZY_SWEEP, 121, 16, {})
243 data.AddSlice(self._KEY_COALESCE, 137, 17, {})
244 data.AddSlice(self._KEY_COMPLETE_SWEEP, 154, 18, {})
245 data.AddSlice(self._KEY_MARK, 172, 19,
246 {'lazySweeping': False, 'gcReason': 'ForcedGCForTesting'})
247 data.AddSlice(self._KEY_COALESCE, 191, 20, {})
248 data.AddSlice(self._KEY_LAZY_SWEEP, 211, 21, {})
249 data.AddSlice(self._KEY_COMPLETE_SWEEP, 232, 22, {})
250 data.AddSlice(self._KEY_MARK, 254, 23,
251 {'lazySweeping': False, 'gcReason': 'IdleGC'})
252 data.AddSlice(self._KEY_COALESCE, 277, 24, {})
253 data.AddSlice(self._KEY_LAZY_SWEEP, 301, 25, {})
254 data.AddSlice(self._KEY_COMPLETE_SWEEP, 326, 26, {})
256 # Following events are covered with 'BlinkGCTimeMeasurement' event.
257 first_measure = data.AddSlice(self._KEY_COALESCE, 352, 27, {})
258 data.AddSlice(self._KEY_MARK, 380, 28,
259 {'lazySweeping': True, 'gcReason': 'ConservativeGC'})
260 data.AddSlice(self._KEY_LAZY_SWEEP, 408, 29, {})
261 data.AddSlice(self._KEY_LAZY_SWEEP, 437, 30, {})
262 data.AddSlice(self._KEY_COMPLETE_SWEEP, 467, 31, {})
263 data.AddSlice(self._KEY_MARK, 498, 32,
264 {'lazySweeping': True, 'gcReason': 'PreciseGC'})
265 data.AddSlice(self._KEY_LAZY_SWEEP, 530, 33, {})
266 data.AddSlice(self._KEY_COMPLETE_SWEEP, 563, 34, {})
267 data.AddSlice(self._KEY_MARK, 597, 35,
268 {'lazySweeping': False, 'gcReason': 'ConservativeGC'})
269 data.AddSlice(self._KEY_LAZY_SWEEP, 632, 36, {})
270 data.AddSlice(self._KEY_COMPLETE_SWEEP, 667, 37, {})
271 data.AddSlice(self._KEY_MARK, 704, 38,
272 {'lazySweeping': False, 'gcReason': 'PreciseGC'})
273 data.AddSlice(self._KEY_LAZY_SWEEP, 742, 39, {})
274 data.AddSlice(self._KEY_COMPLETE_SWEEP, 781, 40, {})
275 data.AddSlice(self._KEY_MARK, 821, 41,
276 {'lazySweeping': False, 'gcReason': 'ForcedGCForTesting'})
277 data.AddSlice(self._KEY_COMPLETE_SWEEP, 862, 42, {})
278 data.AddSlice(self._KEY_MARK, 904, 43,
279 {'lazySweeping': False, 'gcReason': 'IdleGC'})
280 last_measure = data.AddSlice(self._KEY_COMPLETE_SWEEP, 947, 44, {})
282 # Async event
283 async_dur = last_measure.end - first_measure.start
284 data.AddAsyncSlice(self._KEY_MEASURE, first_measure.start, async_dur, {})
286 return data