1 # Copyright (c) 2013 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 import os 5 6 from telemetry import test as test_module 7 from telemetry.core import util 8 from telemetry.page import page_set 9 from telemetry.page import page_test 10 11 data_path = os.path.join( 12 util.GetChromiumSrcDir(), 'content', 'test', 'data', 'gpu') 13 14 wait_timeout = 20 # seconds 15 16 harness_script = r""" 17 var domAutomationController = {}; 18 19 domAutomationController._loaded = false; 20 domAutomationController._succeeded = false; 21 domAutomationController._finished = false; 22 23 domAutomationController.setAutomationId = function(id) {} 24 25 domAutomationController.send = function(msg) { 26 msg = msg.toLowerCase() 27 if (msg == "loaded") { 28 domAutomationController._loaded = true; 29 } else if (msg == "success") { 30 domAutomationController._succeeded = true; 31 domAutomationController._finished = true; 32 } else { 33 domAutomationController._succeeded = false; 34 domAutomationController._finished = true; 35 } 36 } 37 38 window.domAutomationController = domAutomationController; 39 console.log("Harness injected."); 40 """ 41 42 class _ContextLostValidator(page_test.PageTest): 43 def __init__(self): 44 # Strictly speaking this test doesn't yet need a browser restart 45 # after each run, but if more tests are added which crash the GPU 46 # process, then it will. 47 super(_ContextLostValidator, self).__init__( 48 'ValidatePage', needs_browser_restart_after_each_run=True) 49 50 def CustomizeBrowserOptions(self, options): 51 options.AppendExtraBrowserArgs( 52 '--disable-domain-blocking-for-3d-apis') 53 # Required for about:gpucrash handling from Telemetry. 54 options.AppendExtraBrowserArgs('--enable-gpu-benchmarking') 55 56 def ValidatePage(self, page, tab, results): 57 if page.kill_gpu_process: 58 if not tab.browser.supports_tab_control: 59 raise page_test.Failure('Browser must support tab control') 60 # Crash the GPU process. 61 new_tab = tab.browser.tabs.New() 62 # To access these debug URLs from Telemetry, they have to be 63 # written using the chrome:// scheme. 64 new_tab.Navigate('chrome://gpucrash') 65 # Activate the original tab and wait for completion. 66 tab.Activate() 67 completed = False 68 try: 69 util.WaitFor(lambda: tab.EvaluateJavaScript( 70 'window.domAutomationController._finished'), wait_timeout) 71 completed = True 72 except util.TimeoutException: 73 pass 74 new_tab.Close() 75 if not completed: 76 raise page_test.Failure( 77 'Test didn\'t complete (no context lost event?)') 78 if not tab.EvaluateJavaScript('window.domAutomationController._succeeded'): 79 raise page_test.Failure('Test failed (context not restored properly?)') 80 81 class ContextLost(test_module.Test): 82 enabled = True 83 test = _ContextLostValidator 84 85 def CreatePageSet(self, options): 86 page_set_dict = { 87 'description': 'Test cases for real and synthetic context lost events', 88 'user_agent_type': 'desktop', 89 'serving_dirs': [''], 90 'pages': [ 91 { 92 'name': 'ContextLost.WebGLContextLostFromGPUProcessExit', 93 'url': 'file://webgl.html?query=kill_after_notification', 94 'script_to_evaluate_on_commit': harness_script, 95 'navigate_steps': [ 96 { 'action': 'navigate' }, 97 { 'action': 'wait', 98 'javascript': 'window.domAutomationController._loaded' } 99 ], 100 'kill_gpu_process': True 101 }, 102 { 103 'name': 'ContextLost.WebGLContextLostFromLoseContextExtension', 104 'url': 'file://webgl.html?query=WEBGL_lose_context', 105 'script_to_evaluate_on_commit': harness_script, 106 'navigate_steps': [ 107 { 'action': 'navigate' }, 108 { 'action': 'wait', 109 'javascript': 'window.domAutomationController._finished' } 110 ], 111 'kill_gpu_process': False 112 }, 113 ] 114 } 115 return page_set.PageSet.FromDict(page_set_dict, data_path) 116