class ScalarUnitNegativeTest(TestCase): custom_def_snippet = ''' tosca.my.nodes.Compute: derived_from: tosca.nodes.Root properties: disk_size: required: no type: scalar-unit.size constraints: - greater_or_equal: 1 GB mem_size: required: no type: scalar-unit.size constraints: - in_range: [1 MiB, 1 GiB] ''' custom_def = yamlparser.simple_parse(custom_def_snippet) # disk_size doesn't provide a value, mem_size uses an invalid unit. def test_invalid_scalar_unit(self): tpl_snippet = ''' server: type: tosca.my.nodes.Compute properties: disk_size: MB mem_size: 1 QB ''' nodetemplates = yamlparser.simple_parse(tpl_snippet) nodetemplate = NodeTemplate('server', nodetemplates, self.custom_def) for p in nodetemplate.get_properties_objects(): self.assertRaises(ValueError, p.validate) # disk_size is less than 1 GB, mem_size is not in the required range. # Note: in the spec, the minimum value of mem_size is 1 MiB (> 1 MB) def test_constraint_for_scalar_unit(self): tpl_snippet = ''' server: type: tosca.my.nodes.Compute properties: disk_size: 500 MB mem_size: 1 MB ''' nodetemplates = yamlparser.simple_parse(tpl_snippet) nodetemplate = NodeTemplate('server', nodetemplates, self.custom_def) props = nodetemplate.get_properties() if 'disk_size' in props.keys(): error = self.assertRaises(exception.ValidationError, props['disk_size'].validate) self.assertEqual( 'disk_size: 500 MB must be greater or ' 'equal to "1 GB".', error.__str__()) if 'mem_size' in props.keys(): error = self.assertRaises(exception.ValidationError, props['mem_size'].validate) self.assertEqual( 'mem_size: 1 MB is out of range ' '(min:1 MiB, ' 'max:1 GiB).', error.__str__())
def test_constraint_for_scalar_unit(self): tpl_snippet = ''' server: type: tosca.my.nodes.Compute properties: cpu_frequency: 0.05 GHz disk_size: 500 MB mem_size: 1 MB ''' nodetemplates = yamlparser.simple_parse(tpl_snippet) nodetemplate = NodeTemplate('server', nodetemplates, self.custom_def) props = nodetemplate.get_properties() if 'cpu_frequency' in props.keys(): error = self.assertRaises(exception.ValidationError, props['cpu_frequency'].validate) self.assertEqual('cpu_frequency: 0.05 GHz must be greater or ' 'equal to "0.1 GHz".', error.__str__()) if 'disk_size' in props.keys(): error = self.assertRaises(exception.ValidationError, props['disk_size'].validate) self.assertEqual('disk_size: 500 MB must be greater or ' 'equal to "1 GB".', error.__str__()) if 'mem_size' in props.keys(): error = self.assertRaises(exception.ValidationError, props['mem_size'].validate) self.assertEqual('mem_size: 1 MB is out of range ' '(min:1 MiB, ' 'max:1 GiB).', error.__str__())
def test_constraint_for_scalar_unit(self): tpl_snippet = ''' server: type: tosca.my.nodes.Compute properties: disk_size: 500 MB mem_size: 1 MB ''' nodetemplates = yamlparser.simple_parse(tpl_snippet) nodetemplate = NodeTemplate('server', nodetemplates, self.custom_def) props = nodetemplate.get_properties() if 'disk_size' in props.keys(): error = self.assertRaises(exception.ValidationError, props['disk_size'].validate) self.assertEqual( 'disk_size: 500 MB must be greater or ' 'equal to "1 GB".', error.__str__()) if 'mem_size' in props.keys(): error = self.assertRaises(exception.ValidationError, props['mem_size'].validate) self.assertEqual( 'mem_size: 1 MB is out of range ' '(min:1 MiB, ' 'max:1 GiB).', error.__str__())
def test_schema_none_description(self): tpl_snippet = ''' cpus: type: integer ''' schema = yamlparser.simple_parse(tpl_snippet) cpus_schema = Schema('cpus', schema['cpus']) self.assertEqual('', cpus_schema.description)
def test_custom_datatype(self): value_snippet = ''' name: Mike gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) self.assertIsNotNone(data.validate())
def test_default_field_in_dataentity(self): value_snippet = ''' name: Mike ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) data = data.validate() self.assertEqual('unknown', data.get('gender'))
def test_built_in_datatype_without_properties(self): value_snippet = ''' 2 ''' value = yamlparser.simple_parse(value_snippet) datatype = DataType('PortDef') self.assertEqual('integer', datatype.value_type) data = DataEntity('PortDef', value) self.assertIsNotNone(data.validate())
def test_schema_miss_type(self): tpl_snippet = ''' cpus: description: Number of CPUs for the server. ''' schema = yamlparser.simple_parse(tpl_snippet) error = self.assertRaises(exception.InvalidSchemaError, Schema, 'cpus', schema['cpus']) self.assertEqual('Schema cpus must have type.', str(error))
def test_built_in_nested_datatype(self): value_snippet = ''' user_port: protocol: tcp target: [50000] source: [9000] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('PortSpec', value.get('user_port')) self.assertIsNotNone(data.validate())
def test_type_error_in_dataentity(self): value_snippet = ''' name: 123 gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(ValueError, data.validate) self.assertEqual('"123" is not a string', error.__str__())
def test_non_dict_value_for_datatype(self): value_snippet = ''' [Tom, Jerry] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.TypeMismatchError, data.validate) self.assertEqual('[\'Tom\', \'Jerry\'] must be of type: ' '"tosca.my.datatypes.PeopleBase".', error.__str__())
def test_schema_not_dict(self): tpl_snippet = ''' cpus: - type: integer - description: Number of CPUs for the server. ''' schema = yamlparser.simple_parse(tpl_snippet) error = self.assertRaises(exception.InvalidSchemaError, Schema, 'cpus', schema['cpus']) self.assertEqual('Schema cpus must be a dict.', str(error))
def test_scenario_scalar_unit_positive(self): tpl = self.tpl_snippet nodetemplates = yamlparser.simple_parse(tpl) nodetemplate = NodeTemplate('server', nodetemplates) props = nodetemplate.get_properties() if props and 'mem_size' in props.keys(): prop = props['mem_size'] self.assertIsNone(prop.validate()) resolved = prop.value self.assertEqual(resolved, self.expected)
def test_scenario_scalar_unit_positive(self): tpl = self.tpl_snippet nodetemplates = yamlparser.simple_parse(tpl) nodetemplate = NodeTemplate('server', nodetemplates) props = nodetemplate.get_capability('host').get_properties() if props and 'mem_size' in props.keys(): prop = props['mem_size'] self.assertIsNone(prop.validate()) resolved = prop.value self.assertEqual(resolved, self.expected)
def test_value_error_in_dataentity(self): value_snippet = ''' name: M gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.ValidationError, data.validate) self.assertEqual('length of name: M must be at least "2".', error.__str__())
def test_built_in_datatype(self): value_snippet = ''' private_network: network_name: private network_id: 3e54214f-5c09-1bc9-9999-44100326da1b addresses: [ 10.111.128.10 ] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.datatypes.network.NetworkInfo', value.get('private_network')) self.assertIsNotNone(data.validate())
def test_non_dict_value_for_datatype(self): value_snippet = ''' [Tom, Jerry] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.TypeMismatchError, data.validate) self.assertEqual( '[\'Tom\', \'Jerry\'] must be of type: ' '"tosca.my.datatypes.PeopleBase".', error.__str__())
def test_validation_in_collection_entry(self): value_snippet = ''' name: Mike gender: male addresses: {Home: 1, Office: 9 bar avenue} ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.People', value, DataTypeTest.custom_type_def) error = self.assertRaises(ValueError, data.validate) self.assertEqual('"1" is not a string', error.__str__())
def test_built_in_datatype_with_short_name(self): value_snippet = ''' ethernet_port: port_name: port1 port_id: 2c0c7a37-691a-23a6-7709-2d10ad041467 network_id: 3e54214f-5c09-1bc9-9999-44100326da1b mac_address: f1:18:3b:41:92:1e addresses: [ 172.24.9.102 ] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('PortInfo', value.get('ethernet_port')) self.assertIsNotNone(data.validate())
def test_invalid_scalar_unit(self): tpl_snippet = ''' server: type: tosca.my.nodes.Compute properties: disk_size: MB mem_size: 1 QB ''' nodetemplates = yamlparser.simple_parse(tpl_snippet) nodetemplate = NodeTemplate('server', nodetemplates, self.custom_def) for p in nodetemplate.get_properties_objects(): self.assertRaises(ValueError, p.validate)
def test_missing_field_in_dataentity(self): value_snippet = ''' gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.MissingRequiredFieldError, data.validate) self.assertEqual( 'Data value of type tosca.my.datatypes.PeopleBase ' 'is missing required field: "[\'name\']".', error.__str__())
def test_missing_field_in_dataentity(self): value_snippet = ''' gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.MissingRequiredFieldError, data.validate) self.assertEqual('Data value of type tosca.my.datatypes.PeopleBase ' 'is missing required field: "[\'name\']".', error.__str__())
def test_field_error_in_dataentity(self): value_snippet = ''' nema: Mike gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.UnknownFieldError, data.validate) self.assertEqual( 'Data value of type tosca.my.datatypes.PeopleBase ' 'contain(s) unknown field: "nema", refer to the ' 'definition to verify valid values.', error.__str__())
def test_field_error_in_dataentity(self): value_snippet = ''' nema: Mike gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.UnknownFieldError, data.validate) self.assertEqual('Data value of type tosca.my.datatypes.PeopleBase ' 'contain(s) unknown field: "nema", refer to the ' 'definition to verify valid values.', error.__str__())
def test_schema_dict(self): tpl_snippet = ''' cpus: type: integer description: Number of CPUs for the server. ''' schema = yamlparser.simple_parse(tpl_snippet) cpus_schema = Schema('cpus', schema['cpus']) self.assertEqual(len(cpus_schema), 2) self.assertEqual('integer', cpus_schema.type) self.assertEqual('Number of CPUs for the server.', cpus_schema.description) self.assertEqual(False, cpus_schema.required) self.assertIsNone(cpus_schema.default)
def test_custom_datatype_with_parent(self): value_snippet = ''' name: Mike gender: male contacts: - {contact_name: Tom, contact_email: [email protected], contact_phone: '123456789'} - {contact_name: Jerry, contact_email: [email protected], contact_phone: '321654987'} ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.People', value, DataTypeTest.custom_type_def) self.assertIsNotNone(data.validate())
def test_validation_in_nested_datatype(self): value_snippet = ''' name: Mike gender: male contacts: - {contact_name: Tom, contact_email: [email protected], contact_pone: '123456789'} - {contact_name: Jerry, contact_email: [email protected], contact_phone: '321654987'} ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.People', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.UnknownFieldError, data.validate) self.assertEqual( 'Data value of type tosca.my.datatypes.ContactInfo ' 'contain(s) unknown field: "contact_pone", refer to ' 'the definition to verify valid values.', error.__str__())
def test_list_entry_schema(self): test_property_schema = {'type': 'list', 'entry_schema': {'type': 'string'}} propertyInstance = Property('test_property', ['a', 'b'], test_property_schema) self.assertIsNone(propertyInstance.validate()) self.assertEqual(['a', 'b'], propertyInstance.value) schema_snippet = ''' type: list entry_schema: type: string constraints: - min_length: 2 ''' test_property_schema = yamlparser.simple_parse(schema_snippet) propertyInstance = Property('test_property', ['ab', 'cd'], test_property_schema) self.assertIsNone(propertyInstance.validate()) self.assertEqual(['ab', 'cd'], propertyInstance.value)
def test_validation_in_nested_datatype(self): value_snippet = ''' name: Mike gender: male contacts: - {contact_name: Tom, contact_email: [email protected], contact_pone: '123456789'} - {contact_name: Jerry, contact_email: [email protected], contact_phone: '321654987'} ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.People', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.UnknownFieldError, data.validate) self.assertEqual('Data value of type tosca.my.datatypes.ContactInfo ' 'contain(s) unknown field: "contact_pone", refer to ' 'the definition to verify valid values.', error.__str__())
def test_list_entry_schema(self): test_property_schema = { 'type': 'list', 'entry_schema': { 'type': 'string' } } propertyInstance = Property('test_property', ['a', 'b'], test_property_schema) self.assertIsNone(propertyInstance.validate()) self.assertEqual(['a', 'b'], propertyInstance.value) schema_snippet = ''' type: list entry_schema: type: string constraints: - min_length: 2 ''' test_property_schema = yamlparser.simple_parse(schema_snippet) propertyInstance = Property('test_property', ['ab', 'cd'], test_property_schema) self.assertIsNone(propertyInstance.validate()) self.assertEqual(['ab', 'cd'], propertyInstance.value)
def test_empty_template(self): value_snippet = '' value = yamlparser.simple_parse(value_snippet) self.assertEqual(value, {})
class DataTypeTest(TestCase): custom_type_schema = ''' tosca.my.datatypes.PeopleBase: properties: name: type: string required: true constraints: - min_length: 2 gender: type: string default: unknown tosca.my.datatypes.People: derived_from: tosca.my.datatypes.PeopleBase properties: addresses: type: map entry_schema: type: string contacts: type: list entry_schema: type: tosca.my.datatypes.ContactInfo tosca.my.datatypes.ContactInfo: description: simple contact information properties: contact_name: type: string required: true constraints: - min_length: 2 contact_email: type: string contact_phone: type: string ''' custom_type_def = yamlparser.simple_parse(custom_type_schema) def test_built_in_datatype(self): value_snippet = ''' private_network: network_name: private network_id: 3e54214f-5c09-1bc9-9999-44100326da1b addresses: [ 10.111.128.10 ] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.datatypes.network.NetworkInfo', value.get('private_network')) self.assertIsNotNone(data.validate()) def test_built_in_datatype_with_short_name(self): value_snippet = ''' ethernet_port: port_name: port1 port_id: 2c0c7a37-691a-23a6-7709-2d10ad041467 network_id: 3e54214f-5c09-1bc9-9999-44100326da1b mac_address: f1:18:3b:41:92:1e addresses: [ 172.24.9.102 ] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('PortInfo', value.get('ethernet_port')) self.assertIsNotNone(data.validate()) def test_built_in_datatype_without_properties(self): value_snippet = ''' 2 ''' value = yamlparser.simple_parse(value_snippet) datatype = DataType('PortDef') self.assertEqual('integer', datatype.value_type) data = DataEntity('PortDef', value) self.assertIsNotNone(data.validate()) @skip('The example in TOSCA spec may have some problem.') def test_built_in_nested_datatype(self): value_snippet = ''' user_port: protocol: tcp target: [50000] source: [9000] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('PortSpec', value.get('user_port')) self.assertIsNotNone(data.validate()) def test_custom_datatype(self): value_snippet = ''' name: Mike gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) self.assertIsNotNone(data.validate()) def test_custom_datatype_with_parent(self): value_snippet = ''' name: Mike gender: male contacts: - {contact_name: Tom, contact_email: [email protected], contact_phone: '123456789'} - {contact_name: Jerry, contact_email: [email protected], contact_phone: '321654987'} ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.People', value, DataTypeTest.custom_type_def) self.assertIsNotNone(data.validate()) # [Tom, Jerry] is not a dict, it can't be a value of datatype PeopleBase def test_non_dict_value_for_datatype(self): value_snippet = ''' [Tom, Jerry] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.TypeMismatchError, data.validate) self.assertEqual( '[\'Tom\', \'Jerry\'] must be of type: ' '"tosca.my.datatypes.PeopleBase".', error.__str__()) # 'nema' is an invalid field name def test_field_error_in_dataentity(self): value_snippet = ''' nema: Mike gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.UnknownFieldError, data.validate) self.assertEqual( 'Data value of type tosca.my.datatypes.PeopleBase ' 'contain(s) unknown field: "nema", refer to the ' 'definition to verify valid values.', error.__str__()) def test_default_field_in_dataentity(self): value_snippet = ''' name: Mike ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) data = data.validate() self.assertEqual('unknown', data.get('gender')) # required field 'name' is missing def test_missing_field_in_dataentity(self): value_snippet = ''' gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.MissingRequiredFieldError, data.validate) self.assertEqual( 'Data value of type tosca.my.datatypes.PeopleBase ' 'is missing required field: "[\'name\']".', error.__str__()) # the value of name field is not a string def test_type_error_in_dataentity(self): value_snippet = ''' name: 123 gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(ValueError, data.validate) self.assertEqual('"123" is not a string', error.__str__()) # the value of name doesn't meet the defined constraint def test_value_error_in_dataentity(self): value_snippet = ''' name: M gender: male ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.PeopleBase', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.ValidationError, data.validate) self.assertEqual('length of name: M must be at least "2".', error.__str__()) # value of addresses doesn't fit the entry_schema def test_validation_in_collection_entry(self): value_snippet = ''' name: Mike gender: male addresses: {Home: 1, Office: 9 bar avenue} ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.People', value, DataTypeTest.custom_type_def) error = self.assertRaises(ValueError, data.validate) self.assertEqual('"1" is not a string', error.__str__()) # contact_pone is an invalid field name in nested datatype def test_validation_in_nested_datatype(self): value_snippet = ''' name: Mike gender: male contacts: - {contact_name: Tom, contact_email: [email protected], contact_pone: '123456789'} - {contact_name: Jerry, contact_email: [email protected], contact_phone: '321654987'} ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.People', value, DataTypeTest.custom_type_def) error = self.assertRaises(exception.UnknownFieldError, data.validate) self.assertEqual( 'Data value of type tosca.my.datatypes.ContactInfo ' 'contain(s) unknown field: "contact_pone", refer to ' 'the definition to verify valid values.', error.__str__()) def test_datatype_in_current_template(self): tpl_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "data/datatypes/test_custom_datatypes_in_current_template.yaml") self.assertIsNotNone(ToscaTemplate(tpl_path)) def test_datatype_in_template_positive(self): tpl_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "data/datatypes/test_custom_datatypes_positive.yaml") self.assertIsNotNone(ToscaTemplate(tpl_path)) def test_datatype_in_template_invalid_value(self): tpl_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "data/datatypes/test_custom_datatypes_value_error.yaml") error = self.assertRaises(ValueError, ToscaTemplate, tpl_path) self.assertEqual( '"[\'1 foo street\', \'9 bar avenue\']" ' 'is not a map', error.__str__()) def test_datatype_in_template_nested_datatype_error(self): tpl_path = os.path.join( os.path.dirname(os.path.abspath(__file__)), "data/datatypes/test_custom_datatypes_nested_datatype_error.yaml") error = self.assertRaises(ValueError, ToscaTemplate, tpl_path) self.assertEqual('"123456789" is not a string', error.__str__())