webgl_conformance.py revision 010d83a9304c5a91596085d917d248abff47903a
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.
4import json
5import optparse
6import os
7import sys
8
9import webgl_conformance_expectations
10
11from telemetry import test as test_module
12from telemetry.core import util
13from telemetry.page import page_set
14from telemetry.page import page as page_module
15from telemetry.page import page_test
16# pylint: disable=W0401,W0614
17from telemetry.page.actions.all_page_actions import *
18
19
20conformance_path = os.path.join(
21    util.GetChromiumSrcDir(),
22    'third_party', 'webgl', 'src', 'sdk', 'tests')
23
24conformance_harness_script = r"""
25  var testHarness = {};
26  testHarness._allTestSucceeded = true;
27  testHarness._messages = '';
28  testHarness._failures = 0;
29  testHarness._finished = false;
30  testHarness._originalLog = window.console.log;
31
32  testHarness.log = function(msg) {
33    testHarness._messages += msg + "\n";
34    testHarness._originalLog.apply(window.console, [msg]);
35  }
36
37  testHarness.reportResults = function(url, success, msg) {
38    testHarness._allTestSucceeded = testHarness._allTestSucceeded && !!success;
39    if(!success) {
40      testHarness._failures++;
41      if(msg) {
42        testHarness.log(msg);
43      }
44    }
45  };
46  testHarness.notifyFinished = function(url) {
47    testHarness._finished = true;
48  };
49  testHarness.navigateToPage = function(src) {
50    var testFrame = document.getElementById("test-frame");
51    testFrame.src = src;
52  };
53
54  window.webglTestHarness = testHarness;
55  window.parent.webglTestHarness = testHarness;
56  window.console.log = testHarness.log;
57"""
58
59def _DidWebGLTestSucceed(tab):
60  return tab.EvaluateJavaScript('webglTestHarness._allTestSucceeded')
61
62def _WebGLTestMessages(tab):
63  return tab.EvaluateJavaScript('webglTestHarness._messages')
64
65class WebglConformanceValidator(page_test.PageTest):
66  def __init__(self):
67    super(WebglConformanceValidator, self).__init__(attempts=1, max_errors=10)
68
69  def ValidatePage(self, page, tab, results):
70    if not _DidWebGLTestSucceed(tab):
71      raise page_test.Failure(_WebGLTestMessages(tab))
72
73  def CustomizeBrowserOptions(self, options):
74    options.AppendExtraBrowserArgs([
75        '--disable-gesture-requirement-for-media-playback',
76        '--disable-domain-blocking-for-3d-apis',
77        '--disable-gpu-process-crash-limit'
78    ])
79
80
81class WebglConformancePage(page_module.Page):
82  def __init__(self, page_set, test):
83    super(WebglConformancePage, self).__init__(
84      url='file://' + test, page_set=page_set, base_dir=page_set.base_dir,
85      name=('WebglConformance.%s' %
86              test.replace('/', '_').replace('-', '_').
87                 replace('\\', '_').rpartition('.')[0].replace('.', '_')))
88    self.script_to_evaluate_on_commit = conformance_harness_script
89
90  def RunNavigateSteps(self, action_runner):
91    action_runner.RunAction(NavigateAction())
92    action_runner.RunAction(WaitAction(
93      {'javascript': 'webglTestHarness._finished', 'timeout': 120}))
94
95
96class WebglConformance(test_module.Test):
97  """Conformance with Khronos WebGL Conformance Tests"""
98  test = WebglConformanceValidator
99
100  @classmethod
101  def AddTestCommandLineArgs(cls, group):
102    group.add_option('--webgl-conformance-version',
103        help='Version of the WebGL conformance tests to run.',
104        default='1.0.3')
105
106  def CreatePageSet(self, options):
107    tests = self._ParseTests('00_test_list.txt',
108        options.webgl_conformance_version)
109
110    ps = page_set.PageSet(
111      description='Executes WebGL conformance tests',
112      user_agent_type='desktop',
113      serving_dirs=[''],
114      file_path=conformance_path)
115
116    for test in tests:
117      ps.AddPage(WebglConformancePage(ps, test))
118
119    return ps
120
121  def CreateExpectations(self, page_set):
122    return webgl_conformance_expectations.WebGLConformanceExpectations()
123
124  @staticmethod
125  def _ParseTests(path, version=None):
126    test_paths = []
127    current_dir = os.path.dirname(path)
128    full_path = os.path.normpath(os.path.join(conformance_path, path))
129
130    if not os.path.exists(full_path):
131      raise Exception('The WebGL conformance test path specified ' +
132        'does not exist: ' + full_path)
133
134    with open(full_path, 'r') as f:
135      for line in f:
136        line = line.strip()
137
138        if not line:
139          continue
140
141        if line.startswith('//') or line.startswith('#'):
142          continue
143
144        line_tokens = line.split(' ')
145
146        i = 0
147        min_version = None
148        while i < len(line_tokens):
149          token = line_tokens[i]
150          if token == '--min-version':
151            i += 1
152            min_version = line_tokens[i]
153          i += 1
154
155        if version and min_version and version < min_version:
156          continue
157
158        test_name = line_tokens[-1]
159
160        if '.txt' in test_name:
161          include_path = os.path.join(current_dir, test_name)
162          test_paths += WebglConformance._ParseTests(
163            include_path, version)
164        else:
165          test = os.path.join(current_dir, test_name)
166          test_paths.append(test)
167
168    return test_paths
169