blob: 4e6fb5dd24f7e0e0cd4ca58c491b8d3ba125c5da [file] [log] [blame]
# Copyright 2020 The Fuchsia Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""Recipe for triggering toolchain buildbucket builds."""
from recipe_engine.config import List
from recipe_engine.recipe_api import Property
from PB.go.chromium.org.luci.buildbucket.proto import rpc as rpc_pb2
from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
DEPS = [
'fuchsia/status_check',
'recipe_engine/buildbucket',
'recipe_engine/json',
'recipe_engine/properties',
'recipe_engine/raw_io',
'recipe_engine/step',
'recipe_engine/swarming',
]
PROPERTIES = {
'toolchain_builders':
Property(
kind=List(basestring),
help='List of toolchain builders to trigger',
default=[]),
'goma_builders':
Property(
kind=List(basestring),
help='List of goma toolchain builders to trigger',
default=[]),
'package':
Property(kind=str, help='CIPD path of toolchain package', default=None),
'toolchain':
Property(kind=str, help='toolchain name', default=None),
'interval':
Property(
kind=int, help='Delay between requests when waiting', default=None),
'timeout':
Property(
kind=int, help='Time to wait for the builds to end', default=None),
}
def RunSteps(api, toolchain_builders, goma_builders, package, toolchain,
interval, timeout):
# Trigger the CI build.
ci_build_results = api.buildbucket.run(
[
api.buildbucket.schedule_request(
builder, bucket='ci', swarming_parent_run_id=api.swarming.task_id)
for builder in toolchain_builders
],
collect_interval=interval,
timeout=timeout,
step_name='schedule ci builders',
)
for result in ci_build_results:
if result.status != common_pb2.SUCCESS:
raise api.step.StepFailure('toolchain ci task(s) failed')
# Trigger the PROD build.
prod_build_results = api.buildbucket.run(
[
api.buildbucket.schedule_request(
builder,
bucket='prod',
swarming_parent_run_id=api.swarming.task_id)
for builder in toolchain_builders
],
collect_interval=interval,
timeout=timeout,
step_name='schedule prod builders',
)
for result in prod_build_results:
if result.status != common_pb2.SUCCESS:
raise api.step.StepFailure('toolchain prod task(s) failed')
# Trigger goma builder.
revision = ''
for result in prod_build_results:
output = result.output.properties
if 'git_revision' in output:
if not revision:
revision = output['git_revision']
else:
if revision != output['git_revision']:
raise api.step.StepFailure(
'%s revision not unified, %s:%s' %
(toolchain, revision, output['git_revision']))
if not revision:
api.step('git_revision output property not set', None)
return
goma_properties = {
'package': package,
'toolchain': toolchain,
'project': 'fuchsia-toolchain-images-gcr',
'version': 'git_revision:' + revision,
}
goma_results = api.buildbucket.run(
[
api.buildbucket.schedule_request(
# TODO(haowei): toolchain bots are currently in ci,
# change it to prod in the future.
builder,
bucket='ci',
properties=goma_properties,
swarming_parent_run_id=api.swarming.task_id)
for builder in goma_builders
],
collect_interval=interval,
timeout=timeout,
step_name='schedule goma builders',
)
for result in goma_results:
if result.status != common_pb2.SUCCESS:
raise api.step.StepFailure('goma task(s) failed')
def GenTests(api):
default_properties = api.properties(
toolchain_builders=["clang-linux-x64", "clang-mac-x64"],
goma_builders=["clang-goma"],
package='fuchsia/third_party/clang',
toolchain='clang')
yield (api.test('default') + api.buildbucket.ci_build(
bucket='ci',
git_repo='https://fuchsia.googlesource.com/example',
revision='a' * 40,
))
ci_build = api.buildbucket.ci_build_message(status='SUCCESS')
mock_ci_schedule_data = api.buildbucket.simulated_schedule_output(
step_name='schedule ci builders.schedule',
batch_response=rpc_pb2.BatchResponse(
responses=[dict(schedule_build=dict(id=ci_build.id))],))
mock_ci_collect_data = api.buildbucket.simulated_collect_output(
step_name='schedule ci builders.collect',
builds=[ci_build],
)
ci_build_failure = api.buildbucket.ci_build_message(status='FAILURE')
mock_ci_failure_schedule_data = api.buildbucket.simulated_schedule_output(
step_name='schedule ci builders.schedule',
batch_response=rpc_pb2.BatchResponse(
responses=[dict(schedule_build=dict(id=ci_build_failure.id))],))
mock_ci_failure_collect_data = api.buildbucket.simulated_collect_output(
step_name='schedule ci builders.collect',
builds=[ci_build_failure],
)
prod_build = api.buildbucket.ci_build_message(
build_id=ci_build.id + 1, status='SUCCESS')
prod_build.output.properties['git_revision'] = 'a' * 40
mock_prod_schedule_data = api.buildbucket.simulated_schedule_output(
step_name='schedule prod builders.schedule',
batch_response=rpc_pb2.BatchResponse(
responses=[dict(schedule_build=dict(id=prod_build.id))],))
mock_prod_collect_data = api.buildbucket.simulated_collect_output(
step_name='schedule prod builders.collect',
builds=[prod_build],
)
prod_build_failure = api.buildbucket.ci_build_message(
build_id=ci_build.id + 1, status='FAILURE')
mock_prod_failure_schedule_data = api.buildbucket.simulated_schedule_output(
step_name='schedule prod builders.schedule',
batch_response=rpc_pb2.BatchResponse(
responses=[dict(schedule_build=dict(id=prod_build_failure.id))],))
mock_prod_failure_collect_data = api.buildbucket.simulated_collect_output(
step_name='schedule prod builders.collect',
builds=[prod_build_failure],
)
goma_build_failure = api.buildbucket.ci_build_message(status='FAILURE')
mock_goma_failure_schedule_data = api.buildbucket.simulated_schedule_output(
step_name='schedule goma builders.schedule',
batch_response=rpc_pb2.BatchResponse(
responses=[dict(schedule_build=dict(id=goma_build_failure.id))],))
mock_goma_failure_collect_data = api.buildbucket.simulated_collect_output(
step_name='schedule goma builders.collect',
builds=[goma_build_failure],
)
yield (api.test('default with goma') + api.buildbucket.ci_build(
bucket='ci',
git_repo='https://fuchsia.googlesource.com/example',
revision='a' * 40,
) + default_properties + mock_ci_schedule_data + mock_ci_collect_data +
mock_prod_schedule_data + mock_prod_collect_data)
yield (api.status_check.test('default with ci failure', status='failure') +
api.buildbucket.ci_build(
bucket='ci',
git_repo='https://fuchsia.googlesource.com/example',
revision='a' * 40,
) + default_properties + mock_ci_failure_schedule_data +
mock_ci_failure_collect_data)
yield (api.status_check.test('default with prod failure', status='failure') +
api.buildbucket.ci_build(
bucket='ci',
git_repo='https://fuchsia.googlesource.com/example',
revision='a' * 40,
) + default_properties + mock_ci_schedule_data + mock_ci_collect_data +
mock_prod_failure_schedule_data + mock_prod_failure_collect_data)
yield (api.status_check.test('default with goma failures', status='failure') +
api.buildbucket.ci_build(
bucket='ci',
git_repo='https://fuchsia.googlesource.com/example',
revision='a' * 40,
) + default_properties + mock_ci_schedule_data + mock_ci_collect_data +
mock_prod_schedule_data + mock_prod_collect_data +
mock_goma_failure_schedule_data + mock_goma_failure_collect_data)
prod_build_mismatch = api.buildbucket.ci_build_message(
build_id=prod_build.id + 1, status='SUCCESS')
prod_build_mismatch.output.properties['git_revision'] = 'b' * 40
mock_schedule_data_mismatch = api.buildbucket.simulated_schedule_output(
step_name='schedule prod builders.schedule',
batch_response=rpc_pb2.BatchResponse(
responses=[
dict(schedule_build=dict(id=prod_build.id)),
dict(schedule_build=dict(id=prod_build_mismatch.id))
],))
mock_collect_data_mismatch = api.buildbucket.simulated_collect_output(
step_name='schedule prod builders.collect',
builds=[prod_build, prod_build_mismatch],
)
yield (api.status_check.test(
'default with revision mismatch', status='failure') +
api.buildbucket.ci_build(
bucket='ci',
git_repo='https://fuchsia.googlesource.com/example',
revision='a' * 40,
) + default_properties + mock_ci_schedule_data + mock_ci_collect_data +
mock_schedule_data_mismatch + mock_collect_data_mismatch)