зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 5 changesets (bug 1634554) for lint failure CLOSED TREE
Backed out changeset e8db70067dbf (bug 1634554) Backed out changeset ae24c9902708 (bug 1634554) Backed out changeset 177cc940d57f (bug 1634554) Backed out changeset 3240acbd85b6 (bug 1634554) Backed out changeset 71aa576ada8b (bug 1634554)
This commit is contained in:
Родитель
ec7c82ed3a
Коммит
30c59d36db
|
@ -175,11 +175,6 @@ def mozharness_test_on_docker(config, job, taskdesc):
|
|||
'task-reference': six.ensure_text(json.dumps(extra_config, sort_keys=True))
|
||||
}
|
||||
|
||||
# Bug 1634554 - pass in decision task URL for manifest/test mapping for WPT.
|
||||
if 'web-platform-tests' in test['suite']:
|
||||
env['TESTS_BY_MANIFEST_URL'] = {
|
||||
'artifact-reference': '<decision/public/tests-by-manifest.json.gz>'}
|
||||
|
||||
command = [
|
||||
'{workdir}/bin/test-linux.sh'.format(**run),
|
||||
]
|
||||
|
@ -318,11 +313,6 @@ def mozharness_test_on_generic_worker(config, job, taskdesc):
|
|||
'task-reference': six.ensure_text(json.dumps(extra_config, sort_keys=True))
|
||||
}
|
||||
|
||||
# Bug 1634554 - pass in decision task URL for manifest/test mapping for WPT.
|
||||
if 'web-platform-tests' in test['suite']:
|
||||
env['TESTS_BY_MANIFEST_URL'] = {
|
||||
'artifact-reference': '<decision/public/tests-by-manifest.json.gz>'}
|
||||
|
||||
if is_windows:
|
||||
mh_command = [
|
||||
'c:\\mozilla-build\\python\\python.exe',
|
||||
|
@ -473,11 +463,6 @@ def mozharness_test_on_script_engine_autophone(config, job, taskdesc):
|
|||
'task-reference': six.ensure_text(json.dumps(extra_config, sort_keys=True))
|
||||
}
|
||||
|
||||
# Bug 1634554 - pass in decision task URL for manifest/test mapping for WPT.
|
||||
if 'web-platform-tests' in test['suite']:
|
||||
env['TESTS_BY_MANIFEST_URL'] = {
|
||||
'artifact-reference': '<decision/public/tests-by-manifest.json.gz>'}
|
||||
|
||||
script = 'test-linux.sh'
|
||||
worker['context'] = config.params.file_url(
|
||||
'taskcluster/scripts/tester/{}'.format(script),
|
||||
|
|
|
@ -119,9 +119,9 @@ def chunk_manifests(suite, platform, chunks, manifests):
|
|||
that run in that chunk.
|
||||
"""
|
||||
manifests = set(manifests)
|
||||
runtimes = {k: v for k, v in get_runtimes(platform, suite).items() if k in manifests}
|
||||
|
||||
if "web-platform-tests" not in suite:
|
||||
runtimes = {k: v for k, v in get_runtimes(platform, suite).items() if k in manifests}
|
||||
return [
|
||||
c[1] for c in chunk_by_runtime(
|
||||
None,
|
||||
|
@ -130,19 +130,52 @@ def chunk_manifests(suite, platform, chunks, manifests):
|
|||
).get_chunked_manifests(manifests)
|
||||
]
|
||||
|
||||
paths = {k: v for k, v in wpt_group_translation.items() if k in manifests}
|
||||
|
||||
# Python2 does not support native dictionary sorting, so use an OrderedDict
|
||||
# instead, appending in order of highest to lowest runtime.
|
||||
runtimes = OrderedDict(sorted(runtimes.items(), key=lambda x: x[1], reverse=True))
|
||||
|
||||
# Keep track of test paths for each chunk, and the runtime information.
|
||||
chunked_manifests = [[] for _ in range(chunks)]
|
||||
chunked_manifests = [[[], 0] for _ in range(chunks)]
|
||||
|
||||
# Spread out the test manifests evenly across all chunks.
|
||||
for index, key in enumerate(sorted(manifests)):
|
||||
chunked_manifests[index % chunks].append(key)
|
||||
# Begin chunking the test paths in order from highest running time to lowest.
|
||||
# The keys of runtimes dictionary should match the keys of the test paths
|
||||
# dictionary.
|
||||
for key, rt in runtimes.items():
|
||||
# Sort the chunks from fastest to slowest, based on runtime info
|
||||
# at x[1], then the number of test paths.
|
||||
chunked_manifests.sort(key=lambda x: (x[1], len(x[0])))
|
||||
|
||||
# One last sort by the number of manifests. Chunk size should be more or less
|
||||
# equal in size.
|
||||
chunked_manifests.sort(key=lambda x: len(x))
|
||||
# Look up if there are any test paths under the key in the paths dict.
|
||||
test_paths = paths[key]
|
||||
|
||||
if test_paths:
|
||||
# Add the full set of paths that live under the key and increase the
|
||||
# total runtime counter by the value reported in runtimes.
|
||||
chunked_manifests[0][0].extend(test_paths)
|
||||
# chunked_manifests[0][0].append(key)
|
||||
chunked_manifests[0][1] += rt
|
||||
# Remove the key and test_paths since it has been scheduled.
|
||||
paths.pop(key)
|
||||
# Same goes for the value in runtimes dict.
|
||||
runtimes.pop(key)
|
||||
|
||||
# Sort again prior to the next step.
|
||||
chunked_manifests.sort(key=lambda x: (x[1], len(x[0])))
|
||||
|
||||
# Spread out the remaining test paths that were not scheduled in the previous
|
||||
# step. Such paths did not have runtime information associated, likely due to
|
||||
# implementation status.
|
||||
for index, key in enumerate(paths.keys()):
|
||||
# Append both the key and value in case the value is empty.
|
||||
chunked_manifests[index % chunks][0].append(key)
|
||||
|
||||
# One last sort by the runtime, then number of test paths.
|
||||
chunked_manifests.sort(key=lambda x: (x[1], len(x[0])))
|
||||
|
||||
# Return just the chunked test paths.
|
||||
return chunked_manifests
|
||||
return [c[0] for c in chunked_manifests]
|
||||
|
||||
|
||||
@six.add_metaclass(ABCMeta)
|
||||
|
@ -177,6 +210,29 @@ class BaseManifestLoader(object):
|
|||
class DefaultLoader(BaseManifestLoader):
|
||||
"""Load manifests using metadata from the TestResolver."""
|
||||
|
||||
@classmethod
|
||||
def get_wpt_group(cls, test):
|
||||
"""Get the group for a web-platform-test that matches those created by the
|
||||
WPT harness.
|
||||
|
||||
Args:
|
||||
test (dict): The test object to compute the group for.
|
||||
|
||||
Returns:
|
||||
str: Label representing the group name.
|
||||
"""
|
||||
depth = 3
|
||||
|
||||
path = os.path.dirname(test['name'])
|
||||
# Remove path elements beyond depth of 3, because WPT harness uses
|
||||
# --run-by-dir=3 by convention in Mozilla CI.
|
||||
# Note, this means /_mozilla tests retain an effective depth of 2 due to
|
||||
# the extra prefix element.
|
||||
while path.count('/') >= depth + 1:
|
||||
path = os.path.dirname(path)
|
||||
|
||||
return path
|
||||
|
||||
@memoize
|
||||
def get_tests(self, suite):
|
||||
suite_definition = TEST_SUITES[suite]
|
||||
|
@ -194,7 +250,10 @@ class DefaultLoader(BaseManifestLoader):
|
|||
if "web-platform-tests" in suite:
|
||||
manifests = set()
|
||||
for t in tests:
|
||||
group = self.get_wpt_group(t)
|
||||
wpt_group_translation[t['manifest']].add(group)
|
||||
manifests.add(t['manifest'])
|
||||
|
||||
return {"active": list(manifests), "skipped": []}
|
||||
|
||||
manifests = set(chunk_by_runtime.get_manifest(t) for t in tests)
|
||||
|
|
|
@ -693,26 +693,20 @@ class TestResolver(MozbuildObject):
|
|||
return True
|
||||
return False
|
||||
|
||||
def get_wpt_group(self, test, depth=3):
|
||||
"""Given a test object set the group (aka manifest) that it belongs to.
|
||||
|
||||
If a custom value for `depth` is provided, it will override the default
|
||||
value of 3 path components.
|
||||
def get_wpt_group(self, test):
|
||||
"""Given a test object, set the group (aka manifest) that it belongs to.
|
||||
|
||||
Args:
|
||||
test (dict): Test object for the particular suite and subsuite.
|
||||
depth (int, optional): Custom number of path elements.
|
||||
|
||||
Returns:
|
||||
str: The group the given test belongs to.
|
||||
"""
|
||||
# This takes into account that for mozilla-specific WPT tests, the path
|
||||
# contains an extra '/_mozilla' prefix that must be accounted for.
|
||||
depth = depth + 1 if test['name'].startswith('/_mozilla') else depth
|
||||
|
||||
group = os.path.dirname(test['name'])
|
||||
while group.count('/') > depth:
|
||||
group = os.path.dirname(group)
|
||||
# Extract the first path component (top level directory) as the key.
|
||||
# This value should match the path in manifest-runtimes JSON data.
|
||||
# Mozilla WPT paths have one extra URL component in the front.
|
||||
components = 3 if test['name'].startswith('/_mozilla') else 2
|
||||
group = '/'.join(test['name'].split('/')[:components])
|
||||
return group
|
||||
|
||||
def add_wpt_manifest_data(self):
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
# You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
# ***** END LICENSE BLOCK *****
|
||||
import copy
|
||||
import gzip
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
@ -124,7 +123,6 @@ class WebPlatformTest(TestingMixin, MercurialScript, CodeCoverageMixin, AndroidM
|
|||
'setup-avds',
|
||||
'start-emulator',
|
||||
'download-and-extract',
|
||||
'download-and-process-manifest',
|
||||
'create-virtualenv',
|
||||
'pull',
|
||||
'verify-device',
|
||||
|
@ -241,6 +239,7 @@ class WebPlatformTest(TestingMixin, MercurialScript, CodeCoverageMixin, AndroidM
|
|||
"--symbols-path=%s" % self.symbols_path,
|
||||
"--stackwalk-binary=%s" % self.query_minidump_stackwalk(),
|
||||
"--stackfix-dir=%s" % os.path.join(dirs["abs_test_install_dir"], "bin"),
|
||||
"--run-by-dir=%i" % (3 if not mozinfo.info["asan"] else 0),
|
||||
"--no-pause-after-test",
|
||||
"--instrument-to-file=%s" % os.path.join(dirs["abs_blob_upload_dir"],
|
||||
"wpt_instruments.txt")]
|
||||
|
@ -284,15 +283,9 @@ class WebPlatformTest(TestingMixin, MercurialScript, CodeCoverageMixin, AndroidM
|
|||
if not (self.verify_enabled or self.per_test_coverage):
|
||||
mozharness_test_paths = json.loads(os.environ.get('MOZHARNESS_TEST_PATHS', '""'))
|
||||
if mozharness_test_paths:
|
||||
path = os.path.join(
|
||||
dirs["abs_fetches_dir"], 'wpt_tests_by_group.json')
|
||||
|
||||
if not os.path.exists(path):
|
||||
self.critical('Unable to locate web-platform-test groups file.')
|
||||
|
||||
cmd.append("--test-groups={}".format(path))
|
||||
|
||||
for key in mozharness_test_paths.keys():
|
||||
keys = (['web-platform-tests-%s' % test_type for test_type in test_types] +
|
||||
['web-platform-tests'])
|
||||
for key in keys:
|
||||
paths = mozharness_test_paths.get(key, [])
|
||||
for path in paths:
|
||||
if not path.startswith("/"):
|
||||
|
@ -303,9 +296,6 @@ class WebPlatformTest(TestingMixin, MercurialScript, CodeCoverageMixin, AndroidM
|
|||
path = os.path.join(dirs["abs_wpttest_dir"], path)
|
||||
test_paths.add(path)
|
||||
else:
|
||||
# As per WPT harness, the --run-by-dir flag is incompatible with
|
||||
# the --test-groups flag.
|
||||
cmd.append("--run-by-dir=%i" % (3 if not mozinfo.info["asan"] else 0))
|
||||
for opt in ["total_chunks", "this_chunk"]:
|
||||
val = c.get(opt)
|
||||
if val:
|
||||
|
@ -362,45 +352,6 @@ class WebPlatformTest(TestingMixin, MercurialScript, CodeCoverageMixin, AndroidM
|
|||
self.fatal("Could not create blobber upload directory")
|
||||
# Exit
|
||||
|
||||
def download_and_process_manifest(self):
|
||||
"""Downloads the tests-by-manifest JSON mapping generated by the decision task.
|
||||
|
||||
web-platform-tests are chunked in the decision task as of Bug 1608837
|
||||
and this means tests are resolved by the TestResolver as part of this process.
|
||||
|
||||
The manifest file contains tests keyed by the groups generated in
|
||||
TestResolver.get_wpt_group().
|
||||
|
||||
Upon successful call, a JSON file containing only the web-platform test
|
||||
groups are saved in the fetch directory.
|
||||
|
||||
Bug:
|
||||
1634554
|
||||
"""
|
||||
dirs = self.query_abs_dirs()
|
||||
url = os.environ.get('TESTS_BY_MANIFEST_URL', '')
|
||||
if not url:
|
||||
self.fatal('TESTS_BY_MANIFEST_URL not defined.')
|
||||
|
||||
artifact_name = url.split('/')[-1]
|
||||
|
||||
# Save file to the MOZ_FETCHES dir.
|
||||
self.download_file(url, file_name=artifact_name,
|
||||
parent_dir=dirs["abs_fetches_dir"])
|
||||
|
||||
with gzip.open(os.path.join(dirs["abs_fetches_dir"], artifact_name), 'r') as f:
|
||||
tests_by_manifest = json.loads(f.read())
|
||||
|
||||
# We need to filter out non-web-platform-tests without knowing what the
|
||||
# groups are. Fortunately, all web-platform test 'manifests' begin with a
|
||||
# forward slash.
|
||||
test_groups = {key: tests_by_manifest[key] for key in tests_by_manifest.keys()
|
||||
if key.startswith("/")}
|
||||
|
||||
outfile = os.path.join(dirs["abs_fetches_dir"], "wpt_tests_by_group.json")
|
||||
with open(outfile, 'w+') as f:
|
||||
json.dump(test_groups, f, indent=2, sort_keys=True)
|
||||
|
||||
def install(self):
|
||||
if self.is_android:
|
||||
self.install_apk(self.installer_path)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
import hashlib
|
||||
import json
|
||||
import os
|
||||
from six.moves.urllib.parse import urlsplit
|
||||
from abc import ABCMeta, abstractmethod
|
||||
|
@ -27,45 +26,6 @@ def do_delayed_imports():
|
|||
from manifest.download import download_from_github
|
||||
|
||||
|
||||
class TestGroupsFile(object):
|
||||
"""
|
||||
Mapping object representing {group name: [test ids]}
|
||||
"""
|
||||
|
||||
def __init__(self, logger, path):
|
||||
try:
|
||||
with open(path) as f:
|
||||
self._data = json.load(f)
|
||||
except ValueError:
|
||||
logger.critical("test groups file %s not valid json" % path)
|
||||
raise
|
||||
|
||||
self.group_by_test = {}
|
||||
for group, test_ids in iteritems(self._data):
|
||||
for test_id in test_ids:
|
||||
self.group_by_test[test_id] = group
|
||||
|
||||
def __contains__(self, key):
|
||||
return key in self._data
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self._data[key]
|
||||
|
||||
|
||||
def update_include_for_groups(test_groups, include):
|
||||
if include is None:
|
||||
# We're just running everything
|
||||
return
|
||||
|
||||
new_include = []
|
||||
for item in include:
|
||||
if item in test_groups:
|
||||
new_include.extend(test_groups[item])
|
||||
else:
|
||||
new_include.append(item)
|
||||
return new_include
|
||||
|
||||
|
||||
class TestChunker(object):
|
||||
def __init__(self, total_chunks, chunk_number, **kwargs):
|
||||
self.total_chunks = total_chunks
|
||||
|
@ -332,23 +292,6 @@ class TestLoader(object):
|
|||
return groups
|
||||
|
||||
|
||||
def get_test_src(**kwargs):
|
||||
test_source_kwargs = {"processes": kwargs["processes"],
|
||||
"logger": kwargs["logger"]}
|
||||
chunker_kwargs = {}
|
||||
if kwargs["run_by_dir"] is not False:
|
||||
# A value of None indicates infinite depth
|
||||
test_source_cls = PathGroupedSource
|
||||
test_source_kwargs["depth"] = kwargs["run_by_dir"]
|
||||
chunker_kwargs["depth"] = kwargs["run_by_dir"]
|
||||
elif kwargs["test_groups"]:
|
||||
test_source_cls = GroupFileTestSource
|
||||
test_source_kwargs["test_groups"] = kwargs["test_groups"]
|
||||
else:
|
||||
test_source_cls = SingleTestSource
|
||||
return test_source_cls, test_source_kwargs, chunker_kwargs
|
||||
|
||||
|
||||
class TestSource(object):
|
||||
__metaclass__ = ABCMeta
|
||||
|
||||
|
@ -454,39 +397,3 @@ class PathGroupedSource(GroupedSource):
|
|||
@classmethod
|
||||
def group_metadata(cls, state):
|
||||
return {"scope": "/%s" % "/".join(state["prev_path"])}
|
||||
|
||||
|
||||
class GroupFileTestSource(TestSource):
|
||||
@classmethod
|
||||
def make_queue(cls, tests, **kwargs):
|
||||
tests_by_group = cls.tests_by_group(tests, **kwargs)
|
||||
|
||||
test_queue = Queue()
|
||||
|
||||
for group_name, tests in iteritems(tests_by_group):
|
||||
group_metadata = {"scope": group_name}
|
||||
group = deque()
|
||||
|
||||
for test in tests:
|
||||
group.append(test)
|
||||
test.update_metadata(group_metadata)
|
||||
|
||||
test_queue.put((group, group_metadata))
|
||||
|
||||
return test_queue
|
||||
|
||||
@classmethod
|
||||
def tests_by_group(cls, tests, **kwargs):
|
||||
logger = kwargs["logger"]
|
||||
test_groups = kwargs["test_groups"]
|
||||
|
||||
tests_by_group = defaultdict(list)
|
||||
for test in tests:
|
||||
try:
|
||||
group = test_groups.group_by_test[test.id]
|
||||
except KeyError:
|
||||
logger.error("%s is missing from test groups file" % test.id)
|
||||
raise
|
||||
tests_by_group[group].append(test)
|
||||
|
||||
return tests_by_group
|
||||
|
|
|
@ -700,9 +700,8 @@ class TestRunnerManager(threading.Thread):
|
|||
test, test_group, group_metadata = self.get_next_test()
|
||||
if test is None:
|
||||
return RunnerManagerState.stop()
|
||||
if test_group is not self.state.test_group:
|
||||
if test_group != self.state.test_group:
|
||||
# We are starting a new group of tests, so force a restart
|
||||
self.logger.info("Restarting browser for new test group")
|
||||
restart = True
|
||||
else:
|
||||
test_group = self.state.test_group
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
from __future__ import absolute_import, print_function
|
||||
import argparse
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from collections import OrderedDict
|
||||
|
@ -136,8 +135,6 @@ scheme host and port.""")
|
|||
help="URL prefix to exclude")
|
||||
test_selection_group.add_argument("--include-manifest", type=abs_path,
|
||||
help="Path to manifest listing tests to include")
|
||||
test_selection_group.add_argument("--test-groups", dest="test_groups_file", type=abs_path,
|
||||
help="Path to json file containing a mapping {group_name: [test_ids]}")
|
||||
test_selection_group.add_argument("--skip-timeout", action="store_true",
|
||||
help="Skip tests that are expected to time out")
|
||||
test_selection_group.add_argument("--skip-implementation-status",
|
||||
|
@ -507,14 +504,6 @@ def check_args(kwargs):
|
|||
else:
|
||||
kwargs["chunk_type"] = "none"
|
||||
|
||||
if kwargs["test_groups_file"] is not None:
|
||||
if kwargs["run_by_dir"] is not False:
|
||||
print("Can't pass --test-groups and --run-by-dir")
|
||||
sys.exit(1)
|
||||
if not os.path.exists(kwargs["test_groups_file"]):
|
||||
print("--test-groups file %s not found" % kwargs["test_groups_file"])
|
||||
sys.exit(1)
|
||||
|
||||
if kwargs["processes"] is None:
|
||||
kwargs["processes"] = 1
|
||||
|
||||
|
|
|
@ -45,8 +45,7 @@ def setup_logging(*args, **kwargs):
|
|||
return logger
|
||||
|
||||
|
||||
def get_loader(test_paths, product, debug=None, run_info_extras=None, chunker_kwargs=None,
|
||||
test_groups=None, **kwargs):
|
||||
def get_loader(test_paths, product, debug=None, run_info_extras=None, chunker_kwargs=None, **kwargs):
|
||||
if run_info_extras is None:
|
||||
run_info_extras = {}
|
||||
|
||||
|
@ -63,12 +62,8 @@ def get_loader(test_paths, product, debug=None, run_info_extras=None, chunker_kw
|
|||
|
||||
manifest_filters = []
|
||||
|
||||
include = kwargs["include"]
|
||||
if test_groups:
|
||||
include = testloader.update_include_for_groups(test_groups, include)
|
||||
|
||||
if include or kwargs["exclude"] or kwargs["include_manifest"] or kwargs["default_exclude"]:
|
||||
manifest_filters.append(testloader.TestFilter(include=include,
|
||||
if kwargs["include"] or kwargs["exclude"] or kwargs["include_manifest"] or kwargs["default_exclude"]:
|
||||
manifest_filters.append(testloader.TestFilter(include=kwargs["include"],
|
||||
exclude=kwargs["exclude"],
|
||||
manifest_path=kwargs["include_manifest"],
|
||||
test_manifests=test_manifests,
|
||||
|
@ -171,21 +166,23 @@ def run_tests(config, test_paths, product, **kwargs):
|
|||
|
||||
recording.set(["startup", "load_tests"])
|
||||
|
||||
test_groups = (testloader.TestGroupsFile(logger, kwargs["test_groups_file"])
|
||||
if kwargs["test_groups_file"] else None)
|
||||
test_source_kwargs = {"processes": kwargs["processes"]}
|
||||
chunker_kwargs = {}
|
||||
if kwargs["run_by_dir"] is False:
|
||||
test_source_cls = testloader.SingleTestSource
|
||||
else:
|
||||
# A value of None indicates infinite depth
|
||||
test_source_cls = testloader.PathGroupedSource
|
||||
test_source_kwargs["depth"] = kwargs["run_by_dir"]
|
||||
chunker_kwargs["depth"] = kwargs["run_by_dir"]
|
||||
|
||||
(test_source_cls,
|
||||
test_source_kwargs,
|
||||
chunker_kwargs) = testloader.get_test_src(logger=logger,
|
||||
test_groups=test_groups,
|
||||
**kwargs)
|
||||
run_info, test_loader = get_loader(test_paths,
|
||||
product.name,
|
||||
run_info_extras=product.run_info_extras(**kwargs),
|
||||
chunker_kwargs=chunker_kwargs,
|
||||
test_groups=test_groups,
|
||||
**kwargs)
|
||||
|
||||
|
||||
logger.info("Using %i client processes" % kwargs["processes"])
|
||||
|
||||
skipped_tests = 0
|
||||
|
@ -206,9 +203,7 @@ def run_tests(config, test_paths, product, **kwargs):
|
|||
"host_cert_path": kwargs["host_cert_path"],
|
||||
"ca_cert_path": kwargs["ca_cert_path"]}}
|
||||
|
||||
testharness_timeout_multipler = product.get_timeout_multiplier("testharness",
|
||||
run_info,
|
||||
**kwargs)
|
||||
testharness_timeout_multipler = product.get_timeout_multiplier("testharness", run_info, **kwargs)
|
||||
|
||||
recording.set(["startup", "start_environment"])
|
||||
with env.TestEnvironment(test_paths,
|
||||
|
@ -246,13 +241,7 @@ def run_tests(config, test_paths, product, **kwargs):
|
|||
for test_type in test_loader.test_types:
|
||||
tests.extend(test_loader.tests[test_type])
|
||||
|
||||
try:
|
||||
test_groups = test_source_cls.tests_by_group(tests, **test_source_kwargs)
|
||||
except Exception:
|
||||
logger.critical("Loading tests failed")
|
||||
return False
|
||||
|
||||
logger.suite_start(test_groups,
|
||||
logger.suite_start(test_source_cls.tests_by_group(tests, **test_source_kwargs),
|
||||
name='web-platform-test',
|
||||
run_info=run_info,
|
||||
extra={"run_by_dir": kwargs["run_by_dir"]})
|
||||
|
|
Загрузка…
Ссылка в новой задаче