Expand test in-progress workaround

When working around bug #1450314, we changed integration tests to ignore
the lock when doing an update. Unfortunately, this issue happens for
actions other than update like delete and suspend, so let's apply the
same fix for those actions too.

Change-Id: I04c5f35a1851163bc849f5c8be0f6e865ee0088e
Closes-Bug: #1508990
Related-Bug: #1450314
diff --git a/common/test.py b/common/test.py
index 31ec52c..1ffe222 100644
--- a/common/test.py
+++ b/common/test.py
@@ -330,13 +330,32 @@
 
     def _stack_delete(self, stack_identifier):
         try:
-            self.client.stacks.delete(stack_identifier)
+            self._handle_in_progress(self.client.stacks.delete,
+                                     stack_identifier)
         except heat_exceptions.HTTPNotFound:
             pass
         self._wait_for_stack_status(
             stack_identifier, 'DELETE_COMPLETE',
             success_on_not_found=True)
 
+    def _handle_in_progress(self, fn, *args, **kwargs):
+        build_timeout = self.conf.build_timeout
+        build_interval = self.conf.build_interval
+        start = timeutils.utcnow()
+        while timeutils.delta_seconds(start,
+                                      timeutils.utcnow()) < build_timeout:
+            try:
+                fn(*args, **kwargs)
+            except heat_exceptions.HTTPConflict as ex:
+                # FIXME(sirushtim): Wait a little for the stack lock to be
+                # released and hopefully, the stack should be usable again.
+                if ex.error['error']['type'] != 'ActionInProgress':
+                    raise ex
+
+                time.sleep(build_interval)
+            else:
+                break
+
     def update_stack(self, stack_identifier, template=None, environment=None,
                      files=None, parameters=None, tags=None,
                      expected_status='UPDATE_COMPLETE',
@@ -347,34 +366,20 @@
         parameters = parameters or {}
         stack_name = stack_identifier.split('/')[0]
 
-        build_timeout = self.conf.build_timeout
-        build_interval = self.conf.build_interval
-        start = timeutils.utcnow()
         self.updated_time[stack_identifier] = self.client.stacks.get(
             stack_identifier).updated_time
-        while timeutils.delta_seconds(start,
-                                      timeutils.utcnow()) < build_timeout:
-            try:
-                self.client.stacks.update(
-                    stack_id=stack_identifier,
-                    stack_name=stack_name,
-                    template=template,
-                    files=env_files,
-                    disable_rollback=disable_rollback,
-                    parameters=parameters,
-                    environment=env,
-                    tags=tags,
-                    existing=existing
-                )
-            except heat_exceptions.HTTPConflict as ex:
-                # FIXME(sirushtim): Wait a little for the stack lock to be
-                # released and hopefully, the stack should be updatable again.
-                if ex.error['error']['type'] != 'ActionInProgress':
-                    raise ex
 
-                time.sleep(build_interval)
-            else:
-                break
+        self._handle_in_progress(
+            self.client.stacks.update,
+            stack_id=stack_identifier,
+            stack_name=stack_name,
+            template=template,
+            files=env_files,
+            disable_rollback=disable_rollback,
+            parameters=parameters,
+            environment=env,
+            tags=tags,
+            existing=existing)
 
         kwargs = {'stack_identifier': stack_identifier,
                   'status': expected_status}
@@ -537,7 +542,7 @@
             self.addCleanup(self._stack_delete, stack_identifier)
             self.skipTest('Testing Stack suspend disabled in conf, skipping')
         stack_name = stack_identifier.split('/')[0]
-        self.client.actions.suspend(stack_name)
+        self._handle_in_progress(self.client.actions.suspend, stack_name)
         # improve debugging by first checking the resource's state.
         self._wait_for_all_resource_status(stack_identifier,
                                            'SUSPEND_COMPLETE')
@@ -549,7 +554,7 @@
             self.addCleanup(self._stack_delete, stack_identifier)
             self.skipTest('Testing Stack resume disabled in conf, skipping')
         stack_name = stack_identifier.split('/')[0]
-        self.client.actions.resume(stack_name)
+        self._handle_in_progress(self.client.actions.resume, stack_name)
         # improve debugging by first checking the resource's state.
         self._wait_for_all_resource_status(stack_identifier,
                                            'RESUME_COMPLETE')