fune/taskcluster/taskgraph/loader/test.py
Ricky Stewart 02a7b4ebdf Bug 1654103: Standardize on Black for Python code in mozilla-central.
Allow-list all Python code in tree for use with the black linter, and re-format all code in-tree accordingly.

To produce this patch I did all of the following:

1. Make changes to tools/lint/black.yml to remove include: stanza and update list of source extensions.

2. Run ./mach lint --linter black --fix

3. Make some ad-hoc manual updates to python/mozbuild/mozbuild/test/configure/test_configure.py -- it has some hard-coded line numbers that the reformat breaks.

4. Make some ad-hoc manual updates to `testing/marionette/client/setup.py`, `testing/marionette/harness/setup.py`, and `testing/firefox-ui/harness/setup.py`, which have hard-coded regexes that break after the reformat.

5. Add a set of exclusions to black.yml. These will be deleted in a follow-up bug (1672023).

# ignore-this-changeset

Differential Revision: https://phabricator.services.mozilla.com/D94045
2020-10-26 18:34:53 +00:00

149 lines
5.7 KiB
Python

# This Source Code Form is subject to the terms of the Mozilla Public
# 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, print_function, unicode_literals
import copy
import logging
import six
from .transform import loader as transform_loader
from ..util.yaml import load_yaml
logger = logging.getLogger(__name__)
def loader(kind, path, config, params, loaded_tasks):
"""
Generate tasks implementing Gecko tests.
"""
builds_by_platform = get_builds_by_platform(
dep_kind="build", loaded_tasks=loaded_tasks
)
signed_builds_by_platform = get_builds_by_platform(
dep_kind="build-signing", loaded_tasks=loaded_tasks
)
# get the test platforms for those build tasks
test_platforms_cfg = load_yaml(path, "test-platforms.yml")
test_platforms = get_test_platforms(
test_platforms_cfg, builds_by_platform, signed_builds_by_platform
)
# expand the test sets for each of those platforms
test_sets_cfg = load_yaml(path, "test-sets.yml")
test_platforms = expand_tests(test_sets_cfg, test_platforms)
# load the test descriptions
tests = transform_loader(kind, path, config, params, loaded_tasks)
test_descriptions = {t.pop("name"): t for t in tests}
# generate all tests for all test platforms
for test_platform_name, test_platform in six.iteritems(test_platforms):
for test_name in test_platform["test-names"]:
test = copy.deepcopy(test_descriptions[test_name])
test["build-platform"] = test_platform["build-platform"]
test["test-platform"] = test_platform_name
test["build-label"] = test_platform["build-label"]
if test_platform.get("build-signing-label", None):
test["build-signing-label"] = test_platform["build-signing-label"]
test["build-attributes"] = test_platform["build-attributes"]
test["test-name"] = test_name
if test_platform.get("shippable"):
test.setdefault("attributes", {})["shippable"] = True
test["attributes"]["shipping_product"] = test_platform[
"shipping_product"
]
logger.debug(
"Generating tasks for test {} on platform {}".format(
test_name, test["test-platform"]
)
)
yield test
def get_builds_by_platform(dep_kind, loaded_tasks):
"""Find the build tasks on which tests will depend, keyed by
platform/type. Returns a dictionary mapping build platform to task."""
builds_by_platform = {}
for task in loaded_tasks:
if task.kind != dep_kind:
continue
build_platform = task.attributes.get("build_platform")
build_type = task.attributes.get("build_type")
if not build_platform or not build_type:
continue
platform = "{}/{}".format(build_platform, build_type)
if platform in builds_by_platform:
raise Exception("multiple build jobs for " + platform)
builds_by_platform[platform] = task
return builds_by_platform
def get_test_platforms(
test_platforms_cfg, builds_by_platform, signed_builds_by_platform={}
):
"""Get the test platforms for which test tasks should be generated,
based on the available build platforms. Returns a dictionary mapping
test platform to {test-set, build-platform, build-label}."""
test_platforms = {}
for test_platform, cfg in six.iteritems(test_platforms_cfg):
build_platform = cfg["build-platform"]
if build_platform not in builds_by_platform:
logger.warning(
"No build task with platform {}; ignoring test platform {}".format(
build_platform, test_platform
)
)
continue
test_platforms[test_platform] = {
"build-platform": build_platform,
"build-label": builds_by_platform[build_platform].label,
"build-attributes": builds_by_platform[build_platform].attributes,
}
if builds_by_platform[build_platform].attributes.get("shippable"):
test_platforms[test_platform]["shippable"] = builds_by_platform[
build_platform
].attributes["shippable"]
test_platforms[test_platform]["shipping_product"] = builds_by_platform[
build_platform
].attributes["shipping_product"]
test_platforms[test_platform].update(cfg)
if build_platform in signed_builds_by_platform:
# Context: Signed builds are only used by Windows
test_platforms[test_platform][
"build-signing-label"
] = signed_builds_by_platform[build_platform].label
return test_platforms
def expand_tests(test_sets_cfg, test_platforms):
"""Expand the test sets in `test_platforms` out to sets of test names.
Returns a dictionary like `get_test_platforms`, with an additional
`test-names` key for each test platform, containing a set of test
names."""
rv = {}
for test_platform, cfg in six.iteritems(test_platforms):
test_sets = cfg["test-sets"]
if not set(test_sets) <= set(test_sets_cfg):
raise Exception(
"Test sets {} for test platform {} are not defined".format(
", ".join(test_sets), test_platform
)
)
test_names = set()
for test_set in test_sets:
test_names.update(test_sets_cfg[test_set])
rv[test_platform] = cfg.copy()
rv[test_platform]["test-names"] = test_names
return rv