Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(297)

Side by Side Diff: content/test/gpu/gpu_tests/context_lost_integration_test.py

Issue 2271543002: Port context_lost test to new GpuIntegrationTest harness. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Addressed review feedback from eyaich. Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | content/test/gpu/gpu_tests/gpu_integration_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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
3 # found in the LICENSE file.
4
5 import os
6 import time
7
8 from gpu_tests import gpu_integration_test
9 from gpu_tests import context_lost_expectations
10 from gpu_tests import path_util
11
12 from telemetry.core import exceptions
13 from telemetry.core import util
14
15 data_path = os.path.join(
16 path_util.GetChromiumSrcDir(), 'content', 'test', 'data', 'gpu')
17
18 wait_timeout = 60 # 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 /* Don't squelch earlier failures! */
35 if (!domAutomationController._finished) {
36 domAutomationController._succeeded = true;
37 }
38 domAutomationController._finished = true;
39 } else {
40 /* Always record failures. */
41 domAutomationController._succeeded = false;
42 domAutomationController._finished = true;
43 }
44 }
45
46 domAutomationController.reset = function() {
47 domAutomationController._succeeded = false;
48 domAutomationController._finished = false;
49 }
50
51 window.domAutomationController = domAutomationController;
52 console.log("Harness injected.");
53 """
54
55 class ContextLostIntegrationTest(gpu_integration_test.GpuIntegrationTest):
56
57 @classmethod
58 def Name(cls):
59 return 'context_lost'
60
61 @classmethod
62 def CustomizeOptions(cls):
63 options = cls._finder_options.browser_options
64 options.AppendExtraBrowserArgs(
65 '--disable-domain-blocking-for-3d-apis')
66 options.AppendExtraBrowserArgs(
67 '--disable-gpu-process-crash-limit')
68 # Required for about:gpucrash handling from Telemetry.
69 options.AppendExtraBrowserArgs('--enable-gpu-benchmarking')
70
71 @classmethod
72 def GenerateGpuTests(cls, options):
73 tests = (('GPUProcessCrashesExactlyOncePerVisitToAboutGpuCrash',
74 'gpu_process_crash.html'),
75 ('WebGLContextLostFromGPUProcessExit',
76 'webgl.html?query=kill_after_notification'),
77 ('WebGLContextLostFromLoseContextExtension',
78 'webgl.html?query=WEBGL_lose_context'),
79 ('WebGLContextLostFromQuantity',
80 'webgl.html?query=forced_quantity_loss'),
81 ('WebGLContextLostFromSelectElement',
82 'webgl_with_select_element.html'),
83 ('WebGLContextLostInHiddenTab',
84 'webgl.html?query=kill_after_notification'))
85 for t in tests:
86 yield (t[0], t[1], ('_' + t[0]))
87
88 def RunActualGpuTest(self, test_path, *args):
89 test_name = args[0]
90 tab = self.tab
91 if not tab.browser.supports_tab_control:
92 self.fail('Browser must support tab control')
93 getattr(self, test_name)(test_path)
94
95 @classmethod
96 def _CreateExpectations(cls):
97 return context_lost_expectations.ContextLostExpectations()
98
99 @classmethod
100 def setUpClass(cls):
101 super(cls, ContextLostIntegrationTest).setUpClass()
102 cls.CustomizeOptions()
103 cls.SetBrowserOptions(cls._finder_options)
104 cls.StartBrowser()
105 cls.SetStaticServerDir(data_path)
106
107 def _WaitForPageToFinish(self, tab):
108 try:
109 util.WaitFor(lambda: tab.EvaluateJavaScript(
110 'window.domAutomationController._finished'), wait_timeout)
111 return True
112 except exceptions.TimeoutException:
113 return False
114
115 def _KillGPUProcess(self, tab, number_of_gpu_process_kills,
116 check_crash_count):
117 # Doing the GPU process kill operation cooperatively -- in the
118 # same page's context -- is much more stressful than restarting
119 # the browser every time.
120 for x in range(number_of_gpu_process_kills):
121 expected_kills = x + 1
122
123 # Reset the test's state.
124 tab.EvaluateJavaScript(
125 'window.domAutomationController.reset()')
126
127 # If we're running the GPU process crash test, we need the test
128 # to have fully reset before crashing the GPU process.
129 if check_crash_count:
130 util.WaitFor(lambda: tab.EvaluateJavaScript(
131 'window.domAutomationController._finished'), wait_timeout)
132
133 # Crash the GPU process.
134 gpucrash_tab = tab.browser.tabs.New()
135 # To access these debug URLs from Telemetry, they have to be
136 # written using the chrome:// scheme.
137 # The try/except is a workaround for crbug.com/368107.
138 try:
139 gpucrash_tab.Navigate('chrome://gpucrash')
140 except Exception:
141 print 'Tab crashed while navigating to chrome://gpucrash'
142 # Activate the original tab and wait for completion.
143 tab.Activate()
144 completed = self._WaitForPageToFinish(tab)
145
146 if check_crash_count:
147 self._CheckCrashCount(tab, expected_kills)
148
149 # The try/except is a workaround for crbug.com/368107.
150 try:
151 gpucrash_tab.Close()
152 except Exception:
153 print 'Tab crashed while closing chrome://gpucrash'
154 if not completed:
155 self.fail('Test didn\'t complete (no context lost event?)')
156 if not tab.EvaluateJavaScript(
157 'window.domAutomationController._succeeded'):
158 self.fail('Test failed (context not restored properly?)')
159
160 def _CheckCrashCount(self, tab, expected_kills):
161 if not tab.browser.supports_system_info:
162 self.fail('Browser must support system info')
163
164 if not tab.EvaluateJavaScript(
165 'window.domAutomationController._succeeded'):
166 self.fail('Test failed (didn\'t render content properly?)')
167
168 number_of_crashes = -1
169 # To allow time for a gpucrash to complete, wait up to 20s,
170 # polling repeatedly.
171 start_time = time.time()
172 current_time = time.time()
173 while current_time - start_time < 20:
174 system_info = tab.browser.GetSystemInfo()
175 number_of_crashes = \
176 system_info.gpu.aux_attributes[u'process_crash_count']
177 if number_of_crashes >= expected_kills:
178 break
179 time.sleep(1)
180 current_time = time.time()
181
182 # Wait 5 more seconds and re-read process_crash_count, in
183 # attempt to catch latent process crashes.
184 time.sleep(5)
185 system_info = tab.browser.GetSystemInfo()
186 number_of_crashes = \
187 system_info.gpu.aux_attributes[u'process_crash_count']
188
189 if number_of_crashes < expected_kills:
190 self.fail('Timed out waiting for a gpu process crash')
191 elif number_of_crashes != expected_kills:
192 self.fail('Expected %d gpu process crashes; got: %d' %
193 (expected_kills, number_of_crashes))
194
195 def _NavigateAndWaitForLoad(self, tab, test_path):
196 url = self.UrlOfStaticFilePath(test_path)
197 tab = self.tab
198 tab.Navigate(url, script_to_evaluate_on_commit=harness_script)
199 tab.action_runner.WaitForJavaScriptCondition(
200 'window.domAutomationController._loaded')
201
202 def _WaitForTabAndCheckCompletion(self, tab):
203 completed = self._WaitForPageToFinish(tab)
204 if not completed:
205 self.fail('Test didn\'t complete (no context restored event?)')
206 if not tab.EvaluateJavaScript('window.domAutomationController._succeeded'):
207 self.fail('Test failed (context not restored properly?)')
208
209 # The browser test runner synthesizes methods with the exact name
210 # given in GenerateGpuTests, so in order to hand-write our tests but
211 # also go through the _RunGpuTest trampoline, the test needs to be
212 # slightly differently named.
213 def _GPUProcessCrashesExactlyOncePerVisitToAboutGpuCrash(self, test_path):
214 tab = self.tab
215 self._NavigateAndWaitForLoad(tab, test_path)
216 self._KillGPUProcess(tab, 2, True)
217 self._RestartBrowser('must restart after tests that kill the GPU process')
218
219 def _WebGLContextLostFromGPUProcessExit(self, test_path):
220 tab = self.tab
eyaich1 2016/08/24 13:28:53 remove this line, done in _NavigateAndWaitForLoad
Ken Russell (switch to Gerrit) 2016/08/25 01:41:01 Done.
221 self._NavigateAndWaitForLoad(tab, test_path)
222 self._KillGPUProcess(tab, 1, False)
223 self._RestartBrowser('must restart after tests that kill the GPU process')
224
225 def _WebGLContextLostFromLoseContextExtension(self, test_path):
226 url = self.UrlOfStaticFilePath(test_path)
227 tab = self.tab
228 tab.Navigate(url, script_to_evaluate_on_commit=harness_script)
229 tab.action_runner.WaitForJavaScriptCondition(
230 'window.domAutomationController._finished')
eyaich1 2016/08/24 13:28:53 Can't you replace this entire function with self._
Ken Russell (switch to Gerrit) 2016/08/25 01:41:01 No, because this one waits for _finished rather th
231
232 def _WebGLContextLostFromQuantity(self, test_path):
233 tab = self.tab
eyaich1 2016/08/24 13:28:53 remove this line, done in _NavigateAndWaitForLoad
Ken Russell (switch to Gerrit) 2016/08/25 01:41:01 This method calls self.tab.CollectGarbage(), but I
234 self._NavigateAndWaitForLoad(tab, test_path)
235 # Try to corce GC to clean up any contexts not attached to the page.
236 # This method seems unreliable, so the page will also attempt to
237 # force GC through excessive allocations.
238 tab.CollectGarbage()
239 self._WaitForTabAndCheckCompletion(tab)
240
241 def _WebGLContextLostFromSelectElement(self, test_path):
242 tab = self.tab
eyaich1 2016/08/24 13:28:53 remove this line, done in _NavigateAndWaitForLoad
Ken Russell (switch to Gerrit) 2016/08/25 01:41:01 Done.
243 self._NavigateAndWaitForLoad(tab, test_path)
244 self._WaitForTabAndCheckCompletion(tab)
245
246 def _WebGLContextLostInHiddenTab(self, test_path):
247 tab = self.tab
eyaich1 2016/08/24 13:28:53 remove this line, done in _NavigateAndWaitForLoad
Ken Russell (switch to Gerrit) 2016/08/25 01:41:01 This one uses "tab" locally in a couple of places,
248 self._NavigateAndWaitForLoad(tab, test_path)
249 # Test losing a context in a hidden tab. This test passes if the tab
250 # doesn't crash.
251 dummy_tab = tab.browser.tabs.New()
252 tab.EvaluateJavaScript('loseContextUsingExtension()')
253 tab.Activate()
254 self._WaitForTabAndCheckCompletion(tab)
OLDNEW
« no previous file with comments | « no previous file | content/test/gpu/gpu_tests/gpu_integration_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698