Removing uses of X11 native key events.
[chromium-blink-merge.git] / content / test / gpu / gpu_tests / context_lost.py
blob97603ef8e44b0c606250d7c633b5b1d7a3e5a342
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 import time
7 import context_lost_expectations
9 from telemetry import benchmark as benchmark_module
10 from telemetry.core import exceptions
11 from telemetry.core import util
12 from telemetry.page import page
13 from telemetry.page import page_set
14 from telemetry.page import page_test
16 data_path = os.path.join(
17 util.GetChromiumSrcDir(), 'content', 'test', 'data', 'gpu')
19 wait_timeout = 20 # seconds
21 harness_script = r"""
22 var domAutomationController = {};
24 domAutomationController._loaded = false;
25 domAutomationController._succeeded = false;
26 domAutomationController._finished = false;
28 domAutomationController.setAutomationId = function(id) {}
30 domAutomationController.send = function(msg) {
31 msg = msg.toLowerCase()
32 if (msg == "loaded") {
33 domAutomationController._loaded = true;
34 } else if (msg == "success") {
35 domAutomationController._succeeded = true;
36 domAutomationController._finished = true;
37 } else {
38 domAutomationController._succeeded = false;
39 domAutomationController._finished = true;
43 domAutomationController.reset = function() {
44 domAutomationController._succeeded = false;
45 domAutomationController._finished = false;
48 window.domAutomationController = domAutomationController;
49 console.log("Harness injected.");
50 """
52 class _ContextLostValidator(page_test.PageTest):
53 def __init__(self):
54 # Strictly speaking this test doesn't yet need a browser restart
55 # after each run, but if more tests are added which crash the GPU
56 # process, then it will.
57 super(_ContextLostValidator, self).__init__(
58 needs_browser_restart_after_each_page=True)
60 def CustomizeBrowserOptions(self, options):
61 options.AppendExtraBrowserArgs(
62 '--disable-domain-blocking-for-3d-apis')
63 options.AppendExtraBrowserArgs(
64 '--disable-gpu-process-crash-limit')
65 # Required for about:gpucrash handling from Telemetry.
66 options.AppendExtraBrowserArgs('--enable-gpu-benchmarking')
68 def ValidateAndMeasurePage(self, page, tab, results):
69 def WaitForPageToFinish():
70 print "Waiting for page to finish."
71 try:
72 util.WaitFor(lambda: tab.EvaluateJavaScript(
73 'window.domAutomationController._finished'), wait_timeout)
74 return True
75 except util.TimeoutException:
76 return False
78 if page.kill_gpu_process:
79 # Doing the GPU process kill operation cooperatively -- in the
80 # same page's context -- is much more stressful than restarting
81 # the browser every time.
82 for x in range(page.number_of_gpu_process_kills):
83 if not tab.browser.supports_tab_control:
84 raise page_test.Failure('Browser must support tab control')
86 expected_kills = x + 1
88 # Reset the test's state.
89 tab.EvaluateJavaScript(
90 'window.domAutomationController.reset()');
92 # If we're running the GPU process crash test, we need the
93 # test to have fully reset before crashing the GPU process.
94 if page.check_crash_count:
95 util.WaitFor(lambda: tab.EvaluateJavaScript(
96 'window.domAutomationController._finished'), wait_timeout)
98 # Crash the GPU process.
99 gpucrash_tab = tab.browser.tabs.New()
100 # To access these debug URLs from Telemetry, they have to be
101 # written using the chrome:// scheme.
102 # The try/except is a workaround for crbug.com/368107.
103 try:
104 gpucrash_tab.Navigate('chrome://gpucrash')
105 except (exceptions.TabCrashException, Exception):
106 print 'Tab crashed while navigating to chrome://gpucrash'
107 # Activate the original tab and wait for completion.
108 tab.Activate()
109 completed = WaitForPageToFinish()
111 if page.check_crash_count:
112 if not tab.browser.supports_system_info:
113 raise page_test.Failure('Browser must support system info')
115 if not tab.EvaluateJavaScript(
116 'window.domAutomationController._succeeded'):
117 raise page_test.Failure(
118 'Test failed (didn\'t render content properly?)')
120 number_of_crashes = -1
121 # To allow time for a gpucrash to complete, wait up to 20s,
122 # polling repeatedly.
123 start_time = time.time()
124 current_time = time.time()
125 while current_time - start_time < 20:
126 system_info = tab.browser.GetSystemInfo()
127 number_of_crashes = \
128 system_info.gpu.aux_attributes[u'process_crash_count']
129 if number_of_crashes >= expected_kills:
130 break
131 time.sleep(1)
132 current_time = time.time()
134 # Wait 5 more seconds and re-read process_crash_count, in
135 # attempt to catch latent process crashes.
136 time.sleep(5)
137 system_info = tab.browser.GetSystemInfo()
138 number_of_crashes = \
139 system_info.gpu.aux_attributes[u'process_crash_count']
141 if number_of_crashes < expected_kills:
142 raise page_test.Failure(
143 'Timed out waiting for a gpu process crash')
144 elif number_of_crashes != expected_kills:
145 raise page_test.Failure(
146 'Expected %d gpu process crashes; got: %d' %
147 (expected_kills, number_of_crashes))
149 # The try/except is a workaround for crbug.com/368107.
150 try:
151 gpucrash_tab.Close()
152 except (exceptions.TabCrashException, Exception):
153 print 'Tab crashed while closing chrome://gpucrash'
154 if not completed:
155 raise page_test.Failure(
156 'Test didn\'t complete (no context lost event?)')
157 if not tab.EvaluateJavaScript(
158 'window.domAutomationController._succeeded'):
159 raise page_test.Failure(
160 'Test failed (context not restored properly?)')
161 elif page.force_garbage_collection:
162 # Try to corce GC to clean up any contexts not attached to the page.
163 # This method seem unreliable, so the page will also attempt to force
164 # GC through excessive allocations.
165 tab.CollectGarbage()
166 completed = WaitForPageToFinish()
168 if not completed:
169 raise page_test.Failure(
170 'Test didn\'t complete (no context restored event?)')
171 if not tab.EvaluateJavaScript(
172 'window.domAutomationController._succeeded'):
173 raise page_test.Failure(
174 'Test failed (context not restored properly?)')
175 elif page.hide_tab_and_lose_context:
176 if not tab.browser.supports_tab_control:
177 raise page_test.Failure('Browser must support tab control')
179 # Test losing a context in a hidden tab. This test passes if the tab
180 # doesn't crash.
181 dummy_tab = tab.browser.tabs.New()
182 tab.EvaluateJavaScript('loseContextUsingExtension()')
183 tab.Activate()
185 completed = WaitForPageToFinish()
187 if not completed:
188 raise page_test.Failure('Test didn\'t complete')
189 if not tab.EvaluateJavaScript(
190 'window.domAutomationController._succeeded'):
191 raise page_test.Failure('Test failed')
192 else:
193 completed = WaitForPageToFinish()
195 if not completed:
196 raise page_test.Failure('Test didn\'t complete')
197 if not tab.EvaluateJavaScript(
198 'window.domAutomationController._succeeded'):
199 raise page_test.Failure('Test failed')
201 # Test that navigating to chrome://gpucrash causes the GPU process to crash
202 # exactly one time per navigation.
203 class GPUProcessCrashesExactlyOnce(page.Page):
204 def __init__(self, page_set, base_dir):
205 super(GPUProcessCrashesExactlyOnce, self).__init__(
206 url='file://gpu_process_crash.html',
207 page_set=page_set,
208 base_dir=base_dir,
209 name='GpuCrash.GPUProcessCrashesExactlyOnce')
210 self.script_to_evaluate_on_commit = harness_script
211 self.kill_gpu_process = True
212 self.number_of_gpu_process_kills = 2
213 self.check_crash_count = True
214 self.force_garbage_collection = False
215 self.hide_tab_and_lose_context = False
217 def RunNavigateSteps(self, action_runner):
218 action_runner.NavigateToPage(self)
219 action_runner.WaitForJavaScriptCondition(
220 'window.domAutomationController._loaded')
222 class WebGLContextLostFromGPUProcessExitPage(page.Page):
223 def __init__(self, page_set, base_dir):
224 super(WebGLContextLostFromGPUProcessExitPage, self).__init__(
225 url='file://webgl.html?query=kill_after_notification',
226 page_set=page_set,
227 base_dir=base_dir,
228 name='ContextLost.WebGLContextLostFromGPUProcessExit')
229 self.script_to_evaluate_on_commit = harness_script
230 self.kill_gpu_process = True
231 self.check_crash_count = False
232 self.number_of_gpu_process_kills = 1
233 self.force_garbage_collection = False
234 self.hide_tab_and_lose_context = False
236 def RunNavigateSteps(self, action_runner):
237 action_runner.NavigateToPage(self)
238 action_runner.WaitForJavaScriptCondition(
239 'window.domAutomationController._loaded')
242 class WebGLContextLostFromLoseContextExtensionPage(page.Page):
243 def __init__(self, page_set, base_dir):
244 super(WebGLContextLostFromLoseContextExtensionPage, self).__init__(
245 url='file://webgl.html?query=WEBGL_lose_context',
246 page_set=page_set,
247 base_dir=base_dir,
248 name='ContextLost.WebGLContextLostFromLoseContextExtension')
249 self.script_to_evaluate_on_commit = harness_script
250 self.kill_gpu_process = False
251 self.check_crash_count = False
252 self.force_garbage_collection = False
253 self.hide_tab_and_lose_context = False
255 def RunNavigateSteps(self, action_runner):
256 action_runner.NavigateToPage(self)
257 action_runner.WaitForJavaScriptCondition(
258 'window.domAutomationController._finished')
261 class WebGLContextLostInHiddenTabPage(page.Page):
262 def __init__(self, page_set, base_dir):
263 super(WebGLContextLostInHiddenTabPage, self).__init__(
264 url='file://webgl.html?query=kill_after_notification',
265 page_set=page_set,
266 base_dir=base_dir,
267 name='ContextLost.WebGLContextLostInHiddenTab')
268 self.script_to_evaluate_on_commit = harness_script
269 self.kill_gpu_process = False
270 self.check_crash_count = False
271 self.force_garbage_collection = False
272 self.hide_tab_and_lose_context = True
274 def RunNavigateSteps(self, action_runner):
275 action_runner.NavigateToPage(self)
276 action_runner.WaitForJavaScriptCondition(
277 'window.domAutomationController._loaded')
280 class WebGLContextLostFromQuantityPage(page.Page):
281 def __init__(self, page_set, base_dir):
282 super(WebGLContextLostFromQuantityPage, self).__init__(
283 url='file://webgl.html?query=forced_quantity_loss',
284 page_set=page_set,
285 base_dir=base_dir,
286 name='ContextLost.WebGLContextLostFromQuantity')
287 self.script_to_evaluate_on_commit = harness_script
288 self.kill_gpu_process = False
289 self.check_crash_count = False
290 self.force_garbage_collection = True
291 self.hide_tab_and_lose_context = False
293 def RunNavigateSteps(self, action_runner):
294 action_runner.NavigateToPage(self)
295 action_runner.WaitForJavaScriptCondition(
296 'window.domAutomationController._loaded')
298 class WebGLContextLostFromSelectElementPage(page.Page):
299 def __init__(self, page_set, base_dir):
300 super(WebGLContextLostFromSelectElementPage, self).__init__(
301 url='file://webgl_with_select_element.html',
302 page_set=page_set,
303 base_dir=base_dir,
304 name='ContextLost.WebGLContextLostFromSelectElement')
305 self.script_to_evaluate_on_commit = harness_script
306 self.kill_gpu_process = False
307 self.check_crash_count = False
308 self.force_garbage_collection = False
309 self.hide_tab_and_lose_context = False
311 def RunNavigateSteps(self, action_runner):
312 action_runner.NavigateToPage(self)
313 action_runner.WaitForJavaScriptCondition(
314 'window.domAutomationController._loaded')
316 class ContextLost(benchmark_module.Benchmark):
317 enabled = True
318 test = _ContextLostValidator
320 def CreateExpectations(self, page_set):
321 return context_lost_expectations.ContextLostExpectations()
323 # For the record, this would have been another way to get the pages
324 # to repeat. pageset_repeat would be another option.
325 # options = {'page_repeat': 5}
326 def CreatePageSet(self, options):
327 ps = page_set.PageSet(
328 file_path=data_path,
329 user_agent_type='desktop',
330 serving_dirs=set(['']))
331 ps.AddPage(GPUProcessCrashesExactlyOnce(ps, ps.base_dir))
332 ps.AddPage(WebGLContextLostFromGPUProcessExitPage(ps, ps.base_dir))
333 ps.AddPage(WebGLContextLostFromLoseContextExtensionPage(ps, ps.base_dir))
334 ps.AddPage(WebGLContextLostFromQuantityPage(ps, ps.base_dir))
335 ps.AddPage(WebGLContextLostFromSelectElementPage(ps, ps.base_dir))
336 ps.AddPage(WebGLContextLostInHiddenTabPage(ps, ps.base_dir))
337 return ps