def test_bad_page_size(self): msg = rpc_pb2.SearchBuildsRequest( predicate=rpc_pb2.BuildPredicate(builder=build_pb2.BuilderID( project='chromium', bucket='try', builder='linux-rel'), ), page_size=-1, ) self.assert_invalid(msg, r'page_size: must be not be negative')
def test_valid(self): msg = rpc_pb2.BuildPredicate(builder=build_pb2.BuilderID( project='chromium', bucket='try', builder='linux-rel', )) self.assert_valid(msg)
def test_add(self): builder_id = build_pb2.BuilderID( project='chromium', bucket='try', builder='linux', ) build = self.add(dict(builder=builder_id)) self.assertIsNotNone(build.key) self.assertIsNotNone(build.key.id()) build = build.key.get() self.assertEqual(build.proto.id, build.key.id()) self.assertEqual(build.proto.builder, builder_id) self.assertEqual(build.proto.created_by, auth.get_current_identity().to_bytes()) self.assertEqual(build.proto.builder.project, 'chromium') self.assertEqual(build.proto.builder.bucket, 'try') self.assertEqual(build.proto.builder.builder, 'linux') self.assertEqual(build.created_by, auth.get_current_identity()) infra = model.BuildInfra.key_for(build.key).get().parse() self.assertEqual(infra.logdog.hostname, 'logs.example.com') self.assertIn( build_pb2.BuildInfra.Swarming.CacheEntry( path='git', name='git', wait_for_warm_cache=dict()), infra.swarming.caches, )
def test_invalid_bucket(self): msg = build_pb2.BuilderID( project='chromium', bucket='a b', builder='linux-rel' ) self.assert_invalid( msg, r'bucket: Bucket name "a b" does not match regular' )
def test_dimensions(self): msg = rpc_pb2.ScheduleBuildRequest( builder=build_pb2.BuilderID( project='chromium', bucket='try', builder='linux-rel' ), dimensions=[dict()] ) self.assert_invalid(msg, r'dimensions\[0\]\.key: required')
def test_tags(self): msg = rpc_pb2.ScheduleBuildRequest( builder=build_pb2.BuilderID( project='chromium', bucket='try', builder='linux-rel' ), tags=[dict()] ) self.assert_invalid(msg, r'tags: Invalid tag ":": starts with ":"')
def test_priority(self): msg = rpc_pb2.ScheduleBuildRequest( builder=build_pb2.BuilderID(project='chromium', bucket='try', builder='linux-rel'), priority=256, ) self.assert_invalid(msg, r'priority: must be in \[0, 255\]')
def test_not_found_by_number(self): builder_id = build_pb2.BuilderID(project='chromium', bucket='try', builder='linux-try') req = rpc_pb2.GetBuildRequest(builder=builder_id, build_number=2) self.call(self.api.GetBuild, req, expected_code=prpc.StatusCode.NOT_FOUND)
def test_cipd_version_invalid(self): msg = rpc_pb2.ScheduleBuildRequest( builder=build_pb2.BuilderID(project='chromium', bucket='try', builder='linux-rel'), exe=dict(cipd_version=':'), ) self.assert_invalid(msg, r'exe.cipd_version: invalid version ":"')
def test_cipd_package(self): msg = rpc_pb2.ScheduleBuildRequest( builder=build_pb2.BuilderID(project='chromium', bucket='try', builder='linux-rel'), exe=dict(cipd_package='something'), ) self.assert_invalid(msg, r'exe.cipd_package: disallowed')
def test_invalid_tags(self): msg = rpc_pb2.BuildPredicate( builder=build_pb2.BuilderID(project='chromium', bucket='try', builder='linux-rel'), tags=[common_pb2.StringPair(key='', value='')], ) self.assert_invalid(msg, r'tags: Invalid tag')
def test_cipd_version_latest(self): msg = rpc_pb2.ScheduleBuildRequest( builder=build_pb2.BuilderID(project='chromium', bucket='try', builder='linux-rel'), exe=dict(cipd_version='latest'), ) self.assert_valid(msg)
def test_notify_pubsub_topic(self): msg = rpc_pb2.ScheduleBuildRequest( builder=build_pb2.BuilderID(project='chromium', bucket='try', builder='linux-rel'), notify=notification_pb2.NotificationConfig(), ) self.assert_invalid(msg, r'notify.pubsub_topic: required')
def test_valid_number(self): msg = rpc_pb2.GetBuildRequest( builder=build_pb2.BuilderID(project='chromium', bucket='try', builder='linux-rel'), build_number=1, ) self.assert_valid(msg)
def test_gitiles_commit_incomplete(self): msg = rpc_pb2.ScheduleBuildRequest( builder=build_pb2.BuilderID(project='chromium', bucket='try', builder='linux-rel'), gitiles_commit=common_pb2.GitilesCommit(host='gerrit.example.com', project='project'), ) self.assert_invalid(msg, r'gitiles_commit\.ref: required')
def test_v1_bucket(self): msg = build_pb2.BuilderID(project='chromium', bucket='luci.chromium.ci', builder='linux-rel') self.assert_invalid( msg, (r'bucket: invalid usage of v1 bucket format in v2 API; ' 'use u\'ci\' instead'), )
def test_non_existing_builder(self): builder_id = build_pb2.BuilderID( project='chromium', bucket='try', builder='non-existing', ) req = self.build_request(dict(builder=builder_id)) (_, ex), = creation.add_many_async([req]).get_result() self.assertIsInstance(ex, errors.BuilderNotFoundError)
def test_builder_matches(self, regex, regex_exclude, expected): predicate = service_config_pb2.BuilderPredicate( regex=regex, regex_exclude=regex_exclude) builder_id = build_pb2.BuilderID( project='chromium', bucket='try', builder='linux-rel', ) actual = swarming._builder_matches(builder_id, predicate) self.assertEqual(expected, actual)
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_notify_user_data(self): msg = rpc_pb2.ScheduleBuildRequest( builder=build_pb2.BuilderID(project='chromium', bucket='try', builder='linux-rel'), notify=notification_pb2.NotificationConfig( pubsub_topic='x', user_data='a' * 5000, ), ) self.assert_invalid(msg, r'notify.user_data: must be <= 4096 bytes')
def test_reserved_properties(self): properties = [ {'buildbucket': 1}, {'buildername': 1}, {'$recipe_engine/runtime': {'is_luci': 1}}, {'$recipe_engine/runtime': {'is_experimental': 1}}, ] for p in properties: msg = rpc_pb2.ScheduleBuildRequest( builder=build_pb2.BuilderID( project='chromium', bucket='try', builder='linux-rel' ), ) msg.properties.update(p) self.assert_invalid(msg, r'property .+ is reserved')
def test_by_number(self, search_async): builder_id = build_pb2.BuilderID(project='chromium', bucket='try', builder='linux-try') build = test_util.build(id=1, builder=builder_id, number=2) search_async.return_value = future(([build], None)) req = rpc_pb2.GetBuildRequest(builder=builder_id, build_number=2) res = self.call(self.api.GetBuild, req) self.assertEqual(res.id, 1) self.assertEqual(res.builder, builder_id) self.assertEqual(res.number, 2) search_async.assert_called_once_with( search.Query( bucket_ids=['chromium/try'], tags=['build_address:luci.chromium.try/linux-try/2'], include_experimental=True, ))
def test_legacy_kitchen(self): build = self._test_build( builder=build_pb2.BuilderID( project='chromium', bucket='try', builder='linux_kitchen' ), ) actual = self.compute_task_def(build) self.assertEqual([ "kitchen${EXECUTABLE_SUFFIX}", 'cook', '-buildbucket-hostname', 'cr-buildbucket.appspot.com', '-buildbucket-build-id', '9027773186396127232', '-call-update-build', '-build-url', 'https://milo.example.com/b/9027773186396127232', '-luci-system-account', 'system', '-recipe', 'presubmit', '-cache-dir', 'cache', '-checkout-dir', 'kitchen-checkout', '-temp-dir', 'tmp', '-properties', api_common.properties_to_json( swarming._compute_legacy_properties(build) ), '-logdog-annotation-url', 'logdog://logdog.example.com/chromium/bb/+/annotations', '-known-gerrit-host', 'chromium-review.googlesource.com' ], test_util.ununicode(actual['task_slices'][0]['properties']['command']))
def set_next_build_number(self, request): """Sets the build number that will be used for the next build.""" bucket_id = api.convert_bucket(request.bucket) if not user.can_set_next_number_async(bucket_id).get_result(): raise endpoints.ForbiddenException('access denied') _, bucket = config.get_bucket(bucket_id) if not any(b.name == request.builder for b in bucket.swarming.builders): raise endpoints.BadRequestException( 'builder "%s" not found in bucket "%s"' % (request.builder, bucket_id)) project, bucket = config.parse_bucket_id(bucket_id) builder_id = build_pb2.BuilderID(project=project, bucket=bucket, builder=request.builder) seq_name = sequence.builder_seq_name(builder_id) try: sequence.set_next(seq_name, request.next_number) except ValueError as ex: raise endpoints.BadRequestException(str(ex)) return message_types.VoidMessage()
def test_incomplete_builder(self): msg = rpc_pb2.ScheduleBuildRequest(builder=build_pb2.BuilderID( project='chromium', bucket='try'), ) self.assert_invalid(msg, 'builder.builder: required')
def test_overall(self): self.patch('components.auth.get_current_identity', autospec=True, return_value=auth.Identity('user', '*****@*****.**')) build = self._test_build( id=1, number=1, scheduling_timeout=dict(seconds=3600), execution_timeout=dict(seconds=3600), builder=build_pb2.BuilderID(project='chromium', bucket='try', builder='linux'), exe=dict( cipd_package='infra/recipe_bundle', cipd_version='refs/heads/master', ), input=dict( properties=bbutil.dict_to_struct({ 'a': 'b', 'recipe': 'recipe', }), gerrit_changes=[ dict( host='chromium-review.googlesource.com', project='chromium/src', change=1234, patchset=5, ), ], ), infra=dict(swarming=dict( task_service_account='*****@*****.**', priority=108, task_dimensions=[ dict(key='cores', value='8'), dict(key='os', value='Ubuntu'), dict(key='pool', value='Chrome'), ], caches=[ dict(path='a', name='1'), ], ), ), ) actual = self.prepare_task_def(build) expected_swarming_props_def = { 'env': [{ 'key': 'BUILDBUCKET_EXPERIMENTAL', 'value': 'FALSE', }], 'execution_timeout_secs': '3600', 'extra_args': [ 'cook', '-recipe', 'recipe', '-properties', # Properties are tested by test_properties() above. swarming._setup_recipes(build)[1]['properties_json'], '-logdog-project', 'chromium', ], 'dimensions': [ { 'key': 'cores', 'value': '8' }, { 'key': 'os', 'value': 'Ubuntu' }, { 'key': 'pool', 'value': 'Chrome' }, ], 'caches': [{ 'path': 'cache/a', 'name': '1' }], 'cipd_input': { 'packages': [ { 'package_name': 'infra/tools/luci_runner', 'path': '.', 'version': 'luci-runner-version', }, { 'package_name': 'infra/tools/kitchen', 'path': '.', 'version': 'kitchen-version', }, { 'package_name': 'infra/recipe_bundle', 'path': 'kitchen-checkout', 'version': 'refs/heads/master', }, { 'package_name': 'infra/tools/git', 'path': swarming.USER_PACKAGE_DIR, 'version': 'git-version', }, { 'package_name': 'infra/cpython/python', 'path': '%s/python' % swarming.USER_PACKAGE_DIR, 'version': 'py-version', }, ], }, } expected = { 'name': 'bb-1-chromium-linux', 'priority': '108', 'tags': [ 'build_address:luci.chromium.try/linux/1', 'buildbucket_bucket:chromium/try', 'buildbucket_build_id:1', 'buildbucket_hostname:cr-buildbucket.appspot.com', 'buildbucket_template_canary:0', 'buildbucket_template_revision:template_rev', 'builder:linux', 'buildset:1', ('log_location:logdog://luci-logdog-dev.appspot.com/chromium/' 'buildbucket/cr-buildbucket.appspot.com/1/+/annotations'), 'luci_project:chromium', 'recipe_name:recipe', 'recipe_package:infra/recipe_bundle', ], 'pool_task_template': 'CANARY_NEVER', 'task_slices': [{ 'expiration_secs': '3600', 'properties': expected_swarming_props_def, 'wait_for_capacity': False, }], 'pubsub_topic': 'projects/testbed-test/topics/swarming', 'pubsub_userdata': json.dumps( { 'created_ts': 1448841600000000, 'swarming_hostname': 'swarming.example.com', 'build_id': 1L, }, sort_keys=True), 'service_account': '*****@*****.**', }
def test_properties(self): self.patch('components.auth.get_current_identity', autospec=True, return_value=auth.Identity('user', '*****@*****.**')) build = self._test_build( id=1, number=1, builder=build_pb2.BuilderID(project='chromium', bucket='try', builder='linux'), exe=dict( cipd_package='infra/recipe_bundle', cipd_version='refs/heads/master', ), input=dict( properties=bbutil.dict_to_struct({ 'a': 'b', 'recipe': 'recipe', }), gerrit_changes=[ dict( host='chromium-review.googlesource.com', project='chromium/src', change=1234, patchset=5, ), ], ), infra=dict(swarming=dict( task_service_account='*****@*****.**', priority=108, task_dimensions=[ dict(key='cores', value='8'), dict(key='os', value='Ubuntu'), dict(key='pool', value='Chrome'), ], ), ), ) _, extra_task_template_params = swarming._setup_recipes(build) actual = json.loads(extra_task_template_params['properties_json']) expected = { 'a': 'b', 'buildbucket': { 'hostname': 'cr-buildbucket.appspot.com', 'build': { 'project': 'chromium', 'bucket': 'luci.chromium.try', 'created_by': 'anonymous:anonymous', 'created_ts': 1448841600000000, 'id': '1', 'tags': [ 'build_address:luci.chromium.try/linux/1', 'builder:linux', 'buildset:1', ], }, }, 'buildername': 'linux', 'buildnumber': 1, 'recipe': 'recipe', 'repository': 'https://chromium.googlesource.com/chromium/src', '$recipe_engine/buildbucket': { 'hostname': 'cr-buildbucket.appspot.com', 'build': { 'id': '1', 'builder': { 'project': 'chromium', 'bucket': 'try', 'builder': 'linux', }, 'number': 1, 'tags': [{ 'value': '1', 'key': 'buildset' }], 'exe': { 'cipdPackage': 'infra/recipe_bundle', 'cipdVersion': 'refs/heads/master', }, 'input': { 'gerritChanges': [{ 'host': 'chromium-review.googlesource.com', 'project': 'chromium/src', 'change': '1234', 'patchset': '5', }], }, 'infra': { 'buildbucket': {}, 'swarming': { 'hostname': 'swarming.example.com', 'taskId': 'deadbeef', 'taskServiceAccount': '*****@*****.**', 'priority': 108, 'taskDimensions': [ { 'key': 'cores', 'value': '8' }, { 'key': 'os', 'value': 'Ubuntu' }, { 'key': 'pool', 'value': 'Chrome' }, ], }, 'logdog': { 'hostname': 'logdog.example.com', 'project': 'chromium', 'prefix': 'bb', }, }, 'createdBy': 'anonymous:anonymous', 'createTime': '2015-11-30T00:00:00Z', }, }, '$recipe_engine/runtime': { 'is_experimental': False, 'is_luci': True, }, } self.assertEqual(test_util.ununicode(actual), expected)
def test_builder_empty(self): msg = rpc_pb2.BuildPredicate(builder=build_pb2.BuilderID()) self.assert_invalid(msg, r'builder\.project: required')
def test_builder_project_builder(self): msg = rpc_pb2.BuildPredicate(builder=build_pb2.BuilderID( project='chromium', builder='linux-rel')) self.assert_invalid(msg, 'builder.bucket: required by .builder field')
def test_builder_project_bucket(self): msg = rpc_pb2.BuildPredicate( builder=build_pb2.BuilderID(project='chromium', bucket='try')) self.assert_valid(msg)