]> review.fuel-infra Code Review - openstack-build/heat-build.git/commitdiff
heat engine : Ensure properties validation is caught
authorSteven Hardy <shardy@redhat.com>
Tue, 5 Mar 2013 15:16:59 +0000 (15:16 +0000)
committerSteven Hardy <shardy@redhat.com>
Wed, 6 Mar 2013 10:36:10 +0000 (10:36 +0000)
Rework usage of properties.validate() so that we always
catch the error and set the resource state to failed when
a properties validation error occurs

fixes bug 1146529

Change-Id: I4c5b24cc29a19a5170852aa7626031f9612b3272

heat/engine/properties.py
heat/engine/resource.py
heat/tests/test_properties.py
heat/tests/test_validate.py

index 378bb58cf38bf1c80da27d664abbf737c931837b..0cd808efe59f63e78f2b6b87070f67f14db354ea 100644 (file)
@@ -16,6 +16,8 @@
 import collections
 import re
 
+from heat.common import exception
+
 
 SCHEMA_KEYS = (
     REQUIRED, IMPLEMENTED, DEFAULT, TYPE, SCHEMA,
@@ -175,17 +177,18 @@ class Properties(collections.Mapping):
             try:
                 self[key]
             except ValueError as e:
-                return str(e)
+                msg = "Property error : %s" % str(e)
+                raise exception.StackValidationFailed(message=msg)
 
             # are there unimplemented Properties
             if not prop.implemented() and key in self.data:
-                return (self.error_prefix +
-                        '%s Property not implemented yet' % key)
+                msg = "Property %s not implemented yet" % key
+                raise exception.StackValidationFailed(message=msg)
 
         for key in self.data:
             if key not in self.props:
-                return (self.error_prefix +
-                        'Unknown Property "%s"' % key)
+                msg = "Unknown Property %s" % key
+                raise exception.StackValidationFailed(message=msg)
 
     def __getitem__(self, key):
         if key not in self:
index b5c91a17916385fbcc3ee553c7cad0561b023fe3..7458e517ecdd096f9413aec03c96dfc7b7882b18 100644 (file)
@@ -294,9 +294,7 @@ class Resource(object):
                                      self.stack.resolve_runtime_data,
                                      self.name)
         try:
-            err = self.properties.validate()
-            if err:
-                return err
+            self.properties.validate()
             self.state_set(self.CREATE_IN_PROGRESS)
             if callable(getattr(self, 'handle_create', None)):
                 self.handle_create()
@@ -344,9 +342,7 @@ class Resource(object):
                                     json_snippet.get('Properties', {}),
                                     self.stack.resolve_runtime_data,
                                     self.name)
-            err = properties.validate()
-            if err:
-                raise ValueError(err)
+            properties.validate()
             if callable(getattr(self, 'handle_update', None)):
                 result = self.handle_update(json_snippet)
         except Exception as ex:
index dc60a8a796f5372cb8d8bb5d2a70a02a6c5f25fa..2afd1d23d288892f740ddb09a5be54b8ea8bcdee 100644 (file)
@@ -17,6 +17,7 @@ import unittest
 from nose.plugins.attrib import attr
 
 from heat.engine import properties
+from heat.common import exception
 
 
 @attr(tag=['unit', 'properties'])
@@ -316,7 +317,7 @@ class PropertiesValidationTest(unittest.TestCase):
     def test_missing_required(self):
         schema = {'foo': {'Type': 'String', 'Required': True}}
         props = properties.Properties(schema, {})
-        self.assertEqual(props.validate(), 'Property foo not assigned')
+        self.assertRaises(exception.StackValidationFailed, props.validate)
 
     def test_missing_unimplemented(self):
         schema = {'foo': {'Type': 'String', 'Implemented': False}}
@@ -326,7 +327,7 @@ class PropertiesValidationTest(unittest.TestCase):
     def test_present_unimplemented(self):
         schema = {'foo': {'Type': 'String', 'Implemented': False}}
         props = properties.Properties(schema, {'foo': 'bar'})
-        self.assertEqual(props.validate(), 'foo Property not implemented yet')
+        self.assertRaises(exception.StackValidationFailed, props.validate)
 
     def test_missing(self):
         schema = {'foo': {'Type': 'String'}}
@@ -336,9 +337,9 @@ class PropertiesValidationTest(unittest.TestCase):
     def test_bad_data(self):
         schema = {'foo': {'Type': 'String'}}
         props = properties.Properties(schema, {'foo': 42})
-        self.assertEqual(props.validate(), 'foo Value must be a string')
+        self.assertRaises(exception.StackValidationFailed, props.validate)
 
     def test_unknown_typo(self):
         schema = {'foo': {'Type': 'String'}}
         props = properties.Properties(schema, {'food': 42})
-        self.assertNotEqual(props.validate(), None)
+        self.assertRaises(exception.StackValidationFailed, props.validate)
index 29ffc20aa2ec740fb1b8ada31198e65bcd807034..5465fe5c4d240bcbee1cdb1f10d6df510de90cef 100644 (file)
@@ -19,6 +19,7 @@ import mox
 from nose.plugins.attrib import attr
 
 from heat.tests.v1_1 import fakes
+from heat.common import exception
 from heat.common import template_format
 from heat.engine.resources import instance as instances
 from heat.engine import service
@@ -240,7 +241,8 @@ class validateTest(unittest.TestCase):
 
         self.m.ReplayAll()
         volumeattach = stack.resources['MountPoint']
-        self.assertTrue(volumeattach.validate())
+        self.assertRaises(exception.StackValidationFailed,
+                          volumeattach.validate)
 
     def test_validate_ref_valid(self):
         t = template_format.parse(test_template_ref % 'WikiDatabase')