Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 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 | 2 # Use of this source code is governed by a BSD-style license that can be |
| 3 # found in the LICENSE file. | 3 # found in the LICENSE file. |
| 4 import os | 4 import os |
| 5 import time | |
| 5 | 6 |
| 6 from telemetry import benchmark as benchmark_module | 7 from telemetry import benchmark as benchmark_module |
| 7 from telemetry.core import exceptions | 8 from telemetry.core import exceptions |
| 8 from telemetry.core import util | 9 from telemetry.core import util |
| 9 from telemetry.page import page | 10 from telemetry.page import page |
| 10 from telemetry.page import page_set | 11 from telemetry.page import page_set |
| 11 from telemetry.page import page_test | 12 from telemetry.page import page_test |
| 12 | 13 |
| 13 data_path = os.path.join( | 14 data_path = os.path.join( |
| 14 util.GetChromiumSrcDir(), 'content', 'test', 'data', 'gpu') | 15 util.GetChromiumSrcDir(), 'content', 'test', 'data', 'gpu') |
| (...skipping 15 matching lines...) Expand all Loading... | |
| 30 domAutomationController._loaded = true; | 31 domAutomationController._loaded = true; |
| 31 } else if (msg == "success") { | 32 } else if (msg == "success") { |
| 32 domAutomationController._succeeded = true; | 33 domAutomationController._succeeded = true; |
| 33 domAutomationController._finished = true; | 34 domAutomationController._finished = true; |
| 34 } else { | 35 } else { |
| 35 domAutomationController._succeeded = false; | 36 domAutomationController._succeeded = false; |
| 36 domAutomationController._finished = true; | 37 domAutomationController._finished = true; |
| 37 } | 38 } |
| 38 } | 39 } |
| 39 | 40 |
| 41 domAutomationController.reset = function() { | |
| 42 domAutomationController._succeeded = false; | |
| 43 domAutomationController._finished = false; | |
| 44 } | |
| 45 | |
| 40 window.domAutomationController = domAutomationController; | 46 window.domAutomationController = domAutomationController; |
| 41 console.log("Harness injected."); | 47 console.log("Harness injected."); |
| 42 """ | 48 """ |
| 43 | 49 |
| 50 gpu_process_crash_count_script = r""" | |
| 51 function GetProcessCrashCount() { | |
| 52 var table = document.querySelector('#basic-info #info-view-table'); | |
| 53 if ( table == null ) | |
| 54 return false; | |
| 55 for (var i = 0, row; row = table.rows[i]; i++) { | |
| 56 var span_list = row.getElementsByTagName('span'); | |
| 57 var name_str = span_list[0].textContent; | |
| 58 var value_str = span_list[1].textContent; | |
| 59 if (name_str == 'GPU process crash count') { | |
| 60 window._process_crash_count = value_str; | |
| 61 return true; | |
| 62 } | |
| 63 } | |
| 64 return false; | |
| 65 } | |
| 66 """; | |
| 67 | |
| 44 class _ContextLostValidator(page_test.PageTest): | 68 class _ContextLostValidator(page_test.PageTest): |
| 45 def __init__(self): | 69 def __init__(self): |
| 46 # Strictly speaking this test doesn't yet need a browser restart | 70 # Strictly speaking this test doesn't yet need a browser restart |
| 47 # after each run, but if more tests are added which crash the GPU | 71 # after each run, but if more tests are added which crash the GPU |
| 48 # process, then it will. | 72 # process, then it will. |
| 49 super(_ContextLostValidator, self).__init__( | 73 super(_ContextLostValidator, self).__init__( |
| 50 needs_browser_restart_after_each_page=True) | 74 needs_browser_restart_after_each_page=True) |
| 51 | 75 |
| 52 def CustomizeBrowserOptions(self, options): | 76 def CustomizeBrowserOptions(self, options): |
| 53 options.AppendExtraBrowserArgs( | 77 options.AppendExtraBrowserArgs( |
| 54 '--disable-domain-blocking-for-3d-apis') | 78 '--disable-domain-blocking-for-3d-apis') |
| 55 options.AppendExtraBrowserArgs( | 79 options.AppendExtraBrowserArgs( |
| 56 '--disable-gpu-process-crash-limit') | 80 '--disable-gpu-process-crash-limit') |
| 57 # Required for about:gpucrash handling from Telemetry. | 81 # Required for about:gpucrash handling from Telemetry. |
| 58 options.AppendExtraBrowserArgs('--enable-gpu-benchmarking') | 82 options.AppendExtraBrowserArgs('--enable-gpu-benchmarking') |
| 59 | 83 |
| 60 def ValidatePage(self, page, tab, results): | 84 def ValidatePage(self, page, tab, results): |
| 61 if page.kill_gpu_process: | 85 if page.kill_gpu_process: |
| 62 # Doing the GPU process kill operation cooperatively -- in the | 86 # Doing the GPU process kill operation cooperatively -- in the |
| 63 # same page's context -- is much more stressful than restarting | 87 # same page's context -- is much more stressful than restarting |
| 64 # the browser every time. | 88 # the browser every time. |
| 65 for x in range(page.number_of_gpu_process_kills): | 89 for x in range(page.number_of_gpu_process_kills): |
| 66 if not tab.browser.supports_tab_control: | 90 if not tab.browser.supports_tab_control: |
| 67 raise page_test.Failure('Browser must support tab control') | 91 raise page_test.Failure('Browser must support tab control') |
| 92 | |
| 93 expected_kills = x + 1 | |
| 94 | |
| 68 # Reset the test's state. | 95 # Reset the test's state. |
| 69 tab.EvaluateJavaScript( | 96 tab.EvaluateJavaScript( |
| 70 'window.domAutomationController._succeeded = false'); | 97 'window.domAutomationController.reset()'); |
| 71 tab.EvaluateJavaScript( | |
| 72 'window.domAutomationController._finished = false'); | |
| 73 # Crash the GPU process. | 98 # Crash the GPU process. |
| 74 new_tab = tab.browser.tabs.New() | 99 gpucrash_tab = tab.browser.tabs.New() |
| 75 # To access these debug URLs from Telemetry, they have to be | 100 # To access these debug URLs from Telemetry, they have to be |
| 76 # written using the chrome:// scheme. | 101 # written using the chrome:// scheme. |
| 77 # The try/except is a workaround for crbug.com/368107. | 102 # The try/except is a workaround for crbug.com/368107. |
| 78 try: | 103 try: |
| 79 new_tab.Navigate('chrome://gpucrash') | 104 gpucrash_tab.Navigate('chrome://gpucrash') |
| 80 except (exceptions.TabCrashException, Exception): | 105 except (exceptions.TabCrashException, Exception): |
| 81 print 'Tab crashed while navigating to chrome://gpucrash' | 106 print 'Tab crashed while navigating to chrome://gpucrash' |
| 82 # Activate the original tab and wait for completion. | 107 # Activate the original tab and wait for completion. |
| 83 tab.Activate() | 108 tab.Activate() |
| 84 completed = False | 109 completed = False |
| 85 try: | 110 try: |
| 86 util.WaitFor(lambda: tab.EvaluateJavaScript( | 111 util.WaitFor(lambda: tab.EvaluateJavaScript( |
| 87 'window.domAutomationController._finished'), wait_timeout) | 112 'window.domAutomationController._finished'), wait_timeout) |
| 88 completed = True | 113 completed = True |
| 89 except util.TimeoutException: | 114 except util.TimeoutException: |
| 90 pass | 115 pass |
| 116 | |
| 117 if page.check_crash_count: | |
| 118 number_of_crashes = -1 | |
| 119 # To allow time for a gpucrash to complete, wait 10s with | |
| 120 # maximum retry x3 times. | |
| 121 for retry in range(3): | |
| 122 time.sleep(10) | |
| 123 | |
| 124 # Scrub chrome://gpu page for GPU process crash count. | |
| 125 gpuinfo_tab = tab.browser.tabs.New() | |
| 126 gpuinfo_tab.Navigate('chrome://gpu', gpu_process_crash_count_script) | |
| 127 | |
| 128 # Wait until chrome://gpu page is populated. | |
| 129 util.WaitFor(lambda: gpuinfo_tab.EvaluateJavaScript( | |
| 130 'GetProcessCrashCount()'), wait_timeout) | |
| 131 | |
| 132 number_of_crashes =int( | |
|
Ken Russell (switch to Gerrit)
2014/07/25 01:08:27
space after '='
vmiura
2014/07/25 19:56:03
Done.
| |
| 133 gpuinfo_tab.EvaluateJavaScript("window._process_crash_count")) | |
| 134 | |
| 135 # The try/except is a workaround for crbug.com/368107. | |
| 136 try: | |
| 137 gpuinfo_tab.Close() | |
| 138 except (exceptions.TabCrashException, Exception): | |
| 139 print 'Tab crashed while closing chrome://gpucrash' | |
| 140 | |
| 141 if number_of_crashes >= expected_kills: | |
| 142 break | |
| 143 | |
| 144 if number_of_crashes < expected_kills: | |
| 145 raise page_test.Failure( | |
| 146 'Timed out waiting for a gpu process crash') | |
| 147 elif number_of_crashes != expected_kills: | |
| 148 raise page_test.Failure( | |
| 149 'Expected %d gpu process crashes; got: %d' % | |
| 150 (expected_kills, number_of_crashes)) | |
| 151 | |
| 91 # The try/except is a workaround for crbug.com/368107. | 152 # The try/except is a workaround for crbug.com/368107. |
| 92 try: | 153 try: |
| 93 new_tab.Close() | 154 gpucrash_tab.Close() |
| 94 except (exceptions.TabCrashException, Exception): | 155 except (exceptions.TabCrashException, Exception): |
| 95 print 'Tab crashed while closing chrome://gpucrash' | 156 print 'Tab crashed while closing chrome://gpucrash' |
| 96 if not completed: | 157 if not completed: |
| 97 raise page_test.Failure( | 158 raise page_test.Failure( |
| 98 'Test didn\'t complete (no context lost event?)') | 159 'Test didn\'t complete (no context lost event?)') |
| 99 if not tab.EvaluateJavaScript( | 160 if not tab.EvaluateJavaScript( |
| 100 'window.domAutomationController._succeeded'): | 161 'window.domAutomationController._succeeded'): |
| 101 raise page_test.Failure( | 162 raise page_test.Failure( |
| 102 'Test failed (context not restored properly?)') | 163 'Test failed (context not restored properly?)') |
| 103 elif page.force_garbage_collection: | 164 elif page.force_garbage_collection: |
| (...skipping 26 matching lines...) Expand all Loading... | |
| 130 completed = True | 191 completed = True |
| 131 except util.TimeoutException: | 192 except util.TimeoutException: |
| 132 pass | 193 pass |
| 133 | 194 |
| 134 if not completed: | 195 if not completed: |
| 135 raise page_test.Failure('Test didn\'t complete') | 196 raise page_test.Failure('Test didn\'t complete') |
| 136 if not tab.EvaluateJavaScript( | 197 if not tab.EvaluateJavaScript( |
| 137 'window.domAutomationController._succeeded'): | 198 'window.domAutomationController._succeeded'): |
| 138 raise page_test.Failure('Test failed') | 199 raise page_test.Failure('Test failed') |
| 139 | 200 |
| 201 # Test that navigating to chrome://gpucrash causes the GPU process to crash | |
| 202 # exactly one time. | |
| 203 class GPUProcessExitPageCrashesOnce(page.Page): | |
|
Ken Russell (switch to Gerrit)
2014/07/25 01:08:26
Suggest something like "GPUProcessCrashesExactlyOn
vmiura
2014/07/25 19:56:03
Done.
| |
| 204 def __init__(self, page_set, base_dir): | |
| 205 super(GPUProcessExitPageCrashesOnce, self).__init__( | |
| 206 url='file://gpu_process_crash.html', | |
| 207 page_set=page_set, | |
| 208 base_dir=base_dir, | |
| 209 name='GpuCrash.GPUProcessExitPageCrashesOnce') | |
| 210 self.script_to_evaluate_on_commit = harness_script | |
| 211 self.kill_gpu_process = True | |
| 212 self.number_of_gpu_process_kills = 2 | |
|
Ken Russell (switch to Gerrit)
2014/07/25 01:08:26
Running the test twice looks good. Just checking t
vmiura
2014/07/25 19:56:03
Yes I thought it would be good to check behavior o
| |
| 213 self.check_crash_count = True | |
| 214 self.force_garbage_collection = False | |
| 215 | |
| 216 def RunNavigateSteps(self, action_runner): | |
| 217 action_runner.NavigateToPage(self) | |
| 218 action_runner.WaitForJavaScriptCondition( | |
| 219 'window.domAutomationController._loaded') | |
| 220 | |
| 140 class WebGLContextLostFromGPUProcessExitPage(page.Page): | 221 class WebGLContextLostFromGPUProcessExitPage(page.Page): |
| 141 def __init__(self, page_set, base_dir): | 222 def __init__(self, page_set, base_dir): |
| 142 super(WebGLContextLostFromGPUProcessExitPage, self).__init__( | 223 super(WebGLContextLostFromGPUProcessExitPage, self).__init__( |
| 143 url='file://webgl.html?query=kill_after_notification', | 224 url='file://webgl.html?query=kill_after_notification', |
| 144 page_set=page_set, | 225 page_set=page_set, |
| 145 base_dir=base_dir, | 226 base_dir=base_dir, |
| 146 name='ContextLost.WebGLContextLostFromGPUProcessExit') | 227 name='ContextLost.WebGLContextLostFromGPUProcessExit') |
| 147 self.script_to_evaluate_on_commit = harness_script | 228 self.script_to_evaluate_on_commit = harness_script |
| 148 self.kill_gpu_process = True | 229 self.kill_gpu_process = True |
| 230 self.check_crash_count = False | |
| 149 self.number_of_gpu_process_kills = 1 | 231 self.number_of_gpu_process_kills = 1 |
| 150 self.force_garbage_collection = False | 232 self.force_garbage_collection = False |
| 151 | 233 |
| 152 def RunNavigateSteps(self, action_runner): | 234 def RunNavigateSteps(self, action_runner): |
| 153 action_runner.NavigateToPage(self) | 235 action_runner.NavigateToPage(self) |
| 154 action_runner.WaitForJavaScriptCondition( | 236 action_runner.WaitForJavaScriptCondition( |
| 155 'window.domAutomationController._loaded') | 237 'window.domAutomationController._loaded') |
| 156 | 238 |
| 157 | 239 |
| 158 class WebGLContextLostFromLoseContextExtensionPage(page.Page): | 240 class WebGLContextLostFromLoseContextExtensionPage(page.Page): |
| 159 def __init__(self, page_set, base_dir): | 241 def __init__(self, page_set, base_dir): |
| 160 super(WebGLContextLostFromLoseContextExtensionPage, self).__init__( | 242 super(WebGLContextLostFromLoseContextExtensionPage, self).__init__( |
| 161 url='file://webgl.html?query=WEBGL_lose_context', | 243 url='file://webgl.html?query=WEBGL_lose_context', |
| 162 page_set=page_set, | 244 page_set=page_set, |
| 163 base_dir=base_dir, | 245 base_dir=base_dir, |
| 164 name='ContextLost.WebGLContextLostFromLoseContextExtension') | 246 name='ContextLost.WebGLContextLostFromLoseContextExtension') |
| 165 self.script_to_evaluate_on_commit = harness_script | 247 self.script_to_evaluate_on_commit = harness_script |
| 166 self.kill_gpu_process = False | 248 self.kill_gpu_process = False |
| 249 self.check_crash_count = False | |
| 167 self.force_garbage_collection = False | 250 self.force_garbage_collection = False |
| 168 | 251 |
| 169 def RunNavigateSteps(self, action_runner): | 252 def RunNavigateSteps(self, action_runner): |
| 170 action_runner.NavigateToPage(self) | 253 action_runner.NavigateToPage(self) |
| 171 action_runner.WaitForJavaScriptCondition( | 254 action_runner.WaitForJavaScriptCondition( |
| 172 'window.domAutomationController._finished') | 255 'window.domAutomationController._finished') |
| 173 | 256 |
| 174 class WebGLContextLostFromQuantityPage(page.Page): | 257 class WebGLContextLostFromQuantityPage(page.Page): |
| 175 def __init__(self, page_set, base_dir): | 258 def __init__(self, page_set, base_dir): |
| 176 super(WebGLContextLostFromQuantityPage, self).__init__( | 259 super(WebGLContextLostFromQuantityPage, self).__init__( |
| 177 url='file://webgl.html?query=forced_quantity_loss', | 260 url='file://webgl.html?query=forced_quantity_loss', |
| 178 page_set=page_set, | 261 page_set=page_set, |
| 179 base_dir=base_dir, | 262 base_dir=base_dir, |
| 180 name='ContextLost.WebGLContextLostFromQuantity') | 263 name='ContextLost.WebGLContextLostFromQuantity') |
| 181 self.script_to_evaluate_on_commit = harness_script | 264 self.script_to_evaluate_on_commit = harness_script |
| 182 self.kill_gpu_process = False | 265 self.kill_gpu_process = False |
| 266 self.check_crash_count = False | |
| 183 self.force_garbage_collection = True | 267 self.force_garbage_collection = True |
| 184 | 268 |
| 185 def RunNavigateSteps(self, action_runner): | 269 def RunNavigateSteps(self, action_runner): |
| 186 action_runner.NavigateToPage(self) | 270 action_runner.NavigateToPage(self) |
| 187 action_runner.WaitForJavaScriptCondition( | 271 action_runner.WaitForJavaScriptCondition( |
| 188 'window.domAutomationController._loaded') | 272 'window.domAutomationController._loaded') |
| 189 | 273 |
| 190 class WebGLContextLostFromSelectElementPage(page.Page): | 274 class WebGLContextLostFromSelectElementPage(page.Page): |
| 191 def __init__(self, page_set, base_dir): | 275 def __init__(self, page_set, base_dir): |
| 192 super(WebGLContextLostFromSelectElementPage, self).__init__( | 276 super(WebGLContextLostFromSelectElementPage, self).__init__( |
| 193 url='file://webgl_with_select_element.html', | 277 url='file://webgl_with_select_element.html', |
| 194 page_set=page_set, | 278 page_set=page_set, |
| 195 base_dir=base_dir, | 279 base_dir=base_dir, |
| 196 name='ContextLost.WebGLContextLostFromSelectElement') | 280 name='ContextLost.WebGLContextLostFromSelectElement') |
| 197 self.script_to_evaluate_on_commit = harness_script | 281 self.script_to_evaluate_on_commit = harness_script |
| 198 self.kill_gpu_process = False | 282 self.kill_gpu_process = False |
| 283 self.check_crash_count = False | |
| 199 self.force_garbage_collection = False | 284 self.force_garbage_collection = False |
| 200 | 285 |
| 201 def RunNavigateSteps(self, action_runner): | 286 def RunNavigateSteps(self, action_runner): |
| 202 action_runner.NavigateToPage(self) | 287 action_runner.NavigateToPage(self) |
| 203 action_runner.WaitForJavaScriptCondition( | 288 action_runner.WaitForJavaScriptCondition( |
| 204 'window.domAutomationController._loaded') | 289 'window.domAutomationController._loaded') |
| 205 | 290 |
| 206 class ContextLost(benchmark_module.Benchmark): | 291 class ContextLost(benchmark_module.Benchmark): |
| 207 enabled = True | 292 enabled = True |
| 208 test = _ContextLostValidator | 293 test = _ContextLostValidator |
| 209 # For the record, this would have been another way to get the pages | 294 # For the record, this would have been another way to get the pages |
| 210 # to repeat. pageset_repeat would be another option. | 295 # to repeat. pageset_repeat would be another option. |
| 211 # options = {'page_repeat': 5} | 296 # options = {'page_repeat': 5} |
| 212 def CreatePageSet(self, options): | 297 def CreatePageSet(self, options): |
| 213 ps = page_set.PageSet( | 298 ps = page_set.PageSet( |
| 214 file_path=data_path, | 299 file_path=data_path, |
| 215 user_agent_type='desktop', | 300 user_agent_type='desktop', |
| 216 serving_dirs=set([''])) | 301 serving_dirs=set([''])) |
| 302 ps.AddPage(GPUProcessExitPageCrashesOnce(ps, ps.base_dir)) | |
| 217 ps.AddPage(WebGLContextLostFromGPUProcessExitPage(ps, ps.base_dir)) | 303 ps.AddPage(WebGLContextLostFromGPUProcessExitPage(ps, ps.base_dir)) |
| 218 ps.AddPage(WebGLContextLostFromLoseContextExtensionPage(ps, ps.base_dir)) | 304 ps.AddPage(WebGLContextLostFromLoseContextExtensionPage(ps, ps.base_dir)) |
| 219 ps.AddPage(WebGLContextLostFromQuantityPage(ps, ps.base_dir)) | 305 ps.AddPage(WebGLContextLostFromQuantityPage(ps, ps.base_dir)) |
| 220 ps.AddPage(WebGLContextLostFromSelectElementPage(ps, ps.base_dir)) | 306 ps.AddPage(WebGLContextLostFromSelectElementPage(ps, ps.base_dir)) |
| 221 return ps | 307 return ps |
| OLD | NEW |