blob: 272b1400b5ff33293e7937e61aa8f2b34a71f2ac [file] [log] [blame]
# Copyright 2018 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.
from google.protobuf import json_format as jsonpb
from google.protobuf import struct_pb2
from recipe_engine import post_process
from recipe_engine.config import List
from recipe_engine.recipe_api import Property
from PB.go.chromium.org.luci.buildbucket.proto import common as common_pb2
from PB.recipes.fuchsia.fuchsia.spec import Fuchsia
DEPS = [
"fuchsia/buildbucket_util",
"fuchsia/checkout",
"fuchsia/jiri",
"fuchsia/release",
"recipe_engine/assertions",
"recipe_engine/file",
"recipe_engine/json",
"recipe_engine/path",
"recipe_engine/properties",
"recipe_engine/raw_io",
]
PROPERTIES = {
"project": Property(
kind=str,
help="The name of the project",
default="integration",
),
"remote": Property(
kind=str,
help="The remote URL of the manifest repo",
default="https://fuchsia.googlesource.com/integration",
),
"manifest": Property(
kind=str,
help="The name of the manifest to import from the integration repo",
default="minimal",
),
"is_release_version": Property(
kind=bool, help="Whether or not checkout is a release version", default=False
),
"attributes": Property(
kind=List(str),
help="Attributes corresponding to optional packages or projects to checkout",
default=(),
),
"use_incremental_cache": Property(
kind=bool,
help="Whether to restore an old checkout from the cache",
default=False,
),
"allow_skipping_patch": Property(
kind=bool,
help="Whether to allow skipping the patch if the project doesn't exist",
default=False,
),
"enable_submodules": Property(
kind=bool,
help="Whether to enable submodules in the checkout",
default=False,
),
}
def RunSteps(
api,
project,
remote,
manifest,
is_release_version,
attributes,
use_incremental_cache,
allow_skipping_patch,
enable_submodules,
):
checkout_spec = Fuchsia.Checkout(
project=project,
remote=remote,
manifest=manifest,
is_release_version=is_release_version,
attributes=attributes,
allow_skipping_patch=allow_skipping_patch,
enable_submodules=enable_submodules,
)
checkout = api.checkout.from_spec(
checkout_spec,
use_incremental_cache=use_incremental_cache,
)
assert checkout.root_dir
assert checkout.snapshot_file
checkout.integration_revision # pylint: disable=pointless-statement
checkout.release_branch # pylint: disable=pointless-statement
checkout.release_version # pylint: disable=pointless-statement
checkout.list_files()
checkout.changed_files(base=None)
checkout.upload_results("artifact_gcs_bucket")
checkout.check_clean()
# Checkouts should not be allowed to be rooted in start_dir.
with api.assertions.assertRaises(ValueError):
api.checkout.with_options(
manifest=manifest, remote=remote, path=api.path.start_dir
)
# manifest and remote are required.
with api.assertions.assertRaises(AssertionError):
api.checkout.with_options(manifest="", remote="")
def GenTests(api):
source_info = [
{
"name": "integration",
"remote": "https://fuchsia.googlesource.com/integration",
"revision": "a491082dc1b632bbcd60ba3618d20b503c2de738",
"relativePath": "integration",
},
]
yield (
api.buildbucket_util.test("default", tryjob=True)
+ api.checkout.source_info(source_info)
)
yield (
api.buildbucket_util.test(
"global_integration_commit_with_change",
tryjob=True,
revision="base-revision",
repo="integration",
)
+ api.properties(
**{
"$fuchsia/checkout": {
"respect_gitiles_commit_with_gerrit_change": True,
"cherry_pick_patches": True,
}
}
)
)
yield (
api.buildbucket_util.test(
"global_integration_tryjob", tryjob=True, repo="integration"
)
+ api.checkout.source_info(source_info)
)
yield (
api.buildbucket_util.test(
"smart_integration_tryjob_on_integration_patch",
tryjob=True,
repo="integration",
properties=jsonpb.ParseDict(
{
"recipes_integration_ref_mapping": {
"refs/heads/original": "refs/heads/mapped",
},
},
struct_pb2.Struct(),
),
)
+ api.checkout.source_info(
[
{
"name": "smart-integration",
"remote": "https://fuchsia.googlesource.com/smart-integration",
"revision": "a491082dc1b632bbcd60ba3618d20b503c2de738",
"relativePath": "integration",
},
]
)
+ api.step_data(
"checkout.get change details",
api.json.output(
{
"branch": "original",
"revisions": {
"d4e5f6": {"_number": 7, "ref": "refs/changes/00/100/7"},
},
}
),
)
)
# The current patchset may not immediately be queryable in Gerrit if it was
# recently uploaded, due to replication delays. If it's not included in the
# change details, we should retry until it is included.
yield (
api.buildbucket_util.test("gerrit_replication_delay", tryjob=True, patch_set=2)
+ api.checkout.source_info(source_info)
+ api.step_data(
"checkout.get change details",
api.json.output(
{
"branch": "main",
"revisions": {
"d4e5f6": {"_number": 1, "ref": "refs/changes/00/100/1"},
},
}
),
)
+ api.step_data(
"checkout.get change details (2)",
api.json.output(
{
"branch": "main",
"revisions": {
"d4e5f6": {"_number": 1, "ref": "refs/changes/00/100/1"},
"a1b2c3": {"_number": 2, "ref": "refs/changes/00/100/2"},
},
}
),
)
)
yield (
api.buildbucket_util.test(
"global_integration_release_ci",
tryjob=False,
repo="integration",
git_ref="refs/heads/releases/foo",
)
+ api.properties(
is_release_version=True,
attributes=["attr1", "attr2"],
)
+ api.checkout.source_info(source_info)
+ api.release.ref_to_release_version(
"releases/0.20190603.0.1",
nesting="checkout.resolve release version",
)
)
yield (
api.buildbucket_util.test(
"global_integration_release_ci_invalid_branch",
tryjob=False,
repo="integration",
git_ref="refs/heads/NOT-A-RELEASE-BRANCH",
)
+ api.properties(is_release_version=True)
+ api.checkout.source_info(source_info)
+ api.release.ref_to_release_version(
"releases/0.20190603.0.1",
nesting="checkout.resolve release version",
)
)
yield (
api.buildbucket_util.test(
"fuchsia_enable_submodules",
tryjob=False,
repo="integration",
)
+ api.checkout.source_info(source_info)
+ api.properties(enable_submodules=True)
)
yield (
api.buildbucket_util.test(
"local_integration_tryjob_patch_no_such_project",
tryjob=True,
repo="fuchsia",
status="FAILURE",
)
+ api.step_data("checkout.jiri project", api.json.output([]))
)
yield (
api.buildbucket_util.test(
"local_integration_ci", tryjob=False, repo="not-fuchsia"
)
+ api.checkout.source_info(source_info)
)
# By default, `api.file.read_text()` will return an empty string rather than
# failing when run in recipe unit-testing mode. So make sure that we cover
# the production code path, in which `read_text()` will raise an exception
# rather than returning an empty string.
yield (
api.buildbucket_util.test("missing_patchfile", tryjob=True)
+ api.checkout.source_info(source_info)
+ api.step_data("checkout.read patches.json", api.file.errno("ENOENT"))
)
yield (
api.buildbucket_util.test("tryjob_with_patchfile", tryjob=True, repo="fuchsia")
+ api.checkout.source_info(source_info)
+ api.checkout.patchfile(
[
{
"ref": "refs/changes/33/112233/1",
"host": "example-review.googlesource.com",
"project": "not_fuchsia",
}
]
)
)
yield (
api.buildbucket_util.test("with_package_overrides", tryjob=True)
+ api.step_data(
"checkout.read package overrides",
api.file.read_json({"path/to/package": "abcdef"}),
)
+ api.checkout.source_info(source_info)
)
yield (
api.buildbucket_util.test(
"fail_to_patch_over_gerrit_change",
tryjob=True,
repo="fuchsia",
status="FAILURE",
)
+ api.checkout.patchfile(
[
{
"ref": "refs/changes/33/112233/1",
"host": "fuchsia-review.googlesource.com",
"project": "fuchsia",
}
]
)
)
yield (
api.buildbucket_util.test(
"fail_to_patch_same_project_many_times",
tryjob=True,
repo="fuchsia",
status="FAILURE",
)
+ api.checkout.patchfile(
[
{
"ref": "refs/changes/33/112233/1",
"host": "fuchsia-review.googlesource.com",
"project": "zircon",
},
{
"ref": "refs/changes/66/445566/2",
"host": "fuchsia-review.googlesource.com",
"project": "zircon",
},
]
)
)
yield (
api.buildbucket_util.test(
"patch_json_third_party",
tryjob=True,
repo="integration",
status="SUCCESS",
)
+ api.properties(enable_submodules=True)
+ api.step_data(
"checkout.jiri project submodule check patchfile",
api.json.output(
[
{
"name": "libc-tests",
"relativePath": "third_party/libc-tests",
"gitsubmoduleof": "fuchsia",
"revision": "aaaaaa",
},
{
"name": "fuchsia",
"relativePath": ".",
"revision": "bbbbbb",
},
]
),
)
+ api.checkout.patchfile(
[
{
"ref": "refs/changes/33/112233/1",
"host": "fuchsia-review.googlesource.com",
"project": "fuchsia",
},
{
"ref": "refs/changes/66/445566/2",
"host": "fuchsia-review.googlesource.com",
"project": "libc-tests",
},
]
)
)
yield (
api.buildbucket_util.test(
"patch_third_party_change",
tryjob=True,
repo="libc-tests",
status="SUCCESS",
)
+ api.properties(enable_submodules=True)
+ api.checkout.source_info(source_info)
+ api.step_data(
"checkout.jiri project submodule check patch",
api.json.output(
[
{
"name": "libc-tests",
"relativePath": "third_party/libc-tests",
"gitsubmoduleof": "fuchsia",
"revision": "aaaaaa",
},
{
"name": "fuchsia",
"relativePath": ".",
"revision": "bbbbbb",
},
]
),
)
)
yield (
api.buildbucket_util.test(
"patch_integration_change",
tryjob=True,
repo="integration",
status="SUCCESS",
)
+ api.properties(enable_submodules=True)
+ api.checkout.source_info(source_info)
)
yield (
api.buildbucket_util.test(
"when_patchfile_host_has_protocol", tryjob=True, repo="fuchsia"
)
+ api.checkout.source_info(source_info)
+ api.checkout.patchfile(
[
{
"ref": "refs/changes/33/112233/1",
"host": "https://fuchsia-review.googlesource.com",
"project": "foo",
}
]
)
)
yield (
api.buildbucket_util.test(
"should_ignore_patches_for_non_dependant_projects",
tryjob=True,
repo="fuchsia",
)
+ api.checkout.source_info(source_info)
+ api.checkout.patchfile(
[
{
"ref": "refs/changes/33/112233/1",
"host": "https://fuchsia-review.googlesource.com",
"project": "foo",
}
]
)
+ api.step_data("checkout.jiri project foo", api.json.output([]))
)
# We want to be able to run tryjobs on integration CLs to test property
# changes, which take effect via recipe_wrapper even when the integration
# repo isn't included in the checkout.
yield (
api.buildbucket_util.test(
"ignore_patch_for_nonexistent_integration_project",
tryjob=True,
repo="integration",
)
+ api.checkout.source_info(source_info)
+ api.step_data("checkout.jiri project", api.json.output([]))
+ api.post_process(post_process.MustRun, "checkout.skipping patch")
)
yield (
api.buildbucket_util.test(
"allow_skipping_patch",
tryjob=True,
repo="doesnotexist",
)
+ api.properties(allow_skipping_patch=True)
+ api.checkout.source_info(source_info)
+ api.step_data("checkout.jiri project", api.json.output([]))
+ api.post_process(post_process.MustRun, "checkout.skipping patch")
)
yield (
api.buildbucket_util.test(
"should_ignore_recipe_changes", tryjob=True, repo="infra/recipes"
)
+ api.checkout.source_info(source_info)
+ api.step_data("get changed files.jiri project", api.json.output([]))
)
yield (
api.buildbucket_util.test("sso_manifest_remote", repo="not-fuchsia")
+ api.properties(remote="sso://manifest-host/manifest")
+ api.checkout.source_info(source_info)
)
yield (
api.buildbucket_util.test("use_gitiles_commit_from_properties", tryjob=False)
+ api.properties(
**{
"$fuchsia/checkout": {
"gitiles_commit": jsonpb.MessageToDict(
common_pb2.GitilesCommit(
host="fuchsia.googlesource.com",
project="foo",
id="deadbeef",
)
)
}
}
)
+ api.checkout.source_info(source_info)
)
yield (
api.buildbucket_util.test("use_incremental_cache", tryjob=False)
+ api.properties(use_incremental_cache=True)
+ api.checkout.source_info(source_info)
)
# No gerrit_changes or gitiles_commit.
yield api.test("empty_build_input") + api.checkout.source_info(source_info)
yield (
api.buildbucket_util.test(
"local_integration_tryjob_patch_submodule",
tryjob=True,
repo="third_party/github.com/foobar/foobar",
status="SUCCESS",
)
+ api.checkout.source_info(source_info)
+ api.step_data(
"checkout.jiri patch", retcode=api.jiri.NoSuchProjectError.EXIT_CODE
)
+ api.step_data("checkout.jiri project", api.json.output([]))
+ api.step_data(
"checkout.list submodules",
api.raw_io.stream_output_text(
"\n".join(
[
"submodule.third_party/foobar.path=third_party/foobar",
"submodule.third_party/foobar.url=https://fuchsia.googlesource.com/third_party/github.com/foobar/foobar",
"submodule.third_party/foobar.name=third_party/foobar",
"submodule.third_party/foobar.ignore=all",
"submodule.build/secondary/third_party/foobaz.path=build/secondary/third_party/foobaz",
"submodule.build/secondary/third_party/foobaz.url=https://fuchsia.googlesource.com/foobaz-gn",
"submodule.build/secondary/third_party/foobaz.name=foobaz-gn",
"submodule.build/secondary/third_party/foobaz.ignore=all",
]
)
),
)
)