diff --git a/taskcluster/taskgraph/templates/talos-profile.yml b/taskcluster/taskgraph/templates/talos-profile.yml new file mode 100644 index 000000000000..9b6c73d058d9 --- /dev/null +++ b/taskcluster/taskgraph/templates/talos-profile.yml @@ -0,0 +1,36 @@ +--- +$if: input && task["extra"] +then: + $if: task.extra["suite"] + then: + $if: task.extra.suite["name"] == "talos" + then: + task: + # We can't use mergeDeep as that will append the command below + # instead of overwriting the original command. + $merge: + - $eval: task + - payload: + $merge: + - $eval: task.payload + - command: + $if: typeof(task.payload.command[0]) == 'array' + then: + # Command is an array of arrays. Assumes the command we want + # to append --geckoProfile to is the first one. Also assumes + # that we can't have a space delimited string here (which is + # the case for now at least). + - $flatten: + - $eval: task.payload.command[0] + - ["--geckoProfile"] + else: + $if: len(task.payload.command) == 1 + then: + # Command is an array with a single space delimited string. + # This only happens on Windows. + - "${task.payload.command[0]} --geckoProfile" + else: + # Command is an array of strings. + $flatten: + - $eval: task.payload.command + - ["--geckoProfile"] diff --git a/taskcluster/taskgraph/test/test_morph.py b/taskcluster/taskgraph/test/test_morph.py index bdc46eeb44f4..e74b1a0bf139 100644 --- a/taskcluster/taskgraph/test/test_morph.py +++ b/taskcluster/taskgraph/test/test_morph.py @@ -113,6 +113,7 @@ TASKS = [ 'attributes': {}, 'task': { 'extra': { + 'suite': {'name': 'talos'}, 'treeherder': { 'group': 'tc', 'symbol': 't' @@ -132,15 +133,13 @@ TASKS = [ @pytest.fixture -def taskgraph(make_taskgraph): - return make_taskgraph({ - t['label']: Task(**t) for t in TASKS[:] - }) +def get_morphed(make_taskgraph): + def inner(try_task_config, tasks=None): + tasks = tasks or TASKS + taskgraph = make_taskgraph({ + t['label']: Task(**t) for t in tasks[:] + }) - -@pytest.fixture -def get_morphed(taskgraph): - def inner(try_task_config): fn = morph.apply_jsone_templates(try_task_config) return fn(*taskgraph)[0] return inner @@ -216,5 +215,34 @@ def test_template_rebuild(get_morphed): assert t.attributes['task_duplicates'] == 4 +@pytest.mark.parametrize('command', ( + ['foo --bar'], + ['foo', '--bar'], + [['foo']], + [['foo', '--bar']], +)) +def test_template_talos_profile(get_morphed, command): + tasks = TASKS[:] + for t in tasks: + t['task']['payload']['command'] = command + + morphed = get_morphed({ + 'templates': { + 'talos-profile': True, + } + }, tasks) + + for t in morphed.tasks.values(): + command = t.task['payload']['command'] + if isinstance(command[0], list): + command = command[0] + command = ' '.join(command) + + if t.label == 'a': + assert not command.endswith('--geckoProfile') + elif t.label == 'b': + assert command.endswith('--geckoProfile') + + if __name__ == '__main__': main() diff --git a/tools/tryselect/selectors/fuzzy.py b/tools/tryselect/selectors/fuzzy.py index ac0e5ecf155c..941f5ef34f4f 100644 --- a/tools/tryselect/selectors/fuzzy.py +++ b/tools/tryselect/selectors/fuzzy.py @@ -91,7 +91,7 @@ class FuzzyParser(BaseTryParser): }], ] common_groups = ['push', 'task', 'preset'] - templates = ['artifact', 'path', 'env', 'rebuild', 'chemspill-prio'] + templates = ['artifact', 'path', 'env', 'rebuild', 'chemspill-prio', 'talos-profile'] def run(cmd, cwd=None): diff --git a/tools/tryselect/templates.py b/tools/tryselect/templates.py index 9aaf075c87da..e09220048a98 100644 --- a/tools/tryselect/templates.py +++ b/tools/tryselect/templates.py @@ -12,7 +12,7 @@ from __future__ import absolute_import, print_function, unicode_literals import os import sys from abc import ABCMeta, abstractmethod -from argparse import Action +from argparse import Action, SUPPRESS import mozpack.path as mozpath from mozbuild.base import BuildEnvironmentNotFoundException, MozbuildObject @@ -144,10 +144,26 @@ class ChemspillPrio(Template): } +class TalosProfile(Template): + + def add_arguments(self, parser): + parser.add_argument('--talos-profile', dest='profile', action='store_true', default=False, + help='Create and upload a gecko profile during talos tasks.') + # This is added for consistency with the 'syntax' selector + parser.add_argument('--geckoProfile', dest='profile', action='store_true', default=False, + help=SUPPRESS) + + def context(self, profile, **kwargs): + if not profile: + return + return {'talos-profile': profile} + + all_templates = { 'artifact': Artifact, 'path': Path, 'env': Environment, 'rebuild': Rebuild, 'chemspill-prio': ChemspillPrio, + 'talos-profile': TalosProfile, } diff --git a/tools/tryselect/test/test_templates.py b/tools/tryselect/test/test_templates.py index 71ef15091ef1..af98eb24049c 100644 --- a/tools/tryselect/test/test_templates.py +++ b/tools/tryselect/test/test_templates.py @@ -19,6 +19,10 @@ TEMPLATE_TESTS = { (['--no-artifact'], None), (['--artifact'], {'artifact': {'enabled': '1'}}), ], + 'chemspill-prio': [ + ([], None), + (['--chemspill-prio'], {'chemspill-prio': {}}), + ], 'env': [ ([], None), (['--env', 'foo=bar', '--env', 'num=10'], {'env': {'foo': 'bar', 'num': '10'}}), @@ -36,6 +40,11 @@ TEMPLATE_TESTS = { (['--rebuild', '1'], SystemExit), (['--rebuild', '21'], SystemExit), ], + 'talos-profile': [ + ([], None), + (['--talos-profile'], {'talos-profile': True}), + (['--geckoProfile'], {'talos-profile': True}), + ], }