Pin Chrome's shortcut to the Win10 Start menu on install and OS upgrade.
[chromium-blink-merge.git] / content / test / gpu / gpu_tests / webgl_conformance.py
blob4dd9cd984ab700d95d8decbb29a1435ad55f48bf
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.
4 import json
5 import optparse
6 import os
7 import sys
9 import gpu_test_base
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"""
24 var testHarness = {};
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;
38 if(!success) {
39 testHarness._failures++;
40 if(msg) {
41 testHarness.log(msg);
45 testHarness.notifyFinished = function(url) {
46 testHarness._finished = true;
48 testHarness.navigateToPage = function(src) {
49 var testFrame = document.getElementById("test-frame");
50 testFrame.src = src;
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 """
62 def _DidWebGLTestSucceed(tab):
63 return tab.EvaluateJavaScript('webglTestHarness._allTestSucceeded')
65 def _WebGLTestMessages(tab):
66 return tab.EvaluateJavaScript('webglTestHarness._messages')
68 def _CompareVersion(version1, version2):
69 ver_num1 = [int(x) for x in version1.split('.')]
70 ver_num2 = [int(x) for x in version2.split('.')]
71 size = min(len(ver_num1), len(ver_num2))
72 return cmp(ver_num1[0:size], ver_num2[0:size])
74 class WebglConformanceValidator(gpu_test_base.ValidatorBase):
75 def __init__(self):
76 super(WebglConformanceValidator, self).__init__()
78 def ValidateAndMeasurePageInner(self, page, tab, results):
79 if not _DidWebGLTestSucceed(tab):
80 raise page_test.Failure(_WebGLTestMessages(tab))
82 def CustomizeBrowserOptions(self, options):
83 options.AppendExtraBrowserArgs([
84 '--disable-gesture-requirement-for-media-playback',
85 '--disable-domain-blocking-for-3d-apis',
86 '--disable-gpu-process-crash-limit'
88 browser = browser_finder.FindBrowser(options.finder_options)
89 if (browser.target_os.startswith('android') and
90 browser.browser_type == 'android-webview-shell'):
91 # TODO(kbr): this is overly broad. We'd like to do this only on
92 # Nexus 9. It'll go away shortly anyway. crbug.com/499928
94 # The --ignore_egl_sync_failures is only there to work around
95 # some strange failure on the Nexus 9 bot, not reproducible on
96 # local hardware.
97 options.AppendExtraBrowserArgs([
98 '--disable-gl-extensions=GL_EXT_disjoint_timer_query',
99 '--ignore_egl_sync_failures'
103 class Webgl2ConformanceValidator(WebglConformanceValidator):
104 def __init__(self):
105 super(Webgl2ConformanceValidator, self).__init__()
107 def CustomizeBrowserOptions(self, options):
108 options.AppendExtraBrowserArgs([
109 '--disable-gesture-requirement-for-media-playback',
110 '--disable-domain-blocking-for-3d-apis',
111 '--disable-gpu-process-crash-limit',
112 '--enable-unsafe-es3-apis'
115 class WebglConformancePage(gpu_test_base.PageBase):
116 def __init__(self, story_set, test, expectations):
117 super(WebglConformancePage, self).__init__(
118 url='file://' + test, page_set=story_set, base_dir=story_set.base_dir,
119 shared_page_state_class=shared_page_state.SharedDesktopPageState,
120 name=('WebglConformance.%s' %
121 test.replace('/', '_').replace('-', '_').
122 replace('\\', '_').rpartition('.')[0].replace('.', '_')),
123 expectations=expectations)
124 self.script_to_evaluate_on_commit = conformance_harness_script
126 def RunNavigateStepsInner(self, action_runner):
127 num_tries = 1 + self.GetExpectations().GetFlakyRetriesForPage(
128 self, action_runner.tab.browser)
129 # This loop will run once for tests that aren't marked flaky, and
130 # will fall through to the validator's ValidateAndMeasurePage on
131 # the last iteration.
132 for ii in xrange(0, num_tries):
133 # The first time through, the superclass has already run the
134 # default navigation steps.
135 if ii > 0:
136 self.RunDefaultNavigateSteps(action_runner)
137 action_runner.WaitForJavaScriptCondition(
138 'webglTestHarness._finished', timeout_in_seconds=180)
139 if ii < num_tries - 1:
140 if _DidWebGLTestSucceed(action_runner.tab):
141 return
142 else:
143 print 'FLAKY TEST FAILURE, retrying: ' + self.display_name
144 print 'Error messages from test run:'
145 print _WebGLTestMessages(action_runner.tab)
147 class WebglConformance(gpu_test_base.TestBase):
148 """Conformance with Khronos WebGL Conformance Tests"""
149 def __init__(self):
150 super(WebglConformance, self).__init__(max_failures=10)
151 self._cached_expectations = None
153 @classmethod
154 def Name(cls):
155 return 'webgl_conformance'
157 @classmethod
158 def AddBenchmarkCommandLineArgs(cls, group):
159 group.add_option('--webgl-conformance-version',
160 help='Version of the WebGL conformance tests to run.',
161 default='1.0.4')
162 group.add_option('--webgl2-only',
163 help='Whether we include webgl 1 tests if version is 2.0.0 or above.',
164 default='false')
166 def CreatePageTest(self, options):
167 if _CompareVersion(options.webgl_conformance_version, '2.0.0') >= 0:
168 return Webgl2ConformanceValidator()
169 return WebglConformanceValidator()
171 def CreateStorySet(self, options):
172 tests = self._ParseTests('00_test_list.txt',
173 options.webgl_conformance_version,
174 (options.webgl2_only == 'true'),
175 None)
177 ps = StorySet(serving_dirs=[''], base_dir=conformance_path)
179 expectations = self.GetExpectations()
180 for test in tests:
181 ps.AddStory(WebglConformancePage(ps, test, expectations))
183 return ps
185 def _CreateExpectations(self):
186 return webgl_conformance_expectations.WebGLConformanceExpectations(
187 conformance_path)
189 @staticmethod
190 def _ParseTests(path, version, webgl2_only, folder_min_version):
191 test_paths = []
192 current_dir = os.path.dirname(path)
193 full_path = os.path.normpath(os.path.join(conformance_path, path))
195 if not os.path.exists(full_path):
196 raise Exception('The WebGL conformance test path specified ' +
197 'does not exist: ' + full_path)
199 with open(full_path, 'r') as f:
200 for line in f:
201 line = line.strip()
203 if not line:
204 continue
206 if line.startswith('//') or line.startswith('#'):
207 continue
209 line_tokens = line.split(' ')
210 test_name = line_tokens[-1]
212 i = 0
213 min_version = None
214 while i < len(line_tokens):
215 token = line_tokens[i]
216 if token == '--min-version':
217 i += 1
218 min_version = line_tokens[i]
219 i += 1
221 min_version_to_compare = min_version or folder_min_version
223 if (min_version_to_compare and
224 _CompareVersion(version, min_version_to_compare) < 0):
225 continue
227 if (webgl2_only and (not ('.txt' in test_name)) and
228 ((not min_version_to_compare) or
229 (not min_version_to_compare.startswith('2')))):
230 continue
232 if '.txt' in test_name:
233 include_path = os.path.join(current_dir, test_name)
234 # We only check min-version >= 2.0.0 for the top level list.
235 test_paths += WebglConformance._ParseTests(
236 include_path, version, webgl2_only, min_version_to_compare)
237 else:
238 test = os.path.join(current_dir, test_name)
239 test_paths.append(test)
241 return test_paths