def validator_test(self, cfg, messages): ctx = validation.Context() bot_groups_config.validate_settings(cfg, ctx) self.assertEquals(ctx.result().messages, [ validation.Message(severity=logging.ERROR, text=m) for m in messages ])
def validator_test(self, validator, cfg, messages): ctx = validation.Context() validator(cfg, ctx) self.assertEquals(ctx.result().messages, [ validation.Message(severity=logging.ERROR, text=m) for m in messages ])
def validator_test(self, bm, messages): ctx = validation.Context() actual = pools_config._resolve_bot_monitoring(ctx, bm) self.assertEqual(ctx.result().messages, [ validation.Message(severity=logging.ERROR, text=m) for m in messages ]) return actual
def validator_test(self, cfg, messages): ctx = validation.Context() self.assertIsInstance(cfg, config_pb2.SettingsCfg) config._validate_settings(cfg, ctx) self.assertEquals(ctx.result().messages, [ validation.Message(severity=logging.ERROR, text=m) for m in messages ])
def test_validate_security_config_bad_regexp(self): ctx = validation.Context() config.validate_security_config( security_config_pb2.SecurityConfig(internal_service_regexp=['???' ], ), ctx) self.assertEqual(ctx.result().messages, [ validation.Message( "internal_service_regexp: bad regexp '???' - nothing to repeat", 40), ])
def validate_buildbucket_cfg(cfg, ctx): import swarmingcfg acl_set_names = set() for i, acl_set in enumerate(cfg.acl_sets): with ctx.prefix('ACL set #%d (%s): ', i + 1, acl_set.name): if not acl_set.name: ctx.error('name is unspecified') elif not ACL_SET_NAME_RE.match(acl_set.name): ctx.error('invalid name "%s" does not match regex %r', acl_set.name, ACL_SET_NAME_RE.pattern) elif acl_set.name in acl_set_names: ctx.error('duplicate name "%s"', acl_set.name) acl_set_names.add(acl_set.name) validate_access_list(acl_set.acls, ctx) mixin_ctx = validation.Context( # pragma: no cover on_message=lambda msg: ctx.msg(msg.severity, '%s', msg.text)) swarmingcfg.validate_builder_mixins(cfg.builder_mixins, mixin_ctx) mixins_are_valid = not mixin_ctx.result().has_errors mixin_by_name = {m.name: m for m in cfg.builder_mixins} bucket_names = set() for i, bucket in enumerate(cfg.buckets): with ctx.prefix('Bucket %s: ', bucket.name or ('#%d' % (i + 1))): try: errors.validate_bucket_name(bucket.name, project_id=ctx.project_id) except errors.InvalidInputError as ex: ctx.error('invalid name: %s', ex.message) else: if bucket.name in bucket_names: ctx.error('duplicate bucket name') else: bucket_names.add(bucket.name) if i > 0 and bucket.name < cfg.buckets[i - 1].name: ctx.warning('out of order') validate_access_list(bucket.acls, ctx) for name in bucket.acl_sets: if name not in acl_set_names: ctx.error( 'undefined ACL set "%s". ' 'It must be defined in the same file', name) if bucket.HasField('swarming'): # pragma: no cover with ctx.prefix('swarming: '): swarmingcfg.validate_project_cfg(bucket.swarming, mixin_by_name, mixins_are_valid, ctx)
def validate_config(self, request): logging.debug("requester: %s, config_set: %s, paths: %s", auth.get_current_identity().to_bytes(), request.config_set, [f.path for f in request.files]) if not request.config_set: raise endpoints.BadRequestException('Must specify a config_set') if not request.files: raise endpoints.BadRequestException( 'Must specify files to validate') for f in request.files: if not f.path: raise endpoints.BadRequestException( 'Must specify the path of a file') if not acl.has_validation_access(): logging.warning('%s does not have validation access', auth.get_current_identity().to_bytes()) raise endpoints.ForbiddenException() if not can_read_config_set(request.config_set): logging.warning('%s does not have access to %s', auth.get_current_identity().to_bytes(), request.config_set) raise endpoints.ForbiddenException() futs = [] for f in request.files: ctx = cfg_validation.Context() with ctx.prefix(f.path + ': '): futs.append( validation.validate_config_async(request.config_set, f.path, f.content, ctx=ctx)) ndb.Future.wait_all(futs) # return the severities and the texts msgs = [] for f, fut in zip(request.files, futs): for msg in fut.get_result().messages: msgs.append( cfg_endpoint.ValidationMessage( path=f.path, severity=common.Severity.lookup_by_number( msg.severity), text=msg.text)) return self.ValidateConfigResponseMessage(messages=msgs)
def test_context_metadata(self): ctx = validation.Context() ctx.config_set = 'services/foo' self.assertEqual(ctx.service_id, 'foo') self.assertEqual(ctx.project_id, None) self.assertEqual(ctx.ref, None) ctx.config_set = 'projects/foo' self.assertEqual(ctx.service_id, None) self.assertEqual(ctx.project_id, 'foo') self.assertEqual(ctx.ref, None) ctx.config_set = 'projects/foo/refs/a' self.assertEqual(ctx.service_id, None) self.assertEqual(ctx.project_id, 'foo') self.assertEqual(ctx.ref, 'refs/a')
def validate_config_async(config_set, path, content, ctx=None): """Validates a config against built-in and external validators. External validators are defined in validation.cfg, see proto/service_config.proto. Returns: components.config.validation_context.Result. """ ctx = ctx or validation.Context() # Check the config against built-in validators, # defined using validation.self_rule. validation.validate(config_set, path, content, ctx=ctx) all_services = yield services.get_services_async() futures = [] for service in all_services: futures.append( _validate_by_service_async(service, config_set, path, content, ctx)) yield futures raise ndb.Return(ctx.result())
def is_valid(**fields): ctx = validation.Context() config.validate_settings_cfg(config_pb2.SettingsCfg(**fields), ctx) return not ctx.messages
def test_notify_gitiles_rejection(self): ctx = validation.Context() ctx.error('err') ctx.warning('warn') base = gitiles.Location.parse('https://example.com/x/+/infra/config') new_rev = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa' new_loc = base._replace(treeish=new_rev) old_rev = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb' old_loc = base._replace(treeish=old_rev) self.mock(notifications, '_send', mock.Mock()) john = gitiles.Contribution('John', '*****@*****.**', datetime.datetime(2015, 1, 1)) commit = gitiles.Commit(sha=new_rev, tree='badcoffee', parents=[], author=john, committer=john, message='New config', tree_diff=None) self.mock(gitiles, 'get_log_async', mock.Mock(return_value=ndb.Future())) gitiles.get_log_async.return_value.set_result( gitiles.Log(commits=[commit], next_cursor=None)) self.mock(template, 'render', mock.Mock()) self.mock(auth, 'list_group', mock.Mock()) auth.list_group.return_value = auth.GroupListing([ auth.Identity('user', '*****@*****.**'), auth.Identity('service', 'foo'), ], [], []) # Notify. notifications.notify_gitiles_rejection('projects/x', new_loc, ctx.result()) self.assertTrue(notifications._send.called) email = notifications._send.call_args[0][0] self.assertEqual( email.sender, 'sample-app.appspot.com <*****@*****.**>') self.assertEqual(email.subject, 'Config revision aaaaaaa is rejected') self.assertEqual(email.to, ['John <*****@*****.**>']) self.assertEqual(email.cc, {'*****@*****.**'}) template.render.assert_called_with( 'templates/validation_notification.html', { 'author': 'John', 'messages': [{ 'severity': 'ERROR', 'text': 'err' }, { 'severity': 'WARNING', 'text': 'warn' }], 'rev_link': new_loc, 'rev_hash': 'aaaaaaa', 'rev_repo': 'x', 'cur_rev_hash': None, 'cur_rev_link': None, }) # Do not send second time. notifications._send.reset_mock() notifications.notify_gitiles_rejection('projects/x', new_loc, ctx.result()) self.assertFalse(notifications._send.called) # Now with config set. ndb.Key(notifications.Notification, str(new_loc)).delete() storage.ConfigSet(id='projects/x', latest_revision=old_rev, latest_revision_url=str(old_loc), location=str(base)).put() template.render.reset_mock() notifications.notify_gitiles_rejection('projects/x', new_loc, ctx.result()) template.render.assert_called_with( 'templates/validation_notification.html', { 'author': 'John', 'messages': [{ 'severity': 'ERROR', 'text': 'err' }, { 'severity': 'WARNING', 'text': 'warn' }], 'rev_link': new_loc, 'rev_hash': 'aaaaaaa', 'rev_repo': 'x', 'cur_rev_hash': 'bbbbbbb', 'cur_rev_link': old_loc, })
def setUp(self): super(TaskTemplateBaseTest, self).setUp() self._canary_dice_roll = 5000 # 50% self._randint_normal = random.randint random.randint = lambda *_: self._canary_dice_roll self.ctx = validation.Context()
def setUp(self): self.ctx = validation.Context() self.doc = directory_occlusion.Checker()
def test_validate_security_config_ok(self): ctx = validation.Context() config.validate_security_config(security_config_pb2.SecurityConfig(), ctx) self.assertEqual(ctx.result().messages, [])
def call(self, fields, allow_internal=False): ctx = cfgvalidation.Context() val = validation.Validator(ctx, test_db(), allow_internal) val.validate(realms_config_pb2.RealmsCfg(**fields)) return ctx
def setUp(self): self.ctx = validation.Context()
def make_subctx(): return validation.Context( on_message=lambda msg: ctx.msg(msg.severity, '%s', msg.text))