summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--heat/engine/resource.py9
-rw-r--r--heat/tests/test_resource.py31
2 files changed, 38 insertions, 2 deletions
diff --git a/heat/engine/resource.py b/heat/engine/resource.py
index 6abc6b0fa..5ed832cb8 100644
--- a/heat/engine/resource.py
+++ b/heat/engine/resource.py
@@ -1104,13 +1104,18 @@ class Resource(status.ResourceStatus):
while (count[self.CREATE] <= retry_limit and
count[self.DELETE] <= retry_limit):
- if count[action]:
+ pre_func = None
+ if count[action] > 0:
delay = timeutils.retry_backoff_delay(count[action],
jitter_max=2.0)
waiter = scheduler.TaskRunner(self.pause)
yield waiter.as_task(timeout=delay)
+ elif action == self.CREATE:
+ # Only validate properties in first create call.
+ pre_func = self.properties.validate
+
try:
- yield self._do_action(action, self.properties.validate)
+ yield self._do_action(action, pre_func)
if action == self.CREATE:
first_failure = None
break
diff --git a/heat/tests/test_resource.py b/heat/tests/test_resource.py
index 8189a16f7..0c1fdf614 100644
--- a/heat/tests/test_resource.py
+++ b/heat/tests/test_resource.py
@@ -1022,6 +1022,37 @@ class ResourceTest(common.HeatTestCase):
scheduler.TaskRunner(res.create)()
self.assertEqual((res.CREATE, res.COMPLETE), res.state)
+ @mock.patch.object(properties.Properties, 'validate')
+ @mock.patch.object(timeutils, 'retry_backoff_delay')
+ def test_create_validate(self, m_re, m_v):
+ tmpl = rsrc_defn.ResourceDefinition('test_resource', 'Foo',
+ {'Foo': 'abc'})
+ res = generic_rsrc.ResourceWithProps('test_resource', tmpl, self.stack)
+
+ generic_rsrc.ResourceWithProps.handle_create = mock.Mock()
+ generic_rsrc.ResourceWithProps.handle_delete = mock.Mock()
+ m_v.side_effect = [True, exception.StackValidationFailed()]
+ generic_rsrc.ResourceWithProps.handle_create.side_effect = [
+ exception.ResourceInError(resource_name='test_resource',
+ resource_status='ERROR',
+ resource_type='GenericResourceType',
+ resource_action='CREATE',
+ status_reason='just because'),
+ exception.ResourceInError(resource_name='test_resource',
+ resource_status='ERROR',
+ resource_type='GenericResourceType',
+ resource_action='CREATE',
+ status_reason='just because'),
+ None
+ ]
+
+ generic_rsrc.ResourceWithProps.handle_delete.return_value = None
+ m_re.return_value = 0.01
+ scheduler.TaskRunner(res.create)()
+ self.assertEqual(2, m_re.call_count)
+ self.assertEqual(1, m_v.call_count)
+ self.assertEqual((res.CREATE, res.COMPLETE), res.state)
+
def test_create_fail_retry(self):
tmpl = rsrc_defn.ResourceDefinition('test_resource', 'Foo',
{'Foo': 'abc'})