Merge "Use python abc in DeletableResource class"
diff --git a/etc/schemas/compute/admin/flavor_create.json b/etc/schemas/compute/admin/flavor_create.json
deleted file mode 100644
index 0a3e7b3..0000000
--- a/etc/schemas/compute/admin/flavor_create.json
+++ /dev/null
@@ -1,20 +0,0 @@
-{
-    "name": "flavor-create",
-    "http-method": "POST",
-    "admin_client": true,
-    "url": "flavors",
-    "default_result_code": 400,
-    "json-schema": {
-        "type": "object",
-        "properties": {
-            "name": { "type": "string"},
-            "ram": { "type": "integer", "minimum": 1},
-            "vcpus": { "type": "integer", "minimum": 1},
-            "disk": { "type": "integer"},
-            "id": { "type": "integer"},
-            "swap": { "type": "integer"},
-            "rxtx_factor": { "type": "integer"},
-            "OS-FLV-EXT-DATA:ephemeral": { "type": "integer"}
-        }
-    }
-}
diff --git a/etc/schemas/compute/flavors/flavor_details.json b/etc/schemas/compute/flavors/flavor_details.json
deleted file mode 100644
index c16075c..0000000
--- a/etc/schemas/compute/flavors/flavor_details.json
+++ /dev/null
@@ -1,8 +0,0 @@
-{
-    "name": "get-flavor-details",
-    "http-method": "GET",
-    "url": "flavors/%s",
-    "resources": [
-        {"name": "flavor", "expected_result": 404}
-    ]
-}
diff --git a/etc/schemas/compute/flavors/flavor_details_v3.json b/etc/schemas/compute/flavors/flavor_details_v3.json
deleted file mode 100644
index d1c1077..0000000
--- a/etc/schemas/compute/flavors/flavor_details_v3.json
+++ /dev/null
@@ -1,6 +0,0 @@
-{
-    "name": "get-flavor-details",
-    "http-method": "GET",
-    "url": "flavors/%s",
-    "resources": ["flavor"]
-}
diff --git a/etc/schemas/compute/flavors/flavors_list.json b/etc/schemas/compute/flavors/flavors_list.json
deleted file mode 100644
index eb8383b..0000000
--- a/etc/schemas/compute/flavors/flavors_list.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-    "name": "list-flavors-with-detail",
-    "http-method": "GET",
-    "url": "flavors/detail",
-    "json-schema": {
-        "type": "object",
-        "properties": {
-            "minRam": {
-                "type": "integer",
-                "results": {
-                    "gen_none": 400,
-                    "gen_string": 400
-                }
-            },
-            "minDisk": {
-                "type": "integer",
-                "results": {
-                    "gen_none": 400,
-                    "gen_string": 400
-                }
-            }
-        }
-    }
-}
diff --git a/etc/schemas/compute/flavors/flavors_list_v3.json b/etc/schemas/compute/flavors/flavors_list_v3.json
deleted file mode 100644
index d5388b3..0000000
--- a/etc/schemas/compute/flavors/flavors_list_v3.json
+++ /dev/null
@@ -1,24 +0,0 @@
-{
-    "name": "list-flavors-with-detail",
-    "http-method": "GET",
-    "url": "flavors/detail",
-    "json-schema": {
-        "type": "object",
-        "properties": {
-            "min_ram": {
-                "type": "integer",
-                "results": {
-                    "gen_none": 400,
-                    "gen_string": 400
-                }
-            },
-            "min_disk": {
-                "type": "integer",
-                "results": {
-                    "gen_none": 400,
-                    "gen_string": 400
-                }
-            }
-        }
-    }
-}
diff --git a/etc/schemas/compute/servers/get_console_output.json b/etc/schemas/compute/servers/get_console_output.json
deleted file mode 100644
index 8d974ba..0000000
--- a/etc/schemas/compute/servers/get_console_output.json
+++ /dev/null
@@ -1,23 +0,0 @@
-{
-    "name": "get-console-output",
-    "http-method": "POST",
-    "url": "servers/%s/action",
-    "resources": [
-        {"name":"server", "expected_result": 404}
-    ],
-    "json-schema": {
-        "type": "object",
-        "properties": {
-            "os-getConsoleOutput": {
-                "type": "object",
-                "properties": {
-                    "length": {
-                        "type": ["integer", "string"],
-                        "minimum": 0
-                    }
-                }
-            }
-        },
-        "additionalProperties": false
-    }
-}
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 9ace4ea..247f6d1 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -474,6 +474,10 @@
 # attachment? (boolean value)
 #interface_attach=true
 
+# Does the test environment support creating snapshot images
+# of running instances? (boolean value)
+#snapshot=true
+
 
 [dashboard]
 
diff --git a/tempest/api/compute/admin/test_flavors_negative.py b/tempest/api/compute/admin/test_flavors_negative.py
index 9e4412f..eece096 100644
--- a/tempest/api/compute/admin/test_flavors_negative.py
+++ b/tempest/api/compute/admin/test_flavors_negative.py
@@ -16,6 +16,7 @@
 import uuid
 
 from tempest.api.compute import base
+from tempest.api_schema.request.compute.v2 import flavors
 from tempest.common.utils import data_utils
 from tempest import exceptions
 from tempest import test
@@ -106,4 +107,4 @@
                                    test.NegativeAutoTest):
     _interface = 'json'
     _service = 'compute'
