Commit d94f9a6d authored by Garrett Beaty's avatar Garrett Beaty Committed by LUCI CQ

Add a method for enforcing a tryjob.

The tryserver.require_is_tryserver method will create an infra-failing
step that raises an exception if there is no CL associated with the
build. In the case of an LED task, it will only fail so as not to cause
the removal of the builder cache in the case of a minor user error.

Change-Id: I05d3a86cc727577f067fb3eae49e46398345f672
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/3413971
Auto-Submit: Garrett Beaty <gbeaty@google.com>
Reviewed-by: 's avatarGavin Mak <gavinmak@google.com>
Commit-Queue: Gavin Mak <gavinmak@google.com>
parent 42c5bbbc
......@@ -40,6 +40,7 @@
* [tryserver:tests/gerrit_change_fetch_ref_timeout](#recipes-tryserver_tests_gerrit_change_fetch_ref_timeout) (Python3 ✅)
* [tryserver:tests/gerrit_change_owner](#recipes-tryserver_tests_gerrit_change_owner) (Python3 ✅)
* [tryserver:tests/gerrit_change_target_ref](#recipes-tryserver_tests_gerrit_change_target_ref) (Python3 ✅)
* [tryserver:tests/require_is_tryserver](#recipes-tryserver_tests_require_is_tryserver) (Python3 ✅)
* [windows_sdk:examples/full](#recipes-windows_sdk_examples_full) (Python3 ✅)
## Recipe Modules
......@@ -779,7 +780,7 @@ Returns:
&emsp; **@property**<br>&mdash; **def [presubmit\_support\_path](/recipes/recipe_modules/presubmit/api.py#24)(self):**
### *recipe_modules* / [tryserver](/recipes/recipe_modules/tryserver)
[DEPS](/recipes/recipe_modules/tryserver/__init__.py#7): [gerrit](#recipe_modules-gerrit), [git](#recipe_modules-git), [git\_cl](#recipe_modules-git_cl), [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step]
[DEPS](/recipes/recipe_modules/tryserver/__init__.py#7): [gerrit](#recipe_modules-gerrit), [git](#recipe_modules-git), [git\_cl](#recipe_modules-git_cl), [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/context][recipe_engine/recipe_modules/context], [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/led][recipe_engine/recipe_modules/led], [recipe\_engine/path][recipe_engine/recipe_modules/path], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/python][recipe_engine/recipe_modules/python], [recipe\_engine/raw\_io][recipe_engine/recipe_modules/raw_io], [recipe\_engine/step][recipe_engine/recipe_modules/step]
PYTHON_VERSION_COMPATIBILITY: PY2+3
......@@ -844,7 +845,7 @@ Returns gerrit change patchset, e.g. 6 for a patch ref of
Populated iff gerrit_change is populated Returns None if not populated..
&mdash; **def [get\_files\_affected\_by\_patch](/recipes/recipe_modules/tryserver/api.py#212)(self, patch_root, report_files_via_property=None, \*\*kwargs):**
&mdash; **def [get\_files\_affected\_by\_patch](/recipes/recipe_modules/tryserver/api.py#225)(self, patch_root, report_files_via_property=None, \*\*kwargs):**
Returns list of paths to files affected by the patch.
......@@ -856,11 +857,11 @@ Args:
Returned paths will be relative to to patch_root.
&mdash; **def [get\_footer](/recipes/recipe_modules/tryserver/api.py#352)(self, tag, patch_text=None):**
&mdash; **def [get\_footer](/recipes/recipe_modules/tryserver/api.py#365)(self, tag, patch_text=None):**
Gets a specific tag from a CL description
&mdash; **def [get\_footers](/recipes/recipe_modules/tryserver/api.py#316)(self, patch_text=None):**
&mdash; **def [get\_footers](/recipes/recipe_modules/tryserver/api.py#329)(self, patch_text=None):**
Retrieves footers from the patch description.
......@@ -879,20 +880,22 @@ Returns true iff the properties exist to match a Gerrit issue.
Returns true iff we have a change to check out.
&mdash; **def [normalize\_footer\_name](/recipes/recipe_modules/tryserver/api.py#360)(self, footer):**
&mdash; **def [normalize\_footer\_name](/recipes/recipe_modules/tryserver/api.py#373)(self, footer):**
&mdash; **def [set\_change](/recipes/recipe_modules/tryserver/api.py#363)(self, change):**
&mdash; **def [require\_is\_tryserver](/recipes/recipe_modules/tryserver/api.py#212)(self):**
&mdash; **def [set\_change](/recipes/recipe_modules/tryserver/api.py#376)(self, change):**
Set the gerrit change for this module.
Args:
* change: a self.m.buildbucket.common_pb2.GerritChange.
&mdash; **def [set\_compile\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#277)(self):**
&mdash; **def [set\_compile\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#290)(self):**
Mark the tryjob result as a compile failure.
&mdash; **def [set\_invalid\_test\_results\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#289)(self):**
&mdash; **def [set\_invalid\_test\_results\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#302)(self):**
Mark the tryjob result as having invalid test results.
......@@ -900,32 +903,32 @@ This means we run some tests, but the results were not valid
(e.g. no list of specific test cases that failed, or too many
tests failing, etc).
&mdash; **def [set\_patch\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#273)(self):**
&mdash; **def [set\_patch\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#286)(self):**
Mark the tryjob result as failure to apply the patch.
&mdash; **def [set\_subproject\_tag](/recipes/recipe_modules/tryserver/api.py#251)(self, subproject_tag):**
&mdash; **def [set\_subproject\_tag](/recipes/recipe_modules/tryserver/api.py#264)(self, subproject_tag):**
Adds a subproject tag to the build.
This can be used to distinguish between builds that execute different steps
depending on what was patched, e.g. blink vs. pure chromium patches.
&mdash; **def [set\_test\_expired\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#306)(self):**
&mdash; **def [set\_test\_expired\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#319)(self):**
Mark the tryjob result as a test expiration.
This means a test task expired and was never scheduled, most likely due to
lack of capacity.
&mdash; **def [set\_test\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#281)(self):**
&mdash; **def [set\_test\_failure\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#294)(self):**
Mark the tryjob result as a test failure.
This means we started running actual tests (not prerequisite steps
like checkout or compile), and some of these tests have failed.
&mdash; **def [set\_test\_timeout\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#298)(self):**
&mdash; **def [set\_test\_timeout\_tryjob\_result](/recipes/recipe_modules/tryserver/api.py#311)(self):**
Mark the tryjob result as a test timeout.
......@@ -1139,6 +1142,13 @@ PYTHON_VERSION_COMPATIBILITY: PY2+3
PYTHON_VERSION_COMPATIBILITY: PY2+3
&mdash; **def [RunSteps](/recipes/recipe_modules/tryserver/tests/gerrit_change_target_ref.py#18)(api):**
### *recipes* / [tryserver:tests/require\_is\_tryserver](/recipes/recipe_modules/tryserver/tests/require_is_tryserver.py)
[DEPS](/recipes/recipe_modules/tryserver/tests/require_is_tryserver.py#12): [tryserver](#recipe_modules-tryserver), [recipe\_engine/buildbucket][recipe_engine/recipe_modules/buildbucket], [recipe\_engine/properties][recipe_engine/recipe_modules/properties]
PYTHON_VERSION_COMPATIBILITY: PY2+3
&mdash; **def [RunSteps](/recipes/recipe_modules/tryserver/tests/require_is_tryserver.py#19)(api):**
### *recipes* / [windows\_sdk:examples/full](/recipes/recipe_modules/windows_sdk/examples/full.py)
[DEPS](/recipes/recipe_modules/windows_sdk/examples/full.py#7): [windows\_sdk](#recipe_modules-windows_sdk), [recipe\_engine/json][recipe_engine/recipe_modules/json], [recipe\_engine/platform][recipe_engine/recipe_modules/platform], [recipe\_engine/properties][recipe_engine/recipe_modules/properties], [recipe\_engine/step][recipe_engine/recipe_modules/step]
......@@ -1155,6 +1165,7 @@ PYTHON_VERSION_COMPATIBILITY: PY2+3
[recipe_engine/recipe_modules/cq]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/a476355d81d68d946bb2ab2b9431d648e7ad2167/README.recipes.md#recipe_modules-cq
[recipe_engine/recipe_modules/file]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/a476355d81d68d946bb2ab2b9431d648e7ad2167/README.recipes.md#recipe_modules-file
[recipe_engine/recipe_modules/json]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/a476355d81d68d946bb2ab2b9431d648e7ad2167/README.recipes.md#recipe_modules-json
[recipe_engine/recipe_modules/led]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/a476355d81d68d946bb2ab2b9431d648e7ad2167/README.recipes.md#recipe_modules-led
[recipe_engine/recipe_modules/milo]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/a476355d81d68d946bb2ab2b9431d648e7ad2167/README.recipes.md#recipe_modules-milo
[recipe_engine/recipe_modules/path]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/a476355d81d68d946bb2ab2b9431d648e7ad2167/README.recipes.md#recipe_modules-path
[recipe_engine/recipe_modules/platform]: https://chromium.googlesource.com/infra/luci/recipes-py.git/+/a476355d81d68d946bb2ab2b9431d648e7ad2167/README.recipes.md#recipe_modules-platform
......
......@@ -11,6 +11,7 @@ DEPS = [
'recipe_engine/buildbucket',
'recipe_engine/context',
'recipe_engine/json',
'recipe_engine/led',
'recipe_engine/path',
'recipe_engine/platform',
'recipe_engine/properties',
......
......@@ -209,6 +209,19 @@ class TryserverApi(recipe_api.RecipeApi):
self.m.properties.get('patch_repo_url') and
self.m.properties.get('patch_ref'))
def require_is_tryserver(self):
if self.m.tryserver.is_tryserver:
return
status = self.m.step.EXCEPTION
step_text = 'This recipe requires a gerrit CL for the source under test'
if self.m.led.launched_by_led:
status = self.m.step.FAILURE
step_text += (
"\n run 'led edit-cr-cl <source CL URL>' to attach a CL to test"
)
self.m.step.empty('not a tryjob', status=status, step_text=step_text)
def get_files_affected_by_patch(self, patch_root,
report_files_via_property=None,
**kwargs):
......
# Copyright 2022 The Chromium 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 recipe_engine import post_process
from PB.go.chromium.org.luci.swarming.proto.api import swarming as swarming_pb
from PB.recipe_modules.recipe_engine.led import properties as led_properties_pb
PYTHON_VERSION_COMPATIBILITY = 'PY2+3'
DEPS = [
'tryserver',
'recipe_engine/buildbucket',
'recipe_engine/properties',
]
def RunSteps(api):
api.tryserver.require_is_tryserver()
def GenTests(api):
yield api.test(
'tryjob',
api.buildbucket.try_build(),
api.post_check(post_process.StatusSuccess),
api.post_process(post_process.DropExpectation),
)
yield api.test(
'not-a-tryjob',
api.post_check(post_process.StatusException),
api.post_check(post_process.StepException, 'not a tryjob'),
api.post_process(post_process.DropExpectation),
)
yield api.test(
'not-a-tryjob-led',
api.properties(
**{
'$recipe_engine/led':
led_properties_pb.InputProperties(
led_run_id='fake-run-id',
rbe_cas_input=swarming_pb.CASReference(
cas_instance=(
'projects/example/instances/default_instance'),
digest=swarming_pb.Digest(
hash='examplehash',
size_bytes=71,
),
),
),
}),
api.post_check(post_process.StatusFailure),
api.post_check(post_process.StepFailure, 'not a tryjob'),
api.post_process(post_process.DropExpectation),
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment