def test_get_buckets_async(self): config.Bucket( id='master.tryserver.chromium.linux', project_id='chromium', revision='deadbeef', config_content=MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT).put() config.Bucket( id='master.tryserver.chromium.win', project_id='chromium', revision='deadbeef', config_content=MASTER_TRYSERVER_CHROMIUM_WIN_CONFIG_TEXT).put() actual = config.get_buckets_async().get_result() expected = [ project_config_pb2.Bucket( name='master.tryserver.chromium.linux', acls=[ project_config_pb2.Acl(role=project_config_pb2.Acl.READER, group='all'), project_config_pb2.Acl( role=project_config_pb2.Acl.SCHEDULER, group='tryjob-access'), ]), project_config_pb2.Bucket( name='master.tryserver.chromium.win', acls=[ project_config_pb2.Acl(role=project_config_pb2.Acl.READER, group='all'), project_config_pb2.Acl( role=project_config_pb2.Acl.SCHEDULER, group='tryjob-access'), ]), ] self.assertEqual(actual, expected)
def test_cron_update_buckets_change_reservation(self, get_project_configs): buildbucket_cfg = parse_cfg('''buckets{ name: "bucket" }''') get_project_configs.return_value = { 'bar': ('deadbeef', buildbucket_cfg, None), } config.Bucket( id='bucket', project_id='foo', revision='deadbeef', config_content='name: "bucket"', config_content_binary=text_to_binary('name: "bucket"'), ).put() config.cron_update_buckets() actual = config.Bucket.query().fetch() expected = [ config.Bucket( id='bucket', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, project_id='bar', revision='deadbeef', config_content='name: "bucket"\n', config_content_binary=text_to_binary('name: "bucket"\n'), ) ] self.assertEqual(actual, expected)
def test_cron_update_buckets_change_reservation(self): config.Bucket( id='bucket', project_id='foo', revision='deadbeef', config_content='name: "bucket"', ).put() buildbucket_cfg = project_config_pb2.BuildbucketCfg( buckets=[project_config_pb2.Bucket(name='bucket')]) self.mock(config_component, 'get_project_configs', mock.Mock()) config_component.get_project_configs.return_value = { 'bar': ('deadbeef', buildbucket_cfg), } config.cron_update_buckets() actual = config.Bucket.query().fetch() expected = [ config.Bucket( id='bucket', project_id='bar', revision='deadbeef', config_content='name: "bucket"\n', ) ] self.assertEqual(actual, expected)
def test_get_bucket_async(self): config.Bucket( id='master.tryserver.chromium.linux', project_id='chromium', revision='deadbeef', config_content=MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT), ).put() project, cfg = config.get_bucket_async( 'master.tryserver.chromium.linux').get_result() self.assertEqual(project, 'chromium') self.assertEqual( cfg, project_config_pb2.Bucket( name='master.tryserver.chromium.linux', acls=[ project_config_pb2.Acl(role=project_config_pb2.Acl.READER, group='all'), project_config_pb2.Acl( role=project_config_pb2.Acl.SCHEDULER, group='tryjob-access'), ]), ) self.assertIsNone( config.get_bucket_async('non.existing').get_result()[0])
def test_get_bucket(self, get_buildbucket_cfg_url): get_buildbucket_cfg_url.return_value = 'https://example.com/buildbucket.cfg' bucket_cfg = ''' name: "master.tryserver.chromium.linux" acls { role: READER identity: "anonymous:anonymous" } ''' config.Bucket( id='master.tryserver.chromium.linux', project_id='chromium', revision='deadbeef', config_content=bucket_cfg, config_content_binary=config_test.text_to_binary(bucket_cfg), ).put() req = { 'bucket': 'master.tryserver.chromium.linux', } res = self.call_api('get_bucket', req).json_body self.assertEqual( res, { 'name': 'master.tryserver.chromium.linux', 'project_id': 'chromium', 'config_file_content': bucket_cfg, 'config_file_url': 'https://example.com/buildbucket.cfg', 'config_file_rev': 'deadbeef', })
def test_validate_buildbucket_cfg_duplicate_names(self): config.Bucket(id='master.tryserver.v8', project_id='v8', revision='deadbeef', config_content=MASTER_TRYSERVER_V8_CONFIG_TEXT).put() self.cfg_validation_test( project_config_pb2.BuildbucketCfg(buckets=[ project_config_pb2.Bucket(name='a'), project_config_pb2.Bucket(name='a'), project_config_pb2.Bucket( name='master.tryserver.chromium.linux'), project_config_pb2.Bucket(name='master.tryserver.v8'), ]), [ errmsg('Bucket a: duplicate bucket name'), errmsg('Bucket master.tryserver.v8: ' 'this name is already reserved by another project'), ])
def test_validate_buildbucket_cfg_duplicate_names(self): config.Bucket( id='master.tryserver.v8', project_id='v8', revision='deadbeef', config_content=MASTER_TRYSERVER_V8_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_V8_CONFIG_TEXT), ).put() self.cfg_validation_test( parse_cfg(''' buckets { name: "a" } buckets { name: "a" } buckets { name: "master.tryserver.chromium.linux" } buckets { name: "master.tryserver.v8" } '''), [ errmsg('Bucket a: duplicate bucket name'), errmsg('Bucket master.tryserver.v8: ' 'this name is already reserved by another project'), ])
def test_get_builders(self): secret_cfg = 'name: "secret"' config.Bucket( id='secret', project_id='secret', revision='deadbeef', config_content=secret_cfg, config_content_binary=config_test.text_to_binary(secret_cfg), ).put() resp = self.call_api('get_builders').json_body self.assertEqual(resp, { 'buckets': [ { 'name': 'luci.chromium.try', 'builders': [ {'name': 'linux_chromium_rel_ng', 'category': 'Chromium'}, {'name': 'win_chromium_rel_ng', 'category': 'Chromium'}, ] } ] })
def test_cron_update_buckets_with_broken_configs(self, get_project_configs): bucket = config.Bucket( id='master.tryserver.chromium.linux', project_id='chromium', revision='deadbeef', config_content=MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT), ) bucket.put() get_project_configs.return_value = { 'chromium': ('new!', None, config_component.ConfigFormatError('broken!')), } config.cron_update_buckets() # We must not delete buckets defined in a project that currently have a # broken config. actual = bucket.key.get() self.assertEqual(bucket, actual)
def test_cron_update_buckets_with_existing(self, get_project_configs): chromium_buildbucket_cfg = parse_cfg(''' buckets { name: "master.tryserver.chromium.linux" acls { role: READER group: "all" } acls { role: SCHEDULER group: "tryjob-access" } } buckets { name: "master.tryserver.chromium.mac" acls { role: READER group: "all" } acls { role: SCHEDULER group: "tryjob-access" } } ''') v8_buildbucket_cfg = parse_cfg(''' buckets { name: "master.tryserver.chromium.linux" acls { role: WRITER group: "v8-team" } } buckets { name: "master.tryserver.v8" acls { role: WRITER group: "v8-team" } } ''') get_project_configs.return_value = { 'chromium': ('new!', chromium_buildbucket_cfg, None), 'v8': ('deadbeef', v8_buildbucket_cfg, None), } config.Bucket( id='master.tryserver.chromium.linux', project_id='chromium', revision='deadbeef', config_content=MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT), ).put() # Will not be updated. config.Bucket( id='master.tryserver.v8', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, project_id='v8', revision='deadbeef', config_content=MASTER_TRYSERVER_V8_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_V8_CONFIG_TEXT), ).put() # Will be deleted. config.Bucket( id='master.tryserver.chromium.win', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, project_id='chromium', revision='deadbeef', config_content=MASTER_TRYSERVER_CHROMIUM_WIN_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_CHROMIUM_WIN_CONFIG_TEXT), ).put() config.cron_update_buckets() actual = config.Bucket.query().fetch() actual = sorted(actual, key=lambda b: b.key.id()) expected = [ config.Bucket( id='master.tryserver.chromium.linux', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, project_id='chromium', revision='new!', config_content=MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT), ), config.Bucket( id='master.tryserver.chromium.mac', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, project_id='chromium', revision='new!', config_content=MASTER_TRYSERVER_CHROMIUM_MAC_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_CHROMIUM_MAC_CONFIG_TEXT), ), config.Bucket( id='master.tryserver.v8', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, project_id='v8', revision='deadbeef', config_content=MASTER_TRYSERVER_V8_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_V8_CONFIG_TEXT), ), ] self.assertEqual(actual, expected)
def test_cron_update_buckets(self, get_project_configs): chromium_buildbucket_cfg = parse_cfg(''' acl_sets { name: "public" acls { role: READER group: "all" } acls { role: READER group: "all" } } builder_mixins { name: "recipe-x" recipe { repository: "https://example.com" name: "x" } } buckets { name: "luci.chromium.try" acl_sets: "public" swarming { builder_defaults { dimensions: "pool:default" } builders { name: "release" mixins: "recipe-x" dimensions: "os:Linux" } } } buckets { name: "master.tryserver.chromium.linux" acl_sets: "public" acl_sets: "undefined_acl_set_will_cause_an_error_in_log_but_not_failure" acls { role: SCHEDULER group: "tryjob-access" } } buckets { name: "master.tryserver.chromium.win" acls { role: READER group: "all" } acls { role: SCHEDULER group: "tryjob-access" } } ''') v8_buildbucket_cfg = parse_cfg(''' buckets { name: "master.tryserver.v8" acls { role: WRITER group: "v8-team" } } ''') test_buildbucket_cfg = parse_cfg(''' buckets { name: "master.tryserver.test" acls { role: WRITER identity: "*****@*****.**" } } ''') get_project_configs.return_value = { 'chromium': ('deadbeef', chromium_buildbucket_cfg, None), 'v8': (None, v8_buildbucket_cfg, None), 'test': ('babe', test_buildbucket_cfg, None), } config.cron_update_buckets() actual = config.Bucket.query().fetch() actual = sorted(actual, key=lambda b: b.key) expected = [ config.Bucket( id='luci.chromium.try', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, project_id='chromium', revision='deadbeef', config_content=LUCI_CHROMIUM_TRY_CONFIG_TEXT, config_content_binary=text_to_binary( LUCI_CHROMIUM_TRY_CONFIG_TEXT), ), config.Bucket( id='master.tryserver.chromium.linux', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, project_id='chromium', revision='deadbeef', config_content=MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT), ), config.Bucket( id='master.tryserver.chromium.win', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, project_id='chromium', revision='deadbeef', config_content=MASTER_TRYSERVER_CHROMIUM_WIN_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_CHROMIUM_WIN_CONFIG_TEXT), ), config.Bucket( id='master.tryserver.test', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, project_id='test', revision='babe', config_content=MASTER_TRYSERVER_TEST_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_TEST_CONFIG_TEXT), ), config.Bucket( id='master.tryserver.v8', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, project_id='v8', revision='sha1:cfc761d7a953a72ddea8f3d4c9a28e69777ca22c', config_content=MASTER_TRYSERVER_V8_CONFIG_TEXT, config_content_binary=text_to_binary( MASTER_TRYSERVER_V8_CONFIG_TEXT), ), ] self.assertEqual(actual, expected)
def test_cron_update_buckets_with_existing(self, get_project_configs): chromium_buildbucket_cfg = parse_cfg(''' buckets { name: "master.tryserver.chromium.linux" acls { role: READER group: "all" } acls { role: SCHEDULER group: "tryjob-access" } } buckets { name: "master.tryserver.chromium.mac" acls { role: READER group: "all" } acls { role: SCHEDULER group: "tryjob-access" } } ''') v8_buildbucket_cfg = parse_cfg(''' buckets { name: "master.tryserver.v8" acls { role: WRITER group: "v8-team" } } ''') get_project_configs.return_value = { 'chromium': ('new!', chromium_buildbucket_cfg, None), 'v8': ('deadbeef', v8_buildbucket_cfg, None), } config.put_bucket('chromium', 'deadbeef', MASTER_TRYSERVER_CHROMIUM_LINUX) # Will not be updated. config.put_bucket('v8', 'deadbeef', MASTER_TRYSERVER_V8) # Will be deleted. config.put_bucket('chromium', 'deadbeef', MASTER_TRYSERVER_CHROMIUM_WIN) config.cron_update_buckets() actual = config.Bucket.query().fetch() actual = sorted(actual, key=lambda b: b.key) expected = [ config.Bucket( parent=ndb.Key(config.Project, 'chromium'), id='master.tryserver.chromium.linux', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, revision='new!', config=MASTER_TRYSERVER_CHROMIUM_LINUX, ), config.Bucket( parent=ndb.Key(config.Project, 'chromium'), id='master.tryserver.chromium.mac', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, revision='new!', config=MASTER_TRYSERVER_CHROMIUM_MAC, ), config.Bucket( parent=ndb.Key(config.Project, 'v8'), id='master.tryserver.v8', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, revision='deadbeef', config=MASTER_TRYSERVER_V8, ), ] self.assertEqual(actual, expected)
def test_cron_update_buckets(self, get_project_configs): chromium_buildbucket_cfg = parse_cfg(''' acl_sets { name: "public" acls { role: READER group: "all" } # Test deduplication. acls { group: "all" } } builder_mixins { name: "recipe-x" recipe { cipd_package: "infra/recipe_bundle" cipd_version: "refs/heads/master" name: "x" } } buckets { name: "try" acl_sets: "public" acls { role: SCHEDULER identity: "*****@*****.**" } swarming { hostname: "swarming.example.com" task_template_canary_percentage { value: 10 } builder_defaults { mixins: "recipe-x" } builders { name: "linux" dimensions: "os:Linux" } } } buckets { name: "master.tryserver.chromium.linux" acl_sets: "public" acl_sets: "undefined_acl_set_will_log_an_error_but_not_failure" acls { role: SCHEDULER group: "tryjob-access" } } buckets { name: "master.tryserver.chromium.win" acls { role: READER group: "all" } acls { role: SCHEDULER group: "tryjob-access" } } ''') dart_buildbucket_cfg = parse_cfg(''' buckets { name: "try" swarming { builder_defaults { dimensions: "pool:Dart.LUCI" recipe { cipd_package: "infra/recipe_bundle" cipd_version: "refs/heads/master" name: "x" } } builders { name: "linux" } } } ''') v8_buildbucket_cfg = parse_cfg(''' buckets { name: "master.tryserver.v8" acls { role: WRITER group: "v8-team" } } ''') get_project_configs.return_value = { 'chromium': ('deadbeef', chromium_buildbucket_cfg, None), 'dart': ('deadbeef', dart_buildbucket_cfg, None), 'v8': (None, v8_buildbucket_cfg, None), } config.cron_update_buckets() actual = config.Bucket.query().fetch() actual = sorted(actual, key=lambda b: b.key) expected = [ config.Bucket( parent=ndb.Key(config.Project, 'chromium'), id='master.tryserver.chromium.linux', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, revision='deadbeef', config=MASTER_TRYSERVER_CHROMIUM_LINUX, ), config.Bucket( parent=ndb.Key(config.Project, 'chromium'), id='master.tryserver.chromium.win', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, revision='deadbeef', config=MASTER_TRYSERVER_CHROMIUM_WIN, ), config.Bucket( parent=ndb.Key(config.Project, 'chromium'), id='try', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, revision='deadbeef', config=short_bucket_cfg(LUCI_CHROMIUM_TRY), ), config.Bucket( parent=ndb.Key(config.Project, 'dart'), id='try', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, revision='deadbeef', config=short_bucket_cfg(LUCI_DART_TRY), ), config.Bucket( parent=ndb.Key(config.Project, 'v8'), id='master.tryserver.v8', entity_schema_version=config.CURRENT_BUCKET_SCHEMA_VERSION, revision='sha1:cfc761d7a953a72ddea8f3d4c9a28e69777ca22c', config=MASTER_TRYSERVER_V8), ] self.assertEqual(actual, expected)
def setUp(self): super(SwarmbucketApiTest, self).setUp() self.patch( 'components.utils.utcnow', autospec=True, return_value=datetime.datetime(2015, 11, 30)) auth_testing.reset_local_state() auth.bootstrap_group('all', [auth.Anonymous]) chromium_cfg = ''' name: "luci.chromium.try" acls { role: SCHEDULER group: "all" } swarming { hostname: "swarming.example.com" builders { name: "linux_chromium_rel_ng" category: "Chromium" build_numbers: true recipe { repository: "https://example.com" name: "presubmit" } } builders { name: "win_chromium_rel_ng" category: "Chromium" } } ''' config.Bucket( id='luci.chromium.try', project_id='chromium', revision='deadbeef', config_content=chromium_cfg, config_content_binary=config_test.text_to_binary(chromium_cfg), ).put() v8_cfg = ''' name: "luci.v8.try" acls { role: READER group: "all" } ''' config.Bucket( id='luci.v8.try', project_id='v8', revision='deadbeef', config_content=v8_cfg, config_content_binary=config_test.text_to_binary(v8_cfg), ).put() self.task_template = { 'name': 'buildbucket:${bucket}:${builder}', 'priority': '100', 'expiration_secs': '3600', 'properties': { 'execution_timeout_secs': '3600', 'extra_args': [ 'cook', '-repository', '${repository}', '-revision', '${revision}', '-recipe', '${recipe}', '-properties', '${properties_json}', '-logdog-project', '${project}', ], 'caches': [ {'path': '${cache_dir}/builder', 'name': 'builder_${builder_hash}'}, ], 'cipd_input': { 'packages': [ { 'package_name': 'infra/test/bar/${os_ver}', 'path': '.', 'version': 'latest', }, { 'package_name': 'infra/test/foo/${platform}', 'path': 'third_party', 'version': 'stable', }, ], }, } } self.patch( 'swarming.swarming.get_task_template_async', return_value=future(('rev', self.task_template, False)))
def test_cron_update_buckets_with_existing(self): config.Bucket( id='master.tryserver.chromium.linux', project_id='chromium', revision='deadbeef', config_content=MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT, ).put() # Will not be updated. config.Bucket( id='master.tryserver.v8', project_id='v8', revision='deadbeef', config_content=MASTER_TRYSERVER_V8_CONFIG_TEXT, ).put() # Will be deleted. config.Bucket( id='master.tryserver.chromium.win', project_id='chromium', revision='deadbeef', config_content=MASTER_TRYSERVER_CHROMIUM_WIN_CONFIG_TEXT, ).put() chromium_buildbucket_cfg = project_config_pb2.BuildbucketCfg(buckets=[ project_config_pb2.Bucket( name='master.tryserver.chromium.linux', acls=[ project_config_pb2.Acl(role=project_config_pb2.Acl.READER, group='all'), project_config_pb2.Acl( role=project_config_pb2.Acl.SCHEDULER, group='tryjob-access'), ], ), # Will be added. project_config_pb2.Bucket( name='master.tryserver.chromium.mac', acls=[ project_config_pb2.Acl(role=project_config_pb2.Acl.READER, group='all'), project_config_pb2.Acl( role=project_config_pb2.Acl.SCHEDULER, group='tryjob-access'), ], ), ]) v8_buildbucket_cfg = project_config_pb2.BuildbucketCfg( buckets=[ # Reservation will fail. project_config_pb2.Bucket( name='master.tryserver.chromium.linux', acls=[ project_config_pb2.Acl( role=project_config_pb2.Acl.WRITER, group='v8-team') ], ), # Will not be updated. project_config_pb2.Bucket( name='master.tryserver.v8', acls=[ project_config_pb2.Acl( role=project_config_pb2.Acl.WRITER, group='v8-team') ], ), ], ) self.mock(config_component, 'get_project_configs', mock.Mock()) config_component.get_project_configs.return_value = { 'chromium': ('new!', chromium_buildbucket_cfg), 'v8': ('deadbeef', v8_buildbucket_cfg), } config.cron_update_buckets() actual = config.Bucket.query().fetch() actual = sorted(actual, key=lambda b: b.key.id()) expected = [ config.Bucket( id='master.tryserver.chromium.linux', project_id='chromium', revision='new!', config_content=MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT, ), config.Bucket( id='master.tryserver.chromium.mac', project_id='chromium', revision='new!', config_content=MASTER_TRYSERVER_CHROMIUM_MAC_CONFIG_TEXT, ), config.Bucket( id='master.tryserver.v8', project_id='v8', revision='deadbeef', config_content=MASTER_TRYSERVER_V8_CONFIG_TEXT, ), ] self.assertEqual(actual, expected)
def test_cron_update_buckets(self): chromium_buildbucket_cfg = project_config_pb2.BuildbucketCfg(buckets=[ project_config_pb2.Bucket( name='master.tryserver.chromium.linux', acls=[ project_config_pb2.Acl(role=project_config_pb2.Acl.READER, group='all'), project_config_pb2.Acl( role=project_config_pb2.Acl.SCHEDULER, group='tryjob-access'), ], ), project_config_pb2.Bucket( name='master.tryserver.chromium.win', acls=[ project_config_pb2.Acl(role=project_config_pb2.Acl.READER, group='all'), project_config_pb2.Acl( role=project_config_pb2.Acl.SCHEDULER, group='tryjob-access'), ], ), ]) v8_buildbucket_cfg = project_config_pb2.BuildbucketCfg(buckets=[ project_config_pb2.Bucket( name='master.tryserver.v8', acls=[ project_config_pb2.Acl(role=project_config_pb2.Acl.WRITER, group='v8-team') ], ), ]) test_buildbucket_cfg = project_config_pb2.BuildbucketCfg(buckets=[ project_config_pb2.Bucket( name='master.tryserver.test', acls=[ project_config_pb2.Acl(role=project_config_pb2.Acl.WRITER, identity='*****@*****.**') ], ), ]) self.mock(config_component, 'get_project_configs', mock.Mock()) config_component.get_project_configs.return_value = { 'chromium': ('deadbeef', chromium_buildbucket_cfg), 'v8': (None, v8_buildbucket_cfg), 'test': ('babe', test_buildbucket_cfg), } config.cron_update_buckets() actual = config.Bucket.query().fetch() actual = sorted(actual, key=lambda b: b.key) expected = [ config.Bucket( id='master.tryserver.chromium.linux', project_id='chromium', revision='deadbeef', config_content=MASTER_TRYSERVER_CHROMIUM_LINUX_CONFIG_TEXT, ), config.Bucket( id='master.tryserver.chromium.win', project_id='chromium', revision='deadbeef', config_content=MASTER_TRYSERVER_CHROMIUM_WIN_CONFIG_TEXT, ), config.Bucket(id='master.tryserver.test', project_id='test', revision='babe', config_content=MASTER_TRYSERVER_TEST_CONFIG_TEXT), config.Bucket( id='master.tryserver.v8', project_id='v8', revision='sha1:cfc761d7a953a72ddea8f3d4c9a28e69777ca22c', config_content=MASTER_TRYSERVER_V8_CONFIG_TEXT, ), ] self.assertEqual(actual, expected)