-    _schema_file = 'compute/admin/flavor_create.json'
+    _schema = flavors.flavor_create
diff --git a/tempest/api/compute/admin/test_networks.py b/tempest/api/compute/admin/test_networks.py
new file mode 100644
index 0000000..032e2f5
--- /dev/null
+++ b/tempest/api/compute/admin/test_networks.py
@@ -0,0 +1,52 @@
+# Copyright 2014 Hewlett-Packard Development Company, L.P.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.compute import base
+from tempest import config
+
+CONF = config.CONF
+
+
+class NetworksTest(base.BaseComputeAdminTest):
+    _api_version = 2
+
+    """
+    Tests Nova Networks API that usually requires admin privileges.
+    API docs:
+    http://developer.openstack.org/api-ref-compute-v2-ext.html#ext-os-networks
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        super(NetworksTest, cls).setUpClass()
+        cls.client = cls.os_adm.networks_client
+
+    def test_get_network(self):
+        resp, networks = self.client.list_networks()
+        configured_network = [x for x in networks if x['label'] ==
+                              CONF.compute.fixed_network_name]
+        self.assertEqual(1, len(configured_network),
+                         "{0} networks with label {1}".format(
+                             len(configured_network),
+                             CONF.compute.fixed_network_name))
+        configured_network = configured_network[0]
+        _, network = self.client.get_network(configured_network['id'])
+        self.assertEqual(configured_network['label'], network['label'])
+
+    def test_list_all_networks(self):
+        _, networks = self.client.list_networks()
+        # Check the configured network is in the list
+        configured_network = CONF.compute.fixed_network_name
+        self.assertIn(configured_network, [x['label'] for x in networks])
diff --git a/tempest/api/compute/admin/test_quotas_negative.py b/tempest/api/compute/admin/test_quotas_negative.py
index 599b058..4afda03 100644
--- a/tempest/api/compute/admin/test_quotas_negative.py
+++ b/tempest/api/compute/admin/test_quotas_negative.py
@@ -94,6 +94,7 @@
     @test.skip_because(bug="1186354",
                        condition=CONF.service_available.neutron)
     @test.attr(type='gate')
+    @test.services('network')
     def test_security_groups_exceed_limit(self):
         # Negative test: Creation Security Groups over limit should FAIL
 
@@ -120,6 +121,7 @@
     @test.skip_because(bug="1186354",
                        condition=CONF.service_available.neutron)
     @test.attr(type=['negative', 'gate'])
+    @test.services('network')
     def test_security_groups_rules_exceed_limit(self):
         # Negative test: Creation of Security Group Rules should FAIL
         # when we reach limit maxSecurityGroupRules
diff --git a/tempest/api/compute/admin/test_security_group_default_rules.py b/tempest/api/compute/admin/test_security_group_default_rules.py
index 07408a8..a07d270 100644
--- a/tempest/api/compute/admin/test_security_group_default_rules.py
+++ b/tempest/api/compute/admin/test_security_group_default_rules.py
@@ -55,7 +55,7 @@
     @test.attr(type='smoke')
     def test_create_delete_security_group_default_rules(self):
         # Create and delete Security Group default rule
-        ip_protocols = {'tcp', 'udp', 'icmp'}
+        ip_protocols = ['tcp', 'udp', 'icmp']
         for ip_protocol in ip_protocols:
             rule = self._create_security_group_default_rules(ip_protocol)
             # Delete Security Group default rule
diff --git a/tempest/api/compute/flavors/test_flavors_negative.py b/tempest/api/compute/flavors/test_flavors_negative.py
index 1638f2d..7672fc6 100644
--- a/tempest/api/compute/flavors/test_flavors_negative.py
+++ b/tempest/api/compute/flavors/test_flavors_negative.py
@@ -13,8 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-
 from tempest.api.compute import base
+from tempest.api_schema.request.compute.v2 import flavors
 from tempest import test
 
 
@@ -25,14 +25,14 @@
 class FlavorsListWithDetailsNegativeTestJSON(base.BaseV2ComputeTest,
                                              test.NegativeAutoTest):
     _service = 'compute'
-    _schema_file = 'compute/flavors/flavors_list.json'
+    _schema = flavors.flavor_list
 
 
 @test.SimpleNegativeAutoTest
 class FlavorDetailsNegativeTestJSON(base.BaseV2ComputeTest,
                                     test.NegativeAutoTest):
     _service = 'compute'
-    _schema_file = 'compute/flavors/flavor_details.json'
+    _schema = flavors.flavors_details
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index 29df2b0..bbb887f 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -28,6 +28,12 @@
         if not CONF.service_available.glance:
             skip_msg = ("%s skipped as glance is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
+
+        if not CONF.compute_feature_enabled.snapshot:
+            skip_msg = ("%s skipped as instance snapshotting is not supported"
+                        % cls.__name__)
+            raise cls.skipException(skip_msg)
+
         cls.client = cls.images_client
         cls.servers_client = cls.servers_client
 
diff --git a/tempest/api/compute/images/test_images_negative.py b/tempest/api/compute/images/test_images_negative.py
index 6163f4d..771040b 100644
--- a/tempest/api/compute/images/test_images_negative.py
+++ b/tempest/api/compute/images/test_images_negative.py
@@ -29,6 +29,12 @@
         if not CONF.service_available.glance:
             skip_msg = ("%s skipped as glance is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
+
+        if not CONF.compute_feature_enabled.snapshot:
+            skip_msg = ("%s skipped as instance snapshotting is not supported"
+                        % cls.__name__)
+            raise cls.skipException(skip_msg)
+
         cls.client = cls.images_client
         cls.servers_client = cls.servers_client
 
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index c81cec5..187c0d4 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -54,6 +54,11 @@
             skip_msg = ("%s skipped as glance is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
 
+        if not CONF.compute_feature_enabled.snapshot:
+            skip_msg = ("%s skipped as instance snapshotting is not supported"
+                        % cls.__name__)
+            raise cls.skipException(skip_msg)
+
         try:
             resp, server = cls.create_test_server(wait_until='ACTIVE')
             cls.server_id = server['id']
diff --git a/tempest/api/compute/images/test_images_oneserver_negative.py b/tempest/api/compute/images/test_images_oneserver_negative.py
index 9c4ab00..4e84e08 100644
--- a/tempest/api/compute/images/test_images_oneserver_negative.py
+++ b/tempest/api/compute/images/test_images_oneserver_negative.py
@@ -62,6 +62,11 @@
             skip_msg = ("%s skipped as glance is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
 
+        if not CONF.compute_feature_enabled.snapshot:
+            skip_msg = ("%s skipped as instance snapshotting is not supported"
+                        % cls.__name__)
+            raise cls.skipException(skip_msg)
+
         try:
             resp, server = cls.create_test_server(wait_until='ACTIVE')
             cls.server_id = server['id']
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index f9350e1..68794b1 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -16,6 +16,8 @@
 import StringIO
 import time
 
+import testtools
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
@@ -63,6 +65,9 @@
         cls.image3 = _create_image()
         cls.image3_id = cls.image3['id']
 
+        if not CONF.compute_feature_enabled.snapshot:
+            return
+
         # Create instances and snapshots via nova
         try:
             resp, cls.server1 = cls.create_test_server()
@@ -114,6 +119,8 @@
         self.assertFalse(any([i for i in images if i['id'] == self.image2_id]))
         self.assertFalse(any([i for i in images if i['id'] == self.image3_id]))
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
+                          'Snapshotting is not available.')
     @test.attr(type='gate')
     def test_list_images_filter_by_server_id(self):
         # The images should contain images filtered by server id
@@ -129,6 +136,8 @@
         self.assertFalse(any([i for i in images
                               if i['id'] == self.snapshot3_id]))
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
+                          'Snapshotting is not available.')
     @test.attr(type='gate')
     def test_list_images_filter_by_server_ref(self):
         # The list of servers should be filtered by server ref
@@ -146,6 +155,8 @@
             self.assertTrue(any([i for i in images
                                  if i['id'] == self.snapshot3_id]))
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
+                          'Snapshotting is not available.')
     @test.attr(type='gate')
     def test_list_images_filter_by_type(self):
         # The list of servers should be filtered by image type
@@ -211,6 +222,8 @@
         resp, images = self.client.list_images_with_detail(params)
         self.assertEqual(1, len(images))
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
+                          'Snapshotting is not available.')
     @test.attr(type='gate')
     def test_list_images_with_detail_filter_by_server_ref(self):
         # Detailed list of servers should be filtered by server ref
@@ -228,6 +241,8 @@
             self.assertTrue(any([i for i in images
                                  if i['id'] == self.snapshot3_id]))
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
+                          'Snapshotting is not available.')
     @test.attr(type='gate')
     def test_list_images_with_detail_filter_by_type(self):
         # The detailed list of servers should be filtered by image type
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 005f38a..f684a5a 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -256,6 +256,8 @@
         resp, server = self.client.get_server(self.server_id)
         self.assertEqual(previous_flavor_ref, server['flavor']['id'])
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
+                          'Snapshotting not available, backup not possible.')
     @test.attr(type='gate')
     def test_create_backup(self):
         # Positive test:create backup successfully and rotate backups correctly
diff --git a/tempest/api/compute/servers/test_servers_negative_new.py b/tempest/api/compute/servers/test_servers_negative_new.py
index 43ddb3a..c5f9fdd 100644
--- a/tempest/api/compute/servers/test_servers_negative_new.py
+++ b/tempest/api/compute/servers/test_servers_negative_new.py
@@ -15,6 +15,7 @@
 
 
 from tempest.api.compute import base
+from tempest.api_schema.request.compute.v2 import servers
 from tempest import test
 
 
@@ -25,7 +26,7 @@
 class GetConsoleOutputNegativeTestJSON(base.BaseV2ComputeTest,
                                        test.NegativeAutoTest):
     _service = 'compute'
-    _schema_file = 'compute/servers/get_console_output.json'
+    _schema = servers.get_console_output
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/flavors/test_flavors_negative.py b/tempest/api/compute/v3/flavors/test_flavors_negative.py
index 657e2cd..cdf018f 100644
--- a/tempest/api/compute/v3/flavors/test_flavors_negative.py
+++ b/tempest/api/compute/v3/flavors/test_flavors_negative.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 from tempest.api.compute import base
+from tempest.api_schema.request.compute.v3 import flavors
 from tempest import test
 
 
@@ -24,14 +25,14 @@
 class FlavorsListNegativeV3Test(base.BaseV3ComputeTest,
                                 test.NegativeAutoTest):
     _service = 'computev3'
-    _schema_file = 'compute/flavors/flavors_list_v3.json'
+    _schema = flavors.flavor_list
 
 
 @test.SimpleNegativeAutoTest
 class FlavorDetailsNegativeV3Test(base.BaseV3ComputeTest,
                                   test.NegativeAutoTest):
     _service = 'computev3'
-    _schema_file = 'compute/flavors/flavor_details_v3.json'
+    _schema = flavors.flavors_details
 
     @classmethod
     def setUpClass(cls):
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index d05e158..538507f 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -250,6 +250,8 @@
         resp, server = self.client.get_server(self.server_id)
         self.assertEqual(previous_flavor_ref, server['flavor']['id'])
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
+                          'Snapshotting not available, backup not possible.')
     @test.attr(type='gate')
     def test_create_backup(self):
         # Positive test:create backup successfully and rotate backups correctly
diff --git a/tempest/api/orchestration/stacks/test_volumes.py b/tempest/api/orchestration/stacks/test_volumes.py
index d422752..f11ac2a 100644
--- a/tempest/api/orchestration/stacks/test_volumes.py
+++ b/tempest/api/orchestration/stacks/test_volumes.py
@@ -79,8 +79,7 @@
 
     def _cleanup_volume(self, volume_id):
         """Cleanup the volume direct with cinder."""
-        resp = self.volumes_client.delete_volume(volume_id)
-        self.assertEqual(202, resp[0].status)
+        self.volumes_client.delete_volume(volume_id)
         self.volumes_client.wait_for_resource_deletion(volume_id)
 
     @test.attr(type='gate')
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index d451517..f3b1ad5 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -61,11 +61,11 @@
             extra_specs = {spec_key_with_prefix: backend_name_key}
         else:
             extra_specs = {spec_key_without_prefix: backend_name_key}
-        resp, self.type = self.client.create_volume_type(
+        _, self.type = self.client.create_volume_type(
             type_name, extra_specs=extra_specs)
         self.volume_type_id_list.append(self.type['id'])
 
-        resp, self.volume = self.volume_client.create_volume(
+        _, self.volume = self.volume_client.create_volume(
             size=1, display_name=vol_name, volume_type=type_name)
         self.volume_client.wait_for_volume_status(
             self.volume['id'], 'available')
@@ -130,8 +130,7 @@
         # the multi backend feature has been enabled
         # if multi-backend is enabled: os-vol-attr:host should be like:
         # host@backend_name
-        resp, volume = self.volume_client.get_volume(volume_id)
-        self.assertEqual(200, resp.status)
+        _, volume = self.volume_client.get_volume(volume_id)
 
         volume1_host = volume['os-vol-host-attr:host']
         msg = ("multi-backend reporting incorrect values for volume %s" %
@@ -142,10 +141,10 @@
         # this test checks that the two volumes created at setUp don't
         # belong to the same backend (if they are, than the
         # volume backend distinction is not working properly)
-        resp, volume = self.volume_client.get_volume(volume1_id)
+        _, volume = self.volume_client.get_volume(volume1_id)
         volume1_host = volume['os-vol-host-attr:host']
 
-        resp, volume = self.volume_client.get_volume(volume2_id)
+        _, volume = self.volume_client.get_volume(volume2_id)
         volume2_host = volume['os-vol-host-attr:host']
 
         msg = ("volumes %s and %s were created in the same backend" %
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index 594c703..abbe1e9 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -32,14 +32,14 @@
 
         # Create a test shared volume for tests
         vol_name = data_utils.rand_name(cls.__name__ + '-Volume-')
-        resp_vol, cls.volume = \
+        _, cls.volume = \
             cls.volumes_client.create_volume(size=1, display_name=vol_name)
         cls.volumes_client.wait_for_volume_status(cls.volume['id'],
                                                   'available')
 
         # Create a test shared snapshot for tests
         snap_name = data_utils.rand_name(cls.__name__ + '-Snapshot-')
-        resp_snap, cls.snapshot = \
+        _, cls.snapshot = \
             cls.client.create_snapshot(cls.volume['id'],
                                        display_name=snap_name)
         cls.client.wait_for_snapshot_status(cls.snapshot['id'],
@@ -70,12 +70,10 @@
         # and force delete temp snapshot
         temp_snapshot = self.create_snapshot(self.volume['id'])
         if status:
-            resp, body = self.admin_snapshots_client.\
+            _, 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.\
+        _, 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):
@@ -85,12 +83,10 @@
     def test_reset_snapshot_status(self):
         # Reset snapshot status to creating
         status = 'creating'
-        resp, body = self.admin_snapshots_client.\
+        _, body = self.admin_snapshots_client.\
             reset_snapshot_status(self.snapshot['id'], status)
-        self.assertEqual(202, resp.status)
-        resp_get, snapshot_get \
+        _, snapshot_get \
             = self.admin_snapshots_client.get_snapshot(self.snapshot['id'])
-        self.assertEqual(200, resp_get.status)
         self.assertEqual(status, snapshot_get['status'])
 
     @test.attr(type='gate')
@@ -104,12 +100,10 @@
         progress = '80%'
         status = 'error'
         progress_alias = self._get_progress_alias()
-        resp, body = self.client.update_snapshot_status(self.snapshot['id'],
-                                                        status, progress)
-        self.assertEqual(202, resp.status)
-        resp_get, snapshot_get \
+        _, body = self.client.update_snapshot_status(self.snapshot['id'],
+                                                     status, progress)
+        _, snapshot_get \
             = self.admin_snapshots_client.get_snapshot(self.snapshot['id'])
-        self.assertEqual(200, resp_get.status)
         self.assertEqual(status, snapshot_get['status'])
         self.assertEqual(progress, snapshot_get[progress_alias])
 
diff --git a/tempest/api/volume/admin/test_volume_hosts.py b/tempest/api/volume/admin/test_volume_hosts.py
index 01ba915..017363d 100644
--- a/tempest/api/volume/admin/test_volume_hosts.py
+++ b/tempest/api/volume/admin/test_volume_hosts.py
@@ -22,8 +22,7 @@
 
     @test.attr(type='gate')
     def test_list_hosts(self):
-        resp, hosts = self.hosts_client.list_hosts()
-        self.assertEqual(200, resp.status)
+        _, hosts = self.hosts_client.list_hosts()
         self.assertTrue(len(hosts) >= 2, "No. of hosts are < 2,"
                         "response of list hosts is: % s" % hosts)
 
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index ecd8836..fa3b667 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -34,30 +34,28 @@
 
     @test.attr(type='gate')
     def test_list_quotas(self):
-        resp, quotas = self.quotas_client.get_quota_set(self.demo_tenant_id)
-        self.assertEqual(200, resp.status)
+        _, quotas = self.quotas_client.get_quota_set(self.demo_tenant_id)
         for key in QUOTA_KEYS:
             self.assertIn(key, quotas)
 
     @test.attr(type='gate')
     def test_list_default_quotas(self):
-        resp, quotas = self.quotas_client.get_default_quota_set(
+        _, quotas = self.quotas_client.get_default_quota_set(
             self.demo_tenant_id)
-        self.assertEqual(200, resp.status)
         for key in QUOTA_KEYS:
             self.assertIn(key, quotas)
 
     @test.attr(type='gate')
     def test_update_all_quota_resources_for_tenant(self):
         # Admin can update all the resource quota limits for a tenant
-        resp, default_quota_set = self.quotas_client.get_default_quota_set(
+        _, default_quota_set = self.quotas_client.get_default_quota_set(
             self.demo_tenant_id)
         new_quota_set = {'gigabytes': 1009,
                          'volumes': 11,
                          'snapshots': 11}
 
         # Update limits for all quota resources
-        resp, quota_set = self.quotas_client.update_quota_set(
+        _, quota_set = self.quotas_client.update_quota_set(
             self.demo_tenant_id,
             **new_quota_set)
 
@@ -66,7 +64,6 @@
             if k in QUOTA_KEYS)
         self.addCleanup(self.quotas_client.update_quota_set,
                         self.demo_tenant_id, **cleanup_quota_set)
-        self.assertEqual(200, resp.status)
         # test that the specific values we set are actually in
         # the final result. There is nothing here that ensures there
         # would be no other values in there.
@@ -74,8 +71,7 @@
 
     @test.attr(type='gate')
     def test_show_quota_usage(self):
-        resp, quota_usage = self.quotas_client.get_quota_usage(self.adm_tenant)
-        self.assertEqual(200, resp.status)
+        _, quota_usage = self.quotas_client.get_quota_usage(self.adm_tenant)
         for key in QUOTA_KEYS:
             self.assertIn(key, quota_usage)
             for usage_key in QUOTA_USAGE_KEYS:
@@ -83,17 +79,16 @@
 
     @test.attr(type='gate')
     def test_quota_usage(self):
-        resp, quota_usage = self.quotas_client.get_quota_usage(
+        _, quota_usage = self.quotas_client.get_quota_usage(
             self.demo_tenant_id)
 
         volume = self.create_volume(size=1)
         self.addCleanup(self.admin_volume_client.delete_volume,
                         volume['id'])
 
-        resp, new_quota_usage = self.quotas_client.get_quota_usage(
+        _, new_quota_usage = self.quotas_client.get_quota_usage(
             self.demo_tenant_id)
 
-        self.assertEqual(200, resp.status)
         self.assertEqual(quota_usage['volumes']['in_use'] + 1,
                          new_quota_usage['volumes']['in_use'])
 
@@ -115,9 +110,7 @@
         self.quotas_client.update_quota_set(tenant_id,
                                             volumes=(int(volume_default) + 5))
 
-        resp, _ = self.quotas_client.delete_quota_set(tenant_id)
-        self.assertEqual(200, resp.status)
-
+        self.quotas_client.delete_quota_set(tenant_id)
         _, quota_set_new = self.quotas_client.get_quota_set(tenant_id)
         self.assertEqual(volume_default, quota_set_new['volumes'])
 
diff --git a/tempest/api/volume/admin/test_volume_quotas_negative.py b/tempest/api/volume/admin/test_volume_quotas_negative.py
index ab88b90..515024f 100644
--- a/tempest/api/volume/admin/test_volume_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_quotas_negative.py
@@ -32,7 +32,7 @@
 
         # NOTE(gfidente): no need to restore original quota set
         # after the tests as they only work with tenant isolation.
-        resp, quota_set = cls.quotas_client.update_quota_set(
+        _, quota_set = cls.quotas_client.update_quota_set(
             cls.demo_tenant_id,
             **cls.shared_quota_set)
 
@@ -63,7 +63,7 @@
                         **self.shared_quota_set)
 
         new_quota_set = {'gigabytes': 2, 'volumes': 2, 'snapshots': 1}
-        resp, quota_set = self.quotas_client.update_quota_set(
+        _, quota_set = self.quotas_client.update_quota_set(
             self.demo_tenant_id,
             **new_quota_set)
         self.assertRaises(exceptions.OverLimit,
@@ -71,7 +71,7 @@
                           size=1)
 
         new_quota_set = {'gigabytes': 2, 'volumes': 1, 'snapshots': 2}
-        resp, quota_set = self.quotas_client.update_quota_set(
+        _, quota_set = self.quotas_client.update_quota_set(
             self.demo_tenant_id,
             **self.shared_quota_set)
         self.assertRaises(exceptions.OverLimit,
diff --git a/tempest/api/volume/admin/test_volume_services.py b/tempest/api/volume/admin/test_volume_services.py
index 012c231..4a68e05 100644
--- a/tempest/api/volume/admin/test_volume_services.py
+++ b/tempest/api/volume/admin/test_volume_services.py
@@ -28,21 +28,19 @@
     def setUpClass(cls):
         super(VolumesServicesTestJSON, cls).setUpClass()
         cls.client = cls.os_adm.volume_services_client
-        resp, cls.services = cls.client.list_services()
+        _, cls.services = cls.client.list_services()
         cls.host_name = cls.services[0]['host']
         cls.binary_name = cls.services[0]['binary']
 
     @test.attr(type='gate')
     def test_list_services(self):
-        resp, services = self.client.list_services()
-        self.assertEqual(200, resp.status)
+        _, services = self.client.list_services()
         self.assertNotEqual(0, len(services))
 
     @test.attr(type='gate')
     def test_get_service_by_service_binary_name(self):
         params = {'binary': self.binary_name}
-        resp, services = self.client.list_services(params)
-        self.assertEqual(200, resp.status)
+        _, services = self.client.list_services(params)
         self.assertNotEqual(0, len(services))
         for service in services:
             self.assertEqual(self.binary_name, service['binary'])
@@ -53,7 +51,7 @@
                             service['host'] == self.host_name]
         params = {'host': self.host_name}
 
-        resp, services = self.client.list_services(params)
+        _, services = self.client.list_services(params)
 
         # we could have a periodic job checkin between the 2 service
         # lookups, so only compare binary lists.
@@ -67,8 +65,7 @@
     def test_get_service_by_service_and_host_name(self):
         params = {'host': self.host_name, 'binary': self.binary_name}
 
-        resp, services = self.client.list_services(params)
-        self.assertEqual(200, resp.status)
+        _, services = self.client.list_services(params)
         self.assertEqual(1, len(services))
         self.assertEqual(self.host_name, services[0]['host'])
         self.assertEqual(self.binary_name, services[0]['binary'])
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 3b8c214..070d38f 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -25,19 +25,16 @@
     _interface = "json"
 
     def _delete_volume(self, volume_id):
-        resp, _ = self.volumes_client.delete_volume(volume_id)
-        self.assertEqual(202, resp.status)
+        self.volumes_client.delete_volume(volume_id)
         self.volumes_client.wait_for_resource_deletion(volume_id)
 
     def _delete_volume_type(self, volume_type_id):
-        resp, _ = self.client.delete_volume_type(volume_type_id)
-        self.assertEqual(202, resp.status)
+        self.client.delete_volume_type(volume_type_id)
 
     @test.attr(type='smoke')
     def test_volume_type_list(self):
         # List Volume types.
-        resp, body = self.client.list_volume_types()
-        self.assertEqual(200, resp.status)
+        _, body = self.client.list_volume_types()
         self.assertIsInstance(body, list)
 
     @test.attr(type='smoke')
@@ -51,17 +48,15 @@
         extra_specs = {"storage_protocol": proto,
                        "vendor_name": vendor}
         body = {}
-        resp, body = self.client.create_volume_type(
+        _, body = self.client.create_volume_type(
             vol_type_name,
             extra_specs=extra_specs)
-        self.assertEqual(200, resp.status)
         self.assertIn('id', body)
         self.addCleanup(self._delete_volume_type, body['id'])
         self.assertIn('name', body)
-        resp, volume = self.volumes_client.create_volume(
+        _, volume = self.volumes_client.create_volume(
             size=1, display_name=vol_name,
             volume_type=vol_type_name)
-        self.assertEqual(200, resp.status)
         self.assertIn('id', volume)
         self.addCleanup(self._delete_volume, volume['id'])
         self.assertIn('display_name', volume)
@@ -72,8 +67,7 @@
                         "Field volume id is empty or not found.")
         self.volumes_client.wait_for_volume_status(volume['id'],
                                                    'available')
-        resp, fetched_volume = self.volumes_client.get_volume(volume['id'])
-        self.assertEqual(200, resp.status)
+        _, fetched_volume = self.volumes_client.get_volume(volume['id'])
         self.assertEqual(vol_name, fetched_volume['display_name'],
                          'The fetched Volume is different '
                          'from the created Volume')
@@ -93,10 +87,9 @@
         vendor = CONF.volume.vendor_name
         extra_specs = {"storage_protocol": proto,
                        "vendor_name": vendor}
-        resp, body = self.client.create_volume_type(
+        _, body = self.client.create_volume_type(
             name,
             extra_specs=extra_specs)
-        self.assertEqual(200, resp.status)
         self.assertIn('id', body)
         self.addCleanup(self._delete_volume_type, body['id'])
         self.assertIn('name', body)
@@ -105,8 +98,7 @@
                          "to the requested name")
         self.assertTrue(body['id'] is not None,
                         "Field volume_type id is empty or not found.")
-        resp, fetched_volume_type = self.client.get_volume_type(body['id'])
-        self.assertEqual(200, resp.status)
+        _, fetched_volume_type = self.client.get_volume_type(body['id'])
         self.assertEqual(name, fetched_volume_type['name'],
                          'The fetched Volume_type is different '
                          'from the created Volume_type')
@@ -123,15 +115,13 @@
         provider = "LuksEncryptor"
         control_location = "front-end"
         name = data_utils.rand_name("volume-type-")
-        resp, body = self.client.create_volume_type(name)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.create_volume_type(name)
         self.addCleanup(self._delete_volume_type, body['id'])
 
         # Create encryption type
-        resp, encryption_type = self.client.create_encryption_type(
+        _, encryption_type = self.client.create_encryption_type(
             body['id'], provider=provider,
             control_location=control_location)
-        self.assertEqual(200, resp.status)
         self.assertIn('volume_type_id', encryption_type)
         self.assertEqual(provider, encryption_type['provider'],
                          "The created encryption_type provider is not equal "
@@ -141,9 +131,8 @@
                          "equal to the requested control_location")
 
         # Get encryption type
-        resp, fetched_encryption_type = self.client.get_encryption_type(
+        _, fetched_encryption_type = self.client.get_encryption_type(
             encryption_type['volume_type_id'])
-        self.assertEqual(200, resp.status)
         self.assertEqual(provider,
                          fetched_encryption_type['provider'],
                          'The fetched encryption_type provider is different '
@@ -154,13 +143,11 @@
                          'different from the created encryption_type')
 
         # Delete encryption type
-        resp, _ = self.client.delete_encryption_type(
+        self.client.delete_encryption_type(
             encryption_type['volume_type_id'])
-        self.assertEqual(202, resp.status)
         resource = {"id": encryption_type['volume_type_id'],
                     "type": "encryption-type"}
         self.client.wait_for_resource_deletion(resource)
-        resp, deleted_encryption_type = self.client.get_encryption_type(
+        _, deleted_encryption_type = self.client.get_encryption_type(
             encryption_type['volume_type_id'])
-        self.assertEqual(200, resp.status)
         self.assertEmpty(deleted_encryption_type)
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs.py b/tempest/api/volume/admin/test_volume_types_extra_specs.py
index 06a0b34..c682866 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs.py
@@ -25,7 +25,7 @@
     def setUpClass(cls):
         super(VolumeTypesExtraSpecsTest, cls).setUpClass()
         vol_type_name = data_utils.rand_name('Volume-type-')
-        resp, cls.volume_type = cls.client.create_volume_type(vol_type_name)
+        _, cls.volume_type = cls.client.create_volume_type(vol_type_name)
 
     @classmethod
     def tearDownClass(cls):
@@ -36,14 +36,12 @@
     def test_volume_type_extra_specs_list(self):
         # List Volume types extra specs.
         extra_specs = {"spec1": "val1"}
-        resp, body = self.client.create_volume_type_extra_specs(
+        _, body = self.client.create_volume_type_extra_specs(
             self.volume_type['id'], extra_specs)
-        self.assertEqual(200, resp.status)
         self.assertEqual(extra_specs, body,
                          "Volume type extra spec incorrectly created")
-        resp, body = self.client.list_volume_types_extra_specs(
+        _, body = self.client.list_volume_types_extra_specs(
             self.volume_type['id'])
-        self.assertEqual(200, resp.status)
         self.assertIsInstance(body, dict)
         self.assertIn('spec1', body)
 
@@ -51,18 +49,16 @@
     def test_volume_type_extra_specs_update(self):
         # Update volume type extra specs
         extra_specs = {"spec2": "val1"}
-        resp, body = self.client.create_volume_type_extra_specs(
+        _, body = self.client.create_volume_type_extra_specs(
             self.volume_type['id'], extra_specs)
-        self.assertEqual(200, resp.status)
         self.assertEqual(extra_specs, body,
                          "Volume type extra spec incorrectly created")
 
         extra_spec = {"spec2": "val2"}
-        resp, body = self.client.update_volume_type_extra_specs(
+        _, body = self.client.update_volume_type_extra_specs(
             self.volume_type['id'],
             extra_spec.keys()[0],
             extra_spec)
-        self.assertEqual(200, resp.status)
         self.assertIn('spec2', body)
         self.assertEqual(extra_spec['spec2'], body['spec2'],
                          "Volume type extra spec incorrectly updated")
@@ -71,21 +67,18 @@
     def test_volume_type_extra_spec_create_get_delete(self):
         # Create/Get/Delete volume type extra spec.
         extra_specs = {"spec3": "val1"}
-        resp, body = self.client.create_volume_type_extra_specs(
+        _, body = self.client.create_volume_type_extra_specs(
             self.volume_type['id'],
             extra_specs)
-        self.assertEqual(200, resp.status)
         self.assertEqual(extra_specs, body,
                          "Volume type extra spec incorrectly created")
 
-        resp, _ = self.client.get_volume_type_extra_specs(
+        self.client.get_volume_type_extra_specs(
             self.volume_type['id'],
             extra_specs.keys()[0])
-        self.assertEqual(200, resp.status)
         self.assertEqual(extra_specs, body,
                          "Volume type extra spec incorrectly fetched")
 
-        resp, _ = self.client.delete_volume_type_extra_specs(
+        self.client.delete_volume_type_extra_specs(
             self.volume_type['id'],
             extra_specs.keys()[0])
-        self.assertEqual(202, resp.status)
diff --git a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
index da421dc..ff4f113 100644
--- a/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_extra_specs_negative.py
@@ -29,7 +29,7 @@
         super(ExtraSpecsNegativeTest, cls).setUpClass()
         vol_type_name = data_utils.rand_name('Volume-type-')
         cls.extra_specs = {"spec1": "val1"}
-        resp, cls.volume_type = cls.client.create_volume_type(
+        _, cls.volume_type = cls.client.create_volume_type(
             vol_type_name,
             extra_specs=cls.extra_specs)
 
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index 008f739..d6db1df 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -33,8 +33,8 @@
         # Create a test shared volume for tests
         vol_name = utils.rand_name(cls.__name__ + '-Volume-')
 
-        resp, cls.volume = cls.client.create_volume(size=1,
-                                                    display_name=vol_name)
+        _, cls.volume = cls.client.create_volume(size=1,
+                                                 display_name=vol_name)
         cls.client.wait_for_volume_status(cls.volume['id'], 'available')
 
     @classmethod
@@ -47,9 +47,9 @@
 
     def _reset_volume_status(self, volume_id, status):
         # Reset the volume status
-        resp, body = self.admin_volume_client.reset_volume_status(volume_id,
-                                                                  status)
-        return resp, body
+        _, body = self.admin_volume_client.reset_volume_status(volume_id,
+                                                               status)
+        return _, body
 
     def tearDown(self):
         # Set volume's status to available after test
@@ -59,8 +59,8 @@
     def _create_temp_volume(self):
         # Create a temp volume for force delete tests
         vol_name = utils.rand_name('Volume')
-        resp, temp_volume = self.client.create_volume(size=1,
-                                                      display_name=vol_name)
+        _, temp_volume = self.client.create_volume(size=1,
+                                                   display_name=vol_name)
         self.client.wait_for_volume_status(temp_volume['id'], 'available')
 
         return temp_volume
@@ -69,19 +69,16 @@
         # Create volume, reset volume status, and force delete temp volume
         temp_volume = self._create_temp_volume()
         if status:
-            resp, body = self._reset_volume_status(temp_volume['id'], status)
-            self.assertEqual(202, resp.status)
-        resp_delete, volume_delete = self.admin_volume_client.\
+            _, body = self._reset_volume_status(temp_volume['id'], status)
+        _, volume_delete = self.admin_volume_client.\
             force_delete_volume(temp_volume['id'])
-        self.assertEqual(202, resp_delete.status)
         self.client.wait_for_resource_deletion(temp_volume['id'])
 
     @test.attr(type='gate')
     def test_volume_reset_status(self):
         # test volume reset status : available->error->available
-        resp, body = self._reset_volume_status(self.volume['id'], 'error')
-        self.assertEqual(202, resp.status)
-        resp_get, volume_get = self.admin_volume_client.get_volume(
+        _, body = self._reset_volume_status(self.volume['id'], 'error')
+        _, volume_get = self.admin_volume_client.get_volume(
             self.volume['id'])
         self.assertEqual('error', volume_get['status'])
 
diff --git a/tempest/api/volume/admin/test_volumes_backup.py b/tempest/api/volume/admin/test_volumes_backup.py
index f9fbe18..3699e9c 100644
--- a/tempest/api/volume/admin/test_volumes_backup.py
+++ b/tempest/api/volume/admin/test_volumes_backup.py
@@ -43,9 +43,8 @@
         # Create backup
         backup_name = data_utils.rand_name('Backup')
         create_backup = self.backups_adm_client.create_backup
-        resp, backup = create_backup(self.volume['id'],
-                                     name=backup_name)
-        self.assertEqual(202, resp.status)
+        _, backup = create_backup(self.volume['id'],
+                                  name=backup_name)
         self.addCleanup(self.backups_adm_client.delete_backup,
                         backup['id'])
         self.assertEqual(backup_name, backup['name'])
@@ -55,19 +54,16 @@
                                                        'available')
 
         # Get a given backup
-        resp, backup = self.backups_adm_client.get_backup(backup['id'])
-        self.assertEqual(200, resp.status)
+        _, backup = self.backups_adm_client.get_backup(backup['id'])
         self.assertEqual(backup_name, backup['name'])
 
         # Get all backups with detail
-        resp, backups = self.backups_adm_client.list_backups_with_detail()
-        self.assertEqual(200, resp.status)
+        _, backups = self.backups_adm_client.list_backups_with_detail()
         self.assertIn((backup['name'], backup['id']),
                       [(m['name'], m['id']) for m in backups])
 
         # Restore backup
-        resp, restore = self.backups_adm_client.restore_backup(backup['id'])
-        self.assertEqual(202, resp.status)
+        _, restore = self.backups_adm_client.restore_backup(backup['id'])
 
         # Delete backup
         self.addCleanup(self.volumes_adm_client.delete_volume,
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index b7de767..3cd0827 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -63,8 +63,7 @@
                 cls.os.volume_availability_zone_client)
             # Special fields and resp code for cinder v1
             cls.special_fields = {'name_field': 'display_name',
-                                  'descrip_field': 'display_description',
-                                  'create_resp': 200}
+                                  'descrip_field': 'display_description'}
 
         elif cls._api_version == 2:
             if not CONF.volume_feature_enabled.api_v2:
@@ -76,8 +75,7 @@
                 cls.os.volume_v2_availability_zone_client)
             # Special fields and resp code for cinder v2
             cls.special_fields = {'name_field': 'name',
-                                  'descrip_field': 'description',
-                                  'create_resp': 202}
+                                  'descrip_field': 'description'}
 
         else:
             msg = ("Invalid Cinder API version (%s)" % cls._api_version)
@@ -96,11 +94,9 @@
         name = data_utils.rand_name('Volume')
 
         name_field = cls.special_fields['name_field']
-        expect_status = cls.special_fields['create_resp']
 
         kwargs[name_field] = name
-        resp, volume = cls.volumes_client.create_volume(size, **kwargs)
-        assert expect_status == resp.status
+        _, volume = cls.volumes_client.create_volume(size, **kwargs)
 
         cls.volumes.append(volume)
         cls.volumes_client.wait_for_volume_status(volume['id'], 'available')
@@ -109,9 +105,8 @@
     @classmethod
     def create_snapshot(cls, volume_id=1, **kwargs):
         """Wrapper utility that returns a test snapshot."""
-        resp, snapshot = cls.snapshots_client.create_snapshot(volume_id,
-                                                              **kwargs)
-        assert 200 == resp.status
+        _, snapshot = cls.snapshots_client.create_snapshot(volume_id,
+                                                           **kwargs)
         cls.snapshots.append(snapshot)
         cls.snapshots_client.wait_for_snapshot_status(snapshot['id'],
                                                       'available')
diff --git a/tempest/api/volume/test_availability_zone.py b/tempest/api/volume/test_availability_zone.py
index 25b7b85..c026f71 100644
--- a/tempest/api/volume/test_availability_zone.py
+++ b/tempest/api/volume/test_availability_zone.py
@@ -31,8 +31,7 @@
     @test.attr(type='gate')
     def test_get_availability_zone_list(self):
         # List of availability zone
-        resp, availability_zone = self.client.get_availability_zone_list()
-        self.assertEqual(200, resp.status)
+        _, availability_zone = self.client.get_availability_zone_list()
         self.assertTrue(len(availability_zone) > 0)
 
 
diff --git a/tempest/api/volume/test_extensions.py b/tempest/api/volume/test_extensions.py
index ff00dd1..4fc6ee4 100644
--- a/tempest/api/volume/test_extensions.py
+++ b/tempest/api/volume/test_extensions.py
@@ -30,8 +30,7 @@
     @test.attr(type='gate')
     def test_list_extensions(self):
         # List of all extensions
-        resp, extensions = self.volumes_extension_client.list_extensions()
-        self.assertEqual(200, resp.status)
+        _, extensions = self.volumes_extension_client.list_extensions()
         if len(CONF.volume_feature_enabled.api_extensions) == 0:
             raise self.skipException('There are not any extensions configured')
         extension_list = [extension.get('alias') for extension in extensions]
diff --git a/tempest/api/volume/test_snapshot_metadata.py b/tempest/api/volume/test_snapshot_metadata.py
index d2c4ab7..94ba095 100644
--- a/tempest/api/volume/test_snapshot_metadata.py
+++ b/tempest/api/volume/test_snapshot_metadata.py
@@ -44,19 +44,15 @@
                     "key3": "value3"}
         expected = {"key2": "value2",
                     "key3": "value3"}
-        resp, body = self.client.create_snapshot_metadata(self.snapshot_id,
-                                                          metadata)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.create_snapshot_metadata(self.snapshot_id,
+                                                       metadata)
         # Get the metadata of the snapshot
-        resp, body = self.client.get_snapshot_metadata(self.snapshot_id)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.get_snapshot_metadata(self.snapshot_id)
         self.assertEqual(metadata, body)
         # Delete one item metadata of the snapshot
-        resp, body = self.client.delete_snapshot_metadata_item(
-            self.snapshot_id,
-            "key1")
-        self.assertEqual(200, resp.status)
-        resp, body = self.client.get_snapshot_metadata(self.snapshot_id)
+        self.client.delete_snapshot_metadata_item(
+            self.snapshot_id, "key1")
+        _, body = self.client.get_snapshot_metadata(self.snapshot_id)
         self.assertEqual(expected, body)
 
     @test.attr(type='gate')
@@ -68,21 +64,16 @@
         update = {"key3": "value3_update",
                   "key4": "value4"}
         # Create metadata for the snapshot
-        resp, body = self.client.create_snapshot_metadata(self.snapshot_id,
-                                                          metadata)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.create_snapshot_metadata(self.snapshot_id,
+                                                       metadata)
         # Get the metadata of the snapshot
-        resp, body = self.client.get_snapshot_metadata(self.snapshot_id)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.get_snapshot_metadata(self.snapshot_id)
         self.assertEqual(metadata, body)
         # Update metadata item
-        resp, body = self.client.update_snapshot_metadata(
-            self.snapshot_id,
-            update)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.update_snapshot_metadata(
+            self.snapshot_id, update)
         # Get the metadata of the snapshot
-        resp, body = self.client.get_snapshot_metadata(self.snapshot_id)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.get_snapshot_metadata(self.snapshot_id)
         self.assertEqual(update, body)
 
     @test.attr(type='gate')
@@ -96,21 +87,16 @@
                   "key2": "value2",
                   "key3": "value3_update"}
         # Create metadata for the snapshot
-        resp, body = self.client.create_snapshot_metadata(self.snapshot_id,
-                                                          metadata)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.create_snapshot_metadata(self.snapshot_id,
+                                                       metadata)
         # Get the metadata of the snapshot
-        resp, body = self.client.get_snapshot_metadata(self.snapshot_id)
+        _, body = self.client.get_snapshot_metadata(self.snapshot_id)
         self.assertEqual(metadata, body)
         # Update metadata item
-        resp, body = self.client.update_snapshot_metadata_item(
-            self.snapshot_id,
-            "key3",
-            update_item)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.update_snapshot_metadata_item(
+            self.snapshot_id, "key3", update_item)
         # Get the metadata of the snapshot
-        resp, body = self.client.get_snapshot_metadata(self.snapshot_id)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.get_snapshot_metadata(self.snapshot_id)
         self.assertEqual(expect, body)
 
 
diff --git a/tempest/api/volume/test_volume_metadata.py b/tempest/api/volume/test_volume_metadata.py
index 0505f19..ac760aa 100644
--- a/tempest/api/volume/test_volume_metadata.py
+++ b/tempest/api/volume/test_volume_metadata.py
@@ -42,19 +42,15 @@
                     "key3": "value3",
                     "key4": "<value&special_chars>"}
 
-        rsp, body = self.volumes_client.create_volume_metadata(self.volume_id,
-                                                               metadata)
-        self.assertEqual(200, rsp.status)
+        _, body = self.volumes_client.create_volume_metadata(self.volume_id,
+                                                             metadata)
         # Get the metadata of the volume
-        resp, body = self.volumes_client.get_volume_metadata(self.volume_id)
-        self.assertEqual(200, resp.status)
+        _, body = self.volumes_client.get_volume_metadata(self.volume_id)
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
         # Delete one item metadata of the volume
-        rsp, body = self.volumes_client.delete_volume_metadata_item(
-            self.volume_id,
-            "key1")
-        self.assertEqual(200, rsp.status)
-        resp, body = self.volumes_client.get_volume_metadata(self.volume_id)
+        self.volumes_client.delete_volume_metadata_item(
+            self.volume_id, "key1")
+        _, body = self.volumes_client.get_volume_metadata(self.volume_id)
         self.assertNotIn("key1", body)
         del metadata["key1"]
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
@@ -70,22 +66,16 @@
                   "key1": "value1_update"}
 
         # Create metadata for the volume
-        resp, body = self.volumes_client.create_volume_metadata(
-            self.volume_id,
-            metadata)
-        self.assertEqual(200, resp.status)
+        _, body = self.volumes_client.create_volume_metadata(
+            self.volume_id, metadata)
         # Get the metadata of the volume
-        resp, body = self.volumes_client.get_volume_metadata(self.volume_id)
-        self.assertEqual(200, resp.status)
+        _, body = self.volumes_client.get_volume_metadata(self.volume_id)
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
         # Update metadata
-        resp, body = self.volumes_client.update_volume_metadata(
-            self.volume_id,
-            update)
-        self.assertEqual(200, resp.status)
+        _, body = self.volumes_client.update_volume_metadata(
+            self.volume_id, update)
         # Get the metadata of the volume
-        resp, body = self.volumes_client.get_volume_metadata(self.volume_id)
-        self.assertEqual(200, resp.status)
+        _, body = self.volumes_client.get_volume_metadata(self.volume_id)
         self.assertThat(body.items(), matchers.ContainsAll(update.items()))
 
     @test.attr(type='gate')
@@ -99,20 +89,14 @@
                   "key2": "value2",
                   "key3": "value3_update"}
         # Create metadata for the volume
-        resp, body = self.volumes_client.create_volume_metadata(
-            self.volume_id,
-            metadata)
-        self.assertEqual(200, resp.status)
+        _, body = self.volumes_client.create_volume_metadata(
+            self.volume_id, metadata)
         self.assertThat(body.items(), matchers.ContainsAll(metadata.items()))
         # Update metadata item
-        resp, body = self.volumes_client.update_volume_metadata_item(
-            self.volume_id,
-            "key3",
-            update_item)
-        self.assertEqual(200, resp.status)
+        _, body = self.volumes_client.update_volume_metadata_item(
+            self.volume_id, "key3", update_item)
         # Get the metadata of the volume
-        resp, body = self.volumes_client.get_volume_metadata(self.volume_id)
-        self.assertEqual(200, resp.status)
+        _, body = self.volumes_client.get_volume_metadata(self.volume_id)
         self.assertThat(body.items(), matchers.ContainsAll(expect.items()))
 
 
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index bf61222..4a6ba03 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -47,8 +47,7 @@
 
     def _delete_volume(self, volume_id):
         # Delete the specified volume using admin creds
-        resp, _ = self.adm_client.delete_volume(volume_id)
-        self.assertEqual(202, resp.status)
+        self.adm_client.delete_volume(volume_id)
         self.adm_client.wait_for_resource_deletion(volume_id)
 
     @test.attr(type='gate')
@@ -58,28 +57,24 @@
         self.addCleanup(self._delete_volume, volume['id'])
 
         # Create a volume transfer
-        resp, transfer = self.client.create_volume_transfer(volume['id'])
-        self.assertEqual(202, resp.status)
+        _, transfer = self.client.create_volume_transfer(volume['id'])
         transfer_id = transfer['id']
         auth_key = transfer['auth_key']
         self.client.wait_for_volume_status(volume['id'],
                                            'awaiting-transfer')
 
         # Get a volume transfer
-        resp, body = self.client.get_volume_transfer(transfer_id)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.get_volume_transfer(transfer_id)
         self.assertEqual(volume['id'], body['volume_id'])
 
         # List volume transfers, the result should be greater than
         # or equal to 1
-        resp, body = self.client.list_volume_transfers()
-        self.assertEqual(200, resp.status)
+        _, body = self.client.list_volume_transfers()
         self.assertThat(len(body), matchers.GreaterThan(0))
 
         # Accept a volume transfer by alt_tenant
-        resp, body = self.alt_client.accept_volume_transfer(transfer_id,
-                                                            auth_key)
-        self.assertEqual(202, resp.status)
+        _, body = self.alt_client.accept_volume_transfer(transfer_id,
+                                                         auth_key)
         self.alt_client.wait_for_volume_status(volume['id'], 'available')
 
     def test_create_list_delete_volume_transfer(self):
@@ -88,15 +83,13 @@
         self.addCleanup(self._delete_volume, volume['id'])
 
         # Create a volume transfer
-        resp, body = self.client.create_volume_transfer(volume['id'])
-        self.assertEqual(202, resp.status)
+        _, body = self.client.create_volume_transfer(volume['id'])
         transfer_id = body['id']
         self.client.wait_for_volume_status(volume['id'],
                                            'awaiting-transfer')
 
         # List all volume transfers (looking for the one we created)
-        resp, body = self.client.list_volume_transfers()
-        self.assertEqual(200, resp.status)
+        _, body = self.client.list_volume_transfers()
         for transfer in body:
             if volume['id'] == transfer['volume_id']:
                 break
@@ -104,8 +97,7 @@
             self.fail('Transfer not found for volume %s' % volume['id'])
 
         # Delete a volume transfer
-        resp, body = self.client.delete_volume_transfer(transfer_id)
-        self.assertEqual(202, resp.status)
+        self.client.delete_volume_transfer(transfer_id)
         self.client.wait_for_volume_status(volume['id'], 'available')
 
 
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 6fef564..c87878d 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -40,6 +40,10 @@
         # Create a test shared volume for attach/detach tests
         cls.volume = cls.create_volume()
 
+    def _delete_image_with_wait(self, image_id):
+        self.image_client.delete_image(image_id)
+        self.image_client.wait_for_resource_deletion(image_id)
+
     @classmethod
     def tearDownClass(cls):
         # Delete the test instance
@@ -54,13 +58,11 @@
     def test_attach_detach_volume_to_instance(self):
         # Volume is attached and detached successfully from an instance
         mountpoint = '/dev/vdc'
-        resp, body = self.client.attach_volume(self.volume['id'],
-                                               self.server['id'],
-                                               mountpoint)
-        self.assertEqual(202, resp.status)
+        _, body = self.client.attach_volume(self.volume['id'],
+                                            self.server['id'],
+                                            mountpoint)
         self.client.wait_for_volume_status(self.volume['id'], 'in-use')
-        resp, body = self.client.detach_volume(self.volume['id'])
-        self.assertEqual(202, resp.status)
+        _, body = self.client.detach_volume(self.volume['id'])
         self.client.wait_for_volume_status(self.volume['id'], 'available')
 
     @test.stresstest(class_setup_per='process')
@@ -69,10 +71,9 @@
     def test_get_volume_attachment(self):
         # Verify that a volume's attachment information is retrieved
         mountpoint = '/dev/vdc'
-        resp, body = self.client.attach_volume(self.volume['id'],
-                                               self.server['id'],
-                                               mountpoint)
-        self.assertEqual(202, resp.status)
+        _, body = self.client.attach_volume(self.volume['id'],
+                                            self.server['id'],
+                                            mountpoint)
         self.client.wait_for_volume_status(self.volume['id'], 'in-use')
         # NOTE(gfidente): added in reverse order because functions will be
         # called in reverse order to the order they are added (LIFO)
@@ -80,8 +81,7 @@
                         self.volume['id'],
                         'available')
         self.addCleanup(self.client.detach_volume, self.volume['id'])
-        resp, volume = self.client.get_volume(self.volume['id'])
-        self.assertEqual(200, resp.status)
+        _, volume = self.client.get_volume(self.volume['id'])
         self.assertIn('attachments', volume)
         attachment = self.client.get_attachment_from_volume(volume)
         self.assertEqual(mountpoint, attachment['device'])
@@ -97,41 +97,25 @@
         # there is no way to delete it from Cinder, so we delete it from Glance
         # using the Glance image_client and from Cinder via tearDownClass.
         image_name = data_utils.rand_name('Image-')
-        resp, body = self.client.upload_volume(self.volume['id'],
-                                               image_name,
-                                               CONF.volume.disk_format)
+        _, body = self.client.upload_volume(self.volume['id'],
+                                            image_name,
+                                            CONF.volume.disk_format)
         image_id = body["image_id"]
         self.addCleanup(self.image_client.delete_image, image_id)
-        self.assertEqual(202, resp.status)
         self.image_client.wait_for_image_status(image_id, 'active')
         self.client.wait_for_volume_status(self.volume['id'], 'available')
 
     @test.attr(type='gate')
-    def test_volume_extend(self):
-        # Extend Volume Test.
-        extend_size = int(self.volume['size']) + 1
-        resp, body = self.client.extend_volume(self.volume['id'], extend_size)
-        self.assertEqual(202, resp.status)
-        self.client.wait_for_volume_status(self.volume['id'], 'available')
-        resp, volume = self.client.get_volume(self.volume['id'])
-        self.assertEqual(200, resp.status)
-        self.assertEqual(int(volume['size']), extend_size)
-
-    @test.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)
+        _, body = self.client.reserve_volume(self.volume['id'])
         # To get the volume info
-        resp, body = self.client.get_volume(self.volume['id'])
-        self.assertEqual(200, resp.status)
+        _, body = self.client.get_volume(self.volume['id'])
         self.assertIn('attaching', body['status'])
         # Unmark volume as reserved.
-        resp, body = self.client.unreserve_volume(self.volume['id'])
-        self.assertEqual(202, resp.status)
+        _, body = self.client.unreserve_volume(self.volume['id'])
         # To get the volume info
-        resp, body = self.client.get_volume(self.volume['id'])
-        self.assertEqual(200, resp.status)
+        _, body = self.client.get_volume(self.volume['id'])
         self.assertIn('available', body['status'])
 
     def _is_true(self, val):
@@ -141,26 +125,21 @@
     def test_volume_readonly_update(self):
         # Update volume readonly true
         readonly = True
-        resp, body = self.client.update_volume_readonly(self.volume['id'],
-                                                        readonly)
-        self.assertEqual(202, resp.status)
-
+        _, body = self.client.update_volume_readonly(self.volume['id'],
+                                                     readonly)
         # Get Volume information
-        resp, fetched_volume = self.client.get_volume(self.volume['id'])
+        _, fetched_volume = self.client.get_volume(self.volume['id'])
         bool_flag = self._is_true(fetched_volume['metadata']['readonly'])
-        self.assertEqual(200, resp.status)
         self.assertEqual(True, bool_flag)
 
         # Update volume readonly false
         readonly = False
-        resp, body = self.client.update_volume_readonly(self.volume['id'],
-                                                        readonly)
-        self.assertEqual(202, resp.status)
+        _, body = self.client.update_volume_readonly(self.volume['id'],
+                                                     readonly)
 
         # Get Volume information
-        resp, fetched_volume = self.client.get_volume(self.volume['id'])
+        _, fetched_volume = self.client.get_volume(self.volume['id'])
         bool_flag = self._is_true(fetched_volume['metadata']['readonly'])
-        self.assertEqual(200, resp.status)
         self.assertEqual(False, bool_flag)
 
 
diff --git a/tempest/api/volume/test_volumes_extend.py b/tempest/api/volume/test_volumes_extend.py
new file mode 100644
index 0000000..c9e80aa
--- /dev/null
+++ b/tempest/api/volume/test_volumes_extend.py
@@ -0,0 +1,51 @@
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.volume import base
+from tempest import config
+from tempest import test
+
+CONF = config.CONF
+
+
+class VolumesV2ExtendTest(base.BaseVolumeTest):
+
+    @classmethod
+    @test.safe_setup
+    def setUpClass(cls):
+        super(VolumesV2ExtendTest, cls).setUpClass()
+        cls.client = cls.volumes_client
+
+    @test.attr(type='gate')
+    def test_volume_extend(self):
+        # Extend Volume Test.
+        self.volume = self.create_volume()
+        extend_size = int(self.volume['size']) + 1
+        _, body = self.client.extend_volume(self.volume['id'], extend_size)
+        self.client.wait_for_volume_status(self.volume['id'], 'available')
+        _, volume = self.client.get_volume(self.volume['id'])
+        self.assertEqual(int(volume['size']), extend_size)
+
+
+class VolumesV2ExtendTestXML(VolumesV2ExtendTest):
+    _interface = "xml"
+
+
+class VolumesV1ExtendTest(VolumesV2ExtendTest):
+    _api_version = 1
+
+
+class VolumesV1ExtendTestXML(VolumesV1ExtendTest):
+    _interface = "xml"
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index 82208aa..a346a17 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -32,11 +32,9 @@
 
         cls.name_field = cls.special_fields['name_field']
         cls.descrip_field = cls.special_fields['descrip_field']
-        cls.create_resp = cls.special_fields['create_resp']
 
     def _delete_volume(self, volume_id):
-        resp, _ = self.client.delete_volume(volume_id)
-        self.assertEqual(202, resp.status)
+        self.client.delete_volume(volume_id)
         self.client.wait_for_resource_deletion(volume_id)
 
     def _is_true(self, val):
@@ -56,8 +54,7 @@
         # Create a volume
         kwargs[self.name_field] = v_name
         kwargs['metadata'] = metadata
-        resp, volume = self.client.create_volume(**kwargs)
-        self.assertEqual(self.create_resp, resp.status)
+        _, volume = self.client.create_volume(**kwargs)
         self.assertIn('id', volume)
         self.addCleanup(self._delete_volume, volume['id'])
         self.client.wait_for_volume_status(volume['id'], 'available')
@@ -68,8 +65,7 @@
         self.assertTrue(volume['id'] is not None,
                         "Field volume id is empty or not found.")
         # Get Volume information
-        resp, fetched_volume = self.client.get_volume(volume['id'])
-        self.assertEqual(200, resp.status)
+        _, fetched_volume = self.client.get_volume(volume['id'])
         self.assertEqual(v_name,
                          fetched_volume[self.name_field],
                          'The fetched Volume name is different '
@@ -94,21 +90,18 @@
         # Update Volume
         # Test volume update when display_name is same with original value
         params = {self.name_field: v_name}
-        resp, update_volume = self.client.update_volume(volume['id'], **params)
-        self.assertEqual(200, resp.status)
+        _, update_volume = self.client.update_volume(volume['id'], **params)
         # Test volume update when display_name is new
         new_v_name = data_utils.rand_name('new-Volume')
         new_desc = 'This is the new description of volume'
         params = {self.name_field: new_v_name,
                   self.descrip_field: new_desc}
-        resp, update_volume = self.client.update_volume(volume['id'], **params)
+        _, update_volume = self.client.update_volume(volume['id'], **params)
         # Assert response body for update_volume method
-        self.assertEqual(200, resp.status)
         self.assertEqual(new_v_name, update_volume[self.name_field])
         self.assertEqual(new_desc, update_volume[self.descrip_field])
         # Assert response body for get_volume method
-        resp, updated_volume = self.client.get_volume(volume['id'])
-        self.assertEqual(200, resp.status)
+        _, updated_volume = self.client.get_volume(volume['id'])
         self.assertEqual(volume['id'], updated_volume['id'])
         self.assertEqual(new_v_name, updated_volume[self.name_field])
         self.assertEqual(new_desc, updated_volume[self.descrip_field])
@@ -123,17 +116,15 @@
         new_v_desc = data_utils.rand_name('@#$%^* description')
         params = {self.descrip_field: new_v_desc,
                   'availability_zone': volume['availability_zone']}
-        resp, new_volume = self.client.create_volume(size=1, **params)
-        self.assertEqual(self.create_resp, resp.status)
+        _, new_volume = self.client.create_volume(size=1, **params)
         self.assertIn('id', new_volume)
         self.addCleanup(self._delete_volume, new_volume['id'])
         self.client.wait_for_volume_status(new_volume['id'], 'available')
 
         params = {self.name_field: volume[self.name_field],
                   self.descrip_field: volume[self.descrip_field]}
-        resp, update_volume = self.client.update_volume(new_volume['id'],
-                                                        **params)
-        self.assertEqual(200, resp.status)
+        _, update_volume = self.client.update_volume(new_volume['id'],
+                                                     **params)
 
         # NOTE(jdg): Revert back to strict true/false checking
         # after fix for bug #1227837 merges
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index ff225a2..272a41a 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -67,7 +67,7 @@
         cls.metadata = {'Type': 'work'}
         for i in range(3):
             volume = cls.create_volume(metadata=cls.metadata)
-            resp, volume = cls.client.get_volume(volume['id'])
+            _, volume = cls.client.get_volume(volume['id'])
             cls.volume_list.append(volume)
             cls.volume_id_list.append(volume['id'])
 
@@ -75,7 +75,7 @@
     def tearDownClass(cls):
         # Delete the created volumes
         for volid in cls.volume_id_list:
-            resp, _ = cls.client.delete_volume(volid)
+            cls.client.delete_volume(volid)
             cls.client.wait_for_resource_deletion(volid)
         super(VolumesV2ListTestJSON, cls).tearDownClass()
 
@@ -85,12 +85,11 @@
         and validates result.
         """
         if with_detail:
