| # Copyright (C) 2013 Google Inc. All rights reserved. |
| # |
| # Redistribution and use in source and binary forms, with or without |
| # modification, are permitted provided that the following conditions are |
| # met: |
| # |
| # * Redistributions of source code must retain the above copyright |
| # notice, this list of conditions and the following disclaimer. |
| # * Redistributions in binary form must reproduce the above |
| # copyright notice, this list of conditions and the following disclaimer |
| # in the documentation and/or other materials provided with the |
| # distribution. |
| # * Neither the name of Google Inc. nor the names of its |
| # contributors may be used to endorse or promote products derived from |
| # this software without specific prior written permission. |
| # |
| # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| # LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| # A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| # OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| # SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| # LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| |
| """generates webgl layout tests from the Khronos WebGL Conformance Tests""" |
| |
| # To use this, get a copy of the WebGL conformance tests then run this script |
| # eg. |
| # |
| # cd ~/temp |
| # git clone git://github.com/KhronosGroup/WebGL.git |
| # cd ~/WebKit/LayoutTests/webgl |
| # python generate-webgl-tests.py -w ~/temp/WebGL/sdk/tests -e |
| # |
| # Now check run the LayoutTests, update TestExpectations and check in the |
| # result. |
| |
| import copy |
| import os |
| import os.path |
| import sys |
| import re |
| import json |
| import shutil |
| from optparse import OptionParser |
| |
| if sys.version < '2.6': |
| print 'Wrong Python Version !!!: Need >= 2.6' |
| sys.exit(1) |
| |
| |
| GLOBAL_OPTIONS = { |
| # version use. Tests at or below this will be included. |
| "version": "2.0.0", |
| |
| # version used for unlabled tests |
| "default-version": "2.0", |
| |
| # If set, the version we require. Tests below this will be ignored. |
| "min-version": "1.0.3", |
| } |
| |
| |
| def ReadFile(filename): |
| """Reads a file as a string""" |
| file = open(filename, "r") |
| data = file.read() |
| file.close() |
| return data |
| |
| |
| def WriteFile(filename, data): |
| """Writes a string as a file""" |
| print "Writing: ", filename |
| dirname = os.path.dirname(filename) |
| if not os.path.exists(dirname): |
| os.makedirs(dirname) |
| file = open(filename, "wb") |
| file.write(data) |
| file.close() |
| |
| |
| def CopyTree(src, dst, ignore=None): |
| """Recursively copy a directory tree""" |
| names = os.listdir(src) |
| if ignore is not None: |
| ignored_names = ignore(src, names) |
| else: |
| ignored_names = set() |
| |
| if not os.path.exists(dst): |
| os.makedirs(dst) |
| errors = [] |
| for name in names: |
| if name in ignored_names: |
| continue |
| srcname = os.path.join(src, name) |
| dstname = os.path.join(dst, name) |
| try: |
| if os.path.isdir(srcname): |
| CopyTree(srcname, dstname, ignore) |
| else: |
| # Will raise a SpecialFileError for unsupported file types |
| shutil.copyfile(srcname, dstname) |
| # catch the Error from the recursive copytree so that we can |
| # continue with other files |
| except Error, err: |
| errors.extend(err.args[0]) |
| except EnvironmentError, why: |
| errors.append((srcname, dstname, str(why))) |
| if errors: |
| raise Error, errors |
| |
| |
| def FileReader(filename): |
| """A File generator that returns only non empty, non comment lines""" |
| file = open(filename, "r") |
| lines = file.readlines() |
| file.close() |
| for line_number, line in enumerate(lines): |
| line = line.strip() |
| if (len(line) > 0 and |
| not line.startswith("#") and |
| not line.startswith(";") and |
| not line.startswith("//")): |
| yield line_number + 1, line |
| |
| |
| def GreaterThanOrEqualToVersion(have, want): |
| """Compares to version strings""" |
| have = have.split(" ")[0].split(".") |
| want = want.split(" ")[0].split(".") |
| for ndx, want_str in enumerate(want): |
| want_num = int(want_str) |
| have_num = 0 |
| if ndx < len(have): |
| have_num = int(have[ndx]) |
| if have_num < want_num: |
| return False |
| if have_num >= want_num: |
| return True |
| return True |
| |
| |
| def GetTestList(list_filename, dest_dir, hierarchical_options): |
| global GLOBAL_OPTIONS |
| tests = [] |
| prefix = os.path.dirname(list_filename) |
| for line_number, line in FileReader(list_filename): |
| args = line.split() |
| test_options = {} |
| non_options = [] |
| use_test = True |
| while len(args): |
| arg = args.pop(0) |
| if arg.startswith("-"): |
| if not arg.startswith("--"): |
| raise "%s:%d bad option" % (list_filename, line_number) |
| option = arg[2:] |
| if option == 'slow': |
| pass |
| elif option == 'min-version' or option == "max-version": |
| test_options[option] = args.pop(0) |
| else: |
| raise Exception("%s:%d unknown option '%s'" % (list_filename, line_number, arg)) |
| else: |
| non_options.append(arg) |
| url = os.path.join(prefix, " ".join(non_options)) |
| |
| if not url.endswith(".txt"): |
| if "min-version" in test_options: |
| min_version = test_options["min-version"] |
| else: |
| min_version = hierarchical_options["default-version"] |
| |
| if "min-version" in GLOBAL_OPTIONS: |
| use_test = GreaterThanOrEqualToVersion(min_version, GLOBAL_OPTIONS["min-version"]) |
| else: |
| use_test = GreaterThanOrEqualToVersion(GLOBAL_OPTIONS["version"], min_version) |
| |
| if not use_test: |
| continue |
| |
| if url.endswith(".txt"): |
| if "min-version" in test_options: |
| hierarchical_options["default-version"] = test_options["min-version"] |
| tests = tests + GetTestList( |
| os.path.join(prefix, url), dest_dir, copy.copy(hierarchical_options)) |
| else: |
| tests.append({"url": url}) |
| return tests |
| |
| |
| def main(argv): |
| """This is the main function.""" |
| global GLOBAL_OPTIONS |
| |
| parser = OptionParser() |
| parser.add_option( |
| "-v", "--verbose", action="store_true", |
| help="prints more output.") |
| parser.add_option( |
| "-w", "--webgl-conformance-test", dest="source_dir", |
| help="path to webgl conformance tests. REQUIRED") |
| parser.add_option( |
| "-n", "--no-copy", action="store_true", |
| help="do not copy tests") |
| parser.add_option( |
| "-e", "--generate-expectations", action="store_true", |
| help="generatet the test expectations") |
| |
| (options, args) = parser.parse_args(args=argv) |
| |
| if not options.source_dir: |
| parser.print_help() |
| return 1 |
| |
| os.chdir(os.path.dirname(__file__) or '.') |
| |
| source_dir = options.source_dir; |
| webgl_tests_dir = "resources/webgl_test_files" |
| base_path = "." |
| |
| # copy all the files from the WebGL conformance tests. |
| if not options.no_copy: |
| CopyTree( |
| source_dir, webgl_tests_dir, shutil.ignore_patterns( |
| '.git', '*.pyc', 'tmp*')) |
| |
| test_template = ReadFile("resources/webgl-wrapper-template.html") |
| expectation_template = ReadFile("resources/webgl-expectation-template.txt") |
| |
| # generate wrappers for all the tests |
| tests = GetTestList(os.path.join(source_dir, "00_test_list.txt"), ".", |
| copy.copy(GLOBAL_OPTIONS)) |
| |
| for test in tests: |
| url = os.path.relpath(test["url"], source_dir) |
| dst = url |
| dst_dir = os.path.dirname(dst) |
| src = os.path.relpath(os.path.join(webgl_tests_dir, url), dst_dir).replace("\\", "/") |
| base_url = os.path.relpath(base_path, dst_dir).replace("\\", "/") |
| subs = { |
| "url": src, |
| "url_name": os.path.basename(url), |
| "base_url": base_url, |
| } |
| WriteFile(dst, test_template % subs) |
| if options.generate_expectations: |
| expectation_filename = os.path.splitext(dst)[0] + "-expected.txt" |
| WriteFile(expectation_filename, expectation_template % subs) |
| |
| |
| |
| if __name__ == '__main__': |
| sys.exit(main(sys.argv[1:])) |
| |
| |
| |
| |
| |