Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / tools / perf / page_sets / tough_scheduling_cases.py
blob8f28400d1a71c16d6d00099d1ae4c6040dfed0aa
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.
4 from telemetry.page import page as page_module
5 from telemetry.page import shared_page_state
6 from telemetry import story
9 class ToughSchedulingCasesPage(page_module.Page):
11 def __init__(self, url, page_set):
12 super(ToughSchedulingCasesPage, self).__init__(
13 url=url, page_set=page_set, credentials_path='data/credentials.json',
14 shared_page_state_class=shared_page_state.SharedMobilePageState)
15 self.archive_data_file = 'data/tough_scheduling_cases.json'
17 def RunPageInteractions(self, action_runner):
18 with action_runner.CreateGestureInteraction('ScrollAction'):
19 action_runner.ScrollPage()
22 class Page1(ToughSchedulingCasesPage):
24 """Why: Simulate oversubscribed main thread."""
26 def __init__(self, page_set):
27 super(Page1, self).__init__(
28 url='file://tough_scheduling_cases/simple_text_page.html?main_busy',
29 page_set=page_set)
31 self.synthetic_delays = {'cc.BeginMainFrame': {'target_duration': 0.008}}
34 class Page2(ToughSchedulingCasesPage):
36 """Why: Simulate oversubscribed main thread."""
38 def __init__(self, page_set):
39 super(Page2, self).__init__(
40 # pylint: disable=C0301
41 url='file://tough_scheduling_cases/simple_text_page.html?main_very_busy',
42 page_set=page_set)
44 self.synthetic_delays = {'cc.BeginMainFrame': {'target_duration': 0.024}}
47 class Page3(ToughSchedulingCasesPage):
49 """Why: Simulate a page with a a few graphics layers."""
51 def __init__(self, page_set):
52 super(Page3, self).__init__(
53 # pylint: disable=C0301
54 url='file://tough_scheduling_cases/simple_text_page.html?medium_layers',
55 page_set=page_set)
57 self.synthetic_delays = {
58 'cc.DrawAndSwap': {'target_duration': 0.004},
59 'gpu.PresentingFrame': {'target_duration': 0.004},
60 'cc.BeginMainFrame': {'target_duration': 0.004}
64 class Page4(ToughSchedulingCasesPage):
66 """Why: Simulate a page with many graphics layers."""
68 def __init__(self, page_set):
69 super(Page4, self).__init__(
70 # pylint: disable=C0301
71 url='file://tough_scheduling_cases/simple_text_page.html?many_layers',
72 page_set=page_set)
74 self.synthetic_delays = {
75 'cc.DrawAndSwap': {'target_duration': 0.012},
76 'gpu.PresentingFrame': {'target_duration': 0.012},
77 'cc.BeginMainFrame': {'target_duration': 0.012}
81 class Page5(ToughSchedulingCasesPage):
83 """Why: Simulate a page with expensive recording and rasterization."""
85 def __init__(self, page_set):
86 super(Page5, self).__init__(
87 # pylint: disable=C0301
88 url='file://tough_scheduling_cases/simple_text_page.html?medium_raster',
89 page_set=page_set)
91 self.synthetic_delays = {
92 'cc.RasterRequiredForActivation': {'target_duration': 0.004},
93 'cc.BeginMainFrame': {'target_duration': 0.004},
94 'gpu.AsyncTexImage': {'target_duration': 0.004}
98 class Page6(ToughSchedulingCasesPage):
100 """Why: Simulate a page with expensive recording and rasterization."""
102 def __init__(self, page_set):
103 super(Page6, self).__init__(
104 # pylint: disable=C0301
105 url='file://tough_scheduling_cases/simple_text_page.html?heavy_raster',
106 page_set=page_set)
108 self.synthetic_delays = {
109 'cc.RasterRequiredForActivation': {'target_duration': 0.024},
110 'cc.BeginMainFrame': {'target_duration': 0.024},
111 'gpu.AsyncTexImage': {'target_duration': 0.024}
115 class Page7(ToughSchedulingCasesPage):
117 """Why: Medium cost touch handler."""
119 def __init__(self, page_set):
120 super(Page7, self).__init__(
121 # pylint: disable=C0301
122 url='file://tough_scheduling_cases/touch_handler_scrolling.html?medium_handler',
123 page_set=page_set)
125 self.synthetic_delays = {'blink.HandleInputEvent':
126 {'target_duration': 0.008}}
129 class Page8(ToughSchedulingCasesPage):
131 """Why: Slow touch handler."""
133 def __init__(self, page_set):
134 super(Page8, self).__init__(
135 # pylint: disable=C0301
136 url='file://tough_scheduling_cases/touch_handler_scrolling.html?slow_handler',
137 page_set=page_set)
139 self.synthetic_delays = {'blink.HandleInputEvent':
140 {'target_duration': 0.024}}
143 class Page9(ToughSchedulingCasesPage):
145 """Why: Touch handler that often takes a long time."""
147 def __init__(self, page_set):
148 super(Page9, self).__init__(
149 # pylint: disable=C0301
150 url='file://tough_scheduling_cases/touch_handler_scrolling.html?janky_handler',
151 page_set=page_set)
153 self.synthetic_delays = {'blink.HandleInputEvent':
154 {'target_duration': 0.024, 'mode': 'alternating'}
158 class Page10(ToughSchedulingCasesPage):
160 """Why: Touch handler that occasionally takes a long time."""
162 def __init__(self, page_set):
163 super(Page10, self).__init__(
164 # pylint: disable=C0301
165 url='file://tough_scheduling_cases/touch_handler_scrolling.html?occasionally_janky_handler',
166 page_set=page_set)
168 self.synthetic_delays = {'blink.HandleInputEvent':
169 {'target_duration': 0.024, 'mode': 'oneshot'}}
172 class Page11(ToughSchedulingCasesPage):
174 """Why: Super expensive touch handler causes browser to scroll after a
175 timeout."""
177 def __init__(self, page_set):
178 super(Page11, self).__init__(
179 # pylint: disable=C0301
180 url='file://tough_scheduling_cases/touch_handler_scrolling.html?super_slow_handler',
181 page_set=page_set)
183 self.synthetic_delays = {'blink.HandleInputEvent':
184 {'target_duration': 0.2}}
187 class Page12(ToughSchedulingCasesPage):
189 """Why: Super expensive touch handler that only occupies a part of the page.
192 def __init__(self, page_set):
193 super(Page12, self).__init__(
194 url='file://tough_scheduling_cases/div_touch_handler.html',
195 page_set=page_set)
197 self.synthetic_delays = {'blink.HandleInputEvent': {'target_duration': 0.2}}
200 class Page13(ToughSchedulingCasesPage):
202 """Why: Test a moderately heavy requestAnimationFrame handler."""
204 def __init__(self, page_set):
205 super(Page13, self).__init__(
206 url='file://tough_scheduling_cases/raf.html?medium_handler',
207 page_set=page_set)
209 self.synthetic_delays = {
210 'cc.RasterRequiredForActivation': {'target_duration': 0.004},
211 'cc.BeginMainFrame': {'target_duration': 0.004},
212 'gpu.AsyncTexImage': {'target_duration': 0.004}
216 class Page14(ToughSchedulingCasesPage):
218 """Why: Test a moderately heavy requestAnimationFrame handler."""
220 def __init__(self, page_set):
221 super(Page14, self).__init__(
222 url='file://tough_scheduling_cases/raf.html?heavy_handler',
223 page_set=page_set)
225 self.synthetic_delays = {
226 'cc.RasterRequiredForActivation': {'target_duration': 0.024},
227 'cc.BeginMainFrame': {'target_duration': 0.024},
228 'gpu.AsyncTexImage': {'target_duration': 0.024}
232 class Page15(ToughSchedulingCasesPage):
234 """Why: Simulate a heavily GPU bound page."""
236 def __init__(self, page_set):
237 super(Page15, self).__init__(
238 url='file://tough_scheduling_cases/raf.html?gpu_bound',
239 page_set=page_set)
241 self.synthetic_delays = {'gpu.PresentingFrame': {'target_duration': 0.1}}
244 class Page16(ToughSchedulingCasesPage):
246 """Why: Test a requestAnimationFrame handler with a heavy first frame."""
248 def __init__(self, page_set):
249 super(Page16, self).__init__(
250 url='file://tough_scheduling_cases/raf.html?heavy_first_frame',
251 page_set=page_set)
253 self.synthetic_delays = {'cc.BeginMainFrame': {'target_duration': 0.15,
254 'mode': 'oneshot'}}
257 class Page17(ToughSchedulingCasesPage):
259 """Why: Medium stress test for the scheduler."""
261 def __init__(self, page_set):
262 super(Page17, self).__init__(
263 url='file://tough_scheduling_cases/raf_touch_animation.html?medium',
264 page_set=page_set)
266 self.synthetic_delays = {
267 'cc.DrawAndSwap': {'target_duration': 0.004},
268 'cc.BeginMainFrame': {'target_duration': 0.004}
272 class Page18(ToughSchedulingCasesPage):
274 """Why: Heavy stress test for the scheduler."""
276 def __init__(self, page_set):
277 super(Page18, self).__init__(
278 url='file://tough_scheduling_cases/raf_touch_animation.html?heavy',
279 page_set=page_set)
281 self.synthetic_delays = {
282 'cc.DrawAndSwap': {'target_duration': 0.012},
283 'cc.BeginMainFrame': {'target_duration': 0.012}
287 class Page19(ToughSchedulingCasesPage):
289 """Why: Both main and impl thread animating concurrently."""
291 def __init__(self, page_set):
292 super(Page19, self).__init__(
293 url='file://tough_scheduling_cases/split_animation.html',
294 page_set=page_set)
296 def RunPageInteractions(self, action_runner):
297 with action_runner.CreateInteraction('SplitAnimation'):
298 action_runner.Wait(3)
301 class Page20(ToughSchedulingCasesPage):
303 """Why: Simple JS touch dragging."""
305 def __init__(self, page_set):
306 super(Page20, self).__init__(
307 url='file://tough_scheduling_cases/simple_touch_drag.html',
308 page_set=page_set)
310 def RunPageInteractions(self, action_runner):
311 with action_runner.CreateGestureInteraction('ScrollAction'):
312 action_runner.ScrollElement(
313 selector='#card',
314 use_touch=True,
315 direction='up',
316 speed_in_pixels_per_second=150,
317 distance=400)
320 class EmptyTouchHandlerPage(ToughSchedulingCasesPage):
322 """Why: Scrolling on a page with a touch handler that consumes no events but
323 may be slow."""
325 def __init__(self, name, desktop, slow_handler, bounce, page_set):
326 super(EmptyTouchHandlerPage, self).__init__(
327 url='file://tough_scheduling_cases/empty_touch_handler' +
328 ('_desktop' if desktop else '') + '.html?' + name,
329 page_set=page_set)
331 if slow_handler:
332 self.synthetic_delays = {
333 'blink.HandleInputEvent': {'target_duration': 0.2}
336 self.bounce = bounce
338 def RunPageInteractions(self, action_runner):
339 if self.bounce:
340 with action_runner.CreateGestureInteraction('ScrollBounceAction'):
341 action_runner.ScrollBouncePage()
342 else:
343 with action_runner.CreateGestureInteraction('ScrollAction'):
344 # Speed and distance are tuned to run exactly as long as a scroll
345 # bounce.
346 action_runner.ScrollPage(use_touch=True, speed_in_pixels_per_second=400,
347 distance=2100)
350 class SynchronizedScrollOffsetPage(ToughSchedulingCasesPage):
352 """Why: For measuring the latency of scroll-synchronized effects."""
354 def __init__(self, page_set):
355 super(SynchronizedScrollOffsetPage, self).__init__(
356 url='file://tough_scheduling_cases/sync_scroll_offset.html',
357 page_set=page_set)
359 def RunPageInteractions(self, action_runner):
360 with action_runner.CreateGestureInteraction('ScrollBounceAction'):
361 action_runner.ScrollBouncePage()
364 class SecondBatchJsPage(ToughSchedulingCasesPage):
366 """Why: For testing dynamically loading a large batch of Javascript and
367 running a part of it in response to user input.
370 def __init__(self, page_set, variant='medium'):
371 super(SecondBatchJsPage, self).__init__(
372 url='file://tough_scheduling_cases/second_batch_js.html?%s' % variant,
373 page_set=page_set)
375 def RunPageInteractions(self, action_runner):
376 # Do a dummy tap to warm up the synthetic tap code path.
377 action_runner.TapElement(selector='div[id="spinner"]')
378 # Begin the action immediately because we want the page to update smoothly
379 # even while resources are being loaded.
380 action_runner.WaitForJavaScriptCondition('window.__ready !== undefined')
382 with action_runner.CreateGestureInteraction('LoadAction'):
383 action_runner.ExecuteJavaScript('kickOffLoading()')
384 action_runner.WaitForJavaScriptCondition('window.__ready')
385 # Click one second after the resources have finished loading.
386 action_runner.Wait(1)
387 action_runner.TapElement(selector='input[id="run"]')
388 # Wait for the test to complete.
389 action_runner.WaitForJavaScriptCondition('window.__finished')
392 class ToughSchedulingCasesPageSet(story.StorySet):
394 """Tough scheduler latency test cases."""
396 def __init__(self):
397 super(ToughSchedulingCasesPageSet, self).__init__(
398 archive_data_file='data/tough_scheduling_cases.json',
399 cloud_storage_bucket=story.INTERNAL_BUCKET)
401 # Why: Simple scrolling baseline
402 self.AddStory(ToughSchedulingCasesPage(
403 'file://tough_scheduling_cases/simple_text_page.html',
404 self))
405 self.AddStory(Page1(self))
406 self.AddStory(Page2(self))
407 self.AddStory(Page3(self))
408 self.AddStory(Page4(self))
409 # Disabled until crbug.com/413829 is fixed.
410 # self.AddStory(Page5(self))
411 # Disabled because of crbug.com/413829 and flakiness crbug.com/368532
412 # self.AddStory(Page6(self))
413 # Why: Touch handler scrolling baseline
414 self.AddStory(ToughSchedulingCasesPage(
415 'file://tough_scheduling_cases/touch_handler_scrolling.html',
416 self))
417 self.AddStory(Page7(self))
418 self.AddStory(Page8(self))
419 self.AddStory(Page9(self))
420 self.AddStory(Page10(self))
421 self.AddStory(Page11(self))
422 self.AddStory(Page12(self))
423 # Why: requestAnimationFrame scrolling baseline
424 self.AddStory(ToughSchedulingCasesPage(
425 'file://tough_scheduling_cases/raf.html',
426 self))
427 # Why: Test canvas blocking behavior
428 self.AddStory(ToughSchedulingCasesPage(
429 'file://tough_scheduling_cases/raf_canvas.html',
430 self))
431 # Disabled until crbug.com/413829 is fixed.
432 # self.AddStory(Page13(self))
433 # Disabled because of crbug.com/413829 and flakiness crbug.com/368532
434 # self.AddStory(Page14(self))
435 self.AddStory(Page15(self))
436 self.AddStory(Page16(self))
437 # Why: Test a requestAnimationFrame handler with concurrent CSS animation
438 self.AddStory(ToughSchedulingCasesPage(
439 'file://tough_scheduling_cases/raf_animation.html',
440 self))
441 # Why: Stress test for the scheduler
442 self.AddStory(ToughSchedulingCasesPage(
443 'file://tough_scheduling_cases/raf_touch_animation.html',
444 self))
445 self.AddStory(Page17(self))
446 self.AddStory(Page18(self))
447 self.AddStory(Page19(self))
448 self.AddStory(Page20(self))
449 # Why: Baseline for scrolling in the presence of a no-op touch handler
450 self.AddStory(EmptyTouchHandlerPage(
451 name='baseline',
452 desktop=False,
453 slow_handler=False,
454 bounce=False,
455 page_set=self))
456 # Why: Slow handler blocks scroll start
457 self.AddStory(EmptyTouchHandlerPage(
458 name='slow_handler',
459 desktop=False,
460 slow_handler=True,
461 bounce=False,
462 page_set=self))
463 # Why: Slow handler blocks scroll start until touch ACK timeout
464 self.AddStory(EmptyTouchHandlerPage(
465 name='desktop_slow_handler',
466 desktop=True,
467 slow_handler=True,
468 bounce=False,
469 page_set=self))
470 # Why: Scroll bounce showing repeated transitions between scrolling and
471 # sending synchronous touchmove events. Should be nearly as fast as
472 # scroll baseline.
473 self.AddStory(EmptyTouchHandlerPage(
474 name='bounce',
475 desktop=False,
476 slow_handler=False,
477 bounce=True,
478 page_set=self))
479 # Why: Scroll bounce with slow handler, repeated blocking.
480 self.AddStory(EmptyTouchHandlerPage(
481 name='bounce_slow_handler',
482 desktop=False,
483 slow_handler=True,
484 bounce=True,
485 page_set=self))
486 # Why: Scroll bounce with slow handler on desktop, blocks only once until
487 # ACK timeout.
488 self.AddStory(EmptyTouchHandlerPage(
489 name='bounce_desktop_slow_handler',
490 desktop=True,
491 slow_handler=True,
492 bounce=True,
493 page_set=self))
494 # Why: For measuring the latency of scroll-synchronized effects.
495 self.AddStory(SynchronizedScrollOffsetPage(page_set=self))
496 # Why: Test loading a large amount of Javascript.
497 self.AddStory(SecondBatchJsPage(page_set=self, variant='light'))
498 self.AddStory(SecondBatchJsPage(page_set=self, variant='medium'))
499 self.AddStory(SecondBatchJsPage(page_set=self, variant='heavy'))