]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
heat engine : Resource add function to compare properties
authorSteven Hardy <shardy@redhat.com>
Mon, 4 Feb 2013 14:09:04 +0000 (14:09 +0000)
committerSteven Hardy <shardy@redhat.com>
Mon, 4 Feb 2013 18:05:57 +0000 (18:05 +0000)
Add update_template_diff_properties to make comparison of
pre/post update resource properties easier

Change-Id: Ic37d37ae510a62739d4cc4219cfd69479a87767d
Signed-off-by: Steven Hardy <shardy@redhat.com>
heat/engine/resource.py
heat/tests/test_resource.py

index eb086716e35e770b16d8d7243dad59d37404c093..e6a5ee60305c16a0565daaab5f12e32e0987b7ed 100644 (file)
@@ -105,6 +105,10 @@ class Resource(object):
     # which are supported for handle_update, used by update_template_diff
     update_allowed_keys = ()
 
+    # Resource implementation set this to the subset of resource properties
+    # supported for handle_update, used by update_template_diff_properties
+    update_allowed_properties = ()
+
     def __new__(cls, name, json, stack):
         '''Create a new Resource of the appropriate class for its type.'''
 
@@ -204,6 +208,34 @@ class Resource(object):
 
         return dict((k, json_snippet.get(k)) for k in changed_keys_set)
 
+    def update_template_diff_properties(self, json_snippet=None):
+        '''
+        Returns the changed Properties between json_template and self.t
+        If a property has been removed in json_snippet which exists
+        in self.t we set it to None.  If any properties have changed which
+        are not in update_allowed_properties, raises NotImplementedError
+        '''
+        update_allowed_set = set(self.update_allowed_properties)
+
+        # Create a set containing the keys in both current and update template
+        current_properties = self.parsed_template().get('Properties', {})
+        template_properties = set(current_properties.keys())
+        updated_properties = json_snippet.get('Properties', {})
+        template_properties.update(set(updated_properties.keys()))
+
+        # Create a set of keys which differ (or are missing/added)
+        changed_properties_set = set(k for k in template_properties
+                                     if current_properties.get(k) !=
+                                     updated_properties.get(k))
+
+        if not changed_properties_set.issubset(update_allowed_set):
+            badkeys = changed_properties_set - update_allowed_set
+            raise NotImplementedError("Cannot update properties %s for %s" %
+                                      (badkeys, self.name))
+
+        return dict((k, updated_properties.get(k))
+                    for k in changed_properties_set)
+
     def __str__(self):
         return '%s "%s"' % (self.__class__.__name__, self.name)
 
index eac55c2d22e5eb5e196f40b96ad39640c10cd47e..830ec68345cd6880536f84f3385fa6dcbe7b4abc 100644 (file)
@@ -153,6 +153,46 @@ class ResourceTest(unittest.TestCase):
         diff = res.update_template_diff(json_snippet=update_snippet)
         self.assertEqual(diff, {'Metadata': None})
 
+    def test_update_template_diff_properties_none(self):
+        tmpl = {'Type': 'Foo'}
+        update_snippet = {'Type': 'Foo'}
+        res = resource.GenericResource('test_resource', tmpl, self.stack)
+        diff = res.update_template_diff_properties(json_snippet=update_snippet)
+        self.assertEqual(diff, {})
+
+    def test_update_template_diff_properties_added(self):
+        tmpl = {'Type': 'Foo'}
+        update_snippet = {'Type': 'Foo', 'Properties': {'Bar': 123}}
+        res = resource.GenericResource('test_resource', tmpl, self.stack)
+        res.update_allowed_properties = ('Bar',)
+        diff = res.update_template_diff_properties(json_snippet=update_snippet)
+        self.assertEqual(diff, {'Bar': 123})
+
+    def test_update_template_diff_properties_removed(self):
+        tmpl = {'Type': 'Foo', 'Properties': {'Bar': 123}}
+        update_snippet = {'Type': 'Foo', 'Properties': {}}
+        res = resource.GenericResource('test_resource', tmpl, self.stack)
+        res.update_allowed_properties = ('Bar',)
+        diff = res.update_template_diff_properties(json_snippet=update_snippet)
+        self.assertEqual(diff, {'Bar': None})
+
+    def test_update_template_diff_properties_changed(self):
+        tmpl = {'Type': 'Foo', 'Properties': {'Bar': 123}}
+        update_snippet = {'Type': 'Foo', 'Properties': {'Bar': 456}}
+        res = resource.GenericResource('test_resource', tmpl, self.stack)
+        res.update_allowed_properties = ('Bar',)
+        diff = res.update_template_diff_properties(json_snippet=update_snippet)
+        self.assertEqual(diff, {'Bar': 456})
+
+    def test_update_template_diff_properties_notallowed(self):
+        tmpl = {'Type': 'Foo', 'Properties': {'Bar': 123}}
+        update_snippet = {'Type': 'Foo', 'Properties': {'Bar': 456}}
+        res = resource.GenericResource('test_resource', tmpl, self.stack)
+        res.update_allowed_properties = ('Cat',)
+        self.assertRaises(NotImplementedError,
+                          res.update_template_diff_properties,
+                          update_snippet)
+
 
 @attr(tag=['unit', 'resource'])
 @attr(speed='fast')