-            resp, fetched_vol_list = \
+            _, fetched_vol_list = \
                 self.client.list_volumes_with_detail(params=params)
         else:
-            resp, fetched_vol_list = self.client.list_volumes(params=params)
+            _, fetched_vol_list = self.client.list_volumes(params=params)
 
-        self.assertEqual(200, resp.status)
         # Validating params of fetched volumes
         # In v2, only list detail view includes items in params.
         # In v1, list view and list detail view are same. So the
@@ -113,8 +112,7 @@
     def test_volume_list(self):
         # Get a list of Volumes
         # Fetch all volumes
-        resp, fetched_list = self.client.list_volumes()
-        self.assertEqual(200, resp.status)
+        _, fetched_list = self.client.list_volumes()
         self.assertVolumesIn(fetched_list, self.volume_list,
                              fields=self.VOLUME_FIELDS)
 
@@ -122,16 +120,14 @@
     def test_volume_list_with_details(self):
         # Get a list of Volumes with details
         # Fetch all Volumes
-        resp, fetched_list = self.client.list_volumes_with_detail()
-        self.assertEqual(200, resp.status)
+        _, fetched_list = self.client.list_volumes_with_detail()
         self.assertVolumesIn(fetched_list, self.volume_list)
 
     @test.attr(type='gate')
     def test_volume_list_by_name(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {self.name: volume[self.name]}
-        resp, fetched_vol = self.client.list_volumes(params)
-        self.assertEqual(200, resp.status)
+        _, fetched_vol = self.client.list_volumes(params)
         self.assertEqual(1, len(fetched_vol), str(fetched_vol))
         self.assertEqual(fetched_vol[0][self.name],
                          volume[self.name])
@@ -140,8 +136,7 @@
     def test_volume_list_details_by_name(self):
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         params = {self.name: volume[self.name]}
-        resp, fetched_vol = self.client.list_volumes_with_detail(params)
-        self.assertEqual(200, resp.status)
+        _, fetched_vol = self.client.list_volumes_with_detail(params)
         self.assertEqual(1, len(fetched_vol), str(fetched_vol))
         self.assertEqual(fetched_vol[0][self.name],
                          volume[self.name])
@@ -149,8 +144,7 @@
     @test.attr(type='gate')
     def test_volumes_list_by_status(self):
         params = {'status': 'available'}
-        resp, fetched_list = self.client.list_volumes(params)
-        self.assertEqual(200, resp.status)
+        _, fetched_list = self.client.list_volumes(params)
         self._list_by_param_value_and_assert(params)
         self.assertVolumesIn(fetched_list, self.volume_list,
                              fields=self.VOLUME_FIELDS)
@@ -158,8 +152,7 @@
     @test.attr(type='gate')
     def test_volumes_list_details_by_status(self):
         params = {'status': 'available'}
-        resp, fetched_list = self.client.list_volumes_with_detail(params)
-        self.assertEqual(200, resp.status)
+        _, fetched_list = self.client.list_volumes_with_detail(params)
         for volume in fetched_list:
             self.assertEqual('available', volume['status'])
         self.assertVolumesIn(fetched_list, self.volume_list)
@@ -169,8 +162,7 @@
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
         params = {'availability_zone': zone}
-        resp, fetched_list = self.client.list_volumes(params)
-        self.assertEqual(200, resp.status)
+        _, fetched_list = self.client.list_volumes(params)
         self._list_by_param_value_and_assert(params)
         self.assertVolumesIn(fetched_list, self.volume_list,
                              fields=self.VOLUME_FIELDS)
@@ -180,8 +172,7 @@
         volume = self.volume_list[data_utils.rand_int_id(0, 2)]
         zone = volume['availability_zone']
         params = {'availability_zone': zone}
-        resp, fetched_list = self.client.list_volumes_with_detail(params)
-        self.assertEqual(200, resp.status)
+        _, fetched_list = self.client.list_volumes_with_detail(params)
         for volume in fetched_list:
             self.assertEqual(zone, volume['availability_zone'])
         self.assertVolumesIn(fetched_list, self.volume_list)
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 8bd4c88..5f0cffa 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -225,44 +225,38 @@
     @test.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)
