Merge "Runtime properties may no longer have default value"
This commit is contained in:
commit
fdb2cff7e1
@ -126,5 +126,5 @@ class PropertyWriteError(PropertyAccessError):
|
|||||||
class UninitializedPropertyAccessError(PropertyAccessError):
|
class UninitializedPropertyAccessError(PropertyAccessError):
|
||||||
def __init__(self, name, murano_class):
|
def __init__(self, name, murano_class):
|
||||||
super(PropertyAccessError, self).__init__(
|
super(PropertyAccessError, self).__init__(
|
||||||
'Access to private uninitialized property '
|
'Access to uninitialized property '
|
||||||
'%s in class %s is forbidden' % (name, murano_class.name))
|
'%s in class %s is forbidden' % (name, murano_class.name))
|
||||||
|
@ -54,17 +54,27 @@ class MuranoObject(object):
|
|||||||
for i in xrange(2):
|
for i in xrange(2):
|
||||||
for property_name in self.__type.properties:
|
for property_name in self.__type.properties:
|
||||||
spec = self.__type.get_property(property_name)
|
spec = self.__type.get_property(property_name)
|
||||||
if spec.usage == typespec.PropertyUsages.Runtime:
|
|
||||||
continue
|
|
||||||
needs_evaluation = murano.dsl.helpers.needs_evaluation
|
needs_evaluation = murano.dsl.helpers.needs_evaluation
|
||||||
if i == 0 and needs_evaluation(spec.default) or i == 1\
|
if i == 0 and needs_evaluation(spec.default) or i == 1\
|
||||||
and property_name in used_names:
|
and property_name in used_names:
|
||||||
continue
|
continue
|
||||||
used_names.add(property_name)
|
used_names.add(property_name)
|
||||||
property_value = kwargs.get(property_name, type_scheme.NoValue)
|
if spec.usage == typespec.PropertyUsages.Runtime:
|
||||||
|
if not spec.has_default:
|
||||||
|
continue
|
||||||
|
property_value = type_scheme.NoValue
|
||||||
|
else:
|
||||||
|
property_value = kwargs.get(property_name,
|
||||||
|
type_scheme.NoValue)
|
||||||
|
try:
|
||||||
self.set_property(property_name, property_value)
|
self.set_property(property_name, property_value)
|
||||||
|
except exceptions.ContractViolationException:
|
||||||
|
if spec.usage != typespec.PropertyUsages.Runtime:
|
||||||
|
raise
|
||||||
|
|
||||||
for parent in self.__parents.values():
|
for parent in self.__parents.values():
|
||||||
parent.initialize(**kwargs)
|
parent.initialize(**kwargs)
|
||||||
|
self.__initialized = True
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def object_id(self):
|
def object_id(self):
|
||||||
@ -93,7 +103,7 @@ class MuranoObject(object):
|
|||||||
if caller_class is not None and caller_class.is_compatible(self):
|
if caller_class is not None and caller_class.is_compatible(self):
|
||||||
start_type, derived = caller_class, True
|
start_type, derived = caller_class, True
|
||||||
if name in start_type.properties:
|
if name in start_type.properties:
|
||||||
return self.cast(start_type).__properties[name]
|
return self.cast(start_type)._get_property_value(name)
|
||||||
else:
|
else:
|
||||||
declared_properties = start_type.find_property(name)
|
declared_properties = start_type.find_property(name)
|
||||||
if len(declared_properties) == 1:
|
if len(declared_properties) == 1:
|
||||||
@ -101,14 +111,17 @@ class MuranoObject(object):
|
|||||||
elif len(declared_properties) > 1:
|
elif len(declared_properties) > 1:
|
||||||
raise exceptions.AmbiguousPropertyNameError(name)
|
raise exceptions.AmbiguousPropertyNameError(name)
|
||||||
elif derived:
|
elif derived:
|
||||||
try:
|
return self.cast(caller_class)._get_property_value(name)
|
||||||
return self.cast(caller_class).__properties[name]
|
|
||||||
except KeyError:
|
|
||||||
raise exceptions.UninitializedPropertyAccessError(
|
|
||||||
name, start_type)
|
|
||||||
else:
|
else:
|
||||||
raise exceptions.PropertyReadError(name, start_type)
|
raise exceptions.PropertyReadError(name, start_type)
|
||||||
|
|
||||||
|
def _get_property_value(self, name):
|
||||||
|
try:
|
||||||
|
return self.__properties[name]
|
||||||
|
except KeyError:
|
||||||
|
raise exceptions.UninitializedPropertyAccessError(
|
||||||
|
name, self.__type)
|
||||||
|
|
||||||
def set_property(self, name, value, caller_class=None):
|
def set_property(self, name, value, caller_class=None):
|
||||||
start_type, derived = self.__type, False
|
start_type, derived = self.__type, False
|
||||||
if caller_class is not None and caller_class.is_compatible(self):
|
if caller_class is not None and caller_class.is_compatible(self):
|
||||||
|
@ -1,11 +1,43 @@
|
|||||||
Name: PropertyInit
|
Name: PropertyInit
|
||||||
|
|
||||||
Properties:
|
Properties:
|
||||||
runtimeProperty:
|
runtimePropertyWithoutDefault:
|
||||||
Usage: Runtime
|
Usage: Runtime
|
||||||
Contract: $.string()
|
Contract: $.string()
|
||||||
|
|
||||||
|
runtimePropertyWithStrictContractWithoutDefault:
|
||||||
|
Usage: Runtime
|
||||||
|
Contract: $.string().notNull()
|
||||||
|
|
||||||
|
runtimeProperty2WithStrictContractWithoutDefault:
|
||||||
|
Usage: Runtime
|
||||||
|
Contract: $.string().notNull()
|
||||||
|
|
||||||
|
agentListener:
|
||||||
|
Contract: $.class('io.murano.system.AgentListener')
|
||||||
|
|
||||||
|
runtimePropertyWithStrictContractAndDefault:
|
||||||
|
Usage: Runtime
|
||||||
|
Contract: $.string().notNull()
|
||||||
|
Default: DEFAULT
|
||||||
|
|
||||||
Methods:
|
Methods:
|
||||||
testPropertyAccess:
|
initialize:
|
||||||
Body:
|
Body:
|
||||||
- Return: $this.runtimeProperty
|
$.runtimePropertyWithStrictContractWithoutDefault: VALUE
|
||||||
|
|
||||||
|
testRuntimePropertyWithoutDefault:
|
||||||
|
Body:
|
||||||
|
- Return: $this.runtimePropertyWithoutDefault
|
||||||
|
|
||||||
|
testRuntimePropertyDefault:
|
||||||
|
Body:
|
||||||
|
- Return: $this.runtimePropertyWithStrictContractAndDefault
|
||||||
|
|
||||||
|
testRuntimePropertyWithStrictContractWithoutDefault:
|
||||||
|
Body:
|
||||||
|
- Return: $this.runtimePropertyWithStrictContractWithoutDefault
|
||||||
|
|
||||||
|
testUninitializedRuntimeProperty:
|
||||||
|
Body:
|
||||||
|
- Return: $this.runtimeProperty2WithStrictContractWithoutDefault
|
||||||
|
@ -41,7 +41,7 @@ class TestPropertyAccess(test_case.DslTestCase):
|
|||||||
exceptions.UninitializedPropertyAccessError,
|
exceptions.UninitializedPropertyAccessError,
|
||||||
self._runner.testUninitializedPrivatePropertyAccess)
|
self._runner.testUninitializedPrivatePropertyAccess)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
'Access to private uninitialized property privateName '
|
'Access to uninitialized property privateName '
|
||||||
'in class SampleClass3 is forbidden', str(e))
|
'in class SampleClass3 is forbidden', str(e))
|
||||||
|
|
||||||
def test_read_of_private_property_of_other_class(self):
|
def test_read_of_private_property_of_other_class(self):
|
||||||
@ -113,8 +113,3 @@ class TestPropertyAccess(test_case.DslTestCase):
|
|||||||
exceptions.NoWriteAccessError,
|
exceptions.NoWriteAccessError,
|
||||||
self._runner.on(self._multi_derived).
|
self._runner.on(self._multi_derived).
|
||||||
testModifyUsageTestProperty6)
|
testModifyUsageTestProperty6)
|
||||||
|
|
||||||
def test_runtime_properties_skipped_on_initialize(self):
|
|
||||||
model = om.Object('PropertyInit', runtimeProperty='value')
|
|
||||||
runner = self.new_runner(model)
|
|
||||||
self.assertRaises(KeyError, runner.testPropertyAccess)
|
|
||||||
|
46
murano/tests/unit/dsl/test_property_inititialization.py
Normal file
46
murano/tests/unit/dsl/test_property_inititialization.py
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
# Copyright (c) 2014 Mirantis, Inc.
|
||||||
|
#
|
||||||
|
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
# not use this file except in compliance with the License. You may obtain
|
||||||
|
# a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing, software
|
||||||
|
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
# License for the specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
|
||||||
|
from murano.dsl import exceptions
|
||||||
|
from murano.tests.unit.dsl.foundation import object_model as om
|
||||||
|
from murano.tests.unit.dsl.foundation import test_case
|
||||||
|
|
||||||
|
|
||||||
|
class TestPropertyInitialization(test_case.DslTestCase):
|
||||||
|
def setUp(self):
|
||||||
|
super(TestPropertyInitialization, self).setUp()
|
||||||
|
model = om.Object(
|
||||||
|
'PropertyInit'
|
||||||
|
)
|
||||||
|
self._runner = self.new_runner(model)
|
||||||
|
|
||||||
|
def test_runtime_property_default(self):
|
||||||
|
self.assertEqual(
|
||||||
|
'DEFAULT',
|
||||||
|
self._runner.testRuntimePropertyDefault())
|
||||||
|
|
||||||
|
def test_runtime_property_without_default(self):
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.UninitializedPropertyAccessError,
|
||||||
|
self._runner.testRuntimePropertyWithoutDefault)
|
||||||
|
|
||||||
|
def test_runtime_property_with_strict_contract_without_default(self):
|
||||||
|
self.assertEqual(
|
||||||
|
'VALUE',
|
||||||
|
self._runner.testRuntimePropertyWithStrictContractWithoutDefault())
|
||||||
|
|
||||||
|
def test_uninitialized_runtime_property_with_strict_contract(self):
|
||||||
|
self.assertRaises(
|
||||||
|
exceptions.UninitializedPropertyAccessError,
|
||||||
|
self._runner.testUninitializedRuntimeProperty)
|
Loading…
Reference in New Issue
Block a user