Browse Source

Bug 1580778 - Migrate raptor tests to taskgraph (#5361)

master
Johan Lorenzo 2 years ago
committed by GitHub
parent
commit
4462899763
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 19
      automation/taskcluster/decision_task.py
  2. 170
      automation/taskcluster/lib/tasks.py
  3. 4
      automation/taskcluster/lib/variant.py
  4. 11
      taskcluster/ci/geckoview/kind.yml
  5. 207
      taskcluster/ci/raptor/kind.yml
  6. 96
      taskcluster/fenix_taskgraph/raptor.py
  7. 21
      taskcluster/fenix_taskgraph/target_tasks.py

19
automation/taskcluster/decision_task.py

@ -61,23 +61,8 @@ def raptor(builder, is_staging):
build_task = builder.craft_assemble_raptor_task(variant)
signing_task = builder.craft_raptor_signing_task(build_task['label'], variant, is_staging)
tasks = [build_task, signing_task]
for abi in ('armeabi-v7a', 'arm64-v8a'):
variant_apk = variant.get_apk(abi)
all_raptor_craft_functions = [
builder.craft_raptor_tp6m_cold_task(for_suite=i)
for i in range(1, 28)
] + [
builder.craft_raptor_youtube_playback_task,
]
for craft_function in all_raptor_craft_functions:
raptor_task = craft_function(
signing_task['label'], mozharness_task_id, variant_apk, gecko_revision, is_staging
)
tasks.append(raptor_task)
return tasks
# Raptor tests are generated in taskgraph
return [build_task, signing_task]
def release(builder, channel, engine, is_staging, version_name):

170
automation/taskcluster/lib/tasks.py

@ -123,6 +123,7 @@ class TaskBuilder(object):
'symbol': 'A',
'tier': 1,
},
attributes={'build-type': 'raptor'},
)
def craft_assemble_pr_task(self, variant):
@ -316,7 +317,7 @@ class TaskBuilder(object):
def _craft_build_ish_task(
self, name, description, command, dependencies=None, artifacts=None,
routes=None, treeherder=None, env_vars=None, scopes=None
routes=None, treeherder=None, env_vars=None, scopes=None, attributes=None
):
artifacts = {} if artifacts is None else artifacts
scopes = [] if scopes is None else scopes
@ -361,9 +362,10 @@ class TaskBuilder(object):
routes=routes,
scopes=scopes,
treeherder=treeherder,
attributes=attributes,
)
def _craft_signing_task(self, name, description, signing_type, assemble_task_label, apk_paths, routes, treeherder):
def _craft_signing_task(self, name, description, signing_type, assemble_task_label, apk_paths, routes, treeherder, attributes=None):
signing_format = "autograph_apk"
payload = {
'upstreamArtifacts': [{
@ -387,6 +389,7 @@ class TaskBuilder(object):
description=description,
payload=payload,
treeherder=treeherder,
attributes=attributes,
)
def _craft_default_task_definition(
@ -401,11 +404,13 @@ class TaskBuilder(object):
scopes=None,
treeherder=None,
notify=None,
attributes=None
):
dependencies = {} if dependencies is None else dependencies
scopes = [] if scopes is None else scopes
routes = [] if routes is None else routes
treeherder = {} if treeherder is None else treeherder
attributes = {} if attributes is None else attributes
created = datetime.datetime.now()
deadline = taskcluster.fromNow('1 day')
@ -422,7 +427,7 @@ class TaskBuilder(object):
extra['notify'] = notify
return {
"attributes": {},
"attributes": attributes,
"dependencies": dependencies,
"label": name,
"task": {
@ -477,9 +482,16 @@ class TaskBuilder(object):
'machine': {
'platform': 'android-all',
},
'collection': {
'opt': True,
},
'symbol': 'As',
'tier': 1,
},
attributes={
'build-type': 'raptor',
'apks': variant.upstream_artifacts_per_abi,
},
)
def craft_release_signing_task(
@ -559,158 +571,6 @@ class TaskBuilder(object):
},
)
def craft_raptor_tp6m_cold_task(self, for_suite):
def craft_function(signing_task_label, mozharness_task_id, variant_apk, gecko_revision, is_staging, force_run_on_64_bit_device=False):
return self._craft_raptor_task(
signing_task_label,
mozharness_task_id,
variant_apk,
gecko_revision,
is_staging,
name_prefix='raptor tp6m-cold-{}'.format(for_suite),
description='Raptor tp6m cold on Fenix',
test_name='raptor-tp6m-cold-{}'.format(for_suite),
job_symbol='tp6m-c-{}'.format(for_suite),
force_run_on_64_bit_device=force_run_on_64_bit_device,
)
return craft_function
def craft_raptor_youtube_playback_task(self, signing_task_label, mozharness_task_id, variant_apk, gecko_revision,
is_staging, force_run_on_64_bit_device=False):
return self._craft_raptor_task(
signing_task_label,
mozharness_task_id,
variant_apk,
gecko_revision,
is_staging,
name_prefix='raptor youtube playback',
description='Raptor YouTube Playback on Fenix',
test_name='raptor-youtube-playback',
job_symbol='ytp',
group_symbol='Rap',
force_run_on_64_bit_device=force_run_on_64_bit_device,
)
def _craft_raptor_task(
self,
signing_task_label,
mozharness_task_id,
variant_apk,
gecko_revision,
is_staging,
name_prefix,
description,
test_name,
job_symbol,
group_symbol=None,
force_run_on_64_bit_device=False,
):
worker_type = 'gecko-t-bitbar-gw-perf-p2' if force_run_on_64_bit_device or variant_apk.abi == 'arm64-v8a' else 'gecko-t-bitbar-gw-perf-g5'
if force_run_on_64_bit_device:
treeherder_platform = 'android-hw-p2-8-0-arm7-api-16'
elif variant_apk.abi == 'armeabi-v7a':
treeherder_platform = 'android-hw-g5-7-0-arm7-api-16'
elif variant_apk.abi == 'arm64-v8a':
treeherder_platform = 'android-hw-p2-8-0-android-aarch64'
else:
raise ValueError('Unsupported architecture "{}"'.format(variant_apk.abi))
task_name = '{} {}: forPerformanceTest {}'.format(
name_prefix, variant_apk.abi, '(on 64-bit-device)' if force_run_on_64_bit_device else ''
)
apk_url = '{}/<signing>/artifacts/{}'.format(_DEFAULT_TASK_URL, variant_apk.taskcluster_path)
command = [[
"/builds/taskcluster/script.py",
"bash",
"./test-linux.sh",
"--cfg=mozharness/configs/raptor/android_hw_config.py",
"--test={}".format(test_name),
"--app=fenix",
"--binary=org.mozilla.fenix.performancetest",
"--activity=org.mozilla.fenix.browser.BrowserPerformanceTestActivity",
"--download-symbols=ondemand",
]]
# Bug 1558456 - Stop tracking youtube-playback-test on motoG5 for >1080p cases
if variant_apk.abi == 'armeabi-v7a' and test_name == 'raptor-youtube-playback':
params_query = '&'.join(ARM_RAPTOR_URL_PARAMS)
add_extra_params_option = "--test-url-params={}".format(params_query)
command[0].append(add_extra_params_option)
return self._craft_default_task_definition(
worker_type=worker_type,
provisioner_id='proj-autophone',
dependencies={'signing': signing_task_label},
name=task_name,
description=description,
routes=['notify.email.perftest-alerts@mozilla.com.on-failed'] if not is_staging else [],
payload={
"maxRunTime": 2700,
"artifacts": [{
'path': '{}'.format(worker_path),
'expires': taskcluster.stringDate(taskcluster.fromNow(DEFAULT_EXPIRES_IN)),
'type': 'directory',
'name': 'public/{}/'.format(public_folder)
} for worker_path, public_folder in (
('artifacts/public', 'test'),
('workspace/logs', 'logs'),
('workspace/build/blobber_upload_dir', 'test_info'),
)],
"command": command,
"env": {
"EXTRA_MOZHARNESS_CONFIG": {'task-reference': json.dumps({
"test_packages_url": "{}/{}/artifacts/public/build/en-US/target.test_packages.json".format(_DEFAULT_TASK_URL, mozharness_task_id),
"installer_url": apk_url,
})},
"GECKO_HEAD_REPOSITORY": "https://hg.mozilla.org/mozilla-central",
"GECKO_HEAD_REV": gecko_revision,
"MOZ_AUTOMATION": "1",
"MOZ_HIDE_RESULTS_TABLE": "1",
"MOZ_NO_REMOTE": "1",
"MOZ_NODE_PATH": "/usr/local/bin/node",
"MOZHARNESS_CONFIG": "raptor/android_hw_config.py",
"MOZHARNESS_SCRIPT": "raptor_script.py",
"MOZHARNESS_URL": "{}/{}/artifacts/public/build/en-US/mozharness.zip".format(_DEFAULT_TASK_URL, mozharness_task_id),
"MOZILLA_BUILD_URL": {'task-reference': apk_url},
"NEED_XVFB": "false",
"NO_FAIL_ON_TEST_ERRORS": "1",
"SCCACHE_DISABLE": "1",
"TASKCLUSTER_WORKER_TYPE": worker_type[len('gecko-'):],
"TRY_COMMIT_MSG": "",
"TRY_SELECTOR": "fuzzy",
"XPCOM_DEBUG_BREAK": "warn",
},
"mounts": [{
"content": {
"url": "https://hg.mozilla.org/mozilla-central/raw-file/{}/taskcluster/scripts/tester/test-linux.sh".format(gecko_revision),
},
"file": "test-linux.sh",
}]
},
treeherder={
'jobKind': 'test',
'groupSymbol': 'Rap' if group_symbol is None else group_symbol,
'machine': {
'platform': treeherder_platform,
},
'symbol': job_symbol,
'tier': 2,
},
notify={
'email': {
'link': {
'text': "Treeherder Job",
'href': "https://treeherder.mozilla.org/#/jobs?repo=fenix&revision={}".format(self.commit),
},
'subject': '[fenix] Raptor job "{}" failed'.format(task_name),
'content': "This calls for an action of the Performance team. Use the link to view it on Treeherder.",
},
},
)
def schedule_task(queue, taskId, task):
print("TASK", taskId)
print(json.dumps(task, indent=4, separators=(',', ': ')))

4
automation/taskcluster/lib/variant.py

@ -28,3 +28,7 @@ class Variant:
def upstream_artifacts(self):
return [apk.taskcluster_path for apk in self._apks]
@property
def upstream_artifacts_per_abi(self):
return {apk.abi: apk.taskcluster_path for apk in self._apks}

11
taskcluster/ci/geckoview/kind.yml

@ -0,0 +1,11 @@
---
loader: taskgraph.loader.transform:loader
transforms:
- taskgraph.transforms.index_search:transforms
- taskgraph.transforms.task:transforms
jobs:
nightly:
description: "upstream nightly job"
index-search:
- gecko.v2.mozilla-central.nightly.latest.mobile.android-x86_64-opt

207
taskcluster/ci/raptor/kind.yml

@ -0,0 +1,207 @@
---
loader: taskgraph.loader.transform:loader
transforms:
- fenix_taskgraph.raptor:transforms
- taskgraph.transforms.job:transforms
- taskgraph.transforms.task:transforms
kind-dependencies:
- old-decision
only-for-build-types:
- raptor
only-for-abis:
- armeabi-v7a
- arm64-v8a
job-defaults:
worker-type:
by-abi:
armeabi-v7a: t-bitbar-gw-perf-g5
arm64-v8a: t-bitbar-gw-perf-p2
run-on-tasks-for: []
treeherder:
kind: test
tier: 2
platform:
by-abi:
arm64-v8a: android-hw-p2-8-0-android-aarch64/opt
armeabi-v7a: android-hw-g5-7-0-arm7-api-16/opt
dependencies:
geckoview-nightly: geckoview-nightly
signing: 'sign: forPerformanceTest' # comes from the old-decision task
worker:
max-run-time: 3600
env:
GECKO_HEAD_REPOSITORY: "https://hg.mozilla.org/mozilla-central"
MOZ_AUTOMATION: "1"
MOZ_HIDE_RESULTS_TABLE: "1"
MOZ_NO_REMOTE: "1"
MOZ_NODE_PATH: "/usr/local/bin/node"
MOZHARNESS_CONFIG: "raptor/android_hw_config.py"
MOZHARNESS_SCRIPT: "raptor_script.py"
NEED_XVFB: "false"
NO_FAIL_ON_TEST_ERRORS: "1"
XPCOM_DEBUG_BREAK: "warn"
artifacts:
- name: public/logs/
path: workspace/logs
type: directory
- name: public/test_info/
path: workspace/build/blobber_upload_dir
type: directory
run:
using: run-task
checkout: false
run-as-root: true
command:
- 'bash'
- './test-linux.sh'
- '--cfg=mozharness/configs/raptor/android_hw_config.py'
- '--app=fenix'
- '--binary=org.mozilla.fenix.performancetest'
- '--activity=org.mozilla.fenix.browser.BrowserPerformanceTestActivity'
- '--download-symbols=ondemand'
jobs:
tp6m-cold-1:
test-name: raptor-tp6m-cold-1
treeherder:
symbol: 'Rap(tp6m-c-1)'
tp6m-cold-2:
test-name: raptor-tp6m-cold-2
treeherder:
symbol: 'Rap(tp6m-c-2)'
tp6m-cold-3:
test-name: raptor-tp6m-cold-3
treeherder:
symbol: 'Rap(tp6m-c-3)'
tp6m-cold-4:
test-name: raptor-tp6m-cold-4
treeherder:
symbol: 'Rap(tp6m-c-4)'
tp6m-cold-5:
test-name: raptor-tp6m-cold-5
treeherder:
symbol: 'Rap(tp6m-c-5)'
tp6m-cold-6:
test-name: raptor-tp6m-cold-6
treeherder:
symbol: 'Rap(tp6m-c-6)'
tp6m-cold-7:
test-name: raptor-tp6m-cold-7
treeherder:
symbol: 'Rap(tp6m-c-7)'
tp6m-cold-8:
test-name: raptor-tp6m-cold-8
treeherder:
symbol: 'Rap(tp6m-c-8)'
tp6m-cold-9:
test-name: raptor-tp6m-cold-9
treeherder:
symbol: 'Rap(tp6m-c-9)'
tp6m-cold-10:
test-name: raptor-tp6m-cold-10
treeherder:
symbol: 'Rap(tp6m-c-10)'
tp6m-cold-11:
test-name: raptor-tp6m-cold-11
treeherder:
symbol: 'Rap(tp6m-c-11)'
tp6m-cold-12:
test-name: raptor-tp6m-cold-12
treeherder:
symbol: 'Rap(tp6m-c-12)'
tp6m-cold-13:
test-name: raptor-tp6m-cold-13
treeherder:
symbol: 'Rap(tp6m-c-13)'
tp6m-cold-14:
test-name: raptor-tp6m-cold-14
treeherder:
symbol: 'Rap(tp6m-c-14)'
tp6m-cold-15:
test-name: raptor-tp6m-cold-15
treeherder:
symbol: 'Rap(tp6m-c-15)'
tp6m-cold-16:
test-name: raptor-tp6m-cold-16
treeherder:
symbol: 'Rap(tp6m-c-16)'
tp6m-cold-17:
test-name: raptor-tp6m-cold-17
treeherder:
symbol: 'Rap(tp6m-c-17)'
tp6m-cold-18:
test-name: raptor-tp6m-cold-18
treeherder:
symbol: 'Rap(tp6m-c-18)'
tp6m-cold-19:
test-name: raptor-tp6m-cold-19
treeherder:
symbol: 'Rap(tp6m-c-19)'
tp6m-cold-20:
test-name: raptor-tp6m-cold-20
treeherder:
symbol: 'Rap(tp6m-c-20)'
tp6m-cold-21:
test-name: raptor-tp6m-cold-21
treeherder:
symbol: 'Rap(tp6m-c-21)'
tp6m-cold-22:
test-name: raptor-tp6m-cold-22
treeherder:
symbol: 'Rap(tp6m-c-22)'
tp6m-cold-23:
test-name: raptor-tp6m-cold-23
treeherder:
symbol: 'Rap(tp6m-c-23)'
tp6m-cold-24:
test-name: raptor-tp6m-cold-24
treeherder:
symbol: 'Rap(tp6m-c-24)'
tp6m-cold-25:
test-name: raptor-tp6m-cold-25
treeherder:
symbol: 'Rap(tp6m-c-25)'
tp6m-cold-26:
test-name: raptor-tp6m-cold-26
treeherder:
symbol: 'Rap(tp6m-c-26)'
tp6m-cold-27:
test-name: raptor-tp6m-cold-27
treeherder:
symbol: 'Rap(tp6m-c-27)'
youtube-playback:
test-name: raptor-youtube-playback
treeherder:
symbol: 'Rap(ytp)'

96
taskcluster/fenix_taskgraph/raptor.py

@ -0,0 +1,96 @@
# 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/.
"""
Apply some defaults and minor modifications to the jobs defined in the build
kind.
"""
from __future__ import absolute_import, print_function, unicode_literals
import copy
import json
from taskgraph.transforms.base import TransformSequence
from taskgraph.util.treeherder import inherit_treeherder_from_dep
from taskgraph.util.schema import resolve_keyed_by
transforms = TransformSequence()
@transforms.add
def add_variants(config, tasks):
only_types = config.config["only-for-build-types"]
only_abis = config.config["only-for-abis"]
tests = list(tasks)
for dep_task in config.kind_dependencies_tasks:
build_type = dep_task.attributes.get("build-type", '')
if build_type not in only_types:
continue
# TODO remove this if statement once signing tasks are fully created in taskgraph
if not dep_task.label.startswith('sign: '):
continue
for abi, apk_path in dep_task.attributes["apks"].items():
if abi not in only_abis:
continue
for test in tests:
test = copy.deepcopy(test)
attributes = copy.deepcopy(dep_task.attributes)
attributes.update(test.get("attributes", {}))
attributes["abi"] = abi
attributes["apk"] = apk_path
test["attributes"] = attributes
test["primary-dependency"] = dep_task
yield test
@transforms.add
def build_raptor_task(config, tasks):
for task in tasks:
signing = task.pop("primary-dependency")
build_type = task["attributes"]["build-type"]
abi = task["attributes"]["abi"]
apk = task["attributes"]["apk"]
test_name = task.pop("test-name")
task["name"] = "{}-{}-{}".format(task["name"], build_type, abi)
task["description"] = "{}-{}".format(build_type, abi)
for key in ("worker-type", "treeherder.platform"):
resolve_keyed_by(task, key, item_name=task["name"], **{"abi": abi})
task["treeherder"] = inherit_treeherder_from_dep(task, signing)
extra_config = {
"installer_url": "<signing/{}>".format(apk),
"test_packages_url": "<geckoview-nightly/public/build/en-US/target.test_packages.json>",
}
env = task["worker"]["env"]
env["EXTRA_MOZHARNESS_CONFIG"] = {
"artifact-reference": json.dumps(extra_config, sort_keys=True)
}
env["GECKO_HEAD_REV"] = "default"
env["MOZILLA_BUILD_URL"] = {"artifact-reference": "<signing/{}>".format(apk)}
env["MOZHARNESS_URL"] = {
"artifact-reference": "<geckoview-nightly/public/build/en-US/mozharness.zip>"
}
env["TASKCLUSTER_WORKER_TYPE"] = task["worker-type"]
worker = task["worker"]
worker.setdefault("mounts", []).append(
{
"content": {
"url": "https://hg.mozilla.org/mozilla-central/raw-file/default/taskcluster/scripts/tester/test-linux.sh"
},
"file": "./test-linux.sh",
}
)
task["run"]["command"].append("--test={}".format(test_name))
task["run"]["command"].extend(task.pop("args", []))
yield task

21
taskcluster/fenix_taskgraph/target_tasks.py

@ -6,18 +6,20 @@ from __future__ import absolute_import, print_function, unicode_literals
from taskgraph.target_tasks import _target_task, standard_filter
# XXX We're overwritting the default target_task while all tasks are ported to taskgraph
@_target_task('default')
def target_tasks_default(full_task_graph, parameters, graph_config):
"""Target the tasks which have indicated they should be run on this project
via the `run_on_projects` attributes."""
def filter(t, params):
if t.kind == 'old-decision':
return True
return [l for l, t in full_task_graph.tasks.iteritems() if _old_decision_filter(t, parameters)]
return standard_filter(t, params)
return [l for l, t in full_task_graph.tasks.iteritems() if filter(t, parameters)]
def _old_decision_filter(task, parameters):
if task.kind == 'old-decision':
return True
return standard_filter(task, parameters)
@_target_task('nightly')
@ -28,5 +30,10 @@ def target_tasks_raptor(full_task_graph, parameters, graph_config):
@_target_task('raptor')
def target_tasks_raptor(full_task_graph, parameters, graph_config):
# TODO Change this target task method once old-decision loader is no more
return target_tasks_default(full_task_graph, parameters, graph_config)
def filter(t, params):
if t.kind == 'raptor':
return True
return _old_decision_filter(t, params)
return [l for l, t in full_task_graph.tasks.iteritems() if filter(t, parameters)]

Loading…
Cancel
Save