diff --git a/.cron.yml b/.cron.yml index 6e10ad76bdd2..c8e606f8fc63 100644 --- a/.cron.yml +++ b/.cron.yml @@ -408,6 +408,16 @@ jobs: include-push-tasks: true when: [] + - name: perftest-applink-profiling + job: + type: decision-task + treeherder-symbol: perftest-applink-p + target-tasks-method: perftest-applink-profiling + run-on-projects: + - mozilla-central + when: + - {hour: 6, minute: 00} + - name: retrigger-perftests-autoland job: type: decision-task diff --git a/taskcluster/gecko_taskgraph/actions/gecko_profile.py b/taskcluster/gecko_taskgraph/actions/gecko_profile.py index b86fa4198918..ed261eae5bc5 100644 --- a/taskcluster/gecko_taskgraph/actions/gecko_profile.py +++ b/taskcluster/gecko_taskgraph/actions/gecko_profile.py @@ -222,6 +222,10 @@ def geckoprofile_action(parameters, graph_config, input, task_group_id, task_id) cmd, profiling_command_flags ) + # A single profile is enough, don't inherit the retrigger count + # of the task being profiled. + task.attributes["task_duplicates"] = 1 + task.task["extra"]["treeherder"]["symbol"] += "-p" task.task["extra"]["treeherder"]["groupName"] += " (profiling)" return task diff --git a/taskcluster/gecko_taskgraph/target_tasks.py b/taskcluster/gecko_taskgraph/target_tasks.py index d9cb26346648..567c09353e95 100644 --- a/taskcluster/gecko_taskgraph/target_tasks.py +++ b/taskcluster/gecko_taskgraph/target_tasks.py @@ -1800,6 +1800,19 @@ def target_tasks_perftest_autoland(full_task_graph, parameters, graph_config): yield name +APPLINK_PROFILING_LABELS = { + "perftest-android-hw-a55-aarch64-shippable-startup-fenix-newssite-applink-startup", +} + + +@register_target_task("perftest-applink-profiling") +def target_tasks_perftest_applink_profiling(full_task_graph, parameters, graph_config): + """ + Select the applink startup tasks and run them with profiling + """ + return [name for name in full_task_graph.tasks if name in APPLINK_PROFILING_LABELS] + + @register_target_task("retrigger-perftests-autoland") def retrigger_perftests_autoland_commits(full_task_graph, parameters, graph_config): """ diff --git a/taskcluster/gecko_taskgraph/test/python.toml b/taskcluster/gecko_taskgraph/test/python.toml index a110423a07c2..e426a518fecc 100644 --- a/taskcluster/gecko_taskgraph/test/python.toml +++ b/taskcluster/gecko_taskgraph/test/python.toml @@ -27,6 +27,8 @@ subsuite = "taskgraph" ["test_transforms_job_common.py"] +["test_transforms_perftest.py"] + ["test_transforms_task.py"] ["test_transforms_test.py"] diff --git a/taskcluster/gecko_taskgraph/test/test_target_tasks.py b/taskcluster/gecko_taskgraph/test/test_target_tasks.py index 0ca2e7c0cc0f..ef087eb454ca 100644 --- a/taskcluster/gecko_taskgraph/test/test_target_tasks.py +++ b/taskcluster/gecko_taskgraph/test/test_target_tasks.py @@ -770,5 +770,23 @@ def test_general_perf_testing_selects_safari_video_playback_latency(): assert _raptor_label(vpl_safari, _MACOS) in selected +def test_perftest_applink_profiling_selects_only_the_applink_tasks(): + """Only the applink startup tasks are selected, the perftest transforms + then run them with profiling enabled.""" + labels = target_tasks.APPLINK_PROFILING_LABELS | { + "perftest-android-hw-a55-aarch64-shippable-startup-fenix-homeview-startup", + "test-linux1804-64/opt-mochitest-1", + } + tasks = { + label: Task(kind="perftest", label=label, attributes={}, task={}) + for label in labels + } + graph = TaskGraph(tasks, Graph(nodes=set(tasks), edges=set())) + + selected = set(get_method("perftest-applink-profiling")(graph, {}, {})) + + assert selected == target_tasks.APPLINK_PROFILING_LABELS + + if __name__ == "__main__": main() diff --git a/taskcluster/gecko_taskgraph/test/test_transforms_perftest.py b/taskcluster/gecko_taskgraph/test/test_transforms_perftest.py new file mode 100644 index 000000000000..a131350d9bb9 --- /dev/null +++ b/taskcluster/gecko_taskgraph/test/test_transforms_perftest.py @@ -0,0 +1,57 @@ +# 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/. + +import pytest +from mozunit import main + +from gecko_taskgraph.transforms.perftest import setup_gecko_profile_from_try_config + + +def applink_job(): + return { + "name": "android-hw-a55-aarch64-shippable-startup-fenix-newssite-applink-startup", + "run": {"command": "./mach perftest applink"}, + "treeherder": {"symbol": "perftest-fenix(newssite-applink)"}, + } + + +@pytest.mark.parametrize( + "params,expected", + ( + pytest.param( + {"try_task_config": {}, "target_tasks_method": "perftest-fenix-startup"}, + False, + id="no-profiling", + ), + pytest.param( + {"try_task_config": {"gecko-profile": True}, "target_tasks_method": "try"}, + True, + id="try-gecko-profile", + ), + pytest.param( + { + "try_task_config": {}, + "target_tasks_method": "perftest-applink-profiling", + }, + True, + id="profiling-target-tasks-method", + ), + ), +) +def test_setup_gecko_profile_from_try_config(run_transform, params, expected): + tasks = list( + run_transform( + setup_gecko_profile_from_try_config, [applink_job()], params=params + ) + ) + + assert len(tasks) == 1 + command = tasks[0]["run"]["command"] + assert ("--simpleperf" in command) == expected + assert ("--geckoprofiler" in command) == expected + assert (tasks[0]["treeherder"]["symbol"].endswith("-p)")) == expected + + +if __name__ == "__main__": + main() diff --git a/taskcluster/gecko_taskgraph/transforms/perftest.py b/taskcluster/gecko_taskgraph/transforms/perftest.py index 452052e368f4..9d6a91d3d095 100644 --- a/taskcluster/gecko_taskgraph/transforms/perftest.py +++ b/taskcluster/gecko_taskgraph/transforms/perftest.py @@ -18,6 +18,9 @@ from gecko_taskgraph.transforms.test import linux_perf_platform_restrictions transforms = TransformSequence() +# Target tasks methods that only select tasks meant to be profiled. +PROFILING_TARGET_TASKS_METHODS = {"perftest-applink-profiling"} + class PerftestDescriptionSchema(Schema, forbid_unknown_fields=False, kw_only=True): # The test names and the symbols to use for them: [test-symbol, test-path] @@ -273,12 +276,16 @@ def pass_perftest_options(config, jobs): @transforms.add def setup_gecko_profile_from_try_config(config, jobs): - """Apply gecko-profile settings when --gecko-profile is used with ./mach try fuzzy. + """Apply gecko-profile settings when --gecko-profile is used with ./mach try fuzzy, + or when a cron selects tasks through a profiling target tasks method. This mimics the logic from the gecko_profile action but applies it during task generation instead of as a post-hoc action. """ - gecko_profile = config.params.get("try_task_config", {}).get("gecko-profile", False) + gecko_profile = ( + config.params.get("try_task_config", {}).get("gecko-profile", False) + or config.params.get("target_tasks_method") in PROFILING_TARGET_TASKS_METHODS + ) simpleperf_compatible_tests = ["-homeview-", "-applink-", "-restore-"] for job in jobs: