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 |
44 class _ContextLostValidator(page_test.PageTest): | 50 class _ContextLostValidator(page_test.PageTest): |
45 def __init__(self): | 51 def __init__(self): |
46 # Strictly speaking this test doesn't yet need a browser restart | 52 # 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 | 53 # after each run, but if more tests are added which crash the GPU |
48 # process, then it will. | 54 # process, then it will. |
49 super(_ContextLostValidator, self).__init__( | 55 super(_ContextLostValidator, self).__init__( |
50 needs_browser_restart_after_each_page=True) | 56 needs_browser_restart_after_each_page=True) |
51 | 57 |
52 def CustomizeBrowserOptions(self, options): | 58 def CustomizeBrowserOptions(self, options): |
53 options.AppendExtraBrowserArgs( | 59 options.AppendExtraBrowserArgs( |
54 '--disable-domain-blocking-for-3d-apis') | 60 '--disable-domain-blocking-for-3d-apis') |
55 options.AppendExtraBrowserArgs( | 61 options.AppendExtraBrowserArgs( |
56 '--disable-gpu-process-crash-limit') | 62 '--disable-gpu-process-crash-limit') |
57 # Required for about:gpucrash handling from Telemetry. | 63 # Required for about:gpucrash handling from Telemetry. |
58 options.AppendExtraBrowserArgs('--enable-gpu-benchmarking') | 64 options.AppendExtraBrowserArgs('--enable-gpu-benchmarking') |
59 | 65 |
60 def ValidatePage(self, page, tab, results): | 66 def ValidatePage(self, page, tab, results): |
61 if page.kill_gpu_process: | 67 if page.kill_gpu_process: |
62 # Doing the GPU process kill operation cooperatively -- in the | 68 # Doing the GPU process kill operation cooperatively -- in the |
63 # same page's context -- is much more stressful than restarting | 69 # same page's context -- is much more stressful than restarting |
64 # the browser every time. | 70 # the browser every time. |
65 for x in range(page.number_of_gpu_process_kills): | 71 for x in range(page.number_of_gpu_process_kills): |
66 if not tab.browser.supports_tab_control: | 72 if not tab.browser.supports_tab_control: |
67 raise page_test.Failure('Browser must support tab control') | 73 raise page_test.Failure('Browser must support tab control') |
74 | |
75 expected_kills = x + 1 | |
76 | |
68 # Reset the test's state. | 77 # Reset the test's state. |
69 tab.EvaluateJavaScript( | 78 tab.EvaluateJavaScript( |
70 'window.domAutomationController._succeeded = false'); | 79 'window.domAutomationController.reset()'); |
71 tab.EvaluateJavaScript( | 80 |
72 'window.domAutomationController._finished = false'); | 81 # If we're running the GPU process crash test, we need the |
82 # test to have fully reset before crashing the GPU process. | |
83 if page.check_crash_count: | |
84 util.WaitFor(lambda: tab.EvaluateJavaScript( | |
85 'window.domAutomationController._finished'), wait_timeout) | |
86 | |
73 # Crash the GPU process. | 87 # Crash the GPU process. |
74 new_tab = tab.browser.tabs.New() | 88 gpucrash_tab = tab.browser.tabs.New() |
75 # To access these debug URLs from Telemetry, they have to be | 89 # To access these debug URLs from Telemetry, they have to be |
76 # written using the chrome:// scheme. | 90 # written using the chrome:// scheme. |
77 # The try/except is a workaround for crbug.com/368107. | 91 # The try/except is a workaround for crbug.com/368107. |
78 try: | 92 try: |
79 new_tab.Navigate('chrome://gpucrash') | 93 gpucrash_tab.Navigate('chrome://gpucrash') |
80 except (exceptions.TabCrashException, Exception): | 94 except (exceptions.TabCrashException, Exception): |
81 print 'Tab crashed while navigating to chrome://gpucrash' | 95 print 'Tab crashed while navigating to chrome://gpucrash' |
82 # Activate the original tab and wait for completion. | 96 # Activate the original tab and wait for completion. |
83 tab.Activate() | 97 tab.Activate() |
84 completed = False | 98 completed = False |
85 try: | 99 try: |
86 util.WaitFor(lambda: tab.EvaluateJavaScript( | 100 util.WaitFor(lambda: tab.EvaluateJavaScript( |
87 'window.domAutomationController._finished'), wait_timeout) | 101 'window.domAutomationController._finished'), wait_timeout) |
88 completed = True | 102 completed = True |
89 except util.TimeoutException: | 103 except util.TimeoutException: |
90 pass | 104 pass |
105 | |
106 if page.check_crash_count: | |
107 if not tab.browser.supports_system_info: | |
108 raise page_test.Failure('Browser must support system info') | |
109 | |
110 if not tab.EvaluateJavaScript( | |
111 'window.domAutomationController._succeeded'): | |
112 raise page_test.Failure( | |
113 'Test failed (didn\'t render content properly?)') | |
114 | |
115 number_of_crashes = -1 | |
116 # To allow time for a gpucrash to complete, wait up to 20s, | |
117 # polling repeatedly. | |
118 start_time = time.time() | |
119 current_time = time.time() | |
120 while current_time - start_time < 20: | |
121 system_info = tab.browser.GetSystemInfo() | |
122 number_of_crashes = \ | |
123 system_info.gpu.aux_attributes[u'process_crash_count'] | |
124 if number_of_crashes >= expected_kills: | |
125 break | |
126 time.sleep(1) | |
127 current_time = time.time() | |
128 | |
129 # Wait 5 more seconds and re-read process_crash_count, in attempt | |
130 # to attempt to catch latent process crashes. | |
Ken Russell (switch to Gerrit)
2014/07/28 23:09:32
also, typo in comment: "in attempt to attempt to"
vmiura
2014/07/28 23:12:55
Done.
| |
131 time.sleep(5) | |
132 system_info = tab.browser.GetSystemInfo() | |
133 number_of_crashes = \ | |
134 system_info.gpu.aux_attributes[u'process_crash_count'] | |
135 | |
136 if number_of_crashes < expected_kills: | |
137 raise page_test.Failure( | |
138 'Timed out waiting for a gpu process crash') | |
139 elif number_of_crashes != expected_kills: | |
140 raise page_test.Failure( | |
141 'Expected %d gpu process crashes; got: %d' % | |
142 (expected_kills, number_of_crashes)) | |
143 | |
91 # The try/except is a workaround for crbug.com/368107. | 144 # The try/except is a workaround for crbug.com/368107. |
92 try: | 145 try: |
93 new_tab.Close() | 146 gpucrash_tab.Close() |
94 except (exceptions.TabCrashException, Exception): | 147 except (exceptions.TabCrashException, Exception): |
95 print 'Tab crashed while closing chrome://gpucrash' | 148 print 'Tab crashed while closing chrome://gpucrash' |
96 if not completed: | 149 if not completed: |
97 raise page_test.Failure( | 150 raise page_test.Failure( |
98 'Test didn\'t complete (no context lost event?)') | 151 'Test didn\'t complete (no context lost event?)') |
99 if not tab.EvaluateJavaScript( | 152 if not tab.EvaluateJavaScript( |
100 'window.domAutomationController._succeeded'): | 153 'window.domAutomationController._succeeded'): |
101 raise page_test.Failure( | 154 raise page_test.Failure( |
102 'Test failed (context not restored properly?)') | 155 'Test failed (context not restored properly?)') |
103 elif page.force_garbage_collection: | 156 elif page.force_garbage_collection: |
(...skipping 26 matching lines...) Expand all Loading... | |
130 completed = True | 183 completed = True |
131 except util.TimeoutException: | 184 except util.TimeoutException: |
132 pass | 185 pass |
133 | 186 |
134 if not completed: | 187 if not completed: |
135 raise page_test.Failure('Test didn\'t complete') | 188 raise page_test.Failure('Test didn\'t complete') |
136 if not tab.EvaluateJavaScript( | 189 if not tab.EvaluateJavaScript( |
137 'window.domAutomationController._succeeded'): | 190 'window.domAutomationController._succeeded'): |
138 raise page_test.Failure('Test failed') | 191 raise page_test.Failure('Test failed') |
139 | 192 |
193 # Test that navigating to chrome://gpucrash causes the GPU process to crash | |
194 # exactly one time per navigation. | |
195 class GPUProcessCrashesExactlyOnce(page.Page): | |
196 def __init__(self, page_set, base_dir): | |
197 super(GPUProcessCrashesExactlyOnce, self).__init__( | |
198 url='file://gpu_process_crash.html', | |
199 page_set=page_set, | |
200 base_dir=base_dir, | |
201 name='GpuCrash.GPUProcessCrashesExactlyOnce') | |
202 self.script_to_evaluate_on_commit = harness_script | |
203 self.kill_gpu_process = True | |
204 self.number_of_gpu_process_kills = 2 | |
205 self.check_crash_count = True | |
206 self.force_garbage_collection = False | |
207 | |
208 def RunNavigateSteps(self, action_runner): | |
209 action_runner.NavigateToPage(self) | |
210 action_runner.WaitForJavaScriptCondition( | |
211 'window.domAutomationController._loaded') | |
212 | |
140 class WebGLContextLostFromGPUProcessExitPage(page.Page): | 213 class WebGLContextLostFromGPUProcessExitPage(page.Page): |
141 def __init__(self, page_set, base_dir): | 214 def __init__(self, page_set, base_dir): |
142 super(WebGLContextLostFromGPUProcessExitPage, self).__init__( | 215 super(WebGLContextLostFromGPUProcessExitPage, self).__init__( |
143 url='file://webgl.html?query=kill_after_notification', | 216 url='file://webgl.html?query=kill_after_notification', |
144 page_set=page_set, | 217 page_set=page_set, |
145 base_dir=base_dir, | 218 base_dir=base_dir, |
146 name='ContextLost.WebGLContextLostFromGPUProcessExit') | 219 name='ContextLost.WebGLContextLostFromGPUProcessExit') |
147 self.script_to_evaluate_on_commit = harness_script | 220 self.script_to_evaluate_on_commit = harness_script |
148 self.kill_gpu_process = True | 221 self.kill_gpu_process = True |
222 self.check_crash_count = False | |
149 self.number_of_gpu_process_kills = 1 | 223 self.number_of_gpu_process_kills = 1 |
150 self.force_garbage_collection = False | 224 self.force_garbage_collection = False |
151 | 225 |
152 def RunNavigateSteps(self, action_runner): | 226 def RunNavigateSteps(self, action_runner): |
153 action_runner.NavigateToPage(self) | 227 action_runner.NavigateToPage(self) |
154 action_runner.WaitForJavaScriptCondition( | 228 action_runner.WaitForJavaScriptCondition( |
155 'window.domAutomationController._loaded') | 229 'window.domAutomationController._loaded') |
156 | 230 |
157 | 231 |
158 class WebGLContextLostFromLoseContextExtensionPage(page.Page): | 232 class WebGLContextLostFromLoseContextExtensionPage(page.Page): |
159 def __init__(self, page_set, base_dir): | 233 def __init__(self, page_set, base_dir): |
160 super(WebGLContextLostFromLoseContextExtensionPage, self).__init__( | 234 super(WebGLContextLostFromLoseContextExtensionPage, self).__init__( |
161 url='file://webgl.html?query=WEBGL_lose_context', | 235 url='file://webgl.html?query=WEBGL_lose_context', |
162 page_set=page_set, | 236 page_set=page_set, |
163 base_dir=base_dir, | 237 base_dir=base_dir, |
164 name='ContextLost.WebGLContextLostFromLoseContextExtension') | 238 name='ContextLost.WebGLContextLostFromLoseContextExtension') |
165 self.script_to_evaluate_on_commit = harness_script | 239 self.script_to_evaluate_on_commit = harness_script |
166 self.kill_gpu_process = False | 240 self.kill_gpu_process = False |
241 self.check_crash_count = False | |
167 self.force_garbage_collection = False | 242 self.force_garbage_collection = False |
168 | 243 |
169 def RunNavigateSteps(self, action_runner): | 244 def RunNavigateSteps(self, action_runner): |
170 action_runner.NavigateToPage(self) | 245 action_runner.NavigateToPage(self) |
171 action_runner.WaitForJavaScriptCondition( | 246 action_runner.WaitForJavaScriptCondition( |
172 'window.domAutomationController._finished') | 247 'window.domAutomationController._finished') |
173 | 248 |
174 class WebGLContextLostFromQuantityPage(page.Page): | 249 class WebGLContextLostFromQuantityPage(page.Page): |
175 def __init__(self, page_set, base_dir): | 250 def __init__(self, page_set, base_dir): |
176 super(WebGLContextLostFromQuantityPage, self).__init__( | 251 super(WebGLContextLostFromQuantityPage, self).__init__( |
177 url='file://webgl.html?query=forced_quantity_loss', | 252 url='file://webgl.html?query=forced_quantity_loss', |
178 page_set=page_set, | 253 page_set=page_set, |
179 base_dir=base_dir, | 254 base_dir=base_dir, |
180 name='ContextLost.WebGLContextLostFromQuantity') | 255 name='ContextLost.WebGLContextLostFromQuantity') |
181 self.script_to_evaluate_on_commit = harness_script | 256 self.script_to_evaluate_on_commit = harness_script |
182 self.kill_gpu_process = False | 257 self.kill_gpu_process = False |
258 self.check_crash_count = False | |
183 self.force_garbage_collection = True | 259 self.force_garbage_collection = True |
184 | 260 |
185 def RunNavigateSteps(self, action_runner): | 261 def RunNavigateSteps(self, action_runner): |
186 action_runner.NavigateToPage(self) | 262 action_runner.NavigateToPage(self) |
187 action_runner.WaitForJavaScriptCondition( | 263 action_runner.WaitForJavaScriptCondition( |
188 'window.domAutomationController._loaded') | 264 'window.domAutomationController._loaded') |
189 | 265 |
190 class WebGLContextLostFromSelectElementPage(page.Page): | 266 class WebGLContextLostFromSelectElementPage(page.Page): |
191 def __init__(self, page_set, base_dir): | 267 def __init__(self, page_set, base_dir): |
192 super(WebGLContextLostFromSelectElementPage, self).__init__( | 268 super(WebGLContextLostFromSelectElementPage, self).__init__( |
193 url='file://webgl_with_select_element.html', | 269 url='file://webgl_with_select_element.html', |
194 page_set=page_set, | 270 page_set=page_set, |
195 base_dir=base_dir, | 271 base_dir=base_dir, |
196 name='ContextLost.WebGLContextLostFromSelectElement') | 272 name='ContextLost.WebGLContextLostFromSelectElement') |
197 self.script_to_evaluate_on_commit = harness_script | 273 self.script_to_evaluate_on_commit = harness_script |
198 self.kill_gpu_process = False | 274 self.kill_gpu_process = False |
275 self.check_crash_count = False | |
199 self.force_garbage_collection = False | 276 self.force_garbage_collection = False |
200 | 277 |
201 def RunNavigateSteps(self, action_runner): | 278 def RunNavigateSteps(self, action_runner): |
202 action_runner.NavigateToPage(self) | 279 action_runner.NavigateToPage(self) |
203 action_runner.WaitForJavaScriptCondition( | 280 action_runner.WaitForJavaScriptCondition( |
204 'window.domAutomationController._loaded') | 281 'window.domAutomationController._loaded') |
205 | 282 |
206 class ContextLost(benchmark_module.Benchmark): | 283 class ContextLost(benchmark_module.Benchmark): |
207 enabled = True | 284 enabled = True |
208 test = _ContextLostValidator | 285 test = _ContextLostValidator |
209 # For the record, this would have been another way to get the pages | 286 # For the record, this would have been another way to get the pages |
210 # to repeat. pageset_repeat would be another option. | 287 # to repeat. pageset_repeat would be another option. |
211 # options = {'page_repeat': 5} | 288 # options = {'page_repeat': 5} |
212 def CreatePageSet(self, options): | 289 def CreatePageSet(self, options): |
213 ps = page_set.PageSet( | 290 ps = page_set.PageSet( |
214 file_path=data_path, | 291 file_path=data_path, |
215 user_agent_type='desktop', | 292 user_agent_type='desktop', |
216 serving_dirs=set([''])) | 293 serving_dirs=set([''])) |
294 ps.AddPage(GPUProcessCrashesExactlyOnce(ps, ps.base_dir)) | |
217 ps.AddPage(WebGLContextLostFromGPUProcessExitPage(ps, ps.base_dir)) | 295 ps.AddPage(WebGLContextLostFromGPUProcessExitPage(ps, ps.base_dir)) |
218 ps.AddPage(WebGLContextLostFromLoseContextExtensionPage(ps, ps.base_dir)) | 296 ps.AddPage(WebGLContextLostFromLoseContextExtensionPage(ps, ps.base_dir)) |
219 ps.AddPage(WebGLContextLostFromQuantityPage(ps, ps.base_dir)) | 297 ps.AddPage(WebGLContextLostFromQuantityPage(ps, ps.base_dir)) |
220 ps.AddPage(WebGLContextLostFromSelectElementPage(ps, ps.base_dir)) | 298 ps.AddPage(WebGLContextLostFromSelectElementPage(ps, ps.base_dir)) |
221 return ps | 299 return ps |
OLD | NEW |