You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ariatosca.apache.org by mx...@apache.org on 2017/05/22 14:52:07 UTC
[1/4] incubator-ariatosca git commit: fixed dict
Repository: incubator-ariatosca
Updated Branches:
refs/heads/ARIA-258-Convert-runtime-properties-to-attributes ff3d9647d -> 0b1a306f6
fixed dict
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/b2014b93
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/b2014b93
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/b2014b93
Branch: refs/heads/ARIA-258-Convert-runtime-properties-to-attributes
Commit: b2014b9341398a431703c1ff7cde3722b72c53bc
Parents: ff3d964
Author: max-orlov <ma...@gigaspaces.com>
Authored: Mon May 22 14:28:44 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Mon May 22 14:28:44 2017 +0300
----------------------------------------------------------------------
aria/orchestrator/context/common.py | 181 +++++++---------------
tests/orchestrator/context/test_operation.py | 78 ++++++----
2 files changed, 108 insertions(+), 151 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b2014b93/aria/orchestrator/context/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py
index e1dbf5f..d85f284 100644
--- a/aria/orchestrator/context/common.py
+++ b/aria/orchestrator/context/common.py
@@ -202,146 +202,78 @@ class BaseContext(object):
self.model.log._engine.dispose()
-class _InstrumentedCollection(dict):
- def __init__(self, parent, model, actor=None, field_name=None, nested_key=None, **kwargs):
- super(_InstrumentedCollection, self).__init__(**kwargs)
-
- self._parent = parent
+class _InstrumentedDict(dict):
+ def __init__(self, model, parent, field_name=None, item_cls=None, seq=None, **kwargs):
self._model = model
- self._item_cls = self._model.parameter.model_cls
- self._nested_key = nested_key
-
- # Actor is not None only at the top level, where it should be updated
- self._actor = actor
+ self._parent = parent
self._field_name = field_name
- if self._actor:
- # Only the root parent has an _actor
- self._init_from_parent()
-
- def __getitem__(self, key):
- if self._nested_key is None:
- value = self._parent[key].value
- elif isinstance(self, dict):
- value = dict.__getitem__(self, key)
- else:
- raise BaseException()
-
- if isinstance(value, (list, _InstrumentedList)):
- return _InstrumentedList(self, self._model, nested_key=key, _list=value)
- elif isinstance(value, dict):
- return _InstrumentedDict(self, self._model, nested_key=key, **value)
- else:
- return value
-
- def _set(self, i, y):
- self._insert(i, y)
- if self._nested_key is None:
- nested_key = i
- if not isinstance(y, self._item_cls):
- y = self._item_cls.wrap(i, y)
- self._model.parameter.put(y)
- else:
- nested_key = self._nested_key
-
- self._update_parent(nested_key, i, y)
- return y
-
- def _init_from_parent(self):
- for key, value in self._parent.items():
- self._insert(key, value)
-
- def _insert(self, key, value):
- value = value.value if isinstance(value, self._item_cls) else value
- super(_InstrumentedCollection, self).__setitem__(key, value)
-
- def _update_parent(self, nested_key, key, value):
- if isinstance(self._parent, _InstrumentedCollection):
- self._parent._update_from_child(nested_key, {key: value})
- else:
- if self._nested_key is not None:
- self._parent[nested_key] = {key: value}
- else:
- self._parent[key] = value
-
- def _update_from_child(self, nested_key, value):
- self[nested_key] = value
- if isinstance(value, self._item_cls):
- # We are the the top level
- getattr(self._actor, self._field_name)[nested_key] = value
- self._model.parameter.update(value)
+ self._item_cls = item_cls
+ self._load(seq, **kwargs)
- def _update_actor(self, key, value):
- raise NotImplementedError
+ def _load(self, seq=None, **kwargs):
+ seq = dict((key, value.value if isinstance(value, self._item_cls) else value)
+ for key, value in (seq or {}).items())
+ super(_InstrumentedDict, self).__init__(seq, **kwargs)
- def __setitem__(self, key, value):
- value = self._set(key, value)
-
- if self._actor:
- self._update_actor(key, value)
-
- if isinstance(value, self._item_cls):
- self._model.parameter.update(value)
-
-
-class _InstrumentedDict(_InstrumentedCollection):
- """
- Dict implementation for instrumented collection
- """
def update(self, E=None, **F):
- dict_ = E or {}
- dict_.update(F.copy())
- for key, value in dict_.items():
+ E = E or {}
+ for key, value in E.items():
+ self[key] = value
+ for key, value in F.items():
self[key] = value
- def clear(self):
- self._parent.get(self._nested_key, {}).clear()
- dict.clear(self)
-
- def _update_actor(self, key, value):
- getattr(self._actor, self._field_name)[key] = value
+ def __getitem__(self, key):
+ value = dict.__getitem__(self, key)
+ if isinstance(value, _InstrumentedDict):
+ return value
+ elif isinstance(value, dict):
+ return _InstrumentedDict(self._model, self, key, seq=value)
+ return value
+ def values(self):
+ return [self[key] for key in self.keys()]
-class _InstrumentedList(_InstrumentedDict):
- """
- List implementation of instrumented collection
- """
- def __init__(self, parent, *args, **kwargs):
- list_ = kwargs.pop('_list', [])
- if isinstance(parent, list):
- parent = list(enumerate(parent))
- super(_InstrumentedList, self).__init__(parent, *args, **kwargs)
- for item in list_:
- self.append(item)
+ def items(self):
+ return [(key, self[key]) for key in self.keys()]
def __iter__(self):
- for _, item in sorted(self.items(), cmp=lambda item: item[0]):
- yield item
+ return (key for key in self.keys())
- def _update_actor(self, key, value):
- field = getattr(self._actor, self._field_name)
- if key < len(field):
- field[key] = value
- else:
- field.insert(key, value)
+ def _set(self, key, value):
+ if self._item_cls and isinstance(value, self._item_cls):
+ value = value.value
+ dict.__setitem__(self, key, value)
- def _init_from_parent(self):
- for item in self._parent:
- self.append(item)
+ def __setitem__(self, key, value):
+ self._set(key, value)
+ def _set_parent(value):
+ if key in field and isinstance(field[key], self._item_cls):
+ if isinstance(field[key], dict):
+ field[key].clear()
+ field[key].value = value
+ else:
+ field[key] = value
+ return field[key]
- def append(self, item):
- self._set(len(self), item)
+ if self._item_cls:
+ # We are at the top level
+ field = getattr(self._parent, self._field_name)
+ mapi = getattr(self._model, self._item_cls.__modelname__)
- def _update_parent(self, nested_key, key, value):
- if isinstance(self._parent, _InstrumentedCollection):
- self._parent._update_from_child(nested_key, {key: value})
- else:
- if self._nested_key is not None:
- self._parent[nested_key] = {key: value}
+ if key in field:
+ # Is this a existing field
+ value = _set_parent(value)
else:
- self._parent.insert(key, value)
+ if not isinstance(value, self._item_cls):
+ # If it is not wrapped
+ value = self._item_cls.wrap(key, value)
+ value = _set_parent(value)
- def __repr__(self):
- return repr(list(self))
+ mapi.update(value)
+ else:
+ dict.__setitem__(self, key, value)
+ # We are not at the top level
+ self._parent[self._field_name] = self
class InstrumentCollection(object):
@@ -370,10 +302,9 @@ class InstrumentCollection(object):
setattr(self, '_{0}'.format(self._field_name), field)
# set instrumented value
- inst_cls = _InstrumentedDict if isinstance(field, dict) else _InstrumentedList
setattr(
self,
self._field_name,
- inst_cls(field, func_self.model, actor=self._actor, field_name=self._field_name))
+ _InstrumentedDict(func_self.model, self._actor, field_name=self._field_name, item_cls=modeling.models.Parameter, seq=field))
return self
return _wrapper
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/b2014b93/tests/orchestrator/context/test_operation.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_operation.py b/tests/orchestrator/context/test_operation.py
index 72b8efe..da78199 100644
--- a/tests/orchestrator/context/test_operation.py
+++ b/tests/orchestrator/context/test_operation.py
@@ -351,7 +351,7 @@ def test_attribute_consumption(ctx, executor, dataholder):
source_node = ctx.model.node.get_by_name(mock.models.DEPENDENT_NODE_NAME)
- inputs = {'attributes_dict': {'key': 'value'}}
+ inputs = {'dict_': {'key': 'value'}}
interface = mock.models.create_interface(
source_node.service,
node_int_name,
@@ -489,8 +489,8 @@ def _test_plugin_workdir(ctx, filename, content):
@operation
-def attribute_altering_operation(ctx, attributes_dict, **_):
- ctx.node.attributes.update(attributes_dict)
+def attribute_altering_operation(ctx, dict_, **_):
+ ctx.node.attributes.update(dict_)
@operation
@@ -502,7 +502,7 @@ def attribute_consuming_operation(ctx, holder_path, **_):
class MockActor(object):
def __init__(self):
- self.attributes_dict = {}
+ self.dict_ = {}
self.attributes_list = []
@@ -526,24 +526,25 @@ class TestDict(object):
@pytest.fixture
def dict_(self, actor, model):
- return common._InstrumentedDict(
- actor.attributes_dict, model, actor=actor, field_name='attributes_dict')
+ return common._InstrumentedDict(model, actor, 'dict_', item_cls=Parameter)
- def test_keys(self, dict_):
+ def test_keys(self, actor, dict_):
dict_.update(
{
'key1': Parameter.wrap('key1', 'value1'),
'key2': Parameter.wrap('key2', 'value2')
}
)
- assert sorted(dict_.keys()) == sorted(['key1', 'key2'])
+ assert sorted(dict_.keys()) == sorted(['key1', 'key2']) == sorted(actor.dict_.keys())
- def test_values(self, dict_):
+ def test_values(self, actor, dict_):
dict_.update({
'key1': Parameter.wrap('key1', 'value1'),
'key2': Parameter.wrap('key1', 'value2')
})
- assert sorted(dict_.values()) == sorted(['value1', 'value2'])
+ assert (sorted(dict_.values()) ==
+ sorted(['value1', 'value2']) ==
+ sorted(v.value for v in actor.dict_.values()))
def test_items(self, dict_):
dict_.update({
@@ -552,12 +553,12 @@ class TestDict(object):
})
assert sorted(dict_.items()) == sorted([('key1', 'value1'), ('key2', 'value2')])
- def test_iter(self, dict_):
+ def test_iter(self, actor, dict_):
dict_.update({
'key1': Parameter.wrap('key1', 'value1'),
'key2': Parameter.wrap('key1', 'value2')
})
- assert sorted(list(dict_)) == sorted(['key1', 'key2'])
+ assert sorted(list(dict_)) == sorted(['key1', 'key2']) == sorted(actor.dict_.keys())
def test_bool(self, dict_):
assert not dict_
@@ -567,33 +568,58 @@ class TestDict(object):
})
assert dict_
- def test_set_item(self, dict_):
+ def test_set_item(self, actor, dict_):
dict_['key1'] = Parameter.wrap('key1', 'value1')
- assert dict_['key1'] == 'value1'
- assert isinstance(dict_._parent['key1'], Parameter)
+ assert dict_['key1'] == 'value1' == actor.dict_['key1'].value
+ assert isinstance(actor.dict_['key1'], Parameter)
- dict_['key1'] = {}
- dict_['key1']['inner_key'] = 'value2'
+ def test_nested(self, actor, dict_):
+ dict_['key'] = {}
+ assert isinstance(actor.dict_['key'], Parameter)
+ assert dict_['key'] == actor.dict_['key'].value == {}
- assert isinstance(dict_._parent['key1'], Parameter)
+ dict_['key']['inner_key'] = 'value'
+
+ assert len(dict_) == 1
+ assert 'inner_key' in dict_['key']
+ assert dict_['key']['inner_key'] == 'value'
+ assert dict_['key'].keys() == ['inner_key']
+ assert dict_['key'].values() == ['value']
+ assert dict_['key'].items() == [('inner_key', 'value')]
+ assert isinstance(actor.dict_['key'], Parameter)
+ assert isinstance(dict_['key'], common._InstrumentedDict)
+
+ dict_['key'].update({'updated_key': 'updated_value'})
assert len(dict_) == 1
- assert 'inner_key' in dict_['key1']
- assert isinstance(dict_['key1'], common._InstrumentedDict)
- assert dict_['key1']['inner_key'] == 'value2'
+ assert 'updated_key' in dict_['key']
+ assert dict_['key']['updated_key'] == 'updated_value'
+ assert sorted(dict_['key'].keys()) == sorted(['inner_key', 'updated_key'])
+ assert sorted(dict_['key'].values()) == sorted(['value', 'updated_value'])
+ assert sorted(dict_['key'].items()) == sorted([('inner_key', 'value'),
+ ('updated_key', 'updated_value')])
+ assert isinstance(actor.dict_['key'], Parameter)
+ assert isinstance(dict_['key'], common._InstrumentedDict)
+
+ dict_.update({'key': 'override_value'})
+ assert len(dict_) == 1
+ assert 'key' in dict_
+ assert dict_['key'] == 'override_value'
+ assert len(actor.dict_) == 1
+ assert isinstance(actor.dict_['key'], Parameter)
+ assert actor.dict_['key'].value == 'override_value'
- def test_get_item(self, dict_):
+ def test_get_item(self, actor,dict_):
dict_['key1'] = Parameter.wrap('key1', 'value1')
+ assert isinstance(actor.dict_['key1'], Parameter)
- assert isinstance(dict_._parent['key1'], Parameter)
-
- def test_update(self, dict_):
+ def test_update(self, actor, dict_):
dict_['key1'] = 'value1'
new_dict = {'key2': 'value2'}
dict_.update(new_dict)
assert len(dict_) == 2
assert dict_['key2'] == 'value2'
- assert isinstance(dict_._parent['key2'], Parameter)
+ assert isinstance(actor.dict_['key2'], Parameter)
new_dict = {}
new_dict.update(dict_)
[2/4] incubator-ariatosca git commit: added list support
Posted by mx...@apache.org.
added list support
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/82d96166
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/82d96166
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/82d96166
Branch: refs/heads/ARIA-258-Convert-runtime-properties-to-attributes
Commit: 82d9616661d1c6797e1d5561a5379b97b0070942
Parents: b2014b9
Author: max-orlov <ma...@gigaspaces.com>
Authored: Mon May 22 15:21:53 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Mon May 22 15:21:53 2017 +0300
----------------------------------------------------------------------
aria/orchestrator/context/common.py | 128 ++++++++++++++++------
tests/orchestrator/context/test_operation.py | 44 ++++++--
2 files changed, 125 insertions(+), 47 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/82d96166/aria/orchestrator/context/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py
index d85f284..07596f6 100644
--- a/aria/orchestrator/context/common.py
+++ b/aria/orchestrator/context/common.py
@@ -202,7 +202,49 @@ class BaseContext(object):
self.model.log._engine.dispose()
-class _InstrumentedDict(dict):
+class _InstrumentedCollection(object):
+ def _get_instrumented_collection(self, key, value):
+ if isinstance(value, _InstrumentedCollection):
+ return value
+ elif isinstance(value, dict):
+ return _InstrumentedDict(self._model, self, key, seq=value)
+ elif isinstance(value, list):
+ return _InstrumentedList(self._model, self, key, seq=value)
+
+ return value
+
+ def _raw_value(self, value):
+ if self._item_cls and isinstance(value, self._item_cls):
+ return value.value
+ return value
+
+ def _encapsulate_value(self, key, value):
+ if isinstance(value, self._item_cls):
+ return value
+ # If it is not wrapped
+ return self._item_cls.wrap(key, value)
+
+ def __setitem__(self, key, value):
+ self._set(key, value)
+ if self._item_cls:
+ # We are at the top level
+ field = getattr(self._parent, self._field_name)
+ mapi = getattr(self._model, self._item_cls.__modelname__)
+
+ if key in field:
+ # Is this a existing field
+ value = self._set_parent(field, key, value)
+ else:
+ value = self._set_parent(field, key, self._encapsulate_value(key, value))
+
+ mapi.update(value)
+ else:
+ self._set(key, value)
+ # We are not at the top level
+ self._parent[self._field_name] = self
+
+
+class _InstrumentedDict(_InstrumentedCollection, dict):
def __init__(self, model, parent, field_name=None, item_cls=None, seq=None, **kwargs):
self._model = model
self._parent = parent
@@ -223,12 +265,7 @@ class _InstrumentedDict(dict):
self[key] = value
def __getitem__(self, key):
- value = dict.__getitem__(self, key)
- if isinstance(value, _InstrumentedDict):
- return value
- elif isinstance(value, dict):
- return _InstrumentedDict(self._model, self, key, seq=value)
- return value
+ return self._get_instrumented_collection(key, dict.__getitem__(self, key))
def values(self):
return [self[key] for key in self.keys()]
@@ -240,40 +277,55 @@ class _InstrumentedDict(dict):
return (key for key in self.keys())
def _set(self, key, value):
- if self._item_cls and isinstance(value, self._item_cls):
- value = value.value
- dict.__setitem__(self, key, value)
+ dict.__setitem__(self, key, self._raw_value(value))
- def __setitem__(self, key, value):
- self._set(key, value)
- def _set_parent(value):
- if key in field and isinstance(field[key], self._item_cls):
- if isinstance(field[key], dict):
- field[key].clear()
- field[key].value = value
- else:
- field[key] = value
- return field[key]
+ def _set_parent(self, field, key, value):
+ if key in field and isinstance(field[key], self._item_cls):
+ if isinstance(field[key], dict):
+ field[key].clear()
+ field[key].value = value
+ else:
+ field[key] = value
+ return field[key]
+
+
+class _InstrumentedList(list, _InstrumentedCollection):
+ def __init__(self, model, parent, field_name=None, item_cls=None, seq=None, **kwargs):
+ self._model = model
+ self._parent = parent
+ self._field_name = field_name
+ self._item_cls = item_cls
+ self._load(seq, **kwargs)
+
+ def _load(self, seq=None, **kwargs):
+ seq = list(item for item in seq or [])
+ super(_InstrumentedList, self).__init__(seq)
+
+ def append(self, value):
+ self.insert(len(self), value)
+ def insert(self, index, value):
+ list.insert(self, index, self._raw_value(value))
if self._item_cls:
- # We are at the top level
field = getattr(self._parent, self._field_name)
- mapi = getattr(self._model, self._item_cls.__modelname__)
+ field.insert(index, self._encapsulate_value(index, value))
+ else:
+ self._parent[self._field_name] = self
- if key in field:
- # Is this a existing field
- value = _set_parent(value)
- else:
- if not isinstance(value, self._item_cls):
- # If it is not wrapped
- value = self._item_cls.wrap(key, value)
- value = _set_parent(value)
+ def __getitem__(self, key):
+ return self._get_instrumented_collection(key, list.__getitem__(self, key))
- mapi.update(value)
+ def _set(self, key, value):
+ list.__setitem__(self, key, value)
+
+ def _set_parent(self, field, key, value):
+ if key in field and isinstance(field[key], self._item_cls):
+ if isinstance(field[key], list):
+ del field[key]
+ field[key].value = value
else:
- dict.__setitem__(self, key, value)
- # We are not at the top level
- self._parent[self._field_name] = self
+ field[key] = value
+ return field[key]
class InstrumentCollection(object):
@@ -305,6 +357,12 @@ class InstrumentCollection(object):
setattr(
self,
self._field_name,
- _InstrumentedDict(func_self.model, self._actor, field_name=self._field_name, item_cls=modeling.models.Parameter, seq=field))
+ _InstrumentedDict(
+ func_self.model,
+ self._actor,
+ field_name=self._field_name,
+ item_cls=modeling.models.Parameter,
+ seq=field)
+ )
return self
return _wrapper
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/82d96166/tests/orchestrator/context/test_operation.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_operation.py b/tests/orchestrator/context/test_operation.py
index da78199..73efff5 100644
--- a/tests/orchestrator/context/test_operation.py
+++ b/tests/orchestrator/context/test_operation.py
@@ -503,7 +503,7 @@ def attribute_consuming_operation(ctx, holder_path, **_):
class MockActor(object):
def __init__(self):
self.dict_ = {}
- self.attributes_list = []
+ self.list_ = []
class MockModel(object):
@@ -654,37 +654,57 @@ class TestList(object):
@pytest.fixture
def list_(self, actor, model):
- return common._InstrumentedList(
- actor.attributes_list, model, actor=actor, field_name='attributes_list')
+ return common._InstrumentedList(model, actor, field_name='list_', item_cls=Parameter)
- def test_insert(self, list_):
+ def test_append(self, actor, list_):
list_.append(Parameter.wrap('name', 'value1'))
list_.append('value2')
-
+ assert len(actor.list_) == 2
assert len(list_) == 2
- assert isinstance(list_._parent[0], Parameter)
+ assert isinstance(actor.list_[0], Parameter)
assert list_[0] == 'value1'
- assert isinstance(list_._parent[1], Parameter)
+ assert isinstance(actor.list_[1], Parameter)
assert list_[1] == 'value2'
list_[0] = 'new_value1'
list_[1] = 'new_value2'
- assert isinstance(list_._parent[1], Parameter)
- assert isinstance(list_._parent[1], Parameter)
+ assert isinstance(actor.list_[1], Parameter)
+ assert isinstance(actor.list_[1], Parameter)
assert list_[0] == 'new_value1'
assert list_[1] == 'new_value2'
- def test_insert_into_nested(self, list_):
+ def test_iter(self, list_):
+ list_.append('value1')
+ list_.append('value2')
+ assert sorted(list_) == sorted(['value1', 'value2'])
+
+ def test_insert(self, actor, list_):
+ list_.append('value1')
+ list_.insert(0, 'value2')
+ list_.insert(2, 'value3')
+ list_.insert(10, 'value4')
+ assert sorted(list_) == sorted(['value1', 'value2', 'value3', 'value4'])
+ assert len(actor.list_) == 4
+
+ def test_set(self, list_):
+ list_.append('value1')
+ list_.append('value2')
+
+ list_[1] = 'value3'
+ assert len(list_) == 2
+ assert sorted(list_) == sorted(['value1', 'value3'])
+
+ def test_insert_into_nested(self, actor, list_):
list_.append([])
list_[0].append('inner_item')
- assert isinstance(list_._parent[0], Parameter)
+ assert isinstance(actor.list_[0], Parameter)
assert len(list_) == 1
assert list_[0][0] == 'inner_item'
list_[0].append('new_item')
- assert isinstance(list_._parent[0], Parameter)
+ assert isinstance(actor.list_[0], Parameter)
assert len(list_) == 1
assert list_[0][1] == 'new_item'
[4/4] incubator-ariatosca git commit: created new module and linting
Posted by mx...@apache.org.
created new module and linting
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/0b1a306f
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/0b1a306f
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/0b1a306f
Branch: refs/heads/ARIA-258-Convert-runtime-properties-to-attributes
Commit: 0b1a306f6905fbe838e96108f65d47cf075efdbb
Parents: 4e85105
Author: max-orlov <ma...@gigaspaces.com>
Authored: Mon May 22 17:52:02 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Mon May 22 17:52:02 2017 +0300
----------------------------------------------------------------------
aria/orchestrator/context/common.py | 144 ++++++-----
.../context/test_attribute_suggaring.py | 253 +++++++++++++++++++
tests/orchestrator/context/test_operation.py | 236 -----------------
3 files changed, 331 insertions(+), 302 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0b1a306f/aria/orchestrator/context/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py
index a5c01fa..8b83883 100644
--- a/aria/orchestrator/context/common.py
+++ b/aria/orchestrator/context/common.py
@@ -16,9 +16,7 @@
"""
A common context for both workflow and operation
"""
-import copy
import logging
-import collections
from contextlib import contextmanager
from functools import partial
@@ -219,41 +217,38 @@ class _InstrumentedCollection(object):
self._is_top_level = is_top_level
self._load(seq, **kwargs)
+ @property
+ def _raw(self):
+ raise NotImplementedError
+
def _load(self, seq, **kwargs):
"""
Instantiates the object from existing seq.
-
- :param seq: the original sequence to load from
- :return:
- """
- raise NotImplementedError
- def _set_field(self, collection, key, value):
- """
- enables updating the current change in the ancestors
- :param collection: the collection to change
- :param key: the key for the specific field
- :param value: the new value
- :return:
+ :param seq: the original sequence to load from
+ :return:
"""
raise NotImplementedError
def _set(self, key, value):
"""
set the changes for the current object (not in the db)
-
- :param key:
- :param value:
- :return:
+
+ :param key:
+ :param value:
+ :return:
"""
raise NotImplementedError
+ def _del(self, collection, key):
+ raise NotImplementedError
+
def _instrument(self, key, value):
"""
Instruments any collection to track changes (and ease of access)
- :param key:
- :param value:
- :return:
+ :param key:
+ :param value:
+ :return:
"""
if isinstance(value, _InstrumentedCollection):
return value
@@ -268,9 +263,9 @@ class _InstrumentedCollection(object):
def _raw_value(self, value):
"""
- Get the raw value.
- :param value:
- :return:
+ Get the raw value.
+ :param value:
+ :return:
"""
if self._is_top_level and isinstance(value, self._item_cls):
return value.value
@@ -279,9 +274,9 @@ class _InstrumentedCollection(object):
def _encapsulate_value(self, key, value):
"""
Create a new item cls if needed.
- :param key:
- :param value:
- :return:
+ :param key:
+ :param value:
+ :return:
"""
if isinstance(value, self._item_cls):
return value
@@ -290,30 +285,53 @@ class _InstrumentedCollection(object):
def __setitem__(self, key, value):
"""
- Update the values in both the local and the db locations.
- :param key:
- :param value:
- :return:
+ Update the values in both the local and the db locations.
+ :param key:
+ :param value:
+ :return:
"""
self._set(key, value)
- mapi = getattr(self._model, self._item_cls.__modelname__)
if self._is_top_level:
- field = getattr(self._parent, self._field_name)
# We are at the top level
- if key in field:
- # Is this a existing field
- value = self._set_field(field, key, value)
- else:
- value = self._set_field(field, key, self._encapsulate_value(key, value))
+ field = getattr(self._parent, self._field_name)
+ mapi = getattr(self._model, self._item_cls.__modelname__)
+ value = self._set_field(field,
+ key,
+ value if key in field else self._encapsulate_value(key, value))
+ mapi.update(value)
else:
# We are not at the top level
- value = self._set_field(self._parent, self._field_name, self)
+ self._set_field(self._parent, self._field_name, self)
+
+ def _set_field(self, collection, key, value):
+ """
+ enables updating the current change in the ancestors
+ :param collection: the collection to change
+ :param key: the key for the specific field
+ :param value: the new value
+ :return:
+ """
+ if isinstance(value, _InstrumentedCollection):
+ value = value._raw
+ if key in collection and isinstance(collection[key], self._item_cls):
+ if isinstance(collection[key], self.PYTHON_TYPE):
+ self._del(collection, key)
+ collection[key].value = value
+ else:
+ collection[key] = value
+ return collection[key]
+
+ def __copy__(self):
+ return self._raw
- mapi.update(value)
+ def __deepcopy__(self, *args, **kwargs):
+ return self._raw
class _InstrumentedDict(_InstrumentedCollection, dict):
+ PYTHON_TYPE = dict
+
def _load(self, dict_=None, **kwargs):
dict.__init__(
self,
@@ -342,17 +360,18 @@ class _InstrumentedDict(_InstrumentedCollection, dict):
def _set(self, key, value):
dict.__setitem__(self, key, self._raw_value(value))
- def _set_field(self, collection, key, value):
- if key in collection and isinstance(collection[key], self._item_cls):
- if isinstance(collection[key], dict):
- collection[key].clear()
- collection[key].value = value
- else:
- collection[key] = value
- return collection[key]
+ @property
+ def _raw(self):
+ return dict(self)
+
+ def _del(self, collection, key):
+ collection[key].clear()
class _InstrumentedList(_InstrumentedCollection, list):
+
+ PYTHON_TYPE = list
+
def _load(self, list_=None, **kwargs):
list.__init__(self, list(item for item in list_ or []))
@@ -373,14 +392,12 @@ class _InstrumentedList(_InstrumentedCollection, list):
def _set(self, key, value):
list.__setitem__(self, key, value)
- def _set_field(self, collection, key, value):
- if key in collection and isinstance(collection[key], self._item_cls):
- if isinstance(collection[key], list):
- del collection[key]
- collection[key].value = value
- else:
- collection[key] = value
- return collection[key]
+ def _del(self, collection, key):
+ del collection[key]
+
+ @property
+ def _raw(self):
+ return list(self)
class InstrumentCollection(object):
@@ -409,15 +426,10 @@ class InstrumentCollection(object):
setattr(self, '_{0}'.format(self._field_name), field)
# set instrumented value
- setattr(
- self,
- self._field_name,
- _InstrumentedDict(
- func_self.model,
- self._actor,
- field_name=self._field_name,
- item_cls=modeling.models.Parameter,
- seq=field)
- )
+ setattr(self, self._field_name, _InstrumentedDict(func_self.model,
+ self._actor,
+ self._field_name,
+ modeling.models.Parameter,
+ field))
return self
return _wrapper
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0b1a306f/tests/orchestrator/context/test_attribute_suggaring.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_attribute_suggaring.py b/tests/orchestrator/context/test_attribute_suggaring.py
new file mode 100644
index 0000000..7418d65
--- /dev/null
+++ b/tests/orchestrator/context/test_attribute_suggaring.py
@@ -0,0 +1,253 @@
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You 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.
+
+import pytest
+
+from aria.modeling.models import Parameter
+from aria.orchestrator.context import common
+
+
+class MockActor(object):
+ def __init__(self):
+ self.dict_ = {}
+ self.list_ = []
+
+
+class MockModel(object):
+
+ def __init__(self):
+ self.parameter = type('MockModel', (object, ), {'model_cls': Parameter,
+ 'put': lambda *args, **kwargs: None,
+ 'update': lambda *args, **kwargs: None})()
+
+
+class ContextSugaring(object):
+
+ @pytest.fixture
+ def actor(self):
+ return MockActor()
+
+ @pytest.fixture
+ def model(self):
+ return MockModel()
+
+ @pytest.fixture
+ def dict_(self, actor, model):
+ return common._InstrumentedDict(model, actor, 'dict_', item_cls=Parameter)
+
+ @pytest.fixture
+ def list_(self, actor, model):
+ return common._InstrumentedList(model, actor, field_name='list_', item_cls=Parameter)
+
+
+class TestDict(ContextSugaring):
+
+ def test_keys(self, actor, dict_):
+ dict_.update(
+ {
+ 'key1': Parameter.wrap('key1', 'value1'),
+ 'key2': Parameter.wrap('key2', 'value2')
+ }
+ )
+ assert sorted(dict_.keys()) == sorted(['key1', 'key2']) == sorted(actor.dict_.keys())
+
+ def test_values(self, actor, dict_):
+ dict_.update({
+ 'key1': Parameter.wrap('key1', 'value1'),
+ 'key2': Parameter.wrap('key1', 'value2')
+ })
+ assert (sorted(dict_.values()) ==
+ sorted(['value1', 'value2']) ==
+ sorted(v.value for v in actor.dict_.values()))
+
+ def test_items(self, dict_):
+ dict_.update({
+ 'key1': Parameter.wrap('key1', 'value1'),
+ 'key2': Parameter.wrap('key1', 'value2')
+ })
+ assert sorted(dict_.items()) == sorted([('key1', 'value1'), ('key2', 'value2')])
+
+ def test_iter(self, actor, dict_):
+ dict_.update({
+ 'key1': Parameter.wrap('key1', 'value1'),
+ 'key2': Parameter.wrap('key1', 'value2')
+ })
+ assert sorted(list(dict_)) == sorted(['key1', 'key2']) == sorted(actor.dict_.keys())
+
+ def test_bool(self, dict_):
+ assert not dict_
+ dict_.update({
+ 'key1': Parameter.wrap('key1', 'value1'),
+ 'key2': Parameter.wrap('key1', 'value2')
+ })
+ assert dict_
+
+ def test_set_item(self, actor, dict_):
+ dict_['key1'] = Parameter.wrap('key1', 'value1')
+ assert dict_['key1'] == 'value1' == actor.dict_['key1'].value
+ assert isinstance(actor.dict_['key1'], Parameter)
+
+ def test_nested(self, actor, dict_):
+ dict_['key'] = {}
+ assert isinstance(actor.dict_['key'], Parameter)
+ assert dict_['key'] == actor.dict_['key'].value == {}
+
+ dict_['key']['inner_key'] = 'value'
+
+ assert len(dict_) == 1
+ assert 'inner_key' in dict_['key']
+ assert dict_['key']['inner_key'] == 'value'
+ assert dict_['key'].keys() == ['inner_key']
+ assert dict_['key'].values() == ['value']
+ assert dict_['key'].items() == [('inner_key', 'value')]
+ assert isinstance(actor.dict_['key'], Parameter)
+ assert isinstance(dict_['key'], common._InstrumentedDict)
+
+ dict_['key'].update({'updated_key': 'updated_value'})
+ assert len(dict_) == 1
+ assert 'updated_key' in dict_['key']
+ assert dict_['key']['updated_key'] == 'updated_value'
+ assert sorted(dict_['key'].keys()) == sorted(['inner_key', 'updated_key'])
+ assert sorted(dict_['key'].values()) == sorted(['value', 'updated_value'])
+ assert sorted(dict_['key'].items()) == sorted([('inner_key', 'value'),
+ ('updated_key', 'updated_value')])
+ assert isinstance(actor.dict_['key'], Parameter)
+ assert isinstance(dict_['key'], common._InstrumentedDict)
+
+ dict_.update({'key': 'override_value'})
+ assert len(dict_) == 1
+ assert 'key' in dict_
+ assert dict_['key'] == 'override_value'
+ assert len(actor.dict_) == 1
+ assert isinstance(actor.dict_['key'], Parameter)
+ assert actor.dict_['key'].value == 'override_value'
+
+ def test_get_item(self, actor, dict_):
+ dict_['key1'] = Parameter.wrap('key1', 'value1')
+ assert isinstance(actor.dict_['key1'], Parameter)
+
+ def test_update(self, actor, dict_):
+ dict_['key1'] = 'value1'
+
+ new_dict = {'key2': 'value2'}
+ dict_.update(new_dict)
+ assert len(dict_) == 2
+ assert dict_['key2'] == 'value2'
+ assert isinstance(actor.dict_['key2'], Parameter)
+
+ new_dict = {}
+ new_dict.update(dict_)
+ assert new_dict['key1'] == dict_['key1']
+
+ def test_copy(self, dict_):
+ dict_['key1'] = 'value1'
+
+ new_dict = dict_.copy()
+ assert new_dict is not dict_
+ assert new_dict == dict_
+
+ dict_['key1'] = 'value2'
+ assert new_dict['key1'] == 'value1'
+ assert dict_['key1'] == 'value2'
+
+ def test_clear(self, dict_):
+ dict_['key1'] = 'value1'
+ dict_.clear()
+
+ assert len(dict_) == 0
+
+
+class TestList(ContextSugaring):
+
+ def test_append(self, actor, list_):
+ list_.append(Parameter.wrap('name', 'value1'))
+ list_.append('value2')
+ assert len(actor.list_) == 2
+ assert len(list_) == 2
+ assert isinstance(actor.list_[0], Parameter)
+ assert list_[0] == 'value1'
+
+ assert isinstance(actor.list_[1], Parameter)
+ assert list_[1] == 'value2'
+
+ list_[0] = 'new_value1'
+ list_[1] = 'new_value2'
+ assert isinstance(actor.list_[1], Parameter)
+ assert isinstance(actor.list_[1], Parameter)
+ assert list_[0] == 'new_value1'
+ assert list_[1] == 'new_value2'
+
+ def test_iter(self, list_):
+ list_.append('value1')
+ list_.append('value2')
+ assert sorted(list_) == sorted(['value1', 'value2'])
+
+ def test_insert(self, actor, list_):
+ list_.append('value1')
+ list_.insert(0, 'value2')
+ list_.insert(2, 'value3')
+ list_.insert(10, 'value4')
+ assert sorted(list_) == sorted(['value1', 'value2', 'value3', 'value4'])
+ assert len(actor.list_) == 4
+
+ def test_set(self, list_):
+ list_.append('value1')
+ list_.append('value2')
+
+ list_[1] = 'value3'
+ assert len(list_) == 2
+ assert sorted(list_) == sorted(['value1', 'value3'])
+
+ def test_insert_into_nested(self, actor, list_):
+ list_.append([])
+
+ list_[0].append('inner_item')
+ assert isinstance(actor.list_[0], Parameter)
+ assert len(list_) == 1
+ assert list_[0][0] == 'inner_item'
+
+ list_[0].append('new_item')
+ assert isinstance(actor.list_[0], Parameter)
+ assert len(list_) == 1
+ assert list_[0][1] == 'new_item'
+
+ assert list_[0] == ['inner_item', 'new_item']
+ assert ['inner_item', 'new_item'] == list_[0]
+
+
+class TestDictList(ContextSugaring):
+ def test_dict_in_list(self, actor, list_):
+ list_.append({})
+ assert len(list_) == 1
+ assert isinstance(actor.list_[0], Parameter)
+ assert actor.list_[0].value == {}
+
+ list_[0]['key'] = 'value'
+ assert list_[0]['key'] == 'value'
+ assert len(actor.list_) == 1
+ assert isinstance(actor.list_[0], Parameter)
+ assert actor.list_[0].value['key'] == 'value'
+
+ def test_list_in_dict(self, actor, dict_):
+ dict_['key'] = []
+ assert len(dict_) == 1
+ assert isinstance(actor.dict_['key'], Parameter)
+ assert actor.dict_['key'].value == []
+
+ dict_['key'].append('value')
+ assert dict_['key'][0] == 'value'
+ assert len(actor.dict_) == 1
+ assert isinstance(actor.dict_['key'], Parameter)
+ assert actor.dict_['key'].value[0] == 'value'
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/0b1a306f/tests/orchestrator/context/test_operation.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_operation.py b/tests/orchestrator/context/test_operation.py
index 86e4a24..581e230 100644
--- a/tests/orchestrator/context/test_operation.py
+++ b/tests/orchestrator/context/test_operation.py
@@ -25,9 +25,7 @@ from aria import (
operation,
)
from aria.orchestrator import context
-from aria.orchestrator.context import common
from aria.orchestrator.workflows import api
-from aria.modeling.models import Parameter
import tests
from tests import (
@@ -498,237 +496,3 @@ def attribute_consuming_operation(ctx, holder_path, **_):
holder = helpers.FilesystemDataHolder(holder_path)
ctx.target_node.attributes.update(ctx.source_node.attributes)
holder.update(**ctx.target_node.attributes)
-
-
-class MockActor(object):
- def __init__(self):
- self.dict_ = {}
- self.list_ = []
-
-
-class MockModel(object):
-
- def __init__(self):
- self.parameter = type('MockModel', (object, ), {'model_cls': Parameter,
- 'put': lambda *args, **kwargs: None,
- 'update': lambda *args, **kwargs: None})()
-
-
-class ContextSugaring(object):
-
- @pytest.fixture
- def actor(self):
- return MockActor()
-
- @pytest.fixture
- def model(self):
- return MockModel()
-
- @pytest.fixture
- def dict_(self, actor, model):
- return common._InstrumentedDict(model, actor, 'dict_', item_cls=Parameter)
-
- @pytest.fixture
- def list_(self, actor, model):
- return common._InstrumentedList(model, actor, field_name='list_', item_cls=Parameter)
-
-
-class TestDict(ContextSugaring):
-
- def test_keys(self, actor, dict_):
- dict_.update(
- {
- 'key1': Parameter.wrap('key1', 'value1'),
- 'key2': Parameter.wrap('key2', 'value2')
- }
- )
- assert sorted(dict_.keys()) == sorted(['key1', 'key2']) == sorted(actor.dict_.keys())
-
- def test_values(self, actor, dict_):
- dict_.update({
- 'key1': Parameter.wrap('key1', 'value1'),
- 'key2': Parameter.wrap('key1', 'value2')
- })
- assert (sorted(dict_.values()) ==
- sorted(['value1', 'value2']) ==
- sorted(v.value for v in actor.dict_.values()))
-
- def test_items(self, dict_):
- dict_.update({
- 'key1': Parameter.wrap('key1', 'value1'),
- 'key2': Parameter.wrap('key1', 'value2')
- })
- assert sorted(dict_.items()) == sorted([('key1', 'value1'), ('key2', 'value2')])
-
- def test_iter(self, actor, dict_):
- dict_.update({
- 'key1': Parameter.wrap('key1', 'value1'),
- 'key2': Parameter.wrap('key1', 'value2')
- })
- assert sorted(list(dict_)) == sorted(['key1', 'key2']) == sorted(actor.dict_.keys())
-
- def test_bool(self, dict_):
- assert not dict_
- dict_.update({
- 'key1': Parameter.wrap('key1', 'value1'),
- 'key2': Parameter.wrap('key1', 'value2')
- })
- assert dict_
-
- def test_set_item(self, actor, dict_):
- dict_['key1'] = Parameter.wrap('key1', 'value1')
- assert dict_['key1'] == 'value1' == actor.dict_['key1'].value
- assert isinstance(actor.dict_['key1'], Parameter)
-
- def test_nested(self, actor, dict_):
- dict_['key'] = {}
- assert isinstance(actor.dict_['key'], Parameter)
- assert dict_['key'] == actor.dict_['key'].value == {}
-
- dict_['key']['inner_key'] = 'value'
-
- assert len(dict_) == 1
- assert 'inner_key' in dict_['key']
- assert dict_['key']['inner_key'] == 'value'
- assert dict_['key'].keys() == ['inner_key']
- assert dict_['key'].values() == ['value']
- assert dict_['key'].items() == [('inner_key', 'value')]
- assert isinstance(actor.dict_['key'], Parameter)
- assert isinstance(dict_['key'], common._InstrumentedDict)
-
- dict_['key'].update({'updated_key': 'updated_value'})
- assert len(dict_) == 1
- assert 'updated_key' in dict_['key']
- assert dict_['key']['updated_key'] == 'updated_value'
- assert sorted(dict_['key'].keys()) == sorted(['inner_key', 'updated_key'])
- assert sorted(dict_['key'].values()) == sorted(['value', 'updated_value'])
- assert sorted(dict_['key'].items()) == sorted([('inner_key', 'value'),
- ('updated_key', 'updated_value')])
- assert isinstance(actor.dict_['key'], Parameter)
- assert isinstance(dict_['key'], common._InstrumentedDict)
-
- dict_.update({'key': 'override_value'})
- assert len(dict_) == 1
- assert 'key' in dict_
- assert dict_['key'] == 'override_value'
- assert len(actor.dict_) == 1
- assert isinstance(actor.dict_['key'], Parameter)
- assert actor.dict_['key'].value == 'override_value'
-
- def test_get_item(self, actor,dict_):
- dict_['key1'] = Parameter.wrap('key1', 'value1')
- assert isinstance(actor.dict_['key1'], Parameter)
-
- def test_update(self, actor, dict_):
- dict_['key1'] = 'value1'
-
- new_dict = {'key2': 'value2'}
- dict_.update(new_dict)
- assert len(dict_) == 2
- assert dict_['key2'] == 'value2'
- assert isinstance(actor.dict_['key2'], Parameter)
-
- new_dict = {}
- new_dict.update(dict_)
- assert new_dict['key1'] == dict_['key1']
-
- def test_copy(self, dict_):
- dict_['key1'] = 'value1'
-
- new_dict = dict_.copy()
- assert new_dict is not dict_
- assert new_dict == dict_
-
- dict_['key1'] = 'value2'
- assert new_dict['key1'] == 'value1'
- assert dict_['key1'] == 'value2'
-
- def test_clear(self, dict_):
- dict_['key1'] = 'value1'
- dict_.clear()
-
- assert len(dict_) == 0
-
-
-class TestList(ContextSugaring):
-
- def test_append(self, actor, list_):
- list_.append(Parameter.wrap('name', 'value1'))
- list_.append('value2')
- assert len(actor.list_) == 2
- assert len(list_) == 2
- assert isinstance(actor.list_[0], Parameter)
- assert list_[0] == 'value1'
-
- assert isinstance(actor.list_[1], Parameter)
- assert list_[1] == 'value2'
-
- list_[0] = 'new_value1'
- list_[1] = 'new_value2'
- assert isinstance(actor.list_[1], Parameter)
- assert isinstance(actor.list_[1], Parameter)
- assert list_[0] == 'new_value1'
- assert list_[1] == 'new_value2'
-
- def test_iter(self, list_):
- list_.append('value1')
- list_.append('value2')
- assert sorted(list_) == sorted(['value1', 'value2'])
-
- def test_insert(self, actor, list_):
- list_.append('value1')
- list_.insert(0, 'value2')
- list_.insert(2, 'value3')
- list_.insert(10, 'value4')
- assert sorted(list_) == sorted(['value1', 'value2', 'value3', 'value4'])
- assert len(actor.list_) == 4
-
- def test_set(self, list_):
- list_.append('value1')
- list_.append('value2')
-
- list_[1] = 'value3'
- assert len(list_) == 2
- assert sorted(list_) == sorted(['value1', 'value3'])
-
- def test_insert_into_nested(self, actor, list_):
- list_.append([])
-
- list_[0].append('inner_item')
- assert isinstance(actor.list_[0], Parameter)
- assert len(list_) == 1
- assert list_[0][0] == 'inner_item'
-
- list_[0].append('new_item')
- assert isinstance(actor.list_[0], Parameter)
- assert len(list_) == 1
- assert list_[0][1] == 'new_item'
-
- assert list_[0] == ['inner_item', 'new_item']
- assert ['inner_item', 'new_item'] == list_[0]
-
-
-class TestDictList(ContextSugaring):
- def test_dict_in_list(self, actor, list_):
- list_.append({})
- assert len(list_) == 1
- assert isinstance(actor.list_[0], Parameter)
- assert actor.list_[0].value == {}
-
- list_[0]['key'] = 'value'
- assert list_[0]['key'] == 'value'
- assert len(actor.list_) == 1
- assert isinstance(actor.list_[0], Parameter)
- assert actor.list_[0].value['key'] == 'value'
-
- def test_list_in_dict(self, actor, dict_):
- dict_['key'] = []
- assert len(dict_) == 1
- assert isinstance(actor.dict_['key'], Parameter)
- assert actor.dict_['key'].value == []
-
- dict_['key'].append('value')
- assert dict_['key'][0] == 'value'
- assert len(actor.dict_) == 1
- assert isinstance(actor.dict_['key'], Parameter)
- assert actor.dict_['key'].value[0] == 'value'
[3/4] incubator-ariatosca git commit: added documentation and testing
Posted by mx...@apache.org.
added documentation and testing
Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/4e851057
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/4e851057
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/4e851057
Branch: refs/heads/ARIA-258-Convert-runtime-properties-to-attributes
Commit: 4e8510573d27377d88c9e7811153c2e1c96a9144
Parents: 82d9616
Author: max-orlov <ma...@gigaspaces.com>
Authored: Mon May 22 16:46:50 2017 +0300
Committer: max-orlov <ma...@gigaspaces.com>
Committed: Mon May 22 16:46:50 2017 +0300
----------------------------------------------------------------------
aria/orchestrator/context/common.py | 169 ++++++++++++++--------
tests/orchestrator/context/test_operation.py | 48 ++++--
2 files changed, 147 insertions(+), 70 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4e851057/aria/orchestrator/context/common.py
----------------------------------------------------------------------
diff --git a/aria/orchestrator/context/common.py b/aria/orchestrator/context/common.py
index 07596f6..a5c01fa 100644
--- a/aria/orchestrator/context/common.py
+++ b/aria/orchestrator/context/common.py
@@ -203,69 +203,132 @@ class BaseContext(object):
class _InstrumentedCollection(object):
- def _get_instrumented_collection(self, key, value):
+
+ def __init__(self,
+ model,
+ parent,
+ field_name=None,
+ item_cls=None,
+ seq=None,
+ is_top_level=True,
+ **kwargs):
+ self._model = model
+ self._parent = parent
+ self._field_name = field_name
+ self._item_cls = item_cls
+ self._is_top_level = is_top_level
+ self._load(seq, **kwargs)
+
+ def _load(self, seq, **kwargs):
+ """
+ Instantiates the object from existing seq.
+
+ :param seq: the original sequence to load from
+ :return:
+ """
+ raise NotImplementedError
+
+ def _set_field(self, collection, key, value):
+ """
+ enables updating the current change in the ancestors
+ :param collection: the collection to change
+ :param key: the key for the specific field
+ :param value: the new value
+ :return:
+ """
+ raise NotImplementedError
+
+ def _set(self, key, value):
+ """
+ set the changes for the current object (not in the db)
+
+ :param key:
+ :param value:
+ :return:
+ """
+ raise NotImplementedError
+
+ def _instrument(self, key, value):
+ """
+ Instruments any collection to track changes (and ease of access)
+ :param key:
+ :param value:
+ :return:
+ """
if isinstance(value, _InstrumentedCollection):
return value
elif isinstance(value, dict):
- return _InstrumentedDict(self._model, self, key, seq=value)
+ instrumentation_cls = _InstrumentedDict
elif isinstance(value, list):
- return _InstrumentedList(self._model, self, key, seq=value)
+ instrumentation_cls = _InstrumentedList
+ else:
+ return value
- return value
+ return instrumentation_cls(self._model, self, key, self._item_cls, value, False)
def _raw_value(self, value):
- if self._item_cls and isinstance(value, self._item_cls):
+ """
+ Get the raw value.
+ :param value:
+ :return:
+ """
+ if self._is_top_level and isinstance(value, self._item_cls):
return value.value
return value
def _encapsulate_value(self, key, value):
+ """
+ Create a new item cls if needed.
+ :param key:
+ :param value:
+ :return:
+ """
if isinstance(value, self._item_cls):
return value
# If it is not wrapped
return self._item_cls.wrap(key, value)
def __setitem__(self, key, value):
+ """
+ Update the values in both the local and the db locations.
+ :param key:
+ :param value:
+ :return:
+ """
self._set(key, value)
- if self._item_cls:
- # We are at the top level
+ mapi = getattr(self._model, self._item_cls.__modelname__)
+ if self._is_top_level:
field = getattr(self._parent, self._field_name)
- mapi = getattr(self._model, self._item_cls.__modelname__)
-
+ # We are at the top level
if key in field:
# Is this a existing field
- value = self._set_parent(field, key, value)
+ value = self._set_field(field, key, value)
else:
- value = self._set_parent(field, key, self._encapsulate_value(key, value))
-
- mapi.update(value)
+ value = self._set_field(field, key, self._encapsulate_value(key, value))
else:
- self._set(key, value)
# We are not at the top level
- self._parent[self._field_name] = self
+ value = self._set_field(self._parent, self._field_name, self)
+
+ mapi.update(value)
class _InstrumentedDict(_InstrumentedCollection, dict):
- def __init__(self, model, parent, field_name=None, item_cls=None, seq=None, **kwargs):
- self._model = model
- self._parent = parent
- self._field_name = field_name
- self._item_cls = item_cls
- self._load(seq, **kwargs)
- def _load(self, seq=None, **kwargs):
- seq = dict((key, value.value if isinstance(value, self._item_cls) else value)
- for key, value in (seq or {}).items())
- super(_InstrumentedDict, self).__init__(seq, **kwargs)
+ def _load(self, dict_=None, **kwargs):
+ dict.__init__(
+ self,
+ tuple((key, self._raw_value(value)) for key, value in (dict_ or {}).items()),
+ **kwargs)
- def update(self, E=None, **F):
- E = E or {}
- for key, value in E.items():
+ def update(self, dict_=None, **kwargs):
+ dict_ = dict_ or {}
+ for key, value in dict_.items():
self[key] = value
- for key, value in F.items():
+ for key, value in kwargs.items():
self[key] = value
def __getitem__(self, key):
- return self._get_instrumented_collection(key, dict.__getitem__(self, key))
+ return self._instrument(key, dict.__getitem__(self, key))
def values(self):
return [self[key] for key in self.keys()]
@@ -279,53 +342,45 @@ class _InstrumentedDict(_InstrumentedCollection, dict):
def _set(self, key, value):
dict.__setitem__(self, key, self._raw_value(value))
- def _set_parent(self, field, key, value):
- if key in field and isinstance(field[key], self._item_cls):
- if isinstance(field[key], dict):
- field[key].clear()
- field[key].value = value
+ def _set_field(self, collection, key, value):
+ if key in collection and isinstance(collection[key], self._item_cls):
+ if isinstance(collection[key], dict):
+ collection[key].clear()
+ collection[key].value = value
else:
- field[key] = value
- return field[key]
-
+ collection[key] = value
+ return collection[key]
-class _InstrumentedList(list, _InstrumentedCollection):
- def __init__(self, model, parent, field_name=None, item_cls=None, seq=None, **kwargs):
- self._model = model
- self._parent = parent
- self._field_name = field_name
- self._item_cls = item_cls
- self._load(seq, **kwargs)
- def _load(self, seq=None, **kwargs):
- seq = list(item for item in seq or [])
- super(_InstrumentedList, self).__init__(seq)
+class _InstrumentedList(_InstrumentedCollection, list):
+ def _load(self, list_=None, **kwargs):
+ list.__init__(self, list(item for item in list_ or []))
def append(self, value):
self.insert(len(self), value)
def insert(self, index, value):
list.insert(self, index, self._raw_value(value))
- if self._item_cls:
+ if self._is_top_level:
field = getattr(self._parent, self._field_name)
field.insert(index, self._encapsulate_value(index, value))
else:
self._parent[self._field_name] = self
def __getitem__(self, key):
- return self._get_instrumented_collection(key, list.__getitem__(self, key))
+ return self._instrument(key, list.__getitem__(self, key))
def _set(self, key, value):
list.__setitem__(self, key, value)
- def _set_parent(self, field, key, value):
- if key in field and isinstance(field[key], self._item_cls):
- if isinstance(field[key], list):
- del field[key]
- field[key].value = value
+ def _set_field(self, collection, key, value):
+ if key in collection and isinstance(collection[key], self._item_cls):
+ if isinstance(collection[key], list):
+ del collection[key]
+ collection[key].value = value
else:
- field[key] = value
- return field[key]
+ collection[key] = value
+ return collection[key]
class InstrumentCollection(object):
http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/4e851057/tests/orchestrator/context/test_operation.py
----------------------------------------------------------------------
diff --git a/tests/orchestrator/context/test_operation.py b/tests/orchestrator/context/test_operation.py
index 73efff5..86e4a24 100644
--- a/tests/orchestrator/context/test_operation.py
+++ b/tests/orchestrator/context/test_operation.py
@@ -514,7 +514,7 @@ class MockModel(object):
'update': lambda *args, **kwargs: None})()
-class TestDict(object):
+class ContextSugaring(object):
@pytest.fixture
def actor(self):
@@ -528,6 +528,13 @@ class TestDict(object):
def dict_(self, actor, model):
return common._InstrumentedDict(model, actor, 'dict_', item_cls=Parameter)
+ @pytest.fixture
+ def list_(self, actor, model):
+ return common._InstrumentedList(model, actor, field_name='list_', item_cls=Parameter)
+
+
+class TestDict(ContextSugaring):
+
def test_keys(self, actor, dict_):
dict_.update(
{
@@ -643,18 +650,7 @@ class TestDict(object):
assert len(dict_) == 0
-class TestList(object):
- @pytest.fixture
- def actor(self):
- return MockActor()
-
- @pytest.fixture
- def model(self):
- return MockModel()
-
- @pytest.fixture
- def list_(self, actor, model):
- return common._InstrumentedList(model, actor, field_name='list_', item_cls=Parameter)
+class TestList(ContextSugaring):
def test_append(self, actor, list_):
list_.append(Parameter.wrap('name', 'value1'))
@@ -710,3 +706,29 @@ class TestList(object):
assert list_[0] == ['inner_item', 'new_item']
assert ['inner_item', 'new_item'] == list_[0]
+
+
+class TestDictList(ContextSugaring):
+ def test_dict_in_list(self, actor, list_):
+ list_.append({})
+ assert len(list_) == 1
+ assert isinstance(actor.list_[0], Parameter)
+ assert actor.list_[0].value == {}
+
+ list_[0]['key'] = 'value'
+ assert list_[0]['key'] == 'value'
+ assert len(actor.list_) == 1
+ assert isinstance(actor.list_[0], Parameter)
+ assert actor.list_[0].value['key'] == 'value'
+
+ def test_list_in_dict(self, actor, dict_):
+ dict_['key'] = []
+ assert len(dict_) == 1
+ assert isinstance(actor.dict_['key'], Parameter)
+ assert actor.dict_['key'].value == []
+
+ dict_['key'].append('value')
+ assert dict_['key'][0] == 'value'
+ assert len(actor.dict_) == 1
+ assert isinstance(actor.dict_['key'], Parameter)
+ assert actor.dict_['key'].value[0] == 'value'