| # 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. |
| """ Reruns tests using previously produced build artifacts. |
| |
| Outline: |
| |
| * Find the last green build of `source_builder`. |
| * Fetch that green build's output property `child_build_id`. |
| * Use api.buildbucket to trigger a run of `source_builder`, but with the modifications: |
| * Change the bucket to <my bucket>. |
| * Set the Gitiles input to the same as that of the last green build. |
| * Set `child_build_id` to the `child_build_id` from the last green build. |
| |
| """ |
| |
| from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2 |
| |
| from recipe_engine.recipe_api import Property |
| |
| DEPS = [ |
| 'fuchsia/buildbucket_util', |
| 'fuchsia/status_check', |
| 'recipe_engine/buildbucket', |
| 'recipe_engine/properties', |
| 'recipe_engine/step', |
| ] |
| |
| PROPERTIES = { |
| 'source_bucket': |
| Property(kind=str, help='The bucket for source_builder.', default=None), |
| 'source_builder': |
| Property( |
| kind=str, |
| help='The last build of this builder will be re-run.', |
| default=None), |
| } |
| |
| |
| def RunSteps(api, source_bucket, source_builder): |
| my_build = api.buildbucket.build |
| last_build_status = common_pb2.SUCCESS |
| # Flaky builders are rarely successful, so we take any build. |
| if source_builder.endswith('-flaky'): |
| last_build_status = None |
| |
| # TODO(fxb/44578): We'll no longer need this special case once we've reduced |
| # memory usage such that all rerun builders can run on 1-core machines. |
| original_builder = source_builder |
| one_core_suffix = '-1-core' |
| if original_builder.endswith(one_core_suffix): |
| original_builder = original_builder[:-len(one_core_suffix)] |
| source_build = api.buildbucket_util.last_build( |
| my_build.builder.project, |
| source_bucket, |
| original_builder, |
| status=last_build_status) |
| if not source_build: |
| raise api.step.InfraFailure( |
| 'Failed to find source_build for builder %s/%s/%s' % |
| (my_build.builder.project, source_bucket, source_builder)) |
| |
| rerun_properties = { |
| 'child_build_id': source_build.output.properties['child_build_id'] |
| } |
| schedule_rerun_request = api.buildbucket.schedule_request( |
| source_builder, |
| project=my_build.builder.project, |
| bucket=my_build.builder.bucket, |
| properties=rerun_properties, |
| gitiles_commit=source_build.input.gitiles_commit, |
| ) |
| api.buildbucket.schedule([schedule_rerun_request]) |
| |
| |
| def GenTests(api): |
| properties = api.properties( |
| source_bucket='source-bucket', source_builder='source-builder-flaky') |
| |
| yield (api.status_check.test('no_search_results', status='infra_failure') + |
| properties + api.buildbucket.ci_build()) |
| |
| source_build = api.buildbucket.ci_build_message() |
| source_build.output.properties['child_build_id'] = 123 |
| yield (api.status_check.test('success') + properties + |
| api.buildbucket.simulated_search_results([source_build]) + |
| api.buildbucket.ci_build(bucket='rerun')) |
| |
| yield (api.status_check.test('1_core') + api.properties( |
| source_bucket='source-bucket', source_builder='source-builder-1-core') + |
| api.buildbucket.simulated_search_results([source_build]) + |
| api.buildbucket.ci_build(bucket='rerun')) |