+        _, body = self.client.reserve_volume(self.volume['id'])
         # 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)
+        _, body = self.client.unreserve_volume(self.volume['id'])
 
     @test.attr(type=['negative', 'gate'])
     def test_list_volumes_with_nonexistent_name(self):
         v_name = data_utils.rand_name('Volume-')
         params = {self.name_field: v_name}
-        resp, fetched_volume = self.client.list_volumes(params)
-        self.assertEqual(200, resp.status)
+        _, fetched_volume = self.client.list_volumes(params)
         self.assertEqual(0, len(fetched_volume))
 
     @test.attr(type=['negative', 'gate'])
     def test_list_volumes_detail_with_nonexistent_name(self):
         v_name = data_utils.rand_name('Volume-')
         params = {self.name_field: v_name}
-        resp, fetched_volume = self.client.list_volumes_with_detail(params)
-        self.assertEqual(200, resp.status)
+        _, fetched_volume = self.client.list_volumes_with_detail(params)
         self.assertEqual(0, len(fetched_volume))
 
     @test.attr(type=['negative', 'gate'])
     def test_list_volumes_with_invalid_status(self):
         params = {'status': 'null'}
-        resp, fetched_volume = self.client.list_volumes(params)
-        self.assertEqual(200, resp.status)
+        _, fetched_volume = self.client.list_volumes(params)
         self.assertEqual(0, len(fetched_volume))
 
     @test.attr(type=['negative', 'gate'])
     def test_list_volumes_detail_with_invalid_status(self):
         params = {'status': 'null'}
