Add script to generate LayoutTests from WebGL Conformance Tests
https://bugs.webkit.org/show_bug.cgi?id=110525
Patch by Gregg Tavares <gman@chromium.org> on 2013-02-22
Reviewed by Kenneth Russell.
Adds the script generate-webgl-tests.py which given a path
to the WebGL Conformance 'sdk/tests' folder generates and
or updates LayoutTests for WebGL. Example
git clone git://github.com/KhronosGroup/WebGL.git
generate-webgl-tests.py -w WebGL/sdk/tests -e
* webgl/generate-webgl-tests.py: Added.
(ReadFile):
(WriteFile):
(CopyTree):
(FileReader):
(GreaterThanOrEqualToVersion):
(GetTestList):
(main):
* webgl/resources/webgl-expectation-template.txt: Added.
* webgl/resources/webgl-wrapper-template.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@143782 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/webgl/generate-webgl-tests.py b/LayoutTests/webgl/generate-webgl-tests.py
new file mode 100644
index 0000000..7606c85
--- /dev/null
+++ b/LayoutTests/webgl/generate-webgl-tests.py
@@ -0,0 +1,263 @@
+# 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": "1.0.2",
+
+ # version used for unlabled tests
+ "default-version": "1.0",
+
+ # If set, the version we require. Tests below this will be ignored.
+ #"min-version": "1.0.2",
+}
+
+
+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
+ 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':
+ test_options[option] = args.pop(0)
+ else:
+ raise "%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:]))
+
+
+
+
+