def test_gerrit_change(self): msg = rpc_pb2.ScheduleBuildRequest( builder=build_pb2.BuilderID(project='chromium', bucket='try', builder='linux-rel'), gerrit_changes=[ common_pb2.GerritChange(host='gerrit.example.com', change=2), ], ) self.assert_invalid(msg, r'gerrit_changes\[0\]\.patchset: required')
def test_gerrit_change(self): cl = common_pb2.GerritChange( host='gerrit.example.com', change=1234, patchset=5, ) build = self.add(dict(gerrit_changes=[cl])) self.assertEqual(build.proto.input.gerrit_changes[:], [cl]) bs = 'patch/gerrit/gerrit.example.com/1234/5' self.assertIn('buildset:' + bs, build.tags)
def parse_gerrit_change_buildset(buildset): # pragma: no cover # Example: patch/gerrit/chromium-review.googlesource.com/677784/5 m = RE_BUILDSET_GERRIT_CL.match(buildset) if not m: return None return common_pb2.GerritChange( host=m.group(1), change=int(m.group(2)), patchset=int(m.group(3)), )
def test_put_with_v2_gerrit_changes(self, add_async): changes = [ common_pb2.GerritChange( host='chromium.googlesource.com', project='project', change=1, patchset=1, ), common_pb2.GerritChange( host='chromium.googlesource.com', project='project', change=2, patchset=1, ), ] expected_sbr = rpc_pb2.ScheduleBuildRequest( builder=dict( project='chromium', bucket='try', builder='linux', ), properties=dict(), gerrit_changes=changes, ) expected_request = creation.BuildRequest( schedule_build_request=expected_sbr, parameters={}, ) add_async.return_value = future(test_util.build(id=1)) params = { api_common.BUILDER_PARAMETER: 'linux', 'gerrit_changes': [json_format.MessageToDict(c) for c in changes], } req = { 'bucket': 'luci.chromium.try', 'parameters_json': json.dumps(params), } self.call_api('put', req) add_async.assert_called_once_with(expected_request)
def test_gerrit_changes(self): msg = rpc_pb2.BuildPredicate( gerrit_changes=[common_pb2.GerritChange()]) self.assert_invalid(msg, r'gerrit_changes\[0\].host: required')
def test_no_host(self): msg = common_pb2.GerritChange(host='', change=1, patchset=1) self.assert_invalid(msg, r'host: required')
def test_valid(self): msg = common_pb2.GerritChange(host='gerrit.example.com', change=1, patchset=1) self.assert_valid(msg)
def put_request_message_to_build_request(put_request): """Converts PutRequest to BuildRequest. Raises errors.InvalidInputError if the put_request is invalid. """ lease_expiration_date = parse_datetime(put_request.lease_expiration_ts) errors.validate_lease_expiration_date(lease_expiration_date) # Read parameters. parameters = parse_json_object(put_request.parameters_json, 'parameters_json') parameters = parameters or {} validate_known_build_parameters(parameters) builder = parameters.get(model.BUILDER_PARAMETER) or '' # Validate tags. buildtags.validate_tags(put_request.tags, 'new', builder=builder) # Read properties. Remove them from parameters. props = parameters.pop(model.PROPERTIES_PARAMETER, None) if props is not None and not isinstance(props, dict): raise errors.InvalidInputError( '"properties" parameter must be a JSON object or null') props = props or {} changes = parameters.get(_PARAM_CHANGES) if changes: # pragma: no branch # Buildbucket-Buildbot integration passes repo_url of the first change in # build parameter "changes" as "repository" attribute of SourceStamp. # https://chromium.googlesource.com/chromium/tools/build/+/2c6023d # /scripts/master/buildbucket/changestore.py#140 # Buildbot passes repository of the build source stamp as "repository" # build property. Recipes, in partiular bot_update recipe module, rely on # "repository" property and it is an almost sane property to support in # swarmbucket. repo_url = changes[0].get('repo_url') if repo_url: # pragma: no branch props['repository'] = repo_url # Buildbot-Buildbucket integration converts emails in changes to blamelist # property. emails = [c.get('author', {}).get('email') for c in changes] props['blamelist'] = filter(None, emails) # Create a v2 request. sbr = rpc_pb2.ScheduleBuildRequest( builder=build_pb2.BuilderID(builder=builder), properties=bbutil.dict_to_struct(props), request_id=put_request.client_operation_id, experimental=bbutil.BOOLISH_TO_TRINARY[put_request.experimental], canary=api_common.CANARY_PREFERENCE_TO_TRINARY.get( put_request.canary_preference, common_pb2.UNSET), ) sbr.builder.project, sbr.builder.bucket = config.parse_bucket_id( put_request.bucket) # Parse tags. Extract gitiles commit and gerrit changes. tags, gitiles_commit, gerrit_changes = parse_v1_tags(put_request.tags) sbr.tags.extend(tags) if gitiles_commit: sbr.gitiles_commit.CopyFrom(gitiles_commit) # Gerrit changes explicitly passed via "gerrit_changes" parameter win. gerrit_change_list = parameters.pop('gerrit_changes', None) if gerrit_change_list is not None: if not isinstance(gerrit_change_list, list): # pragma: no cover raise errors.InvalidInputError('gerrit_changes must be a list') try: gerrit_changes = [ json_format.ParseDict(c, common_pb2.GerritChange()) for c in gerrit_change_list ] except json_format.ParseError as ex: # pragma: no cover raise errors.InvalidInputError('Invalid gerrit_changes: %s' % ex) sbr.gerrit_changes.extend(gerrit_changes) if (not gerrit_changes and not sbr.builder.bucket.startswith('master.')): # pragma: no cover changes = parameters.get('changes') if isinstance(changes, list) and changes and not gitiles_commit: legacy_revision = changes[0].get('revision') if legacy_revision: raise errors.InvalidInputError( 'legacy revision without gitiles buildset tag') # Populate Gerrit project from patch_project property. # V2 API users will have to provide this. patch_project = props.get('patch_project') if len(sbr.gerrit_changes) == 1 and isinstance(patch_project, basestring): sbr.gerrit_changes[0].project = patch_project # Read PubSub callback. pubsub_callback_auth_token = None if put_request.pubsub_callback: pubsub_callback_auth_token = put_request.pubsub_callback.auth_token pubsub_callback_to_notification_config(put_request.pubsub_callback, sbr.notify) # Validate the resulting v2 request before continuing. with _wrap_validation_error(): validation.validate_schedule_build_request(sbr, legacy=True) return creation.BuildRequest( schedule_build_request=sbr, parameters=parameters, lease_expiration_date=lease_expiration_date, pubsub_callback_auth_token=pubsub_callback_auth_token, override_builder_cfg=_override_builder_cfg_func(parameters), )