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
.results
import page_test_results
8 from telemetry
.timeline
import model
9 from telemetry
.timeline
import slice as slice_data
10 from telemetry
.timeline
.event
import TimelineEvent
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
16 class TestOilpanGCTimesPage(page_module
.Page
):
17 def __init__(self
, page_set
):
18 super(TestOilpanGCTimesPage
, self
).__init
__(
19 'file://blank.html', page_set
, page_set
.base_dir
)
21 def RunPageInteractions(self
, action_runner
):
22 interaction
= action_runner
.BeginGestureInteraction('ScrollAction')
23 action_runner
.ScrollPage()
27 class OilpanGCTimesTestData(object):
28 def __init__(self
, thread_name
):
29 self
._model
= model
.TimelineModel()
30 self
._renderer
_process
= self
._model
.GetOrCreateProcess(1)
31 self
._renderer
_thread
= self
._renderer
_process
.GetOrCreateThread(2)
32 self
._renderer
_thread
.name
= thread_name
33 self
._results
= page_test_results
.PageTestResults()
39 def AddSlice(self
, name
, timestamp
, duration
, args
):
40 new_slice
= slice_data
.Slice(
49 self
._renderer
_thread
.all_slices
.append(new_slice
)
52 def AddAsyncSlice(self
, name
, timestamp
, duration
, args
):
53 new_slice
= slice_data
.Slice(
62 self
._renderer
_thread
.async_slices
.append(new_slice
)
65 def ClearResults(self
):
66 self
._results
= page_test_results
.PageTestResults()
69 class OilpanGCTimesTest(page_test_test_case
.PageTestTestCase
):
70 """Smoke test for Oilpan GC pause time measurements.
72 Runs OilpanGCTimes measurement on some simple pages and verifies
73 that all metrics were added to the results. The test is purely functional,
74 i.e. it only checks if the metrics are present and non-zero.
76 _KEY_MARK
= 'Heap::collectGarbage'
77 _KEY_LAZY_SWEEP
= 'ThreadHeap::lazySweepPages'
78 _KEY_COMPLETE_SWEEP
= 'ThreadState::completeSweep'
79 _KEY_COALESCE
= 'ThreadHeap::coalesce'
80 _KEY_MEASURE
= 'BlinkGCTimeMeasurement'
83 self
._options
= options_for_unittests
.GetCopy()
85 def testForParsingOldFormat(self
):
86 def getMetric(results
, name
):
87 metrics
= results
.FindAllPageSpecificValuesNamed(name
)
88 self
.assertEquals(1, len(metrics
))
89 return metrics
[0].GetBuildbotValue()
91 data
= self
._GenerateDataForParsingOldFormat
()
93 measurement
= oilpan_gc_times
._OilpanGCTimesBase
()
94 measurement
._renderer
_process
= data
._renderer
_process
95 measurement
._timeline
_model
= data
._model
96 measurement
.ValidateAndMeasurePage(None, None, data
.results
)
98 results
= data
.results
99 self
.assertEquals(7, len(getMetric(results
, 'oilpan_coalesce')))
100 self
.assertEquals(3, len(getMetric(results
, 'oilpan_precise_mark')))
101 self
.assertEquals(3, len(getMetric(results
, 'oilpan_precise_lazy_sweep')))
102 self
.assertEquals(3, len(getMetric(results
,
103 'oilpan_precise_complete_sweep')))
104 self
.assertEquals(1, len(getMetric(results
, 'oilpan_conservative_mark')))
105 self
.assertEquals(1, len(getMetric(results
,
106 'oilpan_conservative_lazy_sweep')))
107 self
.assertEquals(1, len(getMetric(results
,
108 'oilpan_conservative_complete_sweep')))
109 self
.assertEquals(2, len(getMetric(results
, 'oilpan_forced_mark')))
110 self
.assertEquals(2, len(getMetric(results
, 'oilpan_forced_lazy_sweep')))
111 self
.assertEquals(2, len(getMetric(results
,
112 'oilpan_forced_complete_sweep')))
114 def testForParsing(self
):
115 def getMetric(results
, name
):
116 metrics
= results
.FindAllPageSpecificValuesNamed(name
)
117 self
.assertEquals(1, len(metrics
))
118 return metrics
[0].GetBuildbotValue()
120 data
= self
._GenerateDataForParsing
()
122 measurement
= oilpan_gc_times
._OilpanGCTimesBase
()
123 measurement
._renderer
_process
= data
._renderer
_process
124 measurement
._timeline
_model
= data
._model
125 measurement
.ValidateAndMeasurePage(None, None, data
.results
)
127 results
= data
.results
128 self
.assertEquals(8, len(getMetric(results
, 'oilpan_coalesce')))
129 self
.assertEquals(4, len(getMetric(results
, 'oilpan_precise_mark')))
130 self
.assertEquals(4, len(getMetric(results
, 'oilpan_precise_lazy_sweep')))
131 self
.assertEquals(4, len(getMetric(results
,
132 'oilpan_precise_complete_sweep')))
133 self
.assertEquals(4, len(getMetric(results
, 'oilpan_conservative_mark')))
134 self
.assertEquals(4, len(getMetric(results
,
135 'oilpan_conservative_lazy_sweep')))
136 self
.assertEquals(4, len(getMetric(results
,
137 'oilpan_conservative_complete_sweep')))
138 self
.assertEquals(1, len(getMetric(results
, 'oilpan_forced_mark')))
139 self
.assertEquals(1, len(getMetric(results
, 'oilpan_forced_lazy_sweep')))
140 self
.assertEquals(1, len(getMetric(results
,
141 'oilpan_forced_complete_sweep')))
142 self
.assertEquals(2, len(getMetric(results
, 'oilpan_idle_mark')))
143 self
.assertEquals(2, len(getMetric(results
, 'oilpan_idle_lazy_sweep')))
144 self
.assertEquals(2, len(getMetric(results
,
145 'oilpan_idle_complete_sweep')))
147 def testForSmoothness(self
):
148 ps
= self
.CreatePageSetFromFileInUnittestDataDir('create_many_objects.html')
149 measurement
= oilpan_gc_times
.OilpanGCTimesForSmoothness()
150 results
= self
.RunMeasurement(measurement
, ps
, options
=self
._options
)
151 self
.assertEquals(0, len(results
.failures
))
153 precise
= results
.FindAllPageSpecificValuesNamed('oilpan_precise_mark')
154 conservative
= results
.FindAllPageSpecificValuesNamed(
155 'oilpan_conservative_mark')
156 self
.assertLess(0, len(precise
) + len(conservative
))
158 def testForBlinkPerf(self
):
159 ps
= self
.CreatePageSetFromFileInUnittestDataDir('create_many_objects.html')
160 measurement
= oilpan_gc_times
.OilpanGCTimesForBlinkPerf()
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 _GenerateDataForEmptyPageSet(self
):
170 page_set
= self
.CreateEmptyPageSet()
171 page
= TestOilpanGCTimesPage(page_set
)
172 page_set
.AddUserStory(page
)
174 data
= OilpanGCTimesTestData('CrRendererMain')
175 # Pretend we are about to run the tests to silence lower level asserts.
176 data
.results
.WillRunPage(page
)
180 def _GenerateDataForParsingOldFormat(self
):
181 data
= self
._GenerateDataForEmptyPageSet
()
182 data
.AddSlice(self
._KEY
_MARK
, 1, 1, {'precise': True, 'forced': False})
183 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 2, 2, {})
184 data
.AddSlice(self
._KEY
_COALESCE
, 4, 3, {})
185 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 7, 4, {})
186 data
.AddSlice(self
._KEY
_COALESCE
, 11, 5, {})
187 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 16, 6, {})
188 data
.AddSlice(self
._KEY
_MARK
, 22, 7, {'precise': True, 'forced': False})
189 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 29, 8, {})
190 data
.AddSlice(self
._KEY
_COALESCE
, 37, 9, {})
191 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 46, 10, {})
192 data
.AddSlice(self
._KEY
_MARK
, 56, 11, {'precise': False, 'forced': False})
193 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 67, 12, {})
194 data
.AddSlice(self
._KEY
_COALESCE
, 79, 13, {})
195 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 92, 14, {})
196 data
.AddSlice(self
._KEY
_MARK
, 106, 15, {'precise': True, 'forced': False})
197 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 121, 16, {})
198 data
.AddSlice(self
._KEY
_COALESCE
, 137, 17, {})
199 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 154, 18, {})
200 data
.AddSlice(self
._KEY
_MARK
, 172, 19, {'precise': False, 'forced': True})
201 data
.AddSlice(self
._KEY
_COALESCE
, 191, 20, {})
202 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 211, 21, {})
203 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 232, 22, {})
204 data
.AddSlice(self
._KEY
_MARK
, 254, 23, {'precise': True, 'forced': True})
205 data
.AddSlice(self
._KEY
_COALESCE
, 277, 24, {})
206 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 301, 25, {})
207 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 326, 26, {})
210 def _GenerateDataForParsing(self
):
211 data
= self
._GenerateDataForEmptyPageSet
()
212 data
.AddSlice(self
._KEY
_MARK
, 1, 1,
213 {'lazySweeping': True, 'gcReason': 'ConservativeGC'})
214 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 2, 2, {})
215 data
.AddSlice(self
._KEY
_COALESCE
, 4, 3, {})
216 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 7, 4, {})
217 data
.AddSlice(self
._KEY
_COALESCE
, 11, 5, {})
218 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 16, 6, {})
219 data
.AddSlice(self
._KEY
_MARK
, 22, 7,
220 {'lazySweeping': True, 'gcReason': 'PreciseGC'})
221 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 29, 8, {})
222 data
.AddSlice(self
._KEY
_COALESCE
, 37, 9, {})
223 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 46, 10, {})
224 data
.AddSlice(self
._KEY
_MARK
, 56, 11,
225 {'lazySweeping': False, 'gcReason': 'ConservativeGC'})
226 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 67, 12, {})
227 data
.AddSlice(self
._KEY
_COALESCE
, 79, 13, {})
228 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 92, 14, {})
229 data
.AddSlice(self
._KEY
_MARK
, 106, 15,
230 {'lazySweeping': False, 'gcReason': 'PreciseGC'})
231 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 121, 16, {})
232 data
.AddSlice(self
._KEY
_COALESCE
, 137, 17, {})
233 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 154, 18, {})
234 data
.AddSlice(self
._KEY
_MARK
, 172, 19,
235 {'lazySweeping': False, 'gcReason': 'ForcedGCForTesting'})
236 data
.AddSlice(self
._KEY
_COALESCE
, 191, 20, {})
237 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 211, 21, {})
238 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 232, 22, {})
239 data
.AddSlice(self
._KEY
_MARK
, 254, 23,
240 {'lazySweeping': False, 'gcReason': 'IdleGC'})
241 data
.AddSlice(self
._KEY
_COALESCE
, 277, 24, {})
242 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 301, 25, {})
243 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 326, 26, {})
245 # Following events are covered with 'BlinkGCTimeMeasurement' event.
246 first_measure
= data
.AddSlice(self
._KEY
_COALESCE
, 352, 27, {})
247 data
.AddSlice(self
._KEY
_MARK
, 380, 28,
248 {'lazySweeping': True, 'gcReason': 'ConservativeGC'})
249 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 408, 29, {})
250 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 437, 30, {})
251 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 467, 31, {})
252 data
.AddSlice(self
._KEY
_MARK
, 498, 32,
253 {'lazySweeping': True, 'gcReason': 'PreciseGC'})
254 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 530, 33, {})
255 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 563, 34, {})
256 data
.AddSlice(self
._KEY
_MARK
, 597, 35,
257 {'lazySweeping': False, 'gcReason': 'ConservativeGC'})
258 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 632, 36, {})
259 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 667, 37, {})
260 data
.AddSlice(self
._KEY
_MARK
, 704, 38,
261 {'lazySweeping': False, 'gcReason': 'PreciseGC'})
262 data
.AddSlice(self
._KEY
_LAZY
_SWEEP
, 742, 39, {})
263 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 781, 40, {})
264 data
.AddSlice(self
._KEY
_MARK
, 821, 41,
265 {'lazySweeping': False, 'gcReason': 'ForcedGCForTesting'})
266 data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 862, 42, {})
267 data
.AddSlice(self
._KEY
_MARK
, 904, 43,
268 {'lazySweeping': False, 'gcReason': 'IdleGC'})
269 last_measure
= data
.AddSlice(self
._KEY
_COMPLETE
_SWEEP
, 947, 44, {})
272 async_dur
= last_measure
.end
- first_measure
.start
273 data
.AddAsyncSlice(self
._KEY
_MEASURE
, first_measure
.start
, async_dur
, {})