You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
403 lines
14 KiB
Python
403 lines
14 KiB
Python
# Copyright 2019 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.
|
|
|
|
import textwrap
|
|
|
|
from PB.go.chromium.org.luci.common.proto.findings import findings as findings_pb
|
|
from recipe_engine import post_process
|
|
|
|
|
|
PYTHON_VERSION_COMPATIBILITY = 'PY3'
|
|
|
|
DEPS = [
|
|
'gclient',
|
|
'presubmit',
|
|
'recipe_engine/buildbucket',
|
|
'recipe_engine/context',
|
|
'recipe_engine/cq',
|
|
'recipe_engine/json',
|
|
'recipe_engine/path',
|
|
'recipe_engine/properties',
|
|
'recipe_engine/proto',
|
|
'recipe_engine/runtime',
|
|
]
|
|
|
|
|
|
def RunSteps(api):
|
|
api.gclient.set_config('infra')
|
|
with api.context(cwd=api.path.cache_dir / 'builder'):
|
|
bot_update_step = api.presubmit.prepare()
|
|
skip_owners = api.properties.get('skip_owners', False)
|
|
run_all = api.properties.get('run_all', False)
|
|
return api.presubmit.execute(bot_update_step, skip_owners, run_all)
|
|
|
|
|
|
def GenTests(api):
|
|
yield api.test(
|
|
'success_ci',
|
|
api.buildbucket.ci_build(
|
|
git_repo='https://chromium.googlesource.com/infra/infra'),
|
|
api.properties(run_all=True),
|
|
api.step_data('presubmit', api.json.output({})),
|
|
api.post_process(post_process.StatusSuccess),
|
|
api.post_process(post_process.DropExpectation),
|
|
)
|
|
|
|
yield (api.test('success') + api.runtime(is_experimental=False) +
|
|
api.buildbucket.try_build(project='infra') + api.step_data(
|
|
'presubmit',
|
|
api.json.output({
|
|
'errors': [],
|
|
'notifications': [],
|
|
'warnings': []
|
|
}),
|
|
) + api.post_process(post_process.StatusSuccess) +
|
|
api.post_process(post_process.DropExpectation))
|
|
|
|
yield (api.test('cq_dry_run') + api.runtime(is_experimental=False) +
|
|
api.buildbucket.try_build(project='infra') +
|
|
api.cq(run_mode=api.cq.DRY_RUN) +
|
|
api.post_process(post_process.StatusSuccess) + api.post_process(
|
|
post_process.StepCommandContains, 'presubmit', ['--dry_run']) +
|
|
api.post_process(post_process.DropExpectation))
|
|
|
|
yield (api.test('skip_owners') + api.runtime(is_experimental=False) +
|
|
api.buildbucket.try_build(project='infra') +
|
|
api.properties(skip_owners=True) +
|
|
api.post_process(post_process.StatusSuccess) +
|
|
api.post_process(post_process.StepCommandContains, 'presubmit',
|
|
['--skip_canned', 'CheckOwners']) +
|
|
api.post_process(post_process.DropExpectation))
|
|
|
|
yield api.test(
|
|
'timeout',
|
|
api.runtime(is_experimental=False),
|
|
api.buildbucket.try_build(project='infra'),
|
|
api.presubmit(timeout_s=600),
|
|
api.step_data(
|
|
'presubmit',
|
|
api.json.output({
|
|
'errors': [],
|
|
'notifications': [],
|
|
'warnings': []
|
|
}),
|
|
times_out_after=1200,
|
|
),
|
|
api.post_process(post_process.StatusFailure),
|
|
api.post_process(
|
|
post_process.SummaryMarkdown,
|
|
(u'#### There are 0 error(s), 0 warning(s), and 0 notifications(s).'
|
|
'\n\nTimeout occurred during presubmit step.')),
|
|
api.post_process(post_process.DropExpectation),
|
|
status="FAILURE")
|
|
|
|
yield api.test(
|
|
'failure',
|
|
api.runtime(is_experimental=False),
|
|
api.buildbucket.try_build(project='infra'),
|
|
api.step_data(
|
|
'presubmit',
|
|
api.json.output(
|
|
{
|
|
'errors': [{
|
|
'message': 'Missing LGTM',
|
|
'long_text': 'Here are some suggested OWNERS: fake@',
|
|
'items': [],
|
|
'fatal': True
|
|
}, {
|
|
'message': 'Syntax error in fake.py',
|
|
'long_text': 'Expected "," after item in list',
|
|
'items': [],
|
|
'fatal': True
|
|
}],
|
|
'notifications': [{
|
|
'message': 'If there is a bug associated please add it.',
|
|
'long_text': '',
|
|
'items': [],
|
|
'fatal': False
|
|
}],
|
|
'warnings': [{
|
|
'message': 'Line 100 has more than 80 characters',
|
|
'long_text': '',
|
|
'items': [],
|
|
'fatal': False
|
|
}]
|
|
},
|
|
retcode=1)),
|
|
api.post_process(post_process.StatusFailure),
|
|
api.post_process(
|
|
post_process.SummaryMarkdown,
|
|
textwrap.dedent(u'''
|
|
#### There are 2 error(s), 1 warning(s), and 1 notifications(s).
|
|
|
|
**ERROR**
|
|
```
|
|
Missing LGTM
|
|
Here are some suggested OWNERS: fake@
|
|
```
|
|
|
|
**ERROR**
|
|
```
|
|
Syntax error in fake.py
|
|
Expected "," after item in list
|
|
```
|
|
|
|
#### To see notifications and warnings, look at the stdout of the presubmit step.
|
|
''').strip()),
|
|
api.post_process(post_process.DropExpectation),
|
|
status="FAILURE")
|
|
|
|
long_message = (u'Here are some suggested OWNERS:' +
|
|
u'\nreallyLongFakeAccountNameEmail@chromium.org' * 10)
|
|
yield api.test(
|
|
'failure-long-message',
|
|
api.runtime(is_experimental=False),
|
|
api.buildbucket.try_build(project='infra'),
|
|
api.step_data(
|
|
'presubmit',
|
|
api.json.output(
|
|
{
|
|
'errors': [{
|
|
'message': 'Missing LGTM',
|
|
'long_text': long_message,
|
|
'items': [],
|
|
'fatal': True
|
|
}],
|
|
'notifications': [],
|
|
'warnings': []
|
|
},
|
|
retcode=1)),
|
|
api.post_process(post_process.StatusFailure),
|
|
api.post_process(
|
|
post_process.SummaryMarkdown,
|
|
textwrap.dedent('''
|
|
#### There are 1 error(s), 0 warning(s), and 0 notifications(s).
|
|
|
|
**ERROR**
|
|
```
|
|
Missing LGTM
|
|
Here are some suggested OWNERS:
|
|
reallyLongFakeAccountNameEmail@chromium.org
|
|
reallyLongFakeAccountNameEmail@chromium.org
|
|
reallyLongFakeAccountNameEmail@chromium.org
|
|
reallyLongFakeAccountNameEmail@chromium.org
|
|
reallyLongFakeAccountNameEmail@chromium.org
|
|
reallyLongFakeAccountNameEmail@chromium.org
|
|
reallyLongFakeAccountNameEmail@chromium.org
|
|
reallyLongFakeAccountNameEmail@chromium.org
|
|
reallyLongFakeAccountNameEmail@chromium.org
|
|
```
|
|
|
|
**Error size > 450 chars, there are 2 more error(s) (15 total)**
|
|
**The complete output can be found at the bottom of the presubmit stdout.**
|
|
''').strip()),
|
|
api.post_process(post_process.DropExpectation),
|
|
status="FAILURE")
|
|
|
|
yield api.test(
|
|
'infra-failure',
|
|
api.runtime(is_experimental=False),
|
|
api.buildbucket.try_build(project='infra'),
|
|
api.step_data(
|
|
'presubmit',
|
|
api.json.output(
|
|
{
|
|
'errors': [{
|
|
'message': 'Infra Failure',
|
|
'long_text': '',
|
|
'items': [],
|
|
'fatal': True
|
|
}],
|
|
'notifications': [],
|
|
'warnings': []
|
|
},
|
|
retcode=2)),
|
|
api.post_process(post_process.StatusException),
|
|
api.post_process(
|
|
post_process.SummaryMarkdown,
|
|
textwrap.dedent(u'''
|
|
#### There are 1 error(s), 0 warning(s), and 0 notifications(s).
|
|
|
|
**ERROR**
|
|
```
|
|
Infra Failure
|
|
|
|
```
|
|
''').strip()),
|
|
api.post_process(post_process.DropExpectation),
|
|
status="INFRA_FAILURE")
|
|
|
|
bug_msg = ('Something unexpected occurred'
|
|
' while running presubmit checks.'
|
|
' Please [file a bug](https://issues.chromium.org'
|
|
'/issues/new?component=1456211)')
|
|
yield api.test(
|
|
'failure-no-json',
|
|
api.runtime(is_experimental=False),
|
|
api.buildbucket.try_build(project='infra'),
|
|
api.step_data('presubmit', api.json.output(None, retcode=1)),
|
|
api.post_process(post_process.StatusException),
|
|
api.post_process(post_process.SummaryMarkdown, bug_msg),
|
|
api.post_process(post_process.DropExpectation),
|
|
status="INFRA_FAILURE")
|
|
|
|
yield api.test(
|
|
'infra-failure-no-json',
|
|
api.runtime(is_experimental=False),
|
|
api.buildbucket.try_build(project='infra'),
|
|
api.step_data('presubmit', api.json.output(None, retcode=2)),
|
|
api.post_process(post_process.StatusException),
|
|
api.post_process(post_process.SummaryMarkdown, bug_msg),
|
|
api.post_process(post_process.DropExpectation),
|
|
status="INFRA_FAILURE")
|
|
|
|
def _has_uploaded_findings(check, steps, expected_findings):
|
|
step_name = 'upload presubmit results as findings'
|
|
check(step_name in steps)
|
|
check('findings.json' in steps[step_name].logs)
|
|
findings = api.proto.decode(steps[step_name].logs['findings.json'],
|
|
findings_pb.Findings, 'JSONPB').findings
|
|
check(len(findings) == len(expected_findings))
|
|
for (actual, expected) in zip(findings, expected_findings):
|
|
check(actual == expected)
|
|
|
|
gerrit_change_ref = findings_pb.Location.GerritChangeReference(
|
|
host='chromium-review.googlesource.com',
|
|
project='infra',
|
|
change=123456,
|
|
patchset=7)
|
|
|
|
yield api.test(
|
|
'upload_findings',
|
|
api.runtime(is_experimental=False),
|
|
api.buildbucket.try_build(project='infra'),
|
|
api.step_data(
|
|
'presubmit',
|
|
api.json.output(
|
|
{
|
|
'errors': [{
|
|
'message':
|
|
'bug bug bug',
|
|
'long_text':
|
|
'',
|
|
'items': [],
|
|
'locations': [{
|
|
'file_path': 'path/to/file1',
|
|
}, {
|
|
'file_path': 'path/to/file2',
|
|
}],
|
|
'fatal':
|
|
True
|
|
}],
|
|
'notifications':
|
|
[{
|
|
'message': 'cc abc@google.com',
|
|
'long_text': '',
|
|
'items': [],
|
|
'locations': [{
|
|
'file_path': '/COMMIT_MSG',
|
|
}],
|
|
'fatal': False
|
|
}],
|
|
'warnings': [{
|
|
'message':
|
|
'Change takes 20 min to take effect after landing',
|
|
'long_text': '',
|
|
'items': [],
|
|
'locations': [],
|
|
'fatal': False
|
|
}, {
|
|
'message':
|
|
'typo!!',
|
|
'long_text':
|
|
'replace foo with bar',
|
|
'items': [],
|
|
'locations': [{
|
|
'file_path': 'path/to/file',
|
|
'start_line': 1,
|
|
'start_col': 2,
|
|
'end_line': 1,
|
|
'end_col': 5,
|
|
}],
|
|
'fatal':
|
|
False
|
|
}]
|
|
},
|
|
retcode=1)),
|
|
api.post_process(
|
|
_has_uploaded_findings,
|
|
[
|
|
findings_pb.Finding(
|
|
category='chromium_presubmit',
|
|
location=findings_pb.Location(
|
|
gerrit_change_ref=gerrit_change_ref,
|
|
file_path='path/to/file1'),
|
|
message='bug bug bug',
|
|
severity_level=findings_pb.Finding.SEVERITY_LEVEL_ERROR),
|
|
findings_pb.Finding(
|
|
category='chromium_presubmit',
|
|
location=findings_pb.Location(
|
|
gerrit_change_ref=gerrit_change_ref,
|
|
file_path='path/to/file2'),
|
|
message='bug bug bug',
|
|
severity_level=findings_pb.Finding.SEVERITY_LEVEL_ERROR),
|
|
findings_pb.Finding(
|
|
category='chromium_presubmit',
|
|
location=findings_pb.Location(
|
|
gerrit_change_ref=gerrit_change_ref,
|
|
file_path='path/to/file',
|
|
range=findings_pb.Location.Range(
|
|
start_line=1,
|
|
start_column=2,
|
|
end_line=1,
|
|
end_column=5,
|
|
)),
|
|
message='typo!!',
|
|
severity_level=findings_pb.Finding.SEVERITY_LEVEL_WARNING),
|
|
findings_pb.Finding(
|
|
category='chromium_presubmit',
|
|
location=findings_pb.Location(
|
|
gerrit_change_ref=gerrit_change_ref,
|
|
file_path='/COMMIT_MSG'),
|
|
message='cc abc@google.com',
|
|
severity_level=findings_pb.Finding.SEVERITY_LEVEL_INFO),
|
|
],
|
|
),
|
|
api.post_process(post_process.StatusFailure),
|
|
api.post_process(post_process.DropExpectation),
|
|
status="FAILURE")
|
|
|
|
yield api.test(
|
|
'upload_findings_when_presubmit_succeeds',
|
|
api.runtime(is_experimental=False),
|
|
api.buildbucket.try_build(project='infra'),
|
|
api.step_data(
|
|
'presubmit',
|
|
api.json.output({
|
|
'errors': [],
|
|
'notifications': [],
|
|
'warnings': [{
|
|
'message': 'this is a message',
|
|
'long_text': '',
|
|
'items': [],
|
|
'locations': [{
|
|
'file_path': 'path/to/file',
|
|
}],
|
|
'fatal': False
|
|
}]
|
|
})),
|
|
api.post_process(
|
|
_has_uploaded_findings,
|
|
[
|
|
findings_pb.Finding(
|
|
category='chromium_presubmit',
|
|
location=findings_pb.Location(
|
|
gerrit_change_ref=gerrit_change_ref,
|
|
file_path='path/to/file'),
|
|
message='this is a message',
|
|
severity_level=findings_pb.Finding.SEVERITY_LEVEL_WARNING),
|
|
],
|
|
), api.post_process(post_process.StatusSuccess),
|
|
api.post_process(post_process.DropExpectation))
|