Added some tests for reserve and unreserve volume

add positive and negative tests for reserve and unreserve volume

Change-Id: I89f92d727659f6bfa0a9464135b62857893c6829
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index f12d4bb..30c2c74 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -123,6 +123,23 @@
         self.assertEqual(200, resp.status)
         self.assertEqual(int(volume['size']), extend_size)
 
+    @attr(type='gate')
+    def test_reserve_unreserve_volume(self):
+        # Mark volume as reserved.
+        resp, body = self.client.reserve_volume(self.volume['id'])
+        self.assertEqual(202, resp.status)
+        # To get the volume info
+        resp, body = self.client.get_volume(self.volume['id'])
+        self.assertEqual(200, resp.status)
+        self.assertIn('attaching', body['status'])
+        # Unmark volume as reserved.
+        resp, body = self.client.unreserve_volume(self.volume['id'])
+        self.assertEqual(202, resp.status)
+        # To get the volume info
+        resp, body = self.client.get_volume(self.volume['id'])
+        self.assertEqual(200, resp.status)
+        self.assertIn('available', body['status'])
+
 
 class VolumesActionsTestXML(VolumesActionsTest):
     _interface = "xml"
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 9bab9a0..538d5be 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -212,6 +212,31 @@
         self.assertRaises(exceptions.NotFound, self.client.extend_volume,
                           None, extend_size)
 
+    @attr(type=['negative', 'gate'])
+    def test_reserve_volume_with_nonexistent_volume_id(self):
+        self.assertRaises(exceptions.NotFound,
+                          self.client.reserve_volume,
+                          str(uuid.uuid4()))
+
+    @attr(type=['negative', 'gate'])
+    def test_unreserve_volume_with_nonexistent_volume_id(self):
+        self.assertRaises(exceptions.NotFound,
+                          self.client.unreserve_volume,
+                          str(uuid.uuid4()))
+
+    @attr(type=['negative', 'gate'])
+    def test_reserve_volume_with_negative_volume_status(self):
+        # Mark volume as reserved.
+        resp, body = self.client.reserve_volume(self.volume['id'])
+        self.assertEqual(202, resp.status)
+        # Mark volume which is marked as reserved before
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.reserve_volume,
+                          self.volume['id'])
+        # Unmark volume as reserved.
+        resp, body = self.client.unreserve_volume(self.volume['id'])
+        self.assertEqual(202, resp.status)
+
 
 class VolumesNegativeTestXML(VolumesNegativeTest):
     _interface = 'xml'
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index eb87cbe..670492a 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -128,6 +128,22 @@
         resp, body = self.post(url, post_body, self.headers)
         return resp, body
 
+    def reserve_volume(self, volume_id):
+        """Reserves a volume."""
+        post_body = {}
+        post_body = json.dumps({'os-reserve': post_body})
+        url = 'volumes/%s/action' % (volume_id)
+        resp, body = self.post(url, post_body, self.headers)
+        return resp, body
+
+    def unreserve_volume(self, volume_id):
+        """Restore a reserved volume ."""
+        post_body = {}
+        post_body = json.dumps({'os-unreserve': post_body})
+        url = 'volumes/%s/action' % (volume_id)
+        resp, body = self.post(url, post_body, self.headers)
+        return resp, body
+
     def wait_for_volume_status(self, volume_id, status):
         """Waits for a Volume to reach a given status."""
         resp, body = self.get_volume(volume_id)
diff --git a/tempest/services/volume/xml/volumes_client.py b/tempest/services/volume/xml/volumes_client.py
index be292a2..0edf7f3 100644
--- a/tempest/services/volume/xml/volumes_client.py
+++ b/tempest/services/volume/xml/volumes_client.py
@@ -266,3 +266,21 @@
         if body:
             body = xml_to_json(etree.fromstring(body))
         return resp, body
+
+    def reserve_volume(self, volume_id):
+        """Reserves a volume."""
+        post_body = Element("os-reserve")
+        url = 'volumes/%s/action' % str(volume_id)
+        resp, body = self.post(url, str(Document(post_body)), self.headers)
+        if body:
+            body = xml_to_json(etree.fromstring(body))
+        return resp, body
+
+    def unreserve_volume(self, volume_id):
+        """Restore a reserved volume ."""
+        post_body = Element("os-unreserve")
+        url = 'volumes/%s/action' % str(volume_id)
+        resp, body = self.post(url, str(Document(post_body)), self.headers)
+        if body:
+            body = xml_to_json(etree.fromstring(body))
+        return resp, body