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()) value_snippet = ''' portspec_valid: protocol: tcp ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.datatypes.network.PortSpec', value.get('portspec_valid')) self.assertIsNotNone(data.validate()) value_snippet = ''' portspec_invalid: protocol: xyz ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.datatypes.network.PortSpec', value.get('portspec_invalid')) err = self.assertRaises(exception.ValidationError, data.validate) self.assertEqual(_('The value "xyz" of property "protocol" is not ' 'valid. Expected a value from "[udp, tcp, igmp]".' ), err.__str__())
def test_proprety_inheritance(self): from toscaparser.nodetemplate import NodeTemplate tosca_custom_def = ''' tosca.nodes.SoftwareComponent.MySoftware: derived_from: SoftwareComponent properties: install_path: required: false type: string default: /opt/mysoftware ''' tosca_node_template = ''' node_templates: mysoftware_instance: type: tosca.nodes.SoftwareComponent.MySoftware properties: component_version: 3.1 ''' expected_properties = ['component_version', 'install_path'] nodetemplates = yamlparser.\ simple_parse(tosca_node_template)['node_templates'] custom_def = yamlparser.simple_parse(tosca_custom_def) name = list(nodetemplates.keys())[0] tpl = NodeTemplate(name, nodetemplates, custom_def) self.assertIsNone(tpl.validate()) self.assertEqual(expected_properties, sorted(tpl.get_properties().keys()))
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: 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( _('The value "0.05 GHz" of property ' '"cpu_frequency" must be greater than 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( _('The value "500 MB" of property "disk_size" ' 'must be greater than or equal to "1 GB".'), error.__str__()) if 'mem_size' in props.keys(): error = self.assertRaises(exception.ValidationError, props['mem_size'].validate) self.assertEqual( _('The value "1 MB" of property "mem_size" is ' 'out of range "(min:1 MiB, max:1 GiB)".'), error.__str__())
def test_incorrect_field_in_datatype(self): tpl_snippet = ''' tosca_definitions_version: tosca_simple_yaml_1_0 topology_template: node_templates: server: type: tosca.nodes.Compute webserver: type: tosca.nodes.WebServer properties: admin_credential: user: username token: some_pass some_field: value requirements: - host: server ''' tpl = yamlparser.simple_parse(tpl_snippet) err = self.assertRaises(exception.ValidationError, ToscaTemplate, None, None, None, tpl) self.assertIn(_('The pre-parsed input failed validation with the ' 'following error(s): \n\n\tUnknownFieldError: Data ' 'value of type "tosca.datatypes.Credential" contains' ' unknown field "some_field". Refer to the definition' ' to verify valid values'), err.__str__())
def _get_nodetemplate(self, tpl_snippet, custom_def_snippet=None): nodetemplates = yamlparser.\ simple_parse(tpl_snippet)['node_templates'] custom_def = yamlparser.simple_parse(custom_def_snippet) name = list(nodetemplates.keys())[0] tpl = NodeTemplate(name, nodetemplates, custom_def) return tpl
def test_incorrect_field_in_datatype(self): tpl_snippet = ''' tosca_definitions_version: tosca_simple_yaml_1_0 topology_template: node_templates: server: type: tosca.nodes.Compute webserver: type: tosca.nodes.WebServer properties: admin_credential: user: username token: some_pass some_field: value requirements: - host: server ''' tpl = yamlparser.simple_parse(tpl_snippet) err = self.assertRaises(exception.ValidationError, ToscaTemplate, None, None, None, tpl) self.assertIn( _('The pre-parsed input failed validation with the ' 'following error(s): \n\n\tUnknownFieldError: Data ' 'value of type "tosca.datatypes.Credential" contains' ' unknown field "some_field". Refer to the definition' ' to verify valid values'), err.__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(_('The value "0.05 GHz" of property ' '"cpu_frequency" must be greater than 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(_('The value "500 MB" of property "disk_size" ' 'must be greater than or equal to "1 GB".'), error.__str__()) if 'mem_size' in props.keys(): error = self.assertRaises(exception.ValidationError, props['mem_size'].validate) self.assertEqual(_('The value "1 MB" of property "mem_size" is ' 'out of range "(min:1 MiB, max:1 GiB)".'), error.__str__())
def test_range_unbounded(self): value_snippet = ''' temperature: [-100, 999999] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) self.assertIsNotNone(data.validate())
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_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_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_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_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_valid_ranges_against_constraints(self): # The TestLab range type has max=UNBOUNDED value_snippet = ''' temperature1: [-255, 999999] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) self.assertIsNotNone(data.validate()) # The TestLab range type has min=UNBOUNDED value_snippet = ''' temperature2: [-999999, 255] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) self.assertIsNotNone(data.validate())
def test_valid_range_type(self): value_snippet = ''' user_port: protocol: tcp target_range: [20000, 60000] source_range: [1000, 3000] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('PortSpec', value.get('user_port')) self.assertIsNotNone(data.validate())
def test_functions_datatype(self): value_snippet = ''' admin_credential: user: username token: { get_input: password } ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.datatypes.Credential', value.get('admin_credential')) 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_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_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_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 definition of "cpus" must have a "type" ' 'attribute.'), 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_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_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() prop_name = self.property if props and prop_name in props.keys(): prop = props[prop_name] self.assertIsNone(prop.validate()) resolved = prop.value self.assertEqual(resolved, self.expected)
def test_missing_property_type(self): tpl_snippet = ''' properties: prop: typo: tosca.mytesttype.Test ''' schema = yamlparser.simple_parse(tpl_snippet) error = self.assertRaises(exception.InvalidSchemaError, PropertyDef, 'prop', None, schema['properties']['prop']) self.assertEqual(_('Schema definition of "prop" must have a "type" ' 'attribute.'), str(error))
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 value "M" of property "name" must be ' 'at least "2".'), 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 definition of "cpus" must be a dict.'), str(error))
class ScalarUnitNegativeTest(TestCase): custom_def_snippet = ''' tosca.my.nodes.Compute: derived_from: tosca.nodes.Root properties: cpu_frequency: required: false type: scalar-unit.frequency constraints: - greater_or_equal: 0.1 GHz disk_size: required: false type: scalar-unit.size constraints: - greater_or_equal: 1 GB mem_size: required: false 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: cpu_frequency: 50.3.6 GHZ disk_size: MB mem_size: 1 QB ''' nodetemplates = yamlparser.simple_parse(tpl_snippet) self.assertRaises( ValueError, lambda: TopologyTemplate( {'node_templates': nodetemplates}, self.custom_def)) # 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: cpu_frequency: 0.05 GHz disk_size: 500 MB mem_size: 1 MB ''' nodetemplates = yamlparser.simple_parse(tpl_snippet) self.assertRaises( exception.ValidationError, lambda: TopologyTemplate( {'node_templates': nodetemplates}, self.custom_def))
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_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_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_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_range_unbounded(self): value_snippet = ''' humidity: [-100, 100] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) err = self.assertRaises(exception.InvalidSchemaError, lambda: data.validate()) self.assertEqual(_('The property "in_range" expects comparable values.' ), err.__str__())
def _is_valid(self, value): from jsonschema import Draft7Validator if self.property_type != Schema.ANY: value = yamlparser.simple_parse(value) validator = Draft7Validator(self.schema) errors = list(validator.iter_errors(value)) if not errors: return True self.message = "\n".join(e.message for e in errors[:1]) return False
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_range_unbounded(self): value_snippet = ''' humidity: [-100, 100] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) err = self.assertRaises(exception.InvalidSchemaError, lambda: data.validate()) self.assertEqual( _('The property "in_range" expects comparable values.'), err.__str__())
def test_invalid_scalar_unit(self): tpl_snippet = ''' server: type: tosca.my.nodes.Compute properties: cpu_frequency: 50.3.6 GHZ 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_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_invalid_scalar_unit(self): tpl_snippet = ''' server: type: tosca.my.nodes.Compute properties: cpu_frequency: 50.3.6 GHZ disk_size: MB mem_size: 1 QB ''' nodetemplates = yamlparser.simple_parse(tpl_snippet) self.assertRaises( ValueError, lambda: TopologyTemplate( {'node_templates': nodetemplates}, self.custom_def))
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) self.assertRaises( exception.ValidationError, lambda: TopologyTemplate( {'node_templates': nodetemplates}, self.custom_def))
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_invalid_range_datatype(self): value_snippet = ''' user_port: protocol: tcp target: 1 target_range: [20000] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('PortSpec', value.get('user_port')) err = self.assertRaises(ValueError, data.validate) self.assertEqual(_('"[20000]" is not a valid range.' ), err.__str__()) value_snippet = ''' user_port: protocol: tcp target: 1 target_range: [20000, 3000] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('PortSpec', value.get('user_port')) err = self.assertRaises(ValueError, data.validate) self.assertEqual(_('"[20000, 3000]" is not a valid range.' ), err.__str__()) value_snippet = ''' humidity: [-100, 100] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) err = self.assertRaises(exception.InvalidSchemaError, lambda: data.validate()) self.assertEqual(_('The property "in_range" expects comparable values.' ), err.__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" contains unknown ' 'field "nema". Refer to the definition to verify ' 'valid values.'), error.__str__())
def test_invalid_ranges_against_constraints(self): # The TestLab range type has min=-256, max=UNBOUNDED value_snippet = ''' temperature1: [-257, 999999] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) err = self.assertRaises(exception.ValidationError, data.validate) self.assertEqual( _('The value "-257" of property "temperature1" is ' 'out of range "(min:-256, max:UNBOUNDED)".'), err.__str__()) value_snippet = ''' temperature2: [-999999, 257] ''' value = yamlparser.simple_parse(value_snippet) data = DataEntity('tosca.my.datatypes.TestLab', value, DataTypeTest.custom_type_def) err = self.assertRaises(exception.ValidationError, data.validate) self.assertEqual( _('The value "257" of property "temperature2" is ' 'out of range "(min:UNBOUNDED, max:256)".'), err.__str__())