From 968cf06036f9bdb0ce577769108b9d54a146acc5 Mon Sep 17 00:00:00 2001 From: Geoff Brown Date: Tue, 5 Nov 2019 17:09:41 +0000 Subject: [PATCH] Bug 1592608 - Add more fields to ReftestManifest test descriptions; r=ahal,froydnj Add test annotations to the ReftestManifest and TestResolver. For example, a test description from the TestResolver might now contain 'skip-if': 'skiaContent'; similar to the content provided for manifestparser tests; this will allow 'mach test-info report' to filter tests based on reftest manifest test annotations. Also add the referenced-test field which identifies the test file associated with test entries for reference files; this will allow test-verify to run the correct reftest when only the reference file has been modified. Differential Revision: https://phabricator.services.mozilla.com/D51113 --HG-- extra : moz-landing-system : lando --- layout/tools/reftest/reftest/__init__.py | 66 +++++++++++++------- python/mozbuild/mozbuild/frontend/emitter.py | 12 +--- python/mozbuild/mozbuild/frontend/reader.py | 9 ++- 3 files changed, 49 insertions(+), 38 deletions(-) diff --git a/layout/tools/reftest/reftest/__init__.py b/layout/tools/reftest/reftest/__init__.py index 5b1239faee6c..61f8b271db4d 100644 --- a/layout/tools/reftest/reftest/__init__.py +++ b/layout/tools/reftest/reftest/__init__.py @@ -33,24 +33,58 @@ PREF_ITEMS = ( 'test-pref', 'ref-pref', ) +RE_ANNOTATION = re.compile(r'(.*)\((.*)\)') class ReftestManifest(object): """Represents a parsed reftest manifest. - - We currently only capture file information because that is the only thing - tools require. """ def __init__(self, finder=None): self.path = None self.dirs = set() self.files = set() self.manifests = set() - self.tests = set() + self.tests = [] self.finder = finder def load(self, path): """Parse a reftest manifest file.""" + + def add_test(file, annotations, referenced_test=None): + # We can't package about:, data:, or chrome: URIs. + # Discarding data isn't correct for a parser. But retaining + # all data isn't currently a requirement. + if RE_PROTOCOL.match(file): + return + test = os.path.normpath(os.path.join(mdir, urlprefix + file)) + if test in self.files: + # if test path has already been added, make no changes, to + # avoid duplicate paths in self.tests + return + self.files.add(test) + self.dirs.add(os.path.dirname(test)) + test_dict = { + 'path': test, + 'here': os.path.dirname(test), + 'manifest': normalized_path, + 'name': os.path.basename(test), + 'head': '', + 'support-files': '', + 'subsuite': '', + } + if referenced_test: + test_dict['referenced-test'] = referenced_test + for annotation in annotations: + m = RE_ANNOTATION.match(annotation) + if m: + if m.group(1) not in test_dict: + test_dict[m.group(1)] = m.group(2) + else: + test_dict[m.group(1)] += ";" + m.group(2) + else: + test_dict[annotation] = None + self.tests.append(test_dict) + normalized_path = os.path.normpath(os.path.abspath(path)) self.manifests.add(normalized_path) if not self.path: @@ -82,14 +116,13 @@ class ReftestManifest(object): continue items = line.split() - tests = [] + annotations = [] for i in range(len(items)): item = items[i] - if item.startswith(FAILURE_TYPES): - continue - if item.startswith(PREF_ITEMS): + if item.startswith(FAILURE_TYPES) or item.startswith(PREF_ITEMS): + annotations += [item] continue if item == 'HTTP': continue @@ -113,21 +146,10 @@ class ReftestManifest(object): break if item == 'load' or item == 'script': - tests.append(items[i+1]) + add_test(items[i+1], annotations) break if item == '==' or item == '!=' or item == 'print': - tests.extend(items[i+1:i+3]) + add_test(items[i+1], annotations) + add_test(items[i+2], annotations, items[i+1]) break - - for f in tests: - # We can't package about:, data:, or chrome: URIs. - # Discarding data isn't correct for a parser. But retaining - # all data isn't currently a requirement. - if RE_PROTOCOL.match(f): - continue - - test = os.path.normpath(os.path.join(mdir, urlprefix + f)) - self.files.add(test) - self.dirs.add(os.path.dirname(test)) - self.tests.add((test, normalized_path)) diff --git a/python/mozbuild/mozbuild/frontend/emitter.py b/python/mozbuild/mozbuild/frontend/emitter.py index 2d49e328dc1f..40b66502b9fa 100644 --- a/python/mozbuild/mozbuild/frontend/emitter.py +++ b/python/mozbuild/mozbuild/frontend/emitter.py @@ -1600,17 +1600,7 @@ class TreeMetadataEmitter(LoggingMixin): flavor=flavor, install_prefix='%s/' % flavor, relpath=mozpath.join(manifest_reldir, mozpath.basename(manifest_path))) - - for test, source_manifest in sorted(manifest.tests): - obj.tests.append({ - 'path': test, - 'here': mozpath.dirname(test), - 'manifest': source_manifest, - 'name': mozpath.basename(test), - 'head': '', - 'support-files': '', - 'subsuite': '', - }) + obj.tests = list(sorted(manifest.tests, key=lambda t: t['path'])) yield obj diff --git a/python/mozbuild/mozbuild/frontend/reader.py b/python/mozbuild/mozbuild/frontend/reader.py index f9c7ab0b51bc..e43e3a1af803 100644 --- a/python/mozbuild/mozbuild/frontend/reader.py +++ b/python/mozbuild/mozbuild/frontend/reader.py @@ -1418,11 +1418,10 @@ class BuildReader(object): result_context.test_files.add(mozpath.dirname(t) + '/**') else: for t in obj.tests: - if isinstance(t, tuple): - path, _ = t - relpath = mozpath.relpath(path, - self.config.topsrcdir) - else: + if 'relpath' in t: relpath = t['relpath'] + else: + relpath = mozpath.relpath(t['path'], + self.config.topsrcdir) result_context.test_files.add(mozpath.dirname(relpath) + '/**') return result_context