-        resp, fetched_volume = self.client.list_volumes_with_detail(params)
-        self.assertEqual(200, resp.status)
+        _, fetched_volume = self.client.list_volumes_with_detail(params)
         self.assertEqual(0, len(fetched_volume))
 
 
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 26316d2..7db1ef1 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -47,14 +47,13 @@
         and validates result.
         """
         if with_detail:
-            resp, fetched_snap_list = \
+            _, fetched_snap_list = \
                 self.snapshots_client.\
                 list_snapshots_with_detail(params=params)
         else:
-            resp, fetched_snap_list = \
+            _, fetched_snap_list = \
                 self.snapshots_client.list_snapshots(params=params)
 
-        self.assertEqual(200, resp.status)
         # Validating params of fetched snapshots
         for snap in fetched_snap_list:
             for key in params:
@@ -74,9 +73,8 @@
         self.addCleanup(self.servers_client.delete_server, server['id'])
         self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
         mountpoint = '/dev/%s' % CONF.compute.volume_device_name
-        resp, body = self.volumes_client.attach_volume(
+        _, body = self.volumes_client.attach_volume(
             self.volume_origin['id'], server['id'], mountpoint)
-        self.assertEqual(202, resp.status)
         self.volumes_client.wait_for_volume_status(self.volume_origin['id'],
                                                    'in-use')
         self.addCleanup(self._detach, self.volume_origin['id'])
@@ -85,7 +83,6 @@
                                         force=True)
         # Delete the snapshot
         self.snapshots_client.delete_snapshot(snapshot['id'])
-        self.assertEqual(202, resp.status)
         self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
         self.snapshots.remove(snapshot)
 
@@ -97,40 +94,35 @@
                                         display_name=s_name)
 
         # Get the snap and check for some of its details
-        resp, snap_get = self.snapshots_client.get_snapshot(snapshot['id'])
-        self.assertEqual(200, resp.status)
+        _, snap_get = self.snapshots_client.get_snapshot(snapshot['id'])
         self.assertEqual(self.volume_origin['id'],
                          snap_get['volume_id'],
                          "Referred volume origin mismatch")
 
         # Compare also with the output from the list action
         tracking_data = (snapshot['id'], snapshot['display_name'])
-        resp, snaps_list = self.snapshots_client.list_snapshots()
-        self.assertEqual(200, resp.status)
+        _, snaps_list = self.snapshots_client.list_snapshots()
         snaps_data = [(f['id'], f['display_name']) for f in snaps_list]
         self.assertIn(tracking_data, snaps_data)
 
         # Updates snapshot with new values
         new_s_name = data_utils.rand_name('new-snap')
         new_desc = 'This is the new description of snapshot.'
-        resp, update_snapshot = \
+        _, update_snapshot = \
             self.snapshots_client.update_snapshot(snapshot['id'],
                                                   display_name=new_s_name,
                                                   display_description=new_desc)
         # Assert response body for update_snapshot method
-        self.assertEqual(200, resp.status)
         self.assertEqual(new_s_name, update_snapshot['display_name'])
         self.assertEqual(new_desc, update_snapshot['display_description'])
         # Assert response body for get_snapshot method
-        resp, updated_snapshot = \
+        _, updated_snapshot = \
             self.snapshots_client.get_snapshot(snapshot['id'])
-        self.assertEqual(200, resp.status)
         self.assertEqual(new_s_name, updated_snapshot['display_name'])
         self.assertEqual(new_desc, updated_snapshot['display_description'])
 
         # Delete the snapshot
         self.snapshots_client.delete_snapshot(snapshot['id'])
-        self.assertEqual(200, resp.status)
         self.snapshots_client.wait_for_resource_deletion(snapshot['id'])
         self.snapshots.remove(snapshot)
 
@@ -177,13 +169,12 @@
     @test.attr(type='gate')
     def test_volume_from_snapshot(self):
         # Create a temporary snap using wrapper method from base, then
-        # create a snap based volume, check resp code and deletes it
+        # create a snap based volume and deletes it
         snapshot = self.create_snapshot(self.volume_origin['id'])
         # NOTE(gfidente): size is required also when passing snapshot_id
-        resp, volume = self.volumes_client.create_volume(
+        _, volume = self.volumes_client.create_volume(
             size=1,
             snapshot_id=snapshot['id'])
-        self.assertEqual(200, resp.status)
         self.volumes_client.wait_for_volume_status(volume['id'], 'available')
         self.volumes_client.delete_volume(volume['id'])
         self.volumes_client.wait_for_resource_deletion(volume['id'])
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index 7ca8599..3ae227d 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -42,7 +42,7 @@
         cls.metadata = {'Type': 'work'}
         for i in range(3):
             volume = cls.create_volume(metadata=cls.metadata)
-            resp, volume = cls.client.get_volume(volume['id'])
+            _, volume = cls.client.get_volume(volume['id'])
             cls.volume_list.append(volume)
             cls.volume_id_list.append(volume['id'])
 
@@ -50,7 +50,7 @@
     def tearDownClass(cls):
         # Delete the created volumes
         for volid in cls.volume_id_list:
-            resp, _ = cls.client.delete_volume(volid)
+            cls.client.delete_volume(volid)
             cls.client.wait_for_resource_deletion(volid)
         super(VolumesV2ListTestJSON, cls).tearDownClass()
 
@@ -66,8 +66,7 @@
                       'sort_dir': sort_dir,
                       'sort_key': sort_key
                       }
-            resp, fetched_volume = self.client.list_volumes_with_detail(params)
-            self.assertEqual(200, resp.status)
+            _, fetched_volume = self.client.list_volumes_with_detail(params)
             self.assertEqual(limit, len(fetched_volume),
                              "The count of volumes is %s, expected:%s " %
                              (len(fetched_volume), limit))
diff --git a/tempest/api_schema/request/__init__.py b/tempest/api_schema/request/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api_schema/request/__init__.py
diff --git a/tempest/api_schema/request/compute/__init__.py b/tempest/api_schema/request/compute/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api_schema/request/compute/__init__.py
diff --git a/tempest/api_schema/request/compute/flavors.py b/tempest/api_schema/request/compute/flavors.py
new file mode 100644
index 0000000..8fe9e3a
--- /dev/null
+++ b/tempest/api_schema/request/compute/flavors.py
@@ -0,0 +1,53 @@
+# (c) 2014 Deutsche Telekom AG
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+
+common_flavor_details = {
+    "name": "get-flavor-details",
+    "http-method": "GET",
+    "url": "flavors/%s",
+    "resources": [
+        {"name": "flavor", "expected_result": 404}
+    ]
+}
+
+common_flavor_list = {
+    "name": "list-flavors-with-detail",
+    "http-method": "GET",
+    "url": "flavors/detail",
+    "json-schema": {
+        "type": "object",
+        "properties": {
+        }
+    }
+}
+
+common_admin_flavor_create = {
+    "name": "flavor-create",
+    "http-method": "POST",
+    "admin_client": True,
+    "url": "flavors",
+    "default_result_code": 400,
+    "json-schema": {
+        "type": "object",
+        "properties": {
+            "name": {"type": "string"},
+            "ram": {"type": "integer", "minimum": 1},
+            "vcpus": {"type": "integer", "minimum": 1},
+            "disk": {"type": "integer"},
+            "id": {"type": "integer"},
+            "swap": {"type": "integer"},
+            "rxtx_factor": {"type": "integer"},
+            "OS-FLV-EXT-DATA:ephemeral": {"type": "integer"}
+        }
+    }
+}
diff --git a/tempest/api_schema/request/compute/servers.py b/tempest/api_schema/request/compute/servers.py
new file mode 100644
index 0000000..731649c
--- /dev/null
+++ b/tempest/api_schema/request/compute/servers.py
@@ -0,0 +1,36 @@
+# (c) 2014 Deutsche Telekom AG
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+
+common_get_console_output = {
+    "name": "get-console-output",
+    "http-method": "POST",
+    "url": "servers/%s/action",
+    "resources": [
+        {"name": "server", "expected_result": 404}
+    ],
+    "json-schema": {
+        "type": "object",
+        "properties": {
+            "os-getConsoleOutput": {
+                "type": "object",
+                "properties": {
+                    "length": {
+                        "type": ["integer", "string"],
+                        "minimum": 0
+                    }
+                }
+            }
+        },
+        "additionalProperties": False
+    }
+}
diff --git a/tempest/api_schema/request/compute/v2/__init__.py b/tempest/api_schema/request/compute/v2/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api_schema/request/compute/v2/__init__.py
diff --git a/tempest/api_schema/request/compute/v2/flavors.py b/tempest/api_schema/request/compute/v2/flavors.py
new file mode 100644
index 0000000..bc459ad
--- /dev/null
+++ b/tempest/api_schema/request/compute/v2/flavors.py
@@ -0,0 +1,39 @@
+# (c) 2014 Deutsche Telekom AG
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+
+import copy
+
+from tempest.api_schema.request.compute import flavors
+
+flavors_details = copy.deepcopy(flavors.common_flavor_details)
+
+flavor_list = copy.deepcopy(flavors.common_flavor_list)
+
+flavor_create = copy.deepcopy(flavors.common_admin_flavor_create)
+
+flavor_list["json-schema"]["properties"] = {
+    "minRam": {
+        "type": "integer",
+        "results": {
+            "gen_none": 400,
+            "gen_string": 400
+        }
+    },
+    "minDisk": {
+        "type": "integer",
+        "results": {
+            "gen_none": 400,
+            "gen_string": 400
+        }
+    }
+}
diff --git a/tempest/api_schema/request/compute/v2/servers.py b/tempest/api_schema/request/compute/v2/servers.py
new file mode 100644
index 0000000..c9002ed
--- /dev/null
+++ b/tempest/api_schema/request/compute/v2/servers.py
@@ -0,0 +1,18 @@
+# (c) 2014 Deutsche Telekom AG
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+
+import copy
+
+from tempest.api_schema.request.compute import servers
+
+get_console_output = copy.deepcopy(servers.common_get_console_output)
diff --git a/tempest/api_schema/request/compute/v3/__init__.py b/tempest/api_schema/request/compute/v3/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tempest/api_schema/request/compute/v3/__init__.py
diff --git a/tempest/api_schema/request/compute/v3/flavors.py b/tempest/api_schema/request/compute/v3/flavors.py
new file mode 100644
index 0000000..b913aca
--- /dev/null
+++ b/tempest/api_schema/request/compute/v3/flavors.py
@@ -0,0 +1,37 @@
+# (c) 2014 Deutsche Telekom AG
+#    Licensed under the Apache License, Version 2.0 (the "License");
+#    you may not use this file except in compliance with the License.
+#    You may obtain a copy of the License at
+#
+#        http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS,
+#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#    See the License for the specific language governing permissions and
+#    limitations under the License.
+
+import copy
+
+from tempest.api_schema.request.compute import flavors
+
+flavors_details = copy.deepcopy(flavors.common_flavor_details)
+
+flavor_list = copy.deepcopy(flavors.common_flavor_list)
+
+flavor_list["json-schema"]["properties"] = {
+    "min_ram": {
+        "type": "integer",
+        "results": {
+            "gen_none": 400,
+            "gen_string": 400
+        }
+    },
+    "min_disk": {
+        "type": "integer",
+        "results": {
+            "gen_none": 400,
+            "gen_string": 400
+        }
+    }
+}
diff --git a/tempest/cli/simple_read_only/test_ceilometer.py b/tempest/cli/simple_read_only/test_ceilometer.py
index 1d2822d..b622dd4 100644
--- a/tempest/cli/simple_read_only/test_ceilometer.py
+++ b/tempest/cli/simple_read_only/test_ceilometer.py
@@ -39,15 +39,19 @@
             raise cls.skipException(msg)
         super(SimpleReadOnlyCeilometerClientTest, cls).setUpClass()
 
+    @test.services('telemetry')
     def test_ceilometer_meter_list(self):
         self.ceilometer('meter-list')
 
     @test.attr(type='slow')
+    @test.services('telemetry')
     def test_ceilometer_resource_list(self):
         self.ceilometer('resource-list')
 
+    @test.services('telemetry')
     def test_ceilometermeter_alarm_list(self):
         self.ceilometer('alarm-list')
 
+    @test.services('telemetry')
     def test_ceilometer_version(self):
         self.ceilometer('', flags='--version')
diff --git a/tempest/clients.py b/tempest/clients.py
index 0edcdf4..2b8b6fb 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -50,6 +50,7 @@
 from tempest.services.compute.json.limits_client import LimitsClientJSON
 from tempest.services.compute.json.migrations_client import \
     MigrationsClientJSON
+from tempest.services.compute.json.networks_client import NetworksClientJSON
 from tempest.services.compute.json.quotas_client import QuotaClassesClientJSON
 from tempest.services.compute.json.quotas_client import QuotasClientJSON
 from tempest.services.compute.json.security_group_default_rules_client import \
@@ -426,6 +427,7 @@
         self.migrations_client = MigrationsClientJSON(self.auth_provider)
         self.security_group_default_rules_client = (
             SecurityGroupDefaultRulesClientJSON(self.auth_provider))
+        self.networks_client = NetworksClientJSON(self.auth_provider)
 
 
 class AltManager(Manager):
diff --git a/tempest/common/custom_matchers.py b/tempest/common/custom_matchers.py
index 996c365..7348a7d 100644
--- a/tempest/common/custom_matchers.py
+++ b/tempest/common/custom_matchers.py
@@ -13,6 +13,9 @@
 #    under the License.
 
 import re
+from unittest import util
+
+from testtools import helpers
 
 
 class ExistsAllResponseHeaders(object):
@@ -172,3 +175,54 @@
 
     def get_details(self):
         return {}
+
+
+class MatchesDictExceptForKeys(object):
+    """Matches two dictionaries. Verifies all items are equals except for those
+    identified by a list of keys.
+    """
+
+    def __init__(self, expected, excluded_keys=None):
+        self.expected = expected
+        self.excluded_keys = excluded_keys if excluded_keys is not None else []
+
+    def match(self, actual):
+        filtered_expected = helpers.dict_subtract(self.expected,
+                                                  self.excluded_keys)
+        filtered_actual = helpers.dict_subtract(actual,
+                                                self.excluded_keys)
+        if filtered_actual != filtered_expected:
+            return DictMismatch(filtered_expected, filtered_actual)
+
+
+class DictMismatch(object):
+    """Mismatch between two dicts describes deltas"""
+
+    def __init__(self, expected, actual):
+        self.expected = expected
+        self.actual = actual
+        self.intersect = set(self.expected) & set(self.actual)
+        self.symmetric_diff = set(self.expected) ^ set(self.actual)
+
+    def describe(self):
+        msg = ""
+        if self.symmetric_diff:
+            only_expected = helpers.dict_subtract(self.expected, self.actual)
+            only_actual = helpers.dict_subtract(self.actual, self.expected)
+            if only_expected:
+                msg += "Only in expected:\n  %s\n" % \
+                       util.safe_repr(only_expected)
+            if only_actual:
+                msg += "Only in actual:\n  %s\n" % \
+                       util.safe_repr(only_actual)
+        diff_set = set(o for o in self.intersect if
+                       self.expected[o] != self.actual[o])
+        if diff_set:
+            msg += "Differences:\n"
+        for o in diff_set:
+            msg += "  %s: expected %s, actual %s\n" % (
+                o, self.expected[o], self.actual[o])
+        return msg
+
+    def get_details(self):
+        return {}
diff --git a/tempest/common/generator/valid_generator.py b/tempest/common/generator/valid_generator.py
index a99bbc0..0d7b398 100644
--- a/tempest/common/generator/valid_generator.py
+++ b/tempest/common/generator/valid_generator.py
@@ -24,7 +24,7 @@
     @base.generator_type("string")
     @base.simple_generator
     def generate_valid_string(self, schema):
-        size = schema.get("minLength", 0)
+        size = schema.get("minLength", 1)
         # TODO(dkr mko): handle format and pattern
         return "x" * size
 
diff --git a/tempest/config.py b/tempest/config.py
index af6dd7a..4836c63 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -347,7 +347,11 @@
     cfg.BoolOpt('interface_attach',
                 default=True,
                 help='Does the test environment support dynamic network '
-                     'interface attachment?')
+                     'interface attachment?'),
+    cfg.BoolOpt('snapshot',
+                default=True,
+                help='Does the test environment support creating snapshot '
+                     'images of running instances?')
 ]
 
 
@@ -1079,6 +1083,10 @@
 
     DEFAULT_CONFIG_FILE = "tempest.conf"
 
+    def __getattr__(self, attr):
+        # Handles config options from the default group
+        return getattr(cfg.CONF, attr)
+
     def _set_attrs(self):
         self.auth = cfg.CONF.auth
         self.compute = cfg.CONF.compute
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 203b653..76d82aa 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -78,6 +78,11 @@
         return cls._get_credentials(cls.isolated_creds.get_primary_creds,
                                     'user')
 
+    @classmethod
+    def admin_credentials(cls):
+        return cls._get_credentials(cls.isolated_creds.get_admin_creds,
+                                    'identity_admin')
+
 
 class OfficialClientTest(tempest.test.BaseTestCase):
     """
@@ -355,6 +360,22 @@
 
         return secgroup
 
+    def rebuild_server(self, server, client=None, image=None,
+                       preserve_ephemeral=False, wait=True,
+                       rebuild_kwargs=None):
+        if client is None:
+            client = self.compute_client
+        if image is None:
+            image = CONF.compute.image_ref
+        rebuild_kwargs = rebuild_kwargs or {}
+
+        LOG.debug("Rebuilding server (name: %s, image: %s, preserve eph: %s)",
+                  server.name, image, preserve_ephemeral)
+        server.rebuild(image, preserve_ephemeral=preserve_ephemeral,
+                       **rebuild_kwargs)
+        if wait:
+            self.status_timeout(client.servers, server.id, 'ACTIVE')
+
     def create_server(self, client=None, name=None, image=None, flavor=None,
                       wait_on_boot=True, wait_on_delete=True,
                       create_kwargs={}):
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index 0059619..3ad5c69 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -23,7 +23,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class TestAggregatesBasicOps(manager.OfficialClientTest):
+class TestAggregatesBasicOps(manager.ScenarioTest):
     """
     Creates an aggregate within an availability zone
     Adds a host to the aggregate
@@ -33,74 +33,67 @@
     Deletes aggregate
     """
     @classmethod
