git cl: retry-failed avoid not useful retries.
* don't retry successful (last build) or still running builders.
* don't retry CQ experimental builders.
R=ehmaldonado
Bug: 1012631
Change-Id: I2a155b274c822f8ead032098a08702f26362bee3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/tools/depot_tools/+/1851735
Reviewed-by: Edward Lesmes <ehmaldonado@chromium.org>
Commit-Queue: Andrii Shyshkalov <tandrii@google.com>
diff --git a/tests/git_cl_test.py b/tests/git_cl_test.py
index 0da416d..f7de42b 100755
--- a/tests/git_cl_test.py
+++ b/tests/git_cl_test.py
@@ -3037,18 +3037,17 @@
},
}
_DEFAULT_RESPONSE = {
- 'builds': [
- {
- 'id': str(100 + idx),
- 'builder': {
- 'project': 'chromium',
- 'bucket': 'try',
- 'builder': 'bot_' + status.lower(),
- },
- 'status': status,
- }
- for idx, status in enumerate(_STATUSES)
- ]
+ 'builds': [{
+ 'id': str(100 + idx),
+ 'builder': {
+ 'project': 'chromium',
+ 'bucket': 'try',
+ 'builder': 'bot_' + status.lower(),
+ },
+ 'createTime': '2019-10-09T08:00:0%d.854286Z' % (idx % 10),
+ 'tags': [],
+ 'status': status,
+ } for idx, status in enumerate(_STATUSES)]
}
def setUp(self):
@@ -3073,14 +3072,15 @@
class CMDTryResultsTestCase(CMDTestCaseBase):
_DEFAULT_REQUEST = {
'predicate': {
- "gerritChanges": [{
- "project": "depot_tools",
- "host": "chromium-review.googlesource.com",
- "patchset": 7,
- "change": 123456,
- }],
+ "gerritChanges": [{
+ "project": "depot_tools",
+ "host": "chromium-review.googlesource.com",
+ "patchset": 7,
+ "change": 123456,
+ }],
},
- 'fields': 'builds.*.id,builds.*.builder,builds.*.status',
+ 'fields': ('builds.*.id,builds.*.builder,builds.*.status' +
+ ',builds.*.createTime,builds.*.tags'),
}
def testNoJobs(self):
@@ -3147,11 +3147,58 @@
mockJsonDump.assert_called_once_with(
'file.json', self._DEFAULT_RESPONSE['builds'])
- def test_filter_failed(self):
- self.assertEqual({}, git_cl._filter_failed([]))
+ def test_filter_failed_for_one_simple(self):
+ self.assertEqual({}, git_cl._filter_failed_for_retry([]))
self.assertEqual({
- 'chromium/try': {'bot_failure': [], 'bot_infra_failure': []},
- }, git_cl._filter_failed(self._DEFAULT_RESPONSE['builds']))
+ 'chromium/try': {
+ 'bot_failure': [],
+ 'bot_infra_failure': []
+ },
+ }, git_cl._filter_failed_for_retry(self._DEFAULT_RESPONSE['builds']))
+
+ def test_filter_failed_for_retry_many_builds(self):
+
+ def _build(name, created_sec, status, experimental=False):
+ assert 0 <= created_sec < 100, created_sec
+ b = {
+ 'id': 112112,
+ 'builder': {
+ 'project': 'chromium',
+ 'bucket': 'try',
+ 'builder': name,
+ },
+ 'createTime': '2019-10-09T08:00:%02d.854286Z' % created_sec,
+ 'status': status,
+ 'tags': [],
+ }
+ if experimental:
+ b['tags'].append({'key': 'cq_experimental', 'value': 'true'})
+ return b
+
+ builds = [
+ _build('flaky-last-green', 1, 'FAILURE'),
+ _build('flaky-last-green', 2, 'SUCCESS'),
+ _build('flaky', 1, 'SUCCESS'),
+ _build('flaky', 2, 'FAILURE'),
+ _build('running', 1, 'FAILED'),
+ _build('running', 2, 'SCHEDULED'),
+ _build('yep-still-running', 1, 'STARTED'),
+ _build('yep-still-running', 2, 'FAILURE'),
+ _build('cq-experimental', 1, 'SUCCESS', experimental=True),
+ _build('cq-experimental', 2, 'FAILURE', experimental=True),
+
+ # Simulate experimental in CQ builder, which developer decided
+ # to retry manually which resulted in 2nd build non-experimental.
+ _build('sometimes-experimental', 1, 'FAILURE', experimental=True),
+ _build('sometimes-experimental', 2, 'FAILURE', experimental=False),
+ ]
+ builds.sort(key=lambda b: b['status']) # ~deterministic shuffle.
+ self.assertEqual({
+ 'chromium/try': {
+ 'flaky': [],
+ 'sometimes-experimental': []
+ },
+ }, git_cl._filter_failed_for_retry(builds))
class CMDTryTestCase(CMDTestCaseBase):
@@ -3228,11 +3275,10 @@
'builder': {
'project': 'chromium',
'bucket': 'try',
- 'builder': 'linux',
- },
- 'status': 'FAILURE',
- }],
- }[kw['patchset']]
+ 'builder': 'linux',},
+ 'createTime': '2019-10-09T08:00:01.854286Z',
+ 'tags': [],
+ 'status': 'FAILURE',}],}[kw['patchset']]
mockCallBuildbucket.return_value = {}
self.assertEqual(0, git_cl.main(['try', '--retry-failed']))
@@ -3318,18 +3364,17 @@
# Latest patchset: No builds.
[],
# Patchset before latest: Some builds.
- [
- {
- 'id': str(100 + idx),
- 'builder': {
- 'project': 'chromium',
- 'bucket': 'try',
- 'builder': 'bot_' + status.lower(),
- },
- 'status': status,
- }
- for idx, status in enumerate(self._STATUSES)
- ],
+ [{
+ 'id': str(100 + idx),
+ 'builder': {
+ 'project': 'chromium',
+ 'bucket': 'try',
+ 'builder': 'bot_' + status.lower(),
+ },
+ 'createTime': '2019-10-09T08:00:0%d.854286Z' % (idx % 10),
+ 'tags': [],
+ 'status': status,
+ } for idx, status in enumerate(self._STATUSES)],
]
self.assertEqual(0, git_cl.main(['upload', '--retry-failed']))