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'