--- a/python/mozbuild/mozbuild/frontend/emitter.py
+++ b/python/mozbuild/mozbuild/frontend/emitter.py
@@ -2,32 +2,34 @@
# 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/.
from __future__ import absolute_import, unicode_literals
import itertools
import logging
import os
-import traceback
import sys
import time
+import traceback
+from abc import ABCMeta, abstractmethod
+from collections import defaultdict, OrderedDict
-from collections import defaultdict, OrderedDict
+import mozinfo
+import pytoml
from mach.mixin.logging import LoggingMixin
-from mozbuild.util import (
- memoize,
- OrderedDefaultDict,
+
+import mozpack.path as mozpath
+from mozpack.chrome.manifest import (
+ ManifestBinaryComponent,
+ Manifest,
)
-import mozpack.path as mozpath
-import mozinfo
-import pytoml
-
-from .data import (
+from mozbuild.base import ExecutionSummary
+from mozbuild.frontend.data import (
AndroidAssetsDirs,
AndroidExtraPackages,
AndroidExtraResDirs,
AndroidResDirs,
BaseSources,
BrandingFiles,
ChromeManifestEntry,
ConfigFileSubstitution,
@@ -65,74 +67,321 @@ from .data import (
RustLibrary,
RustProgram,
SdkFiles,
SharedLibrary,
SimpleProgram,
Sources,
StaticLibrary,
TestHarnessFiles,
+ TestManifest,
TestWebIDLFile,
- TestManifest,
UnifiedSources,
VariablePassthru,
WebIDLFile,
XPIDLFile,
)
-from mozpack.chrome.manifest import (
- ManifestBinaryComponent,
- Manifest,
-)
-from .reader import SandboxValidationError
-
-from ..testing import (
- TEST_MANIFESTS,
- REFTEST_FLAVORS,
- WEB_PLATFORM_TESTS_FLAVORS,
- SupportFilesConverter,
-)
-
-from .context import (
+from mozbuild.frontend.reader import SandboxValidationError
+from mozbuild.frontend.context import (
Context,
SourcePath,
ObjDirPath,
Path,
SubContext,
TemplateContext,
)
-from mozbuild.base import ExecutionSummary
+from mozbuild.testing import (
+ TEST_MANIFESTS,
+ REFTEST_FLAVORS,
+ WEB_PLATFORM_TESTS_FLAVORS,
+ SupportFilesConverter
+)
+
+from mozbuild.util import (
+ memoize,
+ OrderedDefaultDict,
+)
ALLOWED_XPCOM_GLUE = {
('xpcshell', 'js/xpconnect/shell'),
('testcrasher', 'toolkit/crashreporter/test'),
('mediaconduit_unittests', 'media/webrtc/signaling/test'),
('mediapipeline_unittest', 'media/webrtc/signaling/test'),
('signaling_unittests', 'media/webrtc/signaling/test'),
('TestMailCookie', 'mailnews/base/test'),
('calbasecomps', 'calendar/base/backend/libical/build'),
('purplexpcom', 'extensions/purple/purplexpcom/src'),
('ipdlunittest', 'ipc/ipdl/test/cxx/app'),
}
-class TreeMetadataEmitter(LoggingMixin):
+class BaseEmitter(LoggingMixin):
+ """Base emitter class for consuming moz.build metadata.
+
+ Subclasses should implement emit_from_context."""
+ __metaclass__ = ABCMeta
+
+ def __init__(self, config):
+ self.populate_logger()
+ self.config = config
+
+ self._emitter_time = 0.0
+ self._object_count = 0
+ self._contexts = {}
+
+ @abstractmethod
+ def emit_from_context(self, context):
+ pass
+
+ def summary(self):
+ return ExecutionSummary(
+ 'Processed into {object_count:d} build config descriptors in '
+ '{execution_time:.2f}s',
+ execution_time=self._emitter_time,
+ object_count=self._object_count)
+
+ def _emit_objs(self, objs):
+ for o in objs:
+ self._object_count += 1
+ yield o
+
+ def emit(self, output):
+ """Convert the BuildReader output into data structures.
+
+ The return value from BuildReader.read_topsrcdir() (a generator) is
+ typically fed into this function.
+ """
+ for out in output:
+ # Nothing in sub-contexts is currently of interest to us. Filter
+ # them all out.
+ if isinstance(out, SubContext):
+ continue
+
+ if isinstance(out, Context):
+ # Keep all contexts around, we will need them later.
+ self._contexts[out.objdir] = out
+
+ start = time.time()
+ # We need to expand the generator for the timings to work.
+ objs = list(self.emit_from_context(out))
+ self._emitter_time += time.time() - start
+
+ for o in self._emit_objs(objs): yield o
+
+ else:
+ raise Exception('Unhandled output type: %s' % type(out))
+
+
+class TestManifestEmitter(BaseEmitter):
+ """Emitter that creates test manifest data structures.
+
+ All other in-tree metadata derived from moz.build is ignored.
+ """
+
+ def __init__(self, config):
+ BaseEmitter.__init__(self, config)
+ self._test_files_converter = SupportFilesConverter()
+
+ def emit_from_context(self, context):
+ for prefix, info in TEST_MANIFESTS.items():
+ for path, manifest in context.get('%s_MANIFESTS' % prefix, []):
+ for obj in self._process_test_manifest(context, info, path, manifest):
+ yield obj
+
+ for flavor in REFTEST_FLAVORS:
+ for path, manifest in context.get('%s_MANIFESTS' % flavor.upper(), []):
+ for obj in self._process_reftest_manifest(context, flavor, path, manifest):
+ yield obj
+
+ for flavor in WEB_PLATFORM_TESTS_FLAVORS:
+ for path, manifest in context.get("%s_MANIFESTS" % flavor.upper().replace('-', '_'), []):
+ for obj in self._process_web_platform_tests_manifest(context, path, manifest):
+ yield obj
+
+ def _process_test_manifest(self, context, info, manifest_path, mpmanifest):
+ flavor, install_root, install_subdir, package_tests = info
+
+ path = mozpath.normpath(mozpath.join(context.srcdir, manifest_path))
+ manifest_dir = mozpath.dirname(path)
+ manifest_reldir = mozpath.dirname(mozpath.relpath(path,
+ context.config.topsrcdir))
+ manifest_sources = [mozpath.relpath(pth, context.config.topsrcdir)
+ for pth in mpmanifest.source_files]
+ install_prefix = mozpath.join(install_root, install_subdir)
+
+ try:
+ if not mpmanifest.tests:
+ raise SandboxValidationError('Empty test manifest: %s'
+ % path, context)
+
+ defaults = mpmanifest.manifest_defaults[os.path.normpath(path)]
+ obj = TestManifest(context, path, mpmanifest, flavor=flavor,
+ install_prefix=install_prefix,
+ relpath=mozpath.join(manifest_reldir, mozpath.basename(path)),
+ sources=manifest_sources,
+ dupe_manifest='dupe-manifest' in defaults)
+
+ filtered = mpmanifest.tests
+
+ # Jetpack add-on tests are expected to be generated during the
+ # build process so they won't exist here.
+ if flavor != 'jetpack-addon':
+ missing = [t['name'] for t in filtered if not os.path.exists(t['path'])]
+ if missing:
+ raise SandboxValidationError('Test manifest (%s) lists '
+ 'test that does not exist: %s' % (
+ path, ', '.join(missing)), context)
+
+ out_dir = mozpath.join(install_prefix, manifest_reldir)
+ if 'install-to-subdir' in defaults:
+ # This is terrible, but what are you going to do?
+ out_dir = mozpath.join(out_dir, defaults['install-to-subdir'])
+ obj.manifest_obj_relpath = mozpath.join(manifest_reldir,
+ defaults['install-to-subdir'],
+ mozpath.basename(path))
+
+ def process_support_files(test):
+ install_info = self._test_files_converter.convert_support_files(
+ test, install_root, manifest_dir, out_dir)
+
+ obj.pattern_installs.extend(install_info.pattern_installs)
+ for source, dest in install_info.installs:
+ obj.installs[source] = (dest, False)
+ obj.external_installs |= install_info.external_installs
+ for install_path in install_info.deferred_installs:
+ if all(['*' not in install_path,
+ not os.path.isfile(mozpath.join(context.config.topsrcdir,
+ install_path[2:])),
+ install_path not in install_info.external_installs]):
+ raise SandboxValidationError('Error processing test '
+ 'manifest %s: entry in support-files not present '
+ 'in the srcdir: %s' % (path, install_path), context)
+
+ obj.deferred_installs |= install_info.deferred_installs
+
+ for test in filtered:
+ obj.tests.append(test)
+
+ # Some test files are compiled and should not be copied into the
+ # test package. They function as identifiers rather than files.
+ if package_tests:
+ manifest_relpath = mozpath.relpath(test['path'],
+ mozpath.dirname(test['manifest']))
+ obj.installs[mozpath.normpath(test['path'])] = \
+ ((mozpath.join(out_dir, manifest_relpath)), True)
+
+ process_support_files(test)
+
+ for path, m_defaults in mpmanifest.manifest_defaults.items():
+ process_support_files(m_defaults)
+
+ # We also copy manifests into the output directory,
+ # including manifests from [include:foo] directives.
+ for mpath in mpmanifest.manifests():
+ mpath = mozpath.normpath(mpath)
+ out_path = mozpath.join(out_dir, mozpath.basename(mpath))
+ obj.installs[mpath] = (out_path, False)
+
+ # Some manifests reference files that are auto generated as
+ # part of the build or shouldn't be installed for some
+ # reason. Here, we prune those files from the install set.
+ # FUTURE we should be able to detect autogenerated files from
+ # other build metadata. Once we do that, we can get rid of this.
+ for f in defaults.get('generated-files', '').split():
+ # We re-raise otherwise the stack trace isn't informative.
+ try:
+ del obj.installs[mozpath.join(manifest_dir, f)]
+ except KeyError:
+ raise SandboxValidationError('Error processing test '
+ 'manifest %s: entry in generated-files not present '
+ 'elsewhere in manifest: %s' % (path, f), context)
+
+ yield obj
+ except (AssertionError, Exception):
+ raise SandboxValidationError('Error processing test '
+ 'manifest file %s: %s' % (path,
+ '\n'.join(traceback.format_exception(*sys.exc_info()))),
+ context)
+
+ def _process_reftest_manifest(self, context, flavor, manifest_path, manifest):
+ manifest_full_path = mozpath.normpath(mozpath.join(
+ context.srcdir, manifest_path))
+ manifest_reldir = mozpath.dirname(mozpath.relpath(manifest_full_path,
+ context.config.topsrcdir))
+
+ # reftest manifests don't come from manifest parser. But they are
+ # similar enough that we can use the same emitted objects. Note
+ # that we don't perform any installs for reftests.
+ obj = TestManifest(context, manifest_full_path, manifest,
+ 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': '',
+ 'tail': '',
+ 'support-files': '',
+ 'subsuite': '',
+ })
+
+ yield obj
+
+ def _process_web_platform_tests_manifest(self, context, paths, manifest):
+ manifest_path, tests_root = paths
+ manifest_full_path = mozpath.normpath(mozpath.join(
+ context.srcdir, manifest_path))
+ manifest_reldir = mozpath.dirname(mozpath.relpath(manifest_full_path,
+ context.config.topsrcdir))
+ tests_root = mozpath.normpath(mozpath.join(context.srcdir, tests_root))
+
+ # Create a equivalent TestManifest object
+ obj = TestManifest(context, manifest_full_path, manifest,
+ flavor="web-platform-tests",
+ relpath=mozpath.join(manifest_reldir,
+ mozpath.basename(manifest_path)),
+ install_prefix="web-platform/")
+
+ for path, tests in manifest:
+ path = mozpath.join(tests_root, path)
+ for test in tests:
+ if test.item_type not in ["testharness", "reftest"]:
+ continue
+
+ obj.tests.append({
+ 'path': path,
+ 'here': mozpath.dirname(path),
+ 'manifest': manifest_path,
+ 'name': test.id,
+ 'head': '',
+ 'tail': '',
+ 'support-files': '',
+ 'subsuite': '',
+ })
+
+ yield obj
+
+
+class TreeMetadataEmitter(BaseEmitter):
"""Converts the executed mozbuild files into data structures.
This is a bridge between reader.py and data.py. It takes what was read by
reader.BuildReader and converts it into the classes defined in the data
- module.
+ module. It will emit all metadata, including TestManifest objects.
"""
def __init__(self, config):
- self.populate_logger()
-
- self.config = config
+ BaseEmitter.__init__(self, config)
mozinfo.find_and_update_from_json(config.topobjdir)
# Python 2.6 doesn't allow unicode keys to be used for keyword
# arguments. This gross hack works around the problem until we
# rid ourselves of 2.6.
self.info = {}
for k, v in mozinfo.info.items():
@@ -151,67 +400,32 @@ class TreeMetadataEmitter(LoggingMixin):
# from what we run a subconfigure in. We'll eliminate some directories
# as we traverse them with moz.build (e.g. js/src).
subconfigures = os.path.join(self.config.topobjdir, 'subconfigures')
paths = []
if os.path.exists(subconfigures):
paths = open(subconfigures).read().splitlines()
self._external_paths = set(mozpath.normsep(d) for d in paths)
- self._emitter_time = 0.0
- self._object_count = 0
- self._test_files_converter = SupportFilesConverter()
-
- def summary(self):
- return ExecutionSummary(
- 'Processed into {object_count:d} build config descriptors in '
- '{execution_time:.2f}s',
- execution_time=self._emitter_time,
- object_count=self._object_count)
+ # The RecursiveMakeBackend still consumes TestManifest objects in
+ # order to generate root test manifests and install manifests, so we
+ # still need to emit them here.
+ self._test_emitter = TestManifestEmitter(self.config)
def emit(self, output):
- """Convert the BuildReader output into data structures.
-
- The return value from BuildReader.read_topsrcdir() (a generator) is
- typically fed into this function.
- """
- contexts = {}
-
- def emit_objs(objs):
- for o in objs:
- self._object_count += 1
- yield o
-
- for out in output:
- # Nothing in sub-contexts is currently of interest to us. Filter
- # them all out.
- if isinstance(out, SubContext):
- continue
-
- if isinstance(out, Context):
- # Keep all contexts around, we will need them later.
- contexts[out.objdir] = out
-
- start = time.time()
- # We need to expand the generator for the timings to work.
- objs = list(self.emit_from_context(out))
- self._emitter_time += time.time() - start
-
- for o in emit_objs(objs): yield o
-
- else:
- raise Exception('Unhandled output type: %s' % type(out))
+ for o in BaseEmitter.emit(self, output):
+ yield o
# Don't emit Linkable objects when COMPILE_ENVIRONMENT is not set
if self.config.substs.get('COMPILE_ENVIRONMENT'):
start = time.time()
- objs = list(self._emit_libs_derived(contexts))
+ objs = list(self._emit_libs_derived(self._contexts))
self._emitter_time += time.time() - start
- for o in emit_objs(objs): yield o
+ for o in self._emit_objs(objs): yield o
def _emit_libs_derived(self, contexts):
# First do FINAL_LIBRARY linkage.
for lib in (l for libs in self._libs.values() for l in libs):
if not isinstance(lib, (StaticLibrary, RustLibrary)) or not lib.link_into:
continue
if lib.link_into not in self._libs:
raise SandboxValidationError(
@@ -1122,18 +1336,17 @@ class TreeMetadataEmitter(LoggingMixin):
'https://developer.mozilla.org/en/XPCOM/XPCOM_changes_in_Gecko_2.0 .',
context);
for c in components:
if c.endswith('.manifest'):
yield ChromeManifestEntry(context, 'chrome.manifest',
Manifest('components',
mozpath.basename(c)))
-
- for obj in self._process_test_manifests(context):
+ for obj in self._test_emitter.emit_from_context(context):
yield obj
for obj in self._process_jar_manifests(context):
yield obj
for name, jar in context.get('JAVA_JAR_TARGETS', {}).items():
yield ContextWrapped(context, jar)
@@ -1244,199 +1457,16 @@ class TreeMetadataEmitter(LoggingMixin):
% (f, p.full_path), context)
inputs.append(p)
else:
script = None
method = None
yield GeneratedFile(context, script, method, outputs, inputs,
flags.flags)
- def _process_test_manifests(self, context):
- for prefix, info in TEST_MANIFESTS.items():
- for path, manifest in context.get('%s_MANIFESTS' % prefix, []):
- for obj in self._process_test_manifest(context, info, path, manifest):
- yield obj
-
- for flavor in REFTEST_FLAVORS:
- for path, manifest in context.get('%s_MANIFESTS' % flavor.upper(), []):
- for obj in self._process_reftest_manifest(context, flavor, path, manifest):
- yield obj
-
- for flavor in WEB_PLATFORM_TESTS_FLAVORS:
- for path, manifest in context.get("%s_MANIFESTS" % flavor.upper().replace('-', '_'), []):
- for obj in self._process_web_platform_tests_manifest(context, path, manifest):
- yield obj
-
- def _process_test_manifest(self, context, info, manifest_path, mpmanifest):
- flavor, install_root, install_subdir, package_tests = info
-
- path = mozpath.normpath(mozpath.join(context.srcdir, manifest_path))
- manifest_dir = mozpath.dirname(path)
- manifest_reldir = mozpath.dirname(mozpath.relpath(path,
- context.config.topsrcdir))
- manifest_sources = [mozpath.relpath(pth, context.config.topsrcdir)
- for pth in mpmanifest.source_files]
- install_prefix = mozpath.join(install_root, install_subdir)
-
- try:
- if not mpmanifest.tests:
- raise SandboxValidationError('Empty test manifest: %s'
- % path, context)
-
- defaults = mpmanifest.manifest_defaults[os.path.normpath(path)]
- obj = TestManifest(context, path, mpmanifest, flavor=flavor,
- install_prefix=install_prefix,
- relpath=mozpath.join(manifest_reldir, mozpath.basename(path)),
- sources=manifest_sources,
- dupe_manifest='dupe-manifest' in defaults)
-
- filtered = mpmanifest.tests
-
- # Jetpack add-on tests are expected to be generated during the
- # build process so they won't exist here.
- if flavor != 'jetpack-addon':
- missing = [t['name'] for t in filtered if not os.path.exists(t['path'])]
- if missing:
- raise SandboxValidationError('Test manifest (%s) lists '
- 'test that does not exist: %s' % (
- path, ', '.join(missing)), context)
-
- out_dir = mozpath.join(install_prefix, manifest_reldir)
- if 'install-to-subdir' in defaults:
- # This is terrible, but what are you going to do?
- out_dir = mozpath.join(out_dir, defaults['install-to-subdir'])
- obj.manifest_obj_relpath = mozpath.join(manifest_reldir,
- defaults['install-to-subdir'],
- mozpath.basename(path))
-
- def process_support_files(test):
- install_info = self._test_files_converter.convert_support_files(
- test, install_root, manifest_dir, out_dir)
-
- obj.pattern_installs.extend(install_info.pattern_installs)
- for source, dest in install_info.installs:
- obj.installs[source] = (dest, False)
- obj.external_installs |= install_info.external_installs
- for install_path in install_info.deferred_installs:
- if all(['*' not in install_path,
- not os.path.isfile(mozpath.join(context.config.topsrcdir,
- install_path[2:])),
- install_path not in install_info.external_installs]):
- raise SandboxValidationError('Error processing test '
- 'manifest %s: entry in support-files not present '
- 'in the srcdir: %s' % (path, install_path), context)
-
- obj.deferred_installs |= install_info.deferred_installs
-
- for test in filtered:
- obj.tests.append(test)
-
- # Some test files are compiled and should not be copied into the
- # test package. They function as identifiers rather than files.
- if package_tests:
- manifest_relpath = mozpath.relpath(test['path'],
- mozpath.dirname(test['manifest']))
- obj.installs[mozpath.normpath(test['path'])] = \
- ((mozpath.join(out_dir, manifest_relpath)), True)
-
- process_support_files(test)
-
- for path, m_defaults in mpmanifest.manifest_defaults.items():
- process_support_files(m_defaults)
-
- # We also copy manifests into the output directory,
- # including manifests from [include:foo] directives.
- for mpath in mpmanifest.manifests():
- mpath = mozpath.normpath(mpath)
- out_path = mozpath.join(out_dir, mozpath.basename(mpath))
- obj.installs[mpath] = (out_path, False)
-
- # Some manifests reference files that are auto generated as
- # part of the build or shouldn't be installed for some
- # reason. Here, we prune those files from the install set.
- # FUTURE we should be able to detect autogenerated files from
- # other build metadata. Once we do that, we can get rid of this.
- for f in defaults.get('generated-files', '').split():
- # We re-raise otherwise the stack trace isn't informative.
- try:
- del obj.installs[mozpath.join(manifest_dir, f)]
- except KeyError:
- raise SandboxValidationError('Error processing test '
- 'manifest %s: entry in generated-files not present '
- 'elsewhere in manifest: %s' % (path, f), context)
-
- yield obj
- except (AssertionError, Exception):
- raise SandboxValidationError('Error processing test '
- 'manifest file %s: %s' % (path,
- '\n'.join(traceback.format_exception(*sys.exc_info()))),
- context)
-
- def _process_reftest_manifest(self, context, flavor, manifest_path, manifest):
- manifest_full_path = mozpath.normpath(mozpath.join(
- context.srcdir, manifest_path))
- manifest_reldir = mozpath.dirname(mozpath.relpath(manifest_full_path,
- context.config.topsrcdir))
-
- # reftest manifests don't come from manifest parser. But they are
- # similar enough that we can use the same emitted objects. Note
- # that we don't perform any installs for reftests.
- obj = TestManifest(context, manifest_full_path, manifest,
- 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': '',
- 'tail': '',
- 'support-files': '',
- 'subsuite': '',
- })
-
- yield obj
-
- def _process_web_platform_tests_manifest(self, context, paths, manifest):
- manifest_path, tests_root = paths
- manifest_full_path = mozpath.normpath(mozpath.join(
- context.srcdir, manifest_path))
- manifest_reldir = mozpath.dirname(mozpath.relpath(manifest_full_path,
- context.config.topsrcdir))
- tests_root = mozpath.normpath(mozpath.join(context.srcdir, tests_root))
-
- # Create a equivalent TestManifest object
- obj = TestManifest(context, manifest_full_path, manifest,
- flavor="web-platform-tests",
- relpath=mozpath.join(manifest_reldir,
- mozpath.basename(manifest_path)),
- install_prefix="web-platform/")
-
-
- for path, tests in manifest:
- path = mozpath.join(tests_root, path)
- for test in tests:
- if test.item_type not in ["testharness", "reftest"]:
- continue
-
- obj.tests.append({
- 'path': path,
- 'here': mozpath.dirname(path),
- 'manifest': manifest_path,
- 'name': test.id,
- 'head': '',
- 'tail': '',
- 'support-files': '',
- 'subsuite': '',
- })
-
- yield obj
def _process_jar_manifests(self, context):
jar_manifests = context.get('JAR_MANIFESTS', [])
if len(jar_manifests) > 1:
raise SandboxValidationError('While JAR_MANIFESTS is a list, '
'it is currently limited to one value.', context)
for path in jar_manifests:
--- a/python/mozbuild/mozbuild/test/frontend/test_emitter.py
+++ b/python/mozbuild/mozbuild/test/frontend/test_emitter.py
@@ -41,17 +41,17 @@ from mozbuild.frontend.data import (
SimpleProgram,
Sources,
StaticLibrary,
TestHarnessFiles,
TestManifest,
UnifiedSources,
VariablePassthru,
)
-from mozbuild.frontend.emitter import TreeMetadataEmitter
+from mozbuild.frontend.emitter import TreeMetadataEmitter, TestManifestEmitter
from mozbuild.frontend.reader import (
BuildReader,
BuildReaderError,
SandboxValidationError,
)
from mozpack.chrome import manifest
from mozbuild.test.common import MockConfig
@@ -80,18 +80,19 @@ class TestEmitterBasic(unittest.TestCase
COMPILE_ENVIRONMENT='1',
)
if extra_substs:
substs.update(extra_substs)
config = MockConfig(mozpath.join(data_path, name), extra_substs=substs)
return BuildReader(config)
- def read_topsrcdir(self, reader, filter_common=True):
- emitter = TreeMetadataEmitter(reader.config)
+ def read_topsrcdir(self, reader, filter_common=True, cls=None):
+ cls = cls or TreeMetadataEmitter
+ emitter = cls(reader.config)
objs = list(emitter.emit(reader.read_topsrcdir()))
self.assertGreater(len(objs), 0)
filtered = []
for obj in objs:
if filter_common and isinstance(obj, DirectoryTraversal):
continue
@@ -413,48 +414,48 @@ class TestEmitterBasic(unittest.TestCase
self.assertEqual(objs[1].program, 'test_program1.prog')
self.assertEqual(objs[2].program, 'test_program2.prog')
def test_test_manifest_missing_manifest(self):
"""A missing manifest file should result in an error."""
reader = self.reader('test-manifest-missing-manifest')
with self.assertRaisesRegexp(BuildReaderError, 'IOError: Missing files'):
- self.read_topsrcdir(reader)
+ self.read_topsrcdir(reader, cls=TestManifestEmitter)
def test_empty_test_manifest_rejected(self):
"""A test manifest without any entries is rejected."""
reader = self.reader('test-manifest-empty')
with self.assertRaisesRegexp(SandboxValidationError, 'Empty test manifest'):
- self.read_topsrcdir(reader)
+ self.read_topsrcdir(reader, cls=TestManifestEmitter)
def test_test_manifest_just_support_files(self):
"""A test manifest with no tests but support-files is not supported."""
reader = self.reader('test-manifest-just-support')
with self.assertRaisesRegexp(SandboxValidationError, 'Empty test manifest'):
- self.read_topsrcdir(reader)
+ self.read_topsrcdir(reader, cls=TestManifestEmitter)
def test_test_manifest_dupe_support_files(self):
"""A test manifest with dupe support-files in a single test is not
supported.
"""
reader = self.reader('test-manifest-dupes')
with self.assertRaisesRegexp(SandboxValidationError, 'bar.js appears multiple times '
'in a test manifest under a support-files field, please omit the duplicate entry.'):
- self.read_topsrcdir(reader)
+ self.read_topsrcdir(reader, cls=TestManifestEmitter)
def test_test_manifest_absolute_support_files(self):
"""Support files starting with '/' are placed relative to the install root"""
reader = self.reader('test-manifest-absolute-support')
- objs = self.read_topsrcdir(reader)
+ objs = self.read_topsrcdir(reader, cls=TestManifestEmitter)
self.assertEqual(len(objs), 1)
o = objs[0]
self.assertEqual(len(o.installs), 3)
expected = [
mozpath.normpath(mozpath.join(o.install_prefix, "../.well-known/foo.txt")),
mozpath.join(o.install_prefix, "absolute-support.ini"),
mozpath.join(o.install_prefix, "test_file.js"),
]
@@ -462,17 +463,17 @@ class TestEmitterBasic(unittest.TestCase
self.assertEqual(paths, expected)
@unittest.skip('Bug 1304316 - Items in the second set but not the first')
def test_test_manifest_shared_support_files(self):
"""Support files starting with '!' are given separate treatment, so their
installation can be resolved when running tests.
"""
reader = self.reader('test-manifest-shared-support')
- supported, child = self.read_topsrcdir(reader)
+ supported, child = self.read_topsrcdir(reader, cls=TestManifestEmitter)
expected_deferred_installs = {
'!/child/test_sub.js',
'!/child/another-file.sjs',
'!/child/data/**',
}
self.assertEqual(len(supported.installs), 3)
@@ -482,23 +483,23 @@ class TestEmitterBasic(unittest.TestCase
self.assertEqual(len(child.pattern_installs), 1)
def test_test_manifest_deffered_install_missing(self):
"""A non-existent shared support file reference produces an error."""
reader = self.reader('test-manifest-shared-missing')
with self.assertRaisesRegexp(SandboxValidationError,
'entry in support-files not present in the srcdir'):
- self.read_topsrcdir(reader)
+ self.read_topsrcdir(reader, cls=TestManifestEmitter)
def test_test_manifest_install_to_subdir(self):
""" """
reader = self.reader('test-manifest-install-subdir')
- objs = self.read_topsrcdir(reader)
+ objs = self.read_topsrcdir(reader, cls=TestManifestEmitter)
self.assertEqual(len(objs), 1)
o = objs[0]
self.assertEqual(len(o.installs), 3)
self.assertEqual(o.manifest_relpath, "subdir.ini")
self.assertEqual(o.manifest_obj_relpath, "subdir/subdir.ini")
expected = [
mozpath.normpath(mozpath.join(o.install_prefix, "subdir/subdir.ini")),
mozpath.normpath(mozpath.join(o.install_prefix, "subdir/support.txt")),
@@ -506,17 +507,17 @@ class TestEmitterBasic(unittest.TestCase
]
paths = sorted([v[0] for v in o.installs.values()])
self.assertEqual(paths, expected)
def test_test_manifest_install_includes(self):
"""Ensure that any [include:foo.ini] are copied to the objdir."""
reader = self.reader('test-manifest-install-includes')
- objs = self.read_topsrcdir(reader)
+ objs = self.read_topsrcdir(reader, cls=TestManifestEmitter)
self.assertEqual(len(objs), 1)
o = objs[0]
self.assertEqual(len(o.installs), 3)
self.assertEqual(o.manifest_relpath, "mochitest.ini")
self.assertEqual(o.manifest_obj_relpath, "subdir/mochitest.ini")
expected = [
mozpath.normpath(mozpath.join(o.install_prefix, "subdir/common.ini")),
mozpath.normpath(mozpath.join(o.install_prefix, "subdir/mochitest.ini")),
@@ -524,34 +525,34 @@ class TestEmitterBasic(unittest.TestCase
]
paths = sorted([v[0] for v in o.installs.values()])
self.assertEqual(paths, expected)
def test_test_manifest_includes(self):
"""Ensure that manifest objects from the emitter list a correct manifest.
"""
reader = self.reader('test-manifest-emitted-includes')
- [obj] = self.read_topsrcdir(reader)
+ [obj] = self.read_topsrcdir(reader, cls=TestManifestEmitter)
# Expected manifest leafs for our tests.
expected_manifests = {
'reftest1.html': 'reftest.list',
'reftest1-ref.html': 'reftest.list',
'reftest2.html': 'included-reftest.list',
'reftest2-ref.html': 'included-reftest.list',
}
for t in obj.tests:
self.assertTrue(t['manifest'].endswith(expected_manifests[t['name']]))
def test_test_manifest_keys_extracted(self):
"""Ensure all metadata from test manifests is extracted."""
reader = self.reader('test-manifest-keys-extracted')
- objs = [o for o in self.read_topsrcdir(reader)
+ objs = [o for o in self.read_topsrcdir(reader, cls=TestManifestEmitter)
if isinstance(o, TestManifest)]
self.assertEqual(len(objs), 9)
metadata = {
'a11y.ini': {
'flavor': 'a11y',
'installs': {
@@ -644,23 +645,23 @@ class TestEmitterBasic(unittest.TestCase
if 'pattern-installs' in m:
self.assertEqual(len(o.pattern_installs), m['pattern-installs'])
def test_test_manifest_unmatched_generated(self):
reader = self.reader('test-manifest-unmatched-generated')
with self.assertRaisesRegexp(SandboxValidationError,
'entry in generated-files not present elsewhere'):
- self.read_topsrcdir(reader),
+ self.read_topsrcdir(reader, cls=TestManifestEmitter),
def test_test_manifest_parent_support_files_dir(self):
"""support-files referencing a file in a parent directory works."""
reader = self.reader('test-manifest-parent-support-files-dir')
- objs = [o for o in self.read_topsrcdir(reader)
+ objs = [o for o in self.read_topsrcdir(reader, cls=TestManifestEmitter)
if isinstance(o, TestManifest)]
self.assertEqual(len(objs), 1)
o = objs[0]
expected = mozpath.join(o.srcdir, 'support-file.txt')
self.assertIn(expected, o.installs)
@@ -668,25 +669,25 @@ class TestEmitterBasic(unittest.TestCase
('testing/mochitest/tests/child/support-file.txt', False))
def test_test_manifest_missing_test_error(self):
"""Missing test files should result in error."""
reader = self.reader('test-manifest-missing-test-file')
with self.assertRaisesRegexp(SandboxValidationError,
'lists test that does not exist: test_missing.html'):
- self.read_topsrcdir(reader)
+ self.read_topsrcdir(reader, cls=TestManifestEmitter)
def test_test_manifest_missing_test_error_unfiltered(self):
"""Missing test files should result in error, even when the test list is not filtered."""
reader = self.reader('test-manifest-missing-test-file-unfiltered')
with self.assertRaisesRegexp(SandboxValidationError,
'lists test that does not exist: missing.js'):
- self.read_topsrcdir(reader)
+ self.read_topsrcdir(reader, cls=TestManifestEmitter)
def test_ipdl_sources(self):
reader = self.reader('ipdl_sources')
objs = self.read_topsrcdir(reader)
ipdls = []
for o in objs:
if isinstance(o, IPDLFile):