+    def setUpClass(cls):
+        super(TestAggregatesBasicOps, cls).setUpClass()
+        cls.aggregates_client = cls.manager.aggregates_client
+        cls.hosts_client = cls.manager.hosts_client
+
+    @classmethod
     def credentials(cls):
         return cls.admin_credentials()
 
     def _create_aggregate(self, **kwargs):
-        aggregate = self.compute_client.aggregates.create(**kwargs)
+        _, aggregate = self.aggregates_client.create_aggregate(**kwargs)
+        self.addCleanup(self._delete_aggregate, aggregate)
         aggregate_name = kwargs['name']
         availability_zone = kwargs['availability_zone']
-        self.assertEqual(aggregate.name, aggregate_name)
-        self.assertEqual(aggregate.availability_zone, availability_zone)
-        self.addCleanup(self._delete_aggregate, aggregate)
-        LOG.debug("Aggregate %s created." % (aggregate.name))
+        self.assertEqual(aggregate['name'], aggregate_name)
+        self.assertEqual(aggregate['availability_zone'], availability_zone)
         return aggregate
 
     def _delete_aggregate(self, aggregate):
-        self.compute_client.aggregates.delete(aggregate.id)
-        LOG.debug("Aggregate %s deleted. " % (aggregate.name))
+        self.aggregates_client.delete_aggregate(aggregate['id'])
 
     def _get_host_name(self):
-        hosts = self.compute_client.hosts.list()
+        _, hosts = self.hosts_client.list_hosts()
         self.assertTrue(len(hosts) >= 1)
-        computes = [x for x in hosts if x.service == 'compute']
-        return computes[0].host_name
+        computes = [x for x in hosts if x['service'] == 'compute']
+        return computes[0]['host_name']
 
-    def _add_host(self, aggregate_name, host):
-        aggregate = self.compute_client.aggregates.add_host(aggregate_name,
-                                                            host)
-        self.addCleanup(self._remove_host, aggregate, host)
-        self.assertIn(host, aggregate.hosts)
-        LOG.debug("Host %s added to Aggregate %s." % (host, aggregate.name))
+    def _add_host(self, aggregate_id, host):
+        _, aggregate = self.aggregates_client.add_host(aggregate_id, host)
+        self.addCleanup(self._remove_host, aggregate['id'], host)
+        self.assertIn(host, aggregate['hosts'])
 
-    def _remove_host(self, aggregate_name, host):
-        aggregate = self.compute_client.aggregates.remove_host(aggregate_name,
-                                                               host)
-        self.assertNotIn(host, aggregate.hosts)
-        LOG.debug("Host %s removed to Aggregate %s." % (host, aggregate.name))
+    def _remove_host(self, aggregate_id, host):
+        _, aggregate = self.aggregates_client.remove_host(aggregate_id, host)
+        self.assertNotIn(host, aggregate['hosts'])
 
     def _check_aggregate_details(self, aggregate, aggregate_name, azone,
                                  hosts, metadata):
-        aggregate = self.compute_client.aggregates.get(aggregate.id)
-        self.assertEqual(aggregate_name, aggregate.name)
-        self.assertEqual(azone, aggregate.availability_zone)
-        self.assertEqual(aggregate.hosts, hosts)
+        _, aggregate = self.aggregates_client.get_aggregate(aggregate['id'])
+        self.assertEqual(aggregate_name, aggregate['name'])
+        self.assertEqual(azone, aggregate['availability_zone'])
+        self.assertEqual(hosts, aggregate['hosts'])
         for meta_key in metadata.keys():
-            self.assertIn(meta_key, aggregate.metadata)
-            self.assertEqual(metadata[meta_key], aggregate.metadata[meta_key])
-        LOG.debug("Aggregate %s details match." % aggregate.name)
+            self.assertIn(meta_key, aggregate['metadata'])
+            self.assertEqual(metadata[meta_key],
+                             aggregate['metadata'][meta_key])
 
     def _set_aggregate_metadata(self, aggregate, meta):
-        aggregate = self.compute_client.aggregates.set_metadata(aggregate.id,
-                                                                meta)
+        _, aggregate = self.aggregates_client.set_metadata(aggregate['id'],
+                                                           meta)
 
         for key, value in meta.items():
-            self.assertEqual(meta[key], aggregate.metadata[key])
-        LOG.debug("Aggregate %s metadata updated successfully." %
-                  aggregate.name)
+            self.assertEqual(meta[key], aggregate['metadata'][key])
 
     def _update_aggregate(self, aggregate, aggregate_name,
                           availability_zone):
-        values = {}
-        if aggregate_name:
-            values.update({'name': aggregate_name})
-        if availability_zone:
-            values.update({'availability_zone': availability_zone})
-        if values.keys():
-            aggregate = self.compute_client.aggregates.update(aggregate.id,
-                                                              values)
-            for key, values in values.items():
-                self.assertEqual(getattr(aggregate, key), values)
+        _, aggregate = self.aggregates_client.update_aggregate(
+            aggregate['id'], name=aggregate_name,
+            availability_zone=availability_zone)
+        self.assertEqual(aggregate['name'], aggregate_name)
+        self.assertEqual(aggregate['availability_zone'], availability_zone)
         return aggregate
 
     @test.services('compute')
@@ -115,16 +108,17 @@
         self._set_aggregate_metadata(aggregate, metadata)
 
         host = self._get_host_name()
-        self._add_host(aggregate, host)
+        self._add_host(aggregate['id'], host)
         self._check_aggregate_details(aggregate, aggregate_name, az, [host],
                                       metadata)
 
         aggregate_name = data_utils.rand_name('renamed-aggregate-scenario')
-        aggregate = self._update_aggregate(aggregate, aggregate_name, None)
+        # Updating the name alone. The az must be specified again otherwise
+        # the tempest client would send None in the put body
+        aggregate = self._update_aggregate(aggregate, aggregate_name, az)
 
-        additional_metadata = {'foo': 'bar'}
-        self._set_aggregate_metadata(aggregate, additional_metadata)
+        new_metadata = {'foo': 'bar'}
+        self._set_aggregate_metadata(aggregate, new_metadata)
 
-        metadata.update(additional_metadata)
-        self._check_aggregate_details(aggregate, aggregate.name, az, [host],
-                                      metadata)
+        self._check_aggregate_details(aggregate, aggregate['name'], az,
+                                      [host], new_metadata)
diff --git a/tempest/scenario/test_baremetal_basic_ops.py b/tempest/scenario/test_baremetal_basic_ops.py
index f197c15..9ad6bc4 100644
--- a/tempest/scenario/test_baremetal_basic_ops.py
+++ b/tempest/scenario/test_baremetal_basic_ops.py
@@ -23,7 +23,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class BaremetalBasicOpsPXESSH(manager.BaremetalScenarioTest):
+class BaremetalBasicOps(manager.BaremetalScenarioTest):
     """
     This smoke test tests the pxe_ssh Ironic driver.  It follows this basic
     set of operations:
@@ -35,10 +35,76 @@
         * Verifies SSH connectivity using created keypair via fixed IP
         * Associates a floating ip
         * Verifies SSH connectivity using created keypair via floating IP
+        * Verifies instance rebuild with ephemeral partition preservation
         * Deletes instance
         * Monitors the associated Ironic node for power and
           expected state transitions
     """
+    def rebuild_instance(self, preserve_ephemeral=False):
+        self.rebuild_server(self.instance,
+                            preserve_ephemeral=preserve_ephemeral,
+                            wait=False)
+
+        node = self.get_node(instance_id=self.instance.id)
+        self.instance = self.compute_client.servers.get(self.instance.id)
+
+        self.addCleanup_with_wait(self.compute_client.servers,
+                                  self.instance.id,
+                                  cleanup_callable=self.delete_wrapper,
+                                  cleanup_args=[self.instance])
+
+        # We should remain on the same node
+        self.assertEqual(self.node.uuid, node.uuid)
+        self.node = node
+
+        self.status_timeout(self.compute_client.servers, self.instance.id,
+                            'REBUILD')
+        self.status_timeout(self.compute_client.servers, self.instance.id,
+                            'ACTIVE')
+
+    def create_remote_file(self, client, filename):
+        """Create a file on the remote client connection.
+
+        After creating the file, force a filesystem sync. Otherwise,
+        if we issue a rebuild too quickly, the file may not exist.
+        """
+        client.exec_command('sudo touch ' + filename)
+        client.exec_command('sync')
+
+    def verify_partition(self, client, label, mount, gib_size):
+        """Verify a labeled partition's mount point and size."""
+        LOG.info("Looking for partition %s mounted on %s" % (label, mount))
+
+        # Validate we have a device with the given partition label
+        cmd = "/sbin/blkid | grep '%s' | cut -d':' -f1" % label
+        device = client.exec_command(cmd).rstrip('\n')
+        LOG.debug("Partition device is %s" % device)
+        self.assertNotEqual('', device)
+
+        # Validate the mount point for the device
+        cmd = "mount | grep '%s' | cut -d' ' -f3" % device
+        actual_mount = client.exec_command(cmd).rstrip('\n')
+        LOG.debug("Partition mount point is %s" % actual_mount)
+        self.assertEqual(actual_mount, mount)
+
+        # Validate the partition size matches what we expect
+        numbers = '0123456789'
+        devnum = device.replace('/dev/', '')
+        cmd = "cat /sys/block/%s/%s/size" % (devnum.rstrip(numbers), devnum)
+        num_bytes = client.exec_command(cmd).rstrip('\n')
+        num_bytes = int(num_bytes) * 512
+        actual_gib_size = num_bytes / (1024 * 1024 * 1024)
+        LOG.debug("Partition size is %d GiB" % actual_gib_size)
+        self.assertEqual(actual_gib_size, gib_size)
+
+    def get_flavor_ephemeral_size(self):
+        """Returns size of the ephemeral partition in GiB."""
+        f_id = self.instance.flavor['id']
+        ephemeral = self.compute_client.flavors.get(f_id).ephemeral
+        if ephemeral != 'N/A':
+            return int(ephemeral)
+        return None
+
     def add_floating_ip(self):
         floating_ip = self.compute_client.floating_ips.create()
         self.instance.add_floating_ip(floating_ip)
@@ -53,10 +119,32 @@
 
     @test.services('baremetal', 'compute', 'image', 'network')
     def test_baremetal_server_ops(self):
+        test_filename = '/mnt/rebuild_test.txt'
         self.add_keypair()
         self.boot_instance()
         self.validate_ports()
         self.verify_connectivity()
         floating_ip = self.add_floating_ip()
         self.verify_connectivity(ip=floating_ip)
+
+        vm_client = self.get_remote_client(self.instance)
+
+        # We expect the ephemeral partition to be mounted on /mnt and to have
+        # the same size as our flavor definition.
+        eph_size = self.get_flavor_ephemeral_size()
+        self.assertIsNotNone(eph_size)
+        self.verify_partition(vm_client, 'ephemeral0', '/mnt', eph_size)
+
+        # Create the test file
+        self.create_remote_file(vm_client, test_filename)
+
+        # Rebuild and preserve the ephemeral partition
+        self.rebuild_instance(True)
+        self.verify_connectivity()
+
+        # Check that we maintained our data
+        vm_client = self.get_remote_client(self.instance)
+        self.verify_partition(vm_client, 'ephemeral0', '/mnt', eph_size)
+        vm_client.exec_command('ls ' + test_filename)
+
         self.terminate_instance()
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index fc6c66c..bba034b 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -22,6 +22,7 @@
 from tempest.common import debug
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest.scenario import manager
 from tempest import test
@@ -222,23 +223,31 @@
         self.addCleanup(self.delete_wrapper, server)
 
         def check_ports():
-            port_list = [port for port in
-                         self._list_ports(device_id=server.id)
-                         if port != old_port]
-            return len(port_list) == 1
+            self.new_port_list = [port for port in
+                                  self._list_ports(device_id=server.id)
+                                  if port != old_port]
+            return len(self.new_port_list) == 1
 
-        test.call_until_true(check_ports, 60, 1)
-        new_port_list = [p for p in
-                         self._list_ports(device_id=server.id)
-                         if p != old_port]
-        self.assertEqual(1, len(new_port_list))
-        new_port = new_port_list[0]
+        if not test.call_until_true(check_ports, CONF.network.build_timeout,
+                                    CONF.network.build_interval):
+            raise exceptions.TimeoutException("No new port attached to the "
+                                              "server in time (%s sec) !"
+                                              % CONF.network.build_timeout)
         new_port = net_common.DeletablePort(client=self.network_client,
-                                            **new_port)
-        new_nic_list = self._get_server_nics(ssh_client)
-        diff_list = [n for n in new_nic_list if n not in old_nic_list]
-        self.assertEqual(1, len(diff_list))
-        num, new_nic = diff_list[0]
+                                            **self.new_port_list[0])
+
+        def check_new_nic():
+            new_nic_list = self._get_server_nics(ssh_client)
+            self.diff_list = [n for n in new_nic_list if n not in old_nic_list]
+            return len(self.diff_list) == 1
+
+        if not test.call_until_true(check_new_nic, CONF.network.build_timeout,
+                                    CONF.network.build_interval):
+            raise exceptions.TimeoutException("Interface not visible on the "
+                                              "guest after %s sec"
+                                              % CONF.network.build_timeout)
+
+        num, new_nic = self.diff_list[0]
         ssh_client.assign_static_ip(nic=new_nic,
                                     addr=new_port.fixed_ips[0]['ip_address'])
         ssh_client.turn_nic_on(nic=new_nic)
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 8058b3d..ecb802f 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -213,10 +213,16 @@
         myport = (tenant.router.id, tenant.subnet.id)
         router_ports = [(i['device_id'], i['fixed_ips'][0]['subnet_id']) for i
                         in self.network_client.list_ports()['ports']
-                        if i['device_owner'] == 'network:router_interface']
+                        if self._is_router_port(i)]
 
         self.assertIn(myport, router_ports)
 
+    def _is_router_port(self, port):
+        """Return True if port is a router interface."""
+        # NOTE(armando-migliaccio): match device owner for both centralized
+        # and distributed routers; 'device_owner' is "" by default.
+        return port['device_owner'].startswith('network:router_interface')
+
     def _create_server(self, name, tenant, security_groups=None):
         """
         creates a server and assigns to security group
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 7dd662d..ffdd006 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import testtools
+
 from tempest import config
 from tempest.openstack.common import log
 from tempest.scenario import manager
@@ -71,6 +73,8 @@
     def _set_floating_ip_to_server(self, server, floating_ip):
         server.add_floating_ip(floating_ip)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
+                          'Snapshotting is not available.')
     @test.services('compute', 'network', 'image')
     def test_snapshot_pattern(self):
         # prepare for booting a instance
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index be27024..4783273 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -16,6 +16,7 @@
 import time
 
 from cinderclient import exceptions as cinder_exceptions
+import testtools
 
 from tempest.common.utils import data_utils
 from tempest import config
@@ -150,6 +151,8 @@
         self.assertEqual(self.timestamp, got_timestamp)
 
     @tempest.test.skip_because(bug="1205344")
+    @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
+                          'Snapshotting is not available.')
     @tempest.test.services('compute', 'network', 'volume', 'image')
     def test_stamp_pattern(self):
         # prepare for booting a instance
diff --git a/tempest/services/compute/json/networks_client.py b/tempest/services/compute/json/networks_client.py
new file mode 100644
index 0000000..40eb1a6
--- /dev/null
+++ b/tempest/services/compute/json/networks_client.py
@@ -0,0 +1,40 @@
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import json
+
+from tempest.common import rest_client
+from tempest import config
+
+CONF = config.CONF
+
+
+class NetworksClientJSON(rest_client.RestClient):
+
+    def __init__(self, auth_provider):
+        super(NetworksClientJSON, self).__init__(auth_provider)
+        self.service = CONF.compute.catalog_type
+
+    def list_networks(self):
+        resp, body = self.get("os-networks")
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return resp, body['networks']
+
+    def get_network(self, network_id):
+        resp, body = self.get("os-networks/%s" % str(network_id))
+        body = json.loads(body)
+        self.expected_success(200, resp.status)
+        return resp, body['network']
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index 4a7c163..bc5e04a 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -235,7 +235,7 @@
 
     def is_resource_deleted(self, id):
         try:
-            self.get_image(id)
+            self.get_image_meta(id)
         except exceptions.NotFound:
             return True
         return False
diff --git a/tempest/services/volume/json/admin/volume_hosts_client.py b/tempest/services/volume/json/admin/volume_hosts_client.py
index 84e4705..b3a22b5 100644
--- a/tempest/services/volume/json/admin/volume_hosts_client.py
+++ b/tempest/services/volume/json/admin/volume_hosts_client.py
@@ -43,4 +43,5 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['hosts']
diff --git a/tempest/services/volume/json/admin/volume_quotas_client.py b/tempest/services/volume/json/admin/volume_quotas_client.py
index 7b3e5de..90790e3 100644
--- a/tempest/services/volume/json/admin/volume_quotas_client.py
+++ b/tempest/services/volume/json/admin/volume_quotas_client.py
@@ -42,6 +42,7 @@
 
         url = 'os-quota-sets/%s/defaults' % tenant_id
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def get_quota_set(self, tenant_id, params=None):
@@ -52,12 +53,14 @@
             url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def get_quota_usage(self, tenant_id):
         """List the quota set for a tenant."""
 
         resp, body = self.get_quota_set(tenant_id, params={'usage': True})
+        self.expected_success(200, resp.status)
         return resp, body
 
     def update_quota_set(self, tenant_id, gigabytes=None, volumes=None,
@@ -75,8 +78,10 @@
 
         post_body = jsonutils.dumps({'quota_set': post_body})
         resp, body = self.put('os-quota-sets/%s' % tenant_id, post_body)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def delete_quota_set(self, tenant_id):
         """Delete the tenant's quota set."""
