blob: 5f5fb697ae5f60a6d61152e6806b00f13e23aa61 [file] [log] [blame]
# Copyright 2016 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 json
from recipe_engine import recipe_test_api
class RecipeAutorollerTestApi(recipe_test_api.RecipeTestApi):
_TBR_EMAILS = ('foo@bar.example.com', 'meep@example.com')
_EXTRA_REVIEWERS = ('foo@chromium.org', 'foo@bar.example.com',
'meep@example.com')
def repo_spec(self,
tbr_emails=_TBR_EMAILS,
extra_reviewers=_EXTRA_REVIEWERS,
disable_reason='',
self_approve_method='BOT_COMMIT_APPROVE',
trivial_commit=True,
trivial_dryrun=False,
nontrivial_dryrun=True,
nontrivial_autosubmit=True,
include_autoroll_options=True,
no_cc_authors=False):
spec = {
'api_version': 2,
'deps': {
'recipe_engine': {
'url':
'https://chromium.googlesource.com/infra/luci/recipes-py',
},
},
}
if include_autoroll_options:
spec['autoroll_recipe_options'] = {
'trivial': {
'tbr_emails': list(tbr_emails),
'automatic_commit': trivial_commit,
'dry_run': trivial_dryrun,
'self_approve_method': self_approve_method,
},
'nontrivial': {
'extra_reviewer_emails': list(extra_reviewers),
'automatic_commit_dry_run': nontrivial_dryrun,
'set_autosubmit': nontrivial_autosubmit,
},
'disable_reason': disable_reason,
'no_cc_authors': no_cc_authors,
}
return spec
def roll_data(self,
project,
spec=None,
success=True,
trivial=True,
empty=False,
num_commits=1):
"""Returns mock roll and recipes.cfg data for |project|."""
if spec is None:
spec = self.repo_spec()
if empty:
success = False
ret = self.empty_test_data() + self.recipe_cfg(project, spec)
if spec.get('autoroll_recipe_options', {}).get('disable_reason'):
return ret
commit_infos = []
for i in range(num_commits):
commit_infos.append({
'author_email': 'foo@chromium.org',
'message_lines': [
('some commit summary that is too long to fit in a single '
'line in Gerrit'),
('R=bar@chromium.org,baz@chromium.org,invalid1,'
'invalid2@chromium'),
'BUG=123,456',
],
'revision': '%d23abc' % (i + 1),
})
picked_roll_details = {
'commit_infos': {
'recipe_engine': commit_infos,
},
'spec': spec,
}
roll_result = {
'success': success,
'trivial': trivial if success else None,
'picked_roll_details': picked_roll_details if success else None,
}
roll_result['rejected_candidates_count'] = 0
if empty:
roll_result['roll_details'] = []
else:
roll_result['roll_details'] = [picked_roll_details]
if not success:
roll_result['rejected_candidates_count'] = 1
ret += self.step_data('%s.roll' % project, self.m.json.output(roll_result))
return ret
def repo_data(self, project, trivial, status, timestamp):
return (self.override_step_data(
'%s.gsutil repo_state' % project,
self.m.raw_io.stream_output_text(
json.dumps({
'issue': '123456789',
'issue_url': 'https://codereview.chromium.org/123456789',
'trivial': trivial,
'last_roll_ts_utc': timestamp,
}),
stream='stdout'),
self.m.raw_io.stream_output_text('', stream='stderr')) +
self.step_data('%s.git cl status' % project,
self.m.raw_io.stream_output_text(status)))
def recipe_cfg(self, project, spec=None):
"""Returns mock recipes.cfg data (only) for |project|.
This is used for tests which abort between the 'read recipes.cfg' step and
the 'roll' step (e.g. which read repo state and decide to quit early).
For "normal" test runs, you'll want to use roll_data() from this
RecipeTestApi, which includes this step data automatically.
"""
if spec is None:
spec = self.repo_spec()
return self.override_step_data(
'%s.read recipes.cfg' % project, self.m.json.output(spec)
)