Only validate properties once during create resource
While create a resource, we might retry to create or delete that resource.
Within every action properties validate was act as pre-function before
actually call any action. While the first creat run, if anything goes wrong
during property validation, a validation error will raise right away. Which
will definitely riase in the very first action run. But if it successed,
it still required to revalidate each time an action triggered (whatever is
creat or delete). This patch will ignore properties validate if it's not
the first create run.
Closes-Bug: #1691672
Change-Id: Ibf592a254a862613eddb77ea5933ec6ba0cd2d1a
(cherry picked from commit 4a15c3387a
)
This commit is contained in:
parent
e544ebc859
commit
e671d93b15
|
@ -969,13 +969,18 @@ class Resource(object):
|
|||
|
||||
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
|
||||
|
|
|
@ -965,6 +965,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'})
|
||||
|
|
Loading…
Reference in New Issue