From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- .../harness/wptrunner/manifestinclude.py | 144 +++++++++++++++++++++ 1 file changed, 144 insertions(+) create mode 100644 testing/web-platform/harness/wptrunner/manifestinclude.py (limited to 'testing/web-platform/harness/wptrunner/manifestinclude.py') diff --git a/testing/web-platform/harness/wptrunner/manifestinclude.py b/testing/web-platform/harness/wptrunner/manifestinclude.py new file mode 100644 index 000000000..d9b4ee455 --- /dev/null +++ b/testing/web-platform/harness/wptrunner/manifestinclude.py @@ -0,0 +1,144 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +"""Manifest structure used to store paths that should be included in a test run. + +The manifest is represented by a tree of IncludeManifest objects, the root +representing the file and each subnode representing a subdirectory that should +be included or excluded. +""" +import glob +import os +import urlparse + +from wptmanifest.node import DataNode +from wptmanifest.backends import conditional +from wptmanifest.backends.conditional import ManifestItem + + +class IncludeManifest(ManifestItem): + def __init__(self, node): + """Node in a tree structure representing the paths + that should be included or excluded from the test run. + + :param node: AST Node corresponding to this Node. + """ + ManifestItem.__init__(self, node) + self.child_map = {} + + @classmethod + def create(cls): + """Create an empty IncludeManifest tree""" + node = DataNode(None) + return cls(node) + + def append(self, child): + ManifestItem.append(self, child) + self.child_map[child.name] = child + assert len(self.child_map) == len(self.children) + + def include(self, test): + """Return a boolean indicating whether a particular test should be + included in a test run, based on the IncludeManifest tree rooted on + this object. + + :param test: The test object""" + path_components = self._get_components(test.url) + return self._include(test, path_components) + + def _include(self, test, path_components): + if path_components: + next_path_part = path_components.pop() + if next_path_part in self.child_map: + return self.child_map[next_path_part]._include(test, path_components) + + node = self + while node: + try: + skip_value = self.get("skip", {"test_type": test.item_type}).lower() + assert skip_value in ("true", "false") + return skip_value != "true" + except KeyError: + if node.parent is not None: + node = node.parent + else: + # Include by default + return True + + def _get_components(self, url): + rv = [] + url_parts = urlparse.urlsplit(url) + variant = "" + if url_parts.query: + variant += "?" + url_parts.query + if url_parts.fragment: + variant += "#" + url_parts.fragment + if variant: + rv.append(variant) + rv.extend([item for item in reversed(url_parts.path.split("/")) if item]) + return rv + + def _add_rule(self, test_manifests, url, direction): + maybe_path = os.path.join(os.path.abspath(os.curdir), url) + rest, last = os.path.split(maybe_path) + variant = "" + if "#" in last: + last, fragment = last.rsplit("#", 1) + variant += "#" + fragment + if "?" in last: + last, query = last.rsplit("?", 1) + variant += "?" + query + + maybe_path = os.path.join(rest, last) + paths = glob.glob(maybe_path) + + if paths: + urls = [] + for path in paths: + for manifest, data in test_manifests.iteritems(): + rel_path = os.path.relpath(path, data["tests_path"]) + if ".." not in rel_path.split(os.sep): + urls.append(data["url_base"] + rel_path.replace(os.path.sep, "/") + variant) + break + else: + urls = [url] + + assert direction in ("include", "exclude") + + for url in urls: + components = self._get_components(url) + + node = self + while components: + component = components.pop() + if component not in node.child_map: + new_node = IncludeManifest(DataNode(component)) + node.append(new_node) + new_node.set("skip", node.get("skip", {})) + + node = node.child_map[component] + + skip = False if direction == "include" else True + node.set("skip", str(skip)) + + def add_include(self, test_manifests, url_prefix): + """Add a rule indicating that tests under a url path + should be included in test runs + + :param url_prefix: The url prefix to include + """ + return self._add_rule(test_manifests, url_prefix, "include") + + def add_exclude(self, test_manifests, url_prefix): + """Add a rule indicating that tests under a url path + should be excluded from test runs + + :param url_prefix: The url prefix to exclude + """ + return self._add_rule(test_manifests, url_prefix, "exclude") + + +def get_manifest(manifest_path): + with open(manifest_path) as f: + return conditional.compile(f, data_cls_getter=lambda x, y: IncludeManifest) -- cgit v1.2.3