-        return self.delete('os-quota-sets/%s' % tenant_id)
+        resp, body = self.delete('os-quota-sets/%s' % tenant_id)
+        self.expected_success(200, resp.status)
diff --git a/tempest/services/volume/json/admin/volume_services_client.py b/tempest/services/volume/json/admin/volume_services_client.py
index d43c04a..c9b8bcc 100644
--- a/tempest/services/volume/json/admin/volume_services_client.py
+++ b/tempest/services/volume/json/admin/volume_services_client.py
@@ -35,4 +35,5 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['services']
diff --git a/tempest/services/volume/json/admin/volume_types_client.py b/tempest/services/volume/json/admin/volume_types_client.py
index 65ecc67..44ef9fe 100644
--- a/tempest/services/volume/json/admin/volume_types_client.py
+++ b/tempest/services/volume/json/admin/volume_types_client.py
@@ -63,6 +63,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['volume_types']
 
     def get_volume_type(self, volume_id):
@@ -70,6 +71,7 @@
         url = "types/%s" % str(volume_id)
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['volume_type']
 
     def create_volume_type(self, name, **kwargs):
@@ -87,11 +89,13 @@
         post_body = json.dumps({'volume_type': post_body})
         resp, body = self.post('types', post_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['volume_type']
 
     def delete_volume_type(self, volume_id):
         """Deletes the Specified Volume_type."""
-        return self.delete("types/%s" % str(volume_id))
+        resp, body = self.delete("types/%s" % str(volume_id))
+        self.expected_success(202, resp.status)
 
     def list_volume_types_extra_specs(self, vol_type_id, params=None):
         """List all the volume_types extra specs created."""
@@ -101,6 +105,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['extra_specs']
 
     def get_volume_type_extra_specs(self, vol_type_id, extra_spec_name):
@@ -109,6 +114,7 @@
                                            str(extra_spec_name))
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body
 
     def create_volume_type_extra_specs(self, vol_type_id, extra_spec):
