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 page_set as page_set_module 6 7 8 class ToughSchedulingCasesPage(page_module.Page): 9 10 def __init__(self, url, page_set): 11 super(ToughSchedulingCasesPage, self).__init__(url=url, page_set=page_set) 12 self.credentials_path = 'data/credentials.json' 13 self.user_agent_type = 'mobile' 14 self.archive_data_file = 'data/tough_scheduling_cases.json' 15 16 def RunSmoothness(self, action_runner): 17 interaction = action_runner.BeginGestureInteraction( 18 'ScrollAction', is_smooth=True) 19 action_runner.ScrollPage() 20 interaction.End() 21 22 23 class Page1(ToughSchedulingCasesPage): 24 25 """ Why: Simulate oversubscribed main thread """ 26 27 def __init__(self, page_set): 28 super(Page1, self).__init__( 29 url='file://tough_scheduling_cases/simple_text_page.html?main_busy', 30 page_set=page_set) 31 32 self.synthetic_delays = {'cc.BeginMainFrame': {'target_duration': 0.008}} 33 34 35 class Page2(ToughSchedulingCasesPage): 36 37 """ Why: Simulate oversubscribed main thread """ 38 39 def __init__(self, page_set): 40 super(Page2, self).__init__( 41 # pylint: disable=C0301 42 url='file://tough_scheduling_cases/simple_text_page.html?main_very_busy', 43 page_set=page_set) 44 45 self.synthetic_delays = {'cc.BeginMainFrame': {'target_duration': 0.024}} 46 47 48 class Page3(ToughSchedulingCasesPage): 49 50 """ Why: Simulate a page with a a few graphics layers """ 51 52 def __init__(self, page_set): 53 super(Page3, self).__init__( 54 # pylint: disable=C0301 55 url='file://tough_scheduling_cases/simple_text_page.html?medium_layers', 56 page_set=page_set) 57 58 self.synthetic_delays = { 59 'cc.DrawAndSwap': {'target_duration': 0.004}, 60 'gpu.PresentingFrame': {'target_duration': 0.004}, 61 'cc.BeginMainFrame': {'target_duration': 0.004} 62 } 63 64 65 class Page4(ToughSchedulingCasesPage): 66 67 """ Why: Simulate a page with many graphics layers """ 68 69 def __init__(self, page_set): 70 super(Page4, self).__init__( 71 # pylint: disable=C0301 72 url='file://tough_scheduling_cases/simple_text_page.html?many_layers', 73 page_set=page_set) 74 75 self.synthetic_delays = { 76 'cc.DrawAndSwap': {'target_duration': 0.012}, 77 'gpu.PresentingFrame': {'target_duration': 0.012}, 78 'cc.BeginMainFrame': {'target_duration': 0.012} 79 } 80 81 82 class Page5(ToughSchedulingCasesPage): 83 84 """ Why: Simulate a page with expensive recording and rasterization """ 85 86 def __init__(self, page_set): 87 super(Page5, self).__init__( 88 # pylint: disable=C0301 89 url='file://tough_scheduling_cases/simple_text_page.html?medium_raster', 90 page_set=page_set) 91 92 self.synthetic_delays = { 93 'cc.RasterRequiredForActivation': {'target_duration': 0.004}, 94 'cc.BeginMainFrame': {'target_duration': 0.004}, 95 'gpu.AsyncTexImage': {'target_duration': 0.004} 96 } 97 98 99 class Page6(ToughSchedulingCasesPage): 100 101 """ Why: Simulate a page with expensive recording and rasterization """ 102 103 def __init__(self, page_set): 104 super(Page6, self).__init__( 105 # pylint: disable=C0301 106 url='file://tough_scheduling_cases/simple_text_page.html?heavy_raster', 107 page_set=page_set) 108 109 self.synthetic_delays = { 110 'cc.RasterRequiredForActivation': {'target_duration': 0.024}, 111 'cc.BeginMainFrame': {'target_duration': 0.024}, 112 'gpu.AsyncTexImage': {'target_duration': 0.024} 113 } 114 115 116 class Page7(ToughSchedulingCasesPage): 117 118 """ Why: Medium cost touch handler """ 119 120 def __init__(self, page_set): 121 super(Page7, self).__init__( 122 # pylint: disable=C0301 123 url='file://tough_scheduling_cases/touch_handler_scrolling.html?medium_handler', 124 page_set=page_set) 125 126 self.synthetic_delays = {'blink.HandleInputEvent': 127 {'target_duration': 0.008}} 128 129 130 class Page8(ToughSchedulingCasesPage): 131 132 """ Why: Slow touch handler """ 133 134 def __init__(self, page_set): 135 super(Page8, self).__init__( 136 # pylint: disable=C0301 137 url='file://tough_scheduling_cases/touch_handler_scrolling.html?slow_handler', 138 page_set=page_set) 139 140 self.synthetic_delays = {'blink.HandleInputEvent': 141 {'target_duration': 0.024}} 142 143 144 class Page9(ToughSchedulingCasesPage): 145 146 """ Why: Touch handler that often takes a long time """ 147 148 def __init__(self, page_set): 149 super(Page9, self).__init__( 150 # pylint: disable=C0301 151 url='file://tough_scheduling_cases/touch_handler_scrolling.html?janky_handler', 152 page_set=page_set) 153 154 self.synthetic_delays = {'blink.HandleInputEvent': 155 {'target_duration': 0.024, 'mode': 'alternating'} 156 } 157 158 159 class Page10(ToughSchedulingCasesPage): 160 161 """ Why: Touch handler that occasionally takes a long time """ 162 163 def __init__(self, page_set): 164 super(Page10, self).__init__( 165 # pylint: disable=C0301 166 url='file://tough_scheduling_cases/touch_handler_scrolling.html?occasionally_janky_handler', 167 page_set=page_set) 168 169 self.synthetic_delays = {'blink.HandleInputEvent': 170 {'target_duration': 0.024, 'mode': 'oneshot'}} 171 172 173 class Page11(ToughSchedulingCasesPage): 174 175 """ Why: Super expensive touch handler causes browser to scroll after a 176 timeout. 177 """ 178 179 def __init__(self, page_set): 180 super(Page11, self).__init__( 181 # pylint: disable=C0301 182 url='file://tough_scheduling_cases/touch_handler_scrolling.html?super_slow_handler', 183 page_set=page_set) 184 185 self.synthetic_delays = {'blink.HandleInputEvent': 186 {'target_duration': 0.2}} 187 188 189 class Page12(ToughSchedulingCasesPage): 190 191 """ Why: Super expensive touch handler that only occupies a part of the page. 192 """ 193 194 def __init__(self, page_set): 195 super(Page12, self).__init__( 196 url='file://tough_scheduling_cases/div_touch_handler.html', 197 page_set=page_set) 198 199 self.synthetic_delays = {'blink.HandleInputEvent': {'target_duration': 0.2}} 200 201 202 class Page13(ToughSchedulingCasesPage): 203 204 """ Why: Test a moderately heavy requestAnimationFrame handler """ 205 206 def __init__(self, page_set): 207 super(Page13, self).__init__( 208 url='file://tough_scheduling_cases/raf.html?medium_handler', 209 page_set=page_set) 210 211 self.synthetic_delays = { 212 'cc.RasterRequiredForActivation': {'target_duration': 0.004}, 213 'cc.BeginMainFrame': {'target_duration': 0.004}, 214 'gpu.AsyncTexImage': {'target_duration': 0.004} 215 } 216 217 218 class Page14(ToughSchedulingCasesPage): 219 220 """ Why: Test a moderately heavy requestAnimationFrame handler """ 221 222 def __init__(self, page_set): 223 super(Page14, self).__init__( 224 url='file://tough_scheduling_cases/raf.html?heavy_handler', 225 page_set=page_set) 226 227 self.synthetic_delays = { 228 'cc.RasterRequiredForActivation': {'target_duration': 0.024}, 229 'cc.BeginMainFrame': {'target_duration': 0.024}, 230 'gpu.AsyncTexImage': {'target_duration': 0.024} 231 } 232 233 234 class Page15(ToughSchedulingCasesPage): 235 236 """ Why: Simulate a heavily GPU bound page """ 237 238 def __init__(self, page_set): 239 super(Page15, self).__init__( 240 url='file://tough_scheduling_cases/raf.html?gpu_bound', 241 page_set=page_set) 242 243 self.synthetic_delays = {'gpu.PresentingFrame': {'target_duration': 0.1}} 244 245 246 class Page16(ToughSchedulingCasesPage): 247 248 """ Why: Test a requestAnimationFrame handler with a heavy first frame """ 249 250 def __init__(self, page_set): 251 super(Page16, self).__init__( 252 url='file://tough_scheduling_cases/raf.html?heavy_first_frame', 253 page_set=page_set) 254 255 self.synthetic_delays = {'cc.BeginMainFrame': {'target_duration': 0.15, 256 'mode': 'oneshot'}} 257 258 259 class Page17(ToughSchedulingCasesPage): 260 261 """ Why: Medium stress test for the scheduler """ 262 263 def __init__(self, page_set): 264 super(Page17, self).__init__( 265 url='file://tough_scheduling_cases/raf_touch_animation.html?medium', 266 page_set=page_set) 267 268 self.synthetic_delays = { 269 'cc.DrawAndSwap': {'target_duration': 0.004}, 270 'cc.BeginMainFrame': {'target_duration': 0.004} 271 } 272 273 274 class Page18(ToughSchedulingCasesPage): 275 276 """ Why: Heavy stress test for the scheduler """ 277 278 def __init__(self, page_set): 279 super(Page18, self).__init__( 280 url='file://tough_scheduling_cases/raf_touch_animation.html?heavy', 281 page_set=page_set) 282 283 self.synthetic_delays = { 284 'cc.DrawAndSwap': {'target_duration': 0.012}, 285 'cc.BeginMainFrame': {'target_duration': 0.012} 286 } 287 288 289 class Page19(ToughSchedulingCasesPage): 290 291 """ Why: Both main and impl thread animating concurrently """ 292 293 def __init__(self, page_set): 294 super(Page19, self).__init__( 295 url='file://tough_scheduling_cases/split_animation.html', 296 page_set=page_set) 297 298 def RunSmoothness(self, action_runner): 299 action_runner.Wait(3) 300 301 302 class Page20(ToughSchedulingCasesPage): 303 304 """ Why: Simple JS touch dragging """ 305 306 def __init__(self, page_set): 307 super(Page20, self).__init__( 308 url='file://tough_scheduling_cases/simple_touch_drag.html', 309 page_set=page_set) 310 311 def RunSmoothness(self, action_runner): 312 interaction = action_runner.BeginGestureInteraction( 313 'ScrollAction', is_smooth=True) 314 action_runner.ScrollElement( 315 selector='#card', 316 use_touch=True, 317 direction='up', 318 speed_in_pixels_per_second=150, 319 distance=400) 320 interaction.End() 321 322 323 class EmptyTouchHandlerPage(ToughSchedulingCasesPage): 324 325 """ Why: Scrolling on a page with a touch handler that consumes no events but 326 may be slow """ 327 328 def __init__(self, name, desktop, slow_handler, bounce, page_set): 329 super(EmptyTouchHandlerPage, self).__init__( 330 url='file://tough_scheduling_cases/empty_touch_handler' + 331 ('_desktop' if desktop else '') + '.html?' + name, 332 page_set=page_set) 333 334 if slow_handler: 335 self.synthetic_delays = { 336 'blink.HandleInputEvent': {'target_duration': 0.2} 337 } 338 339 self.bounce = bounce 340 341 def RunSmoothness(self, action_runner): 342 if self.bounce: 343 interaction = action_runner.BeginGestureInteraction( 344 'ScrollBounceAction', is_smooth=True) 345 action_runner.ScrollBouncePage() 346 interaction.End() 347 else: 348 interaction = action_runner.BeginGestureInteraction( 349 'ScrollAction', is_smooth=True) 350 # Speed and distance are tuned to run exactly as long as a scroll 351 # bounce. 352 action_runner.ScrollPage(use_touch=True, speed_in_pixels_per_second=400, 353 distance=2100) 354 interaction.End() 355 356 357 class SynchronizedScrollOffsetPage(ToughSchedulingCasesPage): 358 359 """Why: For measuring the latency of scroll-synchronized effects.""" 360 361 def __init__(self, page_set): 362 super(SynchronizedScrollOffsetPage, self).__init__( 363 url='file://tough_scheduling_cases/sync_scroll_offset.html', 364 page_set=page_set) 365 366 def RunSmoothness(self, action_runner): 367 interaction = action_runner.BeginGestureInteraction( 368 'ScrollBounceAction', is_smooth=True) 369 action_runner.ScrollBouncePage() 370 interaction.End() 371 372 373 class ToughSchedulingCasesPageSet(page_set_module.PageSet): 374 375 """ Tough scheduler latency test cases """ 376 377 def __init__(self): 378 super(ToughSchedulingCasesPageSet, self).__init__( 379 credentials_path='data/credentials.json', 380 user_agent_type='mobile', 381 archive_data_file='data/tough_scheduling_cases.json', 382 bucket=page_set_module.INTERNAL_BUCKET) 383 384 # Why: Simple scrolling baseline 385 self.AddPage(ToughSchedulingCasesPage( 386 'file://tough_scheduling_cases/simple_text_page.html', 387 self)) 388 self.AddPage(Page1(self)) 389 self.AddPage(Page2(self)) 390 self.AddPage(Page3(self)) 391 self.AddPage(Page4(self)) 392 # Disabled until crbug.com/413829 is fixed. 393 # self.AddPage(Page5(self)) 394 # Disabled because of crbug.com/413829 and flakiness crbug.com/368532 395 # self.AddPage(Page6(self)) 396 # Why: Touch handler scrolling baseline 397 self.AddPage(ToughSchedulingCasesPage( 398 'file://tough_scheduling_cases/touch_handler_scrolling.html', 399 self)) 400 self.AddPage(Page7(self)) 401 self.AddPage(Page8(self)) 402 self.AddPage(Page9(self)) 403 self.AddPage(Page10(self)) 404 self.AddPage(Page11(self)) 405 self.AddPage(Page12(self)) 406 # Why: requestAnimationFrame scrolling baseline 407 self.AddPage(ToughSchedulingCasesPage( 408 'file://tough_scheduling_cases/raf.html', 409 self)) 410 # Why: Test canvas blocking behavior 411 self.AddPage(ToughSchedulingCasesPage( 412 'file://tough_scheduling_cases/raf_canvas.html', 413 self)) 414 # Disabled until crbug.com/413829 is fixed. 415 # self.AddPage(Page13(self)) 416 # Disabled because of crbug.com/413829 and flakiness crbug.com/368532 417 # self.AddPage(Page14(self)) 418 self.AddPage(Page15(self)) 419 self.AddPage(Page16(self)) 420 # Why: Test a requestAnimationFrame handler with concurrent CSS animation 421 self.AddPage(ToughSchedulingCasesPage( 422 'file://tough_scheduling_cases/raf_animation.html', 423 self)) 424 # Why: Stress test for the scheduler 425 self.AddPage(ToughSchedulingCasesPage( 426 'file://tough_scheduling_cases/raf_touch_animation.html', 427 self)) 428 self.AddPage(Page17(self)) 429 self.AddPage(Page18(self)) 430 self.AddPage(Page19(self)) 431 self.AddPage(Page20(self)) 432 # Why: Baseline for scrolling in the presence of a no-op touch handler 433 self.AddPage(EmptyTouchHandlerPage( 434 name='baseline', 435 desktop=False, 436 slow_handler=False, 437 bounce=False, 438 page_set=self)) 439 # Why: Slow handler blocks scroll start 440 self.AddPage(EmptyTouchHandlerPage( 441 name='slow_handler', 442 desktop=False, 443 slow_handler=True, 444 bounce=False, 445 page_set=self)) 446 # Why: Slow handler blocks scroll start until touch ACK timeout 447 self.AddPage(EmptyTouchHandlerPage( 448 name='desktop_slow_handler', 449 desktop=True, 450 slow_handler=True, 451 bounce=False, 452 page_set=self)) 453 # Why: Scroll bounce showing repeated transitions between scrolling and 454 # sending synchronous touchmove events. Should be nearly as fast as 455 # scroll baseline. 456 self.AddPage(EmptyTouchHandlerPage( 457 name='bounce', 458 desktop=False, 459 slow_handler=False, 460 bounce=True, 461 page_set=self)) 462 # Why: Scroll bounce with slow handler, repeated blocking. 463 self.AddPage(EmptyTouchHandlerPage( 464 name='bounce_slow_handler', 465 desktop=False, 466 slow_handler=True, 467 bounce=True, 468 page_set=self)) 469 # Why: Scroll bounce with slow handler on desktop, blocks only once until 470 # ACK timeout. 471 self.AddPage(EmptyTouchHandlerPage( 472 name='bounce_desktop_slow_handler', 473 desktop=True, 474 slow_handler=True, 475 bounce=True, 476 page_set=self)) 477 # Why: For measuring the latency of scroll-synchronized effects. 478 self.AddPage(SynchronizedScrollOffsetPage(page_set=self)) 479 # Why: Good examples of poor initial scrolling 480 self.AddPage(ToughSchedulingCasesPage( 481 'http://www.latimes.com', 482 self)) 483 self.AddPage(ToughSchedulingCasesPage( 484 'http://m.espn.go.com/nhl/rankings', 485 self)) 486