Merge "Set property required flag to true as default"
This commit is contained in:
commit
9001371515
@ -506,12 +506,14 @@ tosca.capabilities.Endpoint:
|
||||
properties:
|
||||
protocol:
|
||||
type: string
|
||||
required: true
|
||||
default: tcp
|
||||
port:
|
||||
type: tosca.datatypes.network.PortDef
|
||||
required: false
|
||||
secure:
|
||||
type: boolean
|
||||
required: false
|
||||
default: false
|
||||
url_path:
|
||||
type: string
|
||||
@ -524,6 +526,7 @@ tosca.capabilities.Endpoint:
|
||||
required: false
|
||||
initiator:
|
||||
type: string
|
||||
required: false
|
||||
default: source
|
||||
constraints:
|
||||
- valid_values: [source, target, peer]
|
||||
@ -792,14 +795,18 @@ tosca.datatypes.network.PortSpec:
|
||||
- valid_values: [ udp, tcp, igmp ]
|
||||
target:
|
||||
type: PortDef
|
||||
required: false
|
||||
target_range:
|
||||
type: range
|
||||
required: false
|
||||
constraints:
|
||||
- in_range: [ 1, 65535 ]
|
||||
source:
|
||||
type: PortDef
|
||||
required: false
|
||||
source_range:
|
||||
type: range
|
||||
required: false
|
||||
constraints:
|
||||
- in_range: [ 1, 65535 ]
|
||||
|
||||
|
@ -141,6 +141,8 @@ class NodeType(StatefulEntityType):
|
||||
if caps is None:
|
||||
caps = self.get_value(self.CAPABILITIES, None, True)
|
||||
if caps:
|
||||
# 'name' is symbolic name of the capability
|
||||
# 'value' is a dict { 'type': <capability type name> }
|
||||
for name, value in caps.items():
|
||||
ctype = value.get('type')
|
||||
cap = CapabilityTypeDef(name, ctype, self.type,
|
||||
|
@ -24,7 +24,7 @@ class PropertyDef(object):
|
||||
PROPERTY_KEYNAME_STATUS) = \
|
||||
('default', 'required', 'status')
|
||||
|
||||
PROPERTY_REQUIRED_DEFAULT = False
|
||||
PROPERTY_REQUIRED_DEFAULT = True
|
||||
|
||||
VALID_REQUIRED_VALUES = ['true', 'false']
|
||||
VALID_STATUS_VALUES = (PROPERTY_STATUS_SUPPORTED,
|
||||
|
@ -20,6 +20,7 @@ data_types:
|
||||
- min_length: 2
|
||||
gender:
|
||||
type: string
|
||||
required: false
|
||||
default: unknown
|
||||
|
||||
tosca.my.datatypes.People:
|
||||
@ -27,10 +28,12 @@ data_types:
|
||||
properties:
|
||||
addresses:
|
||||
type: map
|
||||
required: false
|
||||
entry_schema:
|
||||
type: string
|
||||
contacts:
|
||||
type: list
|
||||
required: false
|
||||
entry_schema:
|
||||
type: tosca.my.datatypes.ContactInfo
|
||||
|
||||
@ -44,5 +47,7 @@ data_types:
|
||||
- min_length: 2
|
||||
contact_email:
|
||||
type: string
|
||||
required: false
|
||||
contact_phone:
|
||||
type: string
|
||||
required: false
|
||||
|
@ -20,6 +20,7 @@ data_types:
|
||||
- min_length: 2
|
||||
gender:
|
||||
type: string
|
||||
required: false
|
||||
default: unknown
|
||||
|
||||
tosca.my.datatypes.People:
|
||||
@ -27,10 +28,12 @@ data_types:
|
||||
properties:
|
||||
addresses:
|
||||
type: map
|
||||
required: false
|
||||
entry_schema:
|
||||
type: string
|
||||
contacts:
|
||||
type: list
|
||||
required: false
|
||||
entry_schema:
|
||||
type: tosca.my.datatypes.ContactInfo
|
||||
|
||||
@ -44,8 +47,10 @@ data_types:
|
||||
- min_length: 2
|
||||
contact_email:
|
||||
type: string
|
||||
required: false
|
||||
contact_phone:
|
||||
type: string
|
||||
required: false
|
||||
|
||||
topology_template:
|
||||
node_templates:
|
||||
|
@ -21,8 +21,11 @@ topology_template:
|
||||
trans1:
|
||||
type: example.TransactionSubsystem
|
||||
properties:
|
||||
# to be updated when substitution_mapping is implemented
|
||||
# TODO to be updated when substitution_mapping is implemented
|
||||
# mq_server_ip: { get_attribute: [ mq, server_ip ] }
|
||||
# for now, we will use the loopback address to avoid errors as
|
||||
# this property is required in the schema
|
||||
mq_server_ip: 127.0.0.1
|
||||
receiver_port: 8080
|
||||
# capabilities:
|
||||
# message_receiver:
|
||||
@ -33,8 +36,11 @@ topology_template:
|
||||
trans2:
|
||||
type: example.TransactionSubsystem
|
||||
properties:
|
||||
# to be updated when substitution_mapping is implemented
|
||||
# TODO to be updated when substitution_mapping is implemented
|
||||
# mq_server_ip: { get_attribute: [ mq, server_ip ] }
|
||||
# for now, we will use the loopback address to avoid errors as
|
||||
# this property is required in the schema
|
||||
mq_server_ip: 127.0.0.1
|
||||
receiver_port: 8080
|
||||
# capabilities:
|
||||
# message_receiver:
|
||||
|
@ -42,10 +42,12 @@ class DataTypeTest(TestCase):
|
||||
properties:
|
||||
addresses:
|
||||
type: map
|
||||
required: false
|
||||
entry_schema:
|
||||
type: string
|
||||
contacts:
|
||||
type: list
|
||||
required: false
|
||||
entry_schema:
|
||||
type: tosca.my.datatypes.ContactInfo
|
||||
|
||||
@ -69,6 +71,15 @@ class DataTypeTest(TestCase):
|
||||
value = yamlparser.simple_parse(value_snippet)
|
||||
self.assertEqual(value, {})
|
||||
|
||||
# TODO(Matt) - opened as bug 1555300
|
||||
# Need a test for PortSpec normative data type
|
||||
# that tests the spec. requirement: "A valid PortSpec
|
||||
# must have at least one of the following properties:
|
||||
# target, target_range, source or source_range."
|
||||
# TODO(Matt) - opened as bug 1555310
|
||||
# test PortSpec value for source and target
|
||||
# against the source_range and target_range
|
||||
# when specified.
|
||||
def test_built_in_datatype(self):
|
||||
value_snippet = '''
|
||||
private_network:
|
||||
|
@ -10,6 +10,8 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from testtools import matchers
|
||||
|
||||
from toscaparser.common import exception
|
||||
from toscaparser.elements.property_definition import PropertyDef
|
||||
from toscaparser.nodetemplate import NodeTemplate
|
||||
@ -180,10 +182,12 @@ class PropertyTest(TestCase):
|
||||
def test_timestamp_invalid(self):
|
||||
test_property_schema = {'type': 'timestamp'}
|
||||
# invalid timestamp - day out of range
|
||||
propertyInstance = Property('test_property', '2015-04-115T02:59:43.1Z',
|
||||
value = '2015-04-115T02:59:43.1Z'
|
||||
propertyInstance = Property('test_property', value,
|
||||
test_property_schema)
|
||||
error = self.assertRaises(ValueError, propertyInstance.validate)
|
||||
self.assertEqual(_('day is out of range for month'), str(error))
|
||||
expected_message = (_('"%s" is not a valid timestamp.') % value)
|
||||
self.assertThat(str(error), matchers.StartsWith(expected_message))
|
||||
|
||||
def test_required(self):
|
||||
test_property_schema = {'type': 'string'}
|
||||
|
@ -63,6 +63,11 @@ class ToscaDefTest(TestCase):
|
||||
self.assertIn(ifaces.LIFECYCLE_SHORTNAME, group_type.interfaces)
|
||||
|
||||
def test_capabilities(self):
|
||||
# Assure the normative Compute node type
|
||||
# has all the required Capability types
|
||||
# regardless of symbloc name
|
||||
# TODO(Matt) - since Compute IS a normative node type
|
||||
# we SHOULD test symbolic capability names as well
|
||||
self.assertEqual(
|
||||
['tosca.capabilities.Container',
|
||||
'tosca.capabilities.Node',
|
||||
@ -70,34 +75,29 @@ class ToscaDefTest(TestCase):
|
||||
'tosca.capabilities.Scalable',
|
||||
'tosca.capabilities.network.Bindable'],
|
||||
sorted([c.type for c in compute_type.get_capabilities_objects()]))
|
||||
# Assure the normative Network node type
|
||||
# hsa all the required Capability types
|
||||
# TODO(Matt) - since Network IS a normative node type
|
||||
# we SHOULD test symbolic capability names as well
|
||||
self.assertEqual(
|
||||
['tosca.capabilities.Node',
|
||||
'tosca.capabilities.network.Linkable'],
|
||||
sorted([c.type for c in network_type.get_capabilities_objects()]))
|
||||
endpoint_properties = ['initiator', 'network_name', 'port',
|
||||
'port_name', 'ports', 'protocol',
|
||||
'secure', 'url_path']
|
||||
|
||||
# Assure the normative WebServer node type's
|
||||
# Endpoint cap. has all required property names
|
||||
# Note: we are testing them in alphabetic sort order
|
||||
endpoint_props_def_objects = \
|
||||
self._get_capability_properties_def_objects(
|
||||
webserver_type.get_capabilities_objects(),
|
||||
'tosca.capabilities.Endpoint')
|
||||
# Assure WebServer's Endpoint capability's properties have their
|
||||
# required keyname value set correctly
|
||||
self.assertEqual(
|
||||
endpoint_properties,
|
||||
sorted([p.name for p in endpoint_props_def_objects]))
|
||||
for p in endpoint_props_def_objects:
|
||||
if p.name in endpoint_properties:
|
||||
self.assertFalse(p.required)
|
||||
endpoint_props_def = self._get_capability_properties_def(
|
||||
webserver_type.get_capabilities_objects(),
|
||||
'tosca.capabilities.Endpoint')
|
||||
self.assertEqual(
|
||||
endpoint_properties,
|
||||
sorted(endpoint_props_def.keys()))
|
||||
endpoint_prop_def = self._get_capability_property_def(
|
||||
webserver_type.get_capabilities_objects(),
|
||||
'tosca.capabilities.Endpoint',
|
||||
'initiator')
|
||||
self.assertEqual(None, endpoint_prop_def)
|
||||
[('initiator', False), ('network_name', False), ('port', False),
|
||||
('port_name', False), ('ports', False), ('protocol', True),
|
||||
('secure', False), ('url_path', False)],
|
||||
sorted([(p.name, p.required) for p in endpoint_props_def_objects]))
|
||||
|
||||
os_props = self._get_capability_properties_def_objects(
|
||||
compute_type.get_capabilities_objects(),
|
||||
@ -139,14 +139,6 @@ class ToscaDefTest(TestCase):
|
||||
break
|
||||
return properties_def
|
||||
|
||||
def _get_capability_property_def(self, caps, type, property):
|
||||
property_def = None
|
||||
for cap in caps:
|
||||
if cap.type == type:
|
||||
property_def = cap.get_property_def_value(property)
|
||||
break
|
||||
return property_def
|
||||
|
||||
def test_properties_def(self):
|
||||
self.assertEqual(
|
||||
['name', 'password', 'port', 'user'],
|
||||
|
@ -348,6 +348,11 @@ class ToscaTemplateTest(TestCase):
|
||||
NotImplementedError,
|
||||
lambda: NodeTemplate(tpl_name, nodetemplates).relationships)
|
||||
|
||||
# Test the following:
|
||||
# 1. Custom node type derived from 'WebApplication' named 'TestApp'
|
||||
# with a custom Capability Type 'TestCapability'
|
||||
# 2. Same as #1, but referencing a custom 'TestCapability' Capability Type
|
||||
# that is not defined
|
||||
def test_custom_capability_type_definition(self):
|
||||
tpl_snippet = '''
|
||||
node_templates:
|
||||
@ -358,7 +363,7 @@ class ToscaTemplateTest(TestCase):
|
||||
properties:
|
||||
test: 1
|
||||
'''
|
||||
# custom definition with capability type definition
|
||||
# custom node type definition with custom capability type definition
|
||||
custom_def = '''
|
||||
tosca.nodes.WebApplication.TestApp:
|
||||
derived_from: tosca.nodes.WebApplication
|
||||
@ -383,7 +388,7 @@ class ToscaTemplateTest(TestCase):
|
||||
expected_capabilities,
|
||||
sorted(tpl.get_capabilities().keys()))
|
||||
|
||||
# custom definition without capability type definition
|
||||
# custom definition without valid capability type definition
|
||||
custom_def = '''
|
||||
tosca.nodes.WebApplication.TestApp:
|
||||
derived_from: tosca.nodes.WebApplication
|
||||
|
@ -89,7 +89,19 @@ def validate_boolean(value):
|
||||
|
||||
|
||||
def validate_timestamp(value):
|
||||
return dateutil.parser.parse(value)
|
||||
try:
|
||||
# Note: we must return our own exception message
|
||||
# as dateutil's parser returns different types / values on
|
||||
# different systems. OSX, for example, returns a tuple
|
||||
# containing a different error message than Linux
|
||||
dateutil.parser.parse(value)
|
||||
except Exception as e:
|
||||
original_err_msg = str(e)
|
||||
log.error(original_err_msg)
|
||||
ExceptionCollector.appendException(
|
||||
ValueError(_('"%(val)s" is not a valid timestamp. "%(msg)s"') %
|
||||
{'val': value, 'msg': original_err_msg}))
|
||||
return
|
||||
|
||||
|
||||
class TOSCAVersionProperty(object):
|
||||
|
Loading…
x
Reference in New Issue
Block a user