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:09 UTC

[3/4] incubator-ariatosca git commit: added documentation and testing

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'