Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1758)

Unified Diff: third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/manifest/manifest.py

Issue 2630493002: Use a pinned version of web-platform-tests/manifest. (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/manifest/manifest.py
diff --git a/third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/manifest/manifest.py b/third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/manifest/manifest.py
new file mode 100644
index 0000000000000000000000000000000000000000..1e7f349d2518717d5b4c5ba29b073b01eceaba75
--- /dev/null
+++ b/third_party/WebKit/Tools/Scripts/webkitpy/thirdparty/wpt/wpt/tools/manifest/manifest.py
@@ -0,0 +1,228 @@
+import json
+import os
+import re
+from collections import defaultdict
+from six import iteritems, itervalues, viewkeys
+
+from .item import ManualTest, WebdriverSpecTest, Stub, RefTestNode, RefTest, TestharnessTest, SupportFile, ConformanceCheckerTest, VisualTest
+from .log import get_logger
+from .utils import from_os_path, to_os_path, rel_path_to_url
+
+
+CURRENT_VERSION = 4
+
+
+class ManifestError(Exception):
+ pass
+
+
+class ManifestVersionMismatch(ManifestError):
+ pass
+
+
+def sourcefile_items(args):
+ tests_root, url_base, rel_path, status = args
+ source_file = SourceFile(tests_root,
+ rel_path,
+ url_base)
+ return rel_path, source_file.manifest_items()
+
+
+class Manifest(object):
+ def __init__(self, url_base="/"):
+ assert url_base is not None
+ self._path_hash = {}
+ self._data = defaultdict(dict)
+ self._reftest_nodes_by_url = None
+ self.url_base = url_base
+
+ def __iter__(self):
+ return self.itertypes()
+
+ def itertypes(self, *types):
+ if not types:
+ types = sorted(self._data.keys())
+ for item_type in types:
+ for path, tests in sorted(iteritems(self._data[item_type])):
+ yield item_type, tests
+
+ @property
+ def reftest_nodes_by_url(self):
+ if self._reftest_nodes_by_url is None:
+ by_url = {}
+ for path, nodes in iteritems(self._data.get("reftests", {})):
+ for node in nodes:
+ by_url[node.url] = node
+ self._reftest_nodes_by_url = by_url
+ return self._reftest_nodes_by_url
+
+ def get_reference(self, url):
+ return self.reftest_nodes_by_url.get(url)
+
+ def update(self, tree):
+ new_data = defaultdict(dict)
+ new_hashes = {}
+
+ reftest_nodes = []
+ old_files = defaultdict(set, {k: set(viewkeys(v)) for k, v in iteritems(self._data)})
+
+ changed = False
+ reftest_changes = False
+
+ for source_file in tree:
+ rel_path = source_file.rel_path
+ file_hash = source_file.hash
+
+ is_new = rel_path not in self._path_hash
+ hash_changed = False
+
+ if not is_new:
+ old_hash, old_type = self._path_hash[rel_path]
+ old_files[old_type].remove(rel_path)
+ if old_hash != file_hash:
+ new_type, manifest_items = source_file.manifest_items()
+ hash_changed = True
+ else:
+ new_type, manifest_items = old_type, self._data[old_type][rel_path]
+ else:
+ new_type, manifest_items = source_file.manifest_items()
+
+ if new_type in ("reftest", "reftest_node"):
+ reftest_nodes.extend(manifest_items)
+ if is_new or hash_changed:
+ reftest_changes = True
+ elif new_type:
+ new_data[new_type][rel_path] = set(manifest_items)
+
+ new_hashes[rel_path] = (file_hash, new_type)
+
+ if is_new or hash_changed:
+ changed = True
+
+ if reftest_changes or old_files["reftest"] or old_files["reftest_node"]:
+ reftests, reftest_nodes, changed_hashes = self._compute_reftests(reftest_nodes)
+ new_data["reftest"] = reftests
+ new_data["reftest_node"] = reftest_nodes
+ new_hashes.update(changed_hashes)
+ else:
+ new_data["reftest"] = self._data["reftest"]
+ new_data["reftest_node"] = self._data["reftest_node"]
+
+ if any(itervalues(old_files)):
+ changed = True
+
+ self._data = new_data
+ self._path_hash = new_hashes
+
+ return changed
+
+ def _compute_reftests(self, reftest_nodes):
+ self._reftest_nodes_by_url = {}
+ has_inbound = set()
+ for item in reftest_nodes:
+ for ref_url, ref_type in item.references:
+ has_inbound.add(ref_url)
+
+ reftests = defaultdict(set)
+ references = defaultdict(set)
+ changed_hashes = {}
+
+ for item in reftest_nodes:
+ if item.url in has_inbound:
+ # This is a reference
+ if isinstance(item, RefTest):
+ item = item.to_RefTestNode()
+ changed_hashes[item.source_file.rel_path] = (item.source_file.hash,
+ item.item_type)
+ references[item.source_file.rel_path].add(item)
+ self._reftest_nodes_by_url[item.url] = item
+ else:
+ if isinstance(item, RefTestNode):
+ item = item.to_RefTest()
+ changed_hashes[item.source_file.rel_path] = (item.source_file.hash,
+ item.item_type)
+ reftests[item.source_file.rel_path].add(item)
+
+ return reftests, references, changed_hashes
+
+ def to_json(self):
+ out_items = {
+ test_type: {
+ from_os_path(path):
+ [t for t in sorted(test.to_json() for test in tests)]
+ for path, tests in iteritems(type_paths)
+ }
+ for test_type, type_paths in iteritems(self._data)
+ }
+ rv = {"url_base": self.url_base,
+ "paths": {from_os_path(k): v for k, v in iteritems(self._path_hash)},
+ "items": out_items,
+ "version": CURRENT_VERSION}
+ return rv
+
+ @classmethod
+ def from_json(cls, tests_root, obj):
+ version = obj.get("version")
+ if version != CURRENT_VERSION:
+ raise ManifestVersionMismatch
+
+ self = cls(url_base=obj.get("url_base", "/"))
+ if not hasattr(obj, "items") and hasattr(obj, "paths"):
+ raise ManifestError
+
+ self._path_hash = {to_os_path(k): v for k, v in iteritems(obj["paths"])}
+
+ item_classes = {"testharness": TestharnessTest,
+ "reftest": RefTest,
+ "reftest_node": RefTestNode,
+ "manual": ManualTest,
+ "stub": Stub,
+ "wdspec": WebdriverSpecTest,
+ "conformancechecker": ConformanceCheckerTest,
+ "visual": VisualTest,
+ "support": SupportFile}
+
+ source_files = {}
+
+ for test_type, type_paths in iteritems(obj["items"]):
+ if test_type not in item_classes:
+ raise ManifestError
+ test_cls = item_classes[test_type]
+ tests = defaultdict(set)
+ for path, manifest_tests in iteritems(type_paths):
+ path = to_os_path(path)
+ for test in manifest_tests:
+ manifest_item = test_cls.from_json(self,
+ tests_root,
+ path,
+ test,
+ source_files=source_files)
+ tests[path].add(manifest_item)
+ self._data[test_type] = tests
+
+ return self
+
+
+def load(tests_root, manifest):
+ logger = get_logger()
+
+ # "manifest" is a path or file-like object.
+ if isinstance(manifest, basestring):
+ if os.path.exists(manifest):
+ logger.debug("Opening manifest at %s" % manifest)
+ else:
+ logger.debug("Creating new manifest at %s" % manifest)
+ try:
+ with open(manifest) as f:
+ rv = Manifest.from_json(tests_root, json.load(f))
+ except IOError:
+ return None
+ return rv
+
+ return Manifest.from_json(tests_root, json.load(manifest))
+
+
+def write(manifest, manifest_path):
+ with open(manifest_path, "wb") as f:
+ json.dump(manifest.to_json(), f, sort_keys=True, indent=1, separators=(',', ': '))
+ f.write("\n")

Powered by Google App Engine
This is Rietveld 408576698