add tests for force delete snapshot:

- test_snapshot_force_delete_when_snapshot_is_creating
- test_snapshot_force_delete_when_snapshot_is_deleting
- test_snapshot_force_delete_when_snapshot_is_error
- test_snapshot_force_delete_when_snapshot_is_error_deleting

Change-Id: If03e21ee5b617476aa84f6512d2a6346194c9fcb
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index 03fbd33..39dcfba 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -66,6 +66,19 @@
                                                           status)
         super(SnapshotsActionsTest, self).tearDown()
 
+    def _create_reset_and_force_delete_temp_snapshot(self, status=None):
+        # Create snapshot, reset snapshot status,
+        # and force delete temp snapshot
+        temp_snapshot = self.create_snapshot(self.volume['id'])
+        if status:
+            resp, body = self.admin_snapshots_client.\
+                reset_snapshot_status(temp_snapshot['id'], status)
+            self.assertEqual(202, resp.status)
+        resp_delete, volume_delete = self.admin_snapshots_client.\
+            force_delete_snapshot(temp_snapshot['id'])
+        self.assertEqual(202, resp_delete.status)
+        self.client.wait_for_resource_deletion(temp_snapshot['id'])
+
     def _get_progress_alias(self):
         return 'os-extended-snapshot-attributes:progress'
 
@@ -101,6 +114,26 @@
         self.assertEqual(status, snapshot_get['status'])
         self.assertEqual(progress, snapshot_get[progress_alias])
 
+    @attr(type='gate')
+    def test_snapshot_force_delete_when_snapshot_is_creating(self):
+        # test force delete when status of snapshot is creating
+        self._create_reset_and_force_delete_temp_snapshot('creating')
+
+    @attr(type='gate')
+    def test_snapshot_force_delete_when_snapshot_is_deleting(self):
+        # test force delete when status of snapshot is deleting
+        self._create_reset_and_force_delete_temp_snapshot('deleting')
+
+    @attr(type='gate')
+    def test_snapshot_force_delete_when_snapshot_is_error(self):
+        # test force delete when status of snapshot is error
+        self._create_reset_and_force_delete_temp_snapshot('error')
+
+    @attr(type='gate')
+    def test_snapshot_force_delete_when_snapshot_is_error_deleting(self):
+        # test force delete when status of snapshot is error_deleting
+        self._create_reset_and_force_delete_temp_snapshot('error_deleting')
+
 
 class SnapshotsActionsTestXML(SnapshotsActionsTest):
     _interface = "xml"
diff --git a/tempest/services/volume/json/snapshots_client.py b/tempest/services/volume/json/snapshots_client.py
index c270de8..05e8983 100644
--- a/tempest/services/volume/json/snapshots_client.py
+++ b/tempest/services/volume/json/snapshots_client.py
@@ -186,3 +186,10 @@
         url = "snapshots/%s/metadata/%s" % (str(snapshot_id), str(id))
         resp, body = self.delete(url, self.headers)
         return resp, body
+
+    def force_delete_snapshot(self, snapshot_id):
+        """Force Delete Snapshot."""
+        post_body = json.dumps({'os-force_delete': {}})
+        resp, body = self.post('snapshots/%s/action' % snapshot_id, post_body,
+                               self.headers)
+        return resp, body
diff --git a/tempest/services/volume/xml/snapshots_client.py b/tempest/services/volume/xml/snapshots_client.py
index 3a70eab..f53bed7 100644
--- a/tempest/services/volume/xml/snapshots_client.py
+++ b/tempest/services/volume/xml/snapshots_client.py
@@ -225,3 +225,12 @@
         """Delete metadata item for the snapshot."""
         url = "snapshots/%s/metadata/%s" % (str(snapshot_id), str(id))
         return self.delete(url)
+
+    def force_delete_snapshot(self, snapshot_id):
+        """Force Delete Snapshot."""
+        post_body = Element("os-force_delete")
+        url = 'snapshots/%s/action' % str(snapshot_id)
+        resp, body = self.post(url, str(Document(post_body)), self.headers)
+        if body:
+            body = xml_to_json(etree.fromstring(body))
+        return resp, body