def test_set_value(self): with mock.patch('conftool.tests.unit.MockEntity.fetch'): obj = MockEntity('a', 'b', 'c') # set an existing value obj._set_value('a', get_validator('int'), {'a': 256}) self.assertEqual(obj.a, 256) # Set an inexistent value with no defaults obj._set_value('c', get_validator('string'), {}) self.assertEqual(obj.c, 'FooBar')
def test_set_value(self): with mock.patch('conftool.tests.unit.MockEntity.fetch'): obj = MockEntity('a', 'b', 'c') # set an existing value obj._set_value('a', get_validator('int'), {'a': 256}) self.assertEqual(obj.a, 256) # Set an inexistent value with no defaults obj._set_value('c', get_validator('string'), {}) self.assertEqual(obj.c, 'FooBar')
class MockFreeEntity(FreeSchemaEntity): _tags = ['foo', 'bar'] _schema = {'a': get_validator('int'), 'b': get_validator('string')} @classmethod def base_path(cls): return 'Mock/entity' def get_default(self, what): if what == 'a': return 1 else: return 'FooBar'
def test_str_validator(self): validator = types.get_validator('string') input_string = "abcdef gz" self.assertEqual(input_string, validator(input_string)) input_list = [1, 2] self.assertEqual('[1, 2]', validator(input_list)) self.assertEqual('string', validator.expected_type)
def test_str_validator(self): validator = types.get_validator('string') input_string = "abcdef gz" self.assertEqual(input_string, validator(input_string)) input_list = [1, 2] self.assertEqual('[1, 2]', validator(input_list)) self.assertEqual('string', validator.expected_type)
def test_from_cli(self): """ Test parsing of cli-provided arguments """ a = get_action(self.entity, 'set/bar=ac') a.entity._schema['bar'] = get_validator('list') self.assertEqual(a._from_cli({'bar': 'abc,def,ghi'}), {'bar': ['abc', 'def', 'ghi']}) a.entity._schema['bar'] = get_validator('bool') self.assertEqual(a._from_cli({'bar': 'false'}), {'bar': False}) self.assertEqual(a._from_cli({'bar': 'true'}), {'bar': True}) self.assertRaises(ValueError, a._from_cli, {'bar': 'popcorn!'}) a.entity._schema['bar'] = get_validator('dict') self.assertRaises(ValueError, a._from_cli, {'bar': 'popcorn!'}) del a.entity._schema['bar']
def test_from_cli(self): """ Test parsing of cli-provided arguments """ a = get_action(self.entity, 'set/bar=ac') a.entity._schema['bar'] = get_validator('list') self.assertEqual(a._from_cli({'bar': 'abc,def,ghi'}), {'bar': ['abc', 'def', 'ghi']}) a.entity._schema['bar'] = get_validator('bool') self.assertEqual(a._from_cli({'bar': 'false'}), {'bar': False}) self.assertEqual(a._from_cli({'bar': 'true'}), {'bar': True}) self.assertRaises(ValueError, a._from_cli, {'bar': 'popcorn!'}) a.entity._schema['bar'] = get_validator('dict') self.assertRaises(ValueError, a._from_cli, {'bar': 'popcorn!'}) del a.entity._schema['bar']
def test_any_validator(self): validator = types.get_validator("any") self.assertEqual("a string", validator("a string")) self.assertEqual(['a', 'list'], validator(['a', 'list'])) self.assertEqual({'a': 'dict'}, validator({'a': 'dict'})) class Foo(object): pass self.assertRaises(ValueError, validator, Foo())
def test_any_validator(self): validator = types.get_validator("any") self.assertEqual("a string", validator("a string")) self.assertEqual(['a', 'list'], validator(['a', 'list'])) self.assertEqual({'a': 'dict'}, validator({'a': 'dict'})) class Foo: pass self.assertRaises(ValueError, validator, Foo())
def factory(name, defs): """ Creates a class tailored to the interested entity based on the inputs """ properties = { '_tags': defs['tags'], '_base_path': defs['path'], 'depends': defs.get('depends', []), '_schema': {}, '_default_values': {} } json_schema = defs.get('json_schema', False) if json_schema: cls = JsonSchemaEntity properties['loader'] = get_json_schema(json_schema) elif defs.get('free_form', False): cls = FreeSchemaEntity else: cls = Entity properties['_schema'] = {} properties['_default_values'] = {} for k, v in defs['schema'].items(): if json_schema: # Validation is done with json schema properties['_schema'][k] = get_validator('any') else: properties['_schema'][k] = get_validator(v['type']) properties['_default_values'][k] = v['default'] def base_path(cls): return cls._base_path def get_default(self, what): return self._default_values[what] properties['get_default'] = get_default properties['base_path'] = classmethod(base_path) return type(name, (cls,), properties)
def factory(name, defs): """ Creates a class tailored to the interested entity based on the inputs """ properties = { '_tags': defs['tags'], '_base_path': defs['path'], 'depends': defs.get('depends', []), '_schema': {}, '_default_values': {} } json_schema = defs.get('json_schema', False) if json_schema: cls = JsonSchemaEntity properties['loader'] = get_json_schema(json_schema) elif defs.get('free_form', False): cls = FreeSchemaEntity else: cls = Entity properties['_schema'] = {} properties['_default_values'] = {} for k, v in defs['schema'].items(): if json_schema: # Validation is done with json schema properties['_schema'][k] = get_validator('any') else: properties['_schema'][k] = get_validator(v['type']) properties['_default_values'][k] = v['default'] def base_path(cls): return cls._base_path def get_default(self, what): return self._default_values[what] properties['get_default'] = get_default properties['base_path'] = classmethod(base_path) return type(name, (cls,), properties)
def test_update(self): self.entity.write = mock.Mock() self.entity._set_value = mock.Mock(side_effect=self.entity._set_value) # Setting a value not in the schema doesn't do anything self.entity.update({'c': 'meh'}) self.entity._set_value.assert_not_called() # Setting a value in the schema does set it self.entity.update({'a': 10}) self.entity._set_value.assert_called_with('a', get_validator('int'), {'a': 10}, set_defaults=False) self.entity.write.assert_called_with()
class Node(Entity): _schema = { 'weight': get_validator('int'), 'pooled': get_validator("enum:yes|no|inactive") } _tags = ['dc', 'cluster', 'service'] depends = ['service'] def __init__(self, datacenter, cluster, servname, host): self.service = ServiceCache.get(cluster, servname) super().__init__(datacenter, cluster, servname, host) @classmethod def base_path(cls): return cls.config.pools_path def get_default(self, what): _log.debug("Setting default for %s", what) return self.service.get_defaults(what) @classmethod def from_yaml(cls, data): """ Imports objects from a yaml file. Format is: dc: cluster: hostname: - serviceA - serviceB """ transformed = defaultdict(dict) for dc, clusters in data.items(): for cluster, hosts in clusters.items(): transformed[dc][cluster] = defaultdict(list) for host, services in hosts.items(): for service in services: transformed[dc][cluster][service].append(host) return super().from_yaml(transformed)
def test_update(self): self.entity.write = mock.Mock() self.entity._set_value = mock.Mock(side_effect=self.entity._set_value) # Setting a value not in the schema doesn't do anything self.entity.update({'c': 'meh'}) self.entity._set_value.assert_not_called() # Setting a value in the schema does set it self.entity.update({'a': 10}) self.entity._set_value.assert_called_with('a', get_validator('int'), {'a': 10}, set_defaults=False) self.entity.write.assert_called_with()
class Service(FreeSchemaEntity): _schema = { 'default_values': get_validator('dict'), 'datacenters': get_validator('list') } _tags = ['cluster'] static_values = True @classmethod def base_path(cls): return cls.config.services_path def get_default(self, what): """ Default values for services have no meaning. """ defaults = { 'default_values': {'pooled': "no", "weight": 0}, 'datacenters': ['eqiad', 'codfw'] } return defaults[what] def get_defaults(self, what): return self.default_values[what]
class MockBasicEntity(KVObject): _tags = ['A', 'B', 'C', 'D'] _schema = {'val': get_validator('any')} @classmethod def base_path(cls): return 'base_path' @property def key(self): return 'a/b/c/d/e' @property def dir(self): return 'a'
class MockJsonEntity(JsonSchemaEntity): _tags = ['foo', 'bar'] _schema = {'val': get_validator('any')} # load a catchall rule for a string loader = JsonSchemaLoader( base_path='conftool/tests/fixtures/schemas', rules={'catchall': {'schema': 'val.schema', 'selector': 'name=.*'}} ) @classmethod def base_path(cls): return 'Mock/entity' def get_default(self, what): if what == 'val': return '' else: return 'FooBar'
def test_list_validator(self): validator = types.get_validator("list") self.assertEqual(['abc', 1, 'may'], validator(['abc', 1, 'may'])) self.assertEqual([], validator('abcdesf')) self.assertEqual([], validator(''))
def test_enum_validator(self): validator = types.get_validator("enum:a|b|c") self.assertEqual('c', validator('c')) self.assertRaises(ValueError, validator, 'd')
def test_bool_validator(self): validator = types.get_validator("bool") self.assertEqual(True, validator(True)) self.assertEqual(False, validator(False)) self.assertRaises(ValueError, validator, 'definitely maybe')
def test_list_validator(self): validator = types.get_validator("list") self.assertEqual(['abc', 1, 'may'], validator(['abc',1,'may'])) self.assertEqual([], validator('abcdesf')) self.assertEqual([], validator(''))
def test_int_validator(self): validator = types.get_validator('int') # When a number is passed, as a string self.assertEqual(101, validator("101")) # when a random string gets passed self.assertRaises(ValueError, validator, "neoar sds")
def test_int_validator(self): validator = types.get_validator('int') # When a number is passed, as a string self.assertEqual(101, validator("101")) # when a random string gets passed self.assertRaises(ValueError, validator, "neoar sds")
def test_enum_validator(self): validator = types.get_validator("enum:a|b|c") self.assertEqual('c', validator('c')) self.assertRaises(ValueError, validator, 'd')
def test_bool_validator(self): validator = types.get_validator("bool") self.assertEqual(True, validator(True)) self.assertEqual(False, validator(False)) self.assertRaises(ValueError, validator, 'definitely maybe')