| OLD | NEW |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | 1 # Copyright 2016 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 | 4 |
| 5 import os | 5 import os |
| 6 import sys | 6 import sys |
| 7 import time | 7 import time |
| 8 | 8 |
| 9 from gpu_tests import gpu_integration_test | 9 from gpu_tests import gpu_integration_test |
| 10 from gpu_tests import context_lost_expectations | 10 from gpu_tests import context_lost_expectations |
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 99 @classmethod | 99 @classmethod |
| 100 def SetUpProcess(cls): | 100 def SetUpProcess(cls): |
| 101 super(cls, ContextLostIntegrationTest).SetUpProcess() | 101 super(cls, ContextLostIntegrationTest).SetUpProcess() |
| 102 cls.CustomizeOptions() | 102 cls.CustomizeOptions() |
| 103 cls.SetBrowserOptions(cls._finder_options) | 103 cls.SetBrowserOptions(cls._finder_options) |
| 104 cls.StartBrowser() | 104 cls.StartBrowser() |
| 105 cls.SetStaticServerDirs([data_path]) | 105 cls.SetStaticServerDirs([data_path]) |
| 106 | 106 |
| 107 def _WaitForPageToFinish(self, tab): | 107 def _WaitForPageToFinish(self, tab): |
| 108 try: | 108 try: |
| 109 tab.WaitForJavaScriptCondition2( | 109 tab.WaitForJavaScriptCondition( |
| 110 'window.domAutomationController._finished', timeout=wait_timeout) | 110 'window.domAutomationController._finished', timeout=wait_timeout) |
| 111 return True | 111 return True |
| 112 except exceptions.TimeoutException: | 112 except exceptions.TimeoutException: |
| 113 return False | 113 return False |
| 114 | 114 |
| 115 def _KillGPUProcess(self, number_of_gpu_process_kills, | 115 def _KillGPUProcess(self, number_of_gpu_process_kills, |
| 116 check_crash_count): | 116 check_crash_count): |
| 117 tab = self.tab | 117 tab = self.tab |
| 118 # Doing the GPU process kill operation cooperatively -- in the | 118 # Doing the GPU process kill operation cooperatively -- in the |
| 119 # same page's context -- is much more stressful than restarting | 119 # same page's context -- is much more stressful than restarting |
| 120 # the browser every time. | 120 # the browser every time. |
| 121 for x in range(number_of_gpu_process_kills): | 121 for x in range(number_of_gpu_process_kills): |
| 122 expected_kills = x + 1 | 122 expected_kills = x + 1 |
| 123 | 123 |
| 124 # Reset the test's state. | 124 # Reset the test's state. |
| 125 tab.EvaluateJavaScript2( | 125 tab.EvaluateJavaScript( |
| 126 'window.domAutomationController.reset()') | 126 'window.domAutomationController.reset()') |
| 127 | 127 |
| 128 # If we're running the GPU process crash test, we need the test | 128 # If we're running the GPU process crash test, we need the test |
| 129 # to have fully reset before crashing the GPU process. | 129 # to have fully reset before crashing the GPU process. |
| 130 if check_crash_count: | 130 if check_crash_count: |
| 131 tab.WaitForJavaScriptCondition2( | 131 tab.WaitForJavaScriptCondition( |
| 132 'window.domAutomationController._finished', timeout=wait_timeout) | 132 'window.domAutomationController._finished', timeout=wait_timeout) |
| 133 | 133 |
| 134 # Crash the GPU process. | 134 # Crash the GPU process. |
| 135 gpucrash_tab = tab.browser.tabs.New() | 135 gpucrash_tab = tab.browser.tabs.New() |
| 136 # To access these debug URLs from Telemetry, they have to be | 136 # To access these debug URLs from Telemetry, they have to be |
| 137 # written using the chrome:// scheme. | 137 # written using the chrome:// scheme. |
| 138 # The try/except is a workaround for crbug.com/368107. | 138 # The try/except is a workaround for crbug.com/368107. |
| 139 try: | 139 try: |
| 140 gpucrash_tab.Navigate('chrome://gpucrash') | 140 gpucrash_tab.Navigate('chrome://gpucrash') |
| 141 except Exception: | 141 except Exception: |
| 142 print 'Tab crashed while navigating to chrome://gpucrash' | 142 print 'Tab crashed while navigating to chrome://gpucrash' |
| 143 # Activate the original tab and wait for completion. | 143 # Activate the original tab and wait for completion. |
| 144 tab.Activate() | 144 tab.Activate() |
| 145 completed = self._WaitForPageToFinish(tab) | 145 completed = self._WaitForPageToFinish(tab) |
| 146 | 146 |
| 147 if check_crash_count: | 147 if check_crash_count: |
| 148 self._CheckCrashCount(tab, expected_kills) | 148 self._CheckCrashCount(tab, expected_kills) |
| 149 | 149 |
| 150 # The try/except is a workaround for crbug.com/368107. | 150 # The try/except is a workaround for crbug.com/368107. |
| 151 try: | 151 try: |
| 152 gpucrash_tab.Close() | 152 gpucrash_tab.Close() |
| 153 except Exception: | 153 except Exception: |
| 154 print 'Tab crashed while closing chrome://gpucrash' | 154 print 'Tab crashed while closing chrome://gpucrash' |
| 155 if not completed: | 155 if not completed: |
| 156 self.fail('Test didn\'t complete (no context lost event?)') | 156 self.fail('Test didn\'t complete (no context lost event?)') |
| 157 if not tab.EvaluateJavaScript2( | 157 if not tab.EvaluateJavaScript( |
| 158 'window.domAutomationController._succeeded'): | 158 'window.domAutomationController._succeeded'): |
| 159 self.fail('Test failed (context not restored properly?)') | 159 self.fail('Test failed (context not restored properly?)') |
| 160 | 160 |
| 161 def _CheckCrashCount(self, tab, expected_kills): | 161 def _CheckCrashCount(self, tab, expected_kills): |
| 162 if not tab.browser.supports_system_info: | 162 if not tab.browser.supports_system_info: |
| 163 self.fail('Browser must support system info') | 163 self.fail('Browser must support system info') |
| 164 | 164 |
| 165 if not tab.EvaluateJavaScript2( | 165 if not tab.EvaluateJavaScript( |
| 166 'window.domAutomationController._succeeded'): | 166 'window.domAutomationController._succeeded'): |
| 167 self.fail('Test failed (didn\'t render content properly?)') | 167 self.fail('Test failed (didn\'t render content properly?)') |
| 168 | 168 |
| 169 number_of_crashes = -1 | 169 number_of_crashes = -1 |
| 170 # To allow time for a gpucrash to complete, wait up to 20s, | 170 # To allow time for a gpucrash to complete, wait up to 20s, |
| 171 # polling repeatedly. | 171 # polling repeatedly. |
| 172 start_time = time.time() | 172 start_time = time.time() |
| 173 current_time = time.time() | 173 current_time = time.time() |
| 174 while current_time - start_time < 20: | 174 while current_time - start_time < 20: |
| 175 system_info = tab.browser.GetSystemInfo() | 175 system_info = tab.browser.GetSystemInfo() |
| (...skipping 14 matching lines...) Expand all Loading... |
| 190 if number_of_crashes < expected_kills: | 190 if number_of_crashes < expected_kills: |
| 191 self.fail('Timed out waiting for a gpu process crash') | 191 self.fail('Timed out waiting for a gpu process crash') |
| 192 elif number_of_crashes != expected_kills: | 192 elif number_of_crashes != expected_kills: |
| 193 self.fail('Expected %d gpu process crashes; got: %d' % | 193 self.fail('Expected %d gpu process crashes; got: %d' % |
| 194 (expected_kills, number_of_crashes)) | 194 (expected_kills, number_of_crashes)) |
| 195 | 195 |
| 196 def _NavigateAndWaitForLoad(self, test_path): | 196 def _NavigateAndWaitForLoad(self, test_path): |
| 197 url = self.UrlOfStaticFilePath(test_path) | 197 url = self.UrlOfStaticFilePath(test_path) |
| 198 tab = self.tab | 198 tab = self.tab |
| 199 tab.Navigate(url, script_to_evaluate_on_commit=harness_script) | 199 tab.Navigate(url, script_to_evaluate_on_commit=harness_script) |
| 200 tab.action_runner.WaitForJavaScriptCondition2( | 200 tab.action_runner.WaitForJavaScriptCondition( |
| 201 'window.domAutomationController._loaded') | 201 'window.domAutomationController._loaded') |
| 202 | 202 |
| 203 def _WaitForTabAndCheckCompletion(self): | 203 def _WaitForTabAndCheckCompletion(self): |
| 204 tab = self.tab | 204 tab = self.tab |
| 205 completed = self._WaitForPageToFinish(tab) | 205 completed = self._WaitForPageToFinish(tab) |
| 206 if not completed: | 206 if not completed: |
| 207 self.fail('Test didn\'t complete (no context restored event?)') | 207 self.fail('Test didn\'t complete (no context restored event?)') |
| 208 if not tab.EvaluateJavaScript2('window.domAutomationController._succeeded'): | 208 if not tab.EvaluateJavaScript('window.domAutomationController._succeeded'): |
| 209 self.fail('Test failed (context not restored properly?)') | 209 self.fail('Test failed (context not restored properly?)') |
| 210 | 210 |
| 211 # The browser test runner synthesizes methods with the exact name | 211 # The browser test runner synthesizes methods with the exact name |
| 212 # given in GenerateGpuTests, so in order to hand-write our tests but | 212 # given in GenerateGpuTests, so in order to hand-write our tests but |
| 213 # also go through the _RunGpuTest trampoline, the test needs to be | 213 # also go through the _RunGpuTest trampoline, the test needs to be |
| 214 # slightly differently named. | 214 # slightly differently named. |
| 215 def _GpuCrash_GPUProcessCrashesExactlyOncePerVisitToAboutGpuCrash( | 215 def _GpuCrash_GPUProcessCrashesExactlyOncePerVisitToAboutGpuCrash( |
| 216 self, test_path): | 216 self, test_path): |
| 217 self._NavigateAndWaitForLoad(test_path) | 217 self._NavigateAndWaitForLoad(test_path) |
| 218 self._KillGPUProcess(2, True) | 218 self._KillGPUProcess(2, True) |
| 219 self._RestartBrowser('must restart after tests that kill the GPU process') | 219 self._RestartBrowser('must restart after tests that kill the GPU process') |
| 220 | 220 |
| 221 def _ContextLost_WebGLContextLostFromGPUProcessExit(self, test_path): | 221 def _ContextLost_WebGLContextLostFromGPUProcessExit(self, test_path): |
| 222 self._NavigateAndWaitForLoad(test_path) | 222 self._NavigateAndWaitForLoad(test_path) |
| 223 self._KillGPUProcess(1, False) | 223 self._KillGPUProcess(1, False) |
| 224 self._RestartBrowser('must restart after tests that kill the GPU process') | 224 self._RestartBrowser('must restart after tests that kill the GPU process') |
| 225 | 225 |
| 226 def _ContextLost_WebGLContextLostFromLoseContextExtension(self, test_path): | 226 def _ContextLost_WebGLContextLostFromLoseContextExtension(self, test_path): |
| 227 url = self.UrlOfStaticFilePath(test_path) | 227 url = self.UrlOfStaticFilePath(test_path) |
| 228 tab = self.tab | 228 tab = self.tab |
| 229 tab.Navigate(url, script_to_evaluate_on_commit=harness_script) | 229 tab.Navigate(url, script_to_evaluate_on_commit=harness_script) |
| 230 tab.action_runner.WaitForJavaScriptCondition2( | 230 tab.action_runner.WaitForJavaScriptCondition( |
| 231 'window.domAutomationController._finished') | 231 'window.domAutomationController._finished') |
| 232 | 232 |
| 233 def _ContextLost_WebGLContextLostFromQuantity(self, test_path): | 233 def _ContextLost_WebGLContextLostFromQuantity(self, test_path): |
| 234 self._NavigateAndWaitForLoad(test_path) | 234 self._NavigateAndWaitForLoad(test_path) |
| 235 # Try to coerce GC to clean up any contexts not attached to the page. | 235 # Try to coerce GC to clean up any contexts not attached to the page. |
| 236 # This method seems unreliable, so the page will also attempt to | 236 # This method seems unreliable, so the page will also attempt to |
| 237 # force GC through excessive allocations. | 237 # force GC through excessive allocations. |
| 238 self.tab.CollectGarbage() | 238 self.tab.CollectGarbage() |
| 239 self._WaitForTabAndCheckCompletion() | 239 self._WaitForTabAndCheckCompletion() |
| 240 | 240 |
| 241 def _ContextLost_WebGLContextLostFromSelectElement(self, test_path): | 241 def _ContextLost_WebGLContextLostFromSelectElement(self, test_path): |
| 242 self._NavigateAndWaitForLoad(test_path) | 242 self._NavigateAndWaitForLoad(test_path) |
| 243 self._WaitForTabAndCheckCompletion() | 243 self._WaitForTabAndCheckCompletion() |
| 244 | 244 |
| 245 def _ContextLost_WebGLContextLostInHiddenTab(self, test_path): | 245 def _ContextLost_WebGLContextLostInHiddenTab(self, test_path): |
| 246 self._NavigateAndWaitForLoad(test_path) | 246 self._NavigateAndWaitForLoad(test_path) |
| 247 # Test losing a context in a hidden tab. This test passes if the tab | 247 # Test losing a context in a hidden tab. This test passes if the tab |
| 248 # doesn't crash. | 248 # doesn't crash. |
| 249 tab = self.tab | 249 tab = self.tab |
| 250 dummy_tab = tab.browser.tabs.New() | 250 dummy_tab = tab.browser.tabs.New() |
| 251 tab.EvaluateJavaScript2('loseContextUsingExtension()') | 251 tab.EvaluateJavaScript('loseContextUsingExtension()') |
| 252 tab.Activate() | 252 tab.Activate() |
| 253 self._WaitForTabAndCheckCompletion() | 253 self._WaitForTabAndCheckCompletion() |
| 254 | 254 |
| 255 def load_tests(loader, tests, pattern): | 255 def load_tests(loader, tests, pattern): |
| 256 del loader, tests, pattern # Unused. | 256 del loader, tests, pattern # Unused. |
| 257 return gpu_integration_test.LoadAllTestsInModule(sys.modules[__name__]) | 257 return gpu_integration_test.LoadAllTestsInModule(sys.modules[__name__]) |
| OLD | NEW |