1 # Copyright (c) 2012 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.
10 import webgl_conformance_expectations
12 from telemetry
.core
import util
13 from telemetry
.internal
.browser
import browser_finder
14 from telemetry
.page
import page_test
15 from telemetry
.page
import shared_page_state
16 from telemetry
.story
.story_set
import StorySet
19 conformance_path
= os
.path
.join(
20 util
.GetChromiumSrcDir(),
21 'third_party', 'webgl', 'src', 'sdk', 'tests')
23 conformance_harness_script
= r
"""
25 testHarness._allTestSucceeded = true;
26 testHarness._messages = '';
27 testHarness._failures = 0;
28 testHarness._finished = false;
29 testHarness._originalLog = window.console.log;
31 testHarness.log = function(msg) {
32 testHarness._messages += msg + "\n";
33 testHarness._originalLog.apply(window.console, [msg]);
36 testHarness.reportResults = function(url, success, msg) {
37 testHarness._allTestSucceeded = testHarness._allTestSucceeded && !!success;
39 testHarness._failures++;
45 testHarness.notifyFinished = function(url) {
46 testHarness._finished = true;
48 testHarness.navigateToPage = function(src) {
49 var testFrame = document.getElementById("test-frame");
53 window.webglTestHarness = testHarness;
54 window.parent.webglTestHarness = testHarness;
55 window.console.log = testHarness.log;
56 window.onerror = function(message, url, line) {
57 testHarness.reportResults(null, false, message);
58 testHarness.notifyFinished(null);
60 window.quietMode = function() { return true; }
63 def _DidWebGLTestSucceed(tab
):
64 return tab
.EvaluateJavaScript('webglTestHarness._allTestSucceeded')
66 def _WebGLTestMessages(tab
):
67 return tab
.EvaluateJavaScript('webglTestHarness._messages')
69 def _CompareVersion(version1
, version2
):
70 ver_num1
= [int(x
) for x
in version1
.split('.')]
71 ver_num2
= [int(x
) for x
in version2
.split('.')]
72 size
= min(len(ver_num1
), len(ver_num2
))
73 return cmp(ver_num1
[0:size
], ver_num2
[0:size
])
75 class WebglConformanceValidator(gpu_test_base
.ValidatorBase
):
77 super(WebglConformanceValidator
, self
).__init
__()
79 def ValidateAndMeasurePageInner(self
, page
, tab
, results
):
80 if not _DidWebGLTestSucceed(tab
):
81 raise page_test
.Failure(_WebGLTestMessages(tab
))
83 def CustomizeBrowserOptions(self
, options
):
84 options
.AppendExtraBrowserArgs([
85 '--disable-gesture-requirement-for-media-playback',
86 '--disable-domain-blocking-for-3d-apis',
87 '--disable-gpu-process-crash-limit'
89 browser
= browser_finder
.FindBrowser(options
.finder_options
)
90 if (browser
.target_os
.startswith('android') and
91 browser
.browser_type
== 'android-webview-shell'):
92 # TODO(kbr): this is overly broad. We'd like to do this only on
93 # Nexus 9. It'll go away shortly anyway. crbug.com/499928
95 # The --ignore_egl_sync_failures is only there to work around
96 # some strange failure on the Nexus 9 bot, not reproducible on
98 options
.AppendExtraBrowserArgs([
99 '--disable-gl-extensions=GL_EXT_disjoint_timer_query',
100 '--ignore_egl_sync_failures'
104 class Webgl2ConformanceValidator(WebglConformanceValidator
):
106 super(Webgl2ConformanceValidator
, self
).__init
__()
108 def CustomizeBrowserOptions(self
, options
):
109 options
.AppendExtraBrowserArgs([
110 '--disable-gesture-requirement-for-media-playback',
111 '--disable-domain-blocking-for-3d-apis',
112 '--disable-gpu-process-crash-limit',
113 '--enable-unsafe-es3-apis'
116 class WebglConformancePage(gpu_test_base
.PageBase
):
117 def __init__(self
, story_set
, test
, expectations
):
118 super(WebglConformancePage
, self
).__init
__(
119 url
='file://' + test
, page_set
=story_set
, base_dir
=story_set
.base_dir
,
120 shared_page_state_class
=gpu_test_base
.DesktopGpuSharedPageState
,
121 name
=('WebglConformance.%s' %
122 test
.replace('/', '_').replace('-', '_').
123 replace('\\', '_').rpartition('.')[0].replace('.', '_')),
124 expectations
=expectations
)
125 self
.script_to_evaluate_on_commit
= conformance_harness_script
127 def RunNavigateStepsInner(self
, action_runner
):
128 self
.RunDefaultNavigateSteps(action_runner
)
129 action_runner
.WaitForJavaScriptCondition(
130 'webglTestHarness._finished', timeout_in_seconds
=180)
132 class WebglConformance(gpu_test_base
.TestBase
):
133 """Conformance with Khronos WebGL Conformance Tests"""
135 super(WebglConformance
, self
).__init
__(max_failures
=10)
136 self
._cached
_expectations
= None
140 return 'webgl_conformance'
143 def AddBenchmarkCommandLineArgs(cls
, group
):
144 group
.add_option('--webgl-conformance-version',
145 help='Version of the WebGL conformance tests to run.',
147 group
.add_option('--webgl2-only',
148 help='Whether we include webgl 1 tests if version is 2.0.0 or above.',
151 def CreatePageTest(self
, options
):
152 if _CompareVersion(options
.webgl_conformance_version
, '2.0.0') >= 0:
153 return Webgl2ConformanceValidator()
154 return WebglConformanceValidator()
156 def CreateStorySet(self
, options
):
157 tests
= self
._ParseTests
('00_test_list.txt',
158 options
.webgl_conformance_version
,
159 (options
.webgl2_only
== 'true'),
162 ps
= StorySet(serving_dirs
=[''], base_dir
=conformance_path
)
164 expectations
= self
.GetExpectations()
166 ps
.AddStory(WebglConformancePage(ps
, test
, expectations
))
170 def _CreateExpectations(self
):
171 return webgl_conformance_expectations
.WebGLConformanceExpectations(
175 def _ParseTests(path
, version
, webgl2_only
, folder_min_version
):
177 current_dir
= os
.path
.dirname(path
)
178 full_path
= os
.path
.normpath(os
.path
.join(conformance_path
, path
))
180 if not os
.path
.exists(full_path
):
181 raise Exception('The WebGL conformance test path specified ' +
182 'does not exist: ' + full_path
)
184 with
open(full_path
, 'r') as f
:
191 if line
.startswith('//') or line
.startswith('#'):
194 line_tokens
= line
.split(' ')
195 test_name
= line_tokens
[-1]
199 while i
< len(line_tokens
):
200 token
= line_tokens
[i
]
201 if token
== '--min-version':
203 min_version
= line_tokens
[i
]
206 min_version_to_compare
= min_version
or folder_min_version
208 if (min_version_to_compare
and
209 _CompareVersion(version
, min_version_to_compare
) < 0):
212 if (webgl2_only
and (not ('.txt' in test_name
)) and
213 ((not min_version_to_compare
) or
214 (not min_version_to_compare
.startswith('2')))):
217 if '.txt' in test_name
:
218 include_path
= os
.path
.join(current_dir
, test_name
)
219 # We only check min-version >= 2.0.0 for the top level list.
220 test_paths
+= WebglConformance
._ParseTests
(
221 include_path
, version
, webgl2_only
, min_version_to_compare
)
223 test
= os
.path
.join(current_dir
, test_name
)
224 test_paths
.append(test
)