Upstream version 9.37.195.0
[platform/framework/web/crosswalk.git] / src / content / test / gpu / gpu_tests / context_lost.py
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 exceptions
8 from telemetry.core import util
9 from telemetry.page import page
10 from telemetry.page import page_set
11 # pylint: disable=W0401,W0614
12 from telemetry.page import page_test
13 from telemetry.page.actions.all_page_actions import *
14
15 data_path = os.path.join(
16     util.GetChromiumSrcDir(), 'content', 'test', 'data', 'gpu')
17
18 wait_timeout = 20  # seconds
19
20 harness_script = r"""
21   var domAutomationController = {};
22
23   domAutomationController._loaded = false;
24   domAutomationController._succeeded = false;
25   domAutomationController._finished = false;
26
27   domAutomationController.setAutomationId = function(id) {}
28
29   domAutomationController.send = function(msg) {
30     msg = msg.toLowerCase()
31     if (msg == "loaded") {
32       domAutomationController._loaded = true;
33     } else if (msg == "success") {
34       domAutomationController._succeeded = true;
35       domAutomationController._finished = true;
36     } else {
37       domAutomationController._succeeded = false;
38       domAutomationController._finished = true;
39     }
40   }
41
42   window.domAutomationController = domAutomationController;
43   console.log("Harness injected.");
44 """
45
46 class _ContextLostValidator(page_test.PageTest):
47   def __init__(self):
48     # Strictly speaking this test doesn't yet need a browser restart
49     # after each run, but if more tests are added which crash the GPU
50     # process, then it will.
51     super(_ContextLostValidator, self).__init__(
52       needs_browser_restart_after_each_page=True)
53
54   def CustomizeBrowserOptions(self, options):
55     options.AppendExtraBrowserArgs(
56         '--disable-domain-blocking-for-3d-apis')
57     options.AppendExtraBrowserArgs(
58         '--disable-gpu-process-crash-limit')
59     # Required for about:gpucrash handling from Telemetry.
60     options.AppendExtraBrowserArgs('--enable-gpu-benchmarking')
61
62   def ValidatePage(self, page, tab, results):
63     if page.kill_gpu_process:
64       # Doing the GPU process kill operation cooperatively -- in the
65       # same page's context -- is much more stressful than restarting
66       # the browser every time.
67       for x in range(page.number_of_gpu_process_kills):
68         if not tab.browser.supports_tab_control:
69           raise page_test.Failure('Browser must support tab control')
70         # Reset the test's state.
71         tab.EvaluateJavaScript(
72           'window.domAutomationController._succeeded = false');
73         tab.EvaluateJavaScript(
74           'window.domAutomationController._finished = false');
75         # Crash the GPU process.
76         new_tab = tab.browser.tabs.New()
77         # To access these debug URLs from Telemetry, they have to be
78         # written using the chrome:// scheme.
79         # The try/except is a workaround for crbug.com/368107.
80         try:
81           new_tab.Navigate('chrome://gpucrash')
82         except (exceptions.TabCrashException, Exception):
83           print 'Tab crashed while navigating to chrome://gpucrash'
84         # Activate the original tab and wait for completion.
85         tab.Activate()
86         completed = False
87         try:
88           util.WaitFor(lambda: tab.EvaluateJavaScript(
89               'window.domAutomationController._finished'), wait_timeout)
90           completed = True
91         except util.TimeoutException:
92           pass
93         # The try/except is a workaround for crbug.com/368107.
94         try:
95           new_tab.Close()
96         except (exceptions.TabCrashException, Exception):
97           print 'Tab crashed while closing chrome://gpucrash'
98         if not completed:
99           raise page_test.Failure(
100               'Test didn\'t complete (no context lost event?)')
101         if not tab.EvaluateJavaScript(
102           'window.domAutomationController._succeeded'):
103           raise page_test.Failure(
104             'Test failed (context not restored properly?)')
105     elif page.force_garbage_collection:
106       # Try to corce GC to clean up any contexts not attached to the page.
107       # This method seem unreliable, so the page will also attempt to force
108       # GC through excessive allocations.
109       tab.CollectGarbage()
110       completed = False
111       try:
112         print "Waiting for page to finish."
113         util.WaitFor(lambda: tab.EvaluateJavaScript(
114             'window.domAutomationController._finished'), wait_timeout)
115         completed = True
116       except util.TimeoutException:
117         pass
118
119       if not completed:
120         raise page_test.Failure(
121             'Test didn\'t complete (no context restored event?)')
122       if not tab.EvaluateJavaScript(
123         'window.domAutomationController._succeeded'):
124         raise page_test.Failure(
125           'Test failed (context not restored properly?)')
126     else:
127       completed = False
128       try:
129         print "Waiting for page to finish."
130         util.WaitFor(lambda: tab.EvaluateJavaScript(
131             'window.domAutomationController._finished'), wait_timeout)
132         completed = True
133       except util.TimeoutException:
134         pass
135
136       if not completed:
137         raise page_test.Failure('Test didn\'t complete')
138       if not tab.EvaluateJavaScript(
139         'window.domAutomationController._succeeded'):
140         raise page_test.Failure('Test failed')
141
142 class WebGLContextLostFromGPUProcessExitPage(page.Page):
143   def __init__(self, page_set, base_dir):
144     super(WebGLContextLostFromGPUProcessExitPage, self).__init__(
145       url='file://webgl.html?query=kill_after_notification',
146       page_set=page_set,
147       base_dir=base_dir,
148       name='ContextLost.WebGLContextLostFromGPUProcessExit')
149     self.script_to_evaluate_on_commit = harness_script
150     self.kill_gpu_process = True
151     self.number_of_gpu_process_kills = 1
152     self.force_garbage_collection = False
153
154   def RunNavigateSteps(self, action_runner):
155     action_runner.NavigateToPage(self)
156     action_runner.WaitForJavaScriptCondition(
157         'window.domAutomationController._loaded')
158
159
160 class WebGLContextLostFromLoseContextExtensionPage(page.Page):
161   def __init__(self, page_set, base_dir):
162     super(WebGLContextLostFromLoseContextExtensionPage, self).__init__(
163       url='file://webgl.html?query=WEBGL_lose_context',
164       page_set=page_set,
165       base_dir=base_dir,
166       name='ContextLost.WebGLContextLostFromLoseContextExtension')
167     self.script_to_evaluate_on_commit = harness_script
168     self.kill_gpu_process = False
169     self.force_garbage_collection = False
170
171   def RunNavigateSteps(self, action_runner):
172     action_runner.NavigateToPage(self)
173     action_runner.WaitForJavaScriptCondition(
174         'window.domAutomationController._finished')
175
176 class WebGLContextLostFromQuantityPage(page.Page):
177   def __init__(self, page_set, base_dir):
178     super(WebGLContextLostFromQuantityPage, self).__init__(
179       url='file://webgl.html?query=forced_quantity_loss',
180       page_set=page_set,
181       base_dir=base_dir,
182       name='ContextLost.WebGLContextLostFromQuantity')
183     self.script_to_evaluate_on_commit = harness_script
184     self.kill_gpu_process = False
185     self.force_garbage_collection = True
186
187   def RunNavigateSteps(self, action_runner):
188     action_runner.NavigateToPage(self)
189     action_runner.WaitForJavaScriptCondition(
190         'window.domAutomationController._loaded')
191
192 class WebGLContextLostFromSelectElementPage(page.Page):
193   def __init__(self, page_set, base_dir):
194     super(WebGLContextLostFromSelectElementPage, self).__init__(
195       url='file://webgl_with_select_element.html',
196       page_set=page_set,
197       base_dir=base_dir,
198       name='ContextLost.WebGLContextLostFromSelectElement')
199     self.script_to_evaluate_on_commit = harness_script
200     self.kill_gpu_process = False
201     self.force_garbage_collection = False
202
203   def RunNavigateSteps(self, action_runner):
204     action_runner.NavigateToPage(self)
205     action_runner.WaitForJavaScriptCondition(
206         'window.domAutomationController._loaded')
207
208 class ContextLost(test_module.Test):
209   enabled = True
210   test = _ContextLostValidator
211   # For the record, this would have been another way to get the pages
212   # to repeat. pageset_repeat would be another option.
213   # options = {'page_repeat': 5}
214   def CreatePageSet(self, options):
215     ps = page_set.PageSet(
216       file_path=data_path,
217       user_agent_type='desktop',
218       serving_dirs=set(['']))
219     ps.AddPage(WebGLContextLostFromGPUProcessExitPage(ps, ps.base_dir))
220     ps.AddPage(WebGLContextLostFromLoseContextExtensionPage(ps, ps.base_dir))
221     ps.AddPage(WebGLContextLostFromQuantityPage(ps, ps.base_dir))
222     ps.AddPage(WebGLContextLostFromSelectElementPage(ps, ps.base_dir))
223     return ps