def test_validate_flat_dimension(self): self.assertTrue(config.validate_flat_dimension(u'a:b')) # Broken flat dimensions. self.assertFalse(config.validate_flat_dimension('a:b')) self.assertFalse(config.validate_flat_dimension(u'a:')) self.assertFalse(config.validate_flat_dimension(u':b')) self.assertFalse(config.validate_flat_dimension(u'ab'))
def test_validate_flat_dimension_value(self): l = config.DIMENSION_VALUE_LENGTH self.assertTrue(config.validate_flat_dimension(u'a:' + u'b' * l)) self.assertFalse(config.validate_flat_dimension(u'a:' + u'b' * (l + 1)))
def test_validate_flat_dimension_key(self): l = config.DIMENSION_KEY_LENGTH self.assertTrue(config.validate_flat_dimension(u'a' * l + u':b')) self.assertFalse(config.validate_flat_dimension(u'a' * (l + 1) + u':b'))
def _validate_bots_cfg(cfg, ctx): """Validates bots.cfg file.""" with ctx.prefix('trusted_dimensions: '): for dim_key in cfg.trusted_dimensions: if not local_config.validate_dimension_key(dim_key): ctx.error('invalid dimension key %r', dim_key) # Explicitly mentioned bot_id => index of a group where it was mentioned. bot_ids = {} # bot_id_prefix => index of a group where it was defined. bot_id_prefixes = {} # Index of a group to use as default fallback (there can be only one). default_group_idx = None # machine_type names. machine_type_names = set() for i, entry in enumerate(cfg.bot_group): with ctx.prefix('bot_group #%d: ', i): # Validate bot_id field and make sure bot_id groups do not intersect. _validate_group_bot_ids(ctx, entry.bot_id, i, bot_ids, bot_id_prefixes) # Validate bot_id_prefix and make sure bot_id_prefix groups do not # intersect. _validate_group_bot_id_prefixes(ctx, entry.bot_id_prefix, i, bot_id_prefixes, bot_ids) # A group without bot_id, bot_id_prefix and machine_type is applied to # bots that don't fit any other groups. There should be at most one such # group. if (not entry.bot_id and not entry.bot_id_prefix and not entry.machine_type): if default_group_idx is not None: ctx.error('group #%d is already set as default', default_group_idx) else: default_group_idx = i # Validate machine_type. for i, machine_type in enumerate(entry.machine_type): with ctx.prefix('machine_type #%d: ', i): _validate_machine_type(ctx, machine_type, machine_type_names) # Validate 'auth' and 'system_service_account' fields. _validate_group_auth_and_system_service_account(ctx, entry) # Validate 'owners'. Just check they are emails. for own in entry.owners: _validate_email(ctx, own, 'owner') # Validate 'dimensions'. for dim in entry.dimensions: if not local_config.validate_flat_dimension(dim): ctx.error('bad dimension %r', dim) # Validate 'bot_config_script': the supplemental bot_config.py. if entry.bot_config_script: # Another check in bot_code.py confirms that the script itself is valid # python before it is accepted by the config service. See # _validate_scripts validator there. We later recheck this (see below) # when assembling the final expanded bots.cfg. if not entry.bot_config_script.endswith('.py'): ctx.error( 'invalid bot_config_script name: must end with .py') if os.path.basename( entry.bot_config_script) != entry.bot_config_script: ctx.error( 'invalid bot_config_script name: must not contain path entry' ) # We can't validate that the file exists here. We'll do it later in # _fetch_and_expand_bots_cfg when assembling the final config from # individual files. # Validate 'bot_config_script_content': the content must be valid python. # This validation is hit when validating the expanded bot config. if entry.bot_config_script_content: try: ast.parse(entry.bot_config_script_content) except (SyntaxError, TypeError) as e: ctx.error('invalid bot config script "%s": %s' % (entry.bot_config_script, e))