forked from mirrors/gecko-dev
No bug: [taskgraph] Make verify_test_packaging handle --target-kind gracefully; r=Callek
If we are generating only a part of the graph, to given kind, don't fail if a build is packaging tests and there is no corresponding test task, as the tests may not have been generated. Differential Revision: https://phabricator.services.mozilla.com/D82097
This commit is contained in:
parent
51f106a3a3
commit
e92bbf5dd8
7 changed files with 57 additions and 30 deletions
|
|
@ -235,3 +235,10 @@ Code Review
|
||||||
``phabricator_diff``
|
``phabricator_diff``
|
||||||
The code review process needs to know the Phabricator Differential diff that
|
The code review process needs to know the Phabricator Differential diff that
|
||||||
started the analysis. This parameter must start with `PHID-DIFF-`
|
started the analysis. This parameter must start with `PHID-DIFF-`
|
||||||
|
|
||||||
|
Local configuration
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
``target-kind``
|
||||||
|
Generate only the given kind and its kind-dependencies. This is used for local inspection of the graph
|
||||||
|
and is not supported at run-time.
|
||||||
|
|
|
||||||
|
|
@ -337,12 +337,15 @@ class MachCommands(MachCommandBase):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.setup_logging(quiet=options['quiet'], verbose=options['verbose'])
|
self.setup_logging(quiet=options['quiet'], verbose=options['verbose'])
|
||||||
parameters = taskgraph.parameters.parameters_loader(options['parameters'])
|
parameters = taskgraph.parameters.parameters_loader(
|
||||||
|
options['parameters'],
|
||||||
|
overrides={'target-kind': options.get('target_kind')},
|
||||||
|
strict=False,
|
||||||
|
)
|
||||||
|
|
||||||
tgg = taskgraph.generator.TaskGraphGenerator(
|
tgg = taskgraph.generator.TaskGraphGenerator(
|
||||||
root_dir=options.get('root'),
|
root_dir=options.get('root'),
|
||||||
parameters=parameters,
|
parameters=parameters,
|
||||||
target_kind=options.get('target_kind'),
|
|
||||||
)
|
)
|
||||||
|
|
||||||
tg = getattr(tgg, graph_attr)
|
tg = getattr(tgg, graph_attr)
|
||||||
|
|
|
||||||
|
|
@ -114,7 +114,6 @@ class TaskGraphGenerator(object):
|
||||||
parameters,
|
parameters,
|
||||||
decision_task_id="DECISION-TASK",
|
decision_task_id="DECISION-TASK",
|
||||||
write_artifacts=False,
|
write_artifacts=False,
|
||||||
target_kind=None,
|
|
||||||
):
|
):
|
||||||
"""
|
"""
|
||||||
@param root_dir: root directory, with subdirectories for each kind
|
@param root_dir: root directory, with subdirectories for each kind
|
||||||
|
|
@ -126,7 +125,6 @@ class TaskGraphGenerator(object):
|
||||||
root_dir = 'taskcluster/ci'
|
root_dir = 'taskcluster/ci'
|
||||||
self.root_dir = ensure_text(root_dir)
|
self.root_dir = ensure_text(root_dir)
|
||||||
self._parameters = parameters
|
self._parameters = parameters
|
||||||
self._target_kind = target_kind
|
|
||||||
self._decision_task_id = decision_task_id
|
self._decision_task_id = decision_task_id
|
||||||
self._write_artifacts = write_artifacts
|
self._write_artifacts = write_artifacts
|
||||||
|
|
||||||
|
|
@ -262,11 +260,12 @@ class TaskGraphGenerator(object):
|
||||||
edges.add((kind.name, dep, 'kind-dependency'))
|
edges.add((kind.name, dep, 'kind-dependency'))
|
||||||
kind_graph = Graph(set(kinds), edges)
|
kind_graph = Graph(set(kinds), edges)
|
||||||
|
|
||||||
if self._target_kind:
|
if parameters.get('target-kind'):
|
||||||
|
target_kind = parameters['target-kind']
|
||||||
logger.info(
|
logger.info(
|
||||||
"Limiting kinds to {target_kind} and dependencies".format(
|
"Limiting kinds to {target_kind} and dependencies".format(
|
||||||
target_kind=self._target_kind))
|
target_kind=target_kind))
|
||||||
kind_graph = kind_graph.transitive_closure({self._target_kind, 'docker-image'})
|
kind_graph = kind_graph.transitive_closure({target_kind, 'docker-image'})
|
||||||
|
|
||||||
logger.info("Generating full task set")
|
logger.info("Generating full task set")
|
||||||
all_tasks = {}
|
all_tasks = {}
|
||||||
|
|
@ -419,7 +418,10 @@ def load_tasks_for_kind(parameters, kind, root_dir=None):
|
||||||
|
|
||||||
This function is designed to be called from outside of taskgraph.
|
This function is designed to be called from outside of taskgraph.
|
||||||
"""
|
"""
|
||||||
tgg = TaskGraphGenerator(root_dir=root_dir, parameters=parameters, target_kind=kind)
|
# make parameters read-write
|
||||||
|
parameters = dict(parameters)
|
||||||
|
parameters['target-kind'] = kind
|
||||||
|
tgg = TaskGraphGenerator(root_dir=root_dir, parameters=parameters)
|
||||||
return {
|
return {
|
||||||
task.task['metadata']['name']: task
|
task.task['metadata']['name']: task
|
||||||
for task in tgg.full_task_set
|
for task in tgg.full_task_set
|
||||||
|
|
|
||||||
|
|
@ -96,6 +96,8 @@ base_schema = Schema({
|
||||||
Required('release_product'): Any(None, text_type),
|
Required('release_product'): Any(None, text_type),
|
||||||
Required('required_signoffs'): [text_type],
|
Required('required_signoffs'): [text_type],
|
||||||
Required('signoff_urls'): dict,
|
Required('signoff_urls'): dict,
|
||||||
|
# target-kind is not included, since it should never be
|
||||||
|
# used at run-time
|
||||||
Required('target_tasks_method'): text_type,
|
Required('target_tasks_method'): text_type,
|
||||||
Required('tasks_for'): text_type,
|
Required('tasks_for'): text_type,
|
||||||
Required('test_manifest_loader'): text_type,
|
Required('test_manifest_loader'): text_type,
|
||||||
|
|
|
||||||
|
|
@ -45,9 +45,18 @@ class VerificationSequence(object):
|
||||||
continue
|
continue
|
||||||
scratch_pad = {}
|
scratch_pad = {}
|
||||||
graph.for_each_task(
|
graph.for_each_task(
|
||||||
verification.verify, scratch_pad=scratch_pad, graph_config=graph_config
|
verification.verify,
|
||||||
|
scratch_pad=scratch_pad,
|
||||||
|
graph_config=graph_config,
|
||||||
|
parameters=parameters,
|
||||||
|
)
|
||||||
|
verification.verify(
|
||||||
|
None,
|
||||||
|
graph,
|
||||||
|
scratch_pad=scratch_pad,
|
||||||
|
graph_config=graph_config,
|
||||||
|
parameters=parameters,
|
||||||
)
|
)
|
||||||
verification.verify(None, graph, scratch_pad=scratch_pad, graph_config=graph_config)
|
|
||||||
return graph_name, graph
|
return graph_name, graph
|
||||||
|
|
||||||
def add(self, graph_name, run_on_projects={"all"}):
|
def add(self, graph_name, run_on_projects={"all"}):
|
||||||
|
|
@ -128,7 +137,7 @@ def verify_docs(filename, identifiers, appearing_as):
|
||||||
|
|
||||||
|
|
||||||
@verifications.add('full_task_graph')
|
@verifications.add('full_task_graph')
|
||||||
def verify_task_graph_symbol(task, taskgraph, scratch_pad, graph_config):
|
def verify_task_graph_symbol(task, taskgraph, scratch_pad, graph_config, parameters):
|
||||||
"""
|
"""
|
||||||
This function verifies that tuple
|
This function verifies that tuple
|
||||||
(collection.keys(), machine.platform, groupSymbol, symbol) is unique
|
(collection.keys(), machine.platform, groupSymbol, symbol) is unique
|
||||||
|
|
@ -169,7 +178,7 @@ def verify_task_graph_symbol(task, taskgraph, scratch_pad, graph_config):
|
||||||
|
|
||||||
|
|
||||||
@verifications.add('full_task_graph')
|
@verifications.add('full_task_graph')
|
||||||
def verify_trust_domain_v2_routes(task, taskgraph, scratch_pad, graph_config):
|
def verify_trust_domain_v2_routes(task, taskgraph, scratch_pad, graph_config, parameters):
|
||||||
"""
|
"""
|
||||||
This function ensures that any two tasks have distinct ``index.{trust-domain}.v2`` routes.
|
This function ensures that any two tasks have distinct ``index.{trust-domain}.v2`` routes.
|
||||||
"""
|
"""
|
||||||
|
|
@ -191,7 +200,7 @@ def verify_trust_domain_v2_routes(task, taskgraph, scratch_pad, graph_config):
|
||||||
|
|
||||||
|
|
||||||
@verifications.add('full_task_graph')
|
@verifications.add('full_task_graph')
|
||||||
def verify_routes_notification_filters(task, taskgraph, scratch_pad, graph_config):
|
def verify_routes_notification_filters(task, taskgraph, scratch_pad, graph_config, parameters):
|
||||||
"""
|
"""
|
||||||
This function ensures that only understood filters for notifications are
|
This function ensures that only understood filters for notifications are
|
||||||
specified.
|
specified.
|
||||||
|
|
@ -217,7 +226,7 @@ def verify_routes_notification_filters(task, taskgraph, scratch_pad, graph_confi
|
||||||
|
|
||||||
|
|
||||||
@verifications.add('full_task_graph')
|
@verifications.add('full_task_graph')
|
||||||
def verify_dependency_tiers(task, taskgraph, scratch_pad, graph_config):
|
def verify_dependency_tiers(task, taskgraph, scratch_pad, graph_config, parameters):
|
||||||
tiers = scratch_pad
|
tiers = scratch_pad
|
||||||
if task is not None:
|
if task is not None:
|
||||||
tiers[task.label] = task.task.get('extra', {}) \
|
tiers[task.label] = task.task.get('extra', {}) \
|
||||||
|
|
@ -244,7 +253,7 @@ def verify_dependency_tiers(task, taskgraph, scratch_pad, graph_config):
|
||||||
|
|
||||||
|
|
||||||
@verifications.add('full_task_graph')
|
@verifications.add('full_task_graph')
|
||||||
def verify_required_signoffs(task, taskgraph, scratch_pad, graph_config):
|
def verify_required_signoffs(task, taskgraph, scratch_pad, graph_config, parameters):
|
||||||
"""
|
"""
|
||||||
Task with required signoffs can't be dependencies of tasks with less
|
Task with required signoffs can't be dependencies of tasks with less
|
||||||
required signoffs.
|
required signoffs.
|
||||||
|
|
@ -271,7 +280,7 @@ def verify_required_signoffs(task, taskgraph, scratch_pad, graph_config):
|
||||||
|
|
||||||
|
|
||||||
@verifications.add('full_task_graph')
|
@verifications.add('full_task_graph')
|
||||||
def verify_toolchain_alias(task, taskgraph, scratch_pad, graph_config):
|
def verify_toolchain_alias(task, taskgraph, scratch_pad, graph_config, parameters):
|
||||||
"""
|
"""
|
||||||
This function verifies that toolchain aliases are not reused.
|
This function verifies that toolchain aliases are not reused.
|
||||||
"""
|
"""
|
||||||
|
|
@ -294,7 +303,7 @@ def verify_toolchain_alias(task, taskgraph, scratch_pad, graph_config):
|
||||||
|
|
||||||
|
|
||||||
@verifications.add('optimized_task_graph')
|
@verifications.add('optimized_task_graph')
|
||||||
def verify_always_optimized(task, taskgraph, scratch_pad, graph_config):
|
def verify_always_optimized(task, taskgraph, scratch_pad, graph_config, parameters):
|
||||||
"""
|
"""
|
||||||
This function ensures that always-optimized tasks have been optimized.
|
This function ensures that always-optimized tasks have been optimized.
|
||||||
"""
|
"""
|
||||||
|
|
@ -305,7 +314,7 @@ def verify_always_optimized(task, taskgraph, scratch_pad, graph_config):
|
||||||
|
|
||||||
|
|
||||||
@verifications.add('full_task_graph', run_on_projects=RELEASE_PROJECTS)
|
@verifications.add('full_task_graph', run_on_projects=RELEASE_PROJECTS)
|
||||||
def verify_shippable_no_sccache(task, taskgraph, scratch_pad, graph_config):
|
def verify_shippable_no_sccache(task, taskgraph, scratch_pad, graph_config, parameters):
|
||||||
if task and task.attributes.get('shippable'):
|
if task and task.attributes.get('shippable'):
|
||||||
if task.task.get('payload', {}).get('env', {}).get('USE_SCCACHE'):
|
if task.task.get('payload', {}).get('env', {}).get('USE_SCCACHE'):
|
||||||
raise Exception(
|
raise Exception(
|
||||||
|
|
@ -313,8 +322,9 @@ def verify_shippable_no_sccache(task, taskgraph, scratch_pad, graph_config):
|
||||||
|
|
||||||
|
|
||||||
@verifications.add('full_task_graph')
|
@verifications.add('full_task_graph')
|
||||||
def verify_test_packaging(task, taskgraph, scratch_pad, graph_config):
|
def verify_test_packaging(task, taskgraph, scratch_pad, graph_config, parameters):
|
||||||
if task is None:
|
if task is None:
|
||||||
|
has_target_kind = parameters.get('target-kind') is None
|
||||||
exceptions = []
|
exceptions = []
|
||||||
for task in six.itervalues(taskgraph.tasks):
|
for task in six.itervalues(taskgraph.tasks):
|
||||||
if task.kind == 'build' and not task.attributes.get('skip-verify-test-packaging'):
|
if task.kind == 'build' and not task.attributes.get('skip-verify-test-packaging'):
|
||||||
|
|
@ -342,6 +352,9 @@ def verify_test_packaging(task, taskgraph, scratch_pad, graph_config):
|
||||||
# With the caveat that we expect shippable jobs to always
|
# With the caveat that we expect shippable jobs to always
|
||||||
# produce tests.
|
# produce tests.
|
||||||
if not build_has_tests and not shippable:
|
if not build_has_tests and not shippable:
|
||||||
|
# If we have not generated all task kinds, we can't verify that
|
||||||
|
# there are no dependent tests.
|
||||||
|
if has_target_kind:
|
||||||
exceptions.append(
|
exceptions.append(
|
||||||
'Build job {} has no tests, but specifies '
|
'Build job {} has no tests, but specifies '
|
||||||
'MOZ_AUTOMATION_PACKAGE_TESTS={} in the environment. '
|
'MOZ_AUTOMATION_PACKAGE_TESTS={} in the environment. '
|
||||||
|
|
@ -356,7 +369,7 @@ def verify_test_packaging(task, taskgraph, scratch_pad, graph_config):
|
||||||
|
|
||||||
|
|
||||||
@verifications.add('full_task_graph')
|
@verifications.add('full_task_graph')
|
||||||
def verify_run_known_projects(task, taskgraph, scratch_pad, graph_config):
|
def verify_run_known_projects(task, taskgraph, scratch_pad, graph_config, parameters):
|
||||||
""" Validates the inputs in run-on-projects.
|
""" Validates the inputs in run-on-projects.
|
||||||
|
|
||||||
We should never let 'try' (or 'try-comm-central') be in run-on-projects even though it
|
We should never let 'try' (or 'try-comm-central') be in run-on-projects even though it
|
||||||
|
|
@ -381,7 +394,7 @@ def verify_run_known_projects(task, taskgraph, scratch_pad, graph_config):
|
||||||
|
|
||||||
|
|
||||||
@verifications.add('full_task_graph')
|
@verifications.add('full_task_graph')
|
||||||
def verify_local_toolchains(task, taskgraph, scratch_pad, graph_config):
|
def verify_local_toolchains(task, taskgraph, scratch_pad, graph_config, parameters):
|
||||||
"""
|
"""
|
||||||
Toolchains that are used for local development need to be built on a
|
Toolchains that are used for local development need to be built on a
|
||||||
level-3 branch to installable via `mach bootstrap`. We ensure here that all
|
level-3 branch to installable via `mach bootstrap`. We ensure here that all
|
||||||
|
|
|
||||||
|
|
@ -35,9 +35,9 @@ def create_tgg(responses, datadir):
|
||||||
lm = LoggingManager()
|
lm = LoggingManager()
|
||||||
lm.add_terminal_logging()
|
lm.add_terminal_logging()
|
||||||
|
|
||||||
def inner(parameters=None, overrides=None, target_kind=None):
|
def inner(parameters=None, overrides=None):
|
||||||
params = parameters_loader(parameters, strict=False, overrides=overrides)
|
params = parameters_loader(parameters, strict=False, overrides=overrides)
|
||||||
tgg = TaskGraphGenerator(None, params, target_kind=target_kind)
|
tgg = TaskGraphGenerator(None, params)
|
||||||
|
|
||||||
# Mock out certain requests as they may depend on a revision that does
|
# Mock out certain requests as they may depend on a revision that does
|
||||||
# not exist on hg.mozilla.org.
|
# not exist on hg.mozilla.org.
|
||||||
|
|
|
||||||
|
|
@ -19,9 +19,9 @@ pytestmark = pytest.mark.slow
|
||||||
def tgg(create_tgg):
|
def tgg(create_tgg):
|
||||||
params = TRY_AUTO_PARAMETERS.copy()
|
params = TRY_AUTO_PARAMETERS.copy()
|
||||||
params.update(
|
params.update(
|
||||||
{"head_repository": "https://hg.mozilla.org/try", "project": "try"}
|
{"head_repository": "https://hg.mozilla.org/try", "project": "try", "target_kind": "test"}
|
||||||
)
|
)
|
||||||
tgg = create_tgg(overrides=params, target_kind="test")
|
tgg = create_tgg(overrides=params)
|
||||||
return tgg
|
return tgg
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue