Update web-platform-tests to revision 78f764c05c229883e87ad135c7153051a66e2851

This commit is contained in:
WPT Sync Bot 2019-03-06 20:32:15 -05:00
parent 55347aa39f
commit bf84a079f9
1983 changed files with 58006 additions and 31437 deletions

View file

@ -1,24 +1,8 @@
from copy import copy
from six.moves.urllib.parse import urljoin, urlparse
from abc import ABCMeta, abstractproperty
class SourceFileCache(object):
def __init__(self):
self.source_files = {}
def make_new(self, tests_root, path, url_base):
from .sourcefile import SourceFile
return SourceFile(tests_root, path, url_base)
def get(self, tests_root, manifest, path):
if path not in self.source_files:
self.source_files[path] = self.make_new(tests_root, path, manifest.url_base)
return self.source_files[path]
item_types = {}
@ -38,39 +22,26 @@ class ManifestItemMeta(ABCMeta):
class ManifestItem(object):
__metaclass__ = ManifestItemMeta
__slots__ = ("_tests_root", "path")
item_type = None
source_file_cache = SourceFileCache()
def __init__(self, source_file, manifest=None):
self.source_file = source_file
def __init__(self, tests_root=None, path=None):
self._tests_root = tests_root
self.path = path
@abstractproperty
def id(self):
"""The test's id (usually its url)"""
pass
@property
def meta_flags(self):
return set(self.source_file.meta_flags)
@property
def path(self):
"""The test path relative to the test_root"""
return self.source_file.rel_path
@property
def https(self):
flags = self.meta_flags
return ("https" in flags or "serviceworker" in flags)
def key(self):
"""A unique identifier for the test"""
return (self.item_type, self.id)
def meta_key(self):
"""Extra metadata that doesn't form part of the test identity, but for
which changes mean regenerating the manifest (e.g. the test timeout."""
which changes mean regenerating the manifest (e.g. the test timeout)."""
return ()
def __eq__(self, other):
@ -88,55 +59,80 @@ class ManifestItem(object):
return [{}]
@classmethod
def from_json(cls, manifest, tests_root, path, obj):
source_file = cls.source_file_cache.get(tests_root, manifest, path)
return cls(source_file,
manifest=manifest)
def from_json(cls, manifest, path, obj):
return cls(manifest.tests_root, path)
class URLManifestItem(ManifestItem):
def __init__(self, source_file, url, url_base="/", manifest=None):
ManifestItem.__init__(self, source_file, manifest=manifest)
self._url = url
__slots__ = ("url_base", "_url", "_extras")
def __init__(self, tests_root, path, url_base, url, **extras):
super(URLManifestItem, self).__init__(tests_root, path)
self.url_base = url_base
self._url = url
self._extras = extras or {}
@property
def _source_file(self):
"""create a SourceFile for the item"""
from .sourcefile import SourceFile
return SourceFile(self._tests_root, self.path, self.url_base)
@property
def id(self):
return self.url
@property
def meta_flags(self):
return set(urlparse(self.url).path.rsplit("/", 1)[1].split(".")[1:-1])
@property
def url(self):
return urljoin(self.url_base, self._url)
@property
def https(self):
flags = set(urlparse(self.url).path.rsplit("/", 1)[1].split(".")[1:-1])
return ("https" in flags or "serviceworker" in flags)
def to_json(self):
rv = [self._url, {}]
return rv
@classmethod
def from_json(cls, manifest, tests_root, path, obj):
source_file = cls.source_file_cache.get(tests_root, manifest, path)
def from_json(cls, manifest, path, obj):
url, extras = obj
return cls(source_file,
return cls(manifest.tests_root,
path,
manifest.url_base,
url,
url_base=manifest.url_base,
manifest=manifest)
**extras)
class TestharnessTest(URLManifestItem):
item_type = "testharness"
def __init__(self, source_file, url, url_base="/", timeout=None, testdriver=False, jsshell=False, manifest=None):
URLManifestItem.__init__(self, source_file, url, url_base=url_base, manifest=manifest)
self.timeout = timeout
self.testdriver = testdriver
self.jsshell = jsshell
@property
def timeout(self):
return self._extras.get("timeout")
@property
def testdriver(self):
return self._extras.get("testdriver")
@property
def jsshell(self):
return self._extras.get("jsshell")
@property
def script_metadata(self):
if "script_metadata" in self._extras:
return self._extras["script_metadata"]
else:
# this branch should go when the manifest version is bumped
return self._source_file.script_metadata
def meta_key(self):
return (self.timeout, self.testdriver)
script_metadata = self.script_metadata
if script_metadata is not None:
script_metadata = tuple(tuple(x) for x in script_metadata)
return (self.timeout, self.testdriver, self.jsshell, script_metadata)
def to_json(self):
rv = URLManifestItem.to_json(self)
@ -146,35 +142,32 @@ class TestharnessTest(URLManifestItem):
rv[-1]["testdriver"] = self.testdriver
if self.jsshell:
rv[-1]["jsshell"] = True
if self.script_metadata is not None:
# we store this even if it is [] to avoid having to read the source file
rv[-1]["script_metadata"] = self.script_metadata
return rv
@classmethod
def from_json(cls, manifest, tests_root, path, obj):
source_file = cls.source_file_cache.get(tests_root, manifest, path)
url, extras = obj
return cls(source_file,
url,
url_base=manifest.url_base,
timeout=extras.get("timeout"),
testdriver=bool(extras.get("testdriver")),
jsshell=bool(extras.get("jsshell")),
manifest=manifest)
class RefTestBase(URLManifestItem):
__slots__ = ("references",)
item_type = "reftest_base"
class RefTestNode(URLManifestItem):
item_type = "reftest_node"
def __init__(self, tests_root, path, url_base, url, references=None, **extras):
super(RefTestBase, self).__init__(tests_root, path, url_base, url, **extras)
self.references = references or []
def __init__(self, source_file, url, references, url_base="/", timeout=None,
viewport_size=None, dpi=None, manifest=None):
URLManifestItem.__init__(self, source_file, url, url_base=url_base, manifest=manifest)
for _, ref_type in references:
if ref_type not in ["==", "!="]:
raise ValueError("Unrecognised ref_type %s" % ref_type)
self.references = tuple(references)
self.timeout = timeout
self.viewport_size = viewport_size
self.dpi = dpi
@property
def timeout(self):
return self._extras.get("timeout")
@property
def viewport_size(self):
return self._extras.get("viewport_size")
@property
def dpi(self):
return self._extras.get("dpi")
def meta_key(self):
return (self.timeout, self.viewport_size, self.dpi)
@ -191,34 +184,35 @@ class RefTestNode(URLManifestItem):
return rv
@classmethod
def from_json(cls, manifest, tests_root, path, obj):
source_file = cls.source_file_cache.get(tests_root, manifest, path)
def from_json(cls, manifest, path, obj):
url, references, extras = obj
return cls(source_file,
return cls(manifest.tests_root,
path,
manifest.url_base,
url,
references,
url_base=manifest.url_base,
timeout=extras.get("timeout"),
viewport_size=extras.get("viewport_size"),
dpi=extras.get("dpi"),
manifest=manifest)
**extras)
def to_RefTest(self):
if type(self) == RefTest:
return self
rv = RefTest.__new__(RefTest)
rv.__dict__.update(self.__dict__)
rv = copy(self)
rv.__class__ = RefTest
return rv
def to_RefTestNode(self):
if type(self) == RefTestNode:
return self
rv = RefTestNode.__new__(RefTestNode)
rv.__dict__.update(self.__dict__)
rv = copy(self)
rv.__class__ = RefTestNode
return rv
class RefTest(RefTestNode):
class RefTestNode(RefTestBase):
item_type = "reftest_node"
class RefTest(RefTestBase):
item_type = "reftest"
@ -241,9 +235,9 @@ class Stub(URLManifestItem):
class WebDriverSpecTest(URLManifestItem):
item_type = "wdspec"
def __init__(self, source_file, url, url_base="/", timeout=None, manifest=None):
URLManifestItem.__init__(self, source_file, url, url_base=url_base, manifest=manifest)
self.timeout = timeout
@property
def timeout(self):
return self._extras.get("timeout")
def to_json(self):
rv = URLManifestItem.to_json(self)
@ -251,21 +245,10 @@ class WebDriverSpecTest(URLManifestItem):
rv[-1]["timeout"] = self.timeout
return rv
@classmethod
def from_json(cls, manifest, tests_root, path, obj):
source_file = cls.source_file_cache.get(tests_root, manifest, path)
url, extras = obj
return cls(source_file,
url,
url_base=manifest.url_base,
timeout=extras.get("timeout"),
manifest=manifest)
class SupportFile(ManifestItem):
item_type = "support"
@property
def id(self):
return self.source_file.rel_path
return self.path

View file

@ -4,7 +4,7 @@ from collections import defaultdict
from six import iteritems, iterkeys, itervalues, string_types
from . import vcs
from .item import (ManualTest, WebDriverSpecTest, Stub, RefTestNode, RefTest,
from .item import (ManualTest, WebDriverSpecTest, Stub, RefTestNode, RefTest, RefTestBase,
TestharnessTest, SupportFile, ConformanceCheckerTest, VisualTest)
from .log import get_logger
from .utils import from_os_path, to_os_path
@ -37,6 +37,7 @@ def iterfilter(filters, iter):
item_classes = {"testharness": TestharnessTest,
"reftest": RefTest,
"reftest_node": RefTestNode,
"reftest_base": RefTestBase,
"manual": ManualTest,
"stub": Stub,
"wdspec": WebDriverSpecTest,
@ -132,10 +133,7 @@ class TypeData(object):
data = set()
path = from_os_path(key)
for test in iterfilter(self.meta_filters, self.json_data.get(path, [])):
manifest_item = self.type_cls.from_json(self.manifest,
self.tests_root,
path,
test)
manifest_item = self.type_cls.from_json(self.manifest, path, test)
data.add(manifest_item)
try:
del self.json_data[path]
@ -154,10 +152,7 @@ class TypeData(object):
continue
data = set()
for test in iterfilter(self.meta_filters, self.json_data.get(path, [])):
manifest_item = self.type_cls.from_json(self.manifest,
self.tests_root,
path,
test)
manifest_item = self.type_cls.from_json(self.manifest, path, test)
data.add(manifest_item)
self.data[key] = data
self.json_data = None
@ -202,11 +197,12 @@ class ManifestData(dict):
class Manifest(object):
def __init__(self, url_base="/", meta_filters=None):
def __init__(self, tests_root=None, url_base="/", meta_filters=None):
assert url_base is not None
self._path_hash = {}
self._data = ManifestData(self, meta_filters)
self._reftest_nodes_by_url = None
self.tests_root = tests_root
self.url_base = url_base
def __iter__(self):
@ -285,22 +281,21 @@ class Manifest(object):
new_type, manifest_items = source_file.manifest_items()
hash_changed = True
if new_type != old_type:
try:
del self._data[old_type][rel_path]
except KeyError:
pass
del self._data[old_type][rel_path]
if old_type in reftest_types:
reftest_changes = True
else:
new_type, manifest_items = old_type, self._data[old_type][rel_path]
if old_type in reftest_types and new_type != old_type:
reftest_changes = True
new_type = old_type
if old_type in reftest_types:
manifest_items = 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 new_type in reftest_types:
reftest_nodes.extend((item, file_hash) for item in manifest_items)
if is_new or hash_changed:
reftest_changes = True
elif new_type:
elif is_new or hash_changed:
self._data[new_type][rel_path] = set(manifest_items)
self._path_hash[rel_path] = (file_hash, new_type)
@ -337,7 +332,7 @@ class Manifest(object):
def _compute_reftests(self, reftest_nodes):
self._reftest_nodes_by_url = {}
has_inbound = set()
for item in reftest_nodes:
for item, _ in reftest_nodes:
for ref_url, ref_type in item.references:
has_inbound.add(ref_url)
@ -345,20 +340,20 @@ class Manifest(object):
references = defaultdict(set)
changed_hashes = {}
for item in reftest_nodes:
for item, file_hash 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)
changed_hashes[item.path] = (file_hash,
item.item_type)
references[item.path].add(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)
changed_hashes[item.path] = (file_hash,
item.item_type)
reftests[item.path].add(item)
self._reftest_nodes_by_url[item.url] = item
return reftests, references, changed_hashes
@ -384,7 +379,7 @@ class Manifest(object):
if version != CURRENT_VERSION:
raise ManifestVersionMismatch
self = cls(url_base=obj.get("url_base", "/"), meta_filters=meta_filters)
self = cls(tests_root, url_base=obj.get("url_base", "/"), meta_filters=meta_filters)
if not hasattr(obj, "items") and hasattr(obj, "paths"):
raise ManifestError
@ -473,7 +468,7 @@ def load_and_update(tests_root,
logger.info("Manifest url base did not match, rebuilding")
if manifest is None:
manifest = Manifest(url_base, meta_filters=meta_filters)
manifest = Manifest(tests_root, url_base, meta_filters=meta_filters)
update = True
if update:

View file

@ -13,7 +13,7 @@ import html5lib
from . import XMLParser
from .item import Stub, ManualTest, WebDriverSpecTest, RefTestNode, TestharnessTest, SupportFile, ConformanceCheckerTest, VisualTest
from .utils import rel_path_to_url, ContextManagerBytesIO, cached_property
from .utils import ContextManagerBytesIO, cached_property
wd_pattern = "*.py"
js_meta_re = re.compile(b"//\s*META:\s*(\w*)=(.*)$")
@ -232,9 +232,14 @@ class SourceFile(object):
def path(self):
return os.path.join(self.tests_root, self.rel_path)
@cached_property
def rel_url(self):
assert not os.path.isabs(self.rel_path), self.rel_path
return self.rel_path.replace(os.sep, "/")
@cached_property
def url(self):
return rel_path_to_url(self.rel_path, self.url_base)
return urljoin(self.url_base, self.rel_url)
@cached_property
def hash(self):
@ -599,22 +604,54 @@ class SourceFile(object):
return self.items_cache
if self.name_is_non_test:
rv = "support", [SupportFile(self)]
rv = "support", [
SupportFile(
self.tests_root,
self.rel_path
)]
elif self.name_is_stub:
rv = Stub.item_type, [Stub(self, self.url)]
rv = Stub.item_type, [
Stub(
self.tests_root,
self.rel_path,
self.url_base,
self.rel_url
)]
elif self.name_is_manual:
rv = ManualTest.item_type, [ManualTest(self, self.url)]
rv = ManualTest.item_type, [
ManualTest(
self.tests_root,
self.rel_path,
self.url_base,
self.rel_url
)]
elif self.name_is_conformance:
rv = ConformanceCheckerTest.item_type, [ConformanceCheckerTest(self, self.url)]
rv = ConformanceCheckerTest.item_type, [
ConformanceCheckerTest(
self.tests_root,
self.rel_path,
self.url_base,
self.rel_url
)]
elif self.name_is_conformance_support:
rv = "support", [SupportFile(self)]
rv = "support", [
SupportFile(
self.tests_root,
self.rel_path
)]
elif self.name_is_visual:
rv = VisualTest.item_type, [VisualTest(self, self.url)]
rv = VisualTest.item_type, [
VisualTest(
self.tests_root,
self.rel_path,
self.url_base,
self.rel_url
)]
elif self.name_is_multi_global:
globals = b""
@ -624,53 +661,112 @@ class SourceFile(object):
break
tests = [
TestharnessTest(self, global_variant_url(self.url, suffix) + variant, timeout=self.timeout,
jsshell=jsshell)
TestharnessTest(
self.tests_root,
self.rel_path,
self.url_base,
global_variant_url(self.rel_url, suffix) + variant,
timeout=self.timeout,
jsshell=jsshell,
script_metadata=self.script_metadata
)
for (suffix, jsshell) in sorted(global_suffixes(globals))
for variant in self.test_variants
]
rv = TestharnessTest.item_type, tests
elif self.name_is_worker:
test_url = replace_end(self.url, ".worker.js", ".worker.html")
test_url = replace_end(self.rel_url, ".worker.js", ".worker.html")
tests = [
TestharnessTest(self, test_url + variant, timeout=self.timeout)
TestharnessTest(
self.tests_root,
self.rel_path,
self.url_base,
test_url + variant,
timeout=self.timeout,
script_metadata=self.script_metadata
)
for variant in self.test_variants
]
rv = TestharnessTest.item_type, tests
elif self.name_is_window:
test_url = replace_end(self.url, ".window.js", ".window.html")
test_url = replace_end(self.rel_url, ".window.js", ".window.html")
tests = [
TestharnessTest(self, test_url + variant, timeout=self.timeout)
TestharnessTest(
self.tests_root,
self.rel_path,
self.url_base,
test_url + variant,
timeout=self.timeout,
script_metadata=self.script_metadata
)
for variant in self.test_variants
]
rv = TestharnessTest.item_type, tests
elif self.name_is_webdriver:
rv = WebDriverSpecTest.item_type, [WebDriverSpecTest(self, self.url,
timeout=self.timeout)]
rv = WebDriverSpecTest.item_type, [
WebDriverSpecTest(
self.tests_root,
self.rel_path,
self.url_base,
self.rel_url,
timeout=self.timeout
)]
elif self.content_is_css_manual and not self.name_is_reference:
rv = ManualTest.item_type, [ManualTest(self, self.url)]
rv = ManualTest.item_type, [
ManualTest(
self.tests_root,
self.rel_path,
self.url_base,
self.rel_url
)]
elif self.content_is_testharness:
rv = TestharnessTest.item_type, []
testdriver = self.has_testdriver
for variant in self.test_variants:
url = self.url + variant
rv[1].append(TestharnessTest(self, url, timeout=self.timeout, testdriver=testdriver))
url = self.rel_url + variant
rv[1].append(TestharnessTest(
self.tests_root,
self.rel_path,
self.url_base,
url,
timeout=self.timeout,
testdriver=testdriver,
script_metadata=self.script_metadata
))
elif self.content_is_ref_node:
rv = (RefTestNode.item_type,
[RefTestNode(self, self.url, self.references, timeout=self.timeout,
viewport_size=self.viewport_size, dpi=self.dpi)])
rv = RefTestNode.item_type, [
RefTestNode(
self.tests_root,
self.rel_path,
self.url_base,
self.rel_url,
references=self.references,
timeout=self.timeout,
viewport_size=self.viewport_size,
dpi=self.dpi
)]
elif self.content_is_css_visual and not self.name_is_reference:
rv = VisualTest.item_type, [VisualTest(self, self.url)]
rv = VisualTest.item_type, [
VisualTest(
self.tests_root,
self.rel_path,
self.url_base,
self.rel_url
)]
else:
rv = "support", [SupportFile(self)]
rv = "support", [
SupportFile(
self.tests_root,
self.rel_path
)]
self.items_cache = rv

View file

@ -1,23 +1,66 @@
from ..item import SupportFile, URLManifestItem
from ..sourcefile import SourceFile
import pytest
from ..item import URLManifestItem, TestharnessTest
def test_base_meta_flags():
s = SourceFile("/", "a.b.c.d", "/", contents="")
m = SupportFile(s)
@pytest.mark.parametrize("path", [
"a.https.c",
"a.b.https.c",
"a.https.b.c",
"a.b.https.c.d",
"a.serviceworker.c",
"a.b.serviceworker.c",
"a.serviceworker.b.c",
"a.b.serviceworker.c.d",
])
def test_url_https(path):
m = URLManifestItem("/foobar", "/" + path, "/", "/foo.bar/" + path)
assert m.meta_flags == {"b", "c"}
assert m.https is True
def test_url_meta_flags():
s = SourceFile("/", "a.b.c", "/", contents="")
m = URLManifestItem(s, "/foo.bar/a.b.d.e")
@pytest.mark.parametrize("path", [
"https",
"a.https",
"a.b.https",
"https.a",
"https.a.b",
"a.bhttps.c",
"a.httpsb.c",
"serviceworker",
"a.serviceworker",
"a.b.serviceworker",
"serviceworker.a",
"serviceworker.a.b",
"a.bserviceworker.c",
"a.serviceworkerb.c",
])
def test_url_not_https(path):
m = URLManifestItem("/foobar", "/" + path, "/", "/foo.bar/" + path)
assert m.meta_flags == {"b", "d"}
assert m.https is False
def test_url_empty_meta_flags():
s = SourceFile("/", "a.b.c", "/", contents="")
m = URLManifestItem(s, "/foo.bar/abcde")
def test_testharness_meta_key_includes_jsshell():
a = TestharnessTest("/foobar", "/foo", "/foo.bar", "/foo.bar/foo",
jsshell=False, script_metadata=[])
b = TestharnessTest("/foobar", "/foo", "/foo.bar", "/foo.bar/foo",
jsshell=True, script_metadata=[])
assert m.meta_flags == set()
assert a.meta_key() != b.meta_key()
@pytest.mark.parametrize("script_metadata", [
None,
[],
[('script', '/resources/WebIDLParser.js'), ('script', '/resources/idlharness.js')],
[[u'script', u'/resources/WebIDLParser.js'], [u'script', u'/resources/idlharness.js']],
])
def test_testharness_hashable_script_metadata(script_metadata):
a = TestharnessTest("/",
"BackgroundSync/interfaces.https.any.js",
"/",
"/BackgroundSync/interfaces.https.any.js",
script_metadata=script_metadata)
assert hash(a) is not None

View file

@ -10,15 +10,18 @@ import pytest
from .. import manifest, item, utils
def SourceFileWithTest(path, hash, cls, *args):
def SourceFileWithTest(path, hash, cls, **kwargs):
s = mock.Mock(rel_path=path, hash=hash)
test = cls(s, utils.rel_path_to_url(path), *args)
if cls == item.SupportFile:
test = cls("/foobar", path, **kwargs)
else:
test = cls("/foobar", path, "/", utils.rel_path_to_url(path), **kwargs)
s.manifest_items = mock.Mock(return_value=(cls.item_type, [test]))
return s
def SourceFileWithTests(path, hash, cls, variants):
s = mock.Mock(rel_path=path, hash=hash)
tests = [cls(s, item[0], *item[1:]) for item in variants]
tests = [cls("/foobar", path, "/", item[0], *item[1:]) for item in variants]
s.manifest_items = mock.Mock(return_value=(cls.item_type, tests))
return s
@ -42,7 +45,7 @@ def rel_dir_file_path(draw):
@hs.composite
def sourcefile_strategy(draw):
item_classes = [item.TestharnessTest, item.RefTest, item.RefTestNode,
item_classes = [item.TestharnessTest, item.RefTestNode,
item.ManualTest, item.Stub, item.WebDriverSpecTest,
item.ConformanceCheckerTest, item.SupportFile]
cls = draw(hs.sampled_from(item_classes))
@ -51,15 +54,15 @@ def sourcefile_strategy(draw):
hash = draw(hs.text(alphabet="0123456789abcdef", min_size=40, max_size=40))
s = mock.Mock(rel_path=path, hash=hash)
if cls in (item.RefTest, item.RefTestNode):
if cls is item.RefTestNode:
ref_path = draw(rel_dir_file_path())
h.assume(path != ref_path)
ref_eq = draw(hs.sampled_from(["==", "!="]))
test = cls(s, utils.rel_path_to_url(path), [(utils.rel_path_to_url(ref_path), ref_eq)])
test = cls("/foobar", path, "/", utils.rel_path_to_url(path), references=[(utils.rel_path_to_url(ref_path), ref_eq)])
elif cls is item.SupportFile:
test = cls(s)
test = cls("/foobar", path)
else:
test = cls(s, utils.rel_path_to_url(path))
test = cls("/foobar", path, "/", utils.rel_path_to_url(path))
s.manifest_items = mock.Mock(return_value=(cls.item_type, [test]))
return s
@ -84,7 +87,7 @@ def test_manifest_to_json(s):
@h.given(hs.lists(sourcefile_strategy(),
min_size=1, unique_by=lambda x: x.rel_path))
@h.example([SourceFileWithTest("a", "0"*40, item.TestharnessTest)])
@h.example([SourceFileWithTest("a", "0"*40, item.RefTest, [("/aa", "==")])])
@h.example([SourceFileWithTest("a", "0"*40, item.RefTestNode, references=[("/aa", "==")])])
def test_manifest_idempotent(s):
m = manifest.Manifest()
@ -167,72 +170,68 @@ def test_manifest_from_json_backslash():
def test_reftest_computation_chain():
m = manifest.Manifest()
s1 = SourceFileWithTest("test1", "0"*40, item.RefTest, [("/test2", "==")])
s2 = SourceFileWithTest("test2", "0"*40, item.RefTest, [("/test3", "==")])
s1 = SourceFileWithTest("test1", "0"*40, item.RefTestNode, references=[("/test2", "==")])
s2 = SourceFileWithTest("test2", "0"*40, item.RefTestNode, references=[("/test3", "==")])
m.update([(s1, True), (s2, True)])
test1 = s1.manifest_items()[1][0]
test2 = s2.manifest_items()[1][0]
test2_node = test2.to_RefTestNode()
assert list(m) == [("reftest", test1.path, {test1}),
("reftest_node", test2.path, {test2_node})]
assert list(m) == [("reftest", test1.path, {test1.to_RefTest()}),
("reftest_node", test2.path, {test2})]
def test_reftest_computation_chain_update_add():
m = manifest.Manifest()
s2 = SourceFileWithTest("test2", "0"*40, item.RefTest, [("/test3", "==")])
s2 = SourceFileWithTest("test2", "0"*40, item.RefTestNode, references=[("/test3", "==")])
test2 = s2.manifest_items()[1][0]
assert m.update([(s2, True)]) is True
assert list(m) == [("reftest", test2.path, {test2})]
assert list(m) == [("reftest", test2.path, {test2.to_RefTest()})]
s1 = SourceFileWithTest("test1", "0"*40, item.RefTest, [("/test2", "==")])
s1 = SourceFileWithTest("test1", "0"*40, item.RefTestNode, references=[("/test2", "==")])
test1 = s1.manifest_items()[1][0]
# s2's hash is unchanged, but it has gone from a test to a node
assert m.update([(s1, True), (s2, True)]) is True
test2_node = test2.to_RefTestNode()
assert list(m) == [("reftest", test1.path, {test1}),
("reftest_node", test2.path, {test2_node})]
assert list(m) == [("reftest", test1.path, {test1.to_RefTest()}),
("reftest_node", test2.path, {test2})]
def test_reftest_computation_chain_update_remove():
m = manifest.Manifest()
s1 = SourceFileWithTest("test1", "0"*40, item.RefTest, [("/test2", "==")])
s2 = SourceFileWithTest("test2", "0"*40, item.RefTest, [("/test3", "==")])
s1 = SourceFileWithTest("test1", "0"*40, item.RefTestNode, references=[("/test2", "==")])
s2 = SourceFileWithTest("test2", "0"*40, item.RefTestNode, references=[("/test3", "==")])
assert m.update([(s1, True), (s2, True)]) is True
test1 = s1.manifest_items()[1][0]
test2 = s2.manifest_items()[1][0]
test2_node = test2.to_RefTestNode()
assert list(m) == [("reftest", test1.path, {test1}),
("reftest_node", test2.path, {test2_node})]
assert list(m) == [("reftest", test1.path, {test1.to_RefTest()}),
("reftest_node", test2.path, {test2})]
# s2's hash is unchanged, but it has gone from a node to a test
assert m.update([(s2, True)]) is True
assert list(m) == [("reftest", test2.path, {test2})]
assert list(m) == [("reftest", test2.path, {test2.to_RefTest()})]
def test_reftest_computation_chain_update_test_type():
m = manifest.Manifest()
s1 = SourceFileWithTest("test", "0"*40, item.RefTest, [("/test-ref", "==")])
s1 = SourceFileWithTest("test", "0"*40, item.RefTestNode, references=[("/test-ref", "==")])
assert m.update([(s1, True)]) is True
test1 = s1.manifest_items()[1][0]
assert list(m) == [("reftest", test1.path, {test1})]
assert list(m) == [("reftest", test1.path, {test1.to_RefTest()})]
# test becomes a testharness test (hash change because that is determined
# based on the file contents). The updated manifest should not includes the
@ -248,15 +247,15 @@ def test_reftest_computation_chain_update_test_type():
def test_reftest_computation_chain_update_node_change():
m = manifest.Manifest()
s1 = SourceFileWithTest("test1", "0"*40, item.RefTest, [("/test2", "==")])
s2 = SourceFileWithTest("test2", "0"*40, item.RefTestNode, [("/test3", "==")])
s1 = SourceFileWithTest("test1", "0"*40, item.RefTestNode, references=[("/test2", "==")])
s2 = SourceFileWithTest("test2", "0"*40, item.RefTestNode, references=[("/test3", "==")])
assert m.update([(s1, True), (s2, True)]) is True
test1 = s1.manifest_items()[1][0]
test2 = s2.manifest_items()[1][0]
assert list(m) == [("reftest", test1.path, {test1}),
assert list(m) == [("reftest", test1.path, {test1.to_RefTest()}),
("reftest_node", test2.path, {test2})]
#test2 changes to support type
@ -265,24 +264,20 @@ def test_reftest_computation_chain_update_node_change():
assert m.update([(s1, True), (s2, True)]) is True
test3 = s2.manifest_items()[1][0]
assert list(m) == [("reftest", test1.path, {test1}),
assert list(m) == [("reftest", test1.path, {test1.to_RefTest()}),
("support", test3.path, {test3})]
def test_iterpath():
m = manifest.Manifest()
# This has multiple test types from the same file, which isn't really supported,
# so pretend they have different hashes
sources = [SourceFileWithTest("test1", "0"*40, item.RefTest, [("/test1-ref", "==")]),
SourceFileWithTest("test2", "0"*40, item.RefTest, [("/test2-ref", "==")]),
sources = [SourceFileWithTest("test1", "0"*40, item.RefTestNode, references=[("/test1-ref", "==")]),
SourceFileWithTests("test2", "1"*40, item.TestharnessTest, [("/test2-1.html",),
("/test2-2.html",)]),
SourceFileWithTest("test3", "0"*40, item.TestharnessTest)]
m.update([(s, True) for s in sources])
assert set(item.url for item in m.iterpath("test2")) == set(["/test2",
"/test2-1.html",
assert set(item.url for item in m.iterpath("test2")) == set(["/test2-1.html",
"/test2-2.html"])
assert set(m.iterpath("missing")) == set()
@ -290,10 +285,7 @@ def test_iterpath():
def test_filter():
m = manifest.Manifest()
# This has multiple test types from the same file, which isn't really supported,
# so pretend they have different hashes
sources = [SourceFileWithTest("test1", "0"*40, item.RefTest, [("/test1-ref", "==")]),
SourceFileWithTest("test2", "1"*40, item.RefTest, [("/test2-ref", "==")]),
sources = [SourceFileWithTest("test1", "0"*40, item.RefTestNode, references=[("/test1-ref", "==")]),
SourceFileWithTests("test2", "0"*40, item.TestharnessTest, [("/test2-1.html",),
("/test2-2.html",)]),
SourceFileWithTest("test3", "0"*40, item.TestharnessTest)]
@ -321,20 +313,19 @@ def test_filter():
def test_reftest_node_by_url():
m = manifest.Manifest()
s1 = SourceFileWithTest("test1", "0"*40, item.RefTest, [("/test2", "==")])
s2 = SourceFileWithTest("test2", "0"*40, item.RefTest, [("/test3", "==")])
s1 = SourceFileWithTest("test1", "0"*40, item.RefTestNode, references=[("/test2", "==")])
s2 = SourceFileWithTest("test2", "0"*40, item.RefTestNode, references=[("/test3", "==")])
m.update([(s1, True), (s2, True)])
test1 = s1.manifest_items()[1][0]
test2 = s2.manifest_items()[1][0]
test2_node = test2.to_RefTestNode()
assert m.reftest_nodes_by_url == {"/test1": test1,
"/test2": test2_node}
assert m.reftest_nodes_by_url == {"/test1": test1.to_RefTest(),
"/test2": test2}
m._reftest_nodes_by_url = None
assert m.reftest_nodes_by_url == {"/test1": test1,
"/test2": test2_node}
assert m.reftest_nodes_by_url == {"/test1": test1.to_RefTest(),
"/test2": test2}
def test_no_update():

View file

@ -766,3 +766,26 @@ def test_spec_links_whitespace(url):
content = b"<link rel=help href='%s'>" % url
s = create("foo/test.html", content)
assert s.spec_links == {"http://example.com/"}
def test_url_base():
contents = b"""// META: global=window,worker
// META: variant=
// META: variant=?wss
test()"""
s = SourceFile("/", "html/test.any.js", "/_fake_base/", contents=contents)
item_type, items = s.manifest_items()
assert item_type == "testharness"
assert [item.url for item in items] == [u'/_fake_base/html/test.any.html',
u'/_fake_base/html/test.any.html?wss',
u'/_fake_base/html/test.any.serviceworker.html',
u'/_fake_base/html/test.any.serviceworker.html?wss',
u'/_fake_base/html/test.any.sharedworker.html',
u'/_fake_base/html/test.any.sharedworker.html?wss',
u'/_fake_base/html/test.any.worker.html',
u'/_fake_base/html/test.any.worker.html?wss']
assert items[0].url_base == "/_fake_base/"

View file

@ -0,0 +1,14 @@
import os
import subprocess
import mock
from .. import vcs
def test_git_for_path_no_git():
this_dir = os.path.dirname(__file__)
with mock.patch(
"subprocess.check_output",
side_effect=subprocess.CalledProcessError(1, "foo")):
assert vcs.Git.for_path(this_dir, "/", this_dir) is None

View file

@ -60,10 +60,13 @@ class Git(object):
def for_path(cls, path, url_base, cache_path, manifest_path=None, rebuild=False):
git = Git.get_func(path)
try:
return cls(git("rev-parse", "--show-toplevel").rstrip(), url_base, cache_path,
manifest_path=manifest_path, rebuild=rebuild)
# this needs to be a command that fails if we aren't in a git repo
git("rev-parse", "--show-toplevel")
except (subprocess.CalledProcessError, OSError):
return None
else:
return cls(path, url_base, cache_path,
manifest_path=manifest_path, rebuild=rebuild)
def _local_changes(self):
changes = {}
@ -97,16 +100,15 @@ class Git(object):
for result in self.git(*cmd).split("\0")[:-1]:
rel_path = result.split("\t")[-1]
hash = result.split()[2]
if not os.path.isdir(os.path.join(self.root, rel_path)):
if rel_path in local_changes:
contents = self._show_file(rel_path)
else:
contents = None
yield SourceFile(self.root,
rel_path,
self.url_base,
hash,
contents=contents), True
if rel_path in local_changes:
contents = self._show_file(rel_path)
else:
contents = None
yield SourceFile(self.root,
rel_path,
self.url_base,
hash,
contents=contents), True
def dump_caches(self):
pass