@@ -121,12 +127,14 @@
         post_body = json.dumps({'extra_specs': extra_spec})
         resp, body = self.post(url, post_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['extra_specs']
 
     def delete_volume_type_extra_specs(self, vol_id, extra_spec_name):
         """Deletes the Specified Volume_type extra spec."""
-        return self.delete("types/%s/extra_specs/%s" % ((str(vol_id)),
-                                                        str(extra_spec_name)))
+        resp, body = self.delete("types/%s/extra_specs/%s" % (
+            (str(vol_id)), str(extra_spec_name)))
+        self.expected_success(202, resp.status)
 
     def update_volume_type_extra_specs(self, vol_type_id, extra_spec_name,
                                        extra_spec):
@@ -142,6 +150,7 @@
         put_body = json.dumps(extra_spec)
         resp, body = self.put(url, put_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body
 
     def get_encryption_type(self, vol_type_id):
@@ -152,6 +161,7 @@
         url = "/types/%s/encryption" % str(vol_type_id)
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body
 
     def create_encryption_type(self, vol_type_id, **kwargs):
@@ -170,8 +180,11 @@
         post_body = json.dumps({'encryption': post_body})
         resp, body = self.post(url, post_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['encryption']
 
     def delete_encryption_type(self, vol_type_id):
         """Delete the encryption type for the specified volume-type."""
-        return self.delete("/types/%s/encryption/provider" % str(vol_type_id))
+        resp, body = self.delete(
+            "/types/%s/encryption/provider" % str(vol_type_id))
+        self.expected_success(202, resp.status)
diff --git a/tempest/services/volume/json/availability_zone_client.py b/tempest/services/volume/json/availability_zone_client.py
index f2e7c5c..5ad2287 100644
--- a/tempest/services/volume/json/availability_zone_client.py
+++ b/tempest/services/volume/json/availability_zone_client.py
@@ -31,6 +31,7 @@
     def get_availability_zone_list(self):
         resp, body = self.get('os-availability-zone')
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['availabilityZoneInfo']
 
 
diff --git a/tempest/services/volume/json/backups_client.py b/tempest/services/volume/json/backups_client.py
index 183d06b..63fc646 100644
--- a/tempest/services/volume/json/backups_client.py
+++ b/tempest/services/volume/json/backups_client.py
@@ -47,6 +47,7 @@
         post_body = json.dumps({'backup': post_body})
         resp, body = self.post('backups', post_body)
         body = json.loads(body)
+        self.expected_success(202, resp.status)
         return resp, body['backup']
 
     def restore_backup(self, backup_id, volume_id=None):
@@ -55,11 +56,13 @@
         post_body = json.dumps({'restore': post_body})
         resp, body = self.post('backups/%s/restore' % (backup_id), post_body)
         body = json.loads(body)
+        self.expected_success(202, resp.status)
         return resp, body['restore']
 
     def delete_backup(self, backup_id):
         """Delete a backup of volume."""
         resp, body = self.delete('backups/%s' % (str(backup_id)))
+        self.expected_success(202, resp.status)
         return resp, body
 
     def get_backup(self, backup_id):
@@ -67,6 +70,7 @@
         url = "backups/%s" % str(backup_id)
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['backup']
 
     def list_backups_with_detail(self):
@@ -74,6 +78,7 @@
         url = "backups/detail"
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['backups']
 
     def wait_for_backup_status(self, backup_id, status):
diff --git a/tempest/services/volume/json/extensions_client.py b/tempest/services/volume/json/extensions_client.py
index e3ff00b..c84b186 100644
--- a/tempest/services/volume/json/extensions_client.py
+++ b/tempest/services/volume/json/extensions_client.py
@@ -31,6 +31,7 @@
         url = 'extensions'
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['extensions']
 
 
diff --git a/tempest/services/volume/json/snapshots_client.py b/tempest/services/volume/json/snapshots_client.py
index 2dff63d..f50ba2f 100644
--- a/tempest/services/volume/json/snapshots_client.py
+++ b/tempest/services/volume/json/snapshots_client.py
@@ -42,6 +42,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['snapshots']
 
     def list_snapshots_with_detail(self, params=None):
@@ -52,6 +53,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['snapshots']
 
     def get_snapshot(self, snapshot_id):
@@ -59,6 +61,7 @@
         url = "snapshots/%s" % str(snapshot_id)
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['snapshot']
 
     def create_snapshot(self, volume_id, **kwargs):
@@ -74,6 +77,7 @@
         post_body = json.dumps({'snapshot': post_body})
         resp, body = self.post('snapshots', post_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['snapshot']
 
     def update_snapshot(self, snapshot_id, **kwargs):
@@ -81,6 +85,7 @@
         put_body = json.dumps({'snapshot': kwargs})
         resp, body = self.put('snapshots/%s' % snapshot_id, put_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['snapshot']
 
     # NOTE(afazekas): just for the wait function
@@ -122,7 +127,8 @@
 
     def delete_snapshot(self, snapshot_id):
         """Delete Snapshot."""
-        return self.delete("snapshots/%s" % str(snapshot_id))
+        resp, body = self.delete("snapshots/%s" % str(snapshot_id))
+        self.expected_success(202, resp.status)
 
     def is_resource_deleted(self, id):
         try:
@@ -135,6 +141,7 @@
         """Reset the specified snapshot's status."""
         post_body = json.dumps({'os-reset_status': {"status": status}})
         resp, body = self.post('snapshots/%s/action' % snapshot_id, post_body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def update_snapshot_status(self, snapshot_id, status, progress):
@@ -146,6 +153,7 @@
         post_body = json.dumps({'os-update_snapshot_status': post_body})
         url = 'snapshots/%s/action' % str(snapshot_id)
         resp, body = self.post(url, post_body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def create_snapshot_metadata(self, snapshot_id, metadata):
@@ -154,6 +162,7 @@
         url = "snapshots/%s/metadata" % str(snapshot_id)
         resp, body = self.post(url, put_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['metadata']
 
     def get_snapshot_metadata(self, snapshot_id):
@@ -161,6 +170,7 @@
         url = "snapshots/%s/metadata" % str(snapshot_id)
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['metadata']
 
     def update_snapshot_metadata(self, snapshot_id, metadata):
@@ -169,6 +179,7 @@
         url = "snapshots/%s/metadata" % str(snapshot_id)
         resp, body = self.put(url, put_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['metadata']
 
     def update_snapshot_metadata_item(self, snapshot_id, id, meta_item):
@@ -177,16 +188,18 @@
         url = "snapshots/%s/metadata/%s" % (str(snapshot_id), str(id))
         resp, body = self.put(url, put_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['meta']
 
     def delete_snapshot_metadata_item(self, snapshot_id, id):
         """Delete metadata item for the snapshot."""
         url = "snapshots/%s/metadata/%s" % (str(snapshot_id), str(id))
         resp, body = self.delete(url)
-        return resp, body
+        self.expected_success(200, resp.status)
 
     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.expected_success(202, resp.status)
         return resp, body
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index 6c97497..c3a9269 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -35,6 +35,7 @@
         self.service = CONF.volume.catalog_type
         self.build_interval = CONF.volume.build_interval
         self.build_timeout = CONF.volume.build_timeout
+        self.create_resp = 200
 
     def get_attachment_from_volume(self, volume):
         """Return the element 'attachment' from input volumes."""
@@ -48,6 +49,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['volumes']
 
     def list_volumes_with_detail(self, params=None):
@@ -58,6 +60,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['volumes']
 
     def get_volume(self, volume_id):
@@ -65,6 +68,7 @@
         url = "volumes/%s" % str(volume_id)
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['volume']
 
     def create_volume(self, size=None, **kwargs):
@@ -88,6 +92,7 @@
         post_body = json.dumps({'volume': post_body})
         resp, body = self.post('volumes', post_body)
         body = json.loads(body)
+        self.expected_success(self.create_resp, resp.status)
         return resp, body['volume']
 
     def update_volume(self, volume_id, **kwargs):
@@ -95,11 +100,13 @@
         put_body = json.dumps({'volume': kwargs})
         resp, body = self.put('volumes/%s' % volume_id, put_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['volume']
 
     def delete_volume(self, volume_id):
         """Deletes the Specified Volume."""
-        return self.delete("volumes/%s" % str(volume_id))
+        resp, body = self.delete("volumes/%s" % str(volume_id))
+        self.expected_success(202, resp.status)
 
     def upload_volume(self, volume_id, image_name, disk_format):
         """Uploads a volume in Glance."""
@@ -111,6 +118,7 @@
         url = 'volumes/%s/action' % (volume_id)
         resp, body = self.post(url, post_body)
         body = json.loads(body)
+        self.expected_success(202, resp.status)
         return resp, body['os-volume_upload_image']
 
     def attach_volume(self, volume_id, instance_uuid, mountpoint):
@@ -122,6 +130,7 @@
         post_body = json.dumps({'os-attach': post_body})
         url = 'volumes/%s/action' % (volume_id)
         resp, body = self.post(url, post_body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def detach_volume(self, volume_id):
@@ -130,6 +139,7 @@
         post_body = json.dumps({'os-detach': post_body})
         url = 'volumes/%s/action' % (volume_id)
         resp, body = self.post(url, post_body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def reserve_volume(self, volume_id):
@@ -138,6 +148,7 @@
         post_body = json.dumps({'os-reserve': post_body})
         url = 'volumes/%s/action' % (volume_id)
         resp, body = self.post(url, post_body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def unreserve_volume(self, volume_id):
@@ -146,6 +157,7 @@
         post_body = json.dumps({'os-unreserve': post_body})
         url = 'volumes/%s/action' % (volume_id)
         resp, body = self.post(url, post_body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def wait_for_volume_status(self, volume_id, status):
@@ -183,24 +195,30 @@
         post_body = json.dumps({'os-extend': post_body})
         url = 'volumes/%s/action' % (volume_id)
         resp, body = self.post(url, post_body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def reset_volume_status(self, volume_id, status):
         """Reset the Specified Volume's Status."""
         post_body = json.dumps({'os-reset_status': {"status": status}})
         resp, body = self.post('volumes/%s/action' % volume_id, post_body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def volume_begin_detaching(self, volume_id):
         """Volume Begin Detaching."""
+        # ref cinder/api/contrib/volume_actions.py#L158
         post_body = json.dumps({'os-begin_detaching': {}})
         resp, body = self.post('volumes/%s/action' % volume_id, post_body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def volume_roll_detaching(self, volume_id):
         """Volume Roll Detaching."""
+        # cinder/api/contrib/volume_actions.py#L170
         post_body = json.dumps({'os-roll_detaching': {}})
         resp, body = self.post('volumes/%s/action' % volume_id, post_body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def create_volume_transfer(self, vol_id, display_name=None):
@@ -213,6 +231,7 @@
         post_body = json.dumps({'transfer': post_body})
         resp, body = self.post('os-volume-transfer', post_body)
         body = json.loads(body)
+        self.expected_success(202, resp.status)
         return resp, body['transfer']
 
     def get_volume_transfer(self, transfer_id):
@@ -220,6 +239,7 @@
         url = "os-volume-transfer/%s" % str(transfer_id)
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['transfer']
 
     def list_volume_transfers(self, params=None):
@@ -229,11 +249,13 @@
             url += '?%s' % urllib.urlencode(params)
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['transfers']
 
     def delete_volume_transfer(self, transfer_id):
         """Delete a volume transfer."""
-        return self.delete("os-volume-transfer/%s" % str(transfer_id))
+        resp, body = self.delete("os-volume-transfer/%s" % str(transfer_id))
+        self.expected_success(202, resp.status)
 
     def accept_volume_transfer(self, transfer_id, transfer_auth_key):
         """Accept a volume transfer."""
@@ -244,6 +266,7 @@
         post_body = json.dumps({'accept': post_body})
         resp, body = self.post(url, post_body)
         body = json.loads(body)
+        self.expected_success(202, resp.status)
         return resp, body['transfer']
 
     def update_volume_readonly(self, volume_id, readonly):
@@ -254,12 +277,14 @@
         post_body = json.dumps({'os-update_readonly_flag': post_body})
         url = 'volumes/%s/action' % (volume_id)
         resp, body = self.post(url, post_body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def force_delete_volume(self, volume_id):
         """Force Delete Volume."""
         post_body = json.dumps({'os-force_delete': {}})
         resp, body = self.post('volumes/%s/action' % volume_id, post_body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def create_volume_metadata(self, volume_id, metadata):
@@ -268,6 +293,7 @@
         url = "volumes/%s/metadata" % str(volume_id)
         resp, body = self.post(url, put_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['metadata']
 
     def get_volume_metadata(self, volume_id):
@@ -275,6 +301,7 @@
         url = "volumes/%s/metadata" % str(volume_id)
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['metadata']
 
     def update_volume_metadata(self, volume_id, metadata):
@@ -283,6 +310,7 @@
         url = "volumes/%s/metadata" % str(volume_id)
         resp, body = self.put(url, put_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['metadata']
 
     def update_volume_metadata_item(self, volume_id, id, meta_item):
@@ -291,13 +319,14 @@
         url = "volumes/%s/metadata/%s" % (str(volume_id), str(id))
         resp, body = self.put(url, put_body)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['meta']
 
     def delete_volume_metadata_item(self, volume_id, id):
         """Delete metadata item for the volume."""
         url = "volumes/%s/metadata/%s" % (str(volume_id), str(id))
         resp, body = self.delete(url)
-        return resp, body
+        self.expected_success(200, resp.status)
 
 
 class VolumesClientJSON(BaseVolumesClientJSON):
diff --git a/tempest/services/volume/v2/json/volumes_client.py b/tempest/services/volume/v2/json/volumes_client.py
index 1f16ead..ac4342e 100644
--- a/tempest/services/volume/v2/json/volumes_client.py
+++ b/tempest/services/volume/v2/json/volumes_client.py
@@ -25,3 +25,4 @@
         super(VolumesV2ClientJSON, self).__init__(auth_provider)
 
         self.api_version = "v2"
+        self.create_resp = 202
diff --git a/tempest/services/volume/v2/xml/volumes_client.py b/tempest/services/volume/v2/xml/volumes_client.py
index c1bcf6e..b3133af 100644
--- a/tempest/services/volume/v2/xml/volumes_client.py
+++ b/tempest/services/volume/v2/xml/volumes_client.py
@@ -30,6 +30,7 @@
         super(VolumesV2ClientXML, self).__init__(auth_provider)
 
         self.api_version = "v2"
+        self.create_resp = 202
 
     def _parse_volume(self, body):
         vol = dict((attr, body.get(attr)) for attr in body.keys())
@@ -61,6 +62,7 @@
             volumes += [self._parse_volume(vol) for vol in list(body)]
         for v in volumes:
             v = self._check_if_bootable(v)
+        self.expected_success(200, resp.status)
         return resp, volumes
 
     def get_volume(self, volume_id):
@@ -69,4 +71,5 @@
         resp, body = self.get(url)
         body = self._parse_volume(etree.fromstring(body))
         body = self._check_if_bootable(body)
+        self.expected_success(200, resp.status)
         return resp, body
diff --git a/tempest/services/volume/xml/admin/volume_hosts_client.py b/tempest/services/volume/xml/admin/volume_hosts_client.py
index 967c7c2..98a7c58 100644
--- a/tempest/services/volume/xml/admin/volume_hosts_client.py
+++ b/tempest/services/volume/xml/admin/volume_hosts_client.py
@@ -69,5 +69,6 @@
             url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         body = self._parse_array(etree.fromstring(body))
         return resp, body
diff --git a/tempest/services/volume/xml/admin/volume_quotas_client.py b/tempest/services/volume/xml/admin/volume_quotas_client.py
index a8c92fc..acf9102 100644
--- a/tempest/services/volume/xml/admin/volume_quotas_client.py
+++ b/tempest/services/volume/xml/admin/volume_quotas_client.py
@@ -48,6 +48,7 @@
         """List the quota set for a tenant."""
 
         resp, body = self.get_quota_set(tenant_id, params={'usage': True})
+        self.expected_success(200, resp.status)
         return resp, self._format_quota(body)
 
     def update_quota_set(self, tenant_id, gigabytes=None, volumes=None,
@@ -68,8 +69,10 @@
         resp, body = self.put('os-quota-sets/%s' % tenant_id,
                               str(xml.Document(element)))
         body = xml.xml_to_json(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, self._format_quota(body)
 
     def delete_quota_set(self, tenant_id):
         """Delete the tenant's quota set."""
-        return self.delete('os-quota-sets/%s' % tenant_id)
+        resp, body = self.delete('os-quota-sets/%s' % tenant_id)
+        self.expected_success(200, resp.status)
diff --git a/tempest/services/volume/xml/admin/volume_services_client.py b/tempest/services/volume/xml/admin/volume_services_client.py
index 7bad16d..2ecb590 100644
--- a/tempest/services/volume/xml/admin/volume_services_client.py
+++ b/tempest/services/volume/xml/admin/volume_services_client.py
@@ -39,4 +39,5 @@
         resp, body = self.get(url)
         node = etree.fromstring(body)
         body = [xml_utils.xml_to_json(x) for x in node.getchildren()]
+        self.expected_success(200, resp.status)
         return resp, body
diff --git a/tempest/services/volume/xml/admin/volume_types_client.py b/tempest/services/volume/xml/admin/volume_types_client.py
index 90897ee..679d097 100644
--- a/tempest/services/volume/xml/admin/volume_types_client.py
+++ b/tempest/services/volume/xml/admin/volume_types_client.py
@@ -75,6 +75,7 @@
         if body is not None:
             volume_types += [self._parse_volume_type(vol)
                              for vol in list(body)]
+        self.expected_success(200, resp.status)
         return resp, volume_types
 
     def get_volume_type(self, type_id):
@@ -82,6 +83,7 @@
         url = "types/%s" % str(type_id)
         resp, body = self.get(url)
         body = etree.fromstring(body)
+        self.expected_success(200, resp.status)
         return resp, self._parse_volume_type(body)
 
     def create_volume_type(self, name, **kwargs):
@@ -107,11 +109,13 @@
 
         resp, body = self.post('types', str(common.Document(vol_type)))
         body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def delete_volume_type(self, type_id):
         """Deletes the Specified Volume_type."""
-        return self.delete("types/%s" % str(type_id))
+        resp, body = self.delete("types/%s" % str(type_id))
+        self.expected_success(202, resp.status)
 
     def list_volume_types_extra_specs(self, vol_type_id, params=None):
         """List all the volume_types extra specs created."""
@@ -126,6 +130,7 @@
         if body is not None:
             extra_specs += [self._parse_volume_type_extra_specs(spec)
                             for spec in list(body)]
+        self.expected_success(200, resp.status)
         return resp, extra_specs
 
     def get_volume_type_extra_specs(self, vol_type_id, extra_spec_name):
@@ -134,6 +139,7 @@
                                            str(extra_spec_name))
         resp, body = self.get(url)
         body = etree.fromstring(body)
+        self.expected_success(200, resp.status)
         return resp, self._parse_volume_type_extra_specs(body)
 
     def create_volume_type_extra_specs(self, vol_type_id, extra_spec):
@@ -158,12 +164,15 @@
 
         resp, body = self.post(url, str(common.Document(extra_specs)))
         body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def delete_volume_type_extra_specs(self, vol_id, extra_spec_name):
         """Deletes the Specified Volume_type extra spec."""
-        return self.delete("types/%s/extra_specs/%s" % ((str(vol_id)),
-                                                        str(extra_spec_name)))
+        resp, body = self.delete("types/%s/extra_specs/%s" % (
+            (str(vol_id)), str(extra_spec_name)))
+        self.expected_success(202, resp.status)
+        return resp, body
 
     def update_volume_type_extra_specs(self, vol_type_id, extra_spec_name,
                                        extra_spec):
@@ -187,6 +196,7 @@
 
         resp, body = self.put(url, str(common.Document(extra_specs)))
         body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def is_resource_deleted(self, id):
diff --git a/tempest/services/volume/xml/availability_zone_client.py b/tempest/services/volume/xml/availability_zone_client.py
index a883ef5..b956d3f 100644
--- a/tempest/services/volume/xml/availability_zone_client.py
+++ b/tempest/services/volume/xml/availability_zone_client.py
@@ -36,6 +36,7 @@
     def get_availability_zone_list(self):
         resp, body = self.get('os-availability-zone')
         availability_zone = self._parse_array(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, availability_zone
 
 
diff --git a/tempest/services/volume/xml/extensions_client.py b/tempest/services/volume/xml/extensions_client.py
index fe8b7cb..f2b2e02 100644
--- a/tempest/services/volume/xml/extensions_client.py
+++ b/tempest/services/volume/xml/extensions_client.py
@@ -39,6 +39,7 @@
         url = 'extensions'
         resp, body = self.get(url)
         body = self._parse_array(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
 
diff --git a/tempest/services/volume/xml/snapshots_client.py b/tempest/services/volume/xml/snapshots_client.py
index 4b1ba25..7636707 100644
--- a/tempest/services/volume/xml/snapshots_client.py
+++ b/tempest/services/volume/xml/snapshots_client.py
@@ -49,6 +49,7 @@
         snapshots = []
         for snap in body:
             snapshots.append(common.xml_to_json(snap))
+        self.expected_success(200, resp.status)
         return resp, snapshots
 
     def list_snapshots_with_detail(self, params=None):
@@ -63,6 +64,7 @@
         snapshots = []
         for snap in body:
             snapshots.append(common.xml_to_json(snap))
+        self.expected_success(200, resp.status)
         return resp, snapshots
 
     def get_snapshot(self, snapshot_id):
@@ -70,6 +72,7 @@
         url = "snapshots/%s" % str(snapshot_id)
         resp, body = self.get(url)
         body = etree.fromstring(body)
+        self.expected_success(200, resp.status)
         return resp, common.xml_to_json(body)
 
     def create_snapshot(self, volume_id, **kwargs):
@@ -87,6 +90,7 @@
         resp, body = self.post('snapshots',
                                str(common.Document(snapshot)))
         body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def update_snapshot(self, snapshot_id, **kwargs):
@@ -96,6 +100,7 @@
         resp, body = self.put('snapshots/%s' % snapshot_id,
                               str(common.Document(put_body)))
         body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     # NOTE(afazekas): just for the wait function
@@ -137,7 +142,8 @@
 
     def delete_snapshot(self, snapshot_id):
         """Delete Snapshot."""
-        return self.delete("snapshots/%s" % str(snapshot_id))
+        resp, body = self.delete("snapshots/%s" % str(snapshot_id))
+        self.expected_success(202, resp.status)
 
     def is_resource_deleted(self, id):
         try:
@@ -153,6 +159,7 @@
         resp, body = self.post(url, str(common.Document(post_body)))
         if body:
             body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, body
 
     def update_snapshot_status(self, snapshot_id, status, progress):
@@ -165,6 +172,7 @@
         resp, body = self.post(url, str(common.Document(post_body)))
         if body:
             body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, body
 
     def _metadata_body(self, meta):
@@ -188,6 +196,7 @@
         resp, body = self.post('snapshots/%s/metadata' % snapshot_id,
                                str(common.Document(post_body)))
         body = self._parse_key_value(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def get_snapshot_metadata(self, snapshot_id):
@@ -195,6 +204,7 @@
         url = "snapshots/%s/metadata" % str(snapshot_id)
         resp, body = self.get(url)
         body = self._parse_key_value(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def update_snapshot_metadata(self, snapshot_id, metadata):
@@ -203,6 +213,7 @@
         url = "snapshots/%s/metadata" % str(snapshot_id)
         resp, body = self.put(url, str(common.Document(put_body)))
         body = self._parse_key_value(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def update_snapshot_metadata_item(self, snapshot_id, id, meta_item):
@@ -213,12 +224,15 @@
         url = "snapshots/%s/metadata/%s" % (str(snapshot_id), str(id))
         resp, body = self.put(url, str(common.Document(put_body)))
         body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def delete_snapshot_metadata_item(self, snapshot_id, id):
         """Delete metadata item for the snapshot."""
         url = "snapshots/%s/metadata/%s" % (str(snapshot_id), str(id))
-        return self.delete(url)
+        resp, body = self.delete(url)
+        self.expected_success(200, resp.status)
+        return resp, body
 
     def force_delete_snapshot(self, snapshot_id):
         """Force Delete Snapshot."""
@@ -227,4 +241,5 @@
         resp, body = self.post(url, str(common.Document(post_body)))
         if body:
             body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, body
diff --git a/tempest/services/volume/xml/volumes_client.py b/tempest/services/volume/xml/volumes_client.py
index 89947fb..a8c1ae5 100644
--- a/tempest/services/volume/xml/volumes_client.py
+++ b/tempest/services/volume/xml/volumes_client.py
@@ -43,6 +43,7 @@
         self.service = CONF.volume.catalog_type
         self.build_interval = CONF.compute.build_interval
         self.build_timeout = CONF.compute.build_timeout
+        self.create_resp = 200
 
     def _translate_attributes_to_json(self, volume):
         volume_host_attr = '{' + VOLUME_HOST_NS + '}host'
@@ -114,6 +115,7 @@
         volumes = []
         if body is not None:
             volumes += [self._parse_volume(vol) for vol in list(body)]
+        self.expected_success(200, resp.status)
         return resp, volumes
 
     def list_volumes_with_detail(self, params=None):
@@ -128,6 +130,7 @@
         volumes = []
         if body is not None:
             volumes += [self._parse_volume(vol) for vol in list(body)]
+        self.expected_success(200, resp.status)
         return resp, volumes
 
     def get_volume(self, volume_id):
@@ -135,6 +138,7 @@
         url = "volumes/%s" % str(volume_id)
         resp, body = self.get(url)
         body = self._parse_volume(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def create_volume(self, size=None, **kwargs):
@@ -176,6 +180,7 @@
 
         resp, body = self.post('volumes', str(common.Document(volume)))
         body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(self.create_resp, resp.status)
         return resp, body
 
     def update_volume(self, volume_id, **kwargs):
@@ -185,11 +190,14 @@
         resp, body = self.put('volumes/%s' % volume_id,
                               str(common.Document(put_body)))
         body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def delete_volume(self, volume_id):
         """Deletes the Specified Volume."""
-        return self.delete("volumes/%s" % str(volume_id))
+        resp, body = self.delete("volumes/%s" % str(volume_id))
+        self.expected_success(202, resp.status)
+        return resp, body
 
     def wait_for_volume_status(self, volume_id, status):
         """Waits for a Volume to reach a given status."""
@@ -228,6 +236,7 @@
         resp, body = self.post(url, str(common.Document(post_body)))
         if body:
             body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, body
 
     def detach_volume(self, volume_id):
@@ -237,6 +246,7 @@
         resp, body = self.post(url, str(common.Document(post_body)))
         if body:
             body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, body
 
     def upload_volume(self, volume_id, image_name, disk_format):
@@ -247,6 +257,7 @@
         url = 'volumes/%s/action' % str(volume_id)
         resp, body = self.post(url, str(common.Document(post_body)))
         volume = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, volume
 
     def extend_volume(self, volume_id, extend_size):
@@ -257,6 +268,7 @@
         resp, body = self.post(url, str(common.Document(post_body)))
         if body:
             body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, body
 
     def reset_volume_status(self, volume_id, status):
@@ -268,6 +280,7 @@
         resp, body = self.post(url, str(common.Document(post_body)))
         if body:
             body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, body
 
     def volume_begin_detaching(self, volume_id):
@@ -295,6 +308,7 @@
         resp, body = self.post(url, str(common.Document(post_body)))
         if body:
             body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, body
 
     def unreserve_volume(self, volume_id):
@@ -304,6 +318,7 @@
         resp, body = self.post(url, str(common.Document(post_body)))
         if body:
             body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, body
 
     def create_volume_transfer(self, vol_id, display_name=None):
@@ -315,6 +330,7 @@
         resp, body = self.post('os-volume-transfer',
                                str(common.Document(post_body)))
         volume = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, volume
 
     def get_volume_transfer(self, transfer_id):
@@ -322,6 +338,7 @@
         url = "os-volume-transfer/%s" % str(transfer_id)
         resp, body = self.get(url)
         volume = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, volume
 
     def list_volume_transfers(self, params=None):
@@ -335,6 +352,7 @@
         volumes = []
         if body is not None:
             volumes += [self._parse_volume_transfer(vol) for vol in list(body)]
+        self.expected_success(200, resp.status)
         return resp, volumes
 
     def _parse_volume_transfer(self, body):
@@ -348,7 +366,9 @@
 
     def delete_volume_transfer(self, transfer_id):
         """Delete a volume transfer."""
-        return self.delete("os-volume-transfer/%s" % str(transfer_id))
+        resp, body = self.delete("os-volume-transfer/%s" % str(transfer_id))
+        self.expected_success(202, resp.status)
+        return resp, body
 
     def accept_volume_transfer(self, transfer_id, transfer_auth_key):
         """Accept a volume transfer."""
@@ -356,6 +376,7 @@
         url = 'os-volume-transfer/%s/accept' % transfer_id
         resp, body = self.post(url, str(common.Document(post_body)))
         volume = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, volume
 
     def update_volume_readonly(self, volume_id, readonly):
@@ -366,6 +387,7 @@
         resp, body = self.post(url, str(common.Document(post_body)))
         if body:
             body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, body
 
     def force_delete_volume(self, volume_id):
@@ -375,6 +397,7 @@
         resp, body = self.post(url, str(common.Document(post_body)))
         if body:
             body = common.xml_to_json(etree.fromstring(body))
+        self.expected_success(202, resp.status)
         return resp, body
 
     def _metadata_body(self, meta):
@@ -399,6 +422,7 @@
         resp, body = self.post('volumes/%s/metadata' % volume_id,
                                str(common.Document(post_body)))
         body = self._parse_key_value(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def get_volume_metadata(self, volume_id):
@@ -406,6 +430,7 @@
         url = "volumes/%s/metadata" % str(volume_id)
         resp, body = self.get(url)
         body = self._parse_key_value(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def update_volume_metadata(self, volume_id, metadata):
@@ -414,6 +439,7 @@
         url = "volumes/%s/metadata" % str(volume_id)
         resp, body = self.put(url, str(common.Document(put_body)))
         body = self._parse_key_value(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def update_volume_metadata_item(self, volume_id, id, meta_item):
@@ -423,13 +449,16 @@
             put_body.append(common.Text(v))
         url = "volumes/%s/metadata/%s" % (str(volume_id), str(id))
         resp, body = self.put(url, str(common.Document(put_body)))
+        self.expected_success(200, resp.status)
         body = common.xml_to_json(etree.fromstring(body))
         return resp, body
 
     def delete_volume_metadata_item(self, volume_id, id):
         """Delete metadata item for the volume."""
         url = "volumes/%s/metadata/%s" % (str(volume_id), str(id))
-        return self.delete(url)
+        resp, body = self.delete(url)
+        self.expected_success(200, resp.status)
+        return resp, body
 
 
 class VolumesClientXML(BaseVolumesClientXML):
diff --git a/tempest/test.py b/tempest/test.py
index 1e67d18..59da2f9 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -107,7 +107,7 @@
         'identity': True,
         'object_storage': CONF.service_available.swift,
         'dashboard': CONF.service_available.horizon,
-        'ceilometer': CONF.service_available.ceilometer,
+        'telemetry': CONF.service_available.ceilometer,
         'data_processing': CONF.service_available.sahara
     }
 
diff --git a/tempest/tests/common/test_custom_matchers.py b/tempest/tests/common/test_custom_matchers.py
new file mode 100644
index 0000000..57217e3
--- /dev/null
+++ b/tempest/tests/common/test_custom_matchers.py
@@ -0,0 +1,66 @@
+# Copyright 2014 Hewlett-Packard Development Company, L.P.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.common import custom_matchers
+from tempest.tests import base
+
+from testtools.tests.matchers import helpers
+
+
+class TestMatchesDictExceptForKeys(base.TestCase,
+                                   helpers.TestMatchersInterface):
+
+    matches_matcher = custom_matchers.MatchesDictExceptForKeys(
+        {'a': 1, 'b': 2, 'c': 3, 'd': 4}, ['c', 'd'])
+    matches_matches = [
+        {'a': 1, 'b': 2, 'c': 3, 'd': 4},
+        {'a': 1, 'b': 2, 'c': 5},
+        {'a': 1, 'b': 2},
+    ]
+    matches_mismatches = [
+        {},
+        {'foo': 1},
+        {'a': 1, 'b': 3},
+        {'a': 1, 'b': 2, 'foo': 1},
+        {'a': 1, 'b': None, 'foo': 1},
+    ]
+
+    str_examples = []
+    describe_examples = [
+        ("Only in expected:\n"
+         "  {'a': 1, 'b': 2}\n",
+         {},
+         matches_matcher),
+        ("Only in expected:\n"
+         "  {'a': 1, 'b': 2}\n"
+         "Only in actual:\n"
+         "  {'foo': 1}\n",
+         {'foo': 1},
+         matches_matcher),
+        ("Differences:\n"
+         "  b: expected 2, actual 3\n",
+         {'a': 1, 'b': 3},
+         matches_matcher),
+        ("Only in actual:\n"
+         "  {'foo': 1}\n",
+         {'a': 1, 'b': 2, 'foo': 1},
+         matches_matcher),
+        ("Only in actual:\n"
+         "  {'foo': 1}\n"
+         "Differences:\n"
+         "  b: expected 2, actual None\n",
+         {'a': 1, 'b': None, 'foo': 1},
+         matches_matcher)
+    ]
\ No newline at end of file
diff --git a/tox.ini b/tox.ini
index b3d4397..edcb901 100644
--- a/tox.ini
+++ b/tox.ini
@@ -111,7 +111,8 @@
 # H402 skipped because some docstrings aren't sentences
 # E123 skipped because it is ignored by default in the default pep8
 # E129 skipped because it is too limiting when combined with other rules
+# H305 skipped because it is inconsistent between python versions
 # Skipped because of new hacking 0.9: H405,H904
-ignore = E125,H402,E123,E129,H404,H405,H904
+ignore = E125,H402,E123,E129,H404,H405,H904,H305
 show-source = True
 exclude = .git,.venv,.tox,dist,doc,openstack,*egg