| # 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 testing Recipes.""" |
| |
| from PB.recipes.fuchsia.recipes import InputProperties |
| |
| PYTHON_VERSION_COMPATIBILITY = "PY3" |
| |
| DEPS = [ |
| "fuchsia/build_input_resolver", |
| "fuchsia/checkout", |
| "fuchsia/commit_queue", |
| "fuchsia/recipe_testing", |
| "fuchsia/status_check", |
| "recipe_engine/buildbucket", |
| "recipe_engine/context", |
| "recipe_engine/json", |
| "recipe_engine/path", |
| "recipe_engine/properties", |
| "recipe_engine/step", |
| ] |
| |
| PROPERTIES = InputProperties |
| |
| # If this build is being triggered from a change to this recipe, we need |
| # to explicitly pass a CL. The most recent passing run of |
| # fuchsia.try/recipes could take anywhere from about three to 200 minutes, |
| # and the three minute version does not test much of what this recipe |
| # actually does. In that case alter the recipes build to run on a specific |
| # CL that modifies the cobalt recipe alone. (The cobalt build usually |
| # takes less than 10 minutes.) |
| SELFTEST_CL = "https://fuchsia-review.googlesource.com/c/infra/recipes/+/303171" |
| |
| # If this build is being triggered from a change to this recipe, and we're |
| # using the Buildbucket testing codepath, then we need to explicitly pass a |
| # builder. This builder will run in the case that the only affected recipe is |
| # this one, so we are guaranteed to exercise the scheduling codepath without |
| # recursing infinitely. |
| SELFTEST_BUILDER = "fuchsia/try/bringup.x64-debug-no_opt-build_only" |
| |
| |
| def RunSteps(api, props): |
| """Run tests for recipes.""" |
| |
| # Resolve the build input to always contain a Gitiles commit. |
| api.build_input_resolver.resolve() |
| |
| with api.context(infra_steps=True): |
| api.checkout.with_options( |
| path=api.path["start_dir"], |
| manifest=props.manifest, |
| remote=props.remote, |
| project=props.project, |
| # Override defaults. We should always attempt to patch. |
| skip_patch_projects=(), |
| ) |
| |
| recipes_path = api.path["start_dir"].join("infra", "recipes") |
| |
| if props.check_deps: |
| with api.context(cwd=recipes_path): |
| run_check_deps(api, recipes_path) |
| |
| with api.step.defer_results(): |
| # TODO(olivernewman): Stop allowlisting pipes after it's no longer used by |
| # gcc_toolchain. |
| api.recipe_testing.run_lint(recipes_path, allowlist=r"^pipes$") |
| api.recipe_testing.run_unit_tests(recipes_path) |
| |
| if not props.unittest_only: |
| api.recipe_testing.run_tests( |
| recipes_path, |
| SELFTEST_CL, |
| props.recipe_testing_options, |
| selftest_builder=SELFTEST_BUILDER, |
| ) |
| |
| |
| def run_check_deps(api, recipes_path): |
| step = api.step( |
| "check deps", |
| [ |
| recipes_path.join("scripts", "cleanup_deps.py"), |
| "--check", |
| "--json-output", |
| api.json.output(), |
| ], |
| ok_ret=(0, 1), |
| step_test_data=lambda: api.json.test_api.output([]), |
| ) |
| if not step.retcode: |
| return |
| |
| step.presentation.status = api.step.FAILURE |
| bad_files = step.json.output |
| summary = ( |
| "Files with malformatted DEPS (run ./scripts/cleanup_deps.py to fix):\n\n" |
| + "\n".join(["- `%s`" % path for path in bad_files]) |
| ) |
| raise api.step.StepFailure(summary) |
| |
| |
| def GenTests(api): # pylint: disable=invalid-name |
| def test(name, status="success", run_tests=True, projects=(), **props): |
| ret = ( |
| api.status_check.test(name, status=status) |
| + api.buildbucket.try_build( |
| project="fuchsia", |
| git_repo="https://fuchsia.googlesource.com/infra/recipes", |
| ) |
| + api.properties( |
| manifest="manifest/minimal", |
| remote="https://fuchsia.googlesource.com/infra/recipes", |
| check_deps=True, |
| **props |
| ) |
| ) |
| |
| if projects: |
| ret += api.recipe_testing.config(projects=projects) |
| |
| if run_tests: |
| ret += api.commit_queue.test_data( |
| "fuchsia", config_name=projects[0]["cq_config_name"] |
| ) + api.recipe_testing.affected_recipes_data(["none"]) |
| return ret |
| |
| yield ( |
| test( |
| "cq_try", |
| projects=( |
| api.recipe_testing.project( |
| cq_config_name="alternate-commit-queue.cfg", |
| ), |
| ), |
| ) |
| + api.recipe_testing.build_data( |
| "fuchsia/try/core.x64-debug", "fuchsia", skip=True |
| ) |
| + api.recipe_testing.build_data( |
| "fuchsia/try/core.arm64-debug", "fuchsia", skip=True |
| ) |
| + api.recipe_testing.build_data( |
| "fuchsia/try/cobalt-x64-linux", "cobalt", skip=True |
| ) |
| ) |
| |
| yield ( |
| test( |
| "cq_try_restricted", |
| projects=( |
| api.recipe_testing.project( |
| include_unrestricted=False, |
| include_restricted=True, |
| cq_config_name="alternate-commit-queue.cfg", |
| ), |
| ), |
| ) |
| + api.recipe_testing.build_data("fuchsia/try/secret-tryjob", "docs", skip=True) |
| ) |
| |
| yield ( |
| test("check_deps_fails", run_tests=False, status="failure") |
| + api.step_data("check deps", api.json.output(["recipes/foo.py"]), retcode=1) |
| ) |