1c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
2c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
3c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)# found in the LICENSE file.
4eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochimport json
558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)import optparse
6c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import os
7c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)import sys
8c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
9d3868032626d59662ff73b372b5d584c1d144c53Ben Murdochimport webgl_conformance_expectations
10d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
11116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfrom telemetry import benchmark as benchmark_module
12eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochfrom telemetry.core import util
13c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)from telemetry.page import page_set
145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liufrom telemetry.page import page as page_module
15c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)from telemetry.page import page_test
165c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
17c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
18eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconformance_path = os.path.join(
19a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    util.GetChromiumSrcDir(),
20a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles)    'third_party', 'webgl', 'src', 'sdk', 'tests')
21c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
22c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)conformance_harness_script = r"""
23c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  var testHarness = {};
24c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  testHarness._allTestSucceeded = true;
25c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  testHarness._messages = '';
26c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  testHarness._failures = 0;
27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  testHarness._finished = false;
2858537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  testHarness._originalLog = window.console.log;
2958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
3058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  testHarness.log = function(msg) {
3158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    testHarness._messages += msg + "\n";
3258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    testHarness._originalLog.apply(window.console, [msg]);
3358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  }
34c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
35f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  testHarness.reportResults = function(url, success, msg) {
36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    testHarness._allTestSucceeded = testHarness._allTestSucceeded && !!success;
37c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if(!success) {
38c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      testHarness._failures++;
39c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      if(msg) {
4058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        testHarness.log(msg);
41c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      }
42c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    }
43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
44f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  testHarness.notifyFinished = function(url) {
45c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    testHarness._finished = true;
46c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  testHarness.navigateToPage = function(src) {
48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    var testFrame = document.getElementById("test-frame");
49c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    testFrame.src = src;
50c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  };
51c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
52c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window.webglTestHarness = testHarness;
53c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  window.parent.webglTestHarness = testHarness;
5458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)  window.console.log = testHarness.log;
55f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  window.onerror = function(message, url, line) {
561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci    testHarness.reportResults(null, false, message);
57f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    testHarness.notifyFinished(null);
58f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)  };
59c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)"""
60c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
61c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)def _DidWebGLTestSucceed(tab):
62c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return tab.EvaluateJavaScript('webglTestHarness._allTestSucceeded')
63c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
64c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)def _WebGLTestMessages(tab):
65c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  return tab.EvaluateJavaScript('webglTestHarness._messages')
66c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
67eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochclass WebglConformanceValidator(page_test.PageTest):
68c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  def __init__(self):
69116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    super(WebglConformanceValidator, self).__init__(attempts=1, max_failures=10)
70eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
716e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles)  def ValidateAndMeasurePage(self, page, tab, results):
72eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch    if not _DidWebGLTestSucceed(tab):
73d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch      raise page_test.Failure(_WebGLTestMessages(tab))
74eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
75eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  def CustomizeBrowserOptions(self, options):
76f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    options.AppendExtraBrowserArgs([
77f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        '--disable-gesture-requirement-for-media-playback',
78f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        '--disable-domain-blocking-for-3d-apis',
79f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)        '--disable-gpu-process-crash-limit'
80f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    ])
81eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch
835c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liuclass WebglConformancePage(page_module.Page):
845c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  def __init__(self, page_set, test):
855c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    super(WebglConformancePage, self).__init__(
86010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      url='file://' + test, page_set=page_set, base_dir=page_set.base_dir,
87010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)      name=('WebglConformance.%s' %
88010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)              test.replace('/', '_').replace('-', '_').
89010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)                 replace('\\', '_').rpartition('.')[0].replace('.', '_')))
905c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    self.script_to_evaluate_on_commit = conformance_harness_script
915c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
925c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu  def RunNavigateSteps(self, action_runner):
93cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    action_runner.NavigateToPage(self)
94f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles)    action_runner.WaitForJavaScriptCondition(
951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        'webglTestHarness._finished', timeout_in_seconds=180)
965c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
975c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
98116680a4aac90f2aa7413d9095a592090648e557Ben Murdochclass WebglConformance(benchmark_module.Benchmark):
99eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  """Conformance with Khronos WebGL Conformance Tests"""
100eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  test = WebglConformanceValidator
101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
102a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  @classmethod
103a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  def AddTestCommandLineArgs(cls, group):
10458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    group.add_option('--webgl-conformance-version',
10558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        help='Version of the WebGL conformance tests to run.',
106010d83a9304c5a91596085d917d248abff47903aTorne (Richard Coles)        default='1.0.3')
10758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)
108eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  def CreatePageSet(self, options):
10958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)    tests = self._ParseTests('00_test_list.txt',
11058537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)        options.webgl_conformance_version)
111c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
1125c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    ps = page_set.PageSet(
1135c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      user_agent_type='desktop',
1145c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      serving_dirs=[''],
1155c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      file_path=conformance_path)
116c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    for test in tests:
1185c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      ps.AddPage(WebglConformancePage(ps, test))
1195c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu
1205c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu    return ps
121c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
122d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch  def CreateExpectations(self, page_set):
123d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch    return webgl_conformance_expectations.WebGLConformanceExpectations()
124d3868032626d59662ff73b372b5d584c1d144c53Ben Murdoch
125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  @staticmethod
126eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch  def _ParseTests(path, version=None):
127c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    test_paths = []
128c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    current_dir = os.path.dirname(path)
129c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    full_path = os.path.normpath(os.path.join(conformance_path, path))
130c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
131c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    if not os.path.exists(full_path):
132c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      raise Exception('The WebGL conformance test path specified ' +
133c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        'does not exist: ' + full_path)
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
135c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    with open(full_path, 'r') as f:
136c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      for line in f:
137c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        line = line.strip()
138c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
139c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if not line:
140c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          continue
141c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
142c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if line.startswith('//') or line.startswith('#'):
143c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          continue
144c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
145c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        line_tokens = line.split(' ')
146c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
147c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        i = 0
148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        min_version = None
149c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        while i < len(line_tokens):
150c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          token = line_tokens[i]
151c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          if token == '--min-version':
152c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            i += 1
153c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            min_version = line_tokens[i]
154c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          i += 1
155c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
156b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        if version and min_version and version < min_version:
157c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          continue
158c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
159c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        test_name = line_tokens[-1]
160c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
161c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        if '.txt' in test_name:
162c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          include_path = os.path.join(current_dir, test_name)
163eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch          test_paths += WebglConformance._ParseTests(
164c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)            include_path, version)
165c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        else:
166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          test = os.path.join(current_dir, test_name)
167c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          test_paths.append(test)
168c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)
169c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)    return test_paths
170