Merge "remove default=None for config options"
diff --git a/REVIEWING.rst b/REVIEWING.rst
new file mode 100644
index 0000000..d6dc83e
--- /dev/null
+++ b/REVIEWING.rst
@@ -0,0 +1,60 @@
+Reviewing Tempest Code
+======================
+
+To start read the `OpenStack Common Review Checklist
+<https://wiki.openstack.org/wiki/ReviewChecklist#Common_Review_Checklist>`_
+
+
+Ensuring code is executed
+-------------------------
+
+For any new or change to a test it has to be verified in the gate. This means
+that the first thing to check with any change is that a gate job actually runs
+it. Tests which aren't executed either because of configuration or skips should
+not be accepted.
+
+
+Unit Tests
+----------
+
+For any change that adds new functionality to either common functionality or an
+out-of-band tool unit tests are required. This is to ensure we don't introduce
+future regressions and to test conditions which we may not hit in the gate runs.
+Tests, and service clients aren't required to have unit tests since they should
+be self verifying by running them in the gate.
+
+
+API Stability
+-------------
+Tests should only be added for a published stable APIs. If a patch contains
+tests for an API which hasn't been marked as stable or for an API that which
+doesn't conform to the `API stability guidelines
+<https://wiki.openstack.org/wiki/Governance/Approved/APIStability>`_ then it
+should not be approved.
+
+
+Reject Copy and Paste Test Code
+------------------------
+When creating new tests that are similar to existing tests it is tempting to
+simply copy the code and make a few modifications. This increases code size and
+the maintenance burden. Such changes should not be approved if it is easy to
+abstract the duplicated code into a function or method.
+
+
+Being explicit
+--------------
+When tests are being added that depend on a configurable feature or extension,
+polling the API to discover that it is enabled should not be done. This will
+just result in bugs being masked because the test can be skipped automatically.
+Instead the config file should be used to determine whether a test should be
+skipped or not. Do not approve changes that depend on an API call to determine
+whether to skip or not.
+
+
+When to approve
+---------------
+ * Every patch needs two +2s before being approved.
+ * Its ok to hold off on an approval until a subject matter expert reviews it
+ * If a patch has already been approved but requires a trivial rebase to merge,
+   you do not have to wait for a second +2, since the patch has already had
+   two +2s.
diff --git a/doc/source/REVIEWING.rst b/doc/source/REVIEWING.rst
new file mode 120000
index 0000000..841e042
--- /dev/null
+++ b/doc/source/REVIEWING.rst
@@ -0,0 +1 @@
+../../REVIEWING.rst
\ No newline at end of file
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 25bc900..d3118ac 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -9,6 +9,7 @@
 
    overview
    HACKING
+   REVIEWING
 
 ------------
 Field Guides
diff --git a/etc/accounts.yaml.sample b/etc/accounts.yaml.sample
new file mode 100644
index 0000000..d191769
--- /dev/null
+++ b/etc/accounts.yaml.sample
@@ -0,0 +1,7 @@
+- username: 'user_1'
+  tenant_name: 'test_tenant_1'
+  password: 'test_password'
+
+- username: 'user_2'
+  tenant_name: 'test_tenant_2'
+  password: 'test_password'
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 8a7ad9c..ef56ab3 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -105,6 +105,17 @@
 #syslog_log_facility=LOG_USER
 
 
+[auth]
+
+#
+# Options defined in tempest.config
+#
+
+# Path to the yaml file that contains the list of credentials
+# to use for running tests (string value)
+#test_accounts_file=etc/accounts.yaml
+
+
 [baremetal]
 
 #
@@ -386,29 +397,42 @@
 # If false, skip all nova v3 tests. (boolean value)
 #api_v3=false
 
+# If false skip all v2 api tests with xml (boolean value)
+#xml_api_v2=true
+
 # If false, skip disk config tests (boolean value)
 #disk_config=true
 
 # A list of enabled compute extensions with a special entry
 # all which indicates every extension is enabled. Each
-# extension should be specified with alias name (list value)
+# extension should be specified with alias name. Empty list
+# indicates all extensions are disabled (list value)
 #api_extensions=all
 
 # A list of enabled v3 extensions with a special entry all
 # which indicates every extension is enabled. Each extension
-# should be specified with alias name (list value)
+# should be specified with alias name. Empty list indicates
+# all extensions are disabled (list value)
 #api_v3_extensions=all
 
 # Does the test environment support changing the admin
 # password? (boolean value)
 #change_password=false
 
+# Does the test environment support obtaining instance serial
+# console output? (boolean value)
+#console_output=true
+
 # Does the test environment support resizing? (boolean value)
 #resize=false
 
 # Does the test environment support pausing? (boolean value)
 #pause=true
 
+# Does the test environment support shelving/unshelving?
+# (boolean value)
+#shelve=true
+
 # Does the test environment support suspend/resume? (boolean
 # value)
 #suspend=true
@@ -441,6 +465,19 @@
 # (boolean value)
 #rescue=true
 
+# Enables returning of the instance password by the relevant
+# server API calls such as create, rebuild or rescue. (boolean
+# value)
+#enable_instance_password=true
+
+# Does the test environment support dynamic network interface
+# attachment? (boolean value)
+#interface_attach=true
+
+# Does the test environment support creating snapshot images
+# of running instances? (boolean value)
+#snapshot=true
+
 
 [dashboard]
 
@@ -750,7 +787,8 @@
 #ipv6=true
 
 # A list of enabled network extensions with a special entry
-# all which indicates every extension is enabled (list value)
+# all which indicates every extension is enabled. Empty list
+# indicates all extensions are disabled (list value)
 #api_extensions=all
 
 # Allow the execution of IPv6 subnet tests that use the
@@ -895,8 +933,15 @@
 # Directory containing image files (string value)
 #img_dir=/opt/stack/new/devstack/files/images/cirros-0.3.1-x86_64-uec
 
-# QCOW2 image file name (string value)
-#qcow2_img_file=cirros-0.3.1-x86_64-disk.img
+# Image file name (string value)
+# Deprecated group/name - [DEFAULT]/qcow2_img_file
+#img_file=cirros-0.3.1-x86_64-disk.img
+
+# Image disk format (string value)
+#img_disk_format=qcow2
+
+# Image container format (string value)
+#img_container_format=bare
 
 # AMI image file name (string value)
 #ami_img_file=cirros-0.3.1-x86_64-blank.img
@@ -965,9 +1010,9 @@
 # value)
 #trove=false
 
-# Whether or not Marconi is expected to be available (boolean
+# Whether or not Zaqar is expected to be available (boolean
 # value)
-#marconi=false
+#zaqar=false
 
 
 [stress]
@@ -1105,7 +1150,8 @@
 #snapshot=true
 
 # A list of enabled volume extensions with a special entry all
-# which indicates every extension is enabled (list value)
+# which indicates every extension is enabled. Empty list
+# indicates all extensions are disabled (list value)
 #api_extensions=all
 
 # Is the v1 volume API enabled (boolean value)
diff --git a/requirements.txt b/requirements.txt
index ab2903a..9a3b74d 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -7,11 +7,12 @@
 boto>=2.12.0,!=2.13.0
 paramiko>=1.13.0
 netaddr>=0.7.6
-python-glanceclient>=0.9.0
+python-ceilometerclient>=1.0.6
+python-glanceclient>=0.13.1
 python-keystoneclient>=0.9.0
 python-novaclient>=2.17.0
-python-neutronclient>=2.3.4,<3
-python-cinderclient>=1.0.6
+python-neutronclient>=2.3.5,<3
+python-cinderclient>=1.0.7
 python-heatclient>=0.2.9
 python-ironicclient
 python-saharaclient>=0.6.0
diff --git a/run_tempest.sh b/run_tempest.sh
index bdd1f69..5a9b742 100755
--- a/run_tempest.sh
+++ b/run_tempest.sh
@@ -58,7 +58,7 @@
     -l|--logging) logging=1;;
     -L|--logging-config) logging_config=$2; shift;;
     --) [ "yes" == "$first_uu" ] || testrargs="$testrargs $1"; first_uu=no  ;;
-    *) testrargs+="$testrargs $1";;
+    *) testrargs="$testrargs $1";;
   esac
   shift
 done
diff --git a/tempest/README.rst b/tempest/README.rst
index 18c7cf3..fb25151 100644
--- a/tempest/README.rst
+++ b/tempest/README.rst
@@ -23,9 +23,8 @@
 belongs in each directory, the rules and examples for good tests, are
 documented in a README.rst file in the directory.
 
-
-api
----
+:ref:`api_field_guide`
+----------------------
 
 API tests are validation tests for the OpenStack API. They should not
 use the existing python clients for OpenStack, but should instead use
@@ -39,8 +38,8 @@
 frameworks.
 
 
-cli
----
+:ref:`cli_field_guide`
+----------------------
 
 CLI tests use the openstack CLI to interact with the OpenStack
 cloud. CLI testing in unit tests is somewhat difficult because unlike
@@ -49,8 +48,8 @@
 prereqs having a running OpenStack cloud.
 
 
-scenario
---------
+:ref:`scenario_field_guide`
+---------------------------
 
 Scenario tests are complex "through path" tests for OpenStack
 functionality. They are typically a series of steps where complicated
@@ -59,18 +58,26 @@
 Scenario tests can and should use the OpenStack python clients.
 
 
-stress
-------
+:ref:`stress_field_guide`
+-------------------------
 
 Stress tests are designed to stress an OpenStack environment by running a high
 workload against it and seeing what breaks. The stress test framework runs
 several test jobs in parallel and can run any existing test in Tempest as a
 stress job.
 
-thirdparty
-----------
+:ref:`third_party_field_guide`
+-----------------------------
 
 Many openstack components include 3rdparty API support. It is
 completely legitimate for Tempest to include tests of 3rdparty APIs,
 but those should be kept separate from the normal OpenStack
 validation.
+
+:ref:`unit_tests_field_guide`
+-----------------------------
+
+Unit tests are the self checks for Tempest. They provide functional
+verification and regression checking for the internal components of tempest.
+They should be used to just verify that the individual pieces of tempest are
+working as expected.
diff --git a/tempest/api/README.rst b/tempest/api/README.rst
index 9eac19d..91e6ad6 100644
--- a/tempest/api/README.rst
+++ b/tempest/api/README.rst
@@ -1,3 +1,5 @@
+.. _api_field_guide:
+
 Tempest Field Guide to API tests
 ================================
 
diff --git a/tempest/api/baremetal/README.rst b/tempest/api/baremetal/README.rst
new file mode 100644
index 0000000..759c937
--- /dev/null
+++ b/tempest/api/baremetal/README.rst
@@ -0,0 +1,25 @@
+Tempest Field Guide to Baremetal API tests
+==========================================
+
+
+What are these tests?
+---------------------
+
+These tests stress the OpenStack baremetal provisioning API provided by
+Ironic.
+
+
+Why are these tests in tempest?
+------------------------------
+
+The purpose of these tests is to exercise the various APIs provided by Ironic
+for managing baremetal nodes.
+
+
+Scope of these tests
+--------------------
+
+The baremetal API test perform basic CRUD operations on the Ironic node
+inventory.  They do not actually perform hardware provisioning. It is important
+to note that all Ironic API actions are admin operations meant to be used
+either by cloud operators or other OpenStack services (i.e., Nova).
diff --git a/tempest/api_schema/compute/__init__.py b/tempest/api/baremetal/admin/__init__.py
similarity index 100%
copy from tempest/api_schema/compute/__init__.py
copy to tempest/api/baremetal/admin/__init__.py
diff --git a/tempest/api/baremetal/base.py b/tempest/api/baremetal/admin/base.py
similarity index 88%
rename from tempest/api/baremetal/base.py
rename to tempest/api/baremetal/admin/base.py
index 6f7e438..62edd10 100644
--- a/tempest/api/baremetal/base.py
+++ b/tempest/api/baremetal/admin/base.py
@@ -21,6 +21,14 @@
 CONF = config.CONF
 
 
+# NOTE(adam_g): The baremetal API tests exercise operations such as enroll
+# node, power on, power off, etc.  Testing against real drivers (ie, IPMI)
+# will require passing driver-specific data to Tempest (addresses,
+# credentials, etc).  Until then, only support testing against the fake driver,
+# which has no external dependencies.
+SUPPORTED_DRIVERS = ['fake']
+
+
 def creates(resource):
     """Decorator that adds resources to the appropriate cleanup list."""
 
@@ -48,6 +56,13 @@
             skip_msg = ('%s skipped as Ironic is not available' % cls.__name__)
             raise cls.skipException(skip_msg)
 
+        if CONF.baremetal.driver not in SUPPORTED_DRIVERS:
+            skip_msg = ('%s skipped as Ironic driver %s is not supported for '
+                        'testing.' %
+                        (cls.__name__, CONF.baremetal.driver))
+            raise cls.skipException(skip_msg)
+        cls.driver = CONF.baremetal.driver
+
         mgr = clients.AdminManager()
         cls.client = mgr.baremetal_client
         cls.power_timeout = CONF.baremetal.power_timeout
@@ -85,7 +100,7 @@
     @classmethod
     @creates('node')
     def create_node(cls, chassis_id, cpu_arch='x86', cpu_num=8, storage=1024,
-                    memory=4096, driver='fake'):
+                    memory=4096):
         """
         Wrapper utility for creating test baremetal nodes.
 
@@ -98,7 +113,7 @@
         """
         resp, body = cls.client.create_node(chassis_id, cpu_arch=cpu_arch,
                                             cpu_num=cpu_num, storage=storage,
-                                            memory=memory, driver=driver)
+                                            memory=memory, driver=cls.driver)
 
         return resp, body
 
diff --git a/tempest/api/baremetal/test_api_discovery.py b/tempest/api/baremetal/admin/test_api_discovery.py
similarity index 78%
rename from tempest/api/baremetal/test_api_discovery.py
rename to tempest/api/baremetal/admin/test_api_discovery.py
index bee10b9..09788f2 100644
--- a/tempest/api/baremetal/test_api_discovery.py
+++ b/tempest/api/baremetal/admin/test_api_discovery.py
@@ -10,7 +10,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
 from tempest import test
 
 
@@ -19,10 +19,8 @@
 
     @test.attr(type='smoke')
     def test_api_versions(self):
-        resp, descr = self.client.get_api_description()
-        self.assertEqual('200', resp['status'])
+        _, descr = self.client.get_api_description()
         expected_versions = ('v1',)
-
         versions = [version['id'] for version in descr['versions']]
 
         for v in expected_versions:
@@ -30,16 +28,13 @@
 
     @test.attr(type='smoke')
     def test_default_version(self):
-        resp, descr = self.client.get_api_description()
-        self.assertEqual('200', resp['status'])
+        _, descr = self.client.get_api_description()
         default_version = descr['default_version']
-
         self.assertEqual(default_version['id'], 'v1')
 
     @test.attr(type='smoke')
     def test_version_1_resources(self):
-        resp, descr = self.client.get_version_description(version='v1')
-        self.assertEqual('200', resp['status'])
+        _, descr = self.client.get_version_description(version='v1')
         expected_resources = ('nodes', 'chassis',
                               'ports', 'links', 'media_types')
 
diff --git a/tempest/api/baremetal/test_chassis.py b/tempest/api/baremetal/admin/test_chassis.py
similarity index 73%
rename from tempest/api/baremetal/test_chassis.py
rename to tempest/api/baremetal/admin/test_chassis.py
index 4ab86c2..254a969 100644
--- a/tempest/api/baremetal/test_chassis.py
+++ b/tempest/api/baremetal/admin/test_chassis.py
@@ -11,7 +11,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
 from tempest.common.utils import data_utils
 from tempest import exceptions as exc
 from tempest import test
@@ -35,8 +35,7 @@
     @test.attr(type='smoke')
     def test_create_chassis(self):
         descr = data_utils.rand_name('test-chassis-')
-        resp, chassis = self.create_chassis(description=descr)
-        self.assertEqual('201', resp['status'])
+        _, chassis = self.create_chassis(description=descr)
         self.assertEqual(chassis['description'], descr)
 
     @test.attr(type='smoke')
@@ -44,40 +43,35 @@
         # Use a unicode string for testing:
         # 'We ♡ OpenStack in Ukraine'
         descr = u'В Україні ♡ OpenStack!'
-        resp, chassis = self.create_chassis(description=descr)
-        self.assertEqual('201', resp['status'])
+        _, chassis = self.create_chassis(description=descr)
         self.assertEqual(chassis['description'], descr)
 
     @test.attr(type='smoke')
     def test_show_chassis(self):
-        resp, chassis = self.client.show_chassis(self.chassis['uuid'])
-        self.assertEqual('200', resp['status'])
+        _, chassis = self.client.show_chassis(self.chassis['uuid'])
         self._assertExpected(self.chassis, chassis)
 
     @test.attr(type="smoke")
     def test_list_chassis(self):
-        resp, body = self.client.list_chassis()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_chassis()
         self.assertIn(self.chassis['uuid'],
                       [i['uuid'] for i in body['chassis']])
 
     @test.attr(type='smoke')
     def test_delete_chassis(self):
-        resp, body = self.create_chassis()
+        _, body = self.create_chassis()
         uuid = body['uuid']
 
-        resp = self.delete_chassis(uuid)
-        self.assertEqual('204', resp['status'])
+        self.delete_chassis(uuid)
         self.assertRaises(exc.NotFound, self.client.show_chassis, uuid)
 
     @test.attr(type='smoke')
     def test_update_chassis(self):
-        resp, body = self.create_chassis()
+        _, body = self.create_chassis()
         uuid = body['uuid']
 
         new_description = data_utils.rand_name('new-description-')
-        resp, body = (self.client.update_chassis(uuid,
-                      description=new_description))
-        self.assertEqual('200', resp['status'])
-        resp, chassis = self.client.show_chassis(uuid)
+        _, body = (self.client.update_chassis(uuid,
+                   description=new_description))
+        _, chassis = self.client.show_chassis(uuid)
         self.assertEqual(chassis['description'], new_description)
diff --git a/tempest/api/baremetal/test_drivers.py b/tempest/api/baremetal/admin/test_drivers.py
similarity index 82%
rename from tempest/api/baremetal/test_drivers.py
rename to tempest/api/baremetal/admin/test_drivers.py
index 852b6ab..9e215dc 100644
--- a/tempest/api/baremetal/test_drivers.py
+++ b/tempest/api/baremetal/admin/test_drivers.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
 from tempest import config
 from tempest import test
 
@@ -29,13 +29,11 @@
 
     @test.attr(type="smoke")
     def test_list_drivers(self):
-        resp, drivers = self.client.list_drivers()
-        self.assertEqual('200', resp['status'])
+        _, drivers = self.client.list_drivers()
         self.assertIn(self.driver_name,
                       [d['name'] for d in drivers['drivers']])
 
     @test.attr(type="smoke")
     def test_show_driver(self):
-        resp, driver = self.client.show_driver(self.driver_name)
-        self.assertEqual('200', resp['status'])
+        _, driver = self.client.show_driver(self.driver_name)
         self.assertEqual(self.driver_name, driver['name'])
diff --git a/tempest/api/baremetal/test_nodes.py b/tempest/api/baremetal/admin/test_nodes.py
similarity index 64%
rename from tempest/api/baremetal/test_nodes.py
rename to tempest/api/baremetal/admin/test_nodes.py
index 1572840..ab6aed3 100644
--- a/tempest/api/baremetal/test_nodes.py
+++ b/tempest/api/baremetal/admin/test_nodes.py
@@ -12,7 +12,7 @@
 
 import six
 
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
 from tempest import exceptions as exc
 from tempest import test
 
@@ -40,30 +40,25 @@
                   'storage': '10240',
                   'memory': '1024'}
 
-        resp, body = self.create_node(self.chassis['uuid'], **params)
-        self.assertEqual('201', resp['status'])
+        _, body = self.create_node(self.chassis['uuid'], **params)
         self._assertExpected(params, body['properties'])
 
     @test.attr(type='smoke')
     def test_delete_node(self):
-        resp, node = self.create_node(self.chassis['uuid'])
-        self.assertEqual('201', resp['status'])
+        _, node = self.create_node(self.chassis['uuid'])
 
-        resp = self.delete_node(node['uuid'])
+        self.delete_node(node['uuid'])
 
-        self.assertEqual(resp['status'], '204')
         self.assertRaises(exc.NotFound, self.client.show_node, node['uuid'])
 
     @test.attr(type='smoke')
     def test_show_node(self):
-        resp, loaded_node = self.client.show_node(self.node['uuid'])
-        self.assertEqual('200', resp['status'])
+        _, loaded_node = self.client.show_node(self.node['uuid'])
         self._assertExpected(self.node, loaded_node)
 
     @test.attr(type='smoke')
     def test_list_nodes(self):
-        resp, body = self.client.list_nodes()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_nodes()
         self.assertIn(self.node['uuid'],
                       [i['uuid'] for i in body['nodes']])
 
@@ -74,24 +69,40 @@
                  'storage': '10',
                  'memory': '128'}
 
-        resp, node = self.create_node(self.chassis['uuid'], **props)
-        self.assertEqual('201', resp['status'])
+        _, node = self.create_node(self.chassis['uuid'], **props)
 
         new_p = {'cpu_arch': 'x86',
                  'cpu_num': '1',
                  'storage': '10000',
                  'memory': '12300'}
 
-        resp, body = self.client.update_node(node['uuid'], properties=new_p)
-        self.assertEqual('200', resp['status'])
-        resp, node = self.client.show_node(node['uuid'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_node(node['uuid'], properties=new_p)
+        _, node = self.client.show_node(node['uuid'])
         self._assertExpected(new_p, node['properties'])
 
     @test.attr(type='smoke')
     def test_validate_driver_interface(self):
-        resp, body = self.client.validate_driver_interface(self.node['uuid'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.validate_driver_interface(self.node['uuid'])
         core_interfaces = ['power', 'deploy']
         for interface in core_interfaces:
             self.assertIn(interface, body)
+
+    @test.attr(type='smoke')
+    def test_set_node_boot_device(self):
+        body = self.client.set_node_boot_device(self.node['uuid'], 'pxe')
+        # No content
+        self.assertEqual('', body)
+
+    @test.attr(type='smoke')
+    def test_get_node_boot_device(self):
+        body = self.client.get_node_boot_device(self.node['uuid'])
+        self.assertIn('boot_device', body)
+        self.assertIn('persistent', body)
+        self.assertTrue(isinstance(body['boot_device'], six.string_types))
+        self.assertTrue(isinstance(body['persistent'], bool))
+
+    @test.attr(type='smoke')
+    def test_get_node_supported_boot_devices(self):
+        body = self.client.get_node_supported_boot_devices(self.node['uuid'])
+        self.assertIn('supported_boot_devices', body)
+        self.assertTrue(isinstance(body['supported_boot_devices'], list))
diff --git a/tempest/api/baremetal/test_nodestates.py b/tempest/api/baremetal/admin/test_nodestates.py
similarity index 74%
rename from tempest/api/baremetal/test_nodestates.py
rename to tempest/api/baremetal/admin/test_nodestates.py
index 3044bc6..76f47f9 100644
--- a/tempest/api/baremetal/test_nodestates.py
+++ b/tempest/api/baremetal/admin/test_nodestates.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
 from tempest import exceptions
 from tempest.openstack.common import timeutils
 from tempest import test
@@ -24,8 +24,8 @@
     @classmethod
     def setUpClass(cls):
         super(TestNodeStates, cls).setUpClass()
-        resp, cls.chassis = cls.create_chassis()
-        resp, cls.node = cls.create_node(cls.chassis['uuid'])
+        _, cls.chassis = cls.create_chassis()
+        _, cls.node = cls.create_node(cls.chassis['uuid'])
 
     def _validate_power_state(self, node_uuid, power_state):
         # Validate that power state is set within timeout
@@ -34,8 +34,7 @@
         start = timeutils.utcnow()
         while timeutils.delta_seconds(
                 start, timeutils.utcnow()) < self.power_timeout:
-            resp, node = self.client.show_node(node_uuid)
-            self.assertEqual(200, resp.status)
+            _, node = self.client.show_node(node_uuid)
             if node['power_state'] == power_state:
                 return
         message = ('Failed to set power state within '
@@ -44,20 +43,16 @@
 
     @test.attr(type='smoke')
     def test_list_nodestates(self):
-        resp, nodestates = self.client.list_nodestates(self.node['uuid'])
-        self.assertEqual('200', resp['status'])
+        _, nodestates = self.client.list_nodestates(self.node['uuid'])
         for key in nodestates:
             self.assertEqual(nodestates[key], self.node[key])
 
     @test.attr(type='smoke')
     def test_set_node_power_state(self):
-        resp, node = self.create_node(self.chassis['uuid'])
-        self.assertEqual('201', resp['status'])
+        _, node = self.create_node(self.chassis['uuid'])
         states = ["power on", "rebooting", "power off"]
         for state in states:
             # Set power state
-            resp, _ = self.client.set_node_power_state(node['uuid'],
-                                                       state)
-            self.assertEqual('202', resp['status'])
+            self.client.set_node_power_state(node['uuid'], state)
             # Check power state after state is set
             self._validate_power_state(node['uuid'], state)
diff --git a/tempest/api/baremetal/test_ports.py b/tempest/api/baremetal/admin/test_ports.py
similarity index 67%
rename from tempest/api/baremetal/test_ports.py
rename to tempest/api/baremetal/admin/test_ports.py
index 4ac7e29..b3f9b7f 100644
--- a/tempest/api/baremetal/test_ports.py
+++ b/tempest/api/baremetal/admin/test_ports.py
@@ -10,7 +10,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
 from tempest.common.utils import data_utils
 from tempest import exceptions as exc
 from tempest import test
@@ -39,12 +39,10 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual(201, resp.status)
+        _, port = self.create_port(node_id=node_id, address=address)
 
-        resp, body = self.client.show_port(port['uuid'])
+        _, body = self.client.show_port(port['uuid'])
 
-        self.assertEqual(200, resp.status)
         self._assertExpected(port, body)
 
     @test.attr(type='smoke')
@@ -53,12 +51,10 @@
         address = data_utils.rand_mac_address()
         uuid = data_utils.rand_uuid()
 
-        resp, port = self.create_port(node_id=node_id,
-                                      address=address, uuid=uuid)
-        self.assertEqual(201, resp.status)
+        _, port = self.create_port(node_id=node_id,
+                                   address=address, uuid=uuid)
 
-        resp, body = self.client.show_port(uuid)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.show_port(uuid)
         self._assertExpected(port, body)
 
     @test.attr(type='smoke')
@@ -67,44 +63,37 @@
         address = data_utils.rand_mac_address()
         extra = {'key': 'value'}
 
-        resp, port = self.create_port(node_id=node_id, address=address,
-                                      extra=extra)
-        self.assertEqual(201, resp.status)
+        _, port = self.create_port(node_id=node_id, address=address,
+                                   extra=extra)
 
-        resp, body = self.client.show_port(port['uuid'])
-        self.assertEqual(200, resp.status)
+        _, body = self.client.show_port(port['uuid'])
         self._assertExpected(port, body)
 
     @test.attr(type='smoke')
     def test_delete_port(self):
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual(201, resp.status)
+        _, port = self.create_port(node_id=node_id, address=address)
 
-        resp = self.delete_port(port['uuid'])
+        self.delete_port(port['uuid'])
 
-        self.assertEqual(204, resp.status)
         self.assertRaises(exc.NotFound, self.client.show_port, port['uuid'])
 
     @test.attr(type='smoke')
     def test_show_port(self):
-        resp, port = self.client.show_port(self.port['uuid'])
-        self.assertEqual(200, resp.status)
+        _, port = self.client.show_port(self.port['uuid'])
         self._assertExpected(self.port, port)
 
     @test.attr(type='smoke')
     def test_show_port_with_links(self):
-        resp, port = self.client.show_port(self.port['uuid'])
-        self.assertEqual(200, resp.status)
+        _, port = self.client.show_port(self.port['uuid'])
         self.assertIn('links', port.keys())
         self.assertEqual(2, len(port['links']))
         self.assertIn(port['uuid'], port['links'][0]['href'])
 
     @test.attr(type='smoke')
     def test_list_ports(self):
-        resp, body = self.client.list_ports()
-        self.assertEqual(200, resp.status)
+        _, body = self.client.list_ports()
         self.assertIn(self.port['uuid'],
                       [i['uuid'] for i in body['ports']])
         # Verify self links.
@@ -114,8 +103,7 @@
 
     @test.attr(type='smoke')
     def test_list_with_limit(self):
-        resp, body = self.client.list_ports(limit=3)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.list_ports(limit=3)
 
         next_marker = body['ports'][-1]['uuid']
         self.assertIn(next_marker, body['next'])
@@ -128,8 +116,7 @@
                              address=data_utils.rand_mac_address())
             [1]['uuid'] for i in range(0, 5)]
 
-        resp, body = self.client.list_ports_detail()
-        self.assertEqual(200, resp.status)
+        _, body = self.client.list_ports_detail()
 
         ports_dict = dict((port['uuid'], port) for port in body['ports']
                           if port['uuid'] in uuids)
@@ -153,8 +140,7 @@
             self.create_port(node_id=node_id,
                              address=data_utils.rand_mac_address())
 
-        resp, body = self.client.list_ports_detail(address=address)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.list_ports_detail(address=address)
         self.assertEqual(1, len(body['ports']))
         self.assertEqual(address, body['ports'][0]['address'])
 
@@ -164,9 +150,8 @@
         address = data_utils.rand_mac_address()
         extra = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
 
-        resp, port = self.create_port(node_id=node_id, address=address,
-                                      extra=extra)
-        self.assertEqual(201, resp.status)
+        _, port = self.create_port(node_id=node_id, address=address,
+                                   extra=extra)
 
         new_address = data_utils.rand_mac_address()
         new_extra = {'key1': 'new-value1', 'key2': 'new-value2',
@@ -185,11 +170,9 @@
                   'op': 'replace',
                   'value': new_extra['key3']}]
 
-        resp, _ = self.client.update_port(port['uuid'], patch)
-        self.assertEqual(200, resp.status)
+        self.client.update_port(port['uuid'], patch)
 
-        resp, body = self.client.show_port(port['uuid'])
-        self.assertEqual(200, resp.status)
+        _, body = self.client.show_port(port['uuid'])
         self.assertEqual(new_address, body['address'])
         self.assertEqual(new_extra, body['extra'])
 
@@ -199,26 +182,21 @@
         address = data_utils.rand_mac_address()
         extra = {'key1': 'value1', 'key2': 'value2', 'key3': 'value3'}
 
-        resp, port = self.create_port(node_id=node_id, address=address,
-                                      extra=extra)
-        self.assertEqual(201, resp.status)
+        _, port = self.create_port(node_id=node_id, address=address,
+                                   extra=extra)
 
         # Removing one item from the collection
-        resp, _ = self.client.update_port(port['uuid'],
-                                          [{'path': '/extra/key2',
-                                           'op': 'remove'}])
-        self.assertEqual(200, resp.status)
+        self.client.update_port(port['uuid'],
+                                [{'path': '/extra/key2',
+                                 'op': 'remove'}])
         extra.pop('key2')
-        resp, body = self.client.show_port(port['uuid'])
-        self.assertEqual(200, resp.status)
+        _, body = self.client.show_port(port['uuid'])
         self.assertEqual(extra, body['extra'])
 
         # Removing the collection
-        resp, _ = self.client.update_port(port['uuid'], [{'path': '/extra',
-                                                         'op': 'remove'}])
-        self.assertEqual(200, resp.status)
-        resp, body = self.client.show_port(port['uuid'])
-        self.assertEqual(200, resp.status)
+        self.client.update_port(port['uuid'], [{'path': '/extra',
+                                               'op': 'remove'}])
+        _, body = self.client.show_port(port['uuid'])
         self.assertEqual({}, body['extra'])
 
         # Assert nothing else was changed
@@ -230,8 +208,7 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual(201, resp.status)
+        _, port = self.create_port(node_id=node_id, address=address)
 
         extra = {'key1': 'value1', 'key2': 'value2'}
 
@@ -242,11 +219,9 @@
                   'op': 'add',
                   'value': extra['key2']}]
 
-        resp, _ = self.client.update_port(port['uuid'], patch)
-        self.assertEqual(200, resp.status)
+        self.client.update_port(port['uuid'], patch)
 
-        resp, body = self.client.show_port(port['uuid'])
-        self.assertEqual(200, resp.status)
+        _, body = self.client.show_port(port['uuid'])
         self.assertEqual(extra, body['extra'])
 
     @test.attr(type='smoke')
@@ -255,9 +230,8 @@
         address = data_utils.rand_mac_address()
         extra = {'key1': 'value1', 'key2': 'value2'}
 
-        resp, port = self.create_port(node_id=node_id, address=address,
-                                      extra=extra)
-        self.assertEqual(201, resp.status)
+        _, port = self.create_port(node_id=node_id, address=address,
+                                   extra=extra)
 
         new_address = data_utils.rand_mac_address()
         new_extra = {'key1': 'new-value1', 'key3': 'new-value3'}
@@ -274,10 +248,8 @@
                   'op': 'add',
                   'value': new_extra['key3']}]
 
-        resp, _ = self.client.update_port(port['uuid'], patch)
-        self.assertEqual(200, resp.status)
+        self.client.update_port(port['uuid'], patch)
 
-        resp, body = self.client.show_port(port['uuid'])
-        self.assertEqual(200, resp.status)
+        _, body = self.client.show_port(port['uuid'])
         self.assertEqual(new_address, body['address'])
         self.assertEqual(new_extra, body['extra'])
diff --git a/tempest/api/baremetal/test_ports_negative.py b/tempest/api/baremetal/admin/test_ports_negative.py
similarity index 83%
rename from tempest/api/baremetal/test_ports_negative.py
rename to tempest/api/baremetal/admin/test_ports_negative.py
index 3e77a5f..ead3799 100644
--- a/tempest/api/baremetal/test_ports_negative.py
+++ b/tempest/api/baremetal/admin/test_ports_negative.py
@@ -10,7 +10,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api.baremetal import base
+from tempest.api.baremetal.admin import base
 from tempest.common.utils import data_utils
 from tempest import exceptions as exc
 from tempest import test
@@ -22,11 +22,8 @@
     def setUp(self):
         super(TestPortsNegative, self).setUp()
 
-        resp, self.chassis = self.create_chassis()
-        self.assertEqual('201', resp['status'])
-
-        resp, self.node = self.create_node(self.chassis['uuid'])
-        self.assertEqual('201', resp['status'])
+        _, self.chassis = self.create_chassis()
+        _, self.node = self.create_node(self.chassis['uuid'])
 
     @test.attr(type=['negative', 'smoke'])
     def test_create_port_malformed_mac(self):
@@ -137,13 +134,11 @@
         address = data_utils.rand_mac_address()
         extra = {'key': 'value'}
 
-        resp, port = self.create_port(node_id=node_id, address=address,
-                                      extra=extra)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address,
+                                   extra=extra)
         port_id = port['uuid']
 
-        resp, body = self.client.delete_port(port_id)
-        self.assertEqual('204', resp['status'])
+        _, body = self.client.delete_port(port_id)
 
         patch = [{'path': '/extra/key',
                   'op': 'replace',
@@ -169,8 +164,7 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
         self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
@@ -182,8 +176,7 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
         self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
@@ -196,8 +189,7 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
         self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
@@ -209,8 +201,7 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
         patch = [{'path': '/node_uuid',
@@ -225,11 +216,9 @@
         address1 = data_utils.rand_mac_address()
         address2 = data_utils.rand_mac_address()
 
-        resp, port1 = self.create_port(node_id=node_id, address=address1)
-        self.assertEqual('201', resp['status'])
+        _, port1 = self.create_port(node_id=node_id, address=address1)
 
-        resp, port2 = self.create_port(node_id=node_id, address=address2)
-        self.assertEqual('201', resp['status'])
+        _, port2 = self.create_port(node_id=node_id, address=address2)
         port_id = port2['uuid']
 
         patch = [{'path': '/address',
@@ -243,8 +232,7 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
         patch = [{'path': '/node_uuid',
@@ -258,8 +246,7 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
         patch = [{'path': '/address',
@@ -275,9 +262,8 @@
         address = data_utils.rand_mac_address()
         extra = {'key': 'value'}
 
-        resp, port = self.create_port(node_id=node_id, address=address,
-                                      extra=extra)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address,
+                                   extra=extra)
         port_id = port['uuid']
 
         patch = [{'path': '/extra/key',
@@ -291,8 +277,7 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
         patch = [{'path': '/extra',
@@ -307,8 +292,7 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
         patch = [{'path': '/nonexistent', ' op': 'replace', 'value': 'value'}]
@@ -321,8 +305,7 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
         self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
@@ -333,8 +316,7 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
         self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
@@ -345,8 +327,7 @@
         node_id = self.node['uuid']
         address = data_utils.rand_mac_address()
 
-        resp, port = self.create_port(node_id=node_id, address=address)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address)
         port_id = port['uuid']
 
         self.assertRaises(exc.BadRequest, self.client.update_port, port_id,
@@ -366,9 +347,8 @@
         address = data_utils.rand_mac_address()
         extra = {'key1': 'value1', 'key2': 'value2'}
 
-        resp, port = self.create_port(node_id=node_id, address=address,
-                                      extra=extra)
-        self.assertEqual('201', resp['status'])
+        _, port = self.create_port(node_id=node_id, address=address,
+                                   extra=extra)
         port_id = port['uuid']
 
         new_address = data_utils.rand_mac_address()
@@ -393,7 +373,6 @@
                           patch)
 
         # patch should not be applied
-        resp, body = self.client.show_port(port_id)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.show_port(port_id)
         self.assertEqual(address, body['address'])
         self.assertEqual(extra, body['extra'])
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index c2376c9..3485943 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -145,7 +145,7 @@
         self.assertEqual(200, resp.status)
         self.assertIn((aggregate_id, new_aggregate_name, new_az_name),
                       map(lambda x:
-                         (x['id'], x['name'], x['availability_zone']),
+                          (x['id'], x['name'], x['availability_zone']),
                           aggregates))
 
     @test.attr(type='gate')
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_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index 48f9ffb..85b26a1 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -86,8 +86,27 @@
         # Verify that GET shows the specified hypervisor uptime
         hypers = self._list_hypervisors()
 
-        has_valid_uptime = False
+        # Ironic will register each baremetal node as a 'hypervisor',
+        # so the hypervisor list can contain many hypervisors of type
+        # 'ironic'. If they are ALL ironic, skip this test since ironic
+        # doesn't support hypervisor uptime. Otherwise, remove them
+        # from the list of hypervisors to test.
+        ironic_only = True
+        hypers_without_ironic = []
         for hyper in hypers:
+            resp, details = (self.client.
+                             get_hypervisor_show_details(hypers[0]['id']))
+            self.assertEqual(200, resp.status)
+            if details['hypervisor_type'] != 'ironic':
+                hypers_without_ironic.append(hyper)
+                ironic_only = False
+
+        if ironic_only:
+            raise self.skipException(
+                "Ironic does not support hypervisor uptime")
+
+        has_valid_uptime = False
+        for hyper in hypers_without_ironic:
             # because hypervisors might be disabled, this loops looking
             # for any good hit.
             try:
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 f147b9c..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
 
@@ -111,13 +112,16 @@
                         security_groups=default_sg_quota)
 
         # Check we cannot create anymore
-        self.assertRaises(exceptions.OverLimit,
+        # A 403 Forbidden or 413 Overlimit (old behaviour) exception
+        # will be raised when out of quota
+        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
                           self.sg_client.create_security_group,
                           "sg-overlimit", "sg-desc")
 
     @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
@@ -147,7 +151,9 @@
         ip_protocol = 'tcp'
 
         # Check we cannot create SG rule anymore
-        self.assertRaises(exceptions.OverLimit,
+        # A 403 Forbidden or 413 Overlimit (old behaviour) exception
+        # will be raised when out of quota
+        self.assertRaises((exceptions.OverLimit, exceptions.Unauthorized),
                           self.sg_client.create_security_group_rule,
                           secgroup_id, ip_protocol, 1025, 1025)
 
diff --git a/tempest/api/compute/admin/test_security_group_default_rules.py b/tempest/api/compute/admin/test_security_group_default_rules.py
new file mode 100644
index 0000000..a07d270
--- /dev/null
+++ b/tempest/api/compute/admin/test_security_group_default_rules.py
@@ -0,0 +1,127 @@
+# Copyright 2014 NEC Corporation.  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 testtools
+
+from tempest.api.compute import base
+from tempest import config
+from tempest import exceptions
+from tempest import test
+
+CONF = config.CONF
+
+
+class SecurityGroupDefaultRulesTest(base.BaseV2ComputeAdminTest):
+
+    @classmethod
+    # TODO(GMann): Once Bug# 1311500 is fixed, these test can run
+    # for Neutron also.
+    @testtools.skipIf(CONF.service_available.neutron,
+                      "Skip as this functionality is not yet "
+                      "implemented in Neutron. Related Bug#1311500")
+    @test.safe_setup
+    def setUpClass(cls):
+        # A network and a subnet will be created for these tests
+        cls.set_network_resources(network=True, subnet=True)
+        super(SecurityGroupDefaultRulesTest, cls).setUpClass()
+        cls.adm_client = cls.os_adm.security_group_default_rules_client
+
+    def _create_security_group_default_rules(self, ip_protocol='tcp',
+                                             from_port=22, to_port=22,
+                                             cidr='10.10.0.0/24'):
+        # Create Security Group default rule
+        _, rule = self.adm_client.create_security_default_group_rule(
+            ip_protocol,
+            from_port,
+            to_port,
+            cidr=cidr)
+        self.assertEqual(ip_protocol, rule['ip_protocol'])
+        self.assertEqual(from_port, rule['from_port'])
+        self.assertEqual(to_port, rule['to_port'])
+        self.assertEqual(cidr, rule['ip_range']['cidr'])
+        return rule
+
+    @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']
+        for ip_protocol in ip_protocols:
+            rule = self._create_security_group_default_rules(ip_protocol)
+            # Delete Security Group default rule
+            self.adm_client.delete_security_group_default_rule(rule['id'])
+            self.assertRaises(exceptions.NotFound,
+                              self.adm_client.get_security_group_default_rule,
+                              rule['id'])
+
+    @test.attr(type='smoke')
+    def test_create_security_group_default_rule_without_cidr(self):
+        ip_protocol = 'udp'
+        from_port = 80
+        to_port = 80
+        _, rule = self.adm_client.create_security_default_group_rule(
+            ip_protocol,
+            from_port,
+            to_port)
+        self.addCleanup(self.adm_client.delete_security_group_default_rule,
+                        rule['id'])
+        self.assertNotEqual(0, rule['id'])
+        self.assertEqual('0.0.0.0/0', rule['ip_range']['cidr'])
+
+    @test.attr(type='smoke')
+    def test_create_security_group_default_rule_with_blank_cidr(self):
+        ip_protocol = 'icmp'
+        from_port = 10
+        to_port = 10
+        cidr = ''
+        _, rule = self.adm_client.create_security_default_group_rule(
+            ip_protocol,
+            from_port,
+            to_port,
+            cidr=cidr)
+        self.addCleanup(self.adm_client.delete_security_group_default_rule,
+                        rule['id'])
+        self.assertNotEqual(0, rule['id'])
+        self.assertEqual('0.0.0.0/0', rule['ip_range']['cidr'])
+
+    @test.attr(type='smoke')
+    def test_security_group_default_rules_list(self):
+        ip_protocol = 'tcp'
+        from_port = 22
+        to_port = 22
+        cidr = '10.10.0.0/24'
+        rule = self._create_security_group_default_rules(ip_protocol,
+                                                         from_port,
+                                                         to_port,
+                                                         cidr)
+        self.addCleanup(self.adm_client.delete_security_group_default_rule,
+                        rule['id'])
+        _, rules = self.adm_client.list_security_group_default_rules()
+        self.assertNotEqual(0, len(rules))
+        self.assertIn(rule, rules)
+
+    @test.attr(type='smoke')
+    def test_default_security_group_default_rule_show(self):
+        ip_protocol = 'tcp'
+        from_port = 22
+        to_port = 22
+        cidr = '10.10.0.0/24'
+        rule = self._create_security_group_default_rules(ip_protocol,
+                                                         from_port,
+                                                         to_port,
+                                                         cidr)
+        self.addCleanup(self.adm_client.delete_security_group_default_rule,
+                        rule['id'])
+        _, fetched_rule = self.adm_client.get_security_group_default_rule(
+            rule['id'])
+        self.assertEqual(rule, fetched_rule)
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index cccaf13..f4d010e 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -127,6 +127,8 @@
                           self.client.migrate_server,
                           str(uuid.uuid4()))
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.resize,
+                          'Resize not available.')
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
     @test.attr(type=['negative', 'gate'])
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 70a9604..343a39a 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -37,6 +37,9 @@
     def setUpClass(cls):
         cls.set_network_resources()
         super(BaseComputeTest, cls).setUpClass()
+        if getattr(cls, '_interface', None) == 'xml' and cls._api_version == 2:
+            if not CONF.compute_feature_enabled.xml_api_v2:
+                raise cls.skipException('XML API is not enabled')
 
         # TODO(andreaf) WE should care also for the alt_manager here
         # but only once client lazy load in the manager is done
@@ -83,6 +86,8 @@
             cls.hypervisor_client = cls.os.hypervisor_client
             cls.certificates_client = cls.os.certificates_client
             cls.migrations_client = cls.os.migrations_client
+            cls.security_group_default_rules_client = (
+                cls.os.security_group_default_rules_client)
 
         elif cls._api_version == 3:
             if not CONF.compute_feature_enabled.api_v3:
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_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 91eb4c5..9036726 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import StringIO
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
@@ -31,25 +33,21 @@
             skip_msg = ("%s skipped as glance is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
 
+        cls.glance_client = cls.os.image_client
         cls.client = cls.images_client
         cls.image_id = None
 
-        resp, server = cls.create_test_server(wait_until='ACTIVE')
-        cls.server_id = server['id']
-
-        # Snapshot the server once to save time
         name = data_utils.rand_name('image')
-        resp, _ = cls.client.create_image(cls.server_id, name, {})
-        cls.image_id = resp['location'].rsplit('/', 1)[1]
-
+        resp, body = cls.glance_client.create_image(name=name,
+                                                    container_format='bare',
+                                                    disk_format='raw',
+                                                    is_public=False)
+        cls.image_id = body['id']
+        cls.images.append(cls.image_id)
+        image_file = StringIO.StringIO(('*' * 1024))
+        cls.glance_client.update_image(cls.image_id, data=image_file)
         cls.client.wait_for_image_status(cls.image_id, 'ACTIVE')
 
-    @classmethod
-    def tearDownClass(cls):
-        if cls.image_id:
-            cls.client.delete_image(cls.image_id)
-        super(ImagesMetadataTestJSON, cls).tearDownClass()
-
     def setUp(self):
         super(ImagesMetadataTestJSON, self).setUp()
         meta = {'key1': 'value1', 'key2': 'value2'}
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 86ee4a4..68794b1 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -13,7 +13,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import StringIO
+import time
+
+import testtools
+
 from tempest.api.compute import base
+from tempest.common.utils import data_utils
 from tempest import config
 from tempest.openstack.common import log as logging
 from tempest import test
@@ -32,7 +38,37 @@
             skip_msg = ("%s skipped as glance is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
         cls.client = cls.images_client
+        cls.glance_client = cls.os.image_client
 
+        def _create_image():
+            name = data_utils.rand_name('image')
+            _, body = cls.glance_client.create_image(name=name,
+                                                     container_format='bare',
+                                                     disk_format='raw',
+                                                     is_public=False)
+            image_id = body['id']
+            cls.images.append(image_id)
+            # Wait 1 second between creation and upload to ensure a delta
+            # between created_at and updated_at.
+            time.sleep(1)
+            image_file = StringIO.StringIO(('*' * 1024))
+            cls.glance_client.update_image(image_id, data=image_file)
+            cls.client.wait_for_image_status(image_id, 'ACTIVE')
+            _, body = cls.client.get_image(image_id)
+            return body
+
+        # Create non-snapshot images via glance
+        cls.image1 = _create_image()
+        cls.image1_id = cls.image1['id']
+        cls.image2 = _create_image()
+        cls.image2_id = cls.image2['id']
+        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()
             resp, cls.server2 = cls.create_test_server(wait_until='ACTIVE')
@@ -41,21 +77,21 @@
                                                       'ACTIVE')
 
             # Create images to be used in the filter tests
-            resp, cls.image1 = cls.create_image_from_server(
+            resp, cls.snapshot1 = cls.create_image_from_server(
                 cls.server1['id'], wait_until='ACTIVE')
-            cls.image1_id = cls.image1['id']
+            cls.snapshot1_id = cls.snapshot1['id']
 
             # Servers have a hidden property for when they are being imaged
             # Performing back-to-back create image calls on a single
             # server will sometimes cause failures
-            resp, cls.image3 = cls.create_image_from_server(
+            resp, cls.snapshot3 = cls.create_image_from_server(
                 cls.server2['id'], wait_until='ACTIVE')
-            cls.image3_id = cls.image3['id']
+            cls.snapshot3_id = cls.snapshot3['id']
 
             # Wait for the server to be active after the image upload
-            resp, cls.image2 = cls.create_image_from_server(
+            resp, cls.snapshot2 = cls.create_image_from_server(
                 cls.server1['id'], wait_until='ACTIVE')
-            cls.image2_id = cls.image2['id']
+            cls.snapshot2_id = cls.snapshot2['id']
         except Exception:
             LOG.exception('setUpClass failed')
             cls.tearDownClass()
@@ -83,18 +119,25 @@
         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
         params = {'server': self.server1['id']}
         resp, images = self.client.list_images(params)
 
-        self.assertTrue(any([i for i in images if i['id'] == self.image1_id]),
+        self.assertTrue(any([i for i in images
+                             if i['id'] == self.snapshot1_id]),
                         "Failed to find image %s in images. Got images %s" %
                         (self.image1_id, images))
-        self.assertTrue(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]))
+        self.assertTrue(any([i for i in images
+                             if i['id'] == self.snapshot2_id]))
+        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
@@ -106,22 +149,28 @@
             resp, images = self.client.list_images(params)
 
             self.assertFalse(any([i for i in images
-                                  if i['id'] == self.image1_id]))
+                                  if i['id'] == self.snapshot1_id]))
             self.assertFalse(any([i for i in images
-                                  if i['id'] == self.image2_id]))
+                                  if i['id'] == self.snapshot2_id]))
             self.assertTrue(any([i for i in images
-                                 if i['id'] == self.image3_id]))
+                                 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
         params = {'type': 'snapshot'}
         resp, images = self.client.list_images(params)
 
-        self.assertTrue(any([i for i in images if i['id'] == self.image1_id]))
-        self.assertTrue(any([i for i in images if i['id'] == self.image2_id]))
-        self.assertTrue(any([i for i in images if i['id'] == self.image3_id]))
-        self.assertFalse(any([i for i in images if i['id'] == self.image_ref]))
+        self.assertTrue(any([i for i in images
+                             if i['id'] == self.snapshot1_id]))
+        self.assertTrue(any([i for i in images
+                             if i['id'] == self.snapshot2_id]))
+        self.assertTrue(any([i for i in images
+                             if i['id'] == self.snapshot3_id]))
+        self.assertFalse(any([i for i in images
+                              if i['id'] == self.image_ref]))
 
     @test.attr(type='gate')
     def test_list_images_limit_results(self):
@@ -173,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
@@ -184,12 +235,14 @@
             resp, images = self.client.list_images_with_detail(params)
 
             self.assertFalse(any([i for i in images
-                                  if i['id'] == self.image1_id]))
+                                  if i['id'] == self.snapshot1_id]))
             self.assertFalse(any([i for i in images
-                                  if i['id'] == self.image2_id]))
+                                  if i['id'] == self.snapshot2_id]))
             self.assertTrue(any([i for i in images
-                                 if i['id'] == self.image3_id]))
+                                 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
@@ -197,10 +250,14 @@
         resp, images = self.client.list_images_with_detail(params)
         resp, image4 = self.client.get_image(self.image_ref)
 
-        self.assertTrue(any([i for i in images if i['id'] == self.image1_id]))
-        self.assertTrue(any([i for i in images if i['id'] == self.image2_id]))
-        self.assertTrue(any([i for i in images if i['id'] == self.image3_id]))
-        self.assertFalse(any([i for i in images if i['id'] == self.image_ref]))
+        self.assertTrue(any([i for i in images
+                             if i['id'] == self.snapshot1_id]))
+        self.assertTrue(any([i for i in images
+                             if i['id'] == self.snapshot2_id]))
+        self.assertTrue(any([i for i in images
+                             if i['id'] == self.snapshot3_id]))
+        self.assertFalse(any([i for i in images
+                              if i['id'] == self.image_ref]))
 
     @test.attr(type='gate')
     def test_list_images_with_detail_filter_by_changes_since(self):
diff --git a/tempest/api/compute/limits/test_absolute_limits_negative.py b/tempest/api/compute/limits/test_absolute_limits_negative.py
index f88699b..b2e2981 100644
--- a/tempest/api/compute/limits/test_absolute_limits_negative.py
+++ b/tempest/api/compute/limits/test_absolute_limits_negative.py
@@ -39,7 +39,9 @@
         for xx in range(max_meta_data):
             meta_data[str(xx)] = str(xx)
 
-        self.assertRaises(exceptions.OverLimit,
+        # A 403 Forbidden or 413 Overlimit (old behaviour) exception
+        # will be raised when out of quota
+        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
                           self.server_client.create_server,
                           name='test', meta=meta_data,
                           flavor_ref=self.flavor_ref,
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 067d721..d1192c0 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -29,6 +29,8 @@
     def setUpClass(cls):
         if not CONF.service_available.neutron:
             raise cls.skipException("Neutron is required")
+        if not CONF.compute_feature_enabled.interface_attach:
+            raise cls.skipException("Interface attachment is not available.")
         # This test class requires network and subnet
         cls.set_network_resources(network=True, subnet=True)
         super(AttachInterfacesTestJSON, cls).setUpClass()
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index 9e34922..9c8271f 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -70,6 +70,8 @@
         self.assertEqual('204', resp['status'])
         self.client.wait_for_server_termination(server['id'])
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+                          'Shelve is not available.')
     @test.attr(type='gate')
     def test_delete_server_while_in_shelved_state(self):
         # Delete a server while it's VM state is Shelved
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index f66020c..9d39c9f 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -203,11 +203,13 @@
         params = {'status': 'active'}
         resp, body = self.client.list_servers_with_detail(params)
         servers = body['servers']
+        test_ids = [s['id'] for s in (self.s1, self.s2, self.s3)]
 
         self.assertIn(self.s1['id'], map(lambda x: x['id'], servers))
         self.assertIn(self.s2['id'], map(lambda x: x['id'], servers))
         self.assertIn(self.s3['id'], map(lambda x: x['id'], servers))
-        self.assertEqual(['ACTIVE'] * 3, [x['status'] for x in servers])
+        self.assertEqual(['ACTIVE'] * 3, [x['status'] for x in servers
+                                          if x['id'] in test_ids])
 
     @test.attr(type='gate')
     def test_list_servers_filtered_by_name_wildcard(self):
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 71fcbff..fd6df3e 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -15,9 +15,9 @@
 
 import base64
 import logging
+import urlparse
 
 import testtools
-import urlparse
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
@@ -256,7 +256,10 @@
         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')
+    @test.services('image')
     def test_create_backup(self):
         # Positive test:create backup successfully and rotate backups correctly
         # create the first and the second backup
@@ -348,6 +351,8 @@
         lines = len(output.split('\n'))
         self.assertEqual(lines, 10)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
+                          'Console output not supported.')
     @test.attr(type='gate')
     def test_get_console_output(self):
         # Positive test:Should be able to GET the console output
@@ -364,6 +369,8 @@
 
         self.wait_for(self._get_output)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
+                          'Console output not supported.')
     @test.attr(type='gate')
     def test_get_console_output_server_id_in_shutoff_status(self):
         # Positive test:Should be able to GET the console output
@@ -403,6 +410,8 @@
         self.assertEqual(202, resp.status)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+                          'Shelve is not available.')
     @test.attr(type='gate')
     def test_shelve_unshelve_server(self):
         resp, server = self.client.shelve_server(self.server_id)
diff --git a/tempest/api/compute/servers/test_server_metadata_negative.py b/tempest/api/compute/servers/test_server_metadata_negative.py
index b55833c..fbda401 100644
--- a/tempest/api/compute/servers/test_server_metadata_negative.py
+++ b/tempest/api/compute/servers/test_server_metadata_negative.py
@@ -119,20 +119,22 @@
 
     @test.attr(type=['negative', 'gate'])
     def test_metadata_items_limit(self):
-        # Raise a 413 OverLimit exception while exceeding metadata items limit
-        # for tenant.
+        # A 403 Forbidden or 413 Overlimit (old behaviour) exception
+        # will be raised while exceeding metadata items limit for
+        # tenant.
         _, quota_set = self.quotas.get_quota_set(self.tenant_id)
         quota_metadata = quota_set['metadata_items']
         req_metadata = {}
         for num in range(1, quota_metadata + 2):
             req_metadata['key' + str(num)] = 'val' + str(num)
-        self.assertRaises(exceptions.OverLimit,
+        self.assertRaises((exceptions.OverLimit, exceptions.Unauthorized),
                           self.client.set_server_metadata,
                           self.server_id, req_metadata)
 
-        # Raise a 413 OverLimit exception while exceeding metadata items limit
-        # for tenant (update).
-        self.assertRaises(exceptions.OverLimit,
+        # A 403 Forbidden or 413 Overlimit (old behaviour) exception
+        # will be raised while exceeding metadata items limit for
+        # tenant.
+        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
                           self.client.update_server_metadata,
                           self.server_id, req_metadata)
 
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index b7e4e38..6cc463d 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -40,8 +40,10 @@
             path = 'etc/test' + str(i) + '.txt'
             personality.append({'path': path,
                                 'contents': base64.b64encode(file_contents)})
-        self.assertRaises(exceptions.OverLimit, self.create_test_server,
-                          personality=personality)
+        # A 403 Forbidden or 413 Overlimit (old behaviour) exception
+        # will be raised when out of quota
+        self.assertRaises((exceptions.Unauthorized, exceptions.OverLimit),
+                          self.create_test_server, personality=personality)
 
     @test.attr(type='gate')
     def test_can_create_server_with_max_number_personality_files(self):
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index ab98d88..b737888 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -54,7 +54,6 @@
 
         # Server for positive tests
         resp, server = cls.create_test_server(wait_until='BUILD')
-        resp, resc_server = cls.create_test_server(wait_until='ACTIVE')
         cls.server_id = server['id']
         cls.password = server['adminPass']
         cls.servers_client.wait_for_server_status(cls.server_id, 'ACTIVE')
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index b35e55c..4582a46 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -34,7 +34,7 @@
 
         cls.set_network_resources(network=True, subnet=True, router=True)
         super(ServerRescueNegativeTestJSON, cls).setUpClass()
-        cls.device = 'vdf'
+        cls.device = CONF.compute.volume_device_name
 
         # Create a volume and wait for it to become ready for attach
         resp, cls.volume = cls.volumes_extensions_client.create_volume(
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index d3297ce..792b523 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -425,6 +425,8 @@
                           self.client.restore_soft_deleted_server,
                           self.server_id)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+                          'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_shelve_non_existent_server(self):
         # shelve a non existent server
@@ -432,6 +434,8 @@
         self.assertRaises(exceptions.NotFound, self.client.shelve_server,
                           nonexistent_server)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+                          'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_shelve_shelved_server(self):
         # shelve a shelved server.
@@ -460,6 +464,8 @@
 
         self.client.unshelve_server(self.server_id)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+                          'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_unshelve_non_existent_server(self):
         # unshelve a non existent server
@@ -467,6 +473,8 @@
         self.assertRaises(exceptions.NotFound, self.client.unshelve_server,
                           nonexistent_server)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+                          'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_unshelve_server_invalid_state(self):
         # unshelve an active server.
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/test_authorization.py b/tempest/api/compute/test_authorization.py
index fb8ded3..3fa4a89 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -62,9 +62,9 @@
 
         name = data_utils.rand_name('image')
         resp, body = cls.glance_client.create_image(name=name,
-                                                   container_format='bare',
-                                                   disk_format='raw',
-                                                   is_public=False)
+                                                    container_format='bare',
+                                                    disk_format='raw',
+                                                    is_public=False)
         image_id = body['id']
         image_file = StringIO.StringIO(('*' * 1024))
         resp, body = cls.glance_client.update_image(image_id, data=image_file)
diff --git a/tempest/api/compute/v3/admin/test_aggregates.py b/tempest/api/compute/v3/admin/test_aggregates.py
index e5ec08b..886b6a7 100644
--- a/tempest/api/compute/v3/admin/test_aggregates.py
+++ b/tempest/api/compute/v3/admin/test_aggregates.py
@@ -135,7 +135,7 @@
         self.assertEqual(200, resp.status)
         self.assertIn((aggregate_id, new_aggregate_name, new_az_name),
                       map(lambda x:
-                         (x['id'], x['name'], x['availability_zone']),
+                          (x['id'], x['name'], x['availability_zone']),
                           aggregates))
 
     @test.attr(type='gate')
diff --git a/tempest/api/compute/v3/admin/test_flavors_access.py b/tempest/api/compute/v3/admin/test_flavors_access.py
index c641bf6..09b6ebd 100644
--- a/tempest/api/compute/v3/admin/test_flavors_access.py
+++ b/tempest/api/compute/v3/admin/test_flavors_access.py
@@ -38,7 +38,6 @@
         cls.vcpus = 1
         cls.disk = 10
 
-    @test.skip_because(bug='1265416')
     @test.attr(type='gate')
     def test_flavor_access_list_with_private_flavor(self):
         # Test to list flavor access successfully by querying private flavor
@@ -58,7 +57,6 @@
         self.assertEqual(str(new_flavor_id), str(first_flavor['flavor_id']))
         self.assertEqual(self.adm_tenant_id, first_flavor['tenant_id'])
 
-    @test.skip_because(bug='1265416')
     @test.attr(type='gate')
     def test_flavor_access_add_remove(self):
         # Test to add and remove flavor access to a given tenant.
diff --git a/tempest/api/compute/v3/admin/test_flavors_access_negative.py b/tempest/api/compute/v3/admin/test_flavors_access_negative.py
index 02ecb24..0fdfabd 100644
--- a/tempest/api/compute/v3/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/v3/admin/test_flavors_access_negative.py
@@ -55,7 +55,6 @@
                           self.client.list_flavor_access,
                           new_flavor_id)
 
-    @test.skip_because(bug='1265416')
     @test.attr(type=['negative', 'gate'])
     def test_flavor_non_admin_add(self):
         # Test to add flavor access as a user without admin privileges.
@@ -72,7 +71,6 @@
                           new_flavor['id'],
                           self.tenant_id)
 
-    @test.skip_because(bug='1265416')
     @test.attr(type=['negative', 'gate'])
     def test_flavor_non_admin_remove(self):
         # Test to remove flavor access as a user without admin privileges.
@@ -93,7 +91,6 @@
                           new_flavor['id'],
                           self.tenant_id)
 
-    @test.skip_because(bug='1265416')
     @test.attr(type=['negative', 'gate'])
     def test_add_flavor_access_duplicate(self):
         # Create a new flavor.
@@ -118,7 +115,6 @@
                           new_flavor['id'],
                           self.tenant_id)
 
-    @test.skip_because(bug='1265416')
     @test.attr(type=['negative', 'gate'])
     def test_remove_flavor_access_not_found(self):
         # Create a new flavor.
diff --git a/tempest/api/compute/v3/admin/test_hypervisor.py b/tempest/api/compute/v3/admin/test_hypervisor.py
index f3397a8..9a23789 100644
--- a/tempest/api/compute/v3/admin/test_hypervisor.py
+++ b/tempest/api/compute/v3/admin/test_hypervisor.py
@@ -83,7 +83,27 @@
         # Verify that GET shows the specified hypervisor uptime
         hypers = self._list_hypervisors()
 
-        resp, uptime = self.client.get_hypervisor_uptime(hypers[0]['id'])
+        # Ironic will register each baremetal node as a 'hypervisor',
+        # so the hypervisor list can contain many hypervisors of type
+        # 'ironic'. If they are ALL ironic, skip this test since ironic
+        # doesn't support hypervisor uptime. Otherwise, remove them
+        # from the list of hypervisors to test.
+        ironic_only = True
+        hypers_without_ironic = []
+        for hyper in hypers:
+            resp, details = (self.client.
+                             get_hypervisor_show_details(hypers[0]['id']))
+            self.assertEqual(200, resp.status)
+            if details['hypervisor_type'] != 'ironic':
+                hypers_without_ironic.append(hyper)
+                ironic_only = False
+
+        if ironic_only:
+            raise self.skipException(
+                "Ironic does not support hypervisor uptime")
+
+        resp, uptime = self.client.get_hypervisor_uptime(
+            hypers_without_ironic[0]['id'])
         self.assertEqual(200, resp.status)
         self.assertTrue(len(uptime) > 0)
 
diff --git a/tempest/api/compute/v3/admin/test_servers.py b/tempest/api/compute/v3/admin/test_servers.py
index 366cfc6..d99c329 100644
--- a/tempest/api/compute/v3/admin/test_servers.py
+++ b/tempest/api/compute/v3/admin/test_servers.py
@@ -51,7 +51,6 @@
         self.assertEqual('200', resp['status'])
         self.assertEqual([], servers)
 
-    @test.skip_because(bug='1265416')
     @test.attr(type='gate')
     def test_list_servers_by_admin_with_all_tenants(self):
         # Listing servers by admin user with all tenants parameter
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_attach_interfaces.py b/tempest/api/compute/v3/servers/test_attach_interfaces.py
index 43440c1..c2cf7e0 100644
--- a/tempest/api/compute/v3/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/v3/servers/test_attach_interfaces.py
@@ -29,6 +29,8 @@
     def setUpClass(cls):
         if not CONF.service_available.neutron:
             raise cls.skipException("Neutron is required")
+        if not CONF.compute_feature_enabled.interface_attach:
+            raise cls.skipException("Interface attachment is not available.")
         # This test class requires network and subnet
         cls.set_network_resources(network=True, subnet=True)
         super(AttachInterfacesV3Test, cls).setUpClass()
diff --git a/tempest/api/compute/v3/servers/test_delete_server.py b/tempest/api/compute/v3/servers/test_delete_server.py
index add69ab..e2b47ee 100644
--- a/tempest/api/compute/v3/servers/test_delete_server.py
+++ b/tempest/api/compute/v3/servers/test_delete_server.py
@@ -68,6 +68,8 @@
         self.assertEqual('204', resp['status'])
         self.client.wait_for_server_termination(server['id'])
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+                          'Shelve is not available.')
     @test.attr(type='gate')
     def test_delete_server_while_in_shelved_state(self):
         # Delete a server while it's VM state is Shelved
diff --git a/tempest/api/compute/v3/servers/test_server_actions.py b/tempest/api/compute/v3/servers/test_server_actions.py
index 3ee8050..538507f 100644
--- a/tempest/api/compute/v3/servers/test_server_actions.py
+++ b/tempest/api/compute/v3/servers/test_server_actions.py
@@ -14,9 +14,9 @@
 #    under the License.
 
 import logging
+import urlparse
 
 import testtools
-import urlparse
 
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
@@ -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
@@ -339,6 +341,8 @@
         lines = len(output.split('\n'))
         self.assertEqual(lines, 10)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
+                          'Console output not supported.')
     @test.attr(type='gate')
     def test_get_console_output(self):
         # Positive test:Should be able to GET the console output
@@ -355,6 +359,8 @@
 
         self.wait_for(self._get_output)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
+                          'Console output not supported.')
     @test.attr(type='gate')
     def test_get_console_output_server_id_in_shutoff_status(self):
         # Positive test:Should be able to GET the console output
@@ -394,6 +400,8 @@
         self.assertEqual(202, resp.status)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+                          'Shelve is not available.')
     @test.attr(type='gate')
     def test_shelve_unshelve_server(self):
         resp, server = self.client.shelve_server(self.server_id)
diff --git a/tempest/api/compute/v3/servers/test_server_rescue_negative.py b/tempest/api/compute/v3/servers/test_server_rescue_negative.py
index 5eb6c9a..6d192a3 100644
--- a/tempest/api/compute/v3/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/v3/servers/test_server_rescue_negative.py
@@ -33,7 +33,7 @@
             raise cls.skipException(msg)
 
         super(ServerRescueNegativeV3Test, cls).setUpClass()
-        cls.device = 'vdf'
+        cls.device = CONF.compute.volume_device_name
 
         # Create a volume and wait for it to become ready for attach
         resp, cls.volume = cls.volumes_client.create_volume(
@@ -56,7 +56,8 @@
 
     @classmethod
     def tearDownClass(cls):
-        cls.delete_volume(cls.volume['id'])
+        if hasattr(cls, 'volume'):
+            cls.delete_volume(cls.volume['id'])
         super(ServerRescueNegativeV3Test, cls).tearDownClass()
 
     def _detach(self, server_id, volume_id):
diff --git a/tempest/api/compute/v3/servers/test_servers_negative.py b/tempest/api/compute/v3/servers/test_servers_negative.py
index 90deaa9..f8ff7c8 100644
--- a/tempest/api/compute/v3/servers/test_servers_negative.py
+++ b/tempest/api/compute/v3/servers/test_servers_negative.py
@@ -397,6 +397,8 @@
                           self.client.restore_soft_deleted_server,
                           self.server_id)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+                          'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_shelve_non_existent_server(self):
         # shelve a non existent server
@@ -404,6 +406,8 @@
         self.assertRaises(exceptions.NotFound, self.client.shelve_server,
                           nonexistent_server)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+                          'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_shelve_shelved_server(self):
         # shelve a shelved server.
@@ -431,6 +435,8 @@
 
         self.client.unshelve_server(self.server_id)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+                          'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_unshelve_non_existent_server(self):
         # unshelve a non existent server
@@ -438,6 +444,8 @@
         self.assertRaises(exceptions.NotFound, self.client.unshelve_server,
                           nonexistent_server)
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
+                          'Shelve is not available.')
     @test.attr(type=['negative', 'gate'])
     def test_unshelve_server_invalid_state(self):
         # unshelve an active server.
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index c3d6ba6..708524c 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -13,11 +13,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from testtools import matchers
+
 from tempest.api.compute import base
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import test
-from testtools import matchers
+
 
 CONF = config.CONF
 
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
index ab0e83a..65085b9 100644
--- a/tempest/api/data_processing/base.py
+++ b/tempest/api/data_processing/base.py
@@ -40,6 +40,7 @@
         cls._data_sources = []
         cls._job_binary_internals = []
         cls._job_binaries = []
+        cls._jobs = []
 
     @classmethod
     def tearDownClass(cls):
@@ -47,12 +48,13 @@
                               cls.client.delete_cluster_template)
         cls.cleanup_resources(getattr(cls, '_node_group_templates', []),
                               cls.client.delete_node_group_template)
-        cls.cleanup_resources(getattr(cls, '_data_sources', []),
-                              cls.client.delete_data_source)
-        cls.cleanup_resources(getattr(cls, '_job_binary_internals', []),
-                              cls.client.delete_job_binary_internal)
+        cls.cleanup_resources(getattr(cls, '_jobs', []), cls.client.delete_job)
         cls.cleanup_resources(getattr(cls, '_job_binaries', []),
                               cls.client.delete_job_binary)
+        cls.cleanup_resources(getattr(cls, '_job_binary_internals', []),
+                              cls.client.delete_job_binary_internal)
+        cls.cleanup_resources(getattr(cls, '_data_sources', []),
+                              cls.client.delete_data_source)
         cls.clear_isolated_creds()
         super(BaseDataProcessingTest, cls).tearDownClass()
 
@@ -75,16 +77,16 @@
         object. All resources created in this method will be automatically
         removed in tearDownClass method.
         """
-        resp, body = cls.client.create_node_group_template(name, plugin_name,
-                                                           hadoop_version,
-                                                           node_processes,
-                                                           flavor_id,
-                                                           node_configs,
-                                                           **kwargs)
+        _, resp_body = cls.client.create_node_group_template(name, plugin_name,
+                                                             hadoop_version,
+                                                             node_processes,
+                                                             flavor_id,
+                                                             node_configs,
+                                                             **kwargs)
         # store id of created node group template
-        cls._node_group_templates.append(body['id'])
+        cls._node_group_templates.append(resp_body['id'])
 
-        return resp, body
+        return resp_body
 
     @classmethod
     def create_cluster_template(cls, name, plugin_name, hadoop_version,
@@ -95,15 +97,15 @@
         object. All resources created in this method will be automatically
         removed in tearDownClass method.
         """
-        resp, body = cls.client.create_cluster_template(name, plugin_name,
-                                                        hadoop_version,
-                                                        node_groups,
-                                                        cluster_configs,
-                                                        **kwargs)
+        _, resp_body = cls.client.create_cluster_template(name, plugin_name,
+                                                          hadoop_version,
+                                                          node_groups,
+                                                          cluster_configs,
+                                                          **kwargs)
         # store id of created cluster template
-        cls._cluster_templates.append(body['id'])
+        cls._cluster_templates.append(resp_body['id'])
 
-        return resp, body
+        return resp_body
 
     @classmethod
     def create_data_source(cls, name, type, url, **kwargs):
@@ -113,11 +115,11 @@
         object. All resources created in this method will be automatically
         removed in tearDownClass method.
         """
-        resp, body = cls.client.create_data_source(name, type, url, **kwargs)
+        _, resp_body = cls.client.create_data_source(name, type, url, **kwargs)
         # store id of created data source
-        cls._data_sources.append(body['id'])
+        cls._data_sources.append(resp_body['id'])
 
-        return resp, body
+        return resp_body
 
     @classmethod
     def create_job_binary_internal(cls, name, data):
@@ -126,12 +128,13 @@
         It returns created object. All resources created in this method will
         be automatically removed in tearDownClass method.
         """
-        resp, body = cls.client.create_job_binary_internal(name, data)
+        _, resp_body = cls.client.create_job_binary_internal(name, data)
         # store id of created job binary internal
-        cls._job_binary_internals.append(body['id'])
+        cls._job_binary_internals.append(resp_body['id'])
 
-        return resp, body
+        return resp_body
 
+    @classmethod
     def create_job_binary(cls, name, url, extra=None, **kwargs):
         """Creates watched job binary with specified params.
 
@@ -139,8 +142,23 @@
         object. All resources created in this method will be automatically
         removed in tearDownClass method.
         """
-        resp, body = cls.client.create_job_binary(name, url, extra, **kwargs)
+        _, resp_body = cls.client.create_job_binary(name, url, extra, **kwargs)
         # store id of created job binary
-        cls._job_binaries.append(body['id'])
+        cls._job_binaries.append(resp_body['id'])
 
-        return resp, body
+        return resp_body
+
+    @classmethod
+    def create_job(cls, name, job_type, mains, libs=None, **kwargs):
+        """Creates watched job with specified params.
+
+        It supports passing additional params using kwargs and returns created
+        object. All resources created in this method will be automatically
+        removed in tearDownClass method.
+        """
+        _, resp_body = cls.client.create_job(name,
+                                             job_type, mains, libs, **kwargs)
+        # store id of created job
+        cls._jobs.append(resp_body['id'])
+
+        return resp_body
diff --git a/tempest/api/data_processing/test_cluster_templates.py b/tempest/api/data_processing/test_cluster_templates.py
index ad9ed2a..ff67c1c 100644
--- a/tempest/api/data_processing/test_cluster_templates.py
+++ b/tempest/api/data_processing/test_cluster_templates.py
@@ -39,7 +39,7 @@
                 }
             }
         }
-        resp_body = cls.create_node_group_template(**node_group_template)[1]
+        resp_body = cls.create_node_group_template(**node_group_template)
         node_group_template_id = resp_body['id']
 
         cls.full_cluster_template = {
@@ -95,23 +95,22 @@
     def _create_cluster_template(self, template_name=None):
         """Creates Cluster Template with optional name specified.
 
-        It creates template and ensures response status, template name and
-        response body. Returns id and name of created template.
+        It creates template, ensures template name and response body.
+        Returns id and name of created template.
         """
         if not template_name:
             # generate random name if it's not specified
             template_name = data_utils.rand_name('sahara-cluster-template')
 
         # create cluster template
-        resp, body = self.create_cluster_template(template_name,
-                                                  **self.full_cluster_template)
+        resp_body = self.create_cluster_template(template_name,
+                                                 **self.full_cluster_template)
 
         # ensure that template created successfully
-        self.assertEqual(202, resp.status)
-        self.assertEqual(template_name, body['name'])
-        self.assertDictContainsSubset(self.cluster_template, body)
+        self.assertEqual(template_name, resp_body['name'])
+        self.assertDictContainsSubset(self.cluster_template, resp_body)
 
-        return body['id'], template_name
+        return resp_body['id'], template_name
 
     @test.attr(type='smoke')
     def test_cluster_template_create(self):
@@ -122,8 +121,7 @@
         template_info = self._create_cluster_template()
 
         # check for cluster template in list
-        resp, templates = self.client.list_cluster_templates()
-        self.assertEqual(200, resp.status)
+        _, templates = self.client.list_cluster_templates()
         templates_info = [(template['id'], template['name'])
                           for template in templates]
         self.assertIn(template_info, templates_info)
@@ -133,16 +131,14 @@
         template_id, template_name = self._create_cluster_template()
 
         # check cluster template fetch by id
-        resp, template = self.client.get_cluster_template(template_id)
-        self.assertEqual(200, resp.status)
+        _, template = self.client.get_cluster_template(template_id)
         self.assertEqual(template_name, template['name'])
         self.assertDictContainsSubset(self.cluster_template, template)
 
     @test.attr(type='smoke')
     def test_cluster_template_delete(self):
-        template_id = self._create_cluster_template()[0]
+        template_id, _ = self._create_cluster_template()
 
         # delete the cluster template by id
-        resp = self.client.delete_cluster_template(template_id)[0]
-        self.assertEqual(204, resp.status)
+        self.client.delete_cluster_template(template_id)
         # TODO(ylobankov): check that cluster template is really deleted
diff --git a/tempest/api/data_processing/test_data_sources.py b/tempest/api/data_processing/test_data_sources.py
index 345153b..aae56c4 100644
--- a/tempest/api/data_processing/test_data_sources.py
+++ b/tempest/api/data_processing/test_data_sources.py
@@ -48,65 +48,59 @@
     def _create_data_source(self, source_body, source_name=None):
         """Creates Data Source with optional name specified.
 
-        It creates a link to input-source file (it may not exist) and ensures
-        response status and source name. Returns id and name of created source.
+        It creates a link to input-source file (it may not exist), ensures
+        source name and response body. Returns id and name of created source.
         """
         if not source_name:
             # generate random name if it's not specified
             source_name = data_utils.rand_name('sahara-data-source')
 
         # create data source
-        resp, body = self.create_data_source(source_name, **source_body)
+        resp_body = self.create_data_source(source_name, **source_body)
 
         # ensure that source created successfully
-        self.assertEqual(202, resp.status)
-        self.assertEqual(source_name, body['name'])
+        self.assertEqual(source_name, resp_body['name'])
         if source_body['type'] == 'swift':
             source_body = self.swift_data_source
-        self.assertDictContainsSubset(source_body, body)
+        self.assertDictContainsSubset(source_body, resp_body)
 
-        return body['id'], source_name
+        return resp_body['id'], source_name
 
     def _list_data_sources(self, source_info):
         # check for data source in list
-        resp, sources = self.client.list_data_sources()
-        self.assertEqual(200, resp.status)
+        _, sources = self.client.list_data_sources()
         sources_info = [(source['id'], source['name']) for source in sources]
         self.assertIn(source_info, sources_info)
 
     def _get_data_source(self, source_id, source_name, source_body):
         # check data source fetch by id
-        resp, source = self.client.get_data_source(source_id)
-        self.assertEqual(200, resp.status)
+        _, source = self.client.get_data_source(source_id)
         self.assertEqual(source_name, source['name'])
         self.assertDictContainsSubset(source_body, source)
 
-    def _delete_data_source(self, source_id):
-        # delete the data source by id
-        resp = self.client.delete_data_source(source_id)[0]
-        self.assertEqual(204, resp.status)
-
     @test.attr(type='smoke')
     def test_swift_data_source_create(self):
         self._create_data_source(self.swift_data_source_with_creds)
 
     @test.attr(type='smoke')
     def test_swift_data_source_list(self):
-        source_info = self._create_data_source(
-            self.swift_data_source_with_creds)
+        source_info = (
+            self._create_data_source(self.swift_data_source_with_creds))
         self._list_data_sources(source_info)
 
     @test.attr(type='smoke')
     def test_swift_data_source_get(self):
-        source_id, source_name = self._create_data_source(
-            self.swift_data_source_with_creds)
+        source_id, source_name = (
+            self._create_data_source(self.swift_data_source_with_creds))
         self._get_data_source(source_id, source_name, self.swift_data_source)
 
     @test.attr(type='smoke')
     def test_swift_data_source_delete(self):
-        source_id = self._create_data_source(
-            self.swift_data_source_with_creds)[0]
-        self._delete_data_source(source_id)
+        source_id, _ = (
+            self._create_data_source(self.swift_data_source_with_creds))
+
+        # delete the data source by id
+        self.client.delete_data_source(source_id)
 
     @test.attr(type='smoke')
     def test_local_hdfs_data_source_create(self):
@@ -119,15 +113,17 @@
 
     @test.attr(type='smoke')
     def test_local_hdfs_data_source_get(self):
-        source_id, source_name = self._create_data_source(
-            self.local_hdfs_data_source)
+        source_id, source_name = (
+            self._create_data_source(self.local_hdfs_data_source))
         self._get_data_source(
             source_id, source_name, self.local_hdfs_data_source)
 
     @test.attr(type='smoke')
     def test_local_hdfs_data_source_delete(self):
-        source_id = self._create_data_source(self.local_hdfs_data_source)[0]
-        self._delete_data_source(source_id)
+        source_id, _ = self._create_data_source(self.local_hdfs_data_source)
+
+        # delete the data source by id
+        self.client.delete_data_source(source_id)
 
     @test.attr(type='smoke')
     def test_external_hdfs_data_source_create(self):
@@ -140,12 +136,14 @@
 
     @test.attr(type='smoke')
     def test_external_hdfs_data_source_get(self):
-        source_id, source_name = self._create_data_source(
-            self.external_hdfs_data_source)
+        source_id, source_name = (
+            self._create_data_source(self.external_hdfs_data_source))
         self._get_data_source(
             source_id, source_name, self.external_hdfs_data_source)
 
     @test.attr(type='smoke')
     def test_external_hdfs_data_source_delete(self):
-        source_id = self._create_data_source(self.external_hdfs_data_source)[0]
-        self._delete_data_source(source_id)
+        source_id, _ = self._create_data_source(self.external_hdfs_data_source)
+
+        # delete the data source by id
+        self.client.delete_data_source(source_id)
diff --git a/tempest/api/data_processing/test_job_binaries.py b/tempest/api/data_processing/test_job_binaries.py
index 689c1fe..15ee145 100644
--- a/tempest/api/data_processing/test_job_binaries.py
+++ b/tempest/api/data_processing/test_job_binaries.py
@@ -40,8 +40,8 @@
 
         name = data_utils.rand_name('sahara-internal-job-binary')
         cls.job_binary_data = 'Some script may be data'
-        job_binary_internal = cls.create_job_binary_internal(
-            name, cls.job_binary_data)[1]
+        job_binary_internal = (
+            cls.create_job_binary_internal(name, cls.job_binary_data))
         cls.internal_db_job_binary = {
             'url': 'internal-db://%s' % job_binary_internal['id'],
             'description': 'Test job binary',
@@ -50,26 +50,25 @@
     def _create_job_binary(self, binary_body, binary_name=None):
         """Creates Job Binary with optional name specified.
 
-        It creates a link to data (jar, pig files, etc.) and ensures response
-        status, job binary name and response body. Returns id and name of
-        created job binary. Data may not exist when using Swift
-        as data storage. In other cases data must exist in storage.
+        It creates a link to data (jar, pig files, etc.), ensures job binary
+        name and response body. Returns id and name of created job binary.
+        Data may not exist when using Swift as data storage.
+        In other cases data must exist in storage.
         """
         if not binary_name:
             # generate random name if it's not specified
             binary_name = data_utils.rand_name('sahara-job-binary')
 
         # create job binary
-        resp, body = self.create_job_binary(binary_name, **binary_body)
+        resp_body = self.create_job_binary(binary_name, **binary_body)
 
         # ensure that binary created successfully
-        self.assertEqual(202, resp.status)
-        self.assertEqual(binary_name, body['name'])
+        self.assertEqual(binary_name, resp_body['name'])
         if 'swift' in binary_body['url']:
             binary_body = self.swift_job_binary
-        self.assertDictContainsSubset(binary_body, body)
+        self.assertDictContainsSubset(binary_body, resp_body)
 
-        return body['id'], binary_name
+        return resp_body['id'], binary_name
 
     @test.attr(type='smoke')
     def test_swift_job_binary_create(self):
@@ -80,30 +79,27 @@
         binary_info = self._create_job_binary(self.swift_job_binary_with_extra)
 
         # check for job binary in list
-        resp, binaries = self.client.list_job_binaries()
-        self.assertEqual(200, resp.status)
+        _, binaries = self.client.list_job_binaries()
         binaries_info = [(binary['id'], binary['name']) for binary in binaries]
         self.assertIn(binary_info, binaries_info)
 
     @test.attr(type='smoke')
     def test_swift_job_binary_get(self):
-        binary_id, binary_name = self._create_job_binary(
-            self.swift_job_binary_with_extra)
+        binary_id, binary_name = (
+            self._create_job_binary(self.swift_job_binary_with_extra))
 
         # check job binary fetch by id
-        resp, binary = self.client.get_job_binary(binary_id)
-        self.assertEqual(200, resp.status)
+        _, binary = self.client.get_job_binary(binary_id)
         self.assertEqual(binary_name, binary['name'])
         self.assertDictContainsSubset(self.swift_job_binary, binary)
 
     @test.attr(type='smoke')
     def test_swift_job_binary_delete(self):
-        binary_id = self._create_job_binary(
-            self.swift_job_binary_with_extra)[0]
+        binary_id, _ = (
+            self._create_job_binary(self.swift_job_binary_with_extra))
 
         # delete the job binary by id
-        resp = self.client.delete_job_binary(binary_id)[0]
-        self.assertEqual(204, resp.status)
+        self.client.delete_job_binary(binary_id)
 
     @test.attr(type='smoke')
     def test_internal_db_job_binary_create(self):
@@ -114,35 +110,31 @@
         binary_info = self._create_job_binary(self.internal_db_job_binary)
 
         # check for job binary in list
-        resp, binaries = self.client.list_job_binaries()
-        self.assertEqual(200, resp.status)
+        _, binaries = self.client.list_job_binaries()
         binaries_info = [(binary['id'], binary['name']) for binary in binaries]
         self.assertIn(binary_info, binaries_info)
 
     @test.attr(type='smoke')
     def test_internal_db_job_binary_get(self):
-        binary_id, binary_name = self._create_job_binary(
-            self.internal_db_job_binary)
+        binary_id, binary_name = (
+            self._create_job_binary(self.internal_db_job_binary))
 
         # check job binary fetch by id
-        resp, binary = self.client.get_job_binary(binary_id)
-        self.assertEqual(200, resp.status)
+        _, binary = self.client.get_job_binary(binary_id)
         self.assertEqual(binary_name, binary['name'])
         self.assertDictContainsSubset(self.internal_db_job_binary, binary)
 
     @test.attr(type='smoke')
     def test_internal_db_job_binary_delete(self):
-        binary_id = self._create_job_binary(self.internal_db_job_binary)[0]
+        binary_id, _ = self._create_job_binary(self.internal_db_job_binary)
 
         # delete the job binary by id
-        resp = self.client.delete_job_binary(binary_id)[0]
-        self.assertEqual(204, resp.status)
+        self.client.delete_job_binary(binary_id)
 
     @test.attr(type='smoke')
     def test_job_binary_get_data(self):
-        binary_id = self._create_job_binary(self.internal_db_job_binary)[0]
+        binary_id, _ = self._create_job_binary(self.internal_db_job_binary)
 
         # get data of job binary by id
-        resp, data = self.client.get_job_binary_data(binary_id)
-        self.assertEqual(200, resp.status)
+        _, data = self.client.get_job_binary_data(binary_id)
         self.assertEqual(data, self.job_binary_data)
diff --git a/tempest/api/data_processing/test_job_binary_internals.py b/tempest/api/data_processing/test_job_binary_internals.py
index 6d59177..45e1140 100644
--- a/tempest/api/data_processing/test_job_binary_internals.py
+++ b/tempest/api/data_processing/test_job_binary_internals.py
@@ -29,23 +29,22 @@
     def _create_job_binary_internal(self, binary_name=None):
         """Creates Job Binary Internal with optional name specified.
 
-        It puts data into Sahara database and ensures response status and
-        job binary internal name. Returns id and name of created job binary
-        internal.
+        It puts data into Sahara database and ensures job binary internal name.
+        Returns id and name of created job binary internal.
         """
         if not binary_name:
             # generate random name if it's not specified
             binary_name = data_utils.rand_name('sahara-job-binary-internal')
 
         # create job binary internal
-        resp, body = self.create_job_binary_internal(
-            binary_name, self.job_binary_internal_data)
+        resp_body = (
+            self.create_job_binary_internal(binary_name,
+                                            self.job_binary_internal_data))
 
         # ensure that job binary internal created successfully
-        self.assertEqual(202, resp.status)
-        self.assertEqual(binary_name, body['name'])
+        self.assertEqual(binary_name, resp_body['name'])
 
-        return body['id'], binary_name
+        return resp_body['id'], binary_name
 
     @test.attr(type='smoke')
     def test_job_binary_internal_create(self):
@@ -56,8 +55,7 @@
         binary_info = self._create_job_binary_internal()
 
         # check for job binary internal in list
-        resp, binaries = self.client.list_job_binary_internals()
-        self.assertEqual(200, resp.status)
+        _, binaries = self.client.list_job_binary_internals()
         binaries_info = [(binary['id'], binary['name']) for binary in binaries]
         self.assertIn(binary_info, binaries_info)
 
@@ -66,23 +64,20 @@
         binary_id, binary_name = self._create_job_binary_internal()
 
         # check job binary internal fetch by id
-        resp, binary = self.client.get_job_binary_internal(binary_id)
-        self.assertEqual(200, resp.status)
+        _, binary = self.client.get_job_binary_internal(binary_id)
         self.assertEqual(binary_name, binary['name'])
 
     @test.attr(type='smoke')
     def test_job_binary_internal_delete(self):
-        binary_id = self._create_job_binary_internal()[0]
+        binary_id, _ = self._create_job_binary_internal()
 
         # delete the job binary internal by id
-        resp = self.client.delete_job_binary_internal(binary_id)[0]
-        self.assertEqual(204, resp.status)
+        self.client.delete_job_binary_internal(binary_id)
 
     @test.attr(type='smoke')
     def test_job_binary_internal_get_data(self):
-        binary_id = self._create_job_binary_internal()[0]
+        binary_id, _ = self._create_job_binary_internal()
 
         # get data of job binary internal by id
-        resp, data = self.client.get_job_binary_internal_data(binary_id)
-        self.assertEqual(200, resp.status)
+        _, data = self.client.get_job_binary_internal_data(binary_id)
         self.assertEqual(data, self.job_binary_internal_data)
diff --git a/tempest/api/data_processing/test_jobs.py b/tempest/api/data_processing/test_jobs.py
new file mode 100644
index 0000000..8591dbd
--- /dev/null
+++ b/tempest/api/data_processing/test_jobs.py
@@ -0,0 +1,90 @@
+# Copyright (c) 2014 Mirantis Inc.
+#
+#    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.data_processing import base as dp_base
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class JobTest(dp_base.BaseDataProcessingTest):
+    """Link to the API documentation is http://docs.openstack.org/developer/
+    sahara/restapi/rest_api_v1.1_EDP.html#jobs
+    """
+    @classmethod
+    @test.safe_setup
+    def setUpClass(cls):
+        super(JobTest, cls).setUpClass()
+        # create job binary
+        job_binary = {
+            'name': data_utils.rand_name('sahara-job-binary'),
+            'url': 'swift://sahara-container.sahara/example.jar',
+            'description': 'Test job binary',
+            'extra': {
+                'user': cls.os.credentials.username,
+                'password': cls.os.credentials.password
+            }
+        }
+        resp_body = cls.create_job_binary(**job_binary)
+        job_binary_id = resp_body['id']
+
+        cls.job = {
+            'job_type': 'Pig',
+            'mains': [job_binary_id]
+        }
+
+    def _create_job(self, job_name=None):
+        """Creates Job with optional name specified.
+
+        It creates job and ensures job name. Returns id and name of created
+        job.
+        """
+        if not job_name:
+            # generate random name if it's not specified
+            job_name = data_utils.rand_name('sahara-job')
+
+        # create job
+        resp_body = self.create_job(job_name, **self.job)
+
+        # ensure that job created successfully
+        self.assertEqual(job_name, resp_body['name'])
+
+        return resp_body['id'], job_name
+
+    @test.attr(type='smoke')
+    def test_job_create(self):
+        self._create_job()
+
+    @test.attr(type='smoke')
+    def test_job_list(self):
+        job_info = self._create_job()
+
+        # check for job in list
+        _, jobs = self.client.list_jobs()
+        jobs_info = [(job['id'], job['name']) for job in jobs]
+        self.assertIn(job_info, jobs_info)
+
+    @test.attr(type='smoke')
+    def test_job_get(self):
+        job_id, job_name = self._create_job()
+
+        # check job fetch by id
+        _, job = self.client.get_job(job_id)
+        self.assertEqual(job_name, job['name'])
+
+    @test.attr(type='smoke')
+    def test_job_delete(self):
+        job_id, _ = self._create_job()
+
+        # delete the job by id
+        self.client.delete_job(job_id)
diff --git a/tempest/api/data_processing/test_node_group_templates.py b/tempest/api/data_processing/test_node_group_templates.py
index 04f98b4..c2c0075 100644
--- a/tempest/api/data_processing/test_node_group_templates.py
+++ b/tempest/api/data_processing/test_node_group_templates.py
@@ -43,7 +43,7 @@
     def _create_node_group_template(self, template_name=None):
         """Creates Node Group Template with optional name specified.
 
-        It creates template and ensures response status and template name.
+        It creates template, ensures template name and response body.
         Returns id and name of created template.
         """
         if not template_name:
@@ -51,15 +51,14 @@
             template_name = data_utils.rand_name('sahara-ng-template')
 
         # create node group template
-        resp, body = self.create_node_group_template(
-            template_name, **self.node_group_template)
+        resp_body = self.create_node_group_template(template_name,
+                                                    **self.node_group_template)
 
         # ensure that template created successfully
-        self.assertEqual(202, resp.status)
-        self.assertEqual(template_name, body['name'])
-        self.assertDictContainsSubset(self.node_group_template, body)
+        self.assertEqual(template_name, resp_body['name'])
+        self.assertDictContainsSubset(self.node_group_template, resp_body)
 
-        return body['id'], template_name
+        return resp_body['id'], template_name
 
     @test.attr(type='smoke')
     def test_node_group_template_create(self):
@@ -70,8 +69,7 @@
         template_info = self._create_node_group_template()
 
         # check for node group template in list
-        resp, templates = self.client.list_node_group_templates()
-        self.assertEqual(200, resp.status)
+        _, templates = self.client.list_node_group_templates()
         templates_info = [(template['id'], template['name'])
                           for template in templates]
         self.assertIn(template_info, templates_info)
@@ -81,15 +79,13 @@
         template_id, template_name = self._create_node_group_template()
 
         # check node group template fetch by id
-        resp, template = self.client.get_node_group_template(template_id)
-        self.assertEqual(200, resp.status)
+        _, template = self.client.get_node_group_template(template_id)
         self.assertEqual(template_name, template['name'])
         self.assertDictContainsSubset(self.node_group_template, template)
 
     @test.attr(type='smoke')
     def test_node_group_template_delete(self):
-        template_id = self._create_node_group_template()[0]
+        template_id, _ = self._create_node_group_template()
 
         # delete the node group template by id
-        resp = self.client.delete_node_group_template(template_id)[0]
-        self.assertEqual(204, resp.status)
+        self.client.delete_node_group_template(template_id)
diff --git a/tempest/api/data_processing/test_plugins.py b/tempest/api/data_processing/test_plugins.py
index d643f23..9fd7a17 100644
--- a/tempest/api/data_processing/test_plugins.py
+++ b/tempest/api/data_processing/test_plugins.py
@@ -20,10 +20,9 @@
     def _list_all_plugin_names(self):
         """Returns all enabled plugin names.
 
-        It ensures response status and main plugins availability.
+        It ensures main plugins availability.
         """
-        resp, plugins = self.client.list_plugins()
-        self.assertEqual(200, resp.status)
+        _, plugins = self.client.list_plugins()
         plugins_names = [plugin['name'] for plugin in plugins]
         self.assertIn('vanilla', plugins_names)
         self.assertIn('hdp', plugins_names)
@@ -37,14 +36,12 @@
     @test.attr(type='smoke')
     def test_plugin_get(self):
         for plugin_name in self._list_all_plugin_names():
-            resp, plugin = self.client.get_plugin(plugin_name)
-            self.assertEqual(200, resp.status)
+            _, plugin = self.client.get_plugin(plugin_name)
             self.assertEqual(plugin_name, plugin['name'])
 
             for plugin_version in plugin['versions']:
-                resp, detailed_plugin = self.client.get_plugin(plugin_name,
-                                                               plugin_version)
-                self.assertEqual(200, resp.status)
+                _, detailed_plugin = self.client.get_plugin(plugin_name,
+                                                            plugin_version)
                 self.assertEqual(plugin_name, detailed_plugin['name'])
 
                 # check that required image tags contains name and version
diff --git a/tempest/api/database/flavors/test_flavors.py b/tempest/api/database/flavors/test_flavors.py
index 64d71b9..a5c8caa 100644
--- a/tempest/api/database/flavors/test_flavors.py
+++ b/tempest/api/database/flavors/test_flavors.py
@@ -27,8 +27,7 @@
     @test.attr(type='smoke')
     def test_get_db_flavor(self):
         # The expected flavor details should be returned
-        resp, flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
-        self.assertEqual(200, resp.status)
+        _, flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
         self.assertEqual(self.db_flavor_ref, str(flavor['id']))
         self.assertIn('ram', flavor)
         self.assertIn('links', flavor)
@@ -36,11 +35,9 @@
 
     @test.attr(type='smoke')
     def test_list_db_flavors(self):
-        resp, flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
-        self.assertEqual(200, resp.status)
+        _, flavor = self.client.get_db_flavor_details(self.db_flavor_ref)
         # List of all flavors should contain the expected flavor
-        resp, flavors = self.client.list_db_flavors()
-        self.assertEqual(200, resp.status)
+        _, flavors = self.client.list_db_flavors()
         self.assertIn(flavor, flavors)
 
     def _check_values(self, names, db_flavor, os_flavor, in_db=True):
@@ -55,18 +52,16 @@
                 self.assertNotIn(name, db_flavor)
 
     @test.attr(type='smoke')
+    @test.services('compute')
     def test_compare_db_flavors_with_os(self):
-        resp, db_flavors = self.client.list_db_flavors()
-        self.assertEqual(200, resp.status)
-        resp, os_flavors = self.os_flavors_client.list_flavors_with_detail()
-        self.assertEqual(200, resp.status)
+        _, db_flavors = self.client.list_db_flavors()
+        _, os_flavors = self.os_flavors_client.list_flavors_with_detail()
         self.assertEqual(len(os_flavors), len(db_flavors),
                          "OS flavors %s do not match DB flavors %s" %
                          (os_flavors, db_flavors))
         for os_flavor in os_flavors:
-            resp, db_flavor =\
+            _, db_flavor =\
                 self.client.get_db_flavor_details(os_flavor['id'])
-            self.assertEqual(200, resp.status)
             self._check_values(['id', 'name', 'ram'], db_flavor, os_flavor)
             self._check_values(['disk', 'vcpus', 'swap'], db_flavor, os_flavor,
                                in_db=False)
diff --git a/tempest/api/database/versions/test_versions.py b/tempest/api/database/versions/test_versions.py
index 6101f47..453abe7 100644
--- a/tempest/api/database/versions/test_versions.py
+++ b/tempest/api/database/versions/test_versions.py
@@ -27,8 +27,7 @@
 
     @test.attr(type='smoke')
     def test_list_db_versions(self):
-        resp, versions = self.client.list_db_versions()
-        self.assertEqual(200, resp.status)
+        _, versions = self.client.list_db_versions()
         self.assertTrue(len(versions) > 0, "No database versions found")
         # List of all versions should contain the current version, and there
         # should only be one 'current' version
diff --git a/tempest/api/identity/admin/test_roles.py b/tempest/api/identity/admin/test_roles.py
index 7a6d07f..492d56f 100644
--- a/tempest/api/identity/admin/test_roles.py
+++ b/tempest/api/identity/admin/test_roles.py
@@ -49,7 +49,7 @@
 
     @test.attr(type='gate')
     def test_list_roles(self):
-        # Return a list of all roles
+        """Return a list of all roles."""
         _, body = self.client.list_roles()
         found = [role for role in body if role in self.data.roles]
         self.assertTrue(any(found))
@@ -57,7 +57,7 @@
 
     @test.attr(type='gate')
     def test_role_create_delete(self):
-        # Role should be created, verified, and deleted
+        """Role should be created, verified, and deleted."""
         role_name = data_utils.rand_name(name='role-test-')
         _, body = self.client.create_role(role_name)
         self.assertEqual(role_name, body['name'])
@@ -74,7 +74,7 @@
 
     @test.attr(type='gate')
     def test_get_role_by_id(self):
-        # Get a role by its id
+        """Get a role by its id."""
         self.data.setup_test_role()
         role_id = self.data.role['id']
         role_name = self.data.role['name']
@@ -84,7 +84,7 @@
 
     @test.attr(type='gate')
     def test_assign_user_role(self):
-        # Assign a role to a user on a tenant
+        """Assign a role to a user on a tenant."""
         (user, tenant, role) = self._get_role_params()
         self.client.assign_user_role(tenant['id'], user['id'], role['id'])
         _, roles = self.client.list_user_roles(tenant['id'], user['id'])
@@ -92,7 +92,7 @@
 
     @test.attr(type='gate')
     def test_remove_user_role(self):
-        # Remove a role assigned to a user on a tenant
+        """Remove a role assigned to a user on a tenant."""
         (user, tenant, role) = self._get_role_params()
         _, user_role = self.client.assign_user_role(tenant['id'],
                                                     user['id'], role['id'])
@@ -101,7 +101,7 @@
 
     @test.attr(type='gate')
     def test_list_user_roles(self):
-        # List roles assigned to a user on tenant
+        """List roles assigned to a user on tenant."""
         (user, tenant, role) = self._get_role_params()
         self.client.assign_user_role(tenant['id'], user['id'], role['id'])
         _, roles = self.client.list_user_roles(tenant['id'], user['id'])
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 1548f89..6beb8f2 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -40,7 +40,7 @@
         cls.setup_endpoints = list()
         for i in range(2):
             region = data_utils.rand_name('region')
-            url = data_utils.rand_name('url')
+            url = data_utils.rand_url()
             interface = 'public'
             resp, endpoint = cls.client.create_endpoint(
                 cls.service_id, interface, url, region=region, enabled=True)
@@ -69,7 +69,7 @@
     @test.attr(type='gate')
     def test_create_list_delete_endpoint(self):
         region = data_utils.rand_name('region')
-        url = data_utils.rand_name('url')
+        url = data_utils.rand_url()
         interface = 'public'
         resp, endpoint =\
             self.client.create_endpoint(self.service_id, interface, url,
@@ -97,7 +97,7 @@
         # Creating an endpoint so as to check update endpoint
         # with new values
         region1 = data_utils.rand_name('region')
-        url1 = data_utils.rand_name('url')
+        url1 = data_utils.rand_url()
         interface1 = 'public'
         resp, endpoint_for_update =\
             self.client.create_endpoint(self.service_id, interface1,
@@ -114,7 +114,7 @@
         self.service_ids.append(service2['id'])
         # Updating endpoint with new values
         region2 = data_utils.rand_name('region')
-        url2 = data_utils.rand_name('url')
+        url2 = data_utils.rand_url()
         interface2 = 'internal'
         resp, endpoint = \
             self.client.update_endpoint(endpoint_for_update['id'],
diff --git a/tempest/api/identity/admin/v3/test_endpoints_negative.py b/tempest/api/identity/admin/v3/test_endpoints_negative.py
index 1d63cce..d728b1d 100644
--- a/tempest/api/identity/admin/v3/test_endpoints_negative.py
+++ b/tempest/api/identity/admin/v3/test_endpoints_negative.py
@@ -49,7 +49,7 @@
     def test_create_with_enabled_False(self):
         # Enabled should be a boolean, not a string like 'False'
         interface = 'public'
-        url = data_utils.rand_name('url')
+        url = data_utils.rand_url()
         region = data_utils.rand_name('region')
         self.assertRaises(exceptions.BadRequest, self.client.create_endpoint,
                           self.service_id, interface, url, region=region,
@@ -59,7 +59,7 @@
     def test_create_with_enabled_True(self):
         # Enabled should be a boolean, not a string like 'True'
         interface = 'public'
-        url = data_utils.rand_name('url')
+        url = data_utils.rand_url()
         region = data_utils.rand_name('region')
         self.assertRaises(exceptions.BadRequest, self.client.create_endpoint,
                           self.service_id, interface, url, region=region,
@@ -69,7 +69,7 @@
 
         # Create an endpoint
         region1 = data_utils.rand_name('region')
-        url1 = data_utils.rand_name('url')
+        url1 = data_utils.rand_url()
         interface1 = 'public'
         resp, endpoint_for_update = (
             self.client.create_endpoint(self.service_id, interface1,
diff --git a/tempest/api/identity/admin/v3/test_list_projects.py b/tempest/api/identity/admin/v3/test_list_projects.py
new file mode 100644
index 0000000..a3944e2
--- /dev/null
+++ b/tempest/api/identity/admin/v3/test_list_projects.py
@@ -0,0 +1,73 @@
+# 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.identity import base
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class ListProjectsTestJSON(base.BaseIdentityV3AdminTest):
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(ListProjectsTestJSON, cls).setUpClass()
+        cls.project_ids = list()
+        cls.data.setup_test_domain()
+        # Create project with domain
+        cls.p1_name = data_utils.rand_name('project')
+        _, cls.p1 = cls.client.create_project(
+            cls.p1_name, enabled=False, domain_id=cls.data.domain['id'])
+        cls.data.projects.append(cls.p1)
+        cls.project_ids.append(cls.p1['id'])
+        # Create default project
+        p2_name = data_utils.rand_name('project')
+        _, cls.p2 = cls.client.create_project(p2_name)
+        cls.data.projects.append(cls.p2)
+        cls.project_ids.append(cls.p2['id'])
+
+    @test.attr(type='gate')
+    def test_projects_list(self):
+        # List projects
+        resp, list_projects = self.client.list_projects()
+
+        for p in self.project_ids:
+            _, get_project = self.client.get_project(p)
+            self.assertIn(get_project, list_projects)
+
+    @test.attr(type='gate')
+    def test_list_projects_with_domains(self):
+        # List projects with domain
+        self._list_projects_with_params(
+            {'domain_id': self.data.domain['id']}, 'domain_id')
+
+    @test.attr(type='gate')
+    def test_list_projects_with_enabled(self):
+        # List the projects with enabled
+        self._list_projects_with_params({'enabled': False}, 'enabled')
+
+    @test.attr(type='gate')
+    def test_list_projects_with_name(self):
+        # List projects with name
+        self._list_projects_with_params({'name': self.p1_name}, 'name')
+
+    def _list_projects_with_params(self, params, key):
+        resp, body = self.client.list_projects(params)
+        self.assertIn(self.p1[key], map(lambda x: x[key], body))
+        self.assertNotIn(self.p2[key], map(lambda x: x[key], body))
+
+
+class ListProjectsTestXML(ListProjectsTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/identity/admin/v3/test_list_users.py b/tempest/api/identity/admin/v3/test_list_users.py
new file mode 100644
index 0000000..497c5ea
--- /dev/null
+++ b/tempest/api/identity/admin/v3/test_list_users.py
@@ -0,0 +1,100 @@
+# 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.identity import base
+from tempest.common.utils import data_utils
+from tempest import test
+
+
+class UsersV3TestJSON(base.BaseIdentityV3AdminTest):
+    _interface = 'json'
+
+    def _list_users_with_params(self, params, key, expected, not_expected):
+        # Helper method to list users filtered with params and
+        # assert the response based on expected and not_expected
+        # expected: user expected in the list response
+        # not_expected: user, which should not be present in list response
+        _, body = self.client.get_users(params)
+        self.assertIn(expected[key], map(lambda x: x[key], body))
+        self.assertNotIn(not_expected[key],
+                         map(lambda x: x[key], body))
+
+    @classmethod
+    def setUpClass(cls):
+        super(UsersV3TestJSON, cls).setUpClass()
+        alt_user = data_utils.rand_name('test_user')
+        alt_password = data_utils.rand_name('pass')
+        cls.alt_email = alt_user + '@testmail.tm'
+        cls.data.setup_test_domain()
+        # Create user with Domain
+        u1_name = data_utils.rand_name('test_user')
+        _, cls.domain_enabled_user = cls.client.create_user(
+            u1_name, password=alt_password,
+            email=cls.alt_email, domain_id=cls.data.domain['id'])
+        cls.data.v3_users.append(cls.domain_enabled_user)
+        # Create default not enabled user
+        u2_name = data_utils.rand_name('test_user')
+        _, cls.non_domain_enabled_user = cls.client.create_user(
+            u2_name, password=alt_password,
+            email=cls.alt_email, enabled=False)
+        cls.data.v3_users.append(cls.non_domain_enabled_user)
+
+    @test.attr(type='gate')
+    def test_list_user_domains(self):
+        # List users with domain
+        params = {'domain_id': self.data.domain['id']}
+        self._list_users_with_params(params, 'domain_id',
+                                     self.domain_enabled_user,
+                                     self.non_domain_enabled_user)
+
+    @test.attr(type='gate')
+    def test_list_users_with_not_enabled(self):
+        # List the users with not enabled
+        params = {'enabled': False}
+        self._list_users_with_params(params, 'enabled',
+                                     self.non_domain_enabled_user,
+                                     self.domain_enabled_user)
+
+    @test.attr(type='gate')
+    def test_list_users_with_name(self):
+        # List users with name
+        params = {'name': self.domain_enabled_user['name']}
+        self._list_users_with_params(params, 'name',
+                                     self.domain_enabled_user,
+                                     self.non_domain_enabled_user)
+
+    @test.attr(type='gate')
+    def test_list_users(self):
+        # List users
+        _, body = self.client.get_users()
+        fetched_ids = [u['id'] for u in body]
+        missing_users = [u['id'] for u in self.data.v3_users
+                         if u['id'] not in fetched_ids]
+        self.assertEqual(0, len(missing_users),
+                         "Failed to find user %s in fetched list" %
+                         ', '.join(m_user for m_user in missing_users))
+
+    @test.attr(type='gate')
+    def test_get_user(self):
+        # Get a user detail
+        _, user = self.client.get_user(self.data.v3_users[0]['id'])
+        self.assertEqual(self.data.v3_users[0]['id'], user['id'])
+        self.assertEqual(self.data.v3_users[0]['name'], user['name'])
+        self.assertEqual(self.alt_email, user['email'])
+        self.assertEqual(self.data.domain['id'], user['domain_id'])
+
+
+class UsersV3TestXML(UsersV3TestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index 77acd57..5890eab 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -13,35 +13,14 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from six import moves
-
 from tempest.api.identity import base
 from tempest.common.utils import data_utils
-from tempest import exceptions
 from tempest import test
 
 
 class ProjectsTestJSON(base.BaseIdentityV3AdminTest):
     _interface = 'json'
 
-    def _delete_project(self, project_id):
-        self.client.delete_project(project_id)
-        self.assertRaises(
-            exceptions.NotFound, self.client.get_project, project_id)
-
-    @test.attr(type='gate')
-    def test_project_list_delete(self):
-        # Create several projects and delete them
-        for _ in moves.xrange(3):
-            _, project = self.client.create_project(
-                data_utils.rand_name('project-new'))
-            self.addCleanup(self._delete_project, project['id'])
-
-        _, list_projects = self.client.list_projects()
-
-        _, get_project = self.client.get_project(project['id'])
-        self.assertIn(get_project, list_projects)
-
     @test.attr(type='gate')
     def test_project_create_with_description(self):
         # Create project with a description
@@ -60,6 +39,21 @@
                          'to be set')
 
     @test.attr(type='gate')
+    def test_project_create_with_domain(self):
+        # Create project with a domain
+        self.data.setup_test_domain()
+        project_name = data_utils.rand_name('project')
+        resp, project = self.client.create_project(
+            project_name, domain_id=self.data.domain['id'])
+        self.data.projects.append(project)
+        project_id = project['id']
+        self.assertEqual(project_name, project['name'])
+        self.assertEqual(self.data.domain['id'], project['domain_id'])
+        _, body = self.client.get_project(project_id)
+        self.assertEqual(project_name, body['name'])
+        self.assertEqual(self.data.domain['id'], body['domain_id'])
+
+    @test.attr(type='gate')
     def test_project_create_enabled(self):
         # Create a project that is enabled
         project_name = data_utils.rand_name('project-')
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index e61b738..bd08614 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -48,6 +48,7 @@
         self.assertRaises(exceptions.NotFound, self.client.get_token,
                           subject_token)
 
+    @test.skip_because(bug="1351026")
     @test.attr(type='gate')
     def test_rescope_token(self):
         """Rescope a token.
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index fed5171..886c808 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -12,6 +12,7 @@
 
 import datetime
 import re
+
 from tempest.api.identity import base
 from tempest import auth
 from tempest import clients
@@ -150,7 +151,6 @@
         self.assertNotIn('v3/roles/%s' % self.not_delegated_role_id,
                          role['links']['self'])
 
-    @test.skip_because(bug='1334368')
     def check_trust_roles(self):
         # Check we find the delegated role
         _, roles_get = self.trustor_client.get_trust_roles(
@@ -164,12 +164,6 @@
 
         _, role_get = self.trustor_client.check_trust_role(
             self.trust_id, self.delegated_role_id)
-        # This tempest two-step change conflicted with the change
-        # moving response checking to the client. This test should be
-        # re-enabled by removing the following assert and changing
-        # the response code in tempest/services/identity/v3/json/
-        # identity_client.py in the check_trust_role_method.
-        # self.assertEqual('200', resp['status'])
 
         # And that we don't find not_delegated_role
         self.assertRaises(exceptions.NotFound,
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index 558575e..3c25819 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -65,6 +65,28 @@
         self.assertEqual('false', str(new_user_get['enabled']).lower())
 
     @test.attr(type='gate')
+    def test_update_user_password(self):
+        # Creating User to check password updation
+        u_name = data_utils.rand_name('user')
+        original_password = data_utils.rand_name('pass')
+        _, user = self.client.create_user(
+            u_name, password=original_password)
+        # Delete the User at the end all test methods
+        self.addCleanup(self.client.delete_user, user['id'])
+        # Update user with new password
+        new_password = data_utils.rand_name('pass1')
+        self.client.update_user_password(user['id'], new_password,
+                                         original_password)
+        resp, body = self.token.auth(user['id'], new_password)
+        self.assertEqual(201, resp.status)
+        subject_token = resp['x-subject-token']
+        # Perform GET Token to verify and confirm password is updated
+        _, token_details = self.client.get_token(subject_token)
+        self.assertEqual(resp['x-subject-token'], subject_token)
+        self.assertEqual(token_details['user']['id'], user['id'])
+        self.assertEqual(token_details['user']['name'], u_name)
+
+    @test.attr(type='gate')
     def test_list_user_projects(self):
         # List the projects that a user has access upon
         assigned_project_ids = list()
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 0991576..3996cc1 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -18,9 +18,12 @@
 from tempest import clients
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest import exceptions
+from tempest.openstack.common import log as logging
 import tempest.test
 
 CONF = config.CONF
+LOG = logging.getLogger(__name__)
 
 
 class BaseIdentityAdminTest(tempest.test.BaseTestCase):
@@ -121,6 +124,7 @@
             self.v3_users = []
             self.projects = []
             self.v3_roles = []
+            self.domains = []
 
         @property
         def test_credentials(self):
@@ -185,16 +189,45 @@
             _, self.v3_role = self.client.create_role(self.test_role)
             self.v3_roles.append(self.v3_role)
 
+        def setup_test_domain(self):
+            """Set up a test domain."""
+            self.test_domain = data_utils.rand_name('test_domain')
+            self.test_description = data_utils.rand_name('desc')
+            _, self.domain = self.client.create_domain(
+                name=self.test_domain,
+                description=self.test_description)
+            self.domains.append(self.domain)
+
+        @staticmethod
+        def _try_wrapper(func, item, **kwargs):
+            try:
+                if kwargs:
+                    func(item['id'], kwargs)
+                else:
+                    func(item['id'])
+            except exceptions.NotFound:
+                pass
+            except Exception:
+                LOG.exception("Unexpected exception occurred in %s deletion."
+                              " But ignored here." % item['id'])
+
         def teardown_all(self):
+            # NOTE(masayukig): v3 client doesn't have v2 method.
+            # (e.g. delete_tenant) So we need to check resources existence
+            # before using client methods.
             for user in self.users:
-                self.client.delete_user(user['id'])
+                self._try_wrapper(self.client.delete_user, user)
             for tenant in self.tenants:
-                self.client.delete_tenant(tenant['id'])
+                self._try_wrapper(self.client.delete_tenant, tenant)
             for role in self.roles:
-                self.client.delete_role(role['id'])
+                self._try_wrapper(self.client.delete_role, role)
             for v3_user in self.v3_users:
-                self.client.delete_user(v3_user['id'])
+                self._try_wrapper(self.client.delete_user, v3_user)
             for v3_project in self.projects:
-                self.client.delete_project(v3_project['id'])
+                self._try_wrapper(self.client.delete_project, v3_project)
             for v3_role in self.v3_roles:
-                self.client.delete_role(v3_role['id'])
+                self._try_wrapper(self.client.delete_role, v3_role)
+            for domain in self.domains:
+                self._try_wrapper(self.client.update_domain, domain,
+                                  enabled=False)
+                self._try_wrapper(self.client.delete_domain, domain)
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index 02d391b..c875b2f 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -100,7 +100,7 @@
         cls.alt_tenant_id = cls.alt_img_cli.tenant_id
 
     def _create_image(self):
-        image_file = StringIO.StringIO('*' * 1024)
+        image_file = StringIO.StringIO(data_utils.random_bytes())
         resp, image = self.create_image(container_format='bare',
                                         disk_format='raw',
                                         is_public=False,
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 8528e42..bf55b89 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -44,7 +44,7 @@
             self.assertEqual(val, body.get('properties')[key])
 
         # Now try uploading an image file
-        image_file = StringIO.StringIO(('*' * 1024))
+        image_file = StringIO.StringIO(data_utils.random_bytes())
         _, body = self.client.update_image(image_id, data=image_file)
         self.assertIn('size', body)
         self.assertEqual(1024, body.get('size'))
@@ -157,7 +157,7 @@
         image. Note that the size of the new image is a random number between
         1024 and 4096
         """
-        image_file = StringIO.StringIO('*' * size)
+        image_file = StringIO.StringIO(data_utils.random_bytes(size))
         name = 'New Standard Image %s' % name
         _, image = cls.create_image(name=name,
                                     container_format=container_format,
@@ -338,10 +338,9 @@
                                disk_format, size):
         """
         Create a new standard image and return the ID of the newly-registered
-        image. Note that the size of the new image is a random number between
-        1024 and 4096
+        image.
         """
-        image_file = StringIO.StringIO('*' * size)
+        image_file = StringIO.StringIO(data_utils.random_bytes(size))
         name = 'New Standard Image %s' % name
         _, image = cls.create_image(name=name,
                                     container_format=container_format,
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index ae777eb..a974ebb 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -52,7 +52,7 @@
         self.assertEqual('queued', body['status'])
 
         # Now try uploading an image file
-        file_content = '*' * 1024
+        file_content = data_utils.random_bytes()
         image_file = StringIO.StringIO(file_content)
         self.client.store_image(image_id, image_file)
 
@@ -86,7 +86,8 @@
 
         # Verifying deletion
         _, images = self.client.image_list()
-        self.assertNotIn(image_id, images)
+        images_id = [item['id'] for item in images]
+        self.assertNotIn(image_id, images_id)
 
     @test.attr(type='gate')
     def test_update_image(self):
@@ -103,8 +104,7 @@
         image_id = body['id']
 
         # Now try uploading an image file
-        file_content = '*' * 1024
-        image_file = StringIO.StringIO(file_content)
+        image_file = StringIO.StringIO(data_utils.random_bytes())
         self.client.store_image(image_id, image_file)
 
         # Update Image
@@ -145,7 +145,8 @@
         image. Note that the size of the new image is a random number between
         1024 and 4096
         """
-        image_file = StringIO.StringIO('*' * random.randint(1024, 4096))
+        size = random.randint(1024, 4096)
+        image_file = StringIO.StringIO(data_utils.random_bytes(size))
         name = data_utils.rand_name('image-')
         _, body = cls.create_image(name=name,
                                    container_format=container_format,
diff --git a/tempest/api/network/admin/test_agent_management.py b/tempest/api/network/admin/test_agent_management.py
index b848994..f8782ad 100644
--- a/tempest/api/network/admin/test_agent_management.py
+++ b/tempest/api/network/admin/test_agent_management.py
@@ -32,8 +32,7 @@
 
     @test.attr(type='smoke')
     def test_list_agent(self):
-        resp, body = self.admin_client.list_agents()
-        self.assertEqual('200', resp['status'])
+        _, body = self.admin_client.list_agents()
         agents = body['agents']
         # Hearthbeats must be excluded from comparison
         self.agent.pop('heartbeat_timestamp', None)
@@ -45,15 +44,13 @@
 
     @test.attr(type=['smoke'])
     def test_list_agents_non_admin(self):
-        resp, body = self.client.list_agents()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_agents()
         self.assertEqual(len(body["agents"]), 0)
 
     @test.attr(type='smoke')
     def test_show_agent(self):
-        resp, body = self.admin_client.show_agent(self.agent['id'])
+        _, body = self.admin_client.show_agent(self.agent['id'])
         agent = body['agent']
-        self.assertEqual('200', resp['status'])
         self.assertEqual(agent['id'], self.agent['id'])
 
     @test.attr(type='smoke')
@@ -62,10 +59,9 @@
         # Try to update the 'admin_state_up' to the original
         # one to avoid the negative effect.
         agent_status = {'admin_state_up': origin_status}
-        resp, body = self.admin_client.update_agent(agent_id=self.agent['id'],
-                                                    agent_info=agent_status)
+        _, body = self.admin_client.update_agent(agent_id=self.agent['id'],
+                                                 agent_info=agent_status)
         updated_status = body['agent']['admin_state_up']
-        self.assertEqual('200', resp['status'])
         self.assertEqual(origin_status, updated_status)
 
     @test.attr(type='smoke')
@@ -73,10 +69,8 @@
         self.useFixture(fixtures.LockFixture('agent_description'))
         description = 'description for update agent.'
         agent_description = {'description': description}
-        resp, body = self.admin_client.update_agent(
-            agent_id=self.agent['id'],
-            agent_info=agent_description)
-        self.assertEqual('200', resp['status'])
+        _, body = self.admin_client.update_agent(agent_id=self.agent['id'],
+                                                 agent_info=agent_description)
         self.addCleanup(self._restore_agent)
         updated_description = body['agent']['description']
         self.assertEqual(updated_description, description)
diff --git a/tempest/api/network/admin/test_dhcp_agent_scheduler.py b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
index 25e1cc0..c84d1a7 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -35,9 +35,8 @@
 
     @test.attr(type='smoke')
     def test_list_dhcp_agent_hosting_network(self):
-        resp, body = self.admin_client.list_dhcp_agent_hosting_network(
+        _, body = self.admin_client.list_dhcp_agent_hosting_network(
             self.network['id'])
-        self.assertEqual(resp['status'], '200')
 
     @test.attr(type='smoke')
     def test_list_networks_hosted_by_one_dhcp(self):
@@ -51,9 +50,8 @@
 
     def _check_network_in_dhcp_agent(self, network_id, agent):
         network_ids = []
-        resp, body = self.admin_client.list_networks_hosted_by_one_dhcp_agent(
+        _, body = self.admin_client.list_networks_hosted_by_one_dhcp_agent(
             agent['id'])
-        self.assertEqual(resp['status'], '200')
         networks = body['networks']
         for network in networks:
             network_ids.append(network['id'])
@@ -85,17 +83,15 @@
             self._remove_network_from_dhcp_agent(network_id, agent)
 
     def _remove_network_from_dhcp_agent(self, network_id, agent):
-        resp, body = self.admin_client.remove_network_from_dhcp_agent(
+        _, body = self.admin_client.remove_network_from_dhcp_agent(
             agent_id=agent['id'],
             network_id=network_id)
-        self.assertEqual(resp['status'], '204')
         self.assertFalse(self._check_network_in_dhcp_agent(
             network_id, agent))
 
     def _add_dhcp_agent_to_network(self, network_id, agent):
-        resp, body = self.admin_client.add_dhcp_agent_to_network(
-            agent['id'], network_id)
-        self.assertEqual(resp['status'], '201')
+        _, body = self.admin_client.add_dhcp_agent_to_network(agent['id'],
+                                                              network_id)
         self.assertTrue(self._check_network_in_dhcp_agent(
             network_id, agent))
 
diff --git a/tempest/api/network/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index c7fde77..710c669 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -26,9 +26,8 @@
         post_body = {'name': data_utils.rand_name('network-')}
         if external:
             post_body['router:external'] = external
-        resp, body = self.admin_client.create_network(**post_body)
+        _, body = self.admin_client.create_network(**post_body)
         network = body['network']
-        self.assertEqual('201', resp['status'])
         self.addCleanup(self.admin_client.delete_network, network['id'])
         return network
 
@@ -46,9 +45,8 @@
         network = self._create_network(external=False)
         self.assertFalse(network.get('router:external', False))
         update_body = {'router:external': True}
-        resp, body = self.admin_client.update_network(network['id'],
-                                                      **update_body)
-        self.assertEqual('200', resp['status'])
+        _, body = self.admin_client.update_network(network['id'],
+                                                   **update_body)
         updated_network = body['network']
         # Verify that router:external parameter was updated
         self.assertTrue(updated_network['router:external'])
@@ -59,8 +57,7 @@
         # List networks as a normal user and confirm the external
         # network extension attribute is returned for those networks
         # that were created as external
-        resp, body = self.client.list_networks()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_networks()
         networks_list = [net['id'] for net in body['networks']]
         self.assertIn(external_network['id'], networks_list)
         self.assertIn(self.network['id'], networks_list)
@@ -75,14 +72,12 @@
         external_network = self._create_network()
         # Show an external network as a normal user and confirm the
         # external network extension attribute is returned.
-        resp, body = self.client.show_network(external_network['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_network(external_network['id'])
         show_ext_net = body['network']
         self.assertEqual(external_network['name'], show_ext_net['name'])
         self.assertEqual(external_network['id'], show_ext_net['id'])
         self.assertTrue(show_ext_net['router:external'])
-        resp, body = self.client.show_network(self.network['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_network(self.network['id'])
         show_net = body['network']
         # Verify with show that router:external is False for network
         self.assertEqual(self.network['name'], show_net['name'])
diff --git a/tempest/api/network/admin/test_floating_ips_admin_actions.py b/tempest/api/network/admin/test_floating_ips_admin_actions.py
index 5728432..3718cb5 100644
--- a/tempest/api/network/admin/test_floating_ips_admin_actions.py
+++ b/tempest/api/network/admin/test_floating_ips_admin_actions.py
@@ -36,21 +36,18 @@
     @test.attr(type='smoke')
     def test_list_floating_ips_from_admin_and_nonadmin(self):
         # Create floating ip from admin user
-        resp, floating_ip_admin = self.admin_client.create_floatingip(
+        _, floating_ip_admin = self.admin_client.create_floatingip(
             floating_network_id=self.ext_net_id)
-        self.assertEqual('201', resp['status'])
         self.addCleanup(self.admin_client.delete_floatingip,
                         floating_ip_admin['floatingip']['id'])
         # Create floating ip from alt user
-        resp, body = self.alt_client.create_floatingip(
+        _, body = self.alt_client.create_floatingip(
             floating_network_id=self.ext_net_id)
-        self.assertEqual('201', resp['status'])
         floating_ip_alt = body['floatingip']
         self.addCleanup(self.alt_client.delete_floatingip,
                         floating_ip_alt['id'])
         # List floating ips from admin
-        resp, body = self.admin_client.list_floatingips()
-        self.assertEqual('200', resp['status'])
+        _, body = self.admin_client.list_floatingips()
         floating_ip_ids_admin = [f['id'] for f in body['floatingips']]
         # Check that admin sees all floating ips
         self.assertIn(self.floating_ip['id'], floating_ip_ids_admin)
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index 3b05f42..d7de73b 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -52,9 +52,7 @@
 
     @test.attr(type='smoke')
     def test_list_routers_on_l3_agent(self):
-        resp, body = self.admin_client.list_routers_on_l3_agent(
-            self.agent['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.admin_client.list_routers_on_l3_agent(self.agent['id'])
 
     @test.attr(type='smoke')
     def test_add_list_remove_router_on_l3_agent(self):
@@ -62,21 +60,20 @@
         name = data_utils.rand_name('router1-')
         resp, router = self.client.create_router(name)
         self.addCleanup(self.client.delete_router, router['router']['id'])
-        resp, body = self.admin_client.add_router_to_l3_agent(
-            self.agent['id'], router['router']['id'])
-        self.assertEqual('201', resp['status'])
-        resp, body = self.admin_client.list_l3_agents_hosting_router(
+        _, body = self.admin_client.add_router_to_l3_agent(
+            self.agent['id'],
             router['router']['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.admin_client.list_l3_agents_hosting_router(
+            router['router']['id'])
         for agent in body['agents']:
             l3_agent_ids.append(agent['id'])
             self.assertIn('agent_type', agent)
             self.assertEqual('L3 agent', agent['agent_type'])
         self.assertIn(self.agent['id'], l3_agent_ids)
         del l3_agent_ids[:]
-        resp, body = self.admin_client.remove_router_from_l3_agent(
-            self.agent['id'], router['router']['id'])
-        self.assertEqual('204', resp['status'])
+        _, body = self.admin_client.remove_router_from_l3_agent(
+            self.agent['id'],
+            router['router']['id'])
         # NOTE(afazekas): The deletion not asserted, because neutron
         # is not forbidden to reschedule the router to the same agent
 
diff --git a/tempest/api/network/admin/test_lbaas_agent_scheduler.py b/tempest/api/network/admin/test_lbaas_agent_scheduler.py
index 675c62d..d0c31b3 100644
--- a/tempest/api/network/admin/test_lbaas_agent_scheduler.py
+++ b/tempest/api/network/admin/test_lbaas_agent_scheduler.py
@@ -50,17 +50,15 @@
     @test.attr(type='smoke')
     def test_list_pools_on_lbaas_agent(self):
         found = False
-        resp, body = self.admin_client.list_agents(
+        _, body = self.admin_client.list_agents(
             agent_type="Loadbalancer agent")
-        self.assertEqual('200', resp['status'])
         agents = body['agents']
         for a in agents:
             msg = 'Load Balancer agent expected'
             self.assertEqual(a['agent_type'], 'Loadbalancer agent', msg)
-            resp, body = (
+            _, body = (
                 self.admin_client.list_pools_hosted_by_one_lbaas_agent(
                     a['id']))
-            self.assertEqual('200', resp['status'])
             pools = body['pools']
             if self.pool['id'] in [p['id'] for p in pools]:
                 found = True
@@ -69,9 +67,8 @@
 
     @test.attr(type='smoke')
     def test_show_lbaas_agent_hosting_pool(self):
-        resp, body = self.admin_client.show_lbaas_agent_hosting_pool(
+        _, body = self.admin_client.show_lbaas_agent_hosting_pool(
             self.pool['id'])
-        self.assertEqual('200', resp['status'])
         self.assertEqual('Loadbalancer agent', body['agent']['agent_type'])
 
 
diff --git a/tempest/api/network/admin/test_load_balancer_admin_actions.py b/tempest/api/network/admin/test_load_balancer_admin_actions.py
index fe4fc60..a97d275 100644
--- a/tempest/api/network/admin/test_load_balancer_admin_actions.py
+++ b/tempest/api/network/admin/test_load_balancer_admin_actions.py
@@ -47,56 +47,54 @@
     @test.attr(type='smoke')
     def test_create_vip_as_admin_for_another_tenant(self):
         name = data_utils.rand_name('vip-')
-        resp, body = self.admin_client.create_pool(
-            name=data_utils.rand_name('pool-'), lb_method="ROUND_ROBIN",
-            protocol="HTTP", subnet_id=self.subnet['id'],
+        _, body = self.admin_client.create_pool(
+            name=data_utils.rand_name('pool-'),
+            lb_method="ROUND_ROBIN",
+            protocol="HTTP",
+            subnet_id=self.subnet['id'],
             tenant_id=self.tenant_id)
-        self.assertEqual('201', resp['status'])
         pool = body['pool']
         self.addCleanup(self.admin_client.delete_pool, pool['id'])
-        resp, body = self.admin_client.create_vip(name=name,
-                                                  protocol="HTTP",
-                                                  protocol_port=80,
-                                                  subnet_id=self.subnet['id'],
-                                                  pool_id=pool['id'],
-                                                  tenant_id=self.tenant_id)
-        self.assertEqual('201', resp['status'])
+        _, body = self.admin_client.create_vip(name=name,
+                                               protocol="HTTP",
+                                               protocol_port=80,
+                                               subnet_id=self.subnet['id'],
+                                               pool_id=pool['id'],
+                                               tenant_id=self.tenant_id)
         vip = body['vip']
         self.addCleanup(self.admin_client.delete_vip, vip['id'])
         self.assertIsNotNone(vip['id'])
         self.assertEqual(self.tenant_id, vip['tenant_id'])
-        resp, body = self.client.show_vip(vip['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_vip(vip['id'])
         show_vip = body['vip']
         self.assertEqual(vip['id'], show_vip['id'])
         self.assertEqual(vip['name'], show_vip['name'])
 
     @test.attr(type='smoke')
     def test_create_health_monitor_as_admin_for_another_tenant(self):
-        resp, body = (
+        _, body = (
             self.admin_client.create_health_monitor(delay=4,
                                                     max_retries=3,
                                                     type="TCP",
                                                     timeout=1,
                                                     tenant_id=self.tenant_id))
-        self.assertEqual('201', resp['status'])
         health_monitor = body['health_monitor']
         self.addCleanup(self.admin_client.delete_health_monitor,
                         health_monitor['id'])
         self.assertIsNotNone(health_monitor['id'])
         self.assertEqual(self.tenant_id, health_monitor['tenant_id'])
-        resp, body = self.client.show_health_monitor(health_monitor['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_health_monitor(health_monitor['id'])
         show_health_monitor = body['health_monitor']
         self.assertEqual(health_monitor['id'], show_health_monitor['id'])
 
     @test.attr(type='smoke')
     def test_create_pool_from_admin_user_other_tenant(self):
-        resp, body = self.admin_client.create_pool(
-            name=data_utils.rand_name('pool-'), lb_method="ROUND_ROBIN",
-            protocol="HTTP", subnet_id=self.subnet['id'],
+        _, body = self.admin_client.create_pool(
+            name=data_utils.rand_name('pool-'),
+            lb_method="ROUND_ROBIN",
+            protocol="HTTP",
+            subnet_id=self.subnet['id'],
             tenant_id=self.tenant_id)
-        self.assertEqual('201', resp['status'])
         pool = body['pool']
         self.addCleanup(self.admin_client.delete_pool, pool['id'])
         self.assertIsNotNone(pool['id'])
@@ -104,10 +102,10 @@
 
     @test.attr(type='smoke')
     def test_create_member_from_admin_user_other_tenant(self):
-        resp, body = self.admin_client.create_member(
-            address="10.0.9.47", protocol_port=80, pool_id=self.pool['id'],
-            tenant_id=self.tenant_id)
-        self.assertEqual('201', resp['status'])
+        _, body = self.admin_client.create_member(address="10.0.9.47",
+                                                  protocol_port=80,
+                                                  pool_id=self.pool['id'],
+                                                  tenant_id=self.tenant_id)
         member = body['member']
         self.addCleanup(self.admin_client.delete_member, member['id'])
         self.assertIsNotNone(member['id'])
diff --git a/tempest/api/network/admin/test_quotas.py b/tempest/api/network/admin/test_quotas.py
index d1a8faf..9ac97f9 100644
--- a/tempest/api/network/admin/test_quotas.py
+++ b/tempest/api/network/admin/test_quotas.py
@@ -46,8 +46,7 @@
             raise cls.skipException(msg)
         cls.identity_admin_client = cls.os_adm.identity_client
 
-    @test.attr(type='gate')
-    def test_quotas(self):
+    def _check_quotas(self, new_quotas):
         # Add a tenant to conduct the test
         test_tenant = data_utils.rand_name('test_tenant_')
         test_description = data_utils.rand_name('desc_')
@@ -56,79 +55,42 @@
             description=test_description)
         tenant_id = tenant['id']
         self.addCleanup(self.identity_admin_client.delete_tenant, tenant_id)
+
         # Change quotas for tenant
-        new_quotas = {'network': 0, 'security_group': 0}
-        resp, quota_set = self.admin_client.update_quotas(tenant_id,
-                                                          **new_quotas)
-        self.assertEqual('200', resp['status'])
+        _, quota_set = self.admin_client.update_quotas(tenant_id,
+                                                       **new_quotas)
         self.addCleanup(self.admin_client.reset_quotas, tenant_id)
-        self.assertEqual(0, quota_set['network'])
-        self.assertEqual(0, quota_set['security_group'])
+        for key, value in new_quotas.iteritems():
+            self.assertEqual(value, quota_set[key])
+
         # Confirm our tenant is listed among tenants with non default quotas
-        resp, non_default_quotas = self.admin_client.list_quotas()
-        self.assertEqual('200', resp['status'])
+        _, non_default_quotas = self.admin_client.list_quotas()
         found = False
         for qs in non_default_quotas['quotas']:
             if qs['tenant_id'] == tenant_id:
                 found = True
         self.assertTrue(found)
-        # Confirm from APi quotas were changed as requested for tenant
-        resp, quota_set = self.admin_client.show_quotas(tenant_id)
+
+        # Confirm from API quotas were changed as requested for tenant
+        _, quota_set = self.admin_client.show_quotas(tenant_id)
         quota_set = quota_set['quota']
-        self.assertEqual('200', resp['status'])
-        self.assertEqual(0, quota_set['network'])
-        self.assertEqual(0, quota_set['security_group'])
+        for key, value in new_quotas.iteritems():
+            self.assertEqual(value, quota_set[key])
+
         # Reset quotas to default and confirm
-        resp, body = self.admin_client.reset_quotas(tenant_id)
-        self.assertEqual('204', resp['status'])
-        resp, non_default_quotas = self.admin_client.list_quotas()
-        self.assertEqual('200', resp['status'])
+        _, body = self.admin_client.reset_quotas(tenant_id)
+        _, non_default_quotas = self.admin_client.list_quotas()
         for q in non_default_quotas['quotas']:
             self.assertNotEqual(tenant_id, q['tenant_id'])
 
+    @test.attr(type='gate')
+    def test_quotas(self):
+        new_quotas = {'network': 0, 'security_group': 0}
+        self._check_quotas(new_quotas)
+
     @test.requires_ext(extension='lbaas', service='network')
     @test.attr(type='gate')
     def test_lbaas_quotas(self):
-        # Add a tenant to conduct the test
-        test_tenant = data_utils.rand_name('test_tenant_')
-        test_description = data_utils.rand_name('desc_')
-        _, tenant = self.identity_admin_client.create_tenant(
-            name=test_tenant,
-            description=test_description)
-        tenant_id = tenant['id']
-        self.addCleanup(self.identity_admin_client.delete_tenant, tenant_id)
-        # Change lbaas quotas for tenant
         new_quotas = {'vip': 1, 'pool': 2,
                       'member': 3, 'health_monitor': 4}
-
-        resp, quota_set = self.admin_client.update_quotas(tenant_id,
-                                                          **new_quotas)
-        self.assertEqual('200', resp['status'])
-        self.addCleanup(self.admin_client.reset_quotas, tenant_id)
-        self.assertEqual(1, quota_set['vip'])
-        self.assertEqual(2, quota_set['pool'])
-        self.assertEqual(3, quota_set['member'])
-        self.assertEqual(4, quota_set['health_monitor'])
-        # Confirm our tenant is listed among tenants with non default quotas
-        resp, non_default_quotas = self.admin_client.list_quotas()
-        self.assertEqual('200', resp['status'])
-        found = False
-        for qs in non_default_quotas['quotas']:
-            if qs['tenant_id'] == tenant_id:
-                found = True
-        self.assertTrue(found)
-        # Confirm from APi quotas were changed as requested for tenant
-        resp, quota_set = self.admin_client.show_quotas(tenant_id)
-        quota_set = quota_set['quota']
-        self.assertEqual('200', resp['status'])
-        self.assertEqual(1, quota_set['vip'])
-        self.assertEqual(2, quota_set['pool'])
-        self.assertEqual(3, quota_set['member'])
-        self.assertEqual(4, quota_set['health_monitor'])
-        # Reset quotas to default and confirm
-        resp, body = self.admin_client.reset_quotas(tenant_id)
-        self.assertEqual('204', resp['status'])
-        resp, non_default_quotas = self.admin_client.list_quotas()
-        self.assertEqual('200', resp['status'])
-        for q in non_default_quotas['quotas']:
-            self.assertNotEqual(tenant_id, q['tenant_id'])
+        self._check_quotas(new_quotas)
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 087b87a..1a23cb6 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -49,6 +49,7 @@
         neutron as True
     """
 
+    _interface = 'json'
     force_tenant_isolation = False
 
     # Default to ipv4.
@@ -85,57 +86,58 @@
 
     @classmethod
     def tearDownClass(cls):
-        # Clean up ipsec policies
-        for ipsecpolicy in cls.ipsecpolicies:
-            cls.client.delete_ipsecpolicy(ipsecpolicy['id'])
-        # Clean up firewall policies
-        for fw_policy in cls.fw_policies:
-            cls.client.delete_firewall_policy(fw_policy['id'])
-        # Clean up firewall rules
-        for fw_rule in cls.fw_rules:
-            cls.client.delete_firewall_rule(fw_rule['id'])
-        # Clean up ike policies
-        for ikepolicy in cls.ikepolicies:
-            cls.client.delete_ikepolicy(ikepolicy['id'])
-        # Clean up vpn services
-        for vpnservice in cls.vpnservices:
-            cls.client.delete_vpnservice(vpnservice['id'])
-        # Clean up floating IPs
-        for floating_ip in cls.floating_ips:
-            cls.client.delete_floatingip(floating_ip['id'])
-        # Clean up routers
-        for router in cls.routers:
-            cls.delete_router(router)
+        if CONF.service_available.neutron:
+            # Clean up ipsec policies
+            for ipsecpolicy in cls.ipsecpolicies:
+                cls.client.delete_ipsecpolicy(ipsecpolicy['id'])
+            # Clean up firewall policies
+            for fw_policy in cls.fw_policies:
+                cls.client.delete_firewall_policy(fw_policy['id'])
+            # Clean up firewall rules
+            for fw_rule in cls.fw_rules:
+                cls.client.delete_firewall_rule(fw_rule['id'])
+            # Clean up ike policies
+            for ikepolicy in cls.ikepolicies:
+                cls.client.delete_ikepolicy(ikepolicy['id'])
+            # Clean up vpn services
+            for vpnservice in cls.vpnservices:
+                cls.client.delete_vpnservice(vpnservice['id'])
+            # Clean up floating IPs
+            for floating_ip in cls.floating_ips:
+                cls.client.delete_floatingip(floating_ip['id'])
+            # Clean up routers
+            for router in cls.routers:
+                cls.delete_router(router)
 
-        # Clean up health monitors
-        for health_monitor in cls.health_monitors:
-            cls.client.delete_health_monitor(health_monitor['id'])
-        # Clean up members
-        for member in cls.members:
-            cls.client.delete_member(member['id'])
-        # Clean up vips
-        for vip in cls.vips:
-            cls.client.delete_vip(vip['id'])
-        # Clean up pools
-        for pool in cls.pools:
-            cls.client.delete_pool(pool['id'])
-        # Clean up metering label rules
-        for metering_label_rule in cls.metering_label_rules:
-            cls.admin_client.delete_metering_label_rule(
-                metering_label_rule['id'])
-        # Clean up metering labels
-        for metering_label in cls.metering_labels:
-            cls.admin_client.delete_metering_label(metering_label['id'])
-        # Clean up ports
-        for port in cls.ports:
-            cls.client.delete_port(port['id'])
-        # Clean up subnets
-        for subnet in cls.subnets:
-            cls.client.delete_subnet(subnet['id'])
-        # Clean up networks
-        for network in cls.networks:
-            cls.client.delete_network(network['id'])
-        cls.clear_isolated_creds()
+            # Clean up health monitors
+            for health_monitor in cls.health_monitors:
+                cls.client.delete_health_monitor(health_monitor['id'])
+            # Clean up members
+            for member in cls.members:
+                cls.client.delete_member(member['id'])
+            # Clean up vips
+            for vip in cls.vips:
+                cls.client.delete_vip(vip['id'])
+            # Clean up pools
+            for pool in cls.pools:
+                cls.client.delete_pool(pool['id'])
+            # Clean up metering label rules
+            for metering_label_rule in cls.metering_label_rules:
+                cls.admin_client.delete_metering_label_rule(
+                    metering_label_rule['id'])
+            # Clean up metering labels
+            for metering_label in cls.metering_labels:
+                cls.admin_client.delete_metering_label(metering_label['id'])
+            # Clean up ports
+            for port in cls.ports:
+                cls.client.delete_port(port['id'])
+            # Clean up subnets
+            for subnet in cls.subnets:
+                cls.client.delete_subnet(subnet['id'])
+            # Clean up networks
+            for network in cls.networks:
+                cls.client.delete_network(network['id'])
+            cls.clear_isolated_creds()
         super(BaseNetworkTest, cls).tearDownClass()
 
     @classmethod
diff --git a/tempest/api/network/base_routers.py b/tempest/api/network/base_routers.py
index 1303bcf..f69e6fd 100644
--- a/tempest/api/network/base_routers.py
+++ b/tempest/api/network/base_routers.py
@@ -26,34 +26,29 @@
         super(BaseRouterTest, cls).setUpClass()
 
     def _delete_router(self, router_id):
-        resp, _ = self.client.delete_router(router_id)
-        self.assertEqual(204, resp.status)
+        self.client.delete_router(router_id)
         # Asserting that the router is not found in the list
         # after deletion
-        resp, list_body = self.client.list_routers()
-        self.assertEqual('200', resp['status'])
+        _, list_body = self.client.list_routers()
         routers_list = list()
         for router in list_body['routers']:
             routers_list.append(router['id'])
         self.assertNotIn(router_id, routers_list)
 
     def _add_router_interface_with_subnet_id(self, router_id, subnet_id):
-        resp, interface = self.client.add_router_interface_with_subnet_id(
+        _, interface = self.client.add_router_interface_with_subnet_id(
             router_id, subnet_id)
-        self.assertEqual('200', resp['status'])
         self.addCleanup(self._remove_router_interface_with_subnet_id,
                         router_id, subnet_id)
         self.assertEqual(subnet_id, interface['subnet_id'])
         return interface
 
     def _remove_router_interface_with_subnet_id(self, router_id, subnet_id):
-        resp, body = self.client.remove_router_interface_with_subnet_id(
+        _, body = self.client.remove_router_interface_with_subnet_id(
             router_id, subnet_id)
-        self.assertEqual('200', resp['status'])
         self.assertEqual(subnet_id, body['subnet_id'])
 
     def _remove_router_interface_with_port_id(self, router_id, port_id):
-        resp, body = self.client.remove_router_interface_with_port_id(
-            router_id, port_id)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.remove_router_interface_with_port_id(router_id,
+                                                                   port_id)
         self.assertEqual(port_id, body['port_id'])
diff --git a/tempest/api/network/base_security_groups.py b/tempest/api/network/base_security_groups.py
index 90be454..c2af2f2 100644
--- a/tempest/api/network/base_security_groups.py
+++ b/tempest/api/network/base_security_groups.py
@@ -26,32 +26,27 @@
     def _create_security_group(self):
         # Create a security group
         name = data_utils.rand_name('secgroup-')
-        resp, group_create_body = self.client.create_security_group(name=name)
-        self.assertEqual('201', resp['status'])
+        _, group_create_body = self.client.create_security_group(name=name)
         self.addCleanup(self._delete_security_group,
                         group_create_body['security_group']['id'])
         self.assertEqual(group_create_body['security_group']['name'], name)
         return group_create_body, name
 
     def _delete_security_group(self, secgroup_id):
-        resp, _ = self.client.delete_security_group(secgroup_id)
-        self.assertEqual(204, resp.status)
+        self.client.delete_security_group(secgroup_id)
         # Asserting that the security group is not found in the list
         # after deletion
-        resp, list_body = self.client.list_security_groups()
-        self.assertEqual('200', resp['status'])
+        _, list_body = self.client.list_security_groups()
         secgroup_list = list()
         for secgroup in list_body['security_groups']:
             secgroup_list.append(secgroup['id'])
         self.assertNotIn(secgroup_id, secgroup_list)
 
     def _delete_security_group_rule(self, rule_id):
-        resp, _ = self.client.delete_security_group_rule(rule_id)
-        self.assertEqual(204, resp.status)
+        self.client.delete_security_group_rule(rule_id)
         # Asserting that the security group is not found in the list
         # after deletion
-        resp, list_body = self.client.list_security_group_rules()
-        self.assertEqual('200', resp['status'])
+        _, list_body = self.client.list_security_group_rules()
         rules_list = list()
         for rule in list_body['security_group_rules']:
             rules_list.append(rule['id'])
diff --git a/tempest/api/network/common.py b/tempest/api/network/common.py
index 97e120f..5ac8b5a 100644
--- a/tempest/api/network/common.py
+++ b/tempest/api/network/common.py
@@ -13,6 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import abc
+
+import six
+
 
 class AttributeDict(dict):
 
@@ -27,6 +31,7 @@
         return super(AttributeDict, self).__getattribute__(name)
 
 
+@six.add_metaclass(abc.ABCMeta)
 class DeletableResource(AttributeDict):
 
     """
@@ -42,8 +47,9 @@
         return '<%s id="%s" name="%s">' % (self.__class__.__name__,
                                            self.id, self.name)
 
+    @abc.abstractmethod
     def delete(self):
-        raise NotImplemented()
+        return
 
     def __hash__(self):
         return id(self)
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index c897716..86acc71 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -54,16 +54,14 @@
         # Create port with allowed address pair attribute
         allowed_address_pairs = [{'ip_address': self.ip_address,
                                   'mac_address': self.mac_address}]
-        resp, body = self.client.create_port(
+        _, body = self.client.create_port(
             network_id=self.network['id'],
             allowed_address_pairs=allowed_address_pairs)
-        self.assertEqual('201', resp['status'])
         port_id = body['port']['id']
         self.addCleanup(self.client.delete_port, port_id)
 
         # Confirm port was created with allowed address pair attribute
-        resp, body = self.client.list_ports()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_ports()
         ports = body['ports']
         port = [p for p in ports if p['id'] == port_id]
         msg = 'Created port not found in list of ports returned by Neutron'
@@ -73,21 +71,18 @@
     @test.attr(type='smoke')
     def test_update_port_with_address_pair(self):
         # Create a port without allowed address pair
-        resp, body = self.client.create_port(network_id=self.network['id'])
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_port(network_id=self.network['id'])
         port_id = body['port']['id']
         self.addCleanup(self.client.delete_port, port_id)
 
         # Confirm  port is created
-        resp, body = self.client.show_port(port_id)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_port(port_id)
 
         # Update allowed address pair attribute of port
         allowed_address_pairs = [{'ip_address': self.ip_address,
                                   'mac_address': self.mac_address}]
-        resp, body = self.client.update_port(port_id,
-                          allowed_address_pairs=allowed_address_pairs)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_port(
+            port_id, allowed_address_pairs=allowed_address_pairs)
         newport = body['port']
         self._confirm_allowed_address_pair(newport, self.ip_address)
 
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
index 529f8e9..c3607c8 100644
--- a/tempest/api/network/test_extensions.py
+++ b/tempest/api/network/test_extensions.py
@@ -47,16 +47,14 @@
         expected_alias = [ext for ext in expected_alias if
                           test.is_extension_enabled(ext, 'network')]
         actual_alias = list()
-        resp, extensions = self.client.list_extensions()
-        self.assertEqual('200', resp['status'])
+        _, extensions = self.client.list_extensions()
         list_extensions = extensions['extensions']
         # Show and verify the details of the available extensions
         for ext in list_extensions:
             ext_name = ext['name']
             ext_alias = ext['alias']
             actual_alias.append(ext['alias'])
-            resp, ext_details = self.client.show_extension(ext_alias)
-            self.assertEqual('200', resp['status'])
+            _, ext_details = self.client.show_extension(ext_alias)
             ext_details = ext_details['extension']
 
             self.assertIsNotNone(ext_details)
diff --git a/tempest/api/network/test_extra_dhcp_options.py b/tempest/api/network/test_extra_dhcp_options.py
index 371c651..82ebc5a 100644
--- a/tempest/api/network/test_extra_dhcp_options.py
+++ b/tempest/api/network/test_extra_dhcp_options.py
@@ -54,16 +54,13 @@
             {'opt_value': '123.123.123.123', 'opt_name': 'tftp-server'},
             {'opt_value': '123.123.123.45', 'opt_name': 'server-ip-address'}
         ]
-        resp, body = self.client.create_port(
-            network_id=self.network['id'],
-            extra_dhcp_opts=extra_dhcp_opts)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_port(network_id=self.network['id'],
+                                          extra_dhcp_opts=extra_dhcp_opts)
         port_id = body['port']['id']
         self.addCleanup(self.client.delete_port, port_id)
 
         # Confirm port created has Extra DHCP Options
-        resp, body = self.client.list_ports()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_ports()
         ports = body['ports']
         port = [p for p in ports if p['id'] == port_id]
         self.assertTrue(port)
@@ -78,13 +75,11 @@
             {'opt_value': '123.123.123.45', 'opt_name': 'server-ip-address'}
         ]
         name = data_utils.rand_name('new-port-name')
-        resp, body = self.client.update_port(
-            self.port['id'], name=name, extra_dhcp_opts=extra_dhcp_opts)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_port(self.port['id'], name=name,
+                                          extra_dhcp_opts=extra_dhcp_opts)
 
         # Confirm extra dhcp options were added to the port
-        resp, body = self.client.show_port(self.port['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_port(self.port['id'])
         self._confirm_extra_dhcp_options(body['port'], extra_dhcp_opts)
 
     def _confirm_extra_dhcp_options(self, port, extra_dhcp_opts):
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index 2463654..8b42a9e 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -68,9 +68,9 @@
     @test.attr(type='smoke')
     def test_create_list_show_update_delete_floating_ip(self):
         # Creates a floating IP
-        resp, body = self.client.create_floatingip(
-            floating_network_id=self.ext_net_id, port_id=self.ports[0]['id'])
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_floatingip(
+            floating_network_id=self.ext_net_id,
+            port_id=self.ports[0]['id'])
         created_floating_ip = body['floatingip']
         self.addCleanup(self.client.delete_floatingip,
                         created_floating_ip['id'])
@@ -83,9 +83,7 @@
         self.assertIn(created_floating_ip['fixed_ip_address'],
                       [ip['ip_address'] for ip in self.ports[0]['fixed_ips']])
         # Verifies the details of a floating_ip
-        resp, floating_ip = self.client.show_floatingip(
-            created_floating_ip['id'])
-        self.assertEqual('200', resp['status'])
+        _, floating_ip = self.client.show_floatingip(created_floating_ip['id'])
         shown_floating_ip = floating_ip['floatingip']
         self.assertEqual(shown_floating_ip['id'], created_floating_ip['id'])
         self.assertEqual(shown_floating_ip['floating_network_id'],
@@ -97,16 +95,15 @@
         self.assertEqual(shown_floating_ip['port_id'], self.ports[0]['id'])
 
         # Verify the floating ip exists in the list of all floating_ips
-        resp, floating_ips = self.client.list_floatingips()
-        self.assertEqual('200', resp['status'])
+        _, floating_ips = self.client.list_floatingips()
         floatingip_id_list = list()
         for f in floating_ips['floatingips']:
             floatingip_id_list.append(f['id'])
         self.assertIn(created_floating_ip['id'], floatingip_id_list)
         # Associate floating IP to the other port
-        resp, floating_ip = self.client.update_floatingip(
-            created_floating_ip['id'], port_id=self.ports[1]['id'])
-        self.assertEqual('200', resp['status'])
+        _, floating_ip = self.client.update_floatingip(
+            created_floating_ip['id'],
+            port_id=self.ports[1]['id'])
         updated_floating_ip = floating_ip['floatingip']
         self.assertEqual(updated_floating_ip['port_id'], self.ports[1]['id'])
         self.assertEqual(updated_floating_ip['fixed_ip_address'],
@@ -114,9 +111,9 @@
         self.assertEqual(updated_floating_ip['router_id'], self.router['id'])
 
         # Disassociate floating IP from the port
-        resp, floating_ip = self.client.update_floatingip(
-            created_floating_ip['id'], port_id=None)
-        self.assertEqual('200', resp['status'])
+        _, floating_ip = self.client.update_floatingip(
+            created_floating_ip['id'],
+            port_id=None)
         updated_floating_ip = floating_ip['floatingip']
         self.assertIsNone(updated_floating_ip['port_id'])
         self.assertIsNone(updated_floating_ip['fixed_ip_address'])
@@ -125,24 +122,21 @@
     @test.attr(type='smoke')
     def test_floating_ip_delete_port(self):
         # Create a floating IP
-        resp, body = self.client.create_floatingip(
+        _, body = self.client.create_floatingip(
             floating_network_id=self.ext_net_id)
-        self.assertEqual('201', resp['status'])
         created_floating_ip = body['floatingip']
         self.addCleanup(self.client.delete_floatingip,
                         created_floating_ip['id'])
         # Create a port
         resp, port = self.client.create_port(network_id=self.network['id'])
         created_port = port['port']
-        resp, floating_ip = self.client.update_floatingip(
-            created_floating_ip['id'], port_id=created_port['id'])
-        self.assertEqual('200', resp['status'])
+        _, floating_ip = self.client.update_floatingip(
+            created_floating_ip['id'],
+            port_id=created_port['id'])
         # Delete port
         self.client.delete_port(created_port['id'])
         # Verifies the details of the floating_ip
-        resp, floating_ip = self.client.show_floatingip(
-            created_floating_ip['id'])
-        self.assertEqual('200', resp['status'])
+        _, floating_ip = self.client.show_floatingip(created_floating_ip['id'])
         shown_floating_ip = floating_ip['floatingip']
         # Confirm the fields are back to None
         self.assertEqual(shown_floating_ip['id'], created_floating_ip['id'])
@@ -153,9 +147,9 @@
     @test.attr(type='smoke')
     def test_floating_ip_update_different_router(self):
         # Associate a floating IP to a port on a router
-        resp, body = self.client.create_floatingip(
-            floating_network_id=self.ext_net_id, port_id=self.ports[1]['id'])
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_floatingip(
+            floating_network_id=self.ext_net_id,
+            port_id=self.ports[1]['id'])
         created_floating_ip = body['floatingip']
         self.addCleanup(self.client.delete_floatingip,
                         created_floating_ip['id'])
@@ -167,9 +161,9 @@
         self.create_router_interface(router2['id'], subnet2['id'])
         port_other_router = self.create_port(network2)
         # Associate floating IP to the other port on another router
-        resp, floating_ip = self.client.update_floatingip(
-            created_floating_ip['id'], port_id=port_other_router['id'])
-        self.assertEqual('200', resp['status'])
+        _, floating_ip = self.client.update_floatingip(
+            created_floating_ip['id'],
+            port_id=port_other_router['id'])
         updated_floating_ip = floating_ip['floatingip']
         self.assertEqual(updated_floating_ip['router_id'], router2['id'])
         self.assertEqual(updated_floating_ip['port_id'],
@@ -178,20 +172,19 @@
 
     @test.attr(type='smoke')
     def test_create_floating_ip_specifying_a_fixed_ip_address(self):
-        resp, body = self.client.create_floatingip(
+        _, body = self.client.create_floatingip(
             floating_network_id=self.ext_net_id,
             port_id=self.ports[1]['id'],
             fixed_ip_address=self.ports[1]['fixed_ips'][0]['ip_address'])
-        self.assertEqual('201', resp['status'])
         created_floating_ip = body['floatingip']
         self.addCleanup(self.client.delete_floatingip,
                         created_floating_ip['id'])
         self.assertIsNotNone(created_floating_ip['id'])
         self.assertEqual(created_floating_ip['fixed_ip_address'],
                          self.ports[1]['fixed_ips'][0]['ip_address'])
-        resp, floating_ip = self.client.update_floatingip(
-            created_floating_ip['id'], port_id=None)
-        self.assertEqual('200', resp['status'])
+        _, floating_ip = self.client.update_floatingip(
+            created_floating_ip['id'],
+            port_id=None)
         self.assertIsNone(floating_ip['floatingip']['port_id'])
 
     @test.attr(type='smoke')
@@ -201,25 +194,23 @@
         list_ips = [str(ip) for ip in ips[-3:-1]]
         fixed_ips = [{'ip_address': list_ips[0]}, {'ip_address': list_ips[1]}]
         # Create port
-        resp, body = self.client.create_port(network_id=self.network['id'],
-                                             fixed_ips=fixed_ips)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_port(network_id=self.network['id'],
+                                          fixed_ips=fixed_ips)
         port = body['port']
         self.addCleanup(self.client.delete_port, port['id'])
         # Create floating ip
-        resp, body = self.client.create_floatingip(
-            floating_network_id=self.ext_net_id, port_id=port['id'],
+        _, body = self.client.create_floatingip(
+            floating_network_id=self.ext_net_id,
+            port_id=port['id'],
             fixed_ip_address=list_ips[0])
-        self.assertEqual('201', resp['status'])
         floating_ip = body['floatingip']
         self.addCleanup(self.client.delete_floatingip, floating_ip['id'])
         self.assertIsNotNone(floating_ip['id'])
         self.assertEqual(floating_ip['fixed_ip_address'], list_ips[0])
         # Update floating ip
-        resp, body = self.client.update_floatingip(
-            floating_ip['id'], port_id=port['id'],
-            fixed_ip_address=list_ips[1])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_floatingip(floating_ip['id'],
+                                                port_id=port['id'],
+                                                fixed_ip_address=list_ips[1])
         update_floating_ip = body['floatingip']
         self.assertEqual(update_floating_ip['fixed_ip_address'],
                          list_ips[1])
diff --git a/tempest/api/network/test_fwaas_extensions.py b/tempest/api/network/test_fwaas_extensions.py
index 555cbda..6eec79e 100644
--- a/tempest/api/network/test_fwaas_extensions.py
+++ b/tempest/api/network/test_fwaas_extensions.py
@@ -74,8 +74,7 @@
 
     def _wait_for_active(self, fw_id):
         def _wait():
-            resp, firewall = self.client.show_firewall(fw_id)
-            self.assertEqual('200', resp['status'])
+            _, firewall = self.client.show_firewall(fw_id)
             firewall = firewall['firewall']
             return firewall['status'] == 'ACTIVE'
 
@@ -87,8 +86,7 @@
     @test.attr(type='smoke')
     def test_list_firewall_rules(self):
         # List firewall rules
-        resp, fw_rules = self.client.list_firewall_rules()
-        self.assertEqual('200', resp['status'])
+        _, fw_rules = self.client.list_firewall_rules()
         fw_rules = fw_rules['firewall_rules']
         self.assertIn((self.fw_rule['id'],
                        self.fw_rule['name'],
@@ -106,22 +104,19 @@
     @test.attr(type='smoke')
     def test_create_update_delete_firewall_rule(self):
         # Create firewall rule
-        resp, body = self.client.create_firewall_rule(
+        _, body = self.client.create_firewall_rule(
             name=data_utils.rand_name("fw-rule"),
             action="allow",
             protocol="tcp")
-        self.assertEqual('201', resp['status'])
         fw_rule_id = body['firewall_rule']['id']
 
         # Update firewall rule
-        resp, body = self.client.update_firewall_rule(fw_rule_id,
-                                                      shared=True)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_firewall_rule(fw_rule_id,
+                                                   shared=True)
         self.assertTrue(body["firewall_rule"]['shared'])
 
         # Delete firewall rule
-        resp, _ = self.client.delete_firewall_rule(fw_rule_id)
-        self.assertEqual('204', resp['status'])
+        self.client.delete_firewall_rule(fw_rule_id)
         # Confirm deletion
         resp, fw_rules = self.client.list_firewall_rules()
         self.assertNotIn(fw_rule_id,
@@ -130,15 +125,13 @@
     @test.attr(type='smoke')
     def test_show_firewall_rule(self):
         # show a created firewall rule
-        resp, fw_rule = self.client.show_firewall_rule(self.fw_rule['id'])
-        self.assertEqual('200', resp['status'])
+        _, fw_rule = self.client.show_firewall_rule(self.fw_rule['id'])
         for key, value in fw_rule['firewall_rule'].iteritems():
             self.assertEqual(self.fw_rule[key], value)
 
     @test.attr(type='smoke')
     def test_list_firewall_policies(self):
-        resp, fw_policies = self.client.list_firewall_policies()
-        self.assertEqual('200', resp['status'])
+        _, fw_policies = self.client.list_firewall_policies()
         fw_policies = fw_policies['firewall_policies']
         self.assertIn((self.fw_policy['id'],
                        self.fw_policy['name'],
@@ -150,24 +143,21 @@
     @test.attr(type='smoke')
     def test_create_update_delete_firewall_policy(self):
         # Create firewall policy
-        resp, body = self.client.create_firewall_policy(
+        _, body = self.client.create_firewall_policy(
             name=data_utils.rand_name("fw-policy"))
-        self.assertEqual('201', resp['status'])
         fw_policy_id = body['firewall_policy']['id']
         self.addCleanup(self._try_delete_policy, fw_policy_id)
 
         # Update firewall policy
-        resp, body = self.client.update_firewall_policy(fw_policy_id,
-                                                        shared=True,
-                                                        name="updated_policy")
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_firewall_policy(fw_policy_id,
+                                                     shared=True,
+                                                     name="updated_policy")
         updated_fw_policy = body["firewall_policy"]
         self.assertTrue(updated_fw_policy['shared'])
         self.assertEqual("updated_policy", updated_fw_policy['name'])
 
         # Delete firewall policy
-        resp, _ = self.client.delete_firewall_policy(fw_policy_id)
-        self.assertEqual('204', resp['status'])
+        self.client.delete_firewall_policy(fw_policy_id)
         # Confirm deletion
         resp, fw_policies = self.client.list_firewall_policies()
         fw_policies = fw_policies['firewall_policies']
@@ -176,9 +166,7 @@
     @test.attr(type='smoke')
     def test_show_firewall_policy(self):
         # show a created firewall policy
-        resp, fw_policy = self.client.show_firewall_policy(
-            self.fw_policy['id'])
-        self.assertEqual('200', resp['status'])
+        _, fw_policy = self.client.show_firewall_policy(self.fw_policy['id'])
         fw_policy = fw_policy['firewall_policy']
         for key, value in fw_policy.iteritems():
             self.assertEqual(self.fw_policy[key], value)
@@ -195,10 +183,9 @@
             router['id'], subnet['id'])
 
         # Create firewall
-        resp, body = self.client.create_firewall(
+        _, body = self.client.create_firewall(
             name=data_utils.rand_name("firewall"),
             firewall_policy_id=self.fw_policy['id'])
-        self.assertEqual('201', resp['status'])
         created_firewall = body['firewall']
         firewall_id = created_firewall['id']
         self.addCleanup(self._try_delete_firewall, firewall_id)
@@ -206,8 +193,7 @@
         self._wait_for_active(firewall_id)
 
         # show a created firewall
-        resp, firewall = self.client.show_firewall(firewall_id)
-        self.assertEqual('200', resp['status'])
+        _, firewall = self.client.show_firewall(firewall_id)
         firewall = firewall['firewall']
 
         for key, value in firewall.iteritems():
@@ -216,8 +202,7 @@
             self.assertEqual(created_firewall[key], value)
 
         # list firewall
-        resp, firewalls = self.client.list_firewalls()
-        self.assertEqual('200', resp['status'])
+        _, firewalls = self.client.list_firewalls()
         firewalls = firewalls['firewalls']
         self.assertIn((created_firewall['id'],
                        created_firewall['name'],
@@ -227,8 +212,7 @@
                         m['firewall_policy_id']) for m in firewalls])
 
         # Delete firewall
-        resp, _ = self.client.delete_firewall(firewall_id)
-        self.assertEqual('204', resp['status'])
+        self.client.delete_firewall(firewall_id)
 
 
 class FWaaSExtensionTestXML(FWaaSExtensionTestJSON):
diff --git a/tempest/api/network/test_load_balancer.py b/tempest/api/network/test_load_balancer.py
index db24e0d..e3109ea 100644
--- a/tempest/api/network/test_load_balancer.py
+++ b/tempest/api/network/test_load_balancer.py
@@ -67,34 +67,31 @@
         delete_obj = getattr(self.client, 'delete_' + obj_name)
         list_objs = getattr(self.client, 'list_' + obj_name + 's')
 
-        resp, body = create_obj(**kwargs)
-        self.assertEqual('201', resp['status'])
+        _, body = create_obj(**kwargs)
         obj = body[obj_name]
         self.addCleanup(delete_obj, obj['id'])
         for key, value in obj.iteritems():
             # It is not relevant to filter by all arguments. That is why
             # there is a list of attr to except
             if key not in attr_exceptions:
-                resp, body = list_objs(**{key: value})
-                self.assertEqual('200', resp['status'])
+                _, body = list_objs(**{key: value})
                 objs = [v[key] for v in body[obj_name + 's']]
                 self.assertIn(value, objs)
 
     @test.attr(type='smoke')
     def test_list_vips(self):
         # Verify the vIP exists in the list of all vIPs
-        resp, body = self.client.list_vips()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_vips()
         vips = body['vips']
         self.assertIn(self.vip['id'], [v['id'] for v in vips])
 
     @test.attr(type='smoke')
     def test_list_vips_with_filter(self):
         name = data_utils.rand_name('vip-')
-        resp, body = self.client.create_pool(
-            name=data_utils.rand_name("pool-"), lb_method="ROUND_ROBIN",
-            protocol="HTTPS", subnet_id=self.subnet['id'])
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_pool(name=data_utils.rand_name("pool-"),
+                                          lb_method="ROUND_ROBIN",
+                                          protocol="HTTPS",
+                                          subnet_id=self.subnet['id'])
         pool = body['pool']
         self.addCleanup(self.client.delete_pool, pool['id'])
         attr_exceptions = ['status', 'session_persistence',
@@ -116,18 +113,16 @@
             protocol='HTTP',
             subnet_id=self.subnet['id'])
         pool = body['pool']
-        resp, body = self.client.create_vip(name=name,
-                                            protocol="HTTP",
-                                            protocol_port=80,
-                                            subnet_id=self.subnet['id'],
-                                            pool_id=pool['id'],
-                                            address=address)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_vip(name=name,
+                                         protocol="HTTP",
+                                         protocol_port=80,
+                                         subnet_id=self.subnet['id'],
+                                         pool_id=pool['id'],
+                                         address=address)
         vip = body['vip']
         vip_id = vip['id']
         # Confirm VIP's address correctness with a show
-        resp, body = self.client.show_vip(vip_id)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_vip(vip_id)
         vip = body['vip']
         self.assertEqual(address, vip['address'])
         # Verification of vip update
@@ -136,13 +131,12 @@
         persistence_type = "HTTP_COOKIE"
         update_data = {"session_persistence": {
             "type": persistence_type}}
-        resp, body = self.client.update_vip(vip_id,
-                                            name=new_name,
-                                            description=new_description,
-                                            connection_limit=10,
-                                            admin_state_up=False,
-                                            **update_data)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_vip(vip_id,
+                                         name=new_name,
+                                         description=new_description,
+                                         connection_limit=10,
+                                         admin_state_up=False,
+                                         **update_data)
         updated_vip = body['vip']
         self.assertEqual(new_name, updated_vip['name'])
         self.assertEqual(new_description, updated_vip['description'])
@@ -150,30 +144,24 @@
         self.assertFalse(updated_vip['admin_state_up'])
         self.assertEqual(persistence_type,
                          updated_vip['session_persistence']['type'])
-        # Verification of vip delete
-        resp, body = self.client.delete_vip(vip['id'])
-        self.assertEqual('204', resp['status'])
+        self.client.delete_vip(vip['id'])
         self.client.wait_for_resource_deletion('vip', vip['id'])
         # Verification of pool update
         new_name = "New_pool"
-        resp, body = self.client.update_pool(pool['id'],
-                                             name=new_name,
-                                             description="new_description",
-                                             lb_method='LEAST_CONNECTIONS')
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_pool(pool['id'],
+                                          name=new_name,
+                                          description="new_description",
+                                          lb_method='LEAST_CONNECTIONS')
         updated_pool = body['pool']
         self.assertEqual(new_name, updated_pool['name'])
         self.assertEqual('new_description', updated_pool['description'])
         self.assertEqual('LEAST_CONNECTIONS', updated_pool['lb_method'])
-        # Verification of pool delete
-        resp, body = self.client.delete_pool(pool['id'])
-        self.assertEqual('204', resp['status'])
+        self.client.delete_pool(pool['id'])
 
     @test.attr(type='smoke')
     def test_show_vip(self):
         # Verifies the details of a vip
-        resp, body = self.client.show_vip(self.vip['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_vip(self.vip['id'])
         vip = body['vip']
         for key, value in vip.iteritems():
             # 'status' should not be confirmed in api tests
@@ -183,17 +171,14 @@
     @test.attr(type='smoke')
     def test_show_pool(self):
         # Here we need to new pool without any dependence with vips
-        resp, body = self.client.create_pool(
-            name=data_utils.rand_name("pool-"),
-            lb_method='ROUND_ROBIN',
-            protocol='HTTP',
-            subnet_id=self.subnet['id'])
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_pool(name=data_utils.rand_name("pool-"),
+                                          lb_method='ROUND_ROBIN',
+                                          protocol='HTTP',
+                                          subnet_id=self.subnet['id'])
         pool = body['pool']
         self.addCleanup(self.client.delete_pool, pool['id'])
         # Verifies the details of a pool
-        resp, body = self.client.show_pool(pool['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_pool(pool['id'])
         shown_pool = body['pool']
         for key, value in pool.iteritems():
             # 'status' should not be confirmed in api tests
@@ -203,8 +188,7 @@
     @test.attr(type='smoke')
     def test_list_pools(self):
         # Verify the pool exists in the list of all pools
-        resp, body = self.client.list_pools()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_pools()
         pools = body['pools']
         self.assertIn(self.pool['id'], [p['id'] for p in pools])
 
@@ -222,8 +206,7 @@
     @test.attr(type='smoke')
     def test_list_members(self):
         # Verify the member exists in the list of all members
-        resp, body = self.client.list_members()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_members()
         members = body['members']
         self.assertIn(self.member['id'], [m['id'] for m in members])
 
@@ -237,26 +220,22 @@
     @test.attr(type='smoke')
     def test_create_update_delete_member(self):
         # Creates a member
-        resp, body = self.client.create_member(address="10.0.9.47",
-                                               protocol_port=80,
-                                               pool_id=self.pool['id'])
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_member(address="10.0.9.47",
+                                            protocol_port=80,
+                                            pool_id=self.pool['id'])
         member = body['member']
         # Verification of member update
-        resp, body = self.client.update_member(member['id'],
-                                               admin_state_up=False)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_member(member['id'],
+                                            admin_state_up=False)
         updated_member = body['member']
         self.assertFalse(updated_member['admin_state_up'])
         # Verification of member delete
-        resp, body = self.client.delete_member(member['id'])
-        self.assertEqual('204', resp['status'])
+        self.client.delete_member(member['id'])
 
     @test.attr(type='smoke')
     def test_show_member(self):
         # Verifies the details of a member
-        resp, body = self.client.show_member(self.member['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_member(self.member['id'])
         member = body['member']
         for key, value in member.iteritems():
             # 'status' should not be confirmed in api tests
@@ -266,8 +245,7 @@
     @test.attr(type='smoke')
     def test_list_health_monitors(self):
         # Verify the health monitor exists in the list of all health monitors
-        resp, body = self.client.list_health_monitors()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_health_monitors()
         health_monitors = body['health_monitors']
         self.assertIn(self.health_monitor['id'],
                       [h['id'] for h in health_monitors])
@@ -282,31 +260,27 @@
     @test.attr(type='smoke')
     def test_create_update_delete_health_monitor(self):
         # Creates a health_monitor
-        resp, body = self.client.create_health_monitor(delay=4,
-                                                       max_retries=3,
-                                                       type="TCP",
-                                                       timeout=1)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_health_monitor(delay=4,
+                                                    max_retries=3,
+                                                    type="TCP",
+                                                    timeout=1)
         health_monitor = body['health_monitor']
         # Verification of health_monitor update
-        resp, body = (self.client.update_health_monitor
-                     (health_monitor['id'],
-                      admin_state_up=False))
-        self.assertEqual('200', resp['status'])
+        _, body = (self.client.update_health_monitor
+                   (health_monitor['id'],
+                    admin_state_up=False))
         updated_health_monitor = body['health_monitor']
         self.assertFalse(updated_health_monitor['admin_state_up'])
         # Verification of health_monitor delete
-        resp, body = self.client.delete_health_monitor(health_monitor['id'])
-        self.assertEqual('204', resp['status'])
+        _, body = self.client.delete_health_monitor(health_monitor['id'])
 
     @test.attr(type='smoke')
     def test_create_health_monitor_http_type(self):
         hm_type = "HTTP"
-        resp, body = self.client.create_health_monitor(delay=4,
-                                                       max_retries=3,
-                                                       type=hm_type,
-                                                       timeout=1)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_health_monitor(delay=4,
+                                                    max_retries=3,
+                                                    type=hm_type,
+                                                    timeout=1)
         health_monitor = body['health_monitor']
         self.addCleanup(self.client.delete_health_monitor,
                         health_monitor['id'])
@@ -314,20 +288,18 @@
 
     @test.attr(type='smoke')
     def test_update_health_monitor_http_method(self):
-        resp, body = self.client.create_health_monitor(delay=4,
-                                                       max_retries=3,
-                                                       type="HTTP",
-                                                       timeout=1)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_health_monitor(delay=4,
+                                                    max_retries=3,
+                                                    type="HTTP",
+                                                    timeout=1)
         health_monitor = body['health_monitor']
         self.addCleanup(self.client.delete_health_monitor,
                         health_monitor['id'])
-        resp, body = (self.client.update_health_monitor
-                     (health_monitor['id'],
-                      http_method="POST",
-                      url_path="/home/user",
-                      expected_codes="290"))
-        self.assertEqual('200', resp['status'])
+        _, body = (self.client.update_health_monitor
+                   (health_monitor['id'],
+                    http_method="POST",
+                    url_path="/home/user",
+                    expected_codes="290"))
         updated_health_monitor = body['health_monitor']
         self.assertEqual("POST", updated_health_monitor['http_method'])
         self.assertEqual("/home/user", updated_health_monitor['url_path'])
@@ -336,8 +308,7 @@
     @test.attr(type='smoke')
     def test_show_health_monitor(self):
         # Verifies the details of a health_monitor
-        resp, body = self.client.show_health_monitor(self.health_monitor['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_health_monitor(self.health_monitor['id'])
         health_monitor = body['health_monitor']
         for key, value in health_monitor.iteritems():
             # 'status' should not be confirmed in api tests
@@ -347,9 +318,8 @@
     @test.attr(type='smoke')
     def test_associate_disassociate_health_monitor_with_pool(self):
         # Verify that a health monitor can be associated with a pool
-        resp, body = (self.client.associate_health_monitor_with_pool
-                     (self.health_monitor['id'], self.pool['id']))
-        self.assertEqual('201', resp['status'])
+        _, body = (self.client.associate_health_monitor_with_pool
+                   (self.health_monitor['id'], self.pool['id']))
         resp, body = self.client.show_health_monitor(
             self.health_monitor['id'])
         health_monitor = body['health_monitor']
@@ -359,10 +329,9 @@
                       [p['pool_id'] for p in health_monitor['pools']])
         self.assertIn(health_monitor['id'], pool['health_monitors'])
         # Verify that a health monitor can be disassociated from a pool
-        resp, body = (self.client.disassociate_health_monitor_with_pool
-                     (self.health_monitor['id'], self.pool['id']))
-        self.assertEqual('204', resp['status'])
-        resp, body = self.client.show_pool(self.pool['id'])
+        (self.client.disassociate_health_monitor_with_pool
+            (self.health_monitor['id'], self.pool['id']))
+        _, body = self.client.show_pool(self.pool['id'])
         pool = body['pool']
         resp, body = self.client.show_health_monitor(
             self.health_monitor['id'])
@@ -374,8 +343,7 @@
     @test.attr(type='smoke')
     def test_get_lb_pool_stats(self):
         # Verify the details of pool stats
-        resp, body = self.client.list_lb_pool_stats(self.pool['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_lb_pool_stats(self.pool['id'])
         stats = body['stats']
         self.assertIn("bytes_in", stats)
         self.assertIn("total_connections", stats)
@@ -384,52 +352,41 @@
 
     @test.attr(type='smoke')
     def test_update_list_of_health_monitors_associated_with_pool(self):
-        resp, _ = (self.client.associate_health_monitor_with_pool
-                   (self.health_monitor['id'], self.pool['id']))
-        self.assertEqual('201', resp['status'])
-        resp, _ = self.client.update_health_monitor(
+        (self.client.associate_health_monitor_with_pool
+            (self.health_monitor['id'], self.pool['id']))
+        self.client.update_health_monitor(
             self.health_monitor['id'], admin_state_up=False)
-        self.assertEqual('200', resp['status'])
-        resp, body = self.client.show_pool(self.pool['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_pool(self.pool['id'])
         health_monitors = body['pool']['health_monitors']
         for health_monitor_id in health_monitors:
-            resp, body = self.client.show_health_monitor(health_monitor_id)
-            self.assertEqual('200', resp['status'])
+            _, body = self.client.show_health_monitor(health_monitor_id)
             self.assertFalse(body['health_monitor']['admin_state_up'])
-        resp, _ = (self.client.disassociate_health_monitor_with_pool
-                   (self.health_monitor['id'], self.pool['id']))
-        self.assertEqual('204', resp['status'])
+            (self.client.disassociate_health_monitor_with_pool
+                (self.health_monitor['id'], self.pool['id']))
 
     @test.attr(type='smoke')
     def test_update_admin_state_up_of_pool(self):
-        resp, _ = self.client.update_pool(self.pool['id'],
-                                          admin_state_up=False)
-        self.assertEqual('200', resp['status'])
-        resp, body = self.client.show_pool(self.pool['id'])
-        self.assertEqual('200', resp['status'])
+        self.client.update_pool(self.pool['id'],
+                                admin_state_up=False)
+        _, body = self.client.show_pool(self.pool['id'])
         pool = body['pool']
         self.assertFalse(pool['admin_state_up'])
 
     @test.attr(type='smoke')
     def test_show_vip_associated_with_pool(self):
-        resp, body = self.client.show_pool(self.pool['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_pool(self.pool['id'])
         pool = body['pool']
-        resp, body = self.client.show_vip(pool['vip_id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_vip(pool['vip_id'])
         vip = body['vip']
         self.assertEqual(self.vip['name'], vip['name'])
         self.assertEqual(self.vip['id'], vip['id'])
 
     @test.attr(type='smoke')
     def test_show_members_associated_with_pool(self):
-        resp, body = self.client.show_pool(self.pool['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_pool(self.pool['id'])
         members = body['pool']['members']
         for member_id in members:
-            resp, body = self.client.show_member(member_id)
-            self.assertEqual('200', resp['status'])
+            _, body = self.client.show_member(member_id)
             self.assertIsNotNone(body['member']['status'])
             self.assertEqual(member_id, body['member']['id'])
             self.assertIsNotNone(body['member']['admin_state_up'])
@@ -437,34 +394,28 @@
     @test.attr(type='smoke')
     def test_update_pool_related_to_member(self):
         # Create new pool
-        resp, body = self.client.create_pool(
-            name=data_utils.rand_name("pool-"),
-            lb_method='ROUND_ROBIN',
-            protocol='HTTP',
-            subnet_id=self.subnet['id'])
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_pool(name=data_utils.rand_name("pool-"),
+                                          lb_method='ROUND_ROBIN',
+                                          protocol='HTTP',
+                                          subnet_id=self.subnet['id'])
         new_pool = body['pool']
         self.addCleanup(self.client.delete_pool, new_pool['id'])
         # Update member with new pool's id
-        resp, body = self.client.update_member(self.member['id'],
-                                               pool_id=new_pool['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_member(self.member['id'],
+                                            pool_id=new_pool['id'])
         # Confirm with show that pool_id change
         resp, body = self.client.show_member(self.member['id'])
         member = body['member']
         self.assertEqual(member['pool_id'], new_pool['id'])
         # Update member with old pool id, this is needed for clean up
-        resp, body = self.client.update_member(self.member['id'],
-                                               pool_id=self.pool['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_member(self.member['id'],
+                                            pool_id=self.pool['id'])
 
     @test.attr(type='smoke')
     def test_update_member_weight(self):
-        resp, _ = self.client.update_member(self.member['id'],
-                                            weight=2)
-        self.assertEqual('200', resp['status'])
-        resp, body = self.client.show_member(self.member['id'])
-        self.assertEqual('200', resp['status'])
+        self.client.update_member(self.member['id'],
+                                  weight=2)
+        _, body = self.client.show_member(self.member['id'])
         member = body['member']
         self.assertEqual(2, member['weight'])
 
diff --git a/tempest/api/network/test_metering_extensions.py b/tempest/api/network/test_metering_extensions.py
index 08ccbfe..5b8db43 100644
--- a/tempest/api/network/test_metering_extensions.py
+++ b/tempest/api/network/test_metering_extensions.py
@@ -56,8 +56,7 @@
 
     def _delete_metering_label(self, metering_label_id):
         # Deletes a label and verifies if it is deleted or not
-        resp, body = self.admin_client.delete_metering_label(metering_label_id)
-        self.assertEqual(204, resp.status)
+        _, body = self.admin_client.delete_metering_label(metering_label_id)
         # Asserting that the label is not found in list after deletion
         resp, labels = (self.admin_client.list_metering_labels(
                         id=metering_label_id))
@@ -65,9 +64,8 @@
 
     def _delete_metering_label_rule(self, metering_label_rule_id):
         # Deletes a rule and verifies if it is deleted or not
-        resp, body = (self.admin_client.delete_metering_label_rule(
-                      metering_label_rule_id))
-        self.assertEqual(204, resp.status)
+        _, body = (self.admin_client.delete_metering_label_rule(
+                   metering_label_rule_id))
         # Asserting that the rule is not found in list after deletion
         resp, rules = (self.admin_client.list_metering_label_rules(
                        id=metering_label_rule_id))
@@ -76,8 +74,7 @@
     @test.attr(type='smoke')
     def test_list_metering_labels(self):
         # Verify label filtering
-        resp, body = self.admin_client.list_metering_labels(id=33)
-        self.assertEqual('200', resp['status'])
+        _, body = self.admin_client.list_metering_labels(id=33)
         metering_labels = body['metering_labels']
         self.assertEqual(0, len(metering_labels))
 
@@ -86,9 +83,8 @@
         # Creates a label
         name = data_utils.rand_name('metering-label-')
         description = "label created by tempest"
-        resp, body = (self.admin_client.create_metering_label(name=name,
-                      description=description))
-        self.assertEqual('201', resp['status'])
+        _, body = (self.admin_client.create_metering_label(name=name,
+                   description=description))
         metering_label = body['metering_label']
         self.addCleanup(self._delete_metering_label,
                         metering_label['id'])
@@ -101,9 +97,8 @@
     @test.attr(type='smoke')
     def test_show_metering_label(self):
         # Verifies the details of a label
-        resp, body = (self.admin_client.show_metering_label(
-                      self.metering_label['id']))
-        self.assertEqual('200', resp['status'])
+        _, body = (self.admin_client.show_metering_label(
+                   self.metering_label['id']))
         metering_label = body['metering_label']
         self.assertEqual(self.metering_label['id'], metering_label['id'])
         self.assertEqual(self.metering_label['tenant_id'],
@@ -115,19 +110,17 @@
     @test.attr(type='smoke')
     def test_list_metering_label_rules(self):
         # Verify rule filtering
-        resp, body = self.admin_client.list_metering_label_rules(id=33)
-        self.assertEqual('200', resp['status'])
+        _, body = self.admin_client.list_metering_label_rules(id=33)
         metering_label_rules = body['metering_label_rules']
         self.assertEqual(0, len(metering_label_rules))
 
     @test.attr(type='smoke')
     def test_create_delete_metering_label_rule_with_filters(self):
         # Creates a rule
-        resp, body = (self.admin_client.create_metering_label_rule(
-                      remote_ip_prefix="10.0.1.0/24",
-                      direction="ingress",
-                      metering_label_id=self.metering_label['id']))
-        self.assertEqual('201', resp['status'])
+        _, body = (self.admin_client.create_metering_label_rule(
+                   remote_ip_prefix="10.0.1.0/24",
+                   direction="ingress",
+                   metering_label_id=self.metering_label['id']))
         metering_label_rule = body['metering_label_rule']
         self.addCleanup(self._delete_metering_label_rule,
                         metering_label_rule['id'])
@@ -140,9 +133,8 @@
     @test.attr(type='smoke')
     def test_show_metering_label_rule(self):
         # Verifies the details of a rule
-        resp, body = (self.admin_client.show_metering_label_rule(
-                      self.metering_label_rule['id']))
-        self.assertEqual('200', resp['status'])
+        _, body = (self.admin_client.show_metering_label_rule(
+                   self.metering_label_rule['id']))
         metering_label_rule = body['metering_label_rule']
         self.assertEqual(self.metering_label_rule['id'],
                          metering_label_rule['id'])
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index ac3a072..f3da614 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -71,14 +71,13 @@
     def test_create_update_delete_network_subnet(self):
         # Create a network
         name = data_utils.rand_name('network-')
-        resp, body = self.client.create_network(name=name)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_network(name=name)
         network = body['network']
         net_id = network['id']
+        self.assertEqual('ACTIVE', network['status'])
         # Verify network update
         new_name = "New_network"
-        resp, body = self.client.update_network(net_id, name=new_name)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_network(net_id, name=new_name)
         updated_net = body['network']
         self.assertEqual(updated_net['name'], new_name)
         # Find a cidr that is not in use yet and create a subnet with it
@@ -86,23 +85,19 @@
         subnet_id = subnet['id']
         # Verify subnet update
         new_name = "New_subnet"
-        resp, body = self.client.update_subnet(subnet_id, name=new_name)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_subnet(subnet_id, name=new_name)
         updated_subnet = body['subnet']
         self.assertEqual(updated_subnet['name'], new_name)
         # Delete subnet and network
-        resp, body = self.client.delete_subnet(subnet_id)
-        self.assertEqual('204', resp['status'])
+        _, body = self.client.delete_subnet(subnet_id)
         # Remove subnet from cleanup list
         self.subnets.pop()
-        resp, body = self.client.delete_network(net_id)
-        self.assertEqual('204', resp['status'])
+        _, body = self.client.delete_network(net_id)
 
     @test.attr(type='smoke')
     def test_show_network(self):
         # Verify the details of a network
-        resp, body = self.client.show_network(self.network['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_network(self.network['id'])
         network = body['network']
         for key in ['id', 'name']:
             self.assertEqual(network[key], self.network[key])
@@ -111,9 +106,8 @@
     def test_show_network_fields(self):
         # Verify specific fields of a network
         fields = ['id', 'name']
-        resp, body = self.client.show_network(self.network['id'],
-                                              fields=fields)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_network(self.network['id'],
+                                           fields=fields)
         network = body['network']
         self.assertEqual(sorted(network.keys()), sorted(fields))
         for field_name in fields:
@@ -122,8 +116,7 @@
     @test.attr(type='smoke')
     def test_list_networks(self):
         # Verify the network exists in the list of all networks
-        resp, body = self.client.list_networks()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_networks()
         networks = [network['id'] for network in body['networks']
                     if network['id'] == self.network['id']]
         self.assertNotEmpty(networks, "Created network not found in the list")
@@ -132,8 +125,7 @@
     def test_list_networks_fields(self):
         # Verify specific fields of the networks
         fields = ['id', 'name']
-        resp, body = self.client.list_networks(fields=fields)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_networks(fields=fields)
         networks = body['networks']
         self.assertNotEmpty(networks, "Network list returned is empty")
         for network in networks:
@@ -142,8 +134,7 @@
     @test.attr(type='smoke')
     def test_show_subnet(self):
         # Verify the details of a subnet
-        resp, body = self.client.show_subnet(self.subnet['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_subnet(self.subnet['id'])
         subnet = body['subnet']
         self.assertNotEmpty(subnet, "Subnet returned has no fields")
         for key in ['id', 'cidr']:
@@ -154,9 +145,8 @@
     def test_show_subnet_fields(self):
         # Verify specific fields of a subnet
         fields = ['id', 'network_id']
-        resp, body = self.client.show_subnet(self.subnet['id'],
-                                             fields=fields)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_subnet(self.subnet['id'],
+                                          fields=fields)
         subnet = body['subnet']
         self.assertEqual(sorted(subnet.keys()), sorted(fields))
         for field_name in fields:
@@ -165,8 +155,7 @@
     @test.attr(type='smoke')
     def test_list_subnets(self):
         # Verify the subnet exists in the list of all subnets
-        resp, body = self.client.list_subnets()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_subnets()
         subnets = [subnet['id'] for subnet in body['subnets']
                    if subnet['id'] == self.subnet['id']]
         self.assertNotEmpty(subnets, "Created subnet not found in the list")
@@ -175,8 +164,7 @@
     def test_list_subnets_fields(self):
         # Verify specific fields of subnets
         fields = ['id', 'network_id']
-        resp, body = self.client.list_subnets(fields=fields)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_subnets(fields=fields)
         subnets = body['subnets']
         self.assertNotEmpty(subnets, "Subnet list returned is empty")
         for subnet in subnets:
@@ -194,8 +182,7 @@
     def test_delete_network_with_subnet(self):
         # Creates a network
         name = data_utils.rand_name('network-')
-        resp, body = self.client.create_network(name=name)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_network(name=name)
         network = body['network']
         net_id = network['id']
         self.addCleanup(self._try_delete_network, net_id)
@@ -205,8 +192,7 @@
         subnet_id = subnet['id']
 
         # Delete network while the subnet still exists
-        resp, body = self.client.delete_network(net_id)
-        self.assertEqual('204', resp['status'])
+        _, body = self.client.delete_network(net_id)
 
         # Verify that the subnet got automatically deleted.
         self.assertRaises(exceptions.NotFound, self.client.show_subnet,
@@ -221,16 +207,14 @@
     def test_create_delete_subnet_with_gw(self):
         gateway = '10.100.0.13'
         name = data_utils.rand_name('network-')
-        resp, body = self.client.create_network(name=name)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_network(name=name)
         network = body['network']
         net_id = network['id']
         subnet = self.create_subnet(network, gateway)
         # Verifies Subnet GW in IPv4
         self.assertEqual(subnet['gateway_ip'], gateway)
         # Delete network and subnet
-        resp, body = self.client.delete_network(net_id)
-        self.assertEqual('204', resp['status'])
+        self.client.delete_network(net_id)
         self.subnets.pop()
 
     @test.attr(type='smoke')
@@ -238,16 +222,14 @@
         net = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
         gateway_ip = str(netaddr.IPAddress(net.first + 1))
         name = data_utils.rand_name('network-')
-        resp, body = self.client.create_network(name=name)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_network(name=name)
         network = body['network']
         net_id = network['id']
         subnet = self.create_subnet(network)
         # Verifies Subnet GW in IPv4
         self.assertEqual(subnet['gateway_ip'], gateway_ip)
         # Delete network and subnet
-        resp, body = self.client.delete_network(net_id)
-        self.assertEqual('204', resp['status'])
+        self.client.delete_network(net_id)
         self.subnets.pop()
 
 
@@ -279,8 +261,7 @@
 
     def _delete_networks(self, created_networks):
         for n in created_networks:
-            resp, body = self.client.delete_network(n['id'])
-            self.assertEqual(204, resp.status)
+            self.client.delete_network(n['id'])
         # Asserting that the networks are not found in the list after deletion
         resp, body = self.client.list_networks()
         networks_list = [network['id'] for network in body['networks']]
@@ -289,8 +270,7 @@
 
     def _delete_subnets(self, created_subnets):
         for n in created_subnets:
-            resp, body = self.client.delete_subnet(n['id'])
-            self.assertEqual(204, resp.status)
+            self.client.delete_subnet(n['id'])
         # Asserting that the subnets are not found in the list after deletion
         resp, body = self.client.list_subnets()
         subnets_list = [subnet['id'] for subnet in body['subnets']]
@@ -299,8 +279,7 @@
 
     def _delete_ports(self, created_ports):
         for n in created_ports:
-            resp, body = self.client.delete_port(n['id'])
-            self.assertEqual(204, resp.status)
+            self.client.delete_port(n['id'])
         # Asserting that the ports are not found in the list after deletion
         resp, body = self.client.list_ports()
         ports_list = [port['id'] for port in body['ports']]
@@ -312,9 +291,8 @@
         # Creates 2 networks in one request
         network_names = [data_utils.rand_name('network-'),
                          data_utils.rand_name('network-')]
-        resp, body = self.client.create_bulk_network(2, network_names)
+        _, body = self.client.create_bulk_network(network_names)
         created_networks = body['networks']
-        self.assertEqual('201', resp['status'])
         self.addCleanup(self._delete_networks, created_networks)
         # Asserting that the networks are found in the list after creation
         resp, body = self.client.list_networks()
@@ -344,10 +322,9 @@
             }
             subnets_list.append(p1)
         del subnets_list[1]['name']
-        resp, body = self.client.create_bulk_subnet(subnets_list)
+        _, body = self.client.create_bulk_subnet(subnets_list)
         created_subnets = body['subnets']
         self.addCleanup(self._delete_subnets, created_subnets)
-        self.assertEqual('201', resp['status'])
         # Asserting that the subnets are found in the list after creation
         resp, body = self.client.list_subnets()
         subnets_list = [subnet['id'] for subnet in body['subnets']]
@@ -370,10 +347,9 @@
             }
             port_list.append(p1)
         del port_list[1]['name']
-        resp, body = self.client.create_bulk_port(port_list)
+        _, body = self.client.create_bulk_port(port_list)
         created_ports = body['ports']
         self.addCleanup(self._delete_ports, created_ports)
-        self.assertEqual('201', resp['status'])
         # Asserting that the ports are found in the list after creation
         resp, body = self.client.list_ports()
         ports_list = [port['id'] for port in body['ports']]
@@ -398,33 +374,32 @@
 
     @test.attr(type='smoke')
     def test_create_delete_subnet_with_gw(self):
-        gateway = '2003::2'
+        net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+        gateway = str(netaddr.IPAddress(net.first + 2))
         name = data_utils.rand_name('network-')
-        resp, body = self.client.create_network(name=name)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_network(name=name)
         network = body['network']
         net_id = network['id']
         subnet = self.create_subnet(network, gateway)
         # Verifies Subnet GW in IPv6
         self.assertEqual(subnet['gateway_ip'], gateway)
         # Delete network and subnet
-        resp, body = self.client.delete_network(net_id)
-        self.assertEqual('204', resp['status'])
+        self.client.delete_network(net_id)
         self.subnets.pop()
 
     @test.attr(type='smoke')
     def test_create_delete_subnet_without_gw(self):
+        net = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+        gateway_ip = str(netaddr.IPAddress(net.first + 1))
         name = data_utils.rand_name('network-')
-        resp, body = self.client.create_network(name=name)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_network(name=name)
         network = body['network']
         net_id = network['id']
         subnet = self.create_subnet(network)
         # Verifies Subnet GW in IPv6
-        self.assertEqual(subnet['gateway_ip'], '2003::1')
+        self.assertEqual(subnet['gateway_ip'], gateway_ip)
         # Delete network and subnet
-        resp, body = self.client.delete_network(net_id)
-        self.assertEqual('204', resp['status'])
+        _, body = self.client.delete_network(net_id)
         self.subnets.pop()
 
     @testtools.skipUnless(CONF.network_feature_enabled.ipv6_subnet_attributes,
@@ -433,8 +408,7 @@
     @test.attr(type='smoke')
     def test_create_delete_subnet_with_v6_attributes(self):
         name = data_utils.rand_name('network-')
-        resp, body = self.client.create_network(name=name)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_network(name=name)
         network = body['network']
         net_id = network['id']
         subnet = self.create_subnet(network,
@@ -446,8 +420,7 @@
         self.assertEqual(subnet['ipv6_ra_mode'], 'slaac')
         self.assertEqual(subnet['ipv6_address_mode'], 'slaac')
         # Delete network and subnet
-        resp, body = self.client.delete_network(net_id)
-        self.assertEqual('204', resp['status'])
+        self.client.delete_network(net_id)
         self.subnets.pop()
 
 
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index e6e6ea1..f06d17c 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -44,29 +44,24 @@
         cls.port = cls.create_port(cls.network)
 
     def _delete_port(self, port_id):
-        resp, body = self.client.delete_port(port_id)
-        self.assertEqual('204', resp['status'])
-        resp, body = self.client.list_ports()
-        self.assertEqual('200', resp['status'])
+        self.client.delete_port(port_id)
+        _, body = self.client.list_ports()
         ports_list = body['ports']
         self.assertFalse(port_id in [n['id'] for n in ports_list])
 
     @test.attr(type='smoke')
     def test_create_update_delete_port(self):
         # Verify port creation
-        resp, body = self.client.create_port(network_id=self.network['id'])
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_port(network_id=self.network['id'])
         port = body['port']
         # Schedule port deletion with verification upon test completion
         self.addCleanup(self._delete_port, port['id'])
         self.assertTrue(port['admin_state_up'])
         # Verify port update
         new_name = "New_Port"
-        resp, body = self.client.update_port(
-            port['id'],
-            name=new_name,
-            admin_state_up=False)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_port(port['id'],
+                                          name=new_name,
+                                          admin_state_up=False)
         updated_port = body['port']
         self.assertEqual(updated_port['name'], new_name)
         self.assertFalse(updated_port['admin_state_up'])
@@ -74,8 +69,7 @@
     @test.attr(type='smoke')
     def test_show_port(self):
         # Verify the details of port
-        resp, body = self.client.show_port(self.port['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_port(self.port['id'])
         port = body['port']
         self.assertIn('id', port)
         self.assertEqual(port['id'], self.port['id'])
@@ -95,9 +89,8 @@
     def test_show_port_fields(self):
         # Verify specific fields of a port
         fields = ['id', 'mac_address']
-        resp, body = self.client.show_port(self.port['id'],
-                                           fields=fields)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_port(self.port['id'],
+                                        fields=fields)
         port = body['port']
         self.assertEqual(sorted(port.keys()), sorted(fields))
         for field_name in fields:
@@ -106,8 +99,7 @@
     @test.attr(type='smoke')
     def test_list_ports(self):
         # Verify the port exists in the list of all ports
-        resp, body = self.client.list_ports()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_ports()
         ports = [port['id'] for port in body['ports']
                  if port['id'] == self.port['id']]
         self.assertNotEmpty(ports, "Created port not found in the list")
@@ -125,9 +117,7 @@
         self.addCleanup(self.client.remove_router_interface_with_port_id,
                         router['id'], port['port']['id'])
         # List ports filtered by router_id
-        resp, port_list = self.client.list_ports(
-            device_id=router['id'])
-        self.assertEqual('200', resp['status'])
+        _, port_list = self.client.list_ports(device_id=router['id'])
         ports = port_list['ports']
         self.assertEqual(len(ports), 1)
         self.assertEqual(ports[0]['id'], port['port']['id'])
@@ -137,8 +127,7 @@
     def test_list_ports_fields(self):
         # Verify specific fields of ports
         fields = ['id', 'mac_address']
-        resp, body = self.client.list_ports(fields=fields)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_ports(fields=fields)
         ports = body['ports']
         self.assertNotEmpty(ports, "Port list returned is empty")
         # Asserting the fields returned are correct
@@ -190,8 +179,7 @@
     def test_create_port_binding_ext_attr(self):
         post_body = {"network_id": self.network['id'],
                      "binding:host_id": self.host_id}
-        resp, body = self.admin_client.create_port(**post_body)
-        self.assertEqual('201', resp['status'])
+        _, body = self.admin_client.create_port(**post_body)
         port = body['port']
         self.addCleanup(self.admin_client.delete_port, port['id'])
         host_id = port['binding:host_id']
@@ -201,13 +189,11 @@
     @test.attr(type='smoke')
     def test_update_port_binding_ext_attr(self):
         post_body = {"network_id": self.network['id']}
-        resp, body = self.admin_client.create_port(**post_body)
-        self.assertEqual('201', resp['status'])
+        _, body = self.admin_client.create_port(**post_body)
         port = body['port']
         self.addCleanup(self.admin_client.delete_port, port['id'])
         update_body = {"binding:host_id": self.host_id}
-        resp, body = self.admin_client.update_port(port['id'], **update_body)
-        self.assertEqual('200', resp['status'])
+        _, body = self.admin_client.update_port(port['id'], **update_body)
         updated_port = body['port']
         host_id = updated_port['binding:host_id']
         self.assertIsNotNone(host_id)
@@ -217,21 +203,18 @@
     def test_list_ports_binding_ext_attr(self):
         # Create a new port
         post_body = {"network_id": self.network['id']}
-        resp, body = self.admin_client.create_port(**post_body)
-        self.assertEqual('201', resp['status'])
+        _, body = self.admin_client.create_port(**post_body)
         port = body['port']
         self.addCleanup(self.admin_client.delete_port, port['id'])
 
         # Update the port's binding attributes so that is now 'bound'
         # to a host
         update_body = {"binding:host_id": self.host_id}
-        resp, _ = self.admin_client.update_port(port['id'], **update_body)
-        self.assertEqual('200', resp['status'])
+        self.admin_client.update_port(port['id'], **update_body)
 
         # List all ports, ensure new port is part of list and its binding
         # attributes are set and accurate
-        resp, body = self.admin_client.list_ports()
-        self.assertEqual('200', resp['status'])
+        _, body = self.admin_client.list_ports()
         ports_list = body['ports']
         pids_list = [p['id'] for p in ports_list]
         self.assertIn(port['id'], pids_list)
@@ -243,13 +226,10 @@
 
     @test.attr(type='smoke')
     def test_show_port_binding_ext_attr(self):
-        resp, body = self.admin_client.create_port(
-            network_id=self.network['id'])
-        self.assertEqual('201', resp['status'])
+        _, body = self.admin_client.create_port(network_id=self.network['id'])
         port = body['port']
         self.addCleanup(self.admin_client.delete_port, port['id'])
-        resp, body = self.admin_client.show_port(port['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.admin_client.show_port(port['id'])
         show_port = body['port']
         self.assertEqual(port['binding:host_id'],
                          show_port['binding:host_id'])
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index d38633f..bcd8113 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -54,11 +54,10 @@
         # NOTE(salv-orlando): Do not invoke self.create_router
         # as we need to check the response code
         name = data_utils.rand_name('router-')
-        resp, create_body = self.client.create_router(
+        _, create_body = self.client.create_router(
             name, external_gateway_info={
                 "network_id": CONF.network.public_network_id},
             admin_state_up=False)
-        self.assertEqual('201', resp['status'])
         self.addCleanup(self._delete_router, create_body['router']['id'])
         self.assertEqual(create_body['router']['name'], name)
         self.assertEqual(
@@ -66,26 +65,22 @@
             CONF.network.public_network_id)
         self.assertEqual(create_body['router']['admin_state_up'], False)
         # Show details of the created router
-        resp, show_body = self.client.show_router(
-            create_body['router']['id'])
-        self.assertEqual('200', resp['status'])
+        _, show_body = self.client.show_router(create_body['router']['id'])
         self.assertEqual(show_body['router']['name'], name)
         self.assertEqual(
             show_body['router']['external_gateway_info']['network_id'],
             CONF.network.public_network_id)
         self.assertEqual(show_body['router']['admin_state_up'], False)
         # List routers and verify if created router is there in response
-        resp, list_body = self.client.list_routers()
-        self.assertEqual('200', resp['status'])
+        _, list_body = self.client.list_routers()
         routers_list = list()
         for router in list_body['routers']:
             routers_list.append(router['id'])
         self.assertIn(create_body['router']['id'], routers_list)
         # Update the name of router and verify if it is updated
         updated_name = 'updated ' + name
-        resp, update_body = self.client.update_router(
-            create_body['router']['id'], name=updated_name)
-        self.assertEqual('200', resp['status'])
+        _, update_body = self.client.update_router(create_body['router']['id'],
+                                                   name=updated_name)
         self.assertEqual(update_body['router']['name'], updated_name)
         resp, show_body = self.client.show_router(
             create_body['router']['id'])
@@ -97,28 +92,54 @@
         test_tenant = data_utils.rand_name('test_tenant_')
         test_description = data_utils.rand_name('desc_')
         _, tenant = self.identity_admin_client.create_tenant(
-            name=test_tenant,
-            description=test_description)
+            name=test_tenant, description=test_description)
         tenant_id = tenant['id']
         self.addCleanup(self.identity_admin_client.delete_tenant, tenant_id)
 
         name = data_utils.rand_name('router-')
-        resp, create_body = self.admin_client.create_router(
-            name, tenant_id=tenant_id)
-        self.assertEqual('201', resp['status'])
+        _, create_body = self.admin_client.create_router(name,
+                                                         tenant_id=tenant_id)
         self.addCleanup(self.admin_client.delete_router,
                         create_body['router']['id'])
         self.assertEqual(tenant_id, create_body['router']['tenant_id'])
 
+    @test.requires_ext(extension='ext-gw-mode', service='network')
+    @test.attr(type='smoke')
+    def test_create_router_with_default_snat_value(self):
+        # Create a router with default snat rule
+        name = data_utils.rand_name('router')
+        router = self._create_router(
+            name, external_network_id=CONF.network.public_network_id)
+        self._verify_router_gateway(
+            router['id'], {'network_id': CONF.network.public_network_id,
+                           'enable_snat': True})
+
+    @test.requires_ext(extension='ext-gw-mode', service='network')
+    @test.attr(type='smoke')
+    def test_create_router_with_snat_explicit(self):
+        name = data_utils.rand_name('snat-router')
+        # Create a router enabling snat attributes
+        enable_snat_states = [False, True]
+        for enable_snat in enable_snat_states:
+            external_gateway_info = {
+                'network_id': CONF.network.public_network_id,
+                'enable_snat': enable_snat}
+            _, create_body = self.admin_client.create_router(
+                name, external_gateway_info=external_gateway_info)
+            self.addCleanup(self.admin_client.delete_router,
+                            create_body['router']['id'])
+            # Verify snat attributes after router creation
+            self._verify_router_gateway(create_body['router']['id'],
+                                        exp_ext_gw_info=external_gateway_info)
+
     @test.attr(type='smoke')
     def test_add_remove_router_interface_with_subnet_id(self):
         network = self.create_network()
         subnet = self.create_subnet(network)
         router = self._create_router(data_utils.rand_name('router-'))
         # Add router interface with subnet id
-        resp, interface = self.client.add_router_interface_with_subnet_id(
+        _, interface = self.client.add_router_interface_with_subnet_id(
             router['id'], subnet['id'])
-        self.assertEqual('200', resp['status'])
         self.addCleanup(self._remove_router_interface_with_subnet_id,
                         router['id'], subnet['id'])
         self.assertIn('subnet_id', interface.keys())
@@ -137,9 +158,8 @@
         resp, port_body = self.client.create_port(
             network_id=network['id'])
         # add router interface to port created above
-        resp, interface = self.client.add_router_interface_with_port_id(
+        _, interface = self.client.add_router_interface_with_port_id(
             router['id'], port_body['port']['id'])
-        self.assertEqual('200', resp['status'])
         self.addCleanup(self._remove_router_interface_with_port_id,
                         router['id'], port_body['port']['id'])
         self.assertIn('subnet_id', interface.keys())
@@ -151,8 +171,7 @@
                          router['id'])
 
     def _verify_router_gateway(self, router_id, exp_ext_gw_info=None):
-        resp, show_body = self.client.show_router(router_id)
-        self.assertEqual('200', resp['status'])
+        _, show_body = self.admin_client.show_router(router_id)
         actual_ext_gw_info = show_body['router']['external_gateway_info']
         if exp_ext_gw_info is None:
             self.assertIsNone(actual_ext_gw_info)
@@ -182,8 +201,7 @@
             external_gateway_info={
                 'network_id': CONF.network.public_network_id})
         # Verify operation - router
-        resp, show_body = self.client.show_router(router['id'])
-        self.assertEqual('200', resp['status'])
+        _, show_body = self.client.show_router(router['id'])
         self._verify_router_gateway(
             router['id'],
             {'network_id': CONF.network.public_network_id})
@@ -267,16 +285,14 @@
         cidr = netaddr.IPNetwork(self.subnet['cidr'])
         next_hop = str(cidr[2])
         destination = str(self.subnet['cidr'])
-        resp, extra_route = self.client.update_extra_routes(
-            self.router['id'], next_hop, destination)
-        self.assertEqual('200', resp['status'])
+        _, extra_route = self.client.update_extra_routes(self.router['id'],
+                                                         next_hop, destination)
         self.assertEqual(1, len(extra_route['router']['routes']))
         self.assertEqual(destination,
                          extra_route['router']['routes'][0]['destination'])
         self.assertEqual(next_hop,
                          extra_route['router']['routes'][0]['nexthop'])
-        resp, show_body = self.client.show_router(self.router['id'])
-        self.assertEqual('200', resp['status'])
+        _, show_body = self.client.show_router(self.router['id'])
         self.assertEqual(destination,
                          show_body['router']['routes'][0]['destination'])
         self.assertEqual(next_hop,
@@ -290,12 +306,10 @@
         self.router = self._create_router(data_utils.rand_name('router-'))
         self.assertFalse(self.router['admin_state_up'])
         # Update router admin state
-        resp, update_body = self.client.update_router(self.router['id'],
-                                                      admin_state_up=True)
-        self.assertEqual('200', resp['status'])
+        _, update_body = self.client.update_router(self.router['id'],
+                                                   admin_state_up=True)
         self.assertTrue(update_body['router']['admin_state_up'])
-        resp, show_body = self.client.show_router(self.router['id'])
-        self.assertEqual('200', resp['status'])
+        _, show_body = self.client.show_router(self.router['id'])
         self.assertTrue(show_body['router']['admin_state_up'])
 
     @test.attr(type='smoke')
@@ -318,8 +332,7 @@
                                       interface02['port_id'])
 
     def _verify_router_interface(self, router_id, subnet_id, port_id):
-        resp, show_port_body = self.client.show_port(port_id)
-        self.assertEqual('200', resp['status'])
+        _, show_port_body = self.client.show_port(port_id)
         interface_port = show_port_body['port']
         self.assertEqual(router_id, interface_port['device_id'])
         self.assertEqual(subnet_id,
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index b98cea1..cea8344 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -33,8 +33,7 @@
     @test.attr(type='smoke')
     def test_list_security_groups(self):
         # Verify the that security group belonging to tenant exist in list
-        resp, body = self.client.list_security_groups()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_security_groups()
         security_groups = body['security_groups']
         found = None
         for n in security_groups:
@@ -48,8 +47,7 @@
         group_create_body, name = self._create_security_group()
 
         # List security groups and verify if created group is there in response
-        resp, list_body = self.client.list_security_groups()
-        self.assertEqual('200', resp['status'])
+        _, list_body = self.client.list_security_groups()
         secgroup_list = list()
         for secgroup in list_body['security_groups']:
             secgroup_list.append(secgroup['id'])
@@ -57,12 +55,11 @@
         # Update the security group
         new_name = data_utils.rand_name('security-')
         new_description = data_utils.rand_name('security-description')
-        resp, update_body = self.client.update_security_group(
+        _, update_body = self.client.update_security_group(
             group_create_body['security_group']['id'],
             name=new_name,
             description=new_description)
         # Verify if security group is updated
-        self.assertEqual('200', resp['status'])
         self.assertEqual(update_body['security_group']['name'], new_name)
         self.assertEqual(update_body['security_group']['description'],
                          new_description)
@@ -80,18 +77,16 @@
         # Create rules for each protocol
         protocols = ['tcp', 'udp', 'icmp']
         for protocol in protocols:
-            resp, rule_create_body = self.client.create_security_group_rule(
+            _, rule_create_body = self.client.create_security_group_rule(
                 security_group_id=group_create_body['security_group']['id'],
                 protocol=protocol,
                 direction='ingress'
             )
-            self.assertEqual('201', resp['status'])
 
             # Show details of the created security rule
-            resp, show_rule_body = self.client.show_security_group_rule(
+            _, show_rule_body = self.client.show_security_group_rule(
                 rule_create_body['security_group_rule']['id']
             )
-            self.assertEqual('200', resp['status'])
             create_dict = rule_create_body['security_group_rule']
             for key, value in six.iteritems(create_dict):
                 self.assertEqual(value,
@@ -99,8 +94,7 @@
                                  "%s does not match." % key)
 
             # List rules and verify created rule is in response
-            resp, rule_list_body = self.client.list_security_group_rules()
-            self.assertEqual('200', resp['status'])
+            _, rule_list_body = self.client.list_security_group_rules()
             rule_list = [rule['id']
                          for rule in rule_list_body['security_group_rules']]
             self.assertIn(rule_create_body['security_group_rule']['id'],
@@ -117,7 +111,7 @@
         protocol = 'tcp'
         port_range_min = 77
         port_range_max = 77
-        resp, rule_create_body = self.client.create_security_group_rule(
+        _, rule_create_body = self.client.create_security_group_rule(
             security_group_id=group_create_body['security_group']['id'],
             direction=direction,
             protocol=protocol,
@@ -125,7 +119,6 @@
             port_range_max=port_range_max
         )
 
-        self.assertEqual('201', resp['status'])
         sec_group_rule = rule_create_body['security_group_rule']
 
         self.assertEqual(sec_group_rule['direction'], direction)
diff --git a/tempest/api/network/test_service_type_management.py b/tempest/api/network/test_service_type_management.py
index d272c47..dbb72fb 100644
--- a/tempest/api/network/test_service_type_management.py
+++ b/tempest/api/network/test_service_type_management.py
@@ -26,8 +26,7 @@
 
     @test.attr(type='smoke')
     def test_service_provider_list(self):
-        resp, body = self.client.list_service_providers()
-        self.assertEqual(resp['status'], '200')
+        _, body = self.client.list_service_providers()
         self.assertIsInstance(body['service_providers'], list)
 
 
diff --git a/tempest/api/network/test_vpnaas_extensions.py b/tempest/api/network/test_vpnaas_extensions.py
index 0cc3f19..09e9640 100644
--- a/tempest/api/network/test_vpnaas_extensions.py
+++ b/tempest/api/network/test_vpnaas_extensions.py
@@ -61,8 +61,7 @@
         for ike in all_ike['ikepolicies']:
             ike_list.append(ike['id'])
         if ike_policy_id in ike_list:
-            resp, _ = self.client.delete_ikepolicy(ike_policy_id)
-            self.assertEqual(204, resp.status)
+            self.client.delete_ikepolicy(ike_policy_id)
             # Asserting that the policy is not found in list after deletion
             resp, ikepolicies = self.client.list_ikepolicies()
             ike_id_list = list()
@@ -85,8 +84,7 @@
             self.assertEqual(value, actual[key])
 
     def _delete_vpn_service(self, vpn_service_id):
-        resp, _ = self.client.delete_vpnservice(vpn_service_id)
-        self.assertEqual('204', resp['status'])
+        self.client.delete_vpnservice(vpn_service_id)
         # Asserting if vpn service is found in the list after deletion
         _, body = self.client.list_vpnservices()
         vpn_services = [vs['id'] for vs in body['vpnservices']]
@@ -107,9 +105,8 @@
         tenant_id = self._get_tenant_id()
         # Create IPSec policy for the newly created tenant
         name = data_utils.rand_name('ipsec-policy')
-        resp, body = (self.admin_client.
-                      create_ipsecpolicy(name=name, tenant_id=tenant_id))
-        self.assertEqual('201', resp['status'])
+        _, body = (self.admin_client.
+                   create_ipsecpolicy(name=name, tenant_id=tenant_id))
         ipsecpolicy = body['ipsecpolicy']
         self.assertIsNotNone(ipsecpolicy['id'])
         self.addCleanup(self.admin_client.delete_ipsecpolicy,
@@ -126,13 +123,12 @@
 
         # Create vpn service for the newly created tenant
         name = data_utils.rand_name('vpn-service')
-        resp, body = self.admin_client.create_vpnservice(
+        _, body = self.admin_client.create_vpnservice(
             subnet_id=self.subnet['id'],
             router_id=self.router['id'],
             name=name,
             admin_state_up=True,
             tenant_id=tenant_id)
-        self.assertEqual('201', resp['status'])
         vpnservice = body['vpnservice']
         self.assertIsNotNone(vpnservice['id'])
         self.addCleanup(self.admin_client.delete_vpnservice, vpnservice['id'])
@@ -148,12 +144,11 @@
 
         # Create IKE policy for the newly created tenant
         name = data_utils.rand_name('ike-policy')
-        resp, body = (self.admin_client.
-                      create_ikepolicy(name=name, ike_version="v1",
-                                       encryption_algorithm="aes-128",
-                                       auth_algorithm="sha1",
-                                       tenant_id=tenant_id))
-        self.assertEqual('201', resp['status'])
+        _, body = (self.admin_client.
+                   create_ikepolicy(name=name, ike_version="v1",
+                                    encryption_algorithm="aes-128",
+                                    auth_algorithm="sha1",
+                                    tenant_id=tenant_id))
         ikepolicy = body['ikepolicy']
         self.assertIsNotNone(ikepolicy['id'])
         self.addCleanup(self.admin_client.delete_ikepolicy, ikepolicy['id'])
@@ -166,8 +161,7 @@
     @test.attr(type='smoke')
     def test_list_vpn_services(self):
         # Verify the VPN service exists in the list of all VPN services
-        resp, body = self.client.list_vpnservices()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_vpnservices()
         vpnservices = body['vpnservices']
         self.assertIn(self.vpnservice['id'], [v['id'] for v in vpnservices])
 
@@ -175,11 +169,10 @@
     def test_create_update_delete_vpn_service(self):
         # Creates a VPN service and sets up deletion
         name = data_utils.rand_name('vpn-service')
-        resp, body = self.client.create_vpnservice(subnet_id=self.subnet['id'],
-                                                   router_id=self.router['id'],
-                                                   name=name,
-                                                   admin_state_up=True)
-        self.assertEqual('201', resp['status'])
+        _, body = self.client.create_vpnservice(subnet_id=self.subnet['id'],
+                                                router_id=self.router['id'],
+                                                name=name,
+                                                admin_state_up=True)
         vpnservice = body['vpnservice']
         self.addCleanup(self._delete_vpn_service, vpnservice['id'])
         # Assert if created vpnservices are not found in vpnservices list
@@ -196,8 +189,7 @@
     @test.attr(type='smoke')
     def test_show_vpn_service(self):
         # Verifies the details of a vpn service
-        resp, body = self.client.show_vpnservice(self.vpnservice['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_vpnservice(self.vpnservice['id'])
         vpnservice = body['vpnservice']
         self.assertEqual(self.vpnservice['id'], vpnservice['id'])
         self.assertEqual(self.vpnservice['name'], vpnservice['name'])
@@ -213,8 +205,7 @@
     @test.attr(type='smoke')
     def test_list_ike_policies(self):
         # Verify the ike policy exists in the list of all IKE policies
-        resp, body = self.client.list_ikepolicies()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_ikepolicies()
         ikepolicies = body['ikepolicies']
         self.assertIn(self.ikepolicy['id'], [i['id'] for i in ikepolicies])
 
@@ -222,12 +213,11 @@
     def test_create_update_delete_ike_policy(self):
         # Creates a IKE policy
         name = data_utils.rand_name('ike-policy')
-        resp, body = (self.client.create_ikepolicy(
-                      name=name,
-                      ike_version="v1",
-                      encryption_algorithm="aes-128",
-                      auth_algorithm="sha1"))
-        self.assertEqual('201', resp['status'])
+        _, body = (self.client.create_ikepolicy(
+                   name=name,
+                   ike_version="v1",
+                   encryption_algorithm="aes-128",
+                   auth_algorithm="sha1"))
         ikepolicy = body['ikepolicy']
         self.assertIsNotNone(ikepolicy['id'])
         self.addCleanup(self._delete_ike_policy, ikepolicy['id'])
@@ -239,8 +229,7 @@
                    'ike_version': "v2",
                    'pfs': "group14",
                    'lifetime': {'units': "seconds", 'value': 2000}}
-        resp, _ = self.client.update_ikepolicy(ikepolicy['id'], **new_ike)
-        self.assertEqual('200', resp['status'])
+        self.client.update_ikepolicy(ikepolicy['id'], **new_ike)
         # Confirm that update was successful by verifying using 'show'
         _, body = self.client.show_ikepolicy(ikepolicy['id'])
         ike_policy = body['ikepolicy']
@@ -249,8 +238,7 @@
             self.assertEqual(value, ike_policy[key])
 
         # Verification of ike policy delete
-        resp, _ = self.client.delete_ikepolicy(ikepolicy['id'])
-        self.assertEqual('204', resp['status'])
+        self.client.delete_ikepolicy(ikepolicy['id'])
         _, body = self.client.list_ikepolicies()
         ikepolicies = [ikp['id'] for ikp in body['ikepolicies']]
         self.assertNotIn(ike_policy['id'], ikepolicies)
@@ -258,8 +246,7 @@
     @test.attr(type='smoke')
     def test_show_ike_policy(self):
         # Verifies the details of a ike policy
-        resp, body = self.client.show_ikepolicy(self.ikepolicy['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_ikepolicy(self.ikepolicy['id'])
         ikepolicy = body['ikepolicy']
         self.assertEqual(self.ikepolicy['id'], ikepolicy['id'])
         self.assertEqual(self.ikepolicy['name'], ikepolicy['name'])
@@ -281,8 +268,7 @@
     @test.attr(type='smoke')
     def test_list_ipsec_policies(self):
         # Verify the ipsec policy exists in the list of all ipsec policies
-        resp, body = self.client.list_ipsecpolicies()
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_ipsecpolicies()
         ipsecpolicies = body['ipsecpolicies']
         self.assertIn(self.ipsecpolicy['id'], [i['id'] for i in ipsecpolicies])
 
@@ -293,8 +279,7 @@
                              'pfs': 'group5',
                              'encryption_algorithm': "aes-128",
                              'auth_algorithm': 'sha1'}
-        resp, resp_body = self.client.create_ipsecpolicy(**ipsec_policy_body)
-        self.assertEqual('201', resp['status'])
+        _, resp_body = self.client.create_ipsecpolicy(**ipsec_policy_body)
         ipsecpolicy = resp_body['ipsecpolicy']
         self.addCleanup(self._delete_ipsec_policy, ipsecpolicy['id'])
         self._assertExpected(ipsec_policy_body, ipsecpolicy)
@@ -304,22 +289,19 @@
                      'name': data_utils.rand_name("New-IPSec"),
                      'encryption_algorithm': "aes-256",
                      'lifetime': {'units': "seconds", 'value': '2000'}}
-        resp, body = self.client.update_ipsecpolicy(ipsecpolicy['id'],
-                                                    **new_ipsec)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.update_ipsecpolicy(ipsecpolicy['id'],
+                                                 **new_ipsec)
         updated_ipsec_policy = body['ipsecpolicy']
         self._assertExpected(new_ipsec, updated_ipsec_policy)
         # Verification of ipsec policy delete
-        resp, _ = self.client.delete_ipsecpolicy(ipsecpolicy['id'])
-        self.assertEqual('204', resp['status'])
+        self.client.delete_ipsecpolicy(ipsecpolicy['id'])
         self.assertRaises(exceptions.NotFound,
                           self.client.delete_ipsecpolicy, ipsecpolicy['id'])
 
     @test.attr(type='smoke')
     def test_show_ipsec_policy(self):
         # Verifies the details of an ipsec policy
-        resp, body = self.client.show_ipsecpolicy(self.ipsecpolicy['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.show_ipsecpolicy(self.ipsecpolicy['id'])
         ipsecpolicy = body['ipsecpolicy']
         self._assertExpected(self.ipsecpolicy, ipsecpolicy)
 
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 1ef9aa1..8b74b7e 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -17,10 +17,11 @@
 import hashlib
 import random
 import re
-from six import moves
 import time
 import zlib
 
+import six
+
 from tempest.api.object_storage import base
 from tempest.common import custom_matchers
 from tempest.common.utils import data_utils
@@ -54,15 +55,36 @@
         object_name = data_utils.rand_name(name='LObject')
         data = data_utils.arbitrary_string()
         segments = 10
-        data_segments = [data + str(i) for i in moves.xrange(segments)]
+        data_segments = [data + str(i) for i in six.moves.xrange(segments)]
         # uploading segments
-        for i in moves.xrange(segments):
+        for i in six.moves.xrange(segments):
             resp, _ = self.object_client.create_object_segments(
                 self.container_name, object_name, i, data_segments[i])
             self.assertEqual(resp['status'], '201')
 
         return object_name, data_segments
 
+    def _copy_object_2d(self, src_object_name, metadata=None):
+        dst_object_name = data_utils.rand_name(name='TestObject')
+        resp, _ = self.object_client.copy_object_2d_way(self.container_name,
+                                                        src_object_name,
+                                                        dst_object_name,
+                                                        metadata=metadata)
+        return dst_object_name, resp
+
+    def _check_copied_obj(self, dst_object_name, src_body,
+                          in_meta=None, not_in_meta=None):
+        resp, dest_body = self.object_client.get_object(self.container_name,
+                                                        dst_object_name)
+
+        self.assertEqual(src_body, dest_body)
+        if in_meta:
+            for meta_key in in_meta:
+                self.assertIn('x-object-meta-' + meta_key, resp)
+        if not_in_meta:
+            for meta_key in not_in_meta:
+                self.assertNotIn('x-object-meta-' + meta_key, resp)
+
     @test.attr(type='gate')
     def test_create_object(self):
         # create object
@@ -765,10 +787,7 @@
         # change the content type of an existing object
 
         # create object
-        object_name = data_utils.rand_name(name='TestObject')
-        data = data_utils.arbitrary_string()
-        self.object_client.create_object(self.container_name,
-                                         object_name, data)
+        object_name, data = self._create_object()
         # get the old content type
         resp_tmp, _ = self.object_client.list_object_metadata(
             self.container_name, object_name)
@@ -805,20 +824,12 @@
                                                         dst_object_name)
         self.assertEqual(resp['status'], '201')
         self.assertHeaders(resp, 'Object', 'COPY')
-
-        self.assertIn('last-modified', resp)
-        self.assertIn('x-copied-from', resp)
-        self.assertIn('x-copied-from-last-modified', resp)
-        self.assertNotEqual(len(resp['last-modified']), 0)
         self.assertEqual(
             resp['x-copied-from'],
             self.container_name + "/" + src_object_name)
-        self.assertNotEqual(len(resp['x-copied-from-last-modified']), 0)
 
         # check data
-        resp, body = self.object_client.get_object(self.container_name,
-                                                   dst_object_name)
-        self.assertEqual(body, src_data)
+        self._check_copied_obj(dst_object_name, src_data)
 
     @test.attr(type='smoke')
     def test_copy_object_across_containers(self):
@@ -862,15 +873,82 @@
         self.assertIn(actual_meta_key, resp)
         self.assertEqual(resp[actual_meta_key], meta_value)
 
+    @test.attr(type='smoke')
+    def test_copy_object_with_x_fresh_metadata(self):
+        # create source object
+        metadata = {'x-object-meta-src': 'src_value'}
+        src_object_name, data = self._create_object(metadata)
+
+        # copy source object with x_fresh_metadata header
+        metadata = {'X-Fresh-Metadata': 'true'}
+        dst_object_name, resp = self._copy_object_2d(src_object_name,
+                                                     metadata)
+
+        self.assertEqual(resp['status'], '201')
+        self.assertHeaders(resp, 'Object', 'COPY')
+
+        self.assertNotIn('x-object-meta-src', resp)
+        self.assertEqual(resp['x-copied-from'],
+                         self.container_name + "/" + src_object_name)
+
+        # check that destination object does NOT have any object-meta
+        self._check_copied_obj(dst_object_name, data, not_in_meta=["src"])
+
+    @test.attr(type='smoke')
+    def test_copy_object_with_x_object_metakey(self):
+        # create source object
+        metadata = {'x-object-meta-src': 'src_value'}
+        src_obj_name, data = self._create_object(metadata)
+
+        # copy source object to destination with x-object-meta-key
+        metadata = {'x-object-meta-test': ''}
+        dst_obj_name, resp = self._copy_object_2d(src_obj_name, metadata)
+
+        self.assertEqual(resp['status'], '201')
+        self.assertHeaders(resp, 'Object', 'COPY')
+
+        expected = {'x-object-meta-test': '',
+                    'x-object-meta-src': 'src_value',
+                    'x-copied-from': self.container_name + "/" + src_obj_name}
+        for key, value in six.iteritems(expected):
+            self.assertIn(key, resp)
+            self.assertEqual(value, resp[key])
+
+        # check destination object
+        self._check_copied_obj(dst_obj_name, data, in_meta=["test", "src"])
+
+    @test.attr(type='smoke')
+    def test_copy_object_with_x_object_meta(self):
+        # create source object
+        metadata = {'x-object-meta-src': 'src_value'}
+        src_obj_name, data = self._create_object(metadata)
+
+        # copy source object to destination with object metadata
+        metadata = {'x-object-meta-test': 'value'}
+        dst_obj_name, resp = self._copy_object_2d(src_obj_name, metadata)
+
+        self.assertEqual(resp['status'], '201')
+        self.assertHeaders(resp, 'Object', 'COPY')
+
+        expected = {'x-object-meta-test': 'value',
+                    'x-object-meta-src': 'src_value',
+                    'x-copied-from': self.container_name + "/" + src_obj_name}
+        for key, value in six.iteritems(expected):
+            self.assertIn(key, resp)
+            self.assertEqual(value, resp[key])
+
+        # check destination object
+        self._check_copied_obj(dst_obj_name, data, in_meta=["test", "src"])
+
     @test.attr(type='gate')
     def test_object_upload_in_segments(self):
         # create object
         object_name = data_utils.rand_name(name='LObject')
         data = data_utils.arbitrary_string()
         segments = 10
-        data_segments = [data + str(i) for i in moves.xrange(segments)]
+        data_segments = [data + str(i) for i in six.moves.xrange(segments)]
         # uploading segments
-        for i in moves.xrange(segments):
+        for i in six.moves.xrange(segments):
             resp, _ = self.object_client.create_object_segments(
                 self.container_name, object_name, i, data_segments[i])
             self.assertEqual(resp['status'], '201')
diff --git a/tempest/api/object_storage/test_object_temp_url.py b/tempest/api/object_storage/test_object_temp_url.py
index c597255..264a18a 100644
--- a/tempest/api/object_storage/test_object_temp_url.py
+++ b/tempest/api/object_storage/test_object_temp_url.py
@@ -185,3 +185,20 @@
         resp, body = self.object_client.head(url)
         self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
         self.assertHeaders(resp, 'Object', 'HEAD')
+
+    @test.attr(type='gate')
+    @test.requires_ext(extension='tempurl', service='object')
+    def test_get_object_using_temp_url_with_inline_query_parameter(self):
+        expires = self._get_expiry_date()
+
+        # get a temp URL for the created object
+        url = self._get_temp_url(self.container_name, self.object_name, "GET",
+                                 expires, self.key)
+        url = url + '&inline'
+
+        # trying to get object using temp url within expiry time
+        resp, body = self.object_client.get(url)
+        self.assertIn(int(resp['status']), test.HTTP_SUCCESS)
+        self.assertHeaders(resp, 'Object', 'GET')
+        self.assertEqual(body, self.content)
+        self.assertEqual(resp['content-disposition'], 'inline')
diff --git a/tempest/api/orchestration/base.py b/tempest/api/orchestration/base.py
index 446f4ab..d0fb825 100644
--- a/tempest/api/orchestration/base.py
+++ b/tempest/api/orchestration/base.py
@@ -12,6 +12,8 @@
 
 import os.path
 
+import yaml
+
 from tempest import clients
 from tempest.common.utils import data_utils
 from tempest import config
@@ -49,7 +51,7 @@
 
     @classmethod
     def _get_default_network(cls):
-        __, networks = cls.network_client.list_networks()
+        _, networks = cls.network_client.list_networks()
         for net in networks['networks']:
             if net['name'] == CONF.compute.fixed_network_name:
                 return net
@@ -93,7 +95,7 @@
     @classmethod
     def _create_keypair(cls, name_start='keypair-heat-'):
         kp_name = data_utils.rand_name(name_start)
-        __, body = cls.keypairs_client.create_keypair(kp_name)
+        _, body = cls.keypairs_client.create_keypair(kp_name)
         cls.keypairs.append(kp_name)
         return body
 
@@ -109,9 +111,9 @@
     def _create_image(cls, name_start='image-heat-', container_format='bare',
                       disk_format='iso'):
         image_name = data_utils.rand_name(name_start)
-        __, body = cls.images_v2_client.create_image(image_name,
-                                                     container_format,
-                                                     disk_format)
+        _, body = cls.images_v2_client.create_image(image_name,
+                                                    container_format,
+                                                    disk_format)
         image_id = body['id']
         cls.images.append(image_id)
         return body
@@ -125,7 +127,7 @@
                 pass
 
     @classmethod
-    def load_template(cls, name, ext='yaml'):
+    def read_template(cls, name, ext='yaml'):
         loc = ["stacks", "templates", "%s.%s" % (name, ext)]
         fullpath = os.path.join(os.path.dirname(__file__), *loc)
 
@@ -134,6 +136,14 @@
             return content
 
     @classmethod
+    def load_template(cls, name, ext='yaml'):
+        loc = ["stacks", "templates", "%s.%s" % (name, ext)]
+        fullpath = os.path.join(os.path.dirname(__file__), *loc)
+
+        with open(fullpath, "r") as f:
+            return yaml.safe_load(f)
+
+    @classmethod
     def tearDownClass(cls):
         cls._clear_stacks()
         cls._clear_keypairs()
@@ -152,8 +162,7 @@
 
     def list_resources(self, stack_identifier):
         """Get a dict mapping of resource names to types."""
-        resp, resources = self.client.list_resources(stack_identifier)
-        self.assertEqual('200', resp['status'])
+        _, resources = self.client.list_resources(stack_identifier)
         self.assertIsInstance(resources, list)
         for res in resources:
             self.assert_fields_in_dict(res, 'logical_resource_id',
@@ -164,6 +173,5 @@
                     for r in resources)
 
     def get_stack_output(self, stack_identifier, output_key):
-        resp, body = self.client.get_stack(stack_identifier)
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.get_stack(stack_identifier)
         return self.stack_output(body, output_key)
diff --git a/tempest/api/orchestration/stacks/test_environment.py b/tempest/api/orchestration/stacks/test_environment.py
index 3911e72..96e1c50 100644
--- a/tempest/api/orchestration/stacks/test_environment.py
+++ b/tempest/api/orchestration/stacks/test_environment.py
@@ -28,7 +28,7 @@
     def test_environment_parameter(self):
         """Test passing a stack parameter via the environment."""
         stack_name = data_utils.rand_name('heat')
-        template = self.load_template('random_string')
+        template = self.read_template('random_string')
         environment = {'parameters': {'random_length': 20}}
 
         stack_identifier = self.create_stack(stack_name, template,
@@ -56,7 +56,7 @@
 '''
         environment = {'resource_registry':
                        {'My:Random::String': 'my_random.yaml'}}
-        files = {'my_random.yaml': self.load_template('random_string')}
+        files = {'my_random.yaml': self.read_template('random_string')}
 
         stack_identifier = self.create_stack(stack_name, template,
                                              environment=environment,
@@ -65,7 +65,10 @@
 
         # random_string.yaml specifies a length of 10
         random_value = self.get_stack_output(stack_identifier, 'random_value')
-        self.assertEqual(10, len(random_value))
+        random_string_template = self.load_template('random_string')
+        expected_length = random_string_template['parameters'][
+            'random_length']['default']
+        self.assertEqual(expected_length, len(random_value))
 
     @test.attr(type='gate')
     def test_files_provider_resource(self):
@@ -82,7 +85,7 @@
     random_value:
         value: {get_attr: [random, random_value]}
 '''
-        files = {'my_random.yaml': self.load_template('random_string')}
+        files = {'my_random.yaml': self.read_template('random_string')}
 
         stack_identifier = self.create_stack(stack_name, template,
                                              files=files)
@@ -90,4 +93,7 @@
 
         # random_string.yaml specifies a length of 10
         random_value = self.get_stack_output(stack_identifier, 'random_value')
-        self.assertEqual(10, len(random_value))
+        random_string_template = self.load_template('random_string')
+        expected_length = random_string_template['parameters'][
+            'random_length']['default']
+        self.assertEqual(expected_length, len(random_value))
diff --git a/tempest/api/orchestration/stacks/test_neutron_resources.py b/tempest/api/orchestration/stacks/test_neutron_resources.py
index e92b945..ffadb16 100644
--- a/tempest/api/orchestration/stacks/test_neutron_resources.py
+++ b/tempest/api/orchestration/stacks/test_neutron_resources.py
@@ -12,6 +12,7 @@
 
 
 import logging
+
 import netaddr
 
 from tempest.api.orchestration import base
@@ -37,9 +38,10 @@
         os = clients.Manager()
         if not CONF.service_available.neutron:
             raise cls.skipException("Neutron support is required")
+        cls.neutron_basic_template = cls.load_template('neutron_basic')
         cls.network_client = os.network_client
         cls.stack_name = data_utils.rand_name('heat')
-        template = cls.load_template('neutron_basic')
+        template = cls.read_template('neutron_basic')
         cls.keypair_name = (CONF.orchestration.keypair_name or
                             cls._create_keypair()['name'])
         cls.external_network_id = CONF.network.public_network_id
@@ -66,16 +68,17 @@
             cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
             _, resources = cls.client.list_resources(cls.stack_identifier)
         except exceptions.TimeoutException as e:
-            # attempt to log the server console to help with debugging
-            # the cause of the server not signalling the waitcondition
-            # to heat.
-            resp, body = cls.client.get_resource(cls.stack_identifier,
-                                                 'Server')
-            server_id = body['physical_resource_id']
-            LOG.debug('Console output for %s', server_id)
-            resp, output = cls.servers_client.get_console_output(
-                server_id, None)
-            LOG.debug(output)
+            if CONF.compute_feature_enabled.console_output:
+                # attempt to log the server console to help with debugging
+                # the cause of the server not signalling the waitcondition
+                # to heat.
+                _, body = cls.client.get_resource(cls.stack_identifier,
+                                                  'Server')
+                server_id = body['physical_resource_id']
+                LOG.debug('Console output for %s', server_id)
+                _, output = cls.servers_client.get_console_output(
+                    server_id, None)
+                LOG.debug(output)
             raise e
 
         cls.test_resources = {}
@@ -85,10 +88,14 @@
     @test.attr(type='slow')
     def test_created_resources(self):
         """Verifies created neutron resources."""
-        resources = [('Network', 'OS::Neutron::Net'),
-                     ('Subnet', 'OS::Neutron::Subnet'),
-                     ('RouterInterface', 'OS::Neutron::RouterInterface'),
-                     ('Server', 'OS::Nova::Server')]
+        resources = [('Network', self.neutron_basic_template['resources'][
+                      'Network']['type']),
+                     ('Subnet', self.neutron_basic_template['resources'][
+                      'Subnet']['type']),
+                     ('RouterInterface', self.neutron_basic_template[
+                      'resources']['RouterInterface']['type']),
+                     ('Server', self.neutron_basic_template['resources'][
+                      'Server']['type'])]
         for resource_name, resource_type in resources:
             resource = self.test_resources.get(resource_name, None)
             self.assertIsInstance(resource, dict)
@@ -97,52 +104,56 @@
             self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
 
     @test.attr(type='slow')
+    @test.services('network')
     def test_created_network(self):
         """Verifies created network."""
         network_id = self.test_resources.get('Network')['physical_resource_id']
-        resp, body = self.network_client.show_network(network_id)
-        self.assertEqual('200', resp['status'])
+        _, body = self.network_client.show_network(network_id)
         network = body['network']
         self.assertIsInstance(network, dict)
         self.assertEqual(network_id, network['id'])
-        self.assertEqual('NewNetwork', network['name'])
+        self.assertEqual(self.neutron_basic_template['resources'][
+            'Network']['properties']['name'], network['name'])
 
     @test.attr(type='slow')
+    @test.services('network')
     def test_created_subnet(self):
         """Verifies created subnet."""
         subnet_id = self.test_resources.get('Subnet')['physical_resource_id']
-        resp, body = self.network_client.show_subnet(subnet_id)
-        self.assertEqual('200', resp['status'])
+        _, body = self.network_client.show_subnet(subnet_id)
         subnet = body['subnet']
         network_id = self.test_resources.get('Network')['physical_resource_id']
         self.assertEqual(subnet_id, subnet['id'])
         self.assertEqual(network_id, subnet['network_id'])
-        self.assertEqual('NewSubnet', subnet['name'])
+        self.assertEqual(self.neutron_basic_template['resources'][
+            'Subnet']['properties']['name'], subnet['name'])
         self.assertEqual(sorted(CONF.network.dns_servers),
                          sorted(subnet['dns_nameservers']))
-        self.assertEqual(4, subnet['ip_version'])
+        self.assertEqual(self.neutron_basic_template['resources'][
+            'Subnet']['properties']['ip_version'], subnet['ip_version'])
         self.assertEqual(str(self.subnet_cidr), subnet['cidr'])
 
     @test.attr(type='slow')
+    @test.services('network')
     def test_created_router(self):
         """Verifies created router."""
         router_id = self.test_resources.get('Router')['physical_resource_id']
-        resp, body = self.network_client.show_router(router_id)
-        self.assertEqual('200', resp['status'])
+        _, body = self.network_client.show_router(router_id)
         router = body['router']
-        self.assertEqual('NewRouter', router['name'])
+        self.assertEqual(self.neutron_basic_template['resources'][
+            'Router']['properties']['name'], router['name'])
         self.assertEqual(self.external_network_id,
                          router['external_gateway_info']['network_id'])
         self.assertEqual(True, router['admin_state_up'])
 
     @test.attr(type='slow')
+    @test.services('network')
     def test_created_router_interface(self):
         """Verifies created router interface."""
         router_id = self.test_resources.get('Router')['physical_resource_id']
         network_id = self.test_resources.get('Network')['physical_resource_id']
         subnet_id = self.test_resources.get('Subnet')['physical_resource_id']
-        resp, body = self.network_client.list_ports()
-        self.assertEqual('200', resp['status'])
+        _, body = self.network_client.list_ports()
         ports = body['ports']
         router_ports = filter(lambda port: port['device_id'] ==
                               router_id, ports)
@@ -159,13 +170,14 @@
                          router_interface_ip)
 
     @test.attr(type='slow')
+    @test.services('compute', 'network')
     def test_created_server(self):
         """Verifies created sever."""
         server_id = self.test_resources.get('Server')['physical_resource_id']
-        resp, server = self.servers_client.get_server(server_id)
-        self.assertEqual('200', resp['status'])
+        _, server = self.servers_client.get_server(server_id)
         self.assertEqual(self.keypair_name, server['key_name'])
         self.assertEqual('ACTIVE', server['status'])
-        network = server['addresses']['NewNetwork'][0]
+        network = server['addresses'][self.neutron_basic_template['resources'][
+                                      'Network']['properties']['name']][0]
         self.assertEqual(4, network['version'])
         self.assertIn(netaddr.IPAddress(network['addr']), self.subnet_cidr)
diff --git a/tempest/api/orchestration/stacks/test_non_empty_stack.py b/tempest/api/orchestration/stacks/test_non_empty_stack.py
index 585c90b..72ad5f5 100644
--- a/tempest/api/orchestration/stacks/test_non_empty_stack.py
+++ b/tempest/api/orchestration/stacks/test_non_empty_stack.py
@@ -28,7 +28,7 @@
     def setUpClass(cls):
         super(StacksTestJSON, cls).setUpClass()
         cls.stack_name = data_utils.rand_name('heat')
-        template = cls.load_template('non_empty_stack')
+        template = cls.read_template('non_empty_stack')
         image_id = (CONF.orchestration.image_ref or
                     cls._create_image()['id'])
         # create the stack
@@ -45,8 +45,7 @@
         cls.client.wait_for_stack_status(cls.stack_id, 'CREATE_COMPLETE')
 
     def _list_stacks(self, expected_num=None, **filter_kwargs):
-        resp, stacks = self.client.list_stacks(params=filter_kwargs)
-        self.assertEqual('200', resp['status'])
+        _, stacks = self.client.list_stacks(params=filter_kwargs)
         self.assertIsInstance(stacks, list)
         if expected_num is not None:
             self.assertEqual(expected_num, len(stacks))
@@ -62,8 +61,7 @@
     @test.attr(type='gate')
     def test_stack_show(self):
         """Getting details about created stack should be possible."""
-        resp, stack = self.client.get_stack(self.stack_name)
-        self.assertEqual('200', resp['status'])
+        _, stack = self.client.get_stack(self.stack_name)
         self.assertIsInstance(stack, dict)
         self.assert_fields_in_dict(stack, 'stack_name', 'id', 'links',
                                    'parameters', 'outputs', 'disable_rollback',
@@ -82,12 +80,10 @@
     @test.attr(type='gate')
     def test_suspend_resume_stack(self):
         """Suspend and resume a stack."""
-        resp, suspend_stack = self.client.suspend_stack(self.stack_identifier)
-        self.assertEqual('200', resp['status'])
+        _, suspend_stack = self.client.suspend_stack(self.stack_identifier)
         self.client.wait_for_stack_status(self.stack_identifier,
                                           'SUSPEND_COMPLETE')
-        resp, resume_stack = self.client.resume_stack(self.stack_identifier)
-        self.assertEqual('200', resp['status'])
+        _, resume_stack = self.client.resume_stack(self.stack_identifier)
         self.client.wait_for_stack_status(self.stack_identifier,
                                           'RESUME_COMPLETE')
 
@@ -101,8 +97,8 @@
     @test.attr(type='gate')
     def test_show_resource(self):
         """Getting details about created resource should be possible."""
-        resp, resource = self.client.get_resource(self.stack_identifier,
-                                                  self.resource_name)
+        _, resource = self.client.get_resource(self.stack_identifier,
+                                               self.resource_name)
         self.assertIsInstance(resource, dict)
         self.assert_fields_in_dict(resource, 'resource_name', 'description',
                                    'links', 'logical_resource_id',
@@ -115,18 +111,16 @@
     @test.attr(type='gate')
     def test_resource_metadata(self):
         """Getting metadata for created resources should be possible."""
-        resp, metadata = self.client.show_resource_metadata(
+        _, metadata = self.client.show_resource_metadata(
             self.stack_identifier,
             self.resource_name)
-        self.assertEqual('200', resp['status'])
         self.assertIsInstance(metadata, dict)
         self.assertEqual(['Tom', 'Stinky'], metadata.get('kittens', None))
 
     @test.attr(type='gate')
     def test_list_events(self):
         """Getting list of created events for the stack should be possible."""
-        resp, events = self.client.list_events(self.stack_identifier)
-        self.assertEqual('200', resp['status'])
+        _, events = self.client.list_events(self.stack_identifier)
         self.assertIsInstance(events, list)
 
         for event in events:
@@ -141,14 +135,13 @@
     @test.attr(type='gate')
     def test_show_event(self):
         """Getting details about an event should be possible."""
-        resp, events = self.client.list_resource_events(self.stack_identifier,
-                                                        self.resource_name)
+        _, events = self.client.list_resource_events(self.stack_identifier,
+                                                     self.resource_name)
         self.assertNotEqual([], events)
         events.sort(key=lambda event: event['event_time'])
         event_id = events[0]['id']
-        resp, event = self.client.show_event(self.stack_identifier,
-                                             self.resource_name, event_id)
-        self.assertEqual('200', resp['status'])
+        _, event = self.client.show_event(self.stack_identifier,
+                                          self.resource_name, event_id)
         self.assertIsInstance(event, dict)
         self.assert_fields_in_dict(event, 'resource_name', 'event_time',
                                    'links', 'logical_resource_id',
diff --git a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
index a81a540..2f58611 100644
--- a/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
+++ b/tempest/api/orchestration/stacks/test_nova_keypair_resources.py
@@ -23,12 +23,14 @@
 
 class NovaKeyPairResourcesYAMLTest(base.BaseOrchestrationTest):
     _tpl_type = 'yaml'
+    _resource = 'resources'
+    _type = 'type'
 
     @classmethod
     def setUpClass(cls):
         super(NovaKeyPairResourcesYAMLTest, cls).setUpClass()
         cls.stack_name = data_utils.rand_name('heat')
-        template = cls.load_template('nova_keypair', ext=cls._tpl_type)
+        template = cls.read_template('nova_keypair', ext=cls._tpl_type)
 
         # create the stack, avoid any duplicated key.
         cls.stack_identifier = cls.create_stack(
@@ -46,11 +48,18 @@
         for resource in resources:
             cls.test_resources[resource['logical_resource_id']] = resource
 
-    @test.attr(type='slow')
+    @test.attr(type='gate')
     def test_created_resources(self):
         """Verifies created keypair resource."""
-        resources = [('KeyPairSavePrivate', 'OS::Nova::KeyPair'),
-                     ('KeyPairDontSavePrivate', 'OS::Nova::KeyPair')]
+
+        nova_keypair_template = self.load_template('nova_keypair',
+                                                   ext=self._tpl_type)
+        resources = [('KeyPairSavePrivate',
+                      nova_keypair_template[self._resource][
+                          'KeyPairSavePrivate'][self._type]),
+                     ('KeyPairDontSavePrivate',
+                      nova_keypair_template[self._resource][
+                          'KeyPairDontSavePrivate'][self._type])]
 
         for resource_name, resource_type in resources:
             resource = self.test_resources.get(resource_name, None)
@@ -59,10 +68,9 @@
             self.assertEqual(resource_type, resource['resource_type'])
             self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
 
-    @test.attr(type='slow')
+    @test.attr(type='gate')
     def test_stack_keypairs_output(self):
-        resp, stack = self.client.get_stack(self.stack_name)
-        self.assertEqual('200', resp['status'])
+        _, stack = self.client.get_stack(self.stack_name)
         self.assertIsInstance(stack, dict)
 
         output_map = {}
@@ -85,3 +93,5 @@
 
 class NovaKeyPairResourcesAWSTest(NovaKeyPairResourcesYAMLTest):
     _tpl_type = 'json'
+    _resource = 'Resources'
+    _type = 'Type'
diff --git a/tempest/api/orchestration/stacks/test_resource_types.py b/tempest/api/orchestration/stacks/test_resource_types.py
new file mode 100644
index 0000000..e204894
--- /dev/null
+++ b/tempest/api/orchestration/stacks/test_resource_types.py
@@ -0,0 +1,44 @@
+#    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.orchestration import base
+from tempest import test
+
+
+class ResourceTypesTest(base.BaseOrchestrationTest):
+
+    @test.attr(type='smoke')
+    def test_resource_type_list(self):
+        """Verify it is possible to list resource types."""
+        resource_types = self.client.list_resource_types()
+        self.assertIsInstance(resource_types, list)
+        self.assertIn('OS::Nova::Server', resource_types)
+
+    @test.attr(type='smoke')
+    def test_resource_type_show(self):
+        """Verify it is possible to get schema about resource types."""
+        resource_types = self.client.list_resource_types()
+        self.assertNotEmpty(resource_types)
+
+        for resource_type in resource_types:
+            type_schema = self.client.get_resource_type(resource_type)
+            self.assert_fields_in_dict(type_schema, 'properties',
+                                       'attributes', 'resource_type')
+            self.assertEqual(resource_type, type_schema['resource_type'])
+
+    @test.attr(type='smoke')
+    def test_resource_type_template(self):
+        """Verify it is possible to get template about resource types."""
+        type_template = self.client.get_resource_type_template(
+            'OS::Nova::Server')
+        self.assert_fields_in_dict(type_template, 'Outputs',
+            'Parameters', 'Resources')
\ No newline at end of file
diff --git a/tempest/api/orchestration/stacks/test_soft_conf.py b/tempest/api/orchestration/stacks/test_soft_conf.py
new file mode 100644
index 0000000..8903d4c
--- /dev/null
+++ b/tempest/api/orchestration/stacks/test_soft_conf.py
@@ -0,0 +1,163 @@
+#    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.orchestration import base
+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 import test
+
+LOG = logging.getLogger(__name__)
+CONF = config.CONF
+
+
+class TestSoftwareConfig(base.BaseOrchestrationTest):
+
+    def setUp(self):
+        super(TestSoftwareConfig, self).setUp()
+        self.configs = []
+        # Add 2 sets of software configuration
+        self.configs.append(self._config_create('a'))
+        self.configs.append(self._config_create('b'))
+        # Create a deployment using config a's id
+        self._deployment_create(self.configs[0]['id'])
+
+    def _config_create(self, suffix):
+        configuration = {'group': 'script',
+                         'inputs': [],
+                         'outputs': [],
+                         'options': {}}
+        configuration['name'] = 'heat_soft_config_%s' % suffix
+        configuration['config'] = '#!/bin/bash echo init-%s' % suffix
+        api_config = self.client.create_software_config(**configuration)
+        configuration['id'] = api_config['software_config']['id']
+        self.addCleanup(self._config_delete, configuration['id'])
+        self._validate_config(configuration, api_config)
+        return configuration
+
+    def _validate_config(self, configuration, api_config):
+        # Assert all expected keys are present with matching data
+        for k in configuration.keys():
+            self.assertEqual(configuration[k],
+                             api_config['software_config'][k])
+
+    def _deployment_create(self, config_id):
+        self.server_id = data_utils.rand_name('dummy-server')
+        self.action = 'ACTION_0'
+        self.status = 'STATUS_0'
+        self.input_values = {}
+        self.output_values = []
+        self.status_reason = 'REASON_0'
+        self.signal_transport = 'NO_SIGNAL'
+        self.deployment = self.client.create_software_deploy(
+            self.server_id, config_id, self.action, self.status,
+            self.input_values, self.output_values, self.status_reason,
+            self.signal_transport)
+        self.deployment_id = self.deployment['software_deployment']['id']
+        self.addCleanup(self._deployment_delete, self.deployment_id)
+
+    def _deployment_delete(self, deploy_id):
+        self.client.delete_software_deploy(deploy_id)
+        # Testing that it is really gone
+        self.assertRaises(
+            exceptions.NotFound, self.client.get_software_deploy,
+            self.deployment_id)
+
+    def _config_delete(self, config_id):
+        self.client.delete_software_config(config_id)
+        # Testing that it is really gone
+        self.assertRaises(
+            exceptions.NotFound, self.client.get_software_config, config_id)
+
+    @test.attr(type='smoke')
+    def test_get_software_config(self):
+        """Testing software config get."""
+        for conf in self.configs:
+            api_config = self.client.get_software_config(conf['id'])
+            self._validate_config(conf, api_config)
+
+    @test.attr(type='smoke')
+    def test_get_deployment_list(self):
+        """Getting a list of all deployments"""
+        deploy_list = self.client.get_software_deploy_list()
+        deploy_ids = [deploy['id'] for deploy in
+                      deploy_list['software_deployments']]
+        self.assertIn(self.deployment_id, deploy_ids)
+
+    @test.attr(type='smoke')
+    def test_get_deployment_metadata(self):
+        """Testing deployment metadata get"""
+        metadata = self.client.get_software_deploy_meta(self.server_id)
+        conf_ids = [conf['id'] for conf in metadata['metadata']]
+        self.assertIn(self.configs[0]['id'], conf_ids)
+
+    def _validate_deployment(self, action, status, reason, config_id):
+        deployment = self.client.get_software_deploy(self.deployment_id)
+        self.assertEqual(action, deployment['software_deployment']['action'])
+        self.assertEqual(status, deployment['software_deployment']['status'])
+        self.assertEqual(reason,
+                         deployment['software_deployment']['status_reason'])
+        self.assertEqual(config_id,
+                         deployment['software_deployment']['config_id'])
+
+    @test.attr(type='smoke')
+    def test_software_deployment_create_validate(self):
+        """Testing software deployment was created as expected."""
+        # Asserting that all fields were created
+        self.assert_fields_in_dict(
+            self.deployment['software_deployment'], 'action', 'config_id',
+            'id', 'input_values', 'output_values', 'server_id', 'status',
+            'status_reason')
+        # Testing get for this deployment and verifying parameters
+        self._validate_deployment(self.action, self.status,
+                                  self.status_reason, self.configs[0]['id'])
+
+    @test.attr(type='smoke')
+    def test_software_deployment_update_no_metadata_change(self):
+        """Testing software deployment update without metadata change."""
+        metadata = self.client.get_software_deploy_meta(self.server_id)
+        # Updating values without changing the configuration ID
+        new_action = 'ACTION_1'
+        new_status = 'STATUS_1'
+        new_reason = 'REASON_1'
+        self.client.update_software_deploy(
+            self.deployment_id, self.server_id, self.configs[0]['id'],
+            new_action, new_status, self.input_values, self.output_values,
+            new_reason, self.signal_transport)
+        # Verifying get and that the deployment was updated as expected
+        self._validate_deployment(new_action, new_status,
+                                  new_reason, self.configs[0]['id'])
+
+        # Metadata should not be changed at this point
+        test_metadata = self.client.get_software_deploy_meta(self.server_id)
+        for key in metadata['metadata'][0]:
+            self.assertEqual(
+                metadata['metadata'][0][key],
+                test_metadata['metadata'][0][key])
+
+    @test.attr(type='smoke')
+    def test_software_deployment_update_with_metadata_change(self):
+        """Testing software deployment update with metadata change."""
+        metadata = self.client.get_software_deploy_meta(self.server_id)
+        self.client.update_software_deploy(
+            self.deployment_id, self.server_id, self.configs[1]['id'],
+            self.action, self.status, self.input_values,
+            self.output_values, self.status_reason, self.signal_transport)
+        self._validate_deployment(self.action, self.status,
+                                  self.status_reason, self.configs[1]['id'])
+        # Metadata should now be changed
+        new_metadata = self.client.get_software_deploy_meta(self.server_id)
+        # Its enough to test the ID in this case
+        meta_id = metadata['metadata'][0]['id']
+        test_id = new_metadata['metadata'][0]['id']
+        self.assertNotEqual(meta_id, test_id)
diff --git a/tempest/api/orchestration/stacks/test_stacks.py b/tempest/api/orchestration/stacks/test_stacks.py
index 5b45d82..8023f2c 100644
--- a/tempest/api/orchestration/stacks/test_stacks.py
+++ b/tempest/api/orchestration/stacks/test_stacks.py
@@ -28,8 +28,7 @@
 
     @test.attr(type='smoke')
     def test_stack_list_responds(self):
-        resp, stacks = self.client.list_stacks()
-        self.assertEqual('200', resp['status'])
+        _, stacks = self.client.list_stacks()
         self.assertIsInstance(stacks, list)
 
     @test.attr(type='smoke')
@@ -45,22 +44,22 @@
         self.client.wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
 
         # check for stack in list
-        resp, stacks = self.client.list_stacks()
+        _, stacks = self.client.list_stacks()
         list_ids = list([stack['id'] for stack in stacks])
         self.assertIn(stack_id, list_ids)
 
         # fetch the stack
-        resp, stack = self.client.get_stack(stack_identifier)
+        _, stack = self.client.get_stack(stack_identifier)
         self.assertEqual('CREATE_COMPLETE', stack['stack_status'])
 
         # fetch the stack by name
-        resp, stack = self.client.get_stack(stack_name)
+        _, stack = self.client.get_stack(stack_name)
         self.assertEqual('CREATE_COMPLETE', stack['stack_status'])
 
         # fetch the stack by id
-        resp, stack = self.client.get_stack(stack_id)
+        _, stack = self.client.get_stack(stack_id)
         self.assertEqual('CREATE_COMPLETE', stack['stack_status'])
 
         # delete the stack
-        resp = self.client.delete_stack(stack_identifier)
-        self.assertEqual('204', resp[0]['status'])
+        self.client.delete_stack(stack_identifier)
+        self.client.wait_for_stack_status(stack_identifier, 'DELETE_COMPLETE')
diff --git a/tempest/api/orchestration/stacks/test_swift_resources.py b/tempest/api/orchestration/stacks/test_swift_resources.py
index 6d53fb2..cbe62a1 100644
--- a/tempest/api/orchestration/stacks/test_swift_resources.py
+++ b/tempest/api/orchestration/stacks/test_swift_resources.py
@@ -30,7 +30,7 @@
     def setUpClass(cls):
         super(SwiftResourcesTestJSON, cls).setUpClass()
         cls.stack_name = data_utils.rand_name('heat')
-        template = cls.load_template('swift_basic')
+        template = cls.read_template('swift_basic')
         os = clients.Manager()
         if not CONF.service_available.swift:
             raise cls.skipException("Swift support is required")
@@ -49,8 +49,11 @@
 
     def test_created_resources(self):
         """Created stack should be in the list of existing stacks."""
-        resources = [('SwiftContainer', 'OS::Swift::Container'),
-                     ('SwiftContainerWebsite', 'OS::Swift::Container')]
+        swift_basic_template = self.load_template('swift_basic')
+        resources = [('SwiftContainer', swift_basic_template['resources'][
+                      'SwiftContainer']['type']),
+                     ('SwiftContainerWebsite', swift_basic_template[
+                      'resources']['SwiftContainerWebsite']['type'])]
         for resource_name, resource_type in resources:
             resource = self.test_resources.get(resource_name)
             self.assertIsInstance(resource, dict)
@@ -58,15 +61,16 @@
             self.assertEqual(resource_name, resource['logical_resource_id'])
             self.assertEqual('CREATE_COMPLETE', resource['resource_status'])
 
+    @test.services('object_storage')
     def test_created_containers(self):
         params = {'format': 'json'}
-        resp, container_list = \
+        _, container_list = \
             self.account_client.list_account_containers(params=params)
-        self.assertEqual('200', resp['status'])
         self.assertEqual(2, len(container_list))
         for cont in container_list:
             self.assertTrue(cont['name'].startswith(self.stack_name))
 
+    @test.services('object_storage')
     def test_acl(self):
         acl_headers = ('x-container-meta-web-index', 'x-container-read')
 
@@ -83,11 +87,11 @@
         for h in acl_headers:
             self.assertIn(h, headers)
 
+    @test.services('object_storage')
     def test_metadata(self):
-        metadatas = {
-            "web-index": "index.html",
-            "web-error": "error.html"
-        }
+        swift_basic_template = self.load_template('swift_basic')
+        metadatas = swift_basic_template['resources']['SwiftContainerWebsite'][
+            'properties']['X-Container-Meta']
         swcont_website = self.test_resources.get(
             'SwiftContainerWebsite')['physical_resource_id']
         headers, _ = self.container_client.list_container_metadata(
diff --git a/tempest/api/orchestration/stacks/test_templates.py b/tempest/api/orchestration/stacks/test_templates.py
index 74950a9..0d6060d 100644
--- a/tempest/api/orchestration/stacks/test_templates.py
+++ b/tempest/api/orchestration/stacks/test_templates.py
@@ -39,15 +39,13 @@
     @test.attr(type='gate')
     def test_show_template(self):
         """Getting template used to create the stack."""
-        resp, template = self.client.show_template(self.stack_identifier)
-        self.assertEqual('200', resp['status'])
+        _, template = self.client.show_template(self.stack_identifier)
 
     @test.attr(type='gate')
     def test_validate_template(self):
         """Validating template passing it content."""
-        resp, parameters = self.client.validate_template(self.template,
-                                                         self.parameters)
-        self.assertEqual('200', resp['status'])
+        _, parameters = self.client.validate_template(self.template,
+                                                      self.parameters)
 
 
 class TemplateAWSTestJSON(TemplateYAMLTestJSON):
diff --git a/tempest/api/orchestration/stacks/test_update.py b/tempest/api/orchestration/stacks/test_update.py
index a9a43b6..791a19b 100644
--- a/tempest/api/orchestration/stacks/test_update.py
+++ b/tempest/api/orchestration/stacks/test_update.py
@@ -40,11 +40,10 @@
 
     def update_stack(self, stack_identifier, template):
         stack_name = stack_identifier.split('/')[0]
-        resp = self.client.update_stack(
+        self.client.update_stack(
             stack_identifier=stack_identifier,
             name=stack_name,
             template=template)
-        self.assertEqual('202', resp[0]['status'])
         self.client.wait_for_stack_status(stack_identifier, 'UPDATE_COMPLETE')
 
     @test.attr(type='gate')
diff --git a/tempest/api/orchestration/stacks/test_volumes.py b/tempest/api/orchestration/stacks/test_volumes.py
index 5ac2a8d..f371370 100644
--- a/tempest/api/orchestration/stacks/test_volumes.py
+++ b/tempest/api/orchestration/stacks/test_volumes.py
@@ -31,43 +31,44 @@
         if not CONF.service_available.cinder:
             raise cls.skipException('Cinder support is required')
 
-    def _cinder_verify(self, volume_id):
+    def _cinder_verify(self, volume_id, template):
         self.assertIsNotNone(volume_id)
-        resp, volume = self.volumes_client.get_volume(volume_id)
-        self.assertEqual(200, resp.status)
+        _, volume = self.volumes_client.get_volume(volume_id)
         self.assertEqual('available', volume.get('status'))
-        self.assertEqual(1, volume.get('size'))
-        self.assertEqual('a descriptive description',
-                         volume.get('display_description'))
-        self.assertEqual('volume_name',
-                         volume.get('display_name'))
+        self.assertEqual(template['resources']['volume']['properties'][
+            'size'], volume.get('size'))
+        self.assertEqual(template['resources']['volume']['properties'][
+            'description'], volume.get('display_description'))
+        self.assertEqual(template['resources']['volume']['properties'][
+            'name'], volume.get('display_name'))
 
-    def _outputs_verify(self, stack_identifier):
+    def _outputs_verify(self, stack_identifier, template):
         self.assertEqual('available',
                          self.get_stack_output(stack_identifier, 'status'))
-        self.assertEqual('1',
-                         self.get_stack_output(stack_identifier, 'size'))
-        self.assertEqual('a descriptive description',
-                         self.get_stack_output(stack_identifier,
-                                               'display_description'))
-        self.assertEqual('volume_name',
-                         self.get_stack_output(stack_identifier,
-                                               'display_name'))
+        self.assertEqual(str(template['resources']['volume']['properties'][
+            'size']), self.get_stack_output(stack_identifier, 'size'))
+        self.assertEqual(template['resources']['volume']['properties'][
+            'description'], self.get_stack_output(stack_identifier,
+                                                  'display_description'))
+        self.assertEqual(template['resources']['volume']['properties'][
+            'name'], self.get_stack_output(stack_identifier, 'display_name'))
 
     @test.attr(type='gate')
+    @test.services('volume')
     def test_cinder_volume_create_delete(self):
         """Create and delete a volume via OS::Cinder::Volume."""
         stack_name = data_utils.rand_name('heat')
-        template = self.load_template('cinder_basic')
+        template = self.read_template('cinder_basic')
         stack_identifier = self.create_stack(stack_name, template)
         self.client.wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
 
         # Verify with cinder that the volume exists, with matching details
         volume_id = self.get_stack_output(stack_identifier, 'volume_id')
-        self._cinder_verify(volume_id)
+        cinder_basic_template = self.load_template('cinder_basic')
+        self._cinder_verify(volume_id, cinder_basic_template)
 
         # Verify the stack outputs are as expected
-        self._outputs_verify(stack_identifier)
+        self._outputs_verify(stack_identifier, cinder_basic_template)
 
         # Delete the stack and ensure the volume is gone
         self.client.delete_stack(stack_identifier)
@@ -78,29 +79,30 @@
 
     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')
+    @test.services('volume')
     def test_cinder_volume_create_delete_retain(self):
         """Ensure the 'Retain' deletion policy is respected."""
         stack_name = data_utils.rand_name('heat')
-        template = self.load_template('cinder_basic_delete_retain')
+        template = self.read_template('cinder_basic_delete_retain')
         stack_identifier = self.create_stack(stack_name, template)
         self.client.wait_for_stack_status(stack_identifier, 'CREATE_COMPLETE')
 
         # Verify with cinder that the volume exists, with matching details
         volume_id = self.get_stack_output(stack_identifier, 'volume_id')
         self.addCleanup(self._cleanup_volume, volume_id)
-        self._cinder_verify(volume_id)
+        retain_template = self.load_template('cinder_basic_delete_retain')
+        self._cinder_verify(volume_id, retain_template)
 
         # Verify the stack outputs are as expected
-        self._outputs_verify(stack_identifier)
+        self._outputs_verify(stack_identifier, retain_template)
 
         # Delete the stack and ensure the volume is *not* gone
         self.client.delete_stack(stack_identifier)
         self.client.wait_for_stack_status(stack_identifier, 'DELETE_COMPLETE')
-        self._cinder_verify(volume_id)
+        self._cinder_verify(volume_id, retain_template)
 
         # Volume cleanup happens via addCleanup calling _cleanup_volume
diff --git a/tempest/api/queuing/base.py b/tempest/api/queuing/base.py
index f4ff7f1..41a02f2 100644
--- a/tempest/api/queuing/base.py
+++ b/tempest/api/queuing/base.py
@@ -26,7 +26,7 @@
 class BaseQueuingTest(test.BaseTestCase):
 
     """
-    Base class for the Queuing tests that use the Tempest Marconi REST client
+    Base class for the Queuing tests that use the Tempest Zaqar REST client
 
     It is assumed that the following option is defined in the
     [service_available] section of etc/tempest.conf
@@ -37,8 +37,8 @@
     @classmethod
     def setUpClass(cls):
         super(BaseQueuingTest, cls).setUpClass()
-        if not CONF.service_available.marconi:
-            raise cls.skipException("Marconi support is required")
+        if not CONF.service_available.zaqar:
+            raise cls.skipException("Zaqar support is required")
         os = cls.get_client_manager()
         cls.queuing_cfg = CONF.queuing
         cls.client = os.queuing_client
diff --git a/tempest/api/queuing/test_queues.py b/tempest/api/queuing/test_queues.py
index e43178a..b340b60 100644
--- a/tempest/api/queuing/test_queues.py
+++ b/tempest/api/queuing/test_queues.py
@@ -14,6 +14,7 @@
 # limitations under the License.
 
 import logging
+
 from six import moves
 from testtools import matchers
 
diff --git a/tempest/api/telemetry/base.py b/tempest/api/telemetry/base.py
index 2b422fd..8c2f37b 100644
--- a/tempest/api/telemetry/base.py
+++ b/tempest/api/telemetry/base.py
@@ -29,24 +29,33 @@
     def setUpClass(cls):
         if not CONF.service_available.ceilometer:
             raise cls.skipException("Ceilometer support is required")
+        cls.set_network_resources()
         super(BaseTelemetryTest, cls).setUpClass()
         os = cls.get_client_manager()
         cls.telemetry_client = os.telemetry_client
         cls.servers_client = os.servers_client
         cls.flavors_client = os.flavors_client
+        cls.image_client = os.image_client
+        cls.image_client_v2 = os.image_client_v2
 
         cls.nova_notifications = ['memory', 'vcpus', 'disk.root.size',
                                   'disk.ephemeral.size']
+
+        cls.glance_notifications = ['image.update', 'image.upload',
+                                    'image.delete']
+
+        cls.glance_v2_notifications = ['image.download', 'image.serve']
+
         cls.server_ids = []
         cls.alarm_ids = []
+        cls.image_ids = []
 
     @classmethod
     def create_alarm(cls, **kwargs):
         resp, body = cls.telemetry_client.create_alarm(
             name=data_utils.rand_name('telemetry_alarm'),
             type='threshold', **kwargs)
-        if resp['status'] == '201':
-            cls.alarm_ids.append(body['alarm_id'])
+        cls.alarm_ids.append(body['alarm_id'])
         return resp, body
 
     @classmethod
@@ -55,8 +64,15 @@
             data_utils.rand_name('ceilometer-instance'),
             CONF.compute.image_ref, CONF.compute.flavor_ref,
             wait_until='ACTIVE')
-        if resp['status'] == '202':
-            cls.server_ids.append(body['id'])
+        cls.server_ids.append(body['id'])
+        return resp, body
+
+    @classmethod
+    def create_image(cls, client):
+        resp, body = client.create_image(
+            data_utils.rand_name('image'), container_format='bare',
+            disk_format='raw', visibility='private')
+        cls.image_ids.append(body['id'])
         return resp, body
 
     @staticmethod
@@ -71,6 +87,7 @@
     def tearDownClass(cls):
         cls.cleanup_resources(cls.telemetry_client.delete_alarm, cls.alarm_ids)
         cls.cleanup_resources(cls.servers_client.delete_server, cls.server_ids)
+        cls.cleanup_resources(cls.image_client.delete_image, cls.image_ids)
         cls.clear_isolated_creds()
         super(BaseTelemetryTest, cls).tearDownClass()
 
diff --git a/tempest/api/telemetry/test_telemetry_notification_api.py b/tempest/api/telemetry/test_telemetry_notification_api.py
index 148f5a3..9b15c51 100644
--- a/tempest/api/telemetry/test_telemetry_notification_api.py
+++ b/tempest/api/telemetry/test_telemetry_notification_api.py
@@ -32,6 +32,7 @@
     @test.attr(type="gate")
     @testtools.skipIf(not CONF.service_available.nova,
                       "Nova is not available.")
+    @test.skip_because(bug="1336755")
     def test_check_nova_notification(self):
 
         resp, body = self.create_server()
@@ -42,6 +43,38 @@
         for metric in self.nova_notifications:
             self.await_samples(metric, query)
 
+    @test.attr(type="smoke")
+    @test.services("image")
+    @testtools.skipIf(not CONF.image_feature_enabled.api_v1,
+                      "Glance api v1 is disabled")
+    @test.skip_because(bug='1351627')
+    def test_check_glance_v1_notifications(self):
+        _, body = self.create_image(self.image_client)
+        self.image_client.update_image(body['id'], data='data')
+
+        query = 'resource', 'eq', body['id']
+
+        self.image_client.delete_image(body['id'])
+
+        for metric in self.glance_notifications:
+            self.await_samples(metric, query)
+
+    @test.attr(type="smoke")
+    @test.services("image")
+    @testtools.skipIf(not CONF.image_feature_enabled.api_v2,
+                      "Glance api v2 is disabled")
+    @test.skip_because(bug='1351627')
+    def test_check_glance_v2_notifications(self):
+        _, body = self.create_image(self.image_client_v2)
+
+        self.image_client_v2.store_image(body['id'], "file")
+        self.image_client_v2.get_image_file(body['id'])
+
+        query = 'resource', 'eq', body['id']
+
+        for metric in self.glance_v2_notifications:
+            self.await_samples(metric, query)
+
 
 class TelemetryNotificationAPITestXML(TelemetryNotificationAPITestJSON):
     _interface = 'xml'
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index e79d23c..f3b1ad5 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -36,42 +36,55 @@
 
         cls.volume_client = cls.os_adm.volumes_client
         cls.volume_type_id_list = []
-        cls.volume_id_list = []
+        cls.volume_id_list_with_prefix = []
+        cls.volume_id_list_without_prefix = []
 
-        # Volume/Type creation (uses backend1_name)
-        type1_name = data_utils.rand_name('Type-')
-        vol1_name = data_utils.rand_name('Volume-')
-        extra_specs1 = {"volume_backend_name": cls.backend1_name}
-        resp, cls.type1 = cls.client.create_volume_type(
-            type1_name, extra_specs=extra_specs1)
-        cls.volume_type_id_list.append(cls.type1['id'])
-
-        resp, cls.volume1 = cls.volume_client.create_volume(
-            size=1, display_name=vol1_name, volume_type=type1_name)
-        cls.volume_id_list.append(cls.volume1['id'])
-        cls.volume_client.wait_for_volume_status(cls.volume1['id'],
-                                                 'available')
+        # Volume/Type creation (uses volume_backend_name)
+        cls._create_type_and_volume(cls.backend1_name, False)
+        # Volume/Type creation (uses capabilities:volume_backend_name)
+        cls._create_type_and_volume(cls.backend1_name, True)
 
         if cls.backend1_name != cls.backend2_name:
             # Volume/Type creation (uses backend2_name)
-            type2_name = data_utils.rand_name('Type-')
-            vol2_name = data_utils.rand_name('Volume-')
-            extra_specs2 = {"volume_backend_name": cls.backend2_name}
-            resp, cls.type2 = cls.client.create_volume_type(
-                type2_name, extra_specs=extra_specs2)
-            cls.volume_type_id_list.append(cls.type2['id'])
+            cls._create_type_and_volume(cls.backend2_name, False)
+            # Volume/Type creation (uses capabilities:volume_backend_name)
+            cls._create_type_and_volume(cls.backend2_name, True)
 
-            resp, cls.volume2 = cls.volume_client.create_volume(
-                size=1, display_name=vol2_name, volume_type=type2_name)
-            cls.volume_id_list.append(cls.volume2['id'])
-            cls.volume_client.wait_for_volume_status(cls.volume2['id'],
-                                                     'available')
+    @classmethod
+    def _create_type_and_volume(self, backend_name_key, with_prefix):
+        # Volume/Type creation
+        type_name = data_utils.rand_name('Type')
+        vol_name = data_utils.rand_name('Volume')
+        spec_key_with_prefix = "capabilities:volume_backend_name"
+        spec_key_without_prefix = "volume_backend_name"
+        if with_prefix:
+            extra_specs = {spec_key_with_prefix: backend_name_key}
+        else:
+            extra_specs = {spec_key_without_prefix: backend_name_key}
+        _, self.type = self.client.create_volume_type(
+            type_name, extra_specs=extra_specs)
+        self.volume_type_id_list.append(self.type['id'])
+
+        _, 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')
+        if with_prefix:
+            self.volume_id_list_with_prefix.append(self.volume['id'])
+        else:
+            self.volume_id_list_without_prefix.append(
+                self.volume['id'])
 
     @classmethod
     def tearDownClass(cls):
         # volumes deletion
-        volume_id_list = getattr(cls, 'volume_id_list', [])
-        for volume_id in volume_id_list:
+        vid_prefix = getattr(cls, 'volume_id_list_with_prefix', [])
+        for volume_id in vid_prefix:
+            cls.volume_client.delete_volume(volume_id)
+            cls.volume_client.wait_for_resource_deletion(volume_id)
+
+        vid_no_pre = getattr(cls, 'volume_id_list_without_prefix', [])
+        for volume_id in vid_no_pre:
             cls.volume_client.delete_volume(volume_id)
             cls.volume_client.wait_for_resource_deletion(volume_id)
 
@@ -84,32 +97,56 @@
 
     @test.attr(type='smoke')
     def test_backend_name_reporting(self):
+        # get volume id which created by type without prefix
+        volume_id = self.volume_id_list_without_prefix[0]
+        self._test_backend_name_reporting_by_volume_id(volume_id)
+
+    @test.attr(type='smoke')
+    def test_backend_name_reporting_with_prefix(self):
+        # get volume id which created by type with prefix
+        volume_id = self.volume_id_list_with_prefix[0]
+        self._test_backend_name_reporting_by_volume_id(volume_id)
+
+    @test.attr(type='gate')
+    def test_backend_name_distinction(self):
+        if self.backend1_name == self.backend2_name:
+            raise self.skipException("backends configured with same name")
+        # get volume id which created by type without prefix
+        volume1_id = self.volume_id_list_without_prefix[0]
+        volume2_id = self.volume_id_list_without_prefix[1]
+        self._test_backend_name_distinction(volume1_id, volume2_id)
+
+    @test.attr(type='gate')
+    def test_backend_name_distinction_with_prefix(self):
+        if self.backend1_name == self.backend2_name:
+            raise self.skipException("backends configured with same name")
+        # get volume id which created by type without prefix
+        volume1_id = self.volume_id_list_with_prefix[0]
+        volume2_id = self.volume_id_list_with_prefix[1]
+        self._test_backend_name_distinction(volume1_id, volume2_id)
+
+    def _test_backend_name_reporting_by_volume_id(self, volume_id):
         # this test checks if os-vol-attr:host is populated correctly after
         # 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(self.volume1['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" %
-               self.volume1['id'])
+               volume_id)
         self.assertTrue(len(volume1_host.split("@")) > 1, msg)
 
-    @test.attr(type='gate')
-    def test_backend_name_distinction(self):
+    def _test_backend_name_distinction(self, volume1_id, volume2_id):
         # 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)
-        if self.backend1_name == self.backend2_name:
-            raise self.skipException("backends configured with same name")
-
-        resp, volume = self.volume_client.get_volume(self.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(self.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" %
-               (self.volume1['id'], self.volume2['id']))
+               (volume1_id, volume2_id))
         self.assertNotEqual(volume1_host, volume2_host, msg)
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 c5be1f3..3cd0827 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -61,12 +61,21 @@
             cls.volumes_extension_client = cls.os.volumes_extension_client
             cls.availability_zone_client = (
                 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'}
 
         elif cls._api_version == 2:
             if not CONF.volume_feature_enabled.api_v2:
                 msg = "Volume API v2 is disabled"
                 raise cls.skipException(msg)
             cls.volumes_client = cls.os.volumes_v2_client
+            cls.volumes_extension_client = cls.os.volumes_v2_extension_client
+            cls.availability_zone_client = (
+                cls.os.volume_v2_availability_zone_client)
+            # Special fields and resp code for cinder v2
+            cls.special_fields = {'name_field': 'name',
+                                  'descrip_field': 'description'}
 
         else:
             msg = ("Invalid Cinder API version (%s)" % cls._api_version)
@@ -82,15 +91,13 @@
     @classmethod
     def create_volume(cls, size=1, **kwargs):
         """Wrapper utility that returns a test volume."""
-        vol_name = data_utils.rand_name('Volume')
-        if cls._api_version == 1:
-            resp, volume = cls.volumes_client.create_volume(
-                size, display_name=vol_name, **kwargs)
-            assert 200 == resp.status
-        elif cls._api_version == 2:
-            resp, volume = cls.volumes_client.create_volume(
-                size, name=vol_name, **kwargs)
-            assert 202 == resp.status
+        name = data_utils.rand_name('Volume')
+
+        name_field = cls.special_fields['name_field']
+
+        kwargs[name_field] = name
+        _, volume = cls.volumes_client.create_volume(size, **kwargs)
+
         cls.volumes.append(volume)
         cls.volumes_client.wait_for_volume_status(volume['id'], 'available')
         return volume
@@ -98,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 fe8f96e..c026f71 100644
--- a/tempest/api/volume/test_availability_zone.py
+++ b/tempest/api/volume/test_availability_zone.py
@@ -17,25 +17,31 @@
 from tempest import test
 
 
-class AvailabilityZoneTestJSON(base.BaseVolumeV1Test):
+class AvailabilityZoneV2TestJSON(base.BaseVolumeTest):
 
     """
-    Tests Availability Zone API List
+    Tests Availability Zone V2 API List
     """
-    _interface = 'json'
 
     @classmethod
     def setUpClass(cls):
-        super(AvailabilityZoneTestJSON, cls).setUpClass()
+        super(AvailabilityZoneV2TestJSON, cls).setUpClass()
         cls.client = cls.availability_zone_client
 
     @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)
 
 
-class AvailabilityZoneTestXML(AvailabilityZoneTestJSON):
+class AvailabilityZoneV2TestXML(AvailabilityZoneV2TestJSON):
+    _interface = 'xml'
+
+
+class AvailabilityZoneV1TestJSON(AvailabilityZoneV2TestJSON):
+    _api_version = 1
+
+
+class AvailabilityZoneV1TestXML(AvailabilityZoneV1TestJSON):
     _interface = 'xml'
diff --git a/tempest/api/volume/test_extensions.py b/tempest/api/volume/test_extensions.py
index ce019a2..4fc6ee4 100644
--- a/tempest/api/volume/test_extensions.py
+++ b/tempest/api/volume/test_extensions.py
@@ -25,14 +25,12 @@
 LOG = logging.getLogger(__name__)
 
 
-class ExtensionsTestJSON(base.BaseVolumeV1Test):
-    _interface = 'json'
+class ExtensionsV2TestJSON(base.BaseVolumeTest):
 
     @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]
@@ -46,5 +44,13 @@
             raise self.skipException('There are not any extensions configured')
 
 
-class ExtensionsTestXML(ExtensionsTestJSON):
+class ExtensionsV2TestXML(ExtensionsV2TestJSON):
+    _interface = 'xml'
+
+
+class ExtensionsV1TestJSON(ExtensionsV2TestJSON):
+    _api_version = 1
+
+
+class ExtensionsV1TestXML(ExtensionsV1TestJSON):
     _interface = 'xml'
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 0d57d47..ac760aa 100644
--- a/tempest/api/volume/test_volume_metadata.py
+++ b/tempest/api/volume/test_volume_metadata.py
@@ -19,13 +19,12 @@
 from tempest import test
 
 
-class VolumeMetadataTest(base.BaseVolumeV1Test):
-    _interface = "json"
+class VolumesV2MetadataTest(base.BaseVolumeTest):
 
     @classmethod
     @test.safe_setup
     def setUpClass(cls):
-        super(VolumeMetadataTest, cls).setUpClass()
+        super(VolumesV2MetadataTest, cls).setUpClass()
         # Create a volume
         cls.volume = cls.create_volume()
         cls.volume_id = cls.volume['id']
@@ -33,7 +32,7 @@
     def tearDown(self):
         # Update the metadata to {}
         self.volumes_client.update_volume_metadata(self.volume_id, {})
-        super(VolumeMetadataTest, self).tearDown()
+        super(VolumesV2MetadataTest, self).tearDown()
 
     @test.attr(type='gate')
     def test_create_get_delete_volume_metadata(self):
@@ -43,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()))
@@ -71,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')
@@ -100,22 +89,24 @@
                   "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()))
 
 
-class VolumeMetadataTestXML(VolumeMetadataTest):
+class VolumesV2MetadataTestXML(VolumesV2MetadataTest):
+    _interface = "xml"
+
+
+class VolumesV1MetadataTest(VolumesV2MetadataTest):
+    _api_version = 1
+
+
+class VolumesV1MetadataTestXML(VolumesV1MetadataTest):
     _interface = "xml"
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 82d1364..4a6ba03 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -23,12 +23,11 @@
 CONF = config.CONF
 
 
-class VolumesTransfersTest(base.BaseVolumeV1Test):
-    _interface = "json"
+class VolumesV2TransfersTest(base.BaseVolumeTest):
 
     @classmethod
     def setUpClass(cls):
-        super(VolumesTransfersTest, cls).setUpClass()
+        super(VolumesV2TransfersTest, cls).setUpClass()
 
         # Add another tenant to test volume-transfer
         if CONF.compute.allow_tenant_isolation:
@@ -48,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')
@@ -59,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):
@@ -89,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
@@ -105,10 +97,17 @@
             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')
 
 
-class VolumesTransfersTestXML(VolumesTransfersTest):
+class VolumesV2TransfersTestXML(VolumesV2TransfersTest):
+    _interface = "xml"
+
+
+class VolumesV1TransfersTest(VolumesV2TransfersTest):
+    _api_version = 1
+
+
+class VolumesV1TransfersTestXML(VolumesV1TransfersTest):
     _interface = "xml"
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index cfab0bd..c87878d 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -21,13 +21,12 @@
 CONF = config.CONF
 
 
-class VolumesActionsTest(base.BaseVolumeV1Test):
-    _interface = "json"
+class VolumesV2ActionsTest(base.BaseVolumeTest):
 
     @classmethod
     @test.safe_setup
     def setUpClass(cls):
-        super(VolumesActionsTest, cls).setUpClass()
+        super(VolumesV2ActionsTest, cls).setUpClass()
         cls.client = cls.volumes_client
         cls.image_client = cls.os.image_client
 
@@ -41,13 +40,17 @@
         # 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
         cls.servers_client.delete_server(cls.server['id'])
         cls.servers_client.wait_for_server_termination(cls.server['id'])
 
-        super(VolumesActionsTest, cls).tearDownClass()
+        super(VolumesV2ActionsTest, cls).tearDownClass()
 
     @test.stresstest(class_setup_per='process')
     @test.attr(type='smoke')
@@ -55,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')
@@ -70,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)
@@ -81,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'])
@@ -98,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):
@@ -142,28 +125,31 @@
     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)
 
 
-class VolumesActionsTestXML(VolumesActionsTest):
+class VolumesV2ActionsTestXML(VolumesV2ActionsTest):
+    _interface = "xml"
+
+
+class VolumesV1ActionsTest(VolumesV2ActionsTest):
+    _api_version = 1
+
+
+class VolumesV1ActionsTestXML(VolumesV1ActionsTest):
     _interface = "xml"
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 2745b95..a346a17 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -23,17 +23,18 @@
 CONF = config.CONF
 
 
-class VolumesGetTest(base.BaseVolumeV1Test):
-    _interface = "json"
+class VolumesV2GetTest(base.BaseVolumeTest):
 
     @classmethod
     def setUpClass(cls):
-        super(VolumesGetTest, cls).setUpClass()
+        super(VolumesV2GetTest, cls).setUpClass()
         cls.client = cls.volumes_client
 
+        cls.name_field = cls.special_fields['name_field']
+        cls.descrip_field = cls.special_fields['descrip_field']
+
     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):
@@ -51,24 +52,22 @@
         v_name = data_utils.rand_name('Volume')
         metadata = {'Type': 'Test'}
         # Create a volume
-        resp, volume = self.client.create_volume(display_name=v_name,
-                                                 metadata=metadata,
-                                                 **kwargs)
-        self.assertEqual(200, resp.status)
+        kwargs[self.name_field] = v_name
+        kwargs['metadata'] = metadata
+        _, volume = self.client.create_volume(**kwargs)
         self.assertIn('id', volume)
         self.addCleanup(self._delete_volume, volume['id'])
-        self.assertIn('display_name', volume)
-        self.assertEqual(volume['display_name'], v_name,
+        self.client.wait_for_volume_status(volume['id'], 'available')
+        self.assertIn(self.name_field, volume)
+        self.assertEqual(volume[self.name_field], v_name,
                          "The created volume name is not equal "
                          "to the requested name")
         self.assertTrue(volume['id'] is not None,
                         "Field volume id is empty or not found.")
-        self.client.wait_for_volume_status(volume['id'], 'available')
         # 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['display_name'],
+                         fetched_volume[self.name_field],
                          'The fetched Volume name is different '
                          'from the created Volume')
         self.assertEqual(volume['id'],
@@ -90,27 +89,22 @@
 
         # Update Volume
         # Test volume update when display_name is same with original value
-        resp, update_volume = \
-            self.client.update_volume(volume['id'],
-                                      display_name=v_name)
-        self.assertEqual(200, resp.status)
+        params = {self.name_field: v_name}
+        _, 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'
-        resp, update_volume = \
-            self.client.update_volume(volume['id'],
-                                      display_name=new_v_name,
-                                      display_description=new_desc)
+        params = {self.name_field: new_v_name,
+                  self.descrip_field: new_desc}
+        _, 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['display_name'])
-        self.assertEqual(new_desc, update_volume['display_description'])
+        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['display_name'])
-        self.assertEqual(new_desc, updated_volume['display_description'])
+        self.assertEqual(new_v_name, updated_volume[self.name_field])
+        self.assertEqual(new_desc, updated_volume[self.descrip_field])
         self.assertThat(updated_volume['metadata'].items(),
                         matchers.ContainsAll(metadata.items()),
                         'The fetched Volume metadata misses data '
@@ -120,21 +114,17 @@
         # then test volume update if display_name is duplicated
         new_volume = {}
         new_v_desc = data_utils.rand_name('@#$%^* description')
-        resp, new_volume = \
-            self.client.create_volume(
-                size=1,
-                display_description=new_v_desc,
-                availability_zone=volume['availability_zone'])
-        self.assertEqual(200, resp.status)
+        params = {self.descrip_field: new_v_desc,
+                  'availability_zone': volume['availability_zone']}
+        _, 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')
-        resp, update_volume = \
-            self.client.update_volume(
-                new_volume['id'],
-                display_name=volume['display_name'],
-                display_description=volume['display_description'])
-        self.assertEqual(200, resp.status)
+
+        params = {self.name_field: volume[self.name_field],
+                  self.descrip_field: volume[self.descrip_field]}
+        _, 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
@@ -159,5 +149,13 @@
         self._volume_create_get_update_delete(source_volid=origin['id'])
 
 
-class VolumesGetTestXML(VolumesGetTest):
+class VolumesV2GetTestXML(VolumesV2GetTest):
+    _interface = "xml"
+
+
+class VolumesV1GetTest(VolumesV2GetTest):
+    _api_version = 1
+
+
+class VolumesV1GetTestXML(VolumesV1GetTest):
     _interface = "xml"
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index b8a2faa..272a41a 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -15,11 +15,12 @@
 #    under the License.
 import operator
 
+from testtools import matchers
+
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest.openstack.common import log as logging
 from tempest import test
-from testtools import matchers
 
 LOG = logging.getLogger(__name__)
 
@@ -66,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'])
 
@@ -74,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()
 
@@ -84,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
@@ -112,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)
 
@@ -121,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])
@@ -139,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])
@@ -148,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)
@@ -157,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)
@@ -168,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)
@@ -179,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 bc5b1dc..5f0cffa 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -21,15 +21,16 @@
 from tempest import test
 
 
-class VolumesNegativeTest(base.BaseVolumeV1Test):
-    _interface = 'json'
+class VolumesV2NegativeTest(base.BaseVolumeTest):
 
     @classmethod
     @test.safe_setup
     def setUpClass(cls):
-        super(VolumesNegativeTest, cls).setUpClass()
+        super(VolumesV2NegativeTest, cls).setUpClass()
         cls.client = cls.volumes_client
 
+        cls.name_field = cls.special_fields['name_field']
+
         # Create a test shared instance and volume for attach/detach tests
         cls.volume = cls.create_volume()
         cls.mountpoint = "/dev/vdc"
@@ -224,46 +225,49 @@
     @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 = {'display_name': v_name}
-        resp, fetched_volume = self.client.list_volumes(params)
-        self.assertEqual(200, resp.status)
+        params = {self.name_field: v_name}
+        _, 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 = {'display_name': v_name}
-        resp, fetched_volume = self.client.list_volumes_with_detail(params)
-        self.assertEqual(200, resp.status)
+        params = {self.name_field: v_name}
+        _, 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))
 
 
-class VolumesNegativeTestXML(VolumesNegativeTest):
+class VolumesV2NegativeTestXML(VolumesV2NegativeTest):
+    _interface = 'xml'
+
+
+class VolumesV1NegativeTest(VolumesV2NegativeTest):
+    _api_version = 1
+    _name = 'display_name'
+
+
+class VolumesV1NegativeTestXML(VolumesV1NegativeTest):
     _interface = 'xml'
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/compute/__init__.py b/tempest/api_schema/request/__init__.py
similarity index 100%
copy from tempest/api_schema/compute/__init__.py
copy to tempest/api_schema/request/__init__.py
diff --git a/tempest/api_schema/compute/__init__.py b/tempest/api_schema/request/compute/__init__.py
similarity index 100%
rename from tempest/api_schema/compute/__init__.py
rename to 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/compute/v2/__init__.py b/tempest/api_schema/request/compute/v2/__init__.py
similarity index 100%
rename from tempest/api_schema/compute/v2/__init__.py
rename to 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/compute/v3/__init__.py b/tempest/api_schema/request/compute/v3/__init__.py
similarity index 100%
rename from tempest/api_schema/compute/v3/__init__.py
rename to 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/api_schema/compute/__init__.py b/tempest/api_schema/response/__init__.py
similarity index 100%
copy from tempest/api_schema/compute/__init__.py
copy to tempest/api_schema/response/__init__.py
diff --git a/tempest/api_schema/compute/__init__.py b/tempest/api_schema/response/compute/__init__.py
similarity index 100%
copy from tempest/api_schema/compute/__init__.py
copy to tempest/api_schema/response/compute/__init__.py
diff --git a/tempest/api_schema/compute/agents.py b/tempest/api_schema/response/compute/agents.py
similarity index 100%
rename from tempest/api_schema/compute/agents.py
rename to tempest/api_schema/response/compute/agents.py
diff --git a/tempest/api_schema/compute/aggregates.py b/tempest/api_schema/response/compute/aggregates.py
similarity index 100%
rename from tempest/api_schema/compute/aggregates.py
rename to tempest/api_schema/response/compute/aggregates.py
diff --git a/tempest/api_schema/compute/availability_zone.py b/tempest/api_schema/response/compute/availability_zone.py
similarity index 100%
rename from tempest/api_schema/compute/availability_zone.py
rename to tempest/api_schema/response/compute/availability_zone.py
diff --git a/tempest/api_schema/compute/certificates.py b/tempest/api_schema/response/compute/certificates.py
similarity index 100%
rename from tempest/api_schema/compute/certificates.py
rename to tempest/api_schema/response/compute/certificates.py
diff --git a/tempest/api_schema/compute/flavors.py b/tempest/api_schema/response/compute/flavors.py
similarity index 96%
rename from tempest/api_schema/compute/flavors.py
rename to tempest/api_schema/response/compute/flavors.py
index aa019e4..44020d2 100644
--- a/tempest/api_schema/compute/flavors.py
+++ b/tempest/api_schema/response/compute/flavors.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api_schema.compute import parameter_types
+from tempest.api_schema.response.compute import parameter_types
 
 list_flavors = {
     'status_code': [200],
diff --git a/tempest/api_schema/compute/flavors_access.py b/tempest/api_schema/response/compute/flavors_access.py
similarity index 100%
rename from tempest/api_schema/compute/flavors_access.py
rename to tempest/api_schema/response/compute/flavors_access.py
diff --git a/tempest/api_schema/compute/flavors_extra_specs.py b/tempest/api_schema/response/compute/flavors_extra_specs.py
similarity index 100%
rename from tempest/api_schema/compute/flavors_extra_specs.py
rename to tempest/api_schema/response/compute/flavors_extra_specs.py
diff --git a/tempest/api_schema/compute/hosts.py b/tempest/api_schema/response/compute/hosts.py
similarity index 100%
rename from tempest/api_schema/compute/hosts.py
rename to tempest/api_schema/response/compute/hosts.py
diff --git a/tempest/api_schema/compute/hypervisors.py b/tempest/api_schema/response/compute/hypervisors.py
similarity index 100%
rename from tempest/api_schema/compute/hypervisors.py
rename to tempest/api_schema/response/compute/hypervisors.py
diff --git a/tempest/api_schema/compute/interfaces.py b/tempest/api_schema/response/compute/interfaces.py
similarity index 95%
rename from tempest/api_schema/compute/interfaces.py
rename to tempest/api_schema/response/compute/interfaces.py
index 79a8f42..fd53eb3 100644
--- a/tempest/api_schema/compute/interfaces.py
+++ b/tempest/api_schema/response/compute/interfaces.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api_schema.compute import parameter_types
+from tempest.api_schema.response.compute import parameter_types
 
 delete_interface = {
     'status_code': [202]
diff --git a/tempest/api_schema/compute/keypairs.py b/tempest/api_schema/response/compute/keypairs.py
similarity index 100%
rename from tempest/api_schema/compute/keypairs.py
rename to tempest/api_schema/response/compute/keypairs.py
diff --git a/tempest/api_schema/compute/migrations.py b/tempest/api_schema/response/compute/migrations.py
similarity index 100%
rename from tempest/api_schema/compute/migrations.py
rename to tempest/api_schema/response/compute/migrations.py
diff --git a/tempest/api_schema/compute/parameter_types.py b/tempest/api_schema/response/compute/parameter_types.py
similarity index 100%
rename from tempest/api_schema/compute/parameter_types.py
rename to tempest/api_schema/response/compute/parameter_types.py
diff --git a/tempest/api_schema/compute/quotas.py b/tempest/api_schema/response/compute/quotas.py
similarity index 100%
rename from tempest/api_schema/compute/quotas.py
rename to tempest/api_schema/response/compute/quotas.py
diff --git a/tempest/api_schema/compute/servers.py b/tempest/api_schema/response/compute/servers.py
similarity index 82%
rename from tempest/api_schema/compute/servers.py
rename to tempest/api_schema/response/compute/servers.py
index 6b27f3d..f9c957b 100644
--- a/tempest/api_schema/compute/servers.py
+++ b/tempest/api_schema/response/compute/servers.py
@@ -14,7 +14,7 @@
 
 import copy
 
-from tempest.api_schema.compute import parameter_types
+from tempest.api_schema.response.compute import parameter_types
 
 get_password = {
     'status_code': [200],
@@ -54,14 +54,15 @@
         'id': {'type': 'string'},
         'name': {'type': 'string'},
         'status': {'type': 'string'},
-        'image': {
-            'type': 'object',
-            'properties': {
-                'id': {'type': 'string'},
-                'links': parameter_types.links
-            },
-            'required': ['id', 'links']
-        },
+        'image': {'oneOf': [
+            {'type': 'object',
+                'properties': {
+                    'id': {'type': 'string'},
+                    'links': parameter_types.links
+                },
+                'required': ['id', 'links']},
+            {'type': ['string', 'null']}
+        ]},
         'flavor': {
             'type': 'object',
             'properties': {
@@ -182,6 +183,29 @@
                  'start_time', 'message']
 }
 
+instance_action_events = {
+    'type': 'array',
+    'items': {
+        'type': 'object',
+        'properties': {
+            'event': {'type': 'string'},
+            'start_time': {'type': 'string'},
+            'finish_time': {'type': 'string'},
+            'result': {'type': 'string'},
+            'traceback': {'type': ['string', 'null']}
+        },
+        'required': ['event', 'start_time', 'finish_time', 'result',
+                     'traceback']
+    }
+}
+
+common_get_instance_action = copy.deepcopy(common_instance_actions)
+
+common_get_instance_action['properties'].update({
+    'events': instance_action_events})
+# 'events' does not come in response body always so it is not
+# defined as 'required'
+
 base_list_servers_detail = {
     'status_code': [200],
     'response_body': {
diff --git a/tempest/api_schema/compute/services.py b/tempest/api_schema/response/compute/services.py
similarity index 100%
rename from tempest/api_schema/compute/services.py
rename to tempest/api_schema/response/compute/services.py
diff --git a/tempest/api_schema/compute/v2/__init__.py b/tempest/api_schema/response/compute/v2/__init__.py
similarity index 100%
copy from tempest/api_schema/compute/v2/__init__.py
copy to tempest/api_schema/response/compute/v2/__init__.py
diff --git a/tempest/api_schema/compute/v2/agents.py b/tempest/api_schema/response/compute/v2/agents.py
similarity index 93%
rename from tempest/api_schema/compute/v2/agents.py
rename to tempest/api_schema/response/compute/v2/agents.py
index 30f999f..d827377 100644
--- a/tempest/api_schema/compute/v2/agents.py
+++ b/tempest/api_schema/response/compute/v2/agents.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api_schema.compute import agents
+from tempest.api_schema.response.compute import agents
 
 create_agent = {
     'status_code': [200],
diff --git a/tempest/api_schema/compute/v2/aggregates.py b/tempest/api_schema/response/compute/v2/aggregates.py
similarity index 93%
rename from tempest/api_schema/compute/v2/aggregates.py
rename to tempest/api_schema/response/compute/v2/aggregates.py
index bc36044..d87e4de 100644
--- a/tempest/api_schema/compute/v2/aggregates.py
+++ b/tempest/api_schema/response/compute/v2/aggregates.py
@@ -14,7 +14,7 @@
 
 import copy
 
-from tempest.api_schema.compute import aggregates
+from tempest.api_schema.response.compute import aggregates
 
 delete_aggregate = {
     'status_code': [200]
diff --git a/tempest/api_schema/compute/v2/availability_zone.py b/tempest/api_schema/response/compute/v2/availability_zone.py
similarity index 95%
rename from tempest/api_schema/compute/v2/availability_zone.py
rename to tempest/api_schema/response/compute/v2/availability_zone.py
index d3d2787..e261d3d 100644
--- a/tempest/api_schema/compute/v2/availability_zone.py
+++ b/tempest/api_schema/response/compute/v2/availability_zone.py
@@ -14,7 +14,7 @@
 
 import copy
 
-from tempest.api_schema.compute import availability_zone as common
+from tempest.api_schema.response.compute import availability_zone as common
 
 
 base = {
diff --git a/tempest/api_schema/compute/v2/certificates.py b/tempest/api_schema/response/compute/v2/certificates.py
similarity index 91%
rename from tempest/api_schema/compute/v2/certificates.py
rename to tempest/api_schema/response/compute/v2/certificates.py
index 1eb38ce..bda6075 100644
--- a/tempest/api_schema/compute/v2/certificates.py
+++ b/tempest/api_schema/response/compute/v2/certificates.py
@@ -14,6 +14,6 @@
 
 import copy
 
-from tempest.api_schema.compute import certificates
+from tempest.api_schema.response.compute import certificates
 
 create_certificate = copy.deepcopy(certificates._common_schema)
diff --git a/tempest/api_schema/compute/v2/extensions.py b/tempest/api_schema/response/compute/v2/extensions.py
similarity index 100%
rename from tempest/api_schema/compute/v2/extensions.py
rename to tempest/api_schema/response/compute/v2/extensions.py
diff --git a/tempest/api_schema/compute/v2/fixed_ips.py b/tempest/api_schema/response/compute/v2/fixed_ips.py
similarity index 100%
rename from tempest/api_schema/compute/v2/fixed_ips.py
rename to tempest/api_schema/response/compute/v2/fixed_ips.py
diff --git a/tempest/api_schema/compute/v2/flavors.py b/tempest/api_schema/response/compute/v2/flavors.py
similarity index 92%
rename from tempest/api_schema/compute/v2/flavors.py
rename to tempest/api_schema/response/compute/v2/flavors.py
index bee6ecb..811ea84 100644
--- a/tempest/api_schema/compute/v2/flavors.py
+++ b/tempest/api_schema/response/compute/v2/flavors.py
@@ -14,11 +14,11 @@
 
 import copy
 
-from tempest.api_schema.compute import flavors
+from tempest.api_schema.response.compute import flavors
 
 list_flavors_details = copy.deepcopy(flavors.common_flavor_list_details)
 
-# 'swap' attributes comes as integre value but if it is empty it comes as "".
+# 'swap' attributes comes as integer value but if it is empty it comes as "".
 # So defining type of as string and integer.
 list_flavors_details['response_body']['properties']['flavors']['items'][
     'properties']['swap'] = {'type': ['string', 'integer']}
@@ -38,7 +38,7 @@
 
 create_get_flavor_details = copy.deepcopy(flavors.common_flavor_details)
 
-# 'swap' attributes comes as integre value but if it is empty it comes as "".
+# 'swap' attributes comes as integer value but if it is empty it comes as "".
 # So defining type of as string and integer.
 create_get_flavor_details['response_body']['properties']['flavor'][
     'properties']['swap'] = {'type': ['string', 'integer']}
diff --git a/tempest/api_schema/compute/v2/floating_ips.py b/tempest/api_schema/response/compute/v2/floating_ips.py
similarity index 100%
rename from tempest/api_schema/compute/v2/floating_ips.py
rename to tempest/api_schema/response/compute/v2/floating_ips.py
diff --git a/tempest/api_schema/compute/v2/hosts.py b/tempest/api_schema/response/compute/v2/hosts.py
similarity index 95%
rename from tempest/api_schema/compute/v2/hosts.py
rename to tempest/api_schema/response/compute/v2/hosts.py
index 86efadf..0944792 100644
--- a/tempest/api_schema/compute/v2/hosts.py
+++ b/tempest/api_schema/response/compute/v2/hosts.py
@@ -14,7 +14,7 @@
 
 import copy
 
-from tempest.api_schema.compute import hosts
+from tempest.api_schema.response.compute import hosts
 
 
 startup_host = {
diff --git a/tempest/api_schema/compute/v2/hypervisors.py b/tempest/api_schema/response/compute/v2/hypervisors.py
similarity index 95%
rename from tempest/api_schema/compute/v2/hypervisors.py
rename to tempest/api_schema/response/compute/v2/hypervisors.py
index 6bb43a7..1878881 100644
--- a/tempest/api_schema/compute/v2/hypervisors.py
+++ b/tempest/api_schema/response/compute/v2/hypervisors.py
@@ -13,7 +13,9 @@
 #    under the License.
 
 import copy
-from tempest.api_schema.compute import hypervisors
+
+from tempest.api_schema.response.compute import hypervisors
+
 
 hypervisors_servers = copy.deepcopy(hypervisors.common_hypervisors_detail)
 
diff --git a/tempest/api_schema/compute/v2/images.py b/tempest/api_schema/response/compute/v2/images.py
similarity index 97%
rename from tempest/api_schema/compute/v2/images.py
rename to tempest/api_schema/response/compute/v2/images.py
index 90737a2..923c744 100644
--- a/tempest/api_schema/compute/v2/images.py
+++ b/tempest/api_schema/response/compute/v2/images.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api_schema.compute import parameter_types
+from tempest.api_schema.response.compute import parameter_types
 
 common_image_schema = {
     'type': 'object',
diff --git a/tempest/api_schema/compute/v2/instance_usage_audit_logs.py b/tempest/api_schema/response/compute/v2/instance_usage_audit_logs.py
similarity index 100%
rename from tempest/api_schema/compute/v2/instance_usage_audit_logs.py
rename to tempest/api_schema/response/compute/v2/instance_usage_audit_logs.py
diff --git a/tempest/api_schema/compute/v2/interfaces.py b/tempest/api_schema/response/compute/v2/interfaces.py
similarity index 92%
rename from tempest/api_schema/compute/v2/interfaces.py
rename to tempest/api_schema/response/compute/v2/interfaces.py
index 7fca791..64d161d 100644
--- a/tempest/api_schema/compute/v2/interfaces.py
+++ b/tempest/api_schema/response/compute/v2/interfaces.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api_schema.compute import interfaces as common_schema
+from tempest.api_schema.response.compute import interfaces as common_schema
 
 list_interfaces = {
     'status_code': [200],
diff --git a/tempest/api_schema/compute/v2/keypairs.py b/tempest/api_schema/response/compute/v2/keypairs.py
similarity index 96%
rename from tempest/api_schema/compute/v2/keypairs.py
rename to tempest/api_schema/response/compute/v2/keypairs.py
index 32d8cca..ec26fa0 100644
--- a/tempest/api_schema/compute/v2/keypairs.py
+++ b/tempest/api_schema/response/compute/v2/keypairs.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api_schema.compute import keypairs
+from tempest.api_schema.response.compute import keypairs
 
 get_keypair = {
     'status_code': [200],
diff --git a/tempest/api_schema/compute/v2/limits.py b/tempest/api_schema/response/compute/v2/limits.py
similarity index 100%
rename from tempest/api_schema/compute/v2/limits.py
rename to tempest/api_schema/response/compute/v2/limits.py
diff --git a/tempest/api_schema/compute/v2/quota_classes.py b/tempest/api_schema/response/compute/v2/quota_classes.py
similarity index 95%
rename from tempest/api_schema/compute/v2/quota_classes.py
rename to tempest/api_schema/response/compute/v2/quota_classes.py
index 3464fb4..5474a89 100644
--- a/tempest/api_schema/compute/v2/quota_classes.py
+++ b/tempest/api_schema/response/compute/v2/quota_classes.py
@@ -15,7 +15,7 @@
 
 import copy
 
-from tempest.api_schema.compute.v2 import quotas
+from tempest.api_schema.response.compute.v2 import quotas
 
 # NOTE(mriedem): os-quota-class-sets responses are the same as os-quota-sets
 # except for the key in the response body is quota_class_set instead of
diff --git a/tempest/api_schema/compute/v2/quotas.py b/tempest/api_schema/response/compute/v2/quotas.py
similarity index 97%
rename from tempest/api_schema/compute/v2/quotas.py
rename to tempest/api_schema/response/compute/v2/quotas.py
index 31c0458..630b227 100644
--- a/tempest/api_schema/compute/v2/quotas.py
+++ b/tempest/api_schema/response/compute/v2/quotas.py
@@ -14,7 +14,7 @@
 
 import copy
 
-from tempest.api_schema.compute import quotas
+from tempest.api_schema.response.compute import quotas
 
 quota_set = copy.deepcopy(quotas.common_quota_set)
 quota_set['response_body']['properties']['quota_set']['properties'][
diff --git a/tempest/api_schema/compute/v2/security_groups.py b/tempest/api_schema/response/compute/v2/security_groups.py
similarity index 100%
rename from tempest/api_schema/compute/v2/security_groups.py
rename to tempest/api_schema/response/compute/v2/security_groups.py
diff --git a/tempest/api_schema/compute/v2/servers.py b/tempest/api_schema/response/compute/v2/servers.py
similarity index 83%
rename from tempest/api_schema/compute/v2/servers.py
rename to tempest/api_schema/response/compute/v2/servers.py
index cd46f9b..5fc2008 100644
--- a/tempest/api_schema/compute/v2/servers.py
+++ b/tempest/api_schema/response/compute/v2/servers.py
@@ -14,8 +14,8 @@
 
 import copy
 
-from tempest.api_schema.compute import parameter_types
-from tempest.api_schema.compute import servers
+from tempest.api_schema.response.compute import parameter_types
+from tempest.api_schema.response.compute import servers
 
 create_server = {
     'status_code': [202],
@@ -28,14 +28,11 @@
                     'id': {'type': 'string'},
                     'security_groups': {'type': 'array'},
                     'links': parameter_types.links,
-                    'adminPass': {'type': 'string'},
                     'OS-DCF:diskConfig': {'type': 'string'}
                 },
                 # NOTE: OS-DCF:diskConfig is API extension, and some
                 # environments return a response without the attribute.
                 # So it is not 'required'.
-                # NOTE: adminPass is not required because it can be deactivated
-                # with nova API flag enable_instance_password=False
                 'required': ['id', 'security_groups', 'links']
             }
         },
@@ -43,6 +40,12 @@
     }
 }
 
+create_server_with_admin_pass = copy.deepcopy(create_server)
+create_server_with_admin_pass['response_body']['properties']['server'][
+    'properties'].update({'adminPass': {'type': 'string'}})
+create_server_with_admin_pass['response_body']['properties']['server'][
+    'required'].append('adminPass')
+
 update_server = copy.deepcopy(servers.base_update_get_server)
 update_server['response_body']['properties']['server']['properties'].update({
     'hostId': {'type': 'string'},
@@ -241,6 +244,22 @@
     }
 }
 
+get_instance_actions_object = copy.deepcopy(servers.common_get_instance_action)
+get_instance_actions_object[
+    'properties'].update({'instance_uuid': {'type': 'string'}})
+get_instance_actions_object['required'].extend(['instance_uuid'])
+
+get_instance_action = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'instanceAction': get_instance_actions_object
+        },
+        'required': ['instanceAction']
+    }
+}
+
 list_servers_detail = copy.deepcopy(servers.base_list_servers_detail)
 list_servers_detail['response_body']['properties']['servers']['items'][
     'properties'].update({
@@ -254,3 +273,25 @@
 # without these attributes. So they are not 'required'.
 list_servers_detail['response_body']['properties']['servers']['items'][
     'required'].append('hostId')
+
+rebuild_server = copy.deepcopy(update_server)
+rebuild_server['status_code'] = [202]
+del rebuild_server['response_body']['properties']['server'][
+    'properties']['OS-DCF:diskConfig']
+
+rebuild_server_with_admin_pass = copy.deepcopy(rebuild_server)
+rebuild_server_with_admin_pass['response_body']['properties']['server'][
+    'properties'].update({'adminPass': {'type': 'string'}})
+rebuild_server_with_admin_pass['response_body']['properties']['server'][
+    'required'].append('adminPass')
+
+rescue_server = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'adminPass': {'type': 'string'}
+        },
+        'required': ['adminPass']
+    }
+}
diff --git a/tempest/api_schema/compute/v2/tenant_usages.py b/tempest/api_schema/response/compute/v2/tenant_usages.py
similarity index 100%
rename from tempest/api_schema/compute/v2/tenant_usages.py
rename to tempest/api_schema/response/compute/v2/tenant_usages.py
diff --git a/tempest/api_schema/compute/v2/volumes.py b/tempest/api_schema/response/compute/v2/volumes.py
similarity index 97%
rename from tempest/api_schema/compute/v2/volumes.py
rename to tempest/api_schema/response/compute/v2/volumes.py
index 1af951f..541d3ff 100644
--- a/tempest/api_schema/compute/v2/volumes.py
+++ b/tempest/api_schema/response/compute/v2/volumes.py
@@ -26,7 +26,7 @@
                     'availabilityZone': {'type': 'string'},
                     'createdAt': {'type': 'string'},
                     'displayDescription': {'type': ['string', 'null']},
-                    'volumeType': {'type': 'string'},
+                    'volumeType': {'type': ['string', 'null']},
                     'snapshotId': {'type': ['string', 'null']},
                     'metadata': {'type': 'object'},
                     'size': {'type': 'integer'},
@@ -74,7 +74,7 @@
                         'availabilityZone': {'type': 'string'},
                         'createdAt': {'type': 'string'},
                         'displayDescription': {'type': ['string', 'null']},
-                        'volumeType': {'type': 'string'},
+                        'volumeType': {'type': ['string', 'null']},
                         'snapshotId': {'type': ['string', 'null']},
                         'metadata': {'type': 'object'},
                         'size': {'type': 'integer'},
diff --git a/tempest/api_schema/compute/v3/__init__.py b/tempest/api_schema/response/compute/v3/__init__.py
similarity index 100%
copy from tempest/api_schema/compute/v3/__init__.py
copy to tempest/api_schema/response/compute/v3/__init__.py
diff --git a/tempest/api_schema/compute/v3/agents.py b/tempest/api_schema/response/compute/v3/agents.py
similarity index 93%
rename from tempest/api_schema/compute/v3/agents.py
rename to tempest/api_schema/response/compute/v3/agents.py
index 597a089..9ef05df 100644
--- a/tempest/api_schema/compute/v3/agents.py
+++ b/tempest/api_schema/response/compute/v3/agents.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api_schema.compute import agents
+from tempest.api_schema.response.compute import agents
 
 create_agent = {
     'status_code': [201],
diff --git a/tempest/api_schema/compute/v3/aggregates.py b/tempest/api_schema/response/compute/v3/aggregates.py
similarity index 94%
rename from tempest/api_schema/compute/v3/aggregates.py
rename to tempest/api_schema/response/compute/v3/aggregates.py
index 0272641..e3bae13 100644
--- a/tempest/api_schema/compute/v3/aggregates.py
+++ b/tempest/api_schema/response/compute/v3/aggregates.py
@@ -14,7 +14,7 @@
 
 import copy
 
-from tempest.api_schema.compute import aggregates
+from tempest.api_schema.response.compute import aggregates
 
 delete_aggregate = {
     'status_code': [204]
diff --git a/tempest/api_schema/compute/v3/availability_zone.py b/tempest/api_schema/response/compute/v3/availability_zone.py
similarity index 95%
rename from tempest/api_schema/compute/v3/availability_zone.py
rename to tempest/api_schema/response/compute/v3/availability_zone.py
index 5f36c33..dbb1d41 100644
--- a/tempest/api_schema/compute/v3/availability_zone.py
+++ b/tempest/api_schema/response/compute/v3/availability_zone.py
@@ -14,7 +14,7 @@
 
 import copy
 
-from tempest.api_schema.compute import availability_zone as common
+from tempest.api_schema.response.compute import availability_zone as common
 
 
 base = {
diff --git a/tempest/api_schema/compute/v3/certificates.py b/tempest/api_schema/response/compute/v3/certificates.py
similarity index 92%
rename from tempest/api_schema/compute/v3/certificates.py
rename to tempest/api_schema/response/compute/v3/certificates.py
index 0723a16..c768391 100644
--- a/tempest/api_schema/compute/v3/certificates.py
+++ b/tempest/api_schema/response/compute/v3/certificates.py
@@ -14,7 +14,7 @@
 
 import copy
 
-from tempest.api_schema.compute import certificates
+from tempest.api_schema.response.compute import certificates
 
 create_certificate = copy.deepcopy(certificates._common_schema)
 create_certificate['status_code'] = [201]
diff --git a/tempest/api_schema/compute/v3/extensions.py b/tempest/api_schema/response/compute/v3/extensions.py
similarity index 100%
rename from tempest/api_schema/compute/v3/extensions.py
rename to tempest/api_schema/response/compute/v3/extensions.py
diff --git a/tempest/api_schema/compute/v3/flavors.py b/tempest/api_schema/response/compute/v3/flavors.py
similarity index 95%
rename from tempest/api_schema/compute/v3/flavors.py
rename to tempest/api_schema/response/compute/v3/flavors.py
index 52010f5..d6c2c85 100644
--- a/tempest/api_schema/compute/v3/flavors.py
+++ b/tempest/api_schema/response/compute/v3/flavors.py
@@ -14,8 +14,8 @@
 
 import copy
 
-from tempest.api_schema.compute import flavors
-from tempest.api_schema.compute import flavors_extra_specs
+from tempest.api_schema.response.compute import flavors
+from tempest.api_schema.response.compute import flavors_extra_specs
 
 list_flavors_details = copy.deepcopy(flavors.common_flavor_list_details)
 
diff --git a/tempest/api_schema/compute/v3/hosts.py b/tempest/api_schema/response/compute/v3/hosts.py
similarity index 96%
rename from tempest/api_schema/compute/v3/hosts.py
rename to tempest/api_schema/response/compute/v3/hosts.py
index eb689d1..f356371 100644
--- a/tempest/api_schema/compute/v3/hosts.py
+++ b/tempest/api_schema/response/compute/v3/hosts.py
@@ -14,7 +14,7 @@
 
 import copy
 
-from tempest.api_schema.compute import hosts
+from tempest.api_schema.response.compute import hosts
 
 startup_host = {
     'status_code': [200],
diff --git a/tempest/api_schema/compute/v3/hypervisors.py b/tempest/api_schema/response/compute/v3/hypervisors.py
similarity index 96%
rename from tempest/api_schema/compute/v3/hypervisors.py
rename to tempest/api_schema/response/compute/v3/hypervisors.py
index aa31827..b36ae7e 100644
--- a/tempest/api_schema/compute/v3/hypervisors.py
+++ b/tempest/api_schema/response/compute/v3/hypervisors.py
@@ -13,7 +13,9 @@
 #    under the License.
 
 import copy
-from tempest.api_schema.compute import hypervisors
+
+from tempest.api_schema.response.compute import hypervisors
+
 
 list_hypervisors_detail = copy.deepcopy(
     hypervisors.common_list_hypervisors_detail)
diff --git a/tempest/api_schema/compute/v3/interfaces.py b/tempest/api_schema/response/compute/v3/interfaces.py
similarity index 92%
rename from tempest/api_schema/compute/v3/interfaces.py
rename to tempest/api_schema/response/compute/v3/interfaces.py
index 5e1cee2..7f716ee 100644
--- a/tempest/api_schema/compute/v3/interfaces.py
+++ b/tempest/api_schema/response/compute/v3/interfaces.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api_schema.compute import interfaces as common_schema
+from tempest.api_schema.response.compute import interfaces as common_schema
 
 list_interfaces = {
     'status_code': [200],
diff --git a/tempest/api_schema/compute/v3/keypairs.py b/tempest/api_schema/response/compute/v3/keypairs.py
similarity index 95%
rename from tempest/api_schema/compute/v3/keypairs.py
rename to tempest/api_schema/response/compute/v3/keypairs.py
index de5f4ba..ea15405 100644
--- a/tempest/api_schema/compute/v3/keypairs.py
+++ b/tempest/api_schema/response/compute/v3/keypairs.py
@@ -12,7 +12,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api_schema.compute import keypairs
+from tempest.api_schema.response.compute import keypairs
 
 get_keypair = {
     'status_code': [200],
diff --git a/tempest/api_schema/compute/v3/quotas.py b/tempest/api_schema/response/compute/v3/quotas.py
similarity index 97%
rename from tempest/api_schema/compute/v3/quotas.py
rename to tempest/api_schema/response/compute/v3/quotas.py
index a3212ed..85ed3b3 100644
--- a/tempest/api_schema/compute/v3/quotas.py
+++ b/tempest/api_schema/response/compute/v3/quotas.py
@@ -14,7 +14,7 @@
 
 import copy
 
-from tempest.api_schema.compute import quotas
+from tempest.api_schema.response.compute import quotas
 
 quota_set = copy.deepcopy(quotas.common_quota_set)
 quota_set['response_body']['properties']['quota_set']['properties'][
diff --git a/tempest/api_schema/compute/v3/servers.py b/tempest/api_schema/response/compute/v3/servers.py
similarity index 77%
rename from tempest/api_schema/compute/v3/servers.py
rename to tempest/api_schema/response/compute/v3/servers.py
index b6cb13b..d0edd44 100644
--- a/tempest/api_schema/compute/v3/servers.py
+++ b/tempest/api_schema/response/compute/v3/servers.py
@@ -14,8 +14,8 @@
 
 import copy
 
-from tempest.api_schema.compute import parameter_types
-from tempest.api_schema.compute import servers
+from tempest.api_schema.response.compute import parameter_types
+from tempest.api_schema.response.compute import servers
 
 create_server = {
     'status_code': [202],
@@ -28,7 +28,6 @@
                     'id': {'type': 'string'},
                     'os-security-groups:security_groups': {'type': 'array'},
                     'links': parameter_types.links,
-                    'admin_password': {'type': 'string'},
                     'os-access-ips:access_ip_v4': parameter_types.access_ip_v4,
                     'os-access-ips:access_ip_v6': parameter_types.access_ip_v6
                 },
@@ -36,13 +35,19 @@
                 # and some environments return a response without these
                 # attributes. So they are not 'required'.
                 'required': ['id', 'os-security-groups:security_groups',
-                             'links', 'admin_password']
+                             'links']
             }
         },
         'required': ['server']
     }
 }
 
+create_server_with_admin_pass = copy.deepcopy(create_server)
+create_server_with_admin_pass['response_body']['properties']['server'][
+    'properties'].update({'admin_password': {'type': 'string'}})
+create_server_with_admin_pass['response_body']['properties']['server'][
+    'required'].append('admin_password')
+
 addresses_v3 = copy.deepcopy(parameter_types.addresses)
 addresses_v3['patternProperties']['^[a-zA-Z0-9-_.]+$']['items'][
     'properties'].update({
@@ -50,9 +55,7 @@
         'mac_addr': {'type': 'string'}
     })
 addresses_v3['patternProperties']['^[a-zA-Z0-9-_.]+$']['items'][
-    'required'].extend(
-        ['type', 'mac_addr']
-    )
+    'required'].extend(['type', 'mac_addr'])
 
 update_server = copy.deepcopy(servers.base_update_get_server)
 update_server['response_body']['properties']['server']['properties'].update({
@@ -152,6 +155,22 @@
     }
 }
 
+get_server_actions_object = copy.deepcopy(servers.common_get_instance_action)
+get_server_actions_object[
+    'properties'].update({'server_uuid': {'type': 'string'}})
+get_server_actions_object['required'].extend(['server_uuid'])
+
+get_server_action = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'server_action': get_server_actions_object
+        },
+        'required': ['server_action']
+    }
+}
+
 list_servers_detail = copy.deepcopy(servers.base_list_servers_detail)
 list_servers_detail['response_body']['properties']['servers']['items'][
     'properties'].update({
@@ -165,3 +184,27 @@
 # attributes. So they are not 'required'.
 list_servers_detail['response_body']['properties']['servers']['items'][
     'required'].append('host_id')
+
+rebuild_server = copy.deepcopy(update_server)
+rebuild_server['status_code'] = [202]
+
+rebuild_server_with_admin_pass = copy.deepcopy(rebuild_server)
+rebuild_server_with_admin_pass['response_body']['properties']['server'][
+    'properties'].update({'admin_password': {'type': 'string'}})
+rebuild_server_with_admin_pass['response_body']['properties']['server'][
+    'required'].append('admin_password')
+
+rescue_server_with_admin_pass = {
+    'status_code': [202],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'admin_password': {'type': 'string'}
+        },
+        'required': ['admin_password']
+    }
+}
+
+rescue_server = copy.deepcopy(rescue_server_with_admin_pass)
+del rescue_server['response_body']['properties']
+del rescue_server['response_body']['required']
diff --git a/tempest/api_schema/compute/version.py b/tempest/api_schema/response/compute/version.py
similarity index 100%
rename from tempest/api_schema/compute/version.py
rename to tempest/api_schema/response/compute/version.py
diff --git a/tempest/api_schema/queuing/__init__.py b/tempest/api_schema/response/queuing/__init__.py
similarity index 100%
rename from tempest/api_schema/queuing/__init__.py
rename to tempest/api_schema/response/queuing/__init__.py
diff --git a/tempest/api_schema/queuing/v1/__init__.py b/tempest/api_schema/response/queuing/v1/__init__.py
similarity index 100%
rename from tempest/api_schema/queuing/v1/__init__.py
rename to tempest/api_schema/response/queuing/v1/__init__.py
diff --git a/tempest/api_schema/queuing/v1/queues.py b/tempest/api_schema/response/queuing/v1/queues.py
similarity index 100%
rename from tempest/api_schema/queuing/v1/queues.py
rename to tempest/api_schema/response/queuing/v1/queues.py
diff --git a/tempest/auth.py b/tempest/auth.py
index 830dca9..c84ad6b 100644
--- a/tempest/auth.py
+++ b/tempest/auth.py
@@ -13,24 +13,28 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import abc
 import copy
 import datetime
 import exceptions
 import re
 import urlparse
 
+import six
+
 from tempest import config
+from tempest.openstack.common import log as logging
 from tempest.services.identity.json import identity_client as json_id
 from tempest.services.identity.v3.json import identity_client as json_v3id
 from tempest.services.identity.v3.xml import identity_client as xml_v3id
 from tempest.services.identity.xml import identity_client as xml_id
 
-from tempest.openstack.common import log as logging
 
 CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
 
+@six.add_metaclass(abc.ABCMeta)
 class AuthProvider(object):
     """
     Provide authentication
@@ -70,18 +74,21 @@
                    interface=self.interface, cache=self.cache
                )
 
+    @abc.abstractmethod
     def _decorate_request(self, filters, method, url, headers=None, body=None,
                           auth_data=None):
         """
         Decorate request with authentication data
         """
-        raise NotImplementedError
+        return
 
+    @abc.abstractmethod
     def _get_auth(self):
-        raise NotImplementedError
+        return
 
+    @abc.abstractmethod
     def _fill_credentials(self, auth_data_body):
-        raise NotImplementedError
+        return
 
     def fill_credentials(self):
         """
@@ -130,8 +137,9 @@
         self.cache = None
         self.credentials.reset()
 
+    @abc.abstractmethod
     def is_expired(self, auth_data):
-        raise NotImplementedError
+        return
 
     def auth_request(self, method, url, headers=None, body=None, filters=None):
         """
@@ -188,11 +196,12 @@
         self.alt_part = request_part
         self.alt_auth_data = auth_data
 
+    @abc.abstractmethod
     def base_url(self, filters, auth_data=None):
         """
         Extracts the base_url based on provided filters
         """
-        raise NotImplementedError
+        return
 
 
 class KeystoneAuthProvider(AuthProvider):
@@ -225,11 +234,13 @@
         # no change to method or body
         return str(_url), _headers, body
 
+    @abc.abstractmethod
     def _auth_client(self):
-        raise NotImplementedError
+        return
 
+    @abc.abstractmethod
     def _auth_params(self):
-        raise NotImplementedError
+        return
 
     def _get_auth(self):
         # Bypasses the cache
@@ -321,7 +332,7 @@
             if noversion_path != "":
                 path += "/" + noversion_path
             _base_url = _base_url.replace(parts.path, path)
-        if filters.get('skip_path', None) is not None:
+        if filters.get('skip_path', None) is not None and parts.path != '':
             _base_url = _base_url.replace(parts.path, "/")
 
         return _base_url
diff --git a/tempest/cli/README.rst b/tempest/cli/README.rst
index dcd940b..bc18084 100644
--- a/tempest/cli/README.rst
+++ b/tempest/cli/README.rst
@@ -1,3 +1,5 @@
+.. _cli_field_guide:
+
 Tempest Field Guide to CLI tests
 ================================
 
diff --git a/tempest/cli/__init__.py b/tempest/cli/__init__.py
index ba94c82..c33589a 100644
--- a/tempest/cli/__init__.py
+++ b/tempest/cli/__init__.py
@@ -13,13 +13,18 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import functools
 import os
 import shlex
 import subprocess
 
+import testtools
+
 import tempest.cli.output_parser
 from tempest import config
+from tempest import exceptions
 from tempest.openstack.common import log as logging
+from tempest.openstack.common import versionutils
 import tempest.test
 
 
@@ -28,6 +33,65 @@
 CONF = config.CONF
 
 
+def execute(cmd, action, flags='', params='', fail_ok=False,
+            merge_stderr=False):
+    """Executes specified command for the given action."""
+    cmd = ' '.join([os.path.join(CONF.cli.cli_dir, cmd),
+                    flags, action, params])
+    LOG.info("running: '%s'" % cmd)
+    cmd = shlex.split(cmd.encode('utf-8'))
+    result = ''
+    result_err = ''
+    stdout = subprocess.PIPE
+    stderr = subprocess.STDOUT if merge_stderr else subprocess.PIPE
+    proc = subprocess.Popen(cmd, stdout=stdout, stderr=stderr)
+    result, result_err = proc.communicate()
+    if not fail_ok and proc.returncode != 0:
+        raise exceptions.CommandFailed(proc.returncode,
+                                       cmd,
+                                       result,
+                                       result_err)
+    return result
+
+
+def check_client_version(client, version):
+    """Checks if the client's version is compatible with the given version
+
+    @param client: The client to check.
+    @param version: The version to compare against.
+    @return: True if the client version is compatible with the given version
+             parameter, False otherwise.
+    """
+    current_version = execute(client, '', params='--version',
+                              merge_stderr=True)
+
+    if not current_version.strip():
+        raise exceptions.TempestException('"%s --version" output was empty' %
+                                          client)
+
+    return versionutils.is_compatible(version, current_version,
+                                      same_major=False)
+
+
+def min_client_version(*args, **kwargs):
+    """A decorator to skip tests if the client used isn't of the right version.
+
+    @param client: The client command to run. For python-novaclient, this is
+                   'nova', for python-cinderclient this is 'cinder', etc.
+    @param version: The minimum version required to run the CLI test.
+    """
+    def decorator(func):
+        @functools.wraps(func)
+        def wrapper(*func_args, **func_kwargs):
+            if not check_client_version(kwargs['client'], kwargs['version']):
+                msg = "requires %s client version >= %s" % (kwargs['client'],
+                                                            kwargs['version'])
+                raise testtools.TestCase.skipException(msg)
+            return func(*func_args, **func_kwargs)
+        return wrapper
+    return decorator
+
+
 class ClientTestBase(tempest.test.BaseTestCase):
     @classmethod
     def setUpClass(cls):
@@ -49,7 +113,7 @@
     def nova_manage(self, action, flags='', params='', fail_ok=False,
                     merge_stderr=False):
         """Executes nova-manage command for the given action."""
-        return self.cmd(
+        return execute(
             'nova-manage', action, flags, params, fail_ok, merge_stderr)
 
     def keystone(self, action, flags='', params='', admin=True, fail_ok=False):
@@ -113,28 +177,7 @@
                   CONF.identity.admin_password,
                   CONF.identity.uri))
         flags = creds + ' ' + flags
-        return self.cmd(cmd, action, flags, params, fail_ok, merge_stderr)
-
-    def cmd(self, cmd, action, flags='', params='', fail_ok=False,
-            merge_stderr=False):
-        """Executes specified command for the given action."""
-        cmd = ' '.join([os.path.join(CONF.cli.cli_dir, cmd),
-                        flags, action, params])
-        LOG.info("running: '%s'" % cmd)
-        cmd = shlex.split(cmd.encode('utf-8'))
-        result = ''
-        result_err = ''
-        stdout = subprocess.PIPE
-        stderr = subprocess.STDOUT if merge_stderr else subprocess.PIPE
-        proc = subprocess.Popen(
-            cmd, stdout=stdout, stderr=stderr)
-        result, result_err = proc.communicate()
-        if not fail_ok and proc.returncode != 0:
-            raise CommandFailed(proc.returncode,
-                                cmd,
-                                result,
-                                stderr=result_err)
-        return result
+        return execute(cmd, action, flags, params, fail_ok, merge_stderr)
 
     def assertTableStruct(self, items, field_names):
         """Verify that all items has keys listed in field_names."""
@@ -146,11 +189,3 @@
         self.assertTrue(lines[0].startswith(beginning),
                         msg=('Beginning of first line has invalid content: %s'
                              % lines[:3]))
-
-
-class CommandFailed(subprocess.CalledProcessError):
-    # adds output attribute for python2.6
-    def __init__(self, returncode, cmd, output, stderr=""):
-        super(CommandFailed, self).__init__(returncode, cmd)
-        self.output = output
-        self.stderr = stderr
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/cli/simple_read_only/test_cinder.py b/tempest/cli/simple_read_only/test_cinder.py
index 946b89e..3a9a7a6 100644
--- a/tempest/cli/simple_read_only/test_cinder.py
+++ b/tempest/cli/simple_read_only/test_cinder.py
@@ -15,17 +15,18 @@
 
 import logging
 import re
-import subprocess
+
 import testtools
 
-import tempest.cli
+from tempest import cli
 from tempest import config
+from tempest import exceptions
 
 CONF = config.CONF
 LOG = logging.getLogger(__name__)
 
 
-class SimpleReadOnlyCinderClientTest(tempest.cli.ClientTestBase):
+class SimpleReadOnlyCinderClientTest(cli.ClientTestBase):
     """Basic, read-only tests for Cinder CLI client.
 
     Checks return values and output of read-only commands.
@@ -41,7 +42,7 @@
         super(SimpleReadOnlyCinderClientTest, cls).setUpClass()
 
     def test_cinder_fake_action(self):
-        self.assertRaises(subprocess.CalledProcessError,
+        self.assertRaises(exceptions.CommandFailed,
                           self.cinder,
                           'this-does-not-exist')
 
@@ -66,7 +67,7 @@
                                       'Attached to'])
         self.cinder('list', params='--all-tenants 1')
         self.cinder('list', params='--all-tenants 0')
-        self.assertRaises(subprocess.CalledProcessError,
+        self.assertRaises(exceptions.CommandFailed,
                           self.cinder,
                           'list',
                           params='--all-tenants bad')
diff --git a/tempest/cli/simple_read_only/test_glance.py b/tempest/cli/simple_read_only/test_glance.py
index 9869483..2fd8212 100644
--- a/tempest/cli/simple_read_only/test_glance.py
+++ b/tempest/cli/simple_read_only/test_glance.py
@@ -14,10 +14,10 @@
 #    under the License.
 
 import re
-import subprocess
 
-import tempest.cli
+from tempest import cli
 from tempest import config
+from tempest import exceptions
 from tempest.openstack.common import log as logging
 
 CONF = config.CONF
@@ -25,7 +25,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class SimpleReadOnlyGlanceClientTest(tempest.cli.ClientTestBase):
+class SimpleReadOnlyGlanceClientTest(cli.ClientTestBase):
     """Basic, read-only tests for Glance CLI client.
 
     Checks return values and output of read-only commands.
@@ -41,7 +41,7 @@
         super(SimpleReadOnlyGlanceClientTest, cls).setUpClass()
 
     def test_glance_fake_action(self):
-        self.assertRaises(subprocess.CalledProcessError,
+        self.assertRaises(exceptions.CommandFailed,
                           self.glance,
                           'this-does-not-exist')
 
@@ -76,8 +76,8 @@
         commands = set(commands)
         wanted_commands = set(('image-create', 'image-delete', 'help',
                                'image-download', 'image-show', 'image-update',
-                               'member-add', 'member-create', 'member-delete',
-                               'member-list'))
+                               'member-create', 'member-delete',
+                               'member-list', 'image-list'))
         self.assertFalse(wanted_commands - commands)
 
     # Optional arguments:
diff --git a/tempest/cli/simple_read_only/test_heat.py b/tempest/cli/simple_read_only/test_heat.py
index 7a952fc..8e413a9 100644
--- a/tempest/cli/simple_read_only/test_heat.py
+++ b/tempest/cli/simple_read_only/test_heat.py
@@ -12,6 +12,7 @@
 
 import json
 import os
+
 import yaml
 
 import tempest.cli
@@ -85,6 +86,7 @@
     def test_heat_help(self):
         self.heat('help')
 
+    @tempest.cli.min_client_version(client='heat', version='0.2.7')
     def test_heat_bash_completion(self):
         self.heat('bash-completion')
 
diff --git a/tempest/cli/simple_read_only/test_keystone.py b/tempest/cli/simple_read_only/test_keystone.py
index dda65c1..9218fcd 100644
--- a/tempest/cli/simple_read_only/test_keystone.py
+++ b/tempest/cli/simple_read_only/test_keystone.py
@@ -14,10 +14,10 @@
 #    under the License.
 
 import re
-import subprocess
 
-import tempest.cli
+from tempest import cli
 from tempest import config
+from tempest import exceptions
 from tempest.openstack.common import log as logging
 
 CONF = config.CONF
@@ -26,7 +26,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class SimpleReadOnlyKeystoneClientTest(tempest.cli.ClientTestBase):
+class SimpleReadOnlyKeystoneClientTest(cli.ClientTestBase):
     """Basic, read-only tests for Keystone CLI client.
 
     Checks return values and output of read-only commands.
@@ -35,7 +35,7 @@
     """
 
     def test_admin_fake_action(self):
-        self.assertRaises(subprocess.CalledProcessError,
+        self.assertRaises(exceptions.CommandFailed,
                           self.keystone,
                           'this-does-not-exist')
 
diff --git a/tempest/cli/simple_read_only/test_neutron.py b/tempest/cli/simple_read_only/test_neutron.py
index 49d079e..87f6b67 100644
--- a/tempest/cli/simple_read_only/test_neutron.py
+++ b/tempest/cli/simple_read_only/test_neutron.py
@@ -14,10 +14,10 @@
 #    under the License.
 
 import re
-import subprocess
 
 from tempest import cli
 from tempest import config
+from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest import test
 
@@ -43,7 +43,7 @@
 
     @test.attr(type='smoke')
     def test_neutron_fake_action(self):
-        self.assertRaises(subprocess.CalledProcessError,
+        self.assertRaises(exceptions.CommandFailed,
                           self.neutron,
                           'this-does-not-exist')
 
@@ -89,7 +89,7 @@
     def _test_neutron_lbaas_command(self, command):
         try:
             self.neutron(command)
-        except cli.CommandFailed as e:
+        except exceptions.CommandFailed as e:
             if '404 Not Found' not in e.stderr:
                 self.fail('%s: Unexpected failure.' % command)
 
diff --git a/tempest/cli/simple_read_only/test_nova.py b/tempest/cli/simple_read_only/test_nova.py
index 1c1ddf1..9bac7a6 100644
--- a/tempest/cli/simple_read_only/test_nova.py
+++ b/tempest/cli/simple_read_only/test_nova.py
@@ -13,12 +13,11 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import subprocess
-
 import testtools
 
-import tempest.cli
+from tempest import cli
 from tempest import config
+from tempest import exceptions
 from tempest.openstack.common import log as logging
 import tempest.test
 
@@ -27,7 +26,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class SimpleReadOnlyNovaClientTest(tempest.cli.ClientTestBase):
+class SimpleReadOnlyNovaClientTest(cli.ClientTestBase):
 
     """
     This is a first pass at a simple read only python-novaclient test. This
@@ -49,7 +48,7 @@
         super(SimpleReadOnlyNovaClientTest, cls).setUpClass()
 
     def test_admin_fake_action(self):
-        self.assertRaises(subprocess.CalledProcessError,
+        self.assertRaises(exceptions.CommandFailed,
                           self.nova,
                           'this-does-nova-exist')
 
@@ -86,11 +85,11 @@
         self.nova('endpoints')
 
     def test_admin_flavor_acces_list(self):
-        self.assertRaises(subprocess.CalledProcessError,
+        self.assertRaises(exceptions.CommandFailed,
                           self.nova,
                           'flavor-access-list')
         # Failed to get access list for public flavor type
-        self.assertRaises(subprocess.CalledProcessError,
+        self.assertRaises(exceptions.CommandFailed,
                           self.nova,
                           'flavor-access-list',
                           params='--flavor m1.tiny')
@@ -127,7 +126,7 @@
         self.nova('list')
         self.nova('list', params='--all-tenants 1')
         self.nova('list', params='--all-tenants 0')
-        self.assertRaises(subprocess.CalledProcessError,
+        self.assertRaises(exceptions.CommandFailed,
                           self.nova,
                           'list',
                           params='--all-tenants bad')
@@ -145,6 +144,7 @@
     def test_admin_secgroup_list_rules(self):
         self.nova('secgroup-list-rules')
 
+    @tempest.cli.min_client_version(client='nova', version='2.18')
     def test_admin_server_group_list(self):
         self.nova('server-group-list')
 
diff --git a/tempest/cli/simple_read_only/test_nova_manage.py b/tempest/cli/simple_read_only/test_nova_manage.py
index f1fee2e..c27b12e 100644
--- a/tempest/cli/simple_read_only/test_nova_manage.py
+++ b/tempest/cli/simple_read_only/test_nova_manage.py
@@ -13,10 +13,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import subprocess
-
-import tempest.cli
+from tempest import cli
 from tempest import config
+from tempest import exceptions
 from tempest.openstack.common import log as logging
 
 
@@ -24,7 +23,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class SimpleReadOnlyNovaManageTest(tempest.cli.ClientTestBase):
+class SimpleReadOnlyNovaManageTest(cli.ClientTestBase):
 
     """
     This is a first pass at a simple read only nova-manage test. This
@@ -48,7 +47,7 @@
         super(SimpleReadOnlyNovaManageTest, cls).setUpClass()
 
     def test_admin_fake_action(self):
-        self.assertRaises(subprocess.CalledProcessError,
+        self.assertRaises(exceptions.CommandFailed,
                           self.nova_manage,
                           'this-does-nova-exist')
 
@@ -80,10 +79,6 @@
     def test_flavor_list(self):
         self.assertNotEqual("", self.nova_manage('flavor list'))
 
-    def test_db_archive_deleted_rows(self):
-        # make sure command doesn't error out
-        self.nova_manage('db archive_deleted_rows 50')
-
     def test_db_sync(self):
         # make sure command doesn't error out
         self.nova_manage('db sync')
diff --git a/tempest/cli/simple_read_only/test_sahara.py b/tempest/cli/simple_read_only/test_sahara.py
index f00dcae..2c6e0e2 100644
--- a/tempest/cli/simple_read_only/test_sahara.py
+++ b/tempest/cli/simple_read_only/test_sahara.py
@@ -14,10 +14,10 @@
 # limitations under the License.
 import logging
 import re
-import subprocess
 
 from tempest import cli
 from tempest import config
+from tempest import exceptions
 from tempest import test
 
 CONF = config.CONF
@@ -42,7 +42,7 @@
 
     @test.attr(type='negative')
     def test_sahara_fake_action(self):
-        self.assertRaises(subprocess.CalledProcessError,
+        self.assertRaises(exceptions.CommandFailed,
                           self.sahara,
                           'this-does-not-exist')
 
diff --git a/tempest/cli/simple_read_only/test_swift.py b/tempest/cli/simple_read_only/test_swift.py
index 6d6caa7..069a384 100644
--- a/tempest/cli/simple_read_only/test_swift.py
+++ b/tempest/cli/simple_read_only/test_swift.py
@@ -14,15 +14,15 @@
 #    under the License.
 
 import re
-import subprocess
 
-import tempest.cli
+from tempest import cli
 from tempest import config
+from tempest import exceptions
 
 CONF = config.CONF
 
 
-class SimpleReadOnlySwiftClientTest(tempest.cli.ClientTestBase):
+class SimpleReadOnlySwiftClientTest(cli.ClientTestBase):
     """Basic, read-only tests for Swift CLI client.
 
     Checks return values and output of read-only commands.
@@ -38,7 +38,7 @@
         super(SimpleReadOnlySwiftClientTest, cls).setUpClass()
 
     def test_swift_fake_action(self):
-        self.assertRaises(subprocess.CalledProcessError,
+        self.assertRaises(exceptions.CommandFailed,
                           self.swift,
                           'this-does-not-exist')
 
diff --git a/tempest/clients.py b/tempest/clients.py
index 4e2205e..2b8b6fb 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -50,8 +50,11 @@
 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 \
+    SecurityGroupDefaultRulesClientJSON
 from tempest.services.compute.json.security_groups_client import \
     SecurityGroupsClientJSON
 from tempest.services.compute.json.servers_client import ServersClientJSON
@@ -179,7 +182,15 @@
     ExtensionsClientJSON as VolumeExtensionClientJSON
 from tempest.services.volume.json.snapshots_client import SnapshotsClientJSON
 from tempest.services.volume.json.volumes_client import VolumesClientJSON
+from tempest.services.volume.v2.json.availability_zone_client import \
+    VolumeV2AvailabilityZoneClientJSON
+from tempest.services.volume.v2.json.extensions_client import \
+    ExtensionsV2ClientJSON as VolumeV2ExtensionClientJSON
 from tempest.services.volume.v2.json.volumes_client import VolumesV2ClientJSON
+from tempest.services.volume.v2.xml.availability_zone_client import \
+    VolumeV2AvailabilityZoneClientXML
+from tempest.services.volume.v2.xml.extensions_client import \
+    ExtensionsV2ClientXML as VolumeV2ExtensionClientXML
 from tempest.services.volume.v2.xml.volumes_client import VolumesV2ClientXML
 from tempest.services.volume.xml.admin.volume_hosts_client import \
     VolumeHostsClientXML
@@ -268,6 +279,8 @@
                 self.auth_provider)
             self.volumes_extension_client = VolumeExtensionClientXML(
                 self.auth_provider)
+            self.volumes_v2_extension_client = VolumeV2ExtensionClientXML(
+                self.auth_provider)
             if CONF.service_available.ceilometer:
                 self.telemetry_client = TelemetryClientXML(
                     self.auth_provider)
@@ -275,6 +288,8 @@
             self.token_v3_client = V3TokenClientXML()
             self.volume_availability_zone_client = \
                 VolumeAvailabilityZoneClientXML(self.auth_provider)
+            self.volume_v2_availability_zone_client = \
+                VolumeV2AvailabilityZoneClientXML(self.auth_provider)
 
         elif self.interface == 'json':
             self.certificates_client = CertificatesClientJSON(
@@ -360,6 +375,8 @@
                 self.auth_provider)
             self.volumes_extension_client = VolumeExtensionClientJSON(
                 self.auth_provider)
+            self.volumes_v2_extension_client = VolumeV2ExtensionClientJSON(
+                self.auth_provider)
             self.hosts_v3_client = HostsV3ClientJSON(self.auth_provider)
             self.database_flavors_client = DatabaseFlavorsClientJSON(
                 self.auth_provider)
@@ -376,6 +393,8 @@
             self.negative_client.service = service
             self.volume_availability_zone_client = \
                 VolumeAvailabilityZoneClientJSON(self.auth_provider)
+            self.volume_v2_availability_zone_client = \
+                VolumeV2AvailabilityZoneClientJSON(self.auth_provider)
 
         else:
             msg = "Unsupported interface type `%s'" % interface
@@ -406,6 +425,9 @@
         self.data_processing_client = DataProcessingClient(
             self.auth_provider)
         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/cmd/javelin.py b/tempest/cmd/javelin.py
index 0b72b1c..6761a69 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -19,15 +19,16 @@
 
 """
 
+import argparse
 import logging
 import os
 import sys
 import unittest
+
 import yaml
 
-import argparse
-
 import tempest.auth
+from tempest import config
 from tempest import exceptions
 from tempest.services.compute.json import flavors_client
 from tempest.services.compute.json import servers_client
@@ -218,6 +219,8 @@
 
     def check_objects(self):
         """Check that the objects created are still there."""
+        if not self.res.get('objects'):
+            return
         LOG.info("checking objects")
         for obj in self.res['objects']:
             client = client_for_user(obj['owner'])
@@ -228,6 +231,8 @@
 
     def check_servers(self):
         """Check that the servers are still up and running."""
+        if not self.res.get('servers'):
+            return
         LOG.info("checking servers")
         for server in self.res['servers']:
             client = client_for_user(server['owner'])
@@ -239,12 +244,18 @@
             r, found = client.servers.get_server(found['id'])
             # get the ipv4 address
             addr = found['addresses']['private'][0]['addr']
-            self.assertEqual(os.system("ping -c 1 " + addr), 0,
-                             "Server %s is not pingable at %s" % (
-                                 server['name'], addr))
+            for count in range(60):
+                return_code = os.system("ping -c1 " + addr)
+                if return_code is 0:
+                    break
+            self.assertNotEqual(count, 59,
+                                "Server %s is not pingable at %s" % (
+                                    server['name'], addr))
 
     def check_volumes(self):
         """Check that the volumes are still there and attached."""
+        if not self.res.get('volumes'):
+            return
         LOG.info("checking volumes")
         for volume in self.res['volumes']:
             client = client_for_user(volume['owner'])
@@ -273,6 +284,8 @@
 
 
 def create_objects(objects):
+    if not objects:
+        return
     LOG.info("Creating objects")
     for obj in objects:
         LOG.debug("Object %s" % obj)
@@ -296,14 +309,24 @@
     return name, fname
 
 
+def _get_image_by_name(client, name):
+    r, body = client.images.image_list()
+    for image in body:
+        if name == image['name']:
+            return image
+    return None
+
+
 def create_images(images):
+    if not images:
+        return
+    LOG.info("Creating images")
     for image in images:
         client = client_for_user(image['owner'])
 
         # only upload a new image if the name isn't there
-        r, body = client.images.image_list()
-        names = [x['name'] for x in body]
-        if image['name'] in names:
+        if _get_image_by_name(client, image['name']):
+            LOG.info("Image '%s' already exists" % image['name'])
             continue
 
         # special handling for 3 part image
@@ -328,6 +351,20 @@
         client.images.store_image(image_id, open(fname, 'r'))
 
 
+def destroy_images(images):
+    if not images:
+        return
+    LOG.info("Destroying images")
+    for image in images:
+        client = client_for_user(image['owner'])
+
+        response = _get_image_by_name(client, image['name'])
+        if not response:
+            LOG.info("Image '%s' does not exists" % image['name'])
+            continue
+        client.images.delete_image(response['id'])
+
+
 #######################
 #
 # SERVERS
@@ -342,14 +379,6 @@
     return None
 
 
-def _get_image_by_name(client, name):
-    r, body = client.images.image_list()
-    for image in body:
-        if name == image['name']:
-            return image
-    return None
-
-
 def _get_flavor_by_name(client, name):
     r, body = client.flavors.list_flavors()
     for flavor in body:
@@ -359,15 +388,39 @@
 
 
 def create_servers(servers):
+    if not servers:
+        return
+    LOG.info("Creating servers")
     for server in servers:
         client = client_for_user(server['owner'])
 
         if _get_server_by_name(client, server['name']):
+            LOG.info("Server '%s' already exists" % server['name'])
             continue
 
         image_id = _get_image_by_name(client, server['image'])['id']
         flavor_id = _get_flavor_by_name(client, server['flavor'])['id']
-        client.servers.create_server(server['name'], image_id, flavor_id)
+        resp, body = client.servers.create_server(server['name'], image_id,
+                                                  flavor_id)
+        server_id = body['id']
+        client.servers.wait_for_server_status(server_id, 'ACTIVE')
+
+
+def destroy_servers(servers):
+    if not servers:
+        return
+    LOG.info("Destroying servers")
+    for server in servers:
+        client = client_for_user(server['owner'])
+
+        response = _get_server_by_name(client, server['name'])
+        if not response:
+            LOG.info("Server '%s' does not exist" % server['name'])
+            continue
+
+        client.servers.delete_server(response['id'])
+        client.servers.wait_for_server_termination(response['id'],
+                                                   ignore_error=True)
 
 
 #######################
@@ -428,6 +481,24 @@
     # attach_volumes(RES['volumes'])
 
 
+def destroy_resources():
+    LOG.info("Destroying Resources")
+    # Destroy in inverse order of create
+
+    # Future
+    # detach_volumes
+    # destroy_volumes
+
+    destroy_servers(RES['servers'])
+    destroy_images(RES['images'])
+    # destroy_objects
+
+    # destroy_users
+    # destroy_tenants
+
+    LOG.warn("Destroy mode incomplete")
+
+
 def get_options():
     global OPTS
     parser = argparse.ArgumentParser(
@@ -440,11 +511,17 @@
                         required=True,
                         metavar='resourcefile.yaml',
                         help='Resources definition yaml file')
+
     parser.add_argument(
         '-d', '--devstack-base',
         required=True,
         metavar='/opt/stack/old',
         help='Devstack base directory for retrieving artifacts')
+    parser.add_argument(
+        '-c', '--config-file',
+        metavar='/etc/tempest.conf',
+        help='path to javelin2(tempest) config file')
+
     # auth bits, letting us also just source the devstack openrc
     parser.add_argument('--os-username',
                         metavar='<auth-user-name>',
@@ -464,6 +541,8 @@
         print("ERROR: Unknown mode -m %s\n" % OPTS.mode)
         parser.print_help()
         sys.exit(1)
+    if OPTS.config_file:
+        config.CONF.set_config_path(OPTS.config_file)
 
 
 def setup_logging(debug=True):
@@ -491,15 +570,20 @@
 
     if OPTS.mode == 'create':
         create_resources()
+        # Make sure the resources we just created actually work
+        checker = JavelinCheck(USERS, RES)
+        checker.check()
     elif OPTS.mode == 'check':
         collect_users(RES['users'])
         checker = JavelinCheck(USERS, RES)
         checker.check()
     elif OPTS.mode == 'destroy':
-        LOG.warn("Destroy mode not yet implemented")
+        collect_users(RES['users'])
+        destroy_resources()
     else:
         LOG.error('Unknown mode %s' % OPTS.mode)
         return 1
+    LOG.info('javelin2 successfully finished')
     return 0
 
 if __name__ == "__main__":
diff --git a/tempest/cmd/run_stress.py b/tempest/cmd/run_stress.py
index 07f3f66..a3f185c 100755
--- a/tempest/cmd/run_stress.py
+++ b/tempest/cmd/run_stress.py
@@ -18,13 +18,14 @@
 import inspect
 import json
 import sys
-from testtools import testsuite
 try:
     from unittest import loader
 except ImportError:
     # unittest in python 2.6 does not contain loader, so uses unittest2
     from unittest2 import loader
 
+from testtools import testsuite
+
 from tempest.openstack.common import log as logging
 from tempest.stress import driver
 
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 0834cff..cd696a9 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -29,13 +29,12 @@
 
 CONF = config.CONF
 RAW_HTTP = httplib2.Http()
-CONF_FILE = None
-OUTFILE = sys.stdout
+CONF_PARSER = None
 
 
 def _get_config_file():
     default_config_dir = os.path.join(os.path.abspath(
-        os.path.dirname(os.path.dirname(__file__))), "etc")
+        os.path.dirname(os.path.dirname(os.path.dirname(__file__)))), "etc")
     default_config_file = "tempest.conf"
 
     conf_dir = os.environ.get('TEMPEST_CONFIG_DIR', default_config_dir)
@@ -46,14 +45,9 @@
 
 
 def change_option(option, group, value):
-    config_parse = moves.configparser.SafeConfigParser()
-    config_parse.optionxform = str
-    config_parse.readfp(CONF_FILE)
-    if not config_parse.has_section(group):
-        config_parse.add_section(group)
-    config_parse.set(group, option, str(value))
-    global OUTFILE
-    config_parse.write(OUTFILE)
+    if not CONF_PARSER.has_section(group):
+        CONF_PARSER.add_section(group)
+    CONF_PARSER.set(group, option, str(value))
 
 
 def print_and_or_update(option, group, value, update):
@@ -253,7 +247,7 @@
         'data_processing': 'sahara',
         'baremetal': 'ironic',
         'identity': 'keystone',
-        'queuing': 'marconi',
+        'queuing': 'zaqar',
         'database': 'trove'
     }
     # Get catalog list for endpoints to use for validation
@@ -275,7 +269,7 @@
                 if getattr(CONF.service_available, codename_match[cfgname]):
                     print('Endpoint type %s not found either disable service '
                           '%s or fix the catalog_type in the config file' % (
-                          catalog_type, codename_match[cfgname]))
+                              catalog_type, codename_match[cfgname]))
                     if update:
                         change_option(codename_match[cfgname],
                                       'service_available', False)
@@ -284,10 +278,13 @@
                                codename_match[cfgname]):
                     print('Endpoint type %s is available, service %s should be'
                           ' set as available in the config file.' % (
-                          catalog_type, codename_match[cfgname]))
+                              catalog_type, codename_match[cfgname]))
                     if update:
                         change_option(codename_match[cfgname],
                                       'service_available', True)
+                        # If we are going to enable this we should allow
+                        # extension checks.
+                        avail_services.append(codename_match[cfgname])
                 else:
                     avail_services.append(codename_match[cfgname])
     return avail_services
@@ -321,12 +318,16 @@
     opts = parse_args()
     update = opts.update
     replace = opts.replace_ext
-    global CONF_FILE
-    global OUTFILE
+    global CONF_PARSER
+
+    outfile = sys.stdout
     if update:
-        CONF_FILE = _get_config_file()
+        conf_file = _get_config_file()
         if opts.output:
-            OUTFILE = open(opts.output, 'w+')
+            outfile = open(opts.output, 'w+')
+        CONF_PARSER = moves.configparser.SafeConfigParser()
+        CONF_PARSER.optionxform = str
+        CONF_PARSER.readfp(conf_file)
     os = clients.ComputeAdminManager(interface='json')
     services = check_service_availability(os, update)
     results = {}
@@ -341,9 +342,10 @@
     verify_nova_api_versions(os, update)
     verify_cinder_api_versions(os, update)
     display_results(results, update, replace)
-    if CONF_FILE:
-        CONF_FILE.close()
-    OUTFILE.close()
+    if update:
+        conf_file.close()
+        CONF_PARSER.write(outfile)
+    outfile.close()
 
 
 if __name__ == "__main__":
diff --git a/tempest/common/accounts.py b/tempest/common/accounts.py
new file mode 100644
index 0000000..ad88ea2
--- /dev/null
+++ b/tempest/common/accounts.py
@@ -0,0 +1,131 @@
+# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
+#
+#    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 hashlib
+import os
+
+import yaml
+
+from tempest import auth
+from tempest.common import cred_provider
+from tempest import config
+from tempest import exceptions
+from tempest.openstack.common import lockutils
+from tempest.openstack.common import log as logging
+
+CONF = config.CONF
+LOG = logging.getLogger(__name__)
+
+
+def read_accounts_yaml(path):
+    yaml_file = open(path, 'r')
+    accounts = yaml.load(yaml_file)
+    return accounts
+
+
+class Accounts(cred_provider.CredentialProvider):
+
+    def __init__(self, name):
+        super(Accounts, self).__init__(name)
+        accounts = read_accounts_yaml(CONF.auth.test_accounts_file)
+        self.hash_dict = self.get_hash_dict(accounts)
+        self.accounts_dir = os.path.join(CONF.lock_path, 'test_accounts')
+        self.isolated_creds = {}
+
+    @classmethod
+    def get_hash_dict(cls, accounts):
+        hash_dict = {}
+        for account in accounts:
+            temp_hash = hashlib.md5()
+            temp_hash.update(str(account))
+            hash_dict[temp_hash.hexdigest()] = account
+        return hash_dict
+
+    def _create_hash_file(self, hash):
+        path = os.path.join(os.path.join(self.accounts_dir, hash))
+        if not os.path.isfile(path):
+            open(path, 'w').close()
+            return True
+        return False
+
+    @lockutils.synchronized('test_accounts_io', external=True)
+    def _get_free_hash(self, hashes):
+        if not os.path.isdir(self.accounts_dir):
+            os.mkdir(self.accounts_dir)
+            # Create File from first hash (since none are in use)
+            self._create_hash_file(hashes[0])
+            return hashes[0]
+        for hash in hashes:
+            res = self._create_hash_file(hash)
+            if res:
+                return hash
+        msg = 'Insufficient number of users provided'
+        raise exceptions.InvalidConfiguration(msg)
+
+    def _get_creds(self):
+        free_hash = self._get_free_hash(self.hashes.keys())
+        return self.hash_dict[free_hash]
+
+    @lockutils.synchronized('test_accounts_io', external=True)
+    def remove_hash(self, hash):
+        hash_path = os.path.join(self.accounts_dir, hash)
+        if not os.path.isfile(hash_path):
+            LOG.warning('Expected an account lock file %s to remove, but '
+                        'one did not exist')
+        else:
+            os.remove(hash_path)
+            if not os.listdir(self.accounts_dir):
+                os.rmdir(self.accounts_dir)
+
+    def get_hash(self, creds):
+        for hash in self.hash_dict:
+            # NOTE(mtreinish) Assuming with v3 that username, tenant, password
+            # is unique enough
+            cred_dict = {
+                'username': creds.username,
+                'tenant_name': creds.tenant_name,
+                'password': creds.password
+            }
+            if self.hash_dict[hash] == cred_dict:
+                return hash
+        raise AttributeError('Invalid credentials %s' % creds)
+
+    def remove_credentials(self, creds):
+        hash = self.get_hash(creds)
+        self.remove_hash(hash, self.accounts_dir)
+
+    def get_primary_creds(self):
+        if self.credentials.get('primary'):
+            return self.credentials.get('primary')
+        creds = self._get_creds()
+        primary_credential = auth.get_credentials(**creds)
+        self.credentials['primary'] = primary_credential
+        return primary_credential
+
+    def get_alt_creds(self):
+        if self.credentials.get('alt'):
+            return self.credentials.get('alt')
+        creds = self._get_creds()
+        alt_credential = auth.get_credentials(**creds)
+        self.credentials['alt'] = alt_credential
+        return alt_credential
+
+    def clear_isolated_creds(self):
+        for creds in self.credentials.values():
+            self.remove_credentials(creds)
+
+    def get_admin_creds(self):
+        msg = ('If admin credentials are available tenant_isolation should be'
+               ' used instead')
+        raise NotImplementedError(msg)
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
new file mode 100644
index 0000000..9808ed1
--- /dev/null
+++ b/tempest/common/cred_provider.py
@@ -0,0 +1,45 @@
+# (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 abc
+
+import six
+
+from tempest import config
+from tempest.openstack.common import log as logging
+
+CONF = config.CONF
+LOG = logging.getLogger(__name__)
+
+
+@six.add_metaclass(abc.ABCMeta)
+class CredentialProvider(object):
+    def __init__(self, name, tempest_client=True, interface='json',
+                 password='pass', network_resources=None):
+        self.name = name
+
+    @abc.abstractmethod
+    def get_primary_creds(self):
+        return
+
+    @abc.abstractmethod
+    def get_admin_creds(self):
+        return
+
+    @abc.abstractmethod
+    def get_alt_creds(self):
+        return
+
+    @abc.abstractmethod
+    def clear_isolated_creds(self):
+        return
diff --git a/tempest/common/custom_matchers.py b/tempest/common/custom_matchers.py
index 4a7921f..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):
@@ -69,10 +72,24 @@
             elif self.target == 'Object':
                 if 'etag' not in actual:
                     return NonExistentHeader('etag')
-        elif self.method == 'PUT' or self.method == 'COPY':
+                if 'last-modified' not in actual:
+                    return NonExistentHeader('last-modified')
+        elif self.method == 'PUT':
             if self.target == 'Object':
                 if 'etag' not in actual:
                     return NonExistentHeader('etag')
+                if 'last-modified' not in actual:
+                    return NonExistentHeader('last-modified')
+        elif self.method == 'COPY':
+            if self.target == 'Object':
+                if 'etag' not in actual:
+                    return NonExistentHeader('etag')
+                if 'last-modified' not in actual:
+                    return NonExistentHeader('last-modified')
+                if 'x-copied-from' not in actual:
+                    return NonExistentHeader('x-copied-from')
+                if 'x-copied-from-last-modified' not in actual:
+                    return NonExistentHeader('x-copied-from-last-modified')
 
         return None
 
@@ -122,11 +139,17 @@
                 return InvalidFormat(key, value)
             elif key == 'content-type' and not value:
                 return InvalidFormat(key, value)
+            elif key == 'x-copied-from' and not re.match("\S+/\S+", value):
+                return InvalidFormat(key, value)
+            elif key == 'x-copied-from-last-modified' and not value:
+                return InvalidFormat(key, value)
             elif key == 'x-trans-id' and \
                 not re.match("^tx[0-9a-f]{21}-[0-9a-f]{10}.*", value):
                 return InvalidFormat(key, value)
             elif key == 'date' and not value:
                 return InvalidFormat(key, value)
+            elif key == 'last-modified' and not value:
+                return InvalidFormat(key, value)
             elif key == 'accept-ranges' and not value == 'bytes':
                 return InvalidFormat(key, value)
             elif key == 'etag' and not value.isalnum():
@@ -152,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/debug.py b/tempest/common/debug.py
index 228be7a..16e5ffe 100644
--- a/tempest/common/debug.py
+++ b/tempest/common/debug.py
@@ -14,7 +14,6 @@
 
 from tempest.common import commands
 from tempest import config
-
 from tempest.openstack.common import log as logging
 
 CONF = config.CONF
diff --git a/tempest/common/generator/base_generator.py b/tempest/common/generator/base_generator.py
index 57b98f7..0398af1 100644
--- a/tempest/common/generator/base_generator.py
+++ b/tempest/common/generator/base_generator.py
@@ -13,6 +13,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import functools
+
 import jsonschema
 
 from tempest.openstack.common import log as logging
@@ -39,6 +41,7 @@
     """
     Decorator for simple generators that return one value
     """
+    @functools.wraps(fn)
     def wrapped(self, schema):
         result = fn(self, schema)
         if result is not None:
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/common/glance_http.py b/tempest/common/glance_http.py
index 55aca5a..5f35c85 100644
--- a/tempest/common/glance_http.py
+++ b/tempest/common/glance_http.py
@@ -19,15 +19,17 @@
 import hashlib
 import httplib
 import json
-import OpenSSL
 import posixpath
 import re
-from six import moves
 import socket
 import StringIO
 import struct
 import urlparse
 
+
+import OpenSSL
+from six import moves
+
 from tempest import exceptions as exc
 from tempest.openstack.common import log as logging
 
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index 208f42f..dca1f86 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -13,9 +13,11 @@
 #    under the License.
 
 import netaddr
+from neutronclient.common import exceptions as n_exc
 
 from tempest import auth
 from tempest import clients
+from tempest.common import cred_provider
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -25,15 +27,16 @@
 LOG = logging.getLogger(__name__)
 
 
-class IsolatedCreds(object):
+class IsolatedCreds(cred_provider.CredentialProvider):
 
     def __init__(self, name, tempest_client=True, interface='json',
                  password='pass', network_resources=None):
+        super(IsolatedCreds, self).__init__(name, tempest_client, interface,
+                                            password, network_resources)
         self.network_resources = network_resources
         self.isolated_creds = {}
         self.isolated_net_resources = {}
         self.ports = []
-        self.name = name
         self.tempest_client = tempest_client
         self.interface = interface
         self.password = password
@@ -160,9 +163,11 @@
         email = data_utils.rand_name(root) + suffix + "@example.com"
         user = self._create_user(username, self.password,
                                  tenant, email)
-        # NOTE(andrey-mp): user needs this role to create containers in swift
-        swift_operator_role = CONF.object_storage.operator_role
-        self._assign_user_role(tenant, user, swift_operator_role)
+        if CONF.service_available.swift:
+            # NOTE(andrey-mp): user needs this role to create containers
+            # in swift
+            swift_operator_role = CONF.object_storage.operator_role
+            self._assign_user_role(tenant, user, swift_operator_role)
         if admin:
             self._assign_user_role(tenant, user, CONF.identity.admin_role)
         return self._get_credentials(user, tenant)
@@ -259,7 +264,7 @@
                     body['subnet']['cidr'] = str(subnet_cidr)
                     resp_body = self.network_admin_client.create_subnet(body)
                 break
-            except exceptions.BadRequest as e:
+            except (n_exc.BadRequest, exceptions.BadRequest) as e:
                 if 'overlaps with another subnet' not in str(e):
                     raise
         else:
@@ -328,7 +333,8 @@
             # Maintained until tests are ported
             LOG.info("Acquired isolated creds:\n credentials: %s"
                      % credentials)
-            if CONF.service_available.neutron:
+            if (CONF.service_available.neutron and
+                not CONF.baremetal.driver_enabled):
                 network, subnet, router = self._create_network_resources(
                     credentials.tenant_id)
                 self.isolated_net_resources[credential_type] = (
@@ -370,31 +376,6 @@
             LOG.warn('network with name: %s not found for delete' %
                      network_name)
 
-    def _cleanup_ports(self, network_id):
-        # TODO(mlavalle) This method will be removed once patch
-        # https://review.openstack.org/#/c/46563/ merges in Neutron
-        if not self.ports:
-            if self.tempest_client:
-                resp, resp_body = self.network_admin_client.list_ports()
-            else:
-                resp_body = self.network_admin_client.list_ports()
-            self.ports = resp_body['ports']
-        ports_to_delete = [
-            port
-            for port in self.ports
-            if (port['network_id'] == network_id and
-                port['device_owner'] != 'network:router_interface' and
-                port['device_owner'] != 'network:dhcp')
-        ]
-        for port in ports_to_delete:
-            try:
-                LOG.info('Cleaning up port id %s, name %s' %
-                         (port['id'], port['name']))
-                self.network_admin_client.delete_port(port['id'])
-            except exceptions.NotFound:
-                LOG.warn('Port id: %s, name %s not found for clean-up' %
-                         (port['id'], port['name']))
-
     def _clear_isolated_net_resources(self):
         net_client = self.network_admin_client
         for cred in self.isolated_net_resources:
@@ -416,11 +397,6 @@
                              router['name'])
                 self._clear_isolated_router(router['id'], router['name'])
             if (not self.network_resources or
-                self.network_resources.get('network')):
-                # TODO(mlavalle) This method call will be removed once patch
-                # https://review.openstack.org/#/c/46563/ merges in Neutron
-                self._cleanup_ports(network['id'])
-            if (not self.network_resources or
                 self.network_resources.get('subnet')):
                 self._clear_isolated_subnet(subnet['id'], subnet['name'])
             if (not self.network_resources or
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 9e0f4d3..ff92b67 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -16,12 +16,12 @@
 
 import collections
 import json
-from lxml import etree
 import re
 import string
 import time
 
 import jsonschema
+from lxml import etree
 
 from tempest.common import http
 from tempest.common.utils import misc as misc_utils
@@ -209,8 +209,9 @@
             pattern = """Unexpected http success status code {0},
                          The expected status code is {1}"""
             if ((not isinstance(expected_code, list) and
-                (read_code != expected_code)) or (isinstance(expected_code,
-                list) and (read_code not in expected_code))):
+                 (read_code != expected_code)) or
+                (isinstance(expected_code, list) and
+                 (read_code not in expected_code))):
                 details = pattern.format(read_code, expected_code)
                 raise exceptions.InvalidHttpSuccessCode(details)
 
diff --git a/tempest/common/ssh.py b/tempest/common/ssh.py
index 531887c..c06ce3b 100644
--- a/tempest/common/ssh.py
+++ b/tempest/common/ssh.py
@@ -16,11 +16,12 @@
 
 import cStringIO
 import select
-import six
 import socket
 import time
 import warnings
 
+import six
+
 from tempest import exceptions
 from tempest.openstack.common import log as logging
 
diff --git a/tempest/common/utils/data_utils.py b/tempest/common/utils/data_utils.py
index a0a88dd..5a29ea0 100644
--- a/tempest/common/utils/data_utils.py
+++ b/tempest/common/utils/data_utils.py
@@ -34,6 +34,11 @@
         return randbits
 
 
+def rand_url():
+    randbits = str(random.randint(1, 0x7fffffff))
+    return 'https://url-' + randbits + '.com'
+
+
 def rand_int_id(start=0, end=0x7fffffff):
     return random.randint(start, end)
 
@@ -66,3 +71,11 @@
     if not base_text:
         base_text = 'test'
     return ''.join(itertools.islice(itertools.cycle(base_text), size))
+
+
+def random_bytes(size=1024):
+    """
+    Return size randomly selected bytes as a string.
+    """
+    return ''.join([chr(random.randint(0, 255))
+                    for i in range(size)])
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 57a14a2..89904b2 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -11,9 +11,10 @@
 #    under the License.
 
 import re
-import six
 import time
 
+import six
+
 from tempest.common import ssh
 from tempest import config
 from tempest import exceptions
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index d8474a0..c4f1214 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -22,16 +22,6 @@
 LOG = logging.getLogger(__name__)
 
 
-def _console_dump(client, server_id):
-    try:
-        resp, output = client.get_console_output(server_id, None)
-        LOG.debug("Console Output for Server %s:\n%s" % (
-            server_id, output))
-    except exceptions.NotFound:
-        LOG.debug("Server %s: doesn't have a console" % server_id)
-        pass
-
-
 # NOTE(afazekas): This function needs to know a token and a subject.
 def wait_for_server_status(client, server_id, status, ready_wait=True,
                            extra_timeout=0, raise_on_error=True):
@@ -81,10 +71,12 @@
                      '/'.join((old_status, str(old_task_state))),
                      '/'.join((server_status, str(task_state))),
                      time.time() - start_time)
-
         if (server_status == 'ERROR') and raise_on_error:
-            _console_dump(client, server_id)
-            raise exceptions.BuildErrorException(server_id=server_id)
+            if 'fault' in body:
+                raise exceptions.BuildErrorException(body['fault'],
+                                                     server_id=server_id)
+            else:
+                raise exceptions.BuildErrorException(server_id=server_id)
 
         timed_out = int(time.time()) - start_time >= timeout
 
@@ -99,11 +91,9 @@
                         'timeout': timeout})
             message += ' Current status: %s.' % server_status
             message += ' Current task state: %s.' % task_state
-
             caller = misc_utils.find_test_caller()
             if caller:
                 message = '(%s) %s' % (caller, message)
-            _console_dump(client, server_id)
             raise exceptions.TimeoutException(message)
         old_status = server_status
         old_task_state = task_state
diff --git a/tempest/common/xml_utils.py b/tempest/common/xml_utils.py
index b1bf789..7d460a4 100644
--- a/tempest/common/xml_utils.py
+++ b/tempest/common/xml_utils.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 import collections
+import copy
 
 XMLNS_11 = "http://docs.openstack.org/compute/api/v1.1"
 XMLNS_V3 = "http://docs.openstack.org/compute/api/v1.1"
@@ -78,16 +79,19 @@
 
 class Document(Element):
     def __init__(self, *args, **kwargs):
-        if 'version' not in kwargs:
-            kwargs['version'] = '1.0'
-        if 'encoding' not in kwargs:
-            kwargs['encoding'] = 'UTF-8'
         Element.__init__(self, '?xml', *args, **kwargs)
 
     def __str__(self):
-        args = " ".join(['%s="%s"' %
-                        (k, v if v is not None else "")
-                        for k, v in self._attrs.items()])
+        attrs = copy.copy(self._attrs)
+        # pop the required standard attrs out and render in required
+        # order.
+        vers = attrs.pop('version', '1.0')
+        enc = attrs.pop('encoding', 'UTF-8')
+        args = 'version="%s" encoding="%s"' % (vers, enc)
+        if attrs:
+            args = " ".join([args] + ['%s="%s"' %
+                            (k, v if v is not None else "")
+                            for k, v in attrs.items()])
         string = '<?xml %s?>\n' % args
         for element in self._elements:
             string += str(element)
diff --git a/tempest/config.py b/tempest/config.py
index 0fb3fd3..93d4874 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -29,6 +29,18 @@
         conf.register_opt(opt, group=opt_group.name)
 
 
+auth_group = cfg.OptGroup(name='auth',
+                          title="Options for authentication and credentials")
+
+
+AuthGroup = [
+    cfg.StrOpt('test_accounts_file',
+               default='etc/accounts.yaml',
+               help="Path to the yaml file that contains the list of "
+                    "credentials to use for running tests"),
+]
+
+
 identity_group = cfg.OptGroup(name='identity',
                               title="Keystone Configuration Options")
 
@@ -247,6 +259,9 @@
     cfg.BoolOpt('api_v3',
                 default=False,
                 help="If false, skip all nova v3 tests."),
+    cfg.BoolOpt('xml_api_v2',
+                default=True,
+                help="If false skip all v2 api tests with xml"),
     cfg.BoolOpt('disk_config',
                 default=True,
                 help="If false, skip disk config tests"),
@@ -254,22 +269,31 @@
                 default=['all'],
                 help='A list of enabled compute extensions with a special '
                      'entry all which indicates every extension is enabled. '
-                     'Each extension should be specified with alias name'),
+                     'Each extension should be specified with alias name. '
+                     'Empty list indicates all extensions are disabled'),
     cfg.ListOpt('api_v3_extensions',
                 default=['all'],
                 help='A list of enabled v3 extensions with a special entry all'
                      ' which indicates every extension is enabled. '
-                     'Each extension should be specified with alias name'),
+                     'Each extension should be specified with alias name. '
+                     'Empty list indicates all extensions are disabled'),
     cfg.BoolOpt('change_password',
                 default=False,
                 help="Does the test environment support changing the admin "
                      "password?"),
+    cfg.BoolOpt('console_output',
+                default=True,
+                help="Does the test environment support obtaining instance "
+                     "serial console output?"),
     cfg.BoolOpt('resize',
                 default=False,
                 help="Does the test environment support resizing?"),
     cfg.BoolOpt('pause',
                 default=True,
                 help="Does the test environment support pausing?"),
+    cfg.BoolOpt('shelve',
+                default=True,
+                help="Does the test environment support shelving/unshelving?"),
     cfg.BoolOpt('suspend',
                 default=True,
                 help="Does the test environment support suspend/resume?"),
@@ -300,7 +324,20 @@
     cfg.BoolOpt('rescue',
                 default=True,
                 help='Does the test environment support instance rescue '
-                     'mode?')
+                     'mode?'),
+    cfg.BoolOpt('enable_instance_password',
+                default=True,
+                help='Enables returning of the instance password by the '
+                     'relevant server API calls such as create, rebuild '
+                     'or rescue.'),
+    cfg.BoolOpt('interface_attach',
+                default=True,
+                help='Does the test environment support dynamic network '
+                     'interface attachment?'),
+    cfg.BoolOpt('snapshot',
+                default=True,
+                help='Does the test environment support creating snapshot '
+                     'images of running instances?')
 ]
 
 
@@ -423,7 +460,8 @@
     cfg.ListOpt('api_extensions',
                 default=['all'],
                 help='A list of enabled network extensions with a special '
-                     'entry all which indicates every extension is enabled'),
+                     'entry all which indicates every extension is enabled. '
+                     'Empty list indicates all extensions are disabled'),
     cfg.BoolOpt('ipv6_subnet_attributes',
                 default=False,
                 help="Allow the execution of IPv6 subnet tests that use "
@@ -528,7 +566,8 @@
     cfg.ListOpt('api_extensions',
                 default=['all'],
                 help='A list of enabled volume extensions with a special '
-                     'entry all which indicates every extension is enabled'),
+                     'entry all which indicates every extension is enabled. '
+                     'Empty list indicates all extensions are disabled'),
     cfg.BoolOpt('api_v1',
                 default=True,
                 help="Is the v1 volume API enabled"),
@@ -788,9 +827,15 @@
                default='/opt/stack/new/devstack/files/images/'
                'cirros-0.3.1-x86_64-uec',
                help='Directory containing image files'),
-    cfg.StrOpt('qcow2_img_file',
+    cfg.StrOpt('img_file', deprecated_name='qcow2_img_file',
                default='cirros-0.3.1-x86_64-disk.img',
-               help='QCOW2 image file name'),
+               help='Image file name'),
+    cfg.StrOpt('img_disk_format',
+               default='qcow2',
+               help='Image disk format'),
+    cfg.StrOpt('img_container_format',
+               default='bare',
+               help='Image container format'),
     cfg.StrOpt('ami_img_file',
                default='cirros-0.3.1-x86_64-blank.img',
                help='AMI image file name'),
@@ -848,9 +893,9 @@
     cfg.BoolOpt('trove',
                 default=False,
                 help="Whether or not Trove is expected to be available"),
-    cfg.BoolOpt('marconi',
+    cfg.BoolOpt('zaqar',
                 default=False,
-                help="Whether or not Marconi is expected to be available"),
+                help="Whether or not Zaqar is expected to be available"),
 ]
 
 debug_group = cfg.OptGroup(name="debug",
@@ -968,6 +1013,7 @@
 
 
 def register_opts():
+    register_opt_group(cfg.CONF, auth_group, AuthGroup)
     register_opt_group(cfg.CONF, compute_group, ComputeGroup)
     register_opt_group(cfg.CONF, compute_features_group,
                        ComputeFeaturesGroup)
@@ -1015,7 +1061,12 @@
 
     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
         self.compute_feature_enabled = cfg.CONF['compute-feature-enabled']
         self.identity = cfg.CONF.identity
@@ -1057,18 +1108,22 @@
         cfg.CONF.set_default('domain_name', self.identity.admin_domain_name,
                              group='compute-admin')
 
-    def __init__(self, parse_conf=True):
+    def __init__(self, parse_conf=True, config_path=None):
         """Initialize a configuration from a conf directory and conf file."""
         super(TempestConfigPrivate, self).__init__()
         config_files = []
         failsafe_path = "/etc/tempest/" + self.DEFAULT_CONFIG_FILE
 
-        # Environment variables override defaults...
-        conf_dir = os.environ.get('TEMPEST_CONFIG_DIR',
-                                  self.DEFAULT_CONFIG_DIR)
-        conf_file = os.environ.get('TEMPEST_CONFIG', self.DEFAULT_CONFIG_FILE)
+        if config_path:
+            path = config_path
+        else:
+            # Environment variables override defaults...
+            conf_dir = os.environ.get('TEMPEST_CONFIG_DIR',
+                                      self.DEFAULT_CONFIG_DIR)
+            conf_file = os.environ.get('TEMPEST_CONFIG',
+                                       self.DEFAULT_CONFIG_FILE)
 
-        path = os.path.join(conf_dir, conf_file)
+            path = os.path.join(conf_dir, conf_file)
 
         if not os.path.isfile(path):
             path = failsafe_path
@@ -1090,6 +1145,7 @@
 
 class TempestConfigProxy(object):
     _config = None
+    _path = None
 
     _extra_log_defaults = [
         'keystoneclient.session=INFO',
@@ -1106,9 +1162,12 @@
     def __getattr__(self, attr):
         if not self._config:
             self._fix_log_levels()
-            self._config = TempestConfigPrivate()
+            self._config = TempestConfigPrivate(config_path=self._path)
 
         return getattr(self._config, attr)
 
+    def set_config_path(self, path):
+        self._path = path
+
 
 CONF = TempestConfigProxy()
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 4eb1cea..cc31fad 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -211,3 +211,20 @@
 
 class InvalidStructure(TempestException):
     message = "Invalid structure of table with details"
+
+
+class CommandFailed(Exception):
+    def __init__(self, returncode, cmd, output, stderr):
+        super(CommandFailed, self).__init__()
+        self.returncode = returncode
+        self.cmd = cmd
+        self.stdout = output
+        self.stderr = stderr
+
+    def __str__(self):
+        return ("Command '%s' returned non-zero exit status %d.\n"
+                "stdout:\n%s\n"
+                "stderr:\n%s" % (self.cmd,
+                                 self.returncode,
+                                 self.stdout,
+                                 self.stderr))
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index 93329bc..cef010e 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -20,7 +20,7 @@
 
 PYTHON_CLIENTS = ['cinder', 'glance', 'keystone', 'nova', 'swift', 'neutron',
                   'trove', 'ironic', 'savanna', 'heat', 'ceilometer',
-                  'marconi', 'sahara']
+                  'zaqar', 'sahara']
 
 PYTHON_CLIENT_RE = re.compile('import (%s)client' % '|'.join(PYTHON_CLIENTS))
 TEST_DEFINITION = re.compile(r'^\s*def test.*')
diff --git a/tempest/scenario/README.rst b/tempest/scenario/README.rst
index 835ba99..5a287d6 100644
--- a/tempest/scenario/README.rst
+++ b/tempest/scenario/README.rst
@@ -1,3 +1,5 @@
+.. _scenario_field_guide:
+
 Tempest Field Guide to Scenario tests
 =====================================
 
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index ca79325..0f14c94 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -17,7 +17,6 @@
 import logging
 import os
 import re
-import six
 import subprocess
 import time
 
@@ -27,6 +26,7 @@
 import netaddr
 from neutronclient.common import exceptions as exc
 from novaclient import exceptions as nova_exceptions
+import six
 
 from tempest.api.network import common as net_common
 from tempest import auth
@@ -53,6 +53,370 @@
 LOG_cinder_client.addHandler(log.NullHandler())
 
 
+class ScenarioTest(tempest.test.BaseTestCase):
+    """Replaces the OfficialClientTest base class.
+
+    Uses tempest own clients as opposed to OfficialClients.
+
+    Common differences:
+    - replace resource.attribute with resource['attribute']
+    - replace resouce.delete with delete_callable(resource['id'])
+    - replace local waiters with common / rest_client waiters
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        super(ScenarioTest, cls).setUpClass()
+        # Using tempest client for isolated credentials as well
+        cls.isolated_creds = isolated_creds.IsolatedCreds(
+            cls.__name__, tempest_client=True,
+            network_resources=cls.network_resources)
+        cls.manager = clients.Manager(
+            credentials=cls.credentials()
+        )
+        cls.admin_manager = clients.Manager(cls.admin_credentials())
+        # Clients (in alphabetical order)
+        cls.floating_ips_client = cls.manager.floating_ips_client
+        # Glance image client v1
+        cls.image_client = cls.manager.image_client
+        # Compute image client
+        cls.images_client = cls.manager.images_client
+        cls.keypairs_client = cls.manager.keypairs_client
+        cls.networks_client = cls.admin_manager.networks_client
+        # Nova security groups client
+        cls.security_groups_client = cls.manager.security_groups_client
+        cls.servers_client = cls.manager.servers_client
+        cls.volumes_client = cls.manager.volumes_client
+        cls.snapshots_client = cls.manager.snapshots_client
+
+    @classmethod
+    def _get_credentials(cls, get_creds, ctype):
+        if CONF.compute.allow_tenant_isolation:
+            creds = get_creds()
+        else:
+            creds = auth.get_default_credentials(ctype)
+        return creds
+
+    @classmethod
+    def credentials(cls):
+        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')
+
+    # ## Methods to handle sync and async deletes
+
+    def setUp(self):
+        super(ScenarioTest, self).setUp()
+        self.cleanup_waits = []
+        # NOTE(mtreinish) This is safe to do in setUp instead of setUp class
+        # because scenario tests in the same test class should not share
+        # resources. If resources were shared between test cases then it
+        # should be a single scenario test instead of multiples.
+
+        # NOTE(yfried): this list is cleaned at the end of test_methods and
+        # not at the end of the class
+        self.addCleanup(self._wait_for_cleanups)
+
+    def delete_wrapper(self, delete_thing, thing_id):
+        """Ignores NotFound exceptions for delete operations.
+
+        @param delete_thing: delete method of a resource
+        @param thing_id: id of the resource to be deleted
+        """
+        try:
+            # Tempest clients return dicts, so there is no common delete
+            # method available. Using a callable instead
+            delete_thing(thing_id)
+        except exceptions.NotFound:
+            # If the resource is already missing, mission accomplished.
+            pass
+
+    def addCleanup_with_wait(self, waiter_callable, thing_id, thing_id_param,
+                             cleanup_callable, cleanup_args=[],
+                             cleanup_kwargs={}, ignore_error=True):
+        """Adds wait for ansyc resource deletion at the end of cleanups
+
+        @param waiter_callable: callable to wait for the resource to delete
+        @param thing_id: the id of the resource to be cleaned-up
+        @param thing_id_param: the name of the id param in the waiter
+        @param cleanup_callable: method to load pass to self.addCleanup with
+            the following *cleanup_args, **cleanup_kwargs.
+            usually a delete method.
+        """
+        self.addCleanup(cleanup_callable, *cleanup_args, **cleanup_kwargs)
+        wait_dict = {
+            'waiter_callable': waiter_callable,
+            thing_id_param: thing_id
+        }
+        self.cleanup_waits.append(wait_dict)
+
+    def _wait_for_cleanups(self):
+        """To handle async delete actions, a list of waits is added
+        which will be iterated over as the last step of clearing the
+        cleanup queue. That way all the delete calls are made up front
+        and the tests won't succeed unless the deletes are eventually
+        successful. This is the same basic approach used in the api tests to
+        limit cleanup execution time except here it is multi-resource,
+        because of the nature of the scenario tests.
+        """
+        for wait in self.cleanup_waits:
+            waiter_callable = wait.pop('waiter_callable')
+            waiter_callable(**wait)
+
+    # ## Test functions library
+    #
+    # The create_[resource] functions only return body and discard the
+    # resp part which is not used in scenario tests
+
+    def create_keypair(self):
+        name = data_utils.rand_name(self.__class__.__name__)
+        # We don't need to create a keypair by pubkey in scenario
+        resp, body = self.keypairs_client.create_keypair(name)
+        self.addCleanup(self.keypairs_client.delete_keypair, name)
+        return body
+
+    def create_server(self, name=None, image=None, flavor=None,
+                      wait_on_boot=True, wait_on_delete=True,
+                      create_kwargs={}):
+        """Creates VM instance.
+
+        @param image: image from which to create the instance
+        @param wait_on_boot: wait for status ACTIVE before continue
+        @param wait_on_delete: force synchronous delete on cleanup
+        @param create_kwargs: additional details for instance creation
+        @return: server dict
+        """
+        if name is None:
+            name = data_utils.rand_name(self.__class__.__name__)
+        if image is None:
+            image = CONF.compute.image_ref
+        if flavor is None:
+            flavor = CONF.compute.flavor_ref
+
+        fixed_network_name = CONF.compute.fixed_network_name
+        if 'nics' not in create_kwargs and fixed_network_name:
+            _, networks = self.networks_client.list_networks()
+            # If several networks found, set the NetID on which to connect the
+            # server to avoid the following error "Multiple possible networks
+            # found, use a Network ID to be more specific."
+            # See Tempest #1250866
+            if len(networks) > 1:
+                for network in networks:
+                    if network['label'] == fixed_network_name:
+                        create_kwargs['nics'] = [{'net-id': network['id']}]
+                        break
+                # If we didn't find the network we were looking for :
+                else:
+                    msg = ("The network on which the NIC of the server must "
+                           "be connected can not be found : "
+                           "fixed_network_name=%s. Starting instance without "
+                           "specifying a network.") % fixed_network_name
+                    LOG.info(msg)
+
+        LOG.debug("Creating a server (name: %s, image: %s, flavor: %s)",
+                  name, image, flavor)
+        _, server = self.servers_client.create_server(name, image, flavor,
+                                                      **create_kwargs)
+        if wait_on_delete:
+            self.addCleanup(self.servers_client.wait_for_server_termination,
+                            server['id'])
+        self.addCleanup_with_wait(
+            waiter_callable=self.servers_client.wait_for_server_termination,
+            thing_id=server['id'], thing_id_param='server_id',
+            cleanup_callable=self.delete_wrapper,
+            cleanup_args=[self.servers_client.delete_server, server['id']])
+        if wait_on_boot:
+            self.servers_client.wait_for_server_status(server_id=server['id'],
+                                                       status='ACTIVE')
+        # The instance retrieved on creation is missing network
+        # details, necessitating retrieval after it becomes active to
+        # ensure correct details.
+        _, server = self.servers_client.get_server(server['id'])
+        self.assertEqual(server['name'], name)
+        return server
+
+    def create_volume(self, size=1, name=None, snapshot_id=None,
+                      imageRef=None, volume_type=None, wait_on_delete=True):
+        if name is None:
+            name = data_utils.rand_name(self.__class__.__name__)
+        _, volume = self.volumes_client.create_volume(
+            size=size, display_name=name, snapshot_id=snapshot_id,
+            imageRef=imageRef, volume_type=volume_type)
+        if wait_on_delete:
+            self.addCleanup(self.volumes_client.wait_for_resource_deletion,
+                            volume['id'])
+        self.addCleanup_with_wait(
+            waiter_callable=self.volumes_client.wait_for_resource_deletion,
+            thing_id=volume['id'], thing_id_param='id',
+            cleanup_callable=self.delete_wrapper,
+            cleanup_args=[self.volumes_client.delete_volume, volume['id']])
+
+        self.assertEqual(name, volume['display_name'])
+        self.volumes_client.wait_for_volume_status(volume['id'], 'available')
+        # The volume retrieved on creation has a non-up-to-date status.
+        # Retrieval after it becomes active ensures correct details.
+        _, volume = self.volumes_client.get_volume(volume['id'])
+        return volume
+
+    def _create_loginable_secgroup_rule_nova(self, secgroup_id=None):
+        _client = self.security_groups_client
+        if secgroup_id is None:
+            _, sgs = _client.list_security_groups()
+            for sg in sgs:
+                if sg['name'] == 'default':
+                    secgroup_id = sg['id']
+
+        # These rules are intended to permit inbound ssh and icmp
+        # traffic from all sources, so no group_id is provided.
+        # Setting a group_id would only permit traffic from ports
+        # belonging to the same security group.
+        rulesets = [
+            {
+                # ssh
+                'ip_proto': 'tcp',
+                'from_port': 22,
+                'to_port': 22,
+                'cidr': '0.0.0.0/0',
+            },
+            {
+                # ping
+                'ip_proto': 'icmp',
+                'from_port': -1,
+                'to_port': -1,
+                'cidr': '0.0.0.0/0',
+            }
+        ]
+        rules = list()
+        for ruleset in rulesets:
+            _, sg_rule = _client.create_security_group_rule(secgroup_id,
+                                                            **ruleset)
+            self.addCleanup(self.delete_wrapper,
+                            _client.delete_security_group_rule,
+                            sg_rule['id'])
+            rules.append(sg_rule)
+        return rules
+
+    def _create_security_group_nova(self):
+        # Create security group
+        sg_name = data_utils.rand_name(self.__class__.__name__)
+        sg_desc = sg_name + " description"
+        _, secgroup = self.security_groups_client.create_security_group(
+            sg_name, sg_desc)
+        self.assertEqual(secgroup['name'], sg_name)
+        self.assertEqual(secgroup['description'], sg_desc)
+        self.addCleanup(self.delete_wrapper,
+                        self.security_groups_client.delete_security_group,
+                        secgroup['id'])
+
+        # Add rules to the security group
+        self._create_loginable_secgroup_rule_nova(secgroup['id'])
+
+        return secgroup
+
+    def get_remote_client(self, server_or_ip, username=None, private_key=None):
+        if isinstance(server_or_ip, six.string_types):
+            ip = server_or_ip
+        else:
+            network_name_for_ssh = CONF.compute.network_for_ssh
+            ip = server_or_ip.networks[network_name_for_ssh][0]
+        if username is None:
+            username = CONF.scenario.ssh_user
+        if private_key is None:
+            private_key = self.keypair['private_key']
+        linux_client = remote_client.RemoteClient(ip, username,
+                                                  pkey=private_key)
+        try:
+            linux_client.validate_authentication()
+        except exceptions.SSHTimeout:
+            LOG.exception('ssh connection to %s failed' % ip)
+            debug.log_net_debug()
+            raise
+
+        return linux_client
+
+    def _image_create(self, name, fmt, path, properties={}):
+        name = data_utils.rand_name('%s-' % name)
+        image_file = open(path, 'rb')
+        self.addCleanup(image_file.close)
+        params = {
+            'name': name,
+            'container_format': fmt,
+            'disk_format': fmt,
+            'is_public': 'False',
+        }
+        params.update(properties)
+        _, image = self.image_client.create_image(**params)
+        self.addCleanup(self.image_client.delete_image, image['id'])
+        self.assertEqual("queued", image['status'])
+        self.image_client.update_image(image['id'], data=image_file)
+        return image['id']
+
+    def glance_image_create(self):
+        img_path = CONF.scenario.img_dir + "/" + CONF.scenario.img_file
+        aki_img_path = CONF.scenario.img_dir + "/" + CONF.scenario.aki_img_file
+        ari_img_path = CONF.scenario.img_dir + "/" + CONF.scenario.ari_img_file
+        ami_img_path = CONF.scenario.img_dir + "/" + CONF.scenario.ami_img_file
+        img_container_format = CONF.scenario.img_container_format
+        img_disk_format = CONF.scenario.img_disk_format
+        LOG.debug("paths: img: %s, container_fomat: %s, disk_format: %s, "
+                  "ami: %s, ari: %s, aki: %s" %
+                  (img_path, img_container_format, img_disk_format,
+                   ami_img_path, ari_img_path, aki_img_path))
+        try:
+            self.image = self._image_create('scenario-img',
+                                            img_container_format,
+                                            img_path,
+                                            properties={'disk_format':
+                                                        img_disk_format})
+        except IOError:
+            LOG.debug("A qcow2 image was not found. Try to get a uec image.")
+            kernel = self._image_create('scenario-aki', 'aki', aki_img_path)
+            ramdisk = self._image_create('scenario-ari', 'ari', ari_img_path)
+            properties = {
+                'properties': {'kernel_id': kernel, 'ramdisk_id': ramdisk}
+            }
+            self.image = self._image_create('scenario-ami', 'ami',
+                                            path=ami_img_path,
+                                            properties=properties)
+        LOG.debug("image:%s" % self.image)
+
+    def _log_console_output(self, servers=None):
+        if not servers:
+            _, servers = self.servers_client.list_servers()
+            servers = servers['servers']
+        for server in servers:
+            LOG.debug('Console output for %s', server['id'])
+            LOG.debug(self.servers_client.get_console_output(server['id'],
+                                                             length=None))
+
+    def create_server_snapshot(self, server, name=None):
+        # Glance client
+        _image_client = self.image_client
+        # Compute client
+        _images_client = self.images_client
+        if name is None:
+            name = data_utils.rand_name('scenario-snapshot-')
+        LOG.debug("Creating a snapshot image for server: %s", server['name'])
+        resp, image = _images_client.create_image(server['id'], name)
+        image_id = resp['location'].split('images/')[1]
+        _image_client.wait_for_image_status(image_id, 'active')
+        self.addCleanup_with_wait(
+            waiter_callable=_image_client.wait_for_resource_deletion,
+            thing_id=image_id, thing_id_param='id',
+            cleanup_callable=self.delete_wrapper,
+            cleanup_args=[_image_client.delete_image, image_id])
+        _, snapshot_image = _image_client.get_image_meta(image_id)
+        image_name = snapshot_image['name']
+        self.assertEqual(name, image_name)
+        LOG.debug("Created snapshot image %s for server %s",
+                  image_name, server['name'])
+        return snapshot_image
+
+
 class OfficialClientTest(tempest.test.BaseTestCase):
     """
     Official Client test base class for scenario testing.
@@ -87,6 +451,11 @@
         cls.ceilometer_client = cls.manager.ceilometer_client
 
     @classmethod
+    def tearDownClass(cls):
+        cls.isolated_creds.clear_isolated_creds()
+        super(OfficialClientTest, cls).tearDownClass()
+
+    @classmethod
     def _get_credentials(cls, get_creds, ctype):
         if CONF.compute.allow_tenant_isolation:
             creds = get_creds()
@@ -292,11 +661,25 @@
                 'cidr': '0.0.0.0/0',
             },
             {
+                # ssh -6
+                'ip_protocol': 'tcp',
+                'from_port': 22,
+                'to_port': 22,
+                'cidr': '::/0',
+            },
+            {
                 # ping
                 'ip_protocol': 'icmp',
                 'from_port': -1,
                 'to_port': -1,
                 'cidr': '0.0.0.0/0',
+            },
+            {
+                # ping6
+                'ip_protocol': 'icmp',
+                'from_port': -1,
+                'to_port': -1,
+                'cidr': '::/0',
             }
         ]
         rules = list()
@@ -324,6 +707,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={}):
@@ -459,6 +858,9 @@
         return linux_client
 
     def _log_console_output(self, servers=None):
+        if not CONF.compute_feature_enabled.console_output:
+            LOG.debug('Console output not supported, cannot log')
+            return
         if not servers:
             servers = self.compute_client.servers.list()
         for server in servers:
@@ -488,19 +890,22 @@
         return image.id
 
     def glance_image_create(self):
-        qcow2_img_path = (CONF.scenario.img_dir + "/" +
-                          CONF.scenario.qcow2_img_file)
+        img_path = CONF.scenario.img_dir + "/" + CONF.scenario.img_file
         aki_img_path = CONF.scenario.img_dir + "/" + CONF.scenario.aki_img_file
         ari_img_path = CONF.scenario.img_dir + "/" + CONF.scenario.ari_img_file
         ami_img_path = CONF.scenario.img_dir + "/" + CONF.scenario.ami_img_file
-        LOG.debug("paths: img: %s, ami: %s, ari: %s, aki: %s"
-                  % (qcow2_img_path, ami_img_path, ari_img_path, aki_img_path))
+        img_container_format = CONF.scenario.img_container_format
+        img_disk_format = CONF.scenario.img_disk_format
+        LOG.debug("paths: img: %s, container_fomat: %s, disk_format: %s, "
+                  "ami: %s, ari: %s, aki: %s" %
+                  (img_path, img_container_format, img_disk_format,
+                   ami_img_path, ari_img_path, aki_img_path))
         try:
             self.image = self._image_create('scenario-img',
-                                            'bare',
-                                            qcow2_img_path,
+                                            img_container_format,
+                                            img_path,
                                             properties={'disk_format':
-                                                        'qcow2'})
+                                                        img_disk_format})
         except IOError:
             LOG.debug("A qcow2 image was not found. Try to get a uec image.")
             kernel = self._image_create('scenario-aki', 'aki', aki_img_path)
@@ -1054,7 +1459,8 @@
             try:
                 source.ping_host(dest)
             except exceptions.SSHExecCommandFailed:
-                LOG.exception('Failed to ping host via ssh connection')
+                LOG.warn('Failed to ping IP: %s via a ssh connection from: %s.'
+                         % (dest, source.ssh_client.host))
                 return not should_succeed
             return should_succeed
 
@@ -1408,3 +1814,81 @@
             self.client.stacks.delete(stack_identifier)
         except heat_exceptions.HTTPNotFound:
             pass
+
+
+class SwiftScenarioTest(ScenarioTest):
+    """
+    Provide harness to do Swift scenario tests.
+
+    Subclasses implement the tests that use the methods provided by this
+    class.
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        cls.set_network_resources()
+        super(SwiftScenarioTest, cls).setUpClass()
+        if not CONF.service_available.swift:
+            skip_msg = ("%s skipped as swift is not available" %
+                        cls.__name__)
+            raise cls.skipException(skip_msg)
+        # Clients for Swift
+        cls.account_client = cls.manager.account_client
+        cls.container_client = cls.manager.container_client
+        cls.object_client = cls.manager.object_client
+
+    def _get_swift_stat(self):
+        """get swift status for our user account."""
+        self.account_client.list_account_containers()
+        LOG.debug('Swift status information obtained successfully')
+
+    def _create_container(self, container_name=None):
+        name = container_name or data_utils.rand_name(
+            'swift-scenario-container')
+        self.container_client.create_container(name)
+        # look for the container to assure it is created
+        self._list_and_check_container_objects(name)
+        LOG.debug('Container %s created' % (name))
+        return name
+
+    def _delete_container(self, container_name):
+        self.container_client.delete_container(container_name)
+        LOG.debug('Container %s deleted' % (container_name))
+
+    def _upload_object_to_container(self, container_name, obj_name=None):
+        obj_name = obj_name or data_utils.rand_name('swift-scenario-object')
+        obj_data = data_utils.arbitrary_string()
+        self.object_client.create_object(container_name, obj_name, obj_data)
+        return obj_name, obj_data
+
+    def _delete_object(self, container_name, filename):
+        self.object_client.delete_object(container_name, filename)
+        self._list_and_check_container_objects(container_name,
+                                               not_present_obj=[filename])
+
+    def _list_and_check_container_objects(self, container_name, present_obj=[],
+                                          not_present_obj=[]):
+        """
+        List objects for a given container and assert which are present and
+        which are not.
+        """
+        _, object_list = self.container_client.list_container_contents(
+            container_name)
+        if present_obj:
+            for obj in present_obj:
+                self.assertIn(obj, object_list)
+        if not_present_obj:
+            for obj in not_present_obj:
+                self.assertNotIn(obj, object_list)
+
+    def _change_container_acl(self, container_name, acl):
+        metadata_param = {'metadata_prefix': 'x-container-',
+                          'metadata': {'read': acl}}
+        self.container_client.update_container_metadata(container_name,
+                                                        **metadata_param)
+        resp, _ = self.container_client.list_container_metadata(container_name)
+        self.assertEqual(resp['x-container-read'], acl)
+
+    def _download_and_verify(self, container_name, obj_name, expected_data):
+        _, obj = self.object_client.get_object(container_name, obj_name)
+        self.assertEqual(obj, expected_data)
diff --git a/tempest/scenario/orchestration/test_autoscaling.py b/tempest/scenario/orchestration/test_autoscaling.py
index aa7b6f8..8894106 100644
--- a/tempest/scenario/orchestration/test_autoscaling.py
+++ b/tempest/scenario/orchestration/test_autoscaling.py
@@ -10,9 +10,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import heatclient.exc as heat_exceptions
 import time
 
+import heatclient.exc as heat_exceptions
+
 from tempest import config
 from tempest.scenario import manager
 from tempest import test
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_dashboard_basic_ops.py b/tempest/scenario/test_dashboard_basic_ops.py
index 6418a73..4fcc70a 100644
--- a/tempest/scenario/test_dashboard_basic_ops.py
+++ b/tempest/scenario/test_dashboard_basic_ops.py
@@ -24,7 +24,7 @@
 CONF = config.CONF
 
 
-class TestDashboardBasicOps(manager.OfficialClientTest):
+class TestDashboardBasicOps(manager.ScenarioTest):
 
     """
     This is a basic scenario test:
diff --git a/tempest/scenario/test_load_balancer_basic.py b/tempest/scenario/test_load_balancer_basic.py
index 800b3b0..8191984 100644
--- a/tempest/scenario/test_load_balancer_basic.py
+++ b/tempest/scenario/test_load_balancer_basic.py
@@ -141,7 +141,7 @@
                 server_or_ip=ip,
                 private_key=private_key)
 
-            # Write a backend's responce into a file
+            # Write a backend's response into a file
             resp = """echo -ne "HTTP/1.1 200 OK\r\nContent-Length: 7\r\n""" \
                    """Connection: close\r\nContent-Type: text/html; """ \
                    """charset=UTF-8\r\n\r\n%s"; cat >/dev/null"""
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index 29fdc74..4bc4a98 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -13,6 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from tempest.common import custom_matchers
 from tempest.common import debug
 from tempest import config
 from tempest.openstack.common import log as logging
@@ -24,7 +25,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class TestMinimumBasicScenario(manager.OfficialClientTest):
+class TestMinimumBasicScenario(manager.ScenarioTest):
 
     """
     This is a basic minimum scenario test.
@@ -38,61 +39,69 @@
     """
 
     def _wait_for_server_status(self, status):
-        server_id = self.server.id
-        self.status_timeout(
-            self.compute_client.servers, server_id, status)
+        server_id = self.server['id']
+        # Raise on error defaults to True, which is consistent with the
+        # original function from scenario tests here
+        self.servers_client.wait_for_server_status(server_id, status)
 
     def nova_keypair_add(self):
         self.keypair = self.create_keypair()
 
     def nova_boot(self):
-        create_kwargs = {'key_name': self.keypair.name}
+        create_kwargs = {'key_name': self.keypair['name']}
         self.server = self.create_server(image=self.image,
                                          create_kwargs=create_kwargs)
 
     def nova_list(self):
-        servers = self.compute_client.servers.list()
-        LOG.debug("server_list:%s" % servers)
-        self.assertIn(self.server, servers)
+        _, servers = self.servers_client.list_servers()
+        # The list servers in the compute client is inconsistent...
+        servers = servers['servers']
+        self.assertIn(self.server['id'], [x['id'] for x in servers])
 
     def nova_show(self):
-        got_server = self.compute_client.servers.get(self.server)
-        LOG.debug("got server:%s" % got_server)
-        self.assertEqual(self.server, got_server)
+        _, got_server = self.servers_client.get_server(self.server['id'])
+        self.assertThat(
+            self.server, custom_matchers.MatchesDictExceptForKeys(
+                got_server, excluded_keys=['OS-EXT-AZ:availability_zone']))
 
     def cinder_create(self):
         self.volume = self.create_volume()
 
     def cinder_list(self):
-        volumes = self.volume_client.volumes.list()
-        self.assertIn(self.volume, volumes)
+        _, volumes = self.volumes_client.list_volumes()
+        self.assertIn(self.volume['id'], [x['id'] for x in volumes])
 
     def cinder_show(self):
-        volume = self.volume_client.volumes.get(self.volume.id)
+        _, volume = self.volumes_client.get_volume(self.volume['id'])
         self.assertEqual(self.volume, volume)
 
     def nova_volume_attach(self):
-        attach_volume_client = self.compute_client.volumes.create_server_volume
-        volume = attach_volume_client(self.server.id,
-                                      self.volume.id,
-                                      '/dev/vdb')
-        self.assertEqual(self.volume.id, volume.id)
-        self.wait_for_volume_status('in-use')
+        volume_device_path = '/dev/' + CONF.compute.volume_device_name
+        _, volume_attachment = self.servers_client.attach_volume(
+            self.server['id'], self.volume['id'], volume_device_path)
+        volume = volume_attachment['volumeAttachment']
+        self.assertEqual(self.volume['id'], volume['id'])
+        self.volumes_client.wait_for_volume_status(volume['id'], 'in-use')
+        # Refresh the volume after the attachment
+        _, self.volume = self.volumes_client.get_volume(volume['id'])
 
     def nova_reboot(self):
-        self.server.reboot()
+        self.servers_client.reboot(self.server['id'], 'SOFT')
         self._wait_for_server_status('ACTIVE')
 
     def nova_floating_ip_create(self):
-        self.floating_ip = self.compute_client.floating_ips.create()
-        self.addCleanup(self.delete_wrapper, self.floating_ip)
+        _, self.floating_ip = self.floating_ips_client.create_floating_ip()
+        self.addCleanup(self.delete_wrapper,
+                        self.floating_ips_client.delete_floating_ip,
+                        self.floating_ip['id'])
 
     def nova_floating_ip_add(self):
-        self.server.add_floating_ip(self.floating_ip)
+        self.floating_ips_client.associate_floating_ip_to_server(
+            self.floating_ip['ip'], self.server['id'])
 
     def ssh_to_server(self):
         try:
-            self.linux_client = self.get_remote_client(self.floating_ip.ip)
+            self.linux_client = self.get_remote_client(self.floating_ip['ip'])
         except Exception as e:
             LOG.exception('ssh to server failed')
             self._log_console_output()
@@ -102,21 +111,24 @@
             raise
 
     def check_partitions(self):
+        # NOTE(andreaf) The device name may be different on different guest OS
         partitions = self.linux_client.get_partitions()
-        self.assertEqual(1, partitions.count('vdb'))
+        self.assertEqual(1, partitions.count(CONF.compute.volume_device_name))
 
     def nova_volume_detach(self):
-        detach_volume_client = self.compute_client.volumes.delete_server_volume
-        detach_volume_client(self.server.id, self.volume.id)
-        self.wait_for_volume_status('available')
+        self.servers_client.detach_volume(self.server['id'], self.volume['id'])
+        self.volumes_client.wait_for_volume_status(self.volume['id'],
+                                                   'available')
 
-        volume = self.volume_client.volumes.get(self.volume.id)
-        self.assertEqual('available', volume.status)
+        _, volume = self.volumes_client.get_volume(self.volume['id'])
+        self.assertEqual('available', volume['status'])
 
     def create_and_add_security_group(self):
         secgroup = self._create_security_group_nova()
-        self.server.add_security_group(secgroup.name)
-        self.addCleanup(self.server.remove_security_group, secgroup.name)
+        self.servers_client.add_security_group(self.server['id'],
+                                               secgroup['name'])
+        self.addCleanup(self.servers_client.remove_security_group,
+                        self.server['id'], secgroup['name'])
 
     @test.services('compute', 'volume', 'image', 'network')
     def test_minimum_basic_scenario(self):
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 7dc817d..bba034b 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -14,13 +14,15 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 import collections
-
 import re
 
+import testtools
+
 from tempest.api.network import common as net_common
 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
@@ -221,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)
@@ -347,6 +357,8 @@
                                                 msg="after re-associate "
                                                     "floating ip")
 
+    @testtools.skipUnless(CONF.compute_feature_enabled.interface_attach,
+                          'NIC hotplug not available')
     @test.attr(type='smoke')
     @test.services('compute', 'network')
     def test_hotplug_nic(self):
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_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index 5a1dc04..463f5aa 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -25,7 +25,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class TestServerAdvancedOps(manager.OfficialClientTest):
+class TestServerAdvancedOps(manager.ScenarioTest):
 
     """
     This test case stresses some advanced server instance operations:
@@ -49,19 +49,19 @@
     def test_resize_server_confirm(self):
         # We create an instance for use in this test
         instance = self.create_server()
-        instance_id = instance.id
+        instance_id = instance['id']
         resize_flavor = CONF.compute.flavor_ref_alt
         LOG.debug("Resizing instance %s from flavor %s to flavor %s",
-                  instance.id, instance.flavor, resize_flavor)
-        instance.resize(resize_flavor)
-        self.status_timeout(self.compute_client.servers, instance_id,
-                            'VERIFY_RESIZE')
+                  instance['id'], instance['flavor']['id'], resize_flavor)
+        self.servers_client.resize(instance_id, resize_flavor)
+        self.servers_client.wait_for_server_status(instance_id,
+                                                   'VERIFY_RESIZE')
 
         LOG.debug("Confirming resize of instance %s", instance_id)
-        instance.confirm_resize()
+        self.servers_client.confirm_resize(instance_id)
 
-        self.status_timeout(
-            self.compute_client.servers, instance_id, 'ACTIVE')
+        self.servers_client.wait_for_server_status(instance_id,
+                                                   'ACTIVE')
 
     @testtools.skipUnless(CONF.compute_feature_enabled.suspend,
                           'Suspend is not available.')
@@ -69,24 +69,27 @@
     def test_server_sequence_suspend_resume(self):
         # We create an instance for use in this test
         instance = self.create_server()
-        instance_id = instance.id
+        instance_id = instance['id']
         LOG.debug("Suspending instance %s. Current status: %s",
-                  instance_id, instance.status)
-        instance.suspend()
-        self.status_timeout(self.compute_client.servers, instance_id,
-                            'SUSPENDED')
+                  instance_id, instance['status'])
+        self.servers_client.suspend_server(instance_id)
+        self.servers_client.wait_for_server_status(instance_id,
+                                                   'SUSPENDED')
+        _, fetched_instance = self.servers_client.get_server(instance_id)
         LOG.debug("Resuming instance %s. Current status: %s",
-                  instance_id, instance.status)
-        instance.resume()
-        self.status_timeout(self.compute_client.servers, instance_id,
-                            'ACTIVE')
+                  instance_id, fetched_instance['status'])
+        self.servers_client.resume_server(instance_id)
+        self.servers_client.wait_for_server_status(instance_id,
+                                                   'ACTIVE')
+        _, fetched_instance = self.servers_client.get_server(instance_id)
         LOG.debug("Suspending instance %s. Current status: %s",
-                  instance_id, instance.status)
-        instance.suspend()
-        self.status_timeout(self.compute_client.servers, instance_id,
-                            'SUSPENDED')
+                  instance_id, fetched_instance['status'])
+        self.servers_client.suspend_server(instance_id)
+        self.servers_client.wait_for_server_status(instance_id,
+                                                   'SUSPENDED')
+        _, fetched_instance = self.servers_client.get_server(instance_id)
         LOG.debug("Resuming instance %s. Current status: %s",
-                  instance_id, instance.status)
-        instance.resume()
-        self.status_timeout(self.compute_client.servers, instance_id,
-                            'ACTIVE')
+                  instance_id, fetched_instance['status'])
+        self.servers_client.resume_server(instance_id)
+        self.servers_client.wait_for_server_status(instance_id,
+                                                   'ACTIVE')
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 38686d9..77e195d 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -26,7 +26,7 @@
 load_tests = test_utils.load_tests_input_scenario_utils
 
 
-class TestServerBasicOps(manager.OfficialClientTest):
+class TestServerBasicOps(manager.ScenarioTest):
 
     """
     This smoke test case follows this basic set of operations:
@@ -69,9 +69,9 @@
 
     def boot_instance(self):
         # Create server with image and flavor from input scenario
-        security_groups = [self.security_group.name]
+        security_groups = [self.security_group]
         create_kwargs = {
-            'key_name': self.keypair.id,
+            'key_name': self.keypair['name'],
             'security_groups': security_groups
         }
         self.instance = self.create_server(image=self.image_ref,
@@ -81,16 +81,19 @@
     def verify_ssh(self):
         if self.run_ssh:
             # Obtain a floating IP
-            floating_ip = self.compute_client.floating_ips.create()
-            self.addCleanup(self.delete_wrapper, floating_ip)
+            _, floating_ip = self.floating_ips_client.create_floating_ip()
+            self.addCleanup(self.delete_wrapper,
+                            self.floating_ips_client.delete_floating_ip,
+                            floating_ip['id'])
             # Attach a floating IP
-            self.instance.add_floating_ip(floating_ip)
+            self.floating_ips_client.associate_floating_ip_to_server(
+                floating_ip['ip'], self.instance['id'])
             # Check ssh
             try:
                 self.get_remote_client(
-                    server_or_ip=floating_ip.ip,
+                    server_or_ip=floating_ip['ip'],
                     username=self.image_utils.ssh_user(self.image_ref),
-                    private_key=self.keypair.private_key)
+                    private_key=self.keypair['private_key'])
             except Exception:
                 LOG.exception('ssh to server failed')
                 self._log_console_output()
@@ -102,4 +105,4 @@
         self.security_group = self._create_security_group_nova()
         self.boot_instance()
         self.verify_ssh()
-        self.instance.delete()
+        self.servers_client.delete_server(self.instance['id'])
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 7dd662d..d500065 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
@@ -23,7 +25,7 @@
 LOG = log.getLogger(__name__)
 
 
-class TestSnapshotPattern(manager.OfficialClientTest):
+class TestSnapshotPattern(manager.ScenarioTest):
     """
     This test is for snapshotting an instance and booting with it.
     The following is the scenario outline:
@@ -35,9 +37,9 @@
     """
 
     def _boot_image(self, image_id):
-        security_groups = [self.security_group.name]
+        security_groups = [self.security_group]
         create_kwargs = {
-            'key_name': self.keypair.name,
+            'key_name': self.keypair['name'],
             'security_groups': security_groups
         }
         return self.create_server(image=image_id, create_kwargs=create_kwargs)
@@ -64,13 +66,18 @@
         self.assertEqual(self.timestamp, got_timestamp)
 
     def _create_floating_ip(self):
-        floating_ip = self.compute_client.floating_ips.create()
-        self.addCleanup(self.delete_wrapper, floating_ip)
+        _, floating_ip = self.floating_ips_client.create_floating_ip()
+        self.addCleanup(self.delete_wrapper,
+                        self.floating_ips_client.delete_floating_ip,
+                        floating_ip['id'])
         return floating_ip
 
     def _set_floating_ip_to_server(self, server, floating_ip):
-        server.add_floating_ip(floating_ip)
+        self.floating_ips_client.associate_floating_ip_to_server(
+            floating_ip['ip'], server['id'])
 
+    @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
@@ -82,7 +89,7 @@
         if CONF.compute.use_floatingip_for_ssh:
             fip_for_server = self._create_floating_ip()
             self._set_floating_ip_to_server(server, fip_for_server)
-            self._write_timestamp(fip_for_server.ip)
+            self._write_timestamp(fip_for_server['ip'])
         else:
             self._write_timestamp(server)
 
@@ -90,13 +97,13 @@
         snapshot_image = self.create_server_snapshot(server=server)
 
         # boot a second instance from the snapshot
-        server_from_snapshot = self._boot_image(snapshot_image.id)
+        server_from_snapshot = self._boot_image(snapshot_image['id'])
 
         # check the existence of the timestamp file in the second instance
         if CONF.compute.use_floatingip_for_ssh:
             fip_for_snapshot = self._create_floating_ip()
             self._set_floating_ip_to_server(server_from_snapshot,
                                             fip_for_snapshot)
-            self._check_timestamp(fip_for_snapshot.ip)
+            self._check_timestamp(fip_for_snapshot['ip'])
         else:
             self._check_timestamp(server_from_snapshot)
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/scenario/test_swift_basic_ops.py b/tempest/scenario/test_swift_basic_ops.py
index 86e0867..ad74ec4 100644
--- a/tempest/scenario/test_swift_basic_ops.py
+++ b/tempest/scenario/test_swift_basic_ops.py
@@ -13,8 +13,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-
-from tempest.common.utils import data_utils
+from tempest.common import http
 from tempest import config
 from tempest.openstack.common import log as logging
 from tempest.scenario import manager
@@ -25,80 +24,49 @@
 LOG = logging.getLogger(__name__)
 
 
-class TestSwiftBasicOps(manager.OfficialClientTest):
+class TestSwiftBasicOps(manager.SwiftScenarioTest):
     """
-    Test swift with the follow operations:
+    Test swift basic ops.
      * get swift stat.
      * create container.
      * upload a file to the created container.
      * list container's objects and assure that the uploaded file is present.
+     * download the object and check the content
      * delete object from container.
      * list container's objects and assure that the deleted file is gone.
      * delete a container.
      * list containers and assure that the deleted container is gone.
+     * change ACL of the container and make sure it works successfully
     """
 
-    @classmethod
-    def setUpClass(cls):
-        cls.set_network_resources()
-        super(TestSwiftBasicOps, cls).setUpClass()
-        if not CONF.service_available.swift:
-            skip_msg = ("%s skipped as swift is not available" %
-                        cls.__name__)
-            raise cls.skipException(skip_msg)
-
-    def _get_swift_stat(self):
-        """get swift status for our user account."""
-        self.object_storage_client.get_account()
-        LOG.debug('Swift status information obtained successfully')
-
-    def _create_container(self, container_name=None):
-        name = container_name or data_utils.rand_name(
-            'swift-scenario-container')
-        self.object_storage_client.put_container(name)
-        # look for the container to assure it is created
-        self._list_and_check_container_objects(name)
-        LOG.debug('Container %s created' % (name))
-        return name
-
-    def _delete_container(self, container_name):
-        self.object_storage_client.delete_container(container_name)
-        LOG.debug('Container %s deleted' % (container_name))
-
-    def _upload_object_to_container(self, container_name, obj_name=None):
-        obj_name = obj_name or data_utils.rand_name('swift-scenario-object')
-        self.object_storage_client.put_object(container_name, obj_name,
-                                              data_utils.rand_name('obj_data'),
-                                              content_type='text/plain')
-        return obj_name
-
-    def _delete_object(self, container_name, filename):
-        self.object_storage_client.delete_object(container_name, filename)
-        self._list_and_check_container_objects(container_name,
-                                               not_present_obj=[filename])
-
-    def _list_and_check_container_objects(self, container_name, present_obj=[],
-                                          not_present_obj=[]):
-        """
-        List objects for a given container and assert which are present and
-        which are not.
-        """
-        meta, response = self.object_storage_client.get_container(
-            container_name)
-        # create a list with file name only
-        object_list = [obj['name'] for obj in response]
-        if present_obj:
-            for obj in present_obj:
-                self.assertIn(obj, object_list)
-        if not_present_obj:
-            for obj in not_present_obj:
-                self.assertNotIn(obj, object_list)
-
     @test.services('object_storage')
     def test_swift_basic_ops(self):
         self._get_swift_stat()
         container_name = self._create_container()
-        obj_name = self._upload_object_to_container(container_name)
+        obj_name, obj_data = self._upload_object_to_container(container_name)
         self._list_and_check_container_objects(container_name, [obj_name])
+        self._download_and_verify(container_name, obj_name, obj_data)
+        self._delete_object(container_name, obj_name)
+        self._delete_container(container_name)
+
+    @test.services('object_storage')
+    def test_swift_acl_anonymous_download(self):
+        """This test will cover below steps:
+        1. Create container
+        2. Upload object to the new container
+        3. Change the ACL of the container
+        4. Check if the object can be download by anonymous user
+        5. Delete the object and container
+        """
+        container_name = self._create_container()
+        obj_name, _ = self._upload_object_to_container(container_name)
+        obj_url = '%s/%s/%s' % (self.object_client.base_url,
+                                container_name, obj_name)
+        http_client = http.ClosingHttp()
+        resp, _ = http_client.request(obj_url, 'GET')
+        self.assertEqual(resp.status, 401)
+        self._change_container_acl(container_name, '.r:*')
+        resp, _ = http_client.request(obj_url, 'GET')
+        self.assertEqual(resp.status, 200)
         self._delete_object(container_name, obj_name)
         self._delete_container(container_name)
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index bf5d1f6..ec8575a 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -10,8 +10,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from cinderclient import exceptions as cinder_exc
-
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest.openstack.common import log
@@ -23,7 +21,7 @@
 LOG = log.getLogger(__name__)
 
 
-class TestVolumeBootPattern(manager.OfficialClientTest):
+class TestVolumeBootPattern(manager.ScenarioTest):
 
     """
     This test case attempts to reproduce the following steps:
@@ -54,28 +52,32 @@
         # dev_name=id:type:size:delete_on_terminate
         # where type needs to be "snap" if the server is booted
         # from a snapshot, size instead can be safely left empty
-        bd_map = {
-            'vda': vol_id + ':::0'
-        }
-        security_groups = [self.security_group.name]
+        bd_map = [{
+            'device_name': 'vda',
+            'volume_id': vol_id,
+            'delete_on_termination': '0'}]
+        self.security_group = self._create_security_group_nova()
+        security_groups = [{'name': self.security_group['name']}]
         create_kwargs = {
             'block_device_mapping': bd_map,
-            'key_name': keypair.name,
+            'key_name': keypair['name'],
             'security_groups': security_groups
         }
         return self.create_server(image='', create_kwargs=create_kwargs)
 
     def _create_snapshot_from_volume(self, vol_id):
-        volume_snapshots = self.volume_client.volume_snapshots
         snap_name = data_utils.rand_name('snapshot')
-        snap = volume_snapshots.create(volume_id=vol_id,
-                                       force=True,
-                                       display_name=snap_name)
-        self.addCleanup_with_wait(self.volume_client.volume_snapshots, snap.id,
-                                  exc_type=cinder_exc.NotFound)
-        self.status_timeout(volume_snapshots,
-                            snap.id,
-                            'available')
+        _, snap = self.snapshots_client.create_snapshot(
+            volume_id=vol_id,
+            force=True,
+            display_name=snap_name)
+        self.addCleanup_with_wait(
+            waiter_callable=self.snapshots_client.wait_for_resource_deletion,
+            thing_id=snap['id'], thing_id_param='id',
+            cleanup_callable=self.delete_wrapper,
+            cleanup_args=[self.snapshots_client.delete_snapshot, snap['id']])
+        self.snapshots_client.wait_for_snapshot_status(snap['id'], 'available')
+        self.assertEqual(snap_name, snap['display_name'])
         return snap
 
     def _create_volume_from_snapshot(self, snap_id):
@@ -85,27 +87,26 @@
     def _stop_instances(self, instances):
         # NOTE(gfidente): two loops so we do not wait for the status twice
         for i in instances:
-            self.compute_client.servers.stop(i)
+            self.servers_client.stop(i['id'])
         for i in instances:
-            self.status_timeout(self.compute_client.servers,
-                                i.id,
-                                'SHUTOFF')
+            self.servers_client.wait_for_server_status(i['id'], 'SHUTOFF')
 
     def _detach_volumes(self, volumes):
         # NOTE(gfidente): two loops so we do not wait for the status twice
         for v in volumes:
-            self.volume_client.volumes.detach(v)
+            self.volumes_client.detach_volume(v['id'])
         for v in volumes:
-            self.status_timeout(self.volume_client.volumes,
-                                v.id,
-                                'available')
+            self.volumes_client.wait_for_volume_status(v['id'], 'available')
 
     def _ssh_to_server(self, server, keypair):
         if CONF.compute.use_floatingip_for_ssh:
-            floating_ip = self.compute_client.floating_ips.create()
-            self.addCleanup(self.delete_wrapper, floating_ip)
-            server.add_floating_ip(floating_ip)
-            ip = floating_ip.ip
+            _, floating_ip = self.floating_ips_client.create_floating_ip()
+            self.addCleanup(self.delete_wrapper,
+                            self.floating_ips_client.delete_floating_ip,
+                            floating_ip['id'])
+            self.floating_ips_client.associate_floating_ip_to_server(
+                floating_ip['ip'], server['id'])
+            ip = floating_ip['ip']
         else:
             network_name_for_ssh = CONF.compute.network_for_ssh
             ip = server.networks[network_name_for_ssh][0]
@@ -113,10 +114,10 @@
         try:
             return self.get_remote_client(
                 ip,
-                private_key=keypair.private_key)
+                private_key=keypair['private_key'])
         except Exception:
             LOG.exception('ssh to server failed')
-            self._log_console_output()
+            self._log_console_output(self)
             raise
 
     def _get_content(self, ssh_client):
@@ -129,8 +130,8 @@
         return self._get_content(ssh_client)
 
     def _delete_server(self, server):
-        self.compute_client.servers.delete(server)
-        self.delete_timeout(self.compute_client.servers, server.id)
+        self.servers_client.delete_server(server['id'])
+        self.servers_client.wait_for_server_termination(server['id'])
 
     def _check_content_of_written_file(self, ssh_client, expected):
         actual = self._get_content(ssh_client)
@@ -143,7 +144,7 @@
 
         # create an instance from volume
         volume_origin = self._create_volume_from_image()
-        instance_1st = self._boot_instance_from_volume(volume_origin.id,
+        instance_1st = self._boot_instance_from_volume(volume_origin['id'],
                                                        keypair)
 
         # write content to volume on instance
@@ -155,7 +156,7 @@
         self._delete_server(instance_1st)
 
         # create a 2nd instance from volume
-        instance_2nd = self._boot_instance_from_volume(volume_origin.id,
+        instance_2nd = self._boot_instance_from_volume(volume_origin['id'],
                                                        keypair)
 
         # check the content of written file
@@ -164,11 +165,11 @@
         self._check_content_of_written_file(ssh_client_for_instance_2nd, text)
 
         # snapshot a volume
-        snapshot = self._create_snapshot_from_volume(volume_origin.id)
+        snapshot = self._create_snapshot_from_volume(volume_origin['id'])
 
         # create a 3rd instance from snapshot
-        volume = self._create_volume_from_snapshot(snapshot.id)
-        instance_from_snapshot = self._boot_instance_from_volume(volume.id,
+        volume = self._create_volume_from_snapshot(snapshot['id'])
+        instance_from_snapshot = self._boot_instance_from_volume(volume['id'],
                                                                  keypair)
 
         # check the content of written file
@@ -186,10 +187,11 @@
         bdms = [{'uuid': vol_id, 'source_type': 'volume',
                  'destination_type': 'volume', 'boot_index': 0,
                  'delete_on_termination': False}]
-        security_groups = [self.security_group.name]
+        self.security_group = self._create_security_group_nova()
+        security_groups = [{'name': self.security_group['name']}]
         create_kwargs = {
             'block_device_mapping_v2': bdms,
-            'key_name': keypair.name,
+            'key_name': keypair['name'],
             'security_groups': security_groups
         }
         return self.create_server(image='', create_kwargs=create_kwargs)
diff --git a/tempest/services/__init__.py b/tempest/services/__init__.py
index e7bec60..e69de29 100644
--- a/tempest/services/__init__.py
+++ b/tempest/services/__init__.py
@@ -1,37 +0,0 @@
-# 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.
-
-"""
-Base Service class, which acts as a descriptor for an OpenStack service
-in the test environment
-"""
-
-
-class Service(object):
-
-    def __init__(self, config):
-        """
-        Initializes the service.
-
-        :param config: `tempest.config.Config` object
-        """
-        self.config = config
-
-    def get_client(self):
-        """
-        Returns a client object that may be used to query
-        the service API.
-        """
-        raise NotImplementedError
diff --git a/tempest/services/baremetal/base.py b/tempest/services/baremetal/base.py
index f98ecff..0b97f74 100644
--- a/tempest/services/baremetal/base.py
+++ b/tempest/services/baremetal/base.py
@@ -119,6 +119,7 @@
             uri += "?%s" % urllib.urlencode(kwargs)
 
         resp, body = self.get(uri)
+        self.expected_success(200, resp['status'])
 
         return resp, self.deserialize(body)
 
@@ -135,6 +136,7 @@
         else:
             uri = self._get_uri(resource, uuid=uuid, permanent=permanent)
         resp, body = self.get(uri)
+        self.expected_success(200, resp['status'])
 
         return resp, self.deserialize(body)
 
@@ -153,6 +155,7 @@
         uri = self._get_uri(resource)
 
         resp, body = self.post(uri, body=body)
+        self.expected_success(201, resp['status'])
 
         return resp, self.deserialize(body)
 
@@ -168,6 +171,7 @@
         uri = self._get_uri(resource, uuid)
 
         resp, body = self.delete(uri)
+        self.expected_success(204, resp['status'])
         return resp, body
 
     def _patch_request(self, resource, uuid, patch_object):
@@ -184,6 +188,7 @@
         patch_body = json.dumps(patch_object)
 
         resp, body = self.patch(uri, body=patch_body)
+        self.expected_success(200, resp['status'])
         return resp, self.deserialize(body)
 
     @handle_errors
@@ -212,4 +217,5 @@
         put_body = json.dumps(put_object)
 
         resp, body = self.put(uri, body=put_body)
+        self.expected_success(202, resp['status'])
         return resp, body
diff --git a/tempest/services/baremetal/v1/base_v1.py b/tempest/services/baremetal/v1/base_v1.py
index 9c753c2..07eee8a 100644
--- a/tempest/services/baremetal/v1/base_v1.py
+++ b/tempest/services/baremetal/v1/base_v1.py
@@ -264,3 +264,47 @@
                                                    postf='validate')
 
         return self._show_request('nodes', node_uuid, uri=uri)
+
+    @base.handle_errors
+    def set_node_boot_device(self, node_uuid, boot_device, persistent=False):
+        """
+        Set the boot device of the specified node.
+
+        :param node_uuid: The unique identifier of the node.
+        :param boot_device: The boot device name.
+        :param persistent: Boolean value. True if the boot device will
+                           persist to all future boots, False if not.
+                           Default: False.
+
+        """
+        request = {'boot_device': boot_device, 'persistent': persistent}
+        resp, body = self._put_request('nodes/%s/management/boot_device' %
+                                       node_uuid, request)
+        self.expected_success(204, resp.status)
+        return body
+
+    @base.handle_errors
+    def get_node_boot_device(self, node_uuid):
+        """
+        Get the current boot device of the specified node.
+
+        :param node_uuid: The unique identifier of the node.
+
+        """
+        path = 'nodes/%s/management/boot_device' % node_uuid
+        resp, body = self._list_request(path)
+        self.expected_success(200, resp.status)
+        return body
+
+    @base.handle_errors
+    def get_node_supported_boot_devices(self, node_uuid):
+        """
+        Get the supported boot devices of the specified node.
+
+        :param node_uuid: The unique identifier of the node.
+
+        """
+        path = 'nodes/%s/management/boot_device/supported' % node_uuid
+        resp, body = self._list_request(path)
+        self.expected_success(200, resp.status)
+        return body
diff --git a/tempest/services/compute/json/agents_client.py b/tempest/services/compute/json/agents_client.py
index 4f6602f..5b76a56 100644
--- a/tempest/services/compute/json/agents_client.py
+++ b/tempest/services/compute/json/agents_client.py
@@ -15,8 +15,8 @@
 import json
 import urllib
 
-from tempest.api_schema.compute import agents as common_schema
-from tempest.api_schema.compute.v2 import agents as schema
+from tempest.api_schema.response.compute import agents as common_schema
+from tempest.api_schema.response.compute.v2 import agents as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index 71d6f63..1cb010d 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -15,8 +15,8 @@
 
 import json
 
-from tempest.api_schema.compute import aggregates as schema
-from tempest.api_schema.compute.v2 import aggregates as v2_schema
+from tempest.api_schema.response.compute import aggregates as schema
+from tempest.api_schema.response.compute.v2 import aggregates as v2_schema
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
diff --git a/tempest/services/compute/json/availability_zone_client.py b/tempest/services/compute/json/availability_zone_client.py
index 1c067e8..00f8330 100644
--- a/tempest/services/compute/json/availability_zone_client.py
+++ b/tempest/services/compute/json/availability_zone_client.py
@@ -15,7 +15,7 @@
 
 import json
 
-from tempest.api_schema.compute.v2 import availability_zone as schema
+from tempest.api_schema.response.compute.v2 import availability_zone as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/certificates_client.py b/tempest/services/compute/json/certificates_client.py
index 1d04628..356ded2 100644
--- a/tempest/services/compute/json/certificates_client.py
+++ b/tempest/services/compute/json/certificates_client.py
@@ -15,8 +15,8 @@
 
 import json
 
-from tempest.api_schema.compute import certificates as schema
-from tempest.api_schema.compute.v2 import certificates as v2schema
+from tempest.api_schema.response.compute import certificates as schema
+from tempest.api_schema.response.compute.v2 import certificates as v2schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index ed2b14d..41d1c4e 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -15,7 +15,7 @@
 
 import json
 
-from tempest.api_schema.compute.v2 import extensions as schema
+from tempest.api_schema.response.compute.v2 import extensions as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/fixed_ips_client.py b/tempest/services/compute/json/fixed_ips_client.py
index f2d5cbe..5903334 100644
--- a/tempest/services/compute/json/fixed_ips_client.py
+++ b/tempest/services/compute/json/fixed_ips_client.py
@@ -15,7 +15,7 @@
 
 import json
 
-from tempest.api_schema.compute.v2 import fixed_ips as schema
+from tempest.api_schema.response.compute.v2 import fixed_ips as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 89cbe1d..5452f3a 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -16,11 +16,11 @@
 import json
 import urllib
 
-from tempest.api_schema.compute import flavors as common_schema
-from tempest.api_schema.compute import flavors_access as schema_access
-from tempest.api_schema.compute import flavors_extra_specs \
+from tempest.api_schema.response.compute import flavors as common_schema
+from tempest.api_schema.response.compute import flavors_access as schema_access
+from tempest.api_schema.response.compute import flavors_extra_specs \
     as schema_extra_specs
-from tempest.api_schema.compute.v2 import flavors as v2schema
+from tempest.api_schema.response.compute.v2 import flavors as v2schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index cd195f4..8b020d0 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -16,7 +16,7 @@
 import json
 import urllib
 
-from tempest.api_schema.compute.v2 import floating_ips as schema
+from tempest.api_schema.response.compute.v2 import floating_ips as schema
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
diff --git a/tempest/services/compute/json/hosts_client.py b/tempest/services/compute/json/hosts_client.py
index 342f946..8644173 100644
--- a/tempest/services/compute/json/hosts_client.py
+++ b/tempest/services/compute/json/hosts_client.py
@@ -15,8 +15,8 @@
 import json
 import urllib
 
-from tempest.api_schema.compute import hosts as schema
-from tempest.api_schema.compute.v2 import hosts as v2_schema
+from tempest.api_schema.response.compute import hosts as schema
+from tempest.api_schema.response.compute.v2 import hosts as v2_schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index 30228b3..8eacf61 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -15,8 +15,8 @@
 
 import json
 
-from tempest.api_schema.compute import hypervisors as common_schema
-from tempest.api_schema.compute.v2 import hypervisors as v2schema
+from tempest.api_schema.response.compute import hypervisors as common_schema
+from tempest.api_schema.response.compute.v2 import hypervisors as v2schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index af7752a..9877391 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -16,7 +16,7 @@
 import json
 import urllib
 
-from tempest.api_schema.compute.v2 import images as schema
+from tempest.api_schema.response.compute.v2 import images as schema
 from tempest.common import rest_client
 from tempest.common import waiters
 from tempest import config
diff --git a/tempest/services/compute/json/instance_usage_audit_log_client.py b/tempest/services/compute/json/instance_usage_audit_log_client.py
index 4700ca7..4b0362b 100644
--- a/tempest/services/compute/json/instance_usage_audit_log_client.py
+++ b/tempest/services/compute/json/instance_usage_audit_log_client.py
@@ -15,7 +15,7 @@
 
 import json
 
-from tempest.api_schema.compute.v2 import instance_usage_audit_logs \
+from tempest.api_schema.response.compute.v2 import instance_usage_audit_logs \
     as schema
 from tempest.common import rest_client
 from tempest import config
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index cdac8b7..83c253a 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -16,9 +16,9 @@
 import json
 import time
 
-from tempest.api_schema.compute import interfaces as common_schema
-from tempest.api_schema.compute import servers as servers_schema
-from tempest.api_schema.compute.v2 import interfaces as schema
+from tempest.api_schema.response.compute import interfaces as common_schema
+from tempest.api_schema.response.compute import servers as servers_schema
+from tempest.api_schema.response.compute.v2 import interfaces as schema
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index be93789..31c42a5 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -15,8 +15,8 @@
 
 import json
 
-from tempest.api_schema.compute import keypairs as common_schema
-from tempest.api_schema.compute.v2 import keypairs as schema
+from tempest.api_schema.response.compute import keypairs as common_schema
+from tempest.api_schema.response.compute.v2 import keypairs as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/limits_client.py b/tempest/services/compute/json/limits_client.py
index e503bef..81c602b 100644
--- a/tempest/services/compute/json/limits_client.py
+++ b/tempest/services/compute/json/limits_client.py
@@ -15,7 +15,7 @@
 
 import json
 
-from tempest.api_schema.compute.v2 import limits as schema
+from tempest.api_schema.response.compute.v2 import limits as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/migrations_client.py b/tempest/services/compute/json/migrations_client.py
index beef5d2..f4abbb2 100644
--- a/tempest/services/compute/json/migrations_client.py
+++ b/tempest/services/compute/json/migrations_client.py
@@ -15,7 +15,7 @@
 import json
 import urllib
 
-from tempest.api_schema.compute import migrations as schema
+from tempest.api_schema.response.compute import migrations as schema
 from tempest.common import rest_client
 from tempest import config
 
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/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index 14b7100..b691529 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -15,8 +15,9 @@
 
 import json
 
-from tempest.api_schema.compute.v2 import quota_classes as classes_schema
-from tempest.api_schema.compute.v2 import quotas as schema
+from tempest.api_schema.response.compute.v2\
+    import quota_classes as classes_schema
+from tempest.api_schema.response.compute.v2 import quotas as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/security_group_default_rules_client.py b/tempest/services/compute/json/security_group_default_rules_client.py
new file mode 100644
index 0000000..6d29837
--- /dev/null
+++ b/tempest/services/compute/json/security_group_default_rules_client.py
@@ -0,0 +1,74 @@
+# Copyright 2014 NEC Corporation.
+# 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 SecurityGroupDefaultRulesClientJSON(rest_client.RestClient):
+
+    def __init__(self, auth_provider):
+        super(SecurityGroupDefaultRulesClientJSON,
+              self).__init__(auth_provider)
+        self.service = CONF.compute.catalog_type
+
+    def create_security_default_group_rule(self, ip_protocol, from_port,
+                                           to_port, **kwargs):
+        """
+        Creating security group default rules.
+        ip_protocol : ip_protocol (icmp, tcp, udp).
+        from_port: Port at start of range.
+        to_port  : Port at end of range.
+        cidr     : CIDR for address range.
+        """
+        post_body = {
+            'ip_protocol': ip_protocol,
+            'from_port': from_port,
+            'to_port': to_port,
+            'cidr': kwargs.get('cidr'),
+        }
+        post_body = json.dumps({'security_group_default_rule': post_body})
+        url = 'os-security-group-default-rules'
+        resp, body = self.post(url, post_body)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return resp, body['security_group_default_rule']
+
+    def delete_security_group_default_rule(self,
+                                           security_group_default_rule_id):
+        """Deletes the provided Security Group default rule."""
+        resp, body = self.delete('os-security-group-default-rules/%s' % str(
+            security_group_default_rule_id))
+        self.expected_success(204, resp.status)
+        return resp, body
+
+    def list_security_group_default_rules(self):
+        """List all Security Group default rules."""
+        resp, body = self.get('os-security-group-default-rules')
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return resp, body['security_group_default_rules']
+
+    def get_security_group_default_rule(self, security_group_default_rule_id):
+        """Return the details of provided Security Group default rule."""
+        resp, body = self.get('os-security-group-default-rules/%s' % str(
+            security_group_default_rule_id))
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return resp, body['security_group_default_rule']
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index a86f3df..29859a9 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -16,7 +16,7 @@
 import json
 import urllib
 
-from tempest.api_schema.compute.v2 import security_groups as schema
+from tempest.api_schema.response.compute.v2 import security_groups as schema
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index fea0d28..88b68d3 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -18,8 +18,8 @@
 import time
 import urllib
 
-from tempest.api_schema.compute import servers as common_schema
-from tempest.api_schema.compute.v2 import servers as schema
+from tempest.api_schema.response.compute import servers as common_schema
+from tempest.api_schema.response.compute.v2 import servers as schema
 from tempest.common import rest_client
 from tempest.common import waiters
 from tempest import config
@@ -58,6 +58,7 @@
         disk_config: Determines if user or admin controls disk configuration.
         return_reservation_id: Enable/Disable the return of reservation id
         block_device_mapping: Block device mapping for the server.
+        block_device_mapping_v2: Block device mapping V2 for the server.
         """
         post_body = {
             'name': name,
@@ -70,7 +71,8 @@
                        'availability_zone', 'accessIPv4', 'accessIPv6',
                        'min_count', 'max_count', ('metadata', 'meta'),
                        ('OS-DCF:diskConfig', 'disk_config'),
-                       'return_reservation_id', 'block_device_mapping']:
+                       'return_reservation_id', 'block_device_mapping',
+                       'block_device_mapping_v2']:
             if isinstance(option, tuple):
                 post_param = option[0]
                 key = option[1]
@@ -80,6 +82,7 @@
             value = kwargs.get(key)
             if value is not None:
                 post_body[post_param] = value
+
         post_body = {'server': post_body}
 
         if 'sched_hints' in kwargs:
@@ -93,7 +96,11 @@
         # with return reservation id set True
         if 'reservation_id' in body:
             return resp, body
-        self.validate_response(schema.create_server, resp, body)
+        if CONF.compute_feature_enabled.enable_instance_password:
+            create_schema = schema.create_server_with_admin_pass
+        else:
+            create_schema = schema.create_server
+        self.validate_response(create_schema, resp, body)
         return resp, body['server']
 
     def update_server(self, server_id, name=None, meta=None, accessIPv4=None,
@@ -269,7 +276,12 @@
         if 'disk_config' in kwargs:
             kwargs['OS-DCF:diskConfig'] = kwargs['disk_config']
             del kwargs['disk_config']
-        return self.action(server_id, 'rebuild', 'server', None, **kwargs)
+        if CONF.compute_feature_enabled.enable_instance_password:
+            rebuild_schema = schema.rebuild_server_with_admin_pass
+        else:
+            rebuild_schema = schema.rebuild_server
+        return self.action(server_id, 'rebuild', 'server',
+                           rebuild_schema, **kwargs)
 
     def resize(self, server_id, flavor_ref, **kwargs):
         """Changes the flavor of a server."""
@@ -450,7 +462,8 @@
 
     def rescue_server(self, server_id, **kwargs):
         """Rescue the provided server."""
-        return self.action(server_id, 'rescue', 'adminPass', None, **kwargs)
+        return self.action(server_id, 'rescue', 'adminPass',
+                           schema.rescue_server, **kwargs)
 
     def unrescue_server(self, server_id):
         """Unrescue the provided server."""
@@ -474,6 +487,7 @@
         resp, body = self.get("servers/%s/os-instance-actions/%s" %
                               (str(server_id), str(request_id)))
         body = json.loads(body)
+        self.validate_response(schema.get_instance_action, resp, body)
         return resp, body['instanceAction']
 
     def force_delete_server(self, server_id, **kwargs):
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
index d58ca6f..e56263c 100644
--- a/tempest/services/compute/json/services_client.py
+++ b/tempest/services/compute/json/services_client.py
@@ -17,7 +17,7 @@
 import json
 import urllib
 
-from tempest.api_schema.compute import services as schema
+from tempest.api_schema.response.compute import services as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
index f8adae7..a0b9b4a 100644
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ b/tempest/services/compute/json/tenant_usages_client.py
@@ -16,7 +16,7 @@
 import json
 import urllib
 
-from tempest.api_schema.compute.v2 import tenant_usages as schema
+from tempest.api_schema.response.compute.v2 import tenant_usages as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index d1014af..673e365 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -17,7 +17,7 @@
 import time
 import urllib
 
-from tempest.api_schema.compute.v2 import volumes as schema
+from tempest.api_schema.response.compute.v2 import volumes as schema
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
diff --git a/tempest/services/compute/v3/json/agents_client.py b/tempest/services/compute/v3/json/agents_client.py
index 31314b7..ffca142 100644
--- a/tempest/services/compute/v3/json/agents_client.py
+++ b/tempest/services/compute/v3/json/agents_client.py
@@ -15,8 +15,8 @@
 import json
 import urllib
 
-from tempest.api_schema.compute import agents as common_schema
-from tempest.api_schema.compute.v3 import agents as schema
+from tempest.api_schema.response.compute import agents as common_schema
+from tempest.api_schema.response.compute.v3 import agents as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/v3/json/aggregates_client.py b/tempest/services/compute/v3/json/aggregates_client.py
index d9b7930..960fe05 100644
--- a/tempest/services/compute/v3/json/aggregates_client.py
+++ b/tempest/services/compute/v3/json/aggregates_client.py
@@ -15,8 +15,8 @@
 
 import json
 
-from tempest.api_schema.compute import aggregates as schema
-from tempest.api_schema.compute.v3 import aggregates as v3_schema
+from tempest.api_schema.response.compute import aggregates as schema
+from tempest.api_schema.response.compute.v3 import aggregates as v3_schema
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
diff --git a/tempest/services/compute/v3/json/availability_zone_client.py b/tempest/services/compute/v3/json/availability_zone_client.py
index bf74e68..0da78da 100644
--- a/tempest/services/compute/v3/json/availability_zone_client.py
+++ b/tempest/services/compute/v3/json/availability_zone_client.py
@@ -15,7 +15,7 @@
 
 import json
 
-from tempest.api_schema.compute.v3 import availability_zone as schema
+from tempest.api_schema.response.compute.v3 import availability_zone as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/v3/json/certificates_client.py b/tempest/services/compute/v3/json/certificates_client.py
index be9b3c3..42e9d5a 100644
--- a/tempest/services/compute/v3/json/certificates_client.py
+++ b/tempest/services/compute/v3/json/certificates_client.py
@@ -15,8 +15,8 @@
 
 import json
 
-from tempest.api_schema.compute import certificates as schema
-from tempest.api_schema.compute.v3 import certificates as v3schema
+from tempest.api_schema.response.compute import certificates as schema
+from tempest.api_schema.response.compute.v3 import certificates as v3schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/v3/json/extensions_client.py b/tempest/services/compute/v3/json/extensions_client.py
index 13292db..f172efd 100644
--- a/tempest/services/compute/v3/json/extensions_client.py
+++ b/tempest/services/compute/v3/json/extensions_client.py
@@ -15,7 +15,7 @@
 
 import json
 
-from tempest.api_schema.compute.v3 import extensions as schema
+from tempest.api_schema.response.compute.v3 import extensions as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/v3/json/flavors_client.py b/tempest/services/compute/v3/json/flavors_client.py
index 5afab5a..d1eee5b 100644
--- a/tempest/services/compute/v3/json/flavors_client.py
+++ b/tempest/services/compute/v3/json/flavors_client.py
@@ -16,11 +16,11 @@
 import json
 import urllib
 
-from tempest.api_schema.compute import flavors as common_schema
-from tempest.api_schema.compute import flavors_access as schema_access
-from tempest.api_schema.compute import flavors_extra_specs \
+from tempest.api_schema.response.compute import flavors as common_schema
+from tempest.api_schema.response.compute import flavors_access as schema_access
+from tempest.api_schema.response.compute import flavors_extra_specs \
     as schema_extra_specs
-from tempest.api_schema.compute.v3 import flavors as v3schema
+from tempest.api_schema.response.compute.v3 import flavors as v3schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/v3/json/hosts_client.py b/tempest/services/compute/v3/json/hosts_client.py
index d2eb43d..476afad 100644
--- a/tempest/services/compute/v3/json/hosts_client.py
+++ b/tempest/services/compute/v3/json/hosts_client.py
@@ -15,8 +15,8 @@
 import json
 import urllib
 
-from tempest.api_schema.compute import hosts as schema
-from tempest.api_schema.compute.v3 import hosts as v3_schema
+from tempest.api_schema.response.compute import hosts as schema
+from tempest.api_schema.response.compute.v3 import hosts as v3_schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/v3/json/hypervisor_client.py b/tempest/services/compute/v3/json/hypervisor_client.py
index 51468c9..507157a 100644
--- a/tempest/services/compute/v3/json/hypervisor_client.py
+++ b/tempest/services/compute/v3/json/hypervisor_client.py
@@ -15,8 +15,8 @@
 
 import json
 
-from tempest.api_schema.compute import hypervisors as common_schema
-from tempest.api_schema.compute.v3 import hypervisors as v3schema
+from tempest.api_schema.response.compute import hypervisors as common_schema
+from tempest.api_schema.response.compute.v3 import hypervisors as v3schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/v3/json/interfaces_client.py b/tempest/services/compute/v3/json/interfaces_client.py
index e66ccaa..e99c124 100644
--- a/tempest/services/compute/v3/json/interfaces_client.py
+++ b/tempest/services/compute/v3/json/interfaces_client.py
@@ -16,9 +16,9 @@
 import json
 import time
 
-from tempest.api_schema.compute import interfaces as common_schema
-from tempest.api_schema.compute import servers as servers_schema
-from tempest.api_schema.compute.v3 import interfaces as schema
+from tempest.api_schema.response.compute import interfaces as common_schema
+from tempest.api_schema.response.compute import servers as servers_schema
+from tempest.api_schema.response.compute.v3 import interfaces as schema
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
diff --git a/tempest/services/compute/v3/json/keypairs_client.py b/tempest/services/compute/v3/json/keypairs_client.py
index f090d7d..a290acb 100644
--- a/tempest/services/compute/v3/json/keypairs_client.py
+++ b/tempest/services/compute/v3/json/keypairs_client.py
@@ -15,8 +15,8 @@
 
 import json
 
-from tempest.api_schema.compute import keypairs as common_schema
-from tempest.api_schema.compute.v3 import keypairs as schema
+from tempest.api_schema.response.compute import keypairs as common_schema
+from tempest.api_schema.response.compute.v3 import keypairs as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/v3/json/migration_client.py b/tempest/services/compute/v3/json/migration_client.py
index c821567..bf1ae85 100644
--- a/tempest/services/compute/v3/json/migration_client.py
+++ b/tempest/services/compute/v3/json/migration_client.py
@@ -15,7 +15,7 @@
 import json
 import urllib
 
-from tempest.api_schema.compute import migrations as schema
+from tempest.api_schema.response.compute import migrations as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/v3/json/quotas_client.py b/tempest/services/compute/v3/json/quotas_client.py
index 37a8906..f9aa9e9 100644
--- a/tempest/services/compute/v3/json/quotas_client.py
+++ b/tempest/services/compute/v3/json/quotas_client.py
@@ -15,7 +15,7 @@
 
 import json
 
-from tempest.api_schema.compute.v3 import quotas as schema
+from tempest.api_schema.response.compute.v3 import quotas as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index 932cc2c..89e282d 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -19,8 +19,8 @@
 import time
 import urllib
 
-from tempest.api_schema.compute import servers as common_schema
-from tempest.api_schema.compute.v3 import servers as schema
+from tempest.api_schema.response.compute import servers as common_schema
+from tempest.api_schema.response.compute.v3 import servers as schema
 from tempest.common import rest_client
 from tempest.common import waiters
 from tempest import config
@@ -96,7 +96,11 @@
         # with return reservation id set True
         if 'servers_reservation' in body:
             return resp, body['servers_reservation']
-        self.validate_response(schema.create_server, resp, body)
+        if CONF.compute_feature_enabled.enable_instance_password:
+            create_schema = schema.create_server_with_admin_pass
+        else:
+            create_schema = schema.create_server
+        self.validate_response(create_schema, resp, body)
         return resp, body['server']
 
     def update_server(self, server_id, name=None, meta=None, access_ip_v4=None,
@@ -272,7 +276,12 @@
         if 'disk_config' in kwargs:
             kwargs['os-disk-config:disk_config'] = kwargs['disk_config']
             del kwargs['disk_config']
-        return self.action(server_id, 'rebuild', 'server', None, **kwargs)
+        if CONF.compute_feature_enabled.enable_instance_password:
+            rebuild_schema = schema.rebuild_server_with_admin_pass
+        else:
+            rebuild_schema = schema.rebuild_server
+        return self.action(server_id, 'rebuild', 'server',
+                           rebuild_schema, **kwargs)
 
     def resize(self, server_id, flavor_ref, **kwargs):
         """Changes the flavor of a server."""
@@ -445,8 +454,16 @@
 
     def rescue_server(self, server_id, **kwargs):
         """Rescue the provided server."""
-        return self.action(server_id, 'rescue', 'admin_password',
-                           None, **kwargs)
+        post_body = json.dumps({'rescue': kwargs})
+        resp, body = self.post('servers/%s/action' % str(server_id),
+                               post_body)
+        if CONF.compute_feature_enabled.enable_instance_password:
+            rescue_schema = schema.rescue_server_with_admin_pass
+        else:
+            rescue_schema = schema.rescue_server
+        body = json.loads(body)
+        self.validate_response(rescue_schema, resp, body)
+        return resp, body
 
     def unrescue_server(self, server_id):
         """Unrescue the provided server."""
@@ -471,6 +488,7 @@
         resp, body = self.get("servers/%s/os-server-actions/%s" %
                               (str(server_id), str(request_id)))
         body = json.loads(body)
+        self.validate_response(schema.get_server_action, resp, body)
         return resp, body['server_action']
 
     def force_delete_server(self, server_id, **kwargs):
diff --git a/tempest/services/compute/v3/json/services_client.py b/tempest/services/compute/v3/json/services_client.py
index 96ff580..0645287 100644
--- a/tempest/services/compute/v3/json/services_client.py
+++ b/tempest/services/compute/v3/json/services_client.py
@@ -17,7 +17,7 @@
 import json
 import urllib
 
-from tempest.api_schema.compute import services as schema
+from tempest.api_schema.response.compute import services as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/v3/json/version_client.py b/tempest/services/compute/v3/json/version_client.py
index 568678d..bc4f58c 100644
--- a/tempest/services/compute/v3/json/version_client.py
+++ b/tempest/services/compute/v3/json/version_client.py
@@ -15,7 +15,7 @@
 
 import json
 
-from tempest.api_schema.compute import version as schema
+from tempest.api_schema.response.compute import version as schema
 from tempest.common import rest_client
 from tempest import config
 
diff --git a/tempest/services/compute/xml/floating_ips_client.py b/tempest/services/compute/xml/floating_ips_client.py
index fa4aa07..730e870 100644
--- a/tempest/services/compute/xml/floating_ips_client.py
+++ b/tempest/services/compute/xml/floating_ips_client.py
@@ -13,9 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from lxml import etree
 import urllib
 
+from lxml import etree
+
 from tempest.common import rest_client
 from tempest.common import xml_utils
 from tempest import config
diff --git a/tempest/services/compute/xml/hosts_client.py b/tempest/services/compute/xml/hosts_client.py
index 23a7dd6..ddb92b6 100644
--- a/tempest/services/compute/xml/hosts_client.py
+++ b/tempest/services/compute/xml/hosts_client.py
@@ -15,6 +15,7 @@
 import urllib
 
 from lxml import etree
+
 from tempest.common import rest_client
 from tempest.common import xml_utils
 from tempest import config
diff --git a/tempest/services/compute/xml/security_groups_client.py b/tempest/services/compute/xml/security_groups_client.py
index 9eccb90..56ac7ba 100644
--- a/tempest/services/compute/xml/security_groups_client.py
+++ b/tempest/services/compute/xml/security_groups_client.py
@@ -13,9 +13,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from lxml import etree
 import urllib
 
+from lxml import etree
+
 from tempest.common import rest_client
 from tempest.common import xml_utils
 from tempest import config
diff --git a/tempest/services/data_processing/v1_1/client.py b/tempest/services/data_processing/v1_1/client.py
index c2c7fd1..7acbae7 100644
--- a/tempest/services/data_processing/v1_1/client.py
+++ b/tempest/services/data_processing/v1_1/client.py
@@ -25,29 +25,42 @@
         super(DataProcessingClient, self).__init__(auth_provider)
         self.service = CONF.data_processing.catalog_type
 
-    @classmethod
-    def _request_and_parse(cls, req_fun, uri, res_name, *args, **kwargs):
-        """Make a request using specified req_fun and parse response.
+    def _request_and_check_resp(self, request_func, uri, resp_status):
+        """Make a request using specified request_func and check response
+        status code.
+
+        It returns pair: resp and response body.
+        """
+        resp, body = request_func(uri)
+        self.expected_success(resp_status, resp.status)
+        return resp, body
+
+    def _request_check_and_parse_resp(self, request_func, uri, resp_status,
+                                      resource_name, *args, **kwargs):
+        """Make a request using specified request_func, check response status
+        code and parse response body.
 
         It returns pair: resp and parsed resource(s) body.
         """
-        resp, body = req_fun(uri, headers={
-            'Content-Type': 'application/json'
-        }, *args, **kwargs)
+        headers = {'Content-Type': 'application/json'}
+        resp, body = request_func(uri, headers=headers, *args, **kwargs)
+        self.expected_success(resp_status, resp.status)
         body = json.loads(body)
-        return resp, body[res_name]
+        return resp, body[resource_name]
 
     def list_node_group_templates(self):
         """List all node group templates for a user."""
 
         uri = 'node-group-templates'
-        return self._request_and_parse(self.get, uri, 'node_group_templates')
+        return self._request_check_and_parse_resp(self.get, uri,
+                                                  200, 'node_group_templates')
 
     def get_node_group_template(self, tmpl_id):
         """Returns the details of a single node group template."""
 
         uri = 'node-group-templates/%s' % tmpl_id
-        return self._request_and_parse(self.get, uri, 'node_group_template')
+        return self._request_check_and_parse_resp(self.get, uri,
+                                                  200, 'node_group_template')
 
     def create_node_group_template(self, name, plugin_name, hadoop_version,
                                    node_processes, flavor_id,
@@ -67,20 +80,22 @@
             'flavor_id': flavor_id,
             'node_configs': node_configs or dict(),
         })
-        return self._request_and_parse(self.post, uri, 'node_group_template',
-                                       body=json.dumps(body))
+        return self._request_check_and_parse_resp(self.post, uri, 202,
+                                                  'node_group_template',
+                                                  body=json.dumps(body))
 
     def delete_node_group_template(self, tmpl_id):
         """Deletes the specified node group template by id."""
 
         uri = 'node-group-templates/%s' % tmpl_id
-        return self.delete(uri)
+        return self._request_and_check_resp(self.delete, uri, 204)
 
     def list_plugins(self):
         """List all enabled plugins."""
 
         uri = 'plugins'
-        return self._request_and_parse(self.get, uri, 'plugins')
+        return self._request_check_and_parse_resp(self.get,
+                                                  uri, 200, 'plugins')
 
     def get_plugin(self, plugin_name, plugin_version=None):
         """Returns the details of a single plugin."""
@@ -88,19 +103,21 @@
         uri = 'plugins/%s' % plugin_name
         if plugin_version:
             uri += '/%s' % plugin_version
-        return self._request_and_parse(self.get, uri, 'plugin')
+        return self._request_check_and_parse_resp(self.get, uri, 200, 'plugin')
 
     def list_cluster_templates(self):
         """List all cluster templates for a user."""
 
         uri = 'cluster-templates'
-        return self._request_and_parse(self.get, uri, 'cluster_templates')
+        return self._request_check_and_parse_resp(self.get, uri,
+                                                  200, 'cluster_templates')
 
     def get_cluster_template(self, tmpl_id):
         """Returns the details of a single cluster template."""
 
         uri = 'cluster-templates/%s' % tmpl_id
-        return self._request_and_parse(self.get, uri, 'cluster_template')
+        return self._request_check_and_parse_resp(self.get,
+                                                  uri, 200, 'cluster_template')
 
     def create_cluster_template(self, name, plugin_name, hadoop_version,
                                 node_groups, cluster_configs=None,
@@ -119,26 +136,29 @@
             'node_groups': node_groups,
             'cluster_configs': cluster_configs or dict(),
         })
-        return self._request_and_parse(self.post, uri, 'cluster_template',
-                                       body=json.dumps(body))
+        return self._request_check_and_parse_resp(self.post, uri, 202,
+                                                  'cluster_template',
+                                                  body=json.dumps(body))
 
     def delete_cluster_template(self, tmpl_id):
         """Deletes the specified cluster template by id."""
 
         uri = 'cluster-templates/%s' % tmpl_id
-        return self.delete(uri)
+        return self._request_and_check_resp(self.delete, uri, 204)
 
     def list_data_sources(self):
         """List all data sources for a user."""
 
         uri = 'data-sources'
-        return self._request_and_parse(self.get, uri, 'data_sources')
+        return self._request_check_and_parse_resp(self.get,
+                                                  uri, 200, 'data_sources')
 
     def get_data_source(self, source_id):
         """Returns the details of a single data source."""
 
         uri = 'data-sources/%s' % source_id
-        return self._request_and_parse(self.get, uri, 'data_source')
+        return self._request_check_and_parse_resp(self.get,
+                                                  uri, 200, 'data_source')
 
     def create_data_source(self, name, data_source_type, url, **kwargs):
         """Creates data source with specified params.
@@ -153,57 +173,62 @@
             'type': data_source_type,
             'url': url
         })
-        return self._request_and_parse(self.post, uri, 'data_source',
-                                       body=json.dumps(body))
+        return self._request_check_and_parse_resp(self.post, uri,
+                                                  202, 'data_source',
+                                                  body=json.dumps(body))
 
     def delete_data_source(self, source_id):
         """Deletes the specified data source by id."""
 
         uri = 'data-sources/%s' % source_id
-        return self.delete(uri)
+        return self._request_and_check_resp(self.delete, uri, 204)
 
     def list_job_binary_internals(self):
         """List all job binary internals for a user."""
 
         uri = 'job-binary-internals'
-        return self._request_and_parse(self.get, uri, 'binaries')
+        return self._request_check_and_parse_resp(self.get,
+                                                  uri, 200, 'binaries')
 
     def get_job_binary_internal(self, job_binary_id):
         """Returns the details of a single job binary internal."""
 
         uri = 'job-binary-internals/%s' % job_binary_id
-        return self._request_and_parse(self.get, uri, 'job_binary_internal')
+        return self._request_check_and_parse_resp(self.get, uri,
+                                                  200, 'job_binary_internal')
 
     def create_job_binary_internal(self, name, data):
         """Creates job binary internal with specified params."""
 
         uri = 'job-binary-internals/%s' % name
-        return self._request_and_parse(self.put, uri, 'job_binary_internal',
-                                       data)
+        return self._request_check_and_parse_resp(self.put, uri, 202,
+                                                  'job_binary_internal', data)
 
     def delete_job_binary_internal(self, job_binary_id):
         """Deletes the specified job binary internal by id."""
 
         uri = 'job-binary-internals/%s' % job_binary_id
-        return self.delete(uri)
+        return self._request_and_check_resp(self.delete, uri, 204)
 
     def get_job_binary_internal_data(self, job_binary_id):
         """Returns data of a single job binary internal."""
 
         uri = 'job-binary-internals/%s/data' % job_binary_id
-        return self.get(uri)
+        return self._request_and_check_resp(self.get, uri, 200)
 
     def list_job_binaries(self):
         """List all job binaries for a user."""
 
         uri = 'job-binaries'
-        return self._request_and_parse(self.get, uri, 'binaries')
+        return self._request_check_and_parse_resp(self.get,
+                                                  uri, 200, 'binaries')
 
     def get_job_binary(self, job_binary_id):
         """Returns the details of a single job binary."""
 
         uri = 'job-binaries/%s' % job_binary_id
-        return self._request_and_parse(self.get, uri, 'job_binary')
+        return self._request_check_and_parse_resp(self.get,
+                                                  uri, 200, 'job_binary')
 
     def create_job_binary(self, name, url, extra=None, **kwargs):
         """Creates job binary with specified params.
@@ -218,17 +243,53 @@
             'url': url,
             'extra': extra or dict(),
         })
-        return self._request_and_parse(self.post, uri, 'job_binary',
-                                       body=json.dumps(body))
+        return self._request_check_and_parse_resp(self.post, uri,
+                                                  202, 'job_binary',
+                                                  body=json.dumps(body))
 
     def delete_job_binary(self, job_binary_id):
         """Deletes the specified job binary by id."""
 
         uri = 'job-binaries/%s' % job_binary_id
-        return self.delete(uri)
+        return self._request_and_check_resp(self.delete, uri, 204)
 
     def get_job_binary_data(self, job_binary_id):
         """Returns data of a single job binary."""
 
         uri = 'job-binaries/%s/data' % job_binary_id
-        return self.get(uri)
+        return self._request_and_check_resp(self.get, uri, 200)
+
+    def list_jobs(self):
+        """List all jobs for a user."""
+
+        uri = 'jobs'
+        return self._request_check_and_parse_resp(self.get, uri, 200, 'jobs')
+
+    def get_job(self, job_id):
+        """Returns the details of a single job."""
+
+        uri = 'jobs/%s' % job_id
+        return self._request_check_and_parse_resp(self.get, uri, 200, 'job')
+
+    def create_job(self, name, job_type, mains, libs=None, **kwargs):
+        """Creates job with specified params.
+
+        It supports passing additional params using kwargs and returns created
+        object.
+        """
+        uri = 'jobs'
+        body = kwargs.copy()
+        body.update({
+            'name': name,
+            'type': job_type,
+            'mains': mains,
+            'libs': libs or list(),
+        })
+        return self._request_check_and_parse_resp(self.post, uri, 202,
+                                                  'job', body=json.dumps(body))
+
+    def delete_job(self, job_id):
+        """Deletes the specified job by id."""
+
+        uri = 'jobs/%s' % job_id
+        return self._request_and_check_resp(self.delete, uri, 204)
diff --git a/tempest/services/database/json/flavors_client.py b/tempest/services/database/json/flavors_client.py
index 2ec0405..f276a45 100644
--- a/tempest/services/database/json/flavors_client.py
+++ b/tempest/services/database/json/flavors_client.py
@@ -33,8 +33,10 @@
             url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def get_db_flavor_details(self, db_flavor_id):
         resp, body = self.get("flavors/%s" % str(db_flavor_id))
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
diff --git a/tempest/services/database/json/versions_client.py b/tempest/services/database/json/versions_client.py
index 0269c43..81c0e6c 100644
--- a/tempest/services/database/json/versions_client.py
+++ b/tempest/services/database/json/versions_client.py
@@ -35,4 +35,5 @@
             url += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index 8c72dfa..0522f37 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 import json
+import urllib
 
 from tempest.common import rest_client
 from tempest import config
@@ -76,6 +77,17 @@
         body = json.loads(body)
         return resp, body['user']
 
+    def update_user_password(self, user_id, password, original_password):
+        """Updates a user password."""
+        update_user = {
+            'password': password,
+            'original_password': original_password
+        }
+        update_user = json.dumps({'user': update_user})
+        resp, _ = self.post('users/%s/password' % user_id, update_user)
+        self.expected_success(204, resp.status)
+        return resp
+
     def list_user_projects(self, user_id):
         """Lists the projects on which a user has roles assigned."""
         resp, body = self.get('users/%s/projects' % user_id)
@@ -83,9 +95,12 @@
         body = json.loads(body)
         return resp, body['projects']
 
-    def get_users(self):
+    def get_users(self, params=None):
         """Get the list of users."""
-        resp, body = self.get("users")
+        url = 'users'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['users']
@@ -120,8 +135,11 @@
         body = json.loads(body)
         return resp, body['project']
 
-    def list_projects(self):
-        resp, body = self.get("projects")
+    def list_projects(self, params=None):
+        url = "projects"
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['projects']
@@ -498,10 +516,7 @@
         """HEAD Check if role is delegated by a trust."""
         resp, body = self.head("OS-TRUST/trusts/%s/roles/%s"
                                % (trust_id, role_id))
-        # This code needs to change to 200 when the keystone changes
-        # for bug 1334368 merge and check_trust_roles test is
-        # unskipped
-        self.expected_success(204, resp.status)
+        self.expected_success(200, resp.status)
         return resp, body
 
 
@@ -510,7 +525,7 @@
     def __init__(self):
         super(V3TokenClientJSON, self).__init__(None)
         auth_url = CONF.identity.uri_v3
-        if not auth_url and CONF.identity_feature_enabled.api_v3:
+        if not auth_url:
             raise exceptions.InvalidConfiguration('you must specify a v3 uri '
                                                   'if using the v3 identity '
                                                   'api')
diff --git a/tempest/services/identity/v3/xml/identity_client.py b/tempest/services/identity/v3/xml/identity_client.py
index 242b032..5b761b3 100644
--- a/tempest/services/identity/v3/xml/identity_client.py
+++ b/tempest/services/identity/v3/xml/identity_client.py
@@ -14,6 +14,7 @@
 #    under the License.
 
 import json
+import urllib
 
 from lxml import etree
 
@@ -76,6 +77,14 @@
                 array.append(common.xml_to_json(child))
         return array
 
+    def _parse_users(self, node):
+        array = []
+        for child in node.getchildren():
+            tag_list = child.tag.split('}', 1)
+            if tag_list[1] == "user":
+                array.append(common.xml_to_json(child))
+        return array
+
     def _parse_array(self, node):
         array = []
         for child in node.getchildren():
@@ -130,6 +139,17 @@
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
+    def update_user_password(self, user_id, password, original_password):
+        """Updates a user password."""
+        update_user = common.Element("user",
+                                     xmlns=XMLNS,
+                                     password=password,
+                                     original_password=original_password)
+        resp, _ = self.post('users/%s/password' % user_id,
+                            str(common.Document(update_user)))
+        self.expected_success(204, resp.status)
+        return resp
+
     def list_user_projects(self, user_id):
         """Lists the projects on which a user has roles assigned."""
         resp, body = self.get('users/%s/projects' % user_id)
@@ -137,11 +157,14 @@
         body = self._parse_projects(etree.fromstring(body))
         return resp, body
 
-    def get_users(self):
+    def get_users(self, params=None):
         """Get the list of users."""
-        resp, body = self.get("users")
+        url = 'users'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
         self.expected_success(200, resp.status)
-        body = self._parse_array(etree.fromstring(body))
+        body = self._parse_users(etree.fromstring(body))
         return resp, body
 
     def get_user(self, user_id):
@@ -174,9 +197,12 @@
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
-    def list_projects(self):
+    def list_projects(self, params=None):
         """Get the list of projects."""
-        resp, body = self.get("projects")
+        url = 'projects'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+        resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = self._parse_projects(etree.fromstring(body))
         return resp, body
@@ -494,7 +520,7 @@
     def __init__(self):
         super(V3TokenClientXML, self).__init__(None)
         auth_url = CONF.identity.uri_v3
-        if not auth_url and CONF.identity_feature_enabled.api_v3:
+        if not auth_url:
             raise exceptions.InvalidConfiguration('you must specify a v3 uri '
                                                   'if using the v3 identity '
                                                   'api')
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/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 8e53b8d..16a4f5c 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -54,12 +54,14 @@
         body = json.dumps(put_body)
         uri = '%s/quotas/%s' % (self.uri_prefix, tenant_id)
         resp, body = self.put(uri, body)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['quota']
 
     def reset_quotas(self, tenant_id):
         uri = '%s/quotas/%s' % (self.uri_prefix, tenant_id)
         resp, body = self.delete(uri)
+        self.rest_client.expected_success(204, resp.status)
         return resp, body
 
     def create_router(self, name, admin_state_up=True, **kwargs):
@@ -69,12 +71,14 @@
         body = json.dumps(post_body)
         uri = '%s/routers' % (self.uri_prefix)
         resp, body = self.post(uri, body)
+        self.rest_client.expected_success(201, resp.status)
         body = json.loads(body)
         return resp, body
 
     def _update_router(self, router_id, set_enable_snat, **kwargs):
         uri = '%s/routers/%s' % (self.uri_prefix, router_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         update_body = {}
         update_body['name'] = kwargs.get('name', body['router']['name'])
@@ -88,6 +92,7 @@
         update_body = dict(router=update_body)
         update_body = json.dumps(update_body)
         resp, body = self.put(uri, update_body)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -110,37 +115,41 @@
 
     def add_router_interface_with_subnet_id(self, router_id, subnet_id):
         uri = '%s/routers/%s/add_router_interface' % (self.uri_prefix,
-              router_id)
+                                                      router_id)
         update_body = {"subnet_id": subnet_id}
         update_body = json.dumps(update_body)
         resp, body = self.put(uri, update_body)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
     def add_router_interface_with_port_id(self, router_id, port_id):
         uri = '%s/routers/%s/add_router_interface' % (self.uri_prefix,
-              router_id)
+                                                      router_id)
         update_body = {"port_id": port_id}
         update_body = json.dumps(update_body)
         resp, body = self.put(uri, update_body)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
     def remove_router_interface_with_subnet_id(self, router_id, subnet_id):
         uri = '%s/routers/%s/remove_router_interface' % (self.uri_prefix,
-              router_id)
+                                                         router_id)
         update_body = {"subnet_id": subnet_id}
         update_body = json.dumps(update_body)
         resp, body = self.put(uri, update_body)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
     def remove_router_interface_with_port_id(self, router_id, port_id):
         uri = '%s/routers/%s/remove_router_interface' % (self.uri_prefix,
-              router_id)
+                                                         router_id)
         update_body = {"port_id": port_id}
         update_body = json.dumps(update_body)
         resp, body = self.put(uri, update_body)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -155,6 +164,7 @@
         uri = '%s/lb/pools/%s/health_monitors' % (self.uri_prefix,
                                                   pool_id)
         resp, body = self.post(uri, body)
+        self.rest_client.expected_success(201, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -163,11 +173,13 @@
         uri = '%s/lb/pools/%s/health_monitors/%s' % (self.uri_prefix, pool_id,
                                                      health_monitor_id)
         resp, body = self.delete(uri)
+        self.rest_client.expected_success(204, resp.status)
         return resp, body
 
     def list_router_interfaces(self, uuid):
         uri = '%s/ports?device_id=%s' % (self.uri_prefix, uuid)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -180,12 +192,14 @@
         agent = {"agent": agent_info}
         body = json.dumps(agent)
         resp, body = self.put(uri, body)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
     def list_pools_hosted_by_one_lbaas_agent(self, agent_id):
         uri = '%s/agents/%s/loadbalancer-pools' % (self.uri_prefix, agent_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -193,18 +207,21 @@
         uri = ('%s/lb/pools/%s/loadbalancer-agent' %
                (self.uri_prefix, pool_id))
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
     def list_routers_on_l3_agent(self, agent_id):
         uri = '%s/agents/%s/l3-routers' % (self.uri_prefix, agent_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
     def list_l3_agents_hosting_router(self, router_id):
         uri = '%s/routers/%s/l3-agents' % (self.uri_prefix, router_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -213,6 +230,7 @@
         post_body = {"router_id": router_id}
         body = json.dumps(post_body)
         resp, body = self.post(uri, body)
+        self.rest_client.expected_success(201, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -220,17 +238,20 @@
         uri = '%s/agents/%s/l3-routers/%s' % (
             self.uri_prefix, agent_id, router_id)
         resp, body = self.delete(uri)
+        self.rest_client.expected_success(204, resp.status)
         return resp, body
 
     def list_dhcp_agent_hosting_network(self, network_id):
         uri = '%s/networks/%s/dhcp-agents' % (self.uri_prefix, network_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
     def list_networks_hosted_by_one_dhcp_agent(self, agent_id):
         uri = '%s/agents/%s/dhcp-networks' % (self.uri_prefix, agent_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -238,6 +259,7 @@
         uri = '%s/agents/%s/dhcp-networks/%s' % (self.uri_prefix, agent_id,
                                                  network_id)
         resp, body = self.delete(uri)
+        self.rest_client.expected_success(204, resp.status)
         return resp, body
 
     def create_ikepolicy(self, name, **kwargs):
@@ -251,6 +273,7 @@
         body = json.dumps(post_body)
         uri = '%s/vpn/ikepolicies' % (self.uri_prefix)
         resp, body = self.post(uri, body)
+        self.rest_client.expected_success(201, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -264,6 +287,7 @@
         }
         body = json.dumps(put_body)
         resp, body = self.put(uri, body)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -277,12 +301,14 @@
         }
         body = json.dumps(put_body)
         resp, body = self.put(uri, body)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
     def list_lb_pool_stats(self, pool_id):
         uri = '%s/lb/pools/%s/stats' % (self.uri_prefix, pool_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -291,5 +317,6 @@
         body = json.dumps(post_body)
         uri = '%s/agents/%s/dhcp-networks' % (self.uri_prefix, agent_id)
         resp, body = self.post(uri, body)
+        self.rest_client.expected_success(201, resp.status)
         body = json.loads(body)
         return resp, body
diff --git a/tempest/services/network/network_client_base.py b/tempest/services/network/network_client_base.py
index 4ee8302..94ba5aa 100644
--- a/tempest/services/network/network_client_base.py
+++ b/tempest/services/network/network_client_base.py
@@ -111,6 +111,7 @@
                 uri += '?' + urllib.urlencode(filters, doseq=1)
             resp, body = self.get(uri)
             result = {plural_name: self.deserialize_list(body)}
+            self.rest_client.expected_success(200, resp.status)
             return resp, result
 
         return _list
@@ -119,7 +120,9 @@
         def _delete(resource_id):
             plural = self.pluralize(resource_name)
             uri = '%s/%s' % (self.get_uri(plural), resource_id)
-            return self.delete(uri)
+            resp, body = self.delete(uri)
+            self.rest_client.expected_success(204, resp.status)
+            return resp, body
 
         return _delete
 
@@ -134,6 +137,7 @@
                 uri += '?' + urllib.urlencode(fields, doseq=1)
             resp, body = self.get(uri)
             body = self.deserialize_single(body)
+            self.rest_client.expected_success(200, resp.status)
             return resp, body
 
         return _show
@@ -145,6 +149,7 @@
             post_data = self.serialize({resource_name: kwargs})
             resp, body = self.post(uri, post_data)
             body = self.deserialize_single(body)
+            self.rest_client.expected_success(201, resp.status)
             return resp, body
 
         return _create
@@ -156,6 +161,7 @@
             post_data = self.serialize({resource_name: kwargs})
             resp, body = self.put(uri, post_data)
             body = self.deserialize_single(body)
+            self.rest_client.expected_success(200, resp.status)
             return resp, body
 
         return _update
@@ -174,15 +180,14 @@
         raise AttributeError(name)
 
     # Common methods that are hard to automate
-    def create_bulk_network(self, count, names):
-        network_list = list()
-        for i in range(count):
-            network_list.append({'name': names[i]})
+    def create_bulk_network(self, names):
+        network_list = [{'name': name} for name in names]
         post_data = {'networks': network_list}
         body = self.serialize_list(post_data, "networks", "network")
         uri = self.get_uri("networks")
         resp, body = self.post(uri, body)
         body = {'networks': self.deserialize_list(body)}
+        self.rest_client.expected_success(201, resp.status)
         return resp, body
 
     def create_bulk_subnet(self, subnet_list):
@@ -191,6 +196,7 @@
         uri = self.get_uri('subnets')
         resp, body = self.post(uri, body)
         body = {'subnets': self.deserialize_list(body)}
+        self.rest_client.expected_success(201, resp.status)
         return resp, body
 
     def create_bulk_port(self, port_list):
@@ -199,6 +205,7 @@
         uri = self.get_uri('ports')
         resp, body = self.post(uri, body)
         body = {'ports': self.deserialize_list(body)}
+        self.rest_client.expected_success(201, resp.status)
         return resp, body
 
     def wait_for_resource_deletion(self, resource_type, id):
diff --git a/tempest/services/network/xml/network_client.py b/tempest/services/network/xml/network_client.py
index 22cc948..17b1f8e 100644
--- a/tempest/services/network/xml/network_client.py
+++ b/tempest/services/network/xml/network_client.py
@@ -10,9 +10,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from lxml import etree
 import xml.etree.ElementTree as ET
 
+from lxml import etree
+
 from tempest.common import rest_client
 from tempest.common import xml_utils as common
 from tempest.services.network import network_client_base as client_base
@@ -102,17 +103,21 @@
         post_body.append(p1)
         resp, body = self.post(uri, str(common.Document(post_body)))
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        self.rest_client.expected_success(201, resp.status)
         return resp, body
 
     def disassociate_health_monitor_with_pool(self, health_monitor_id,
                                               pool_id):
         uri = '%s/lb/pools/%s/health_monitors/%s' % (self.uri_prefix, pool_id,
                                                      health_monitor_id)
-        return self.delete(uri)
+        resp, body = self.delete(uri)
+        self.rest_client.expected_success(204, resp.status)
+        return resp, body
 
     def show_extension_details(self, ext_alias):
         uri = '%s/extensions/%s' % (self.uri_prefix, str(ext_alias))
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -122,6 +127,7 @@
         router.append(common.Element("name", name))
         common.deep_dict_to_xml(router, kwargs)
         resp, body = self.post(uri, str(common.Document(router)))
+        self.rest_client.expected_success(201, resp.status)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -131,44 +137,50 @@
         for element, content in kwargs.iteritems():
             router.append(common.Element(element, content))
         resp, body = self.put(uri, str(common.Document(router)))
+        self.rest_client.expected_success(200, resp.status)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
     def add_router_interface_with_subnet_id(self, router_id, subnet_id):
         uri = '%s/routers/%s/add_router_interface' % (self.uri_prefix,
-              router_id)
+                                                      router_id)
         subnet = common.Element("subnet_id", subnet_id)
         resp, body = self.put(uri, str(common.Document(subnet)))
+        self.rest_client.expected_success(200, resp.status)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
     def add_router_interface_with_port_id(self, router_id, port_id):
         uri = '%s/routers/%s/add_router_interface' % (self.uri_prefix,
-              router_id)
+                                                      router_id)
         port = common.Element("port_id", port_id)
         resp, body = self.put(uri, str(common.Document(port)))
+        self.rest_client.expected_success(200, resp.status)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
     def remove_router_interface_with_subnet_id(self, router_id, subnet_id):
         uri = '%s/routers/%s/remove_router_interface' % (self.uri_prefix,
-              router_id)
+                                                         router_id)
         subnet = common.Element("subnet_id", subnet_id)
         resp, body = self.put(uri, str(common.Document(subnet)))
+        self.rest_client.expected_success(200, resp.status)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
     def remove_router_interface_with_port_id(self, router_id, port_id):
         uri = '%s/routers/%s/remove_router_interface' % (self.uri_prefix,
-              router_id)
+                                                         router_id)
         port = common.Element("port_id", port_id)
         resp, body = self.put(uri, str(common.Document(port)))
+        self.rest_client.expected_success(200, resp.status)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
     def list_router_interfaces(self, uuid):
         uri = '%s/ports?device_id=%s' % (self.uri_prefix, uuid)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         ports = common.parse_array(etree.fromstring(body), self.PLURALS)
         ports = {"ports": ports}
         return resp, ports
@@ -180,12 +192,14 @@
             p = common.Element(key, value)
             agent.append(p)
         resp, body = self.put(uri, str(common.Document(agent)))
+        self.rest_client.expected_success(200, resp.status)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
     def list_pools_hosted_by_one_lbaas_agent(self, agent_id):
         uri = '%s/agents/%s/loadbalancer-pools' % (self.uri_prefix, agent_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         pools = common.parse_array(etree.fromstring(body))
         body = {'pools': pools}
         return resp, body
@@ -194,12 +208,14 @@
         uri = ('%s/lb/pools/%s/loadbalancer-agent' %
                (self.uri_prefix, pool_id))
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
     def list_routers_on_l3_agent(self, agent_id):
         uri = '%s/agents/%s/l3-routers' % (self.uri_prefix, agent_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         routers = common.parse_array(etree.fromstring(body))
         body = {'routers': routers}
         return resp, body
@@ -207,6 +223,7 @@
     def list_l3_agents_hosting_router(self, router_id):
         uri = '%s/routers/%s/l3-agents' % (self.uri_prefix, router_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         agents = common.parse_array(etree.fromstring(body))
         body = {'agents': agents}
         return resp, body
@@ -215,6 +232,7 @@
         uri = '%s/agents/%s/l3-routers' % (self.uri_prefix, agent_id)
         router = (common.Element("router_id", router_id))
         resp, body = self.post(uri, str(common.Document(router)))
+        self.rest_client.expected_success(201, resp.status)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -222,11 +240,13 @@
         uri = '%s/agents/%s/l3-routers/%s' % (
             self.uri_prefix, agent_id, router_id)
         resp, body = self.delete(uri)
+        self.rest_client.expected_success(204, resp.status)
         return resp, body
 
     def list_dhcp_agent_hosting_network(self, network_id):
         uri = '%s/networks/%s/dhcp-agents' % (self.uri_prefix, network_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         agents = common.parse_array(etree.fromstring(body))
         body = {'agents': agents}
         return resp, body
@@ -234,6 +254,7 @@
     def list_networks_hosted_by_one_dhcp_agent(self, agent_id):
         uri = '%s/agents/%s/dhcp-networks' % (self.uri_prefix, agent_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         networks = common.parse_array(etree.fromstring(body))
         body = {'networks': networks}
         return resp, body
@@ -242,11 +263,13 @@
         uri = '%s/agents/%s/dhcp-networks/%s' % (self.uri_prefix, agent_id,
                                                  network_id)
         resp, body = self.delete(uri)
+        self.rest_client.expected_success(204, resp.status)
         return resp, body
 
     def list_lb_pool_stats(self, pool_id):
         uri = '%s/lb/pools/%s/stats' % (self.uri_prefix, pool_id)
         resp, body = self.get(uri)
+        self.rest_client.expected_success(200, resp.status)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
@@ -254,6 +277,7 @@
         uri = '%s/agents/%s/dhcp-networks' % (self.uri_prefix, agent_id)
         network = common.Element("network_id", network_id)
         resp, body = self.post(uri, str(common.Document(network)))
+        self.rest_client.expected_success(201, resp.status)
         body = _root_tag_fetcher_and_xml_to_json_parse(body)
         return resp, body
 
diff --git a/tempest/services/object_storage/account_client.py b/tempest/services/object_storage/account_client.py
index a0506f2..be0f888 100644
--- a/tempest/services/object_storage/account_client.py
+++ b/tempest/services/object_storage/account_client.py
@@ -15,12 +15,12 @@
 
 import json
 import urllib
+from xml.etree import ElementTree as etree
 
 from tempest.common import http
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
-from xml.etree import ElementTree as etree
 
 CONF = config.CONF
 
diff --git a/tempest/services/object_storage/container_client.py b/tempest/services/object_storage/container_client.py
index 546b557..ffc1326 100644
--- a/tempest/services/object_storage/container_client.py
+++ b/tempest/services/object_storage/container_client.py
@@ -15,10 +15,10 @@
 
 import json
 import urllib
+from xml.etree import ElementTree as etree
 
 from tempest.common import rest_client
 from tempest import config
-from xml.etree import ElementTree as etree
 
 CONF = config.CONF
 
diff --git a/tempest/services/orchestration/json/orchestration_client.py b/tempest/services/orchestration/json/orchestration_client.py
index c459f28..9c76f51 100644
--- a/tempest/services/orchestration/json/orchestration_client.py
+++ b/tempest/services/orchestration/json/orchestration_client.py
@@ -41,6 +41,7 @@
             uri += '?%s' % urllib.urlencode(params)
 
         resp, body = self.get(uri)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['stacks']
 
@@ -58,6 +59,7 @@
             files)
         uri = 'stacks'
         resp, body = self.post(uri, headers=headers, body=body)
+        self.expected_success(201, resp.status)
         return resp, body
 
     def update_stack(self, stack_identifier, name, disable_rollback=True,
@@ -74,6 +76,7 @@
 
         uri = "stacks/%s" % stack_identifier
         resp, body = self.put(uri, headers=headers, body=body)
+        self.expected_success(202, resp.status)
         return resp, body
 
     def _prepare_update_create(self, name, disable_rollback=True,
@@ -106,6 +109,7 @@
         """Returns the details of a single stack."""
         url = "stacks/%s" % stack_identifier
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['stack']
 
@@ -114,6 +118,7 @@
         url = 'stacks/%s/actions' % stack_identifier
         body = {'suspend': None}
         resp, body = self.post(url, json.dumps(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def resume_stack(self, stack_identifier):
@@ -121,12 +126,14 @@
         url = 'stacks/%s/actions' % stack_identifier
         body = {'resume': None}
         resp, body = self.post(url, json.dumps(body))
+        self.expected_success(200, resp.status)
         return resp, body
 
     def list_resources(self, stack_identifier):
         """Returns the details of a single resource."""
         url = "stacks/%s/resources" % stack_identifier
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['resources']
 
@@ -134,12 +141,15 @@
         """Returns the details of a single resource."""
         url = "stacks/%s/resources/%s" % (stack_identifier, resource_name)
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['resource']
 
     def delete_stack(self, stack_identifier):
         """Deletes the specified Stack."""
-        return self.delete("stacks/%s" % str(stack_identifier))
+        resp, _ = self.delete("stacks/%s" % str(stack_identifier))
+        self.expected_success(204, resp.status)
+        return resp
 
     def wait_for_resource_status(self, stack_identifier, resource_name,
                                  status, failure_pattern='^.*_FAILED$'):
@@ -181,7 +191,11 @@
         fail_regexp = re.compile(failure_pattern)
 
         while True:
-            resp, body = self.get_stack(stack_identifier)
+            try:
+                resp, body = self.get_stack(stack_identifier)
+            except exceptions.NotFound:
+                if status == 'DELETE_COMPLETE':
+                    return
             stack_name = body['stack_name']
             stack_status = body['stack_status']
             if stack_status == status:
@@ -204,6 +218,7 @@
         url = ('stacks/{stack_identifier}/resources/{resource_name}'
                '/metadata'.format(**locals()))
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['metadata']
 
@@ -211,6 +226,7 @@
         """Returns list of all events for a stack."""
         url = 'stacks/{stack_identifier}/events'.format(**locals())
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['events']
 
@@ -219,6 +235,7 @@
         url = ('stacks/{stack_identifier}/resources/{resource_name}'
                '/events'.format(**locals()))
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['events']
 
@@ -227,6 +244,7 @@
         url = ('stacks/{stack_identifier}/resources/{resource_name}/events'
                '/{event_id}'.format(**locals()))
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['event']
 
@@ -234,6 +252,7 @@
         """Returns the template for the stack."""
         url = ('stacks/{stack_identifier}/template'.format(**locals()))
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -241,6 +260,7 @@
         """Returns the validation request result."""
         post_body = json.dumps(post_body)
         resp, body = self.post('validate', post_body)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body
 
@@ -259,3 +279,161 @@
             'parameters': parameters,
         }
         return self._validate_template(post_body)
+
+    def list_resource_types(self):
+        """List resource types."""
+        resp, body = self.get('resource_types')
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return body['resource_types']
+
+    def get_resource_type(self, resource_type_name):
+        """Return the schema of a resource type."""
+        url = 'resource_types/%s' % resource_type_name
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        return json.loads(body)
+
+    def get_resource_type_template(self, resource_type_name):
+        """Return the template of a resource type."""
+        url = 'resource_types/%s/template' % resource_type_name
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        return json.loads(body)
+
+    def create_software_config(self, name=None, config=None, group=None,
+                               inputs=None, outputs=None, options=None):
+        headers, body = self._prep_software_config_create(
+            name, config, group, inputs, outputs, options)
+
+        url = 'software_configs'
+        resp, body = self.post(url, headers=headers, body=body)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return body
+
+    def get_software_config(self, conf_id):
+        """Returns a software configuration resource."""
+        url = 'software_configs/%s' % str(conf_id)
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return body
+
+    def delete_software_config(self, conf_id):
+        """Deletes a specific software configuration."""
+        url = 'software_configs/%s' % str(conf_id)
+        resp, _ = self.delete(url)
+        self.expected_success(204, resp.status)
+
+    def create_software_deploy(self, server_id=None, config_id=None,
+                               action=None, status=None,
+                               input_values=None, output_values=None,
+                               status_reason=None, signal_transport=None):
+        """Creates or updates a software deployment."""
+        headers, body = self._prep_software_deploy_update(
+            None, server_id, config_id, action, status, input_values,
+            output_values, status_reason, signal_transport)
+
+        url = 'software_deployments'
+        resp, body = self.post(url, headers=headers, body=body)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return body
+
+    def update_software_deploy(self, deploy_id=None, server_id=None,
+                               config_id=None, action=None, status=None,
+                               input_values=None, output_values=None,
+                               status_reason=None, signal_transport=None):
+        """Creates or updates a software deployment."""
+        headers, body = self._prep_software_deploy_update(
+            deploy_id, server_id, config_id, action, status, input_values,
+            output_values, status_reason, signal_transport)
+
+        url = 'software_deployments/%s' % str(deploy_id)
+        resp, body = self.put(url, headers=headers, body=body)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return body
+
+    def get_software_deploy_list(self):
+        """Returns a list of all deployments."""
+        url = 'software_deployments'
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return body
+
+    def get_software_deploy(self, deploy_id):
+        """Returns a specific software deployment."""
+        url = 'software_deployments/%s' % str(deploy_id)
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return body
+
+    def get_software_deploy_meta(self, server_id):
+        """Return a config metadata for a specific server."""
+        url = 'software_deployments/metadata/%s' % server_id
+        resp, body = self.get(url)
+        self.expected_success(200, resp.status)
+        body = json.loads(body)
+        return body
+
+    def delete_software_deploy(self, deploy_id):
+        """Deletes a specific software deployment."""
+        url = 'software_deployments/%s' % str(deploy_id)
+        resp, _ = self.delete(url)
+        self.expected_success(204, resp.status)
+
+    def _prep_software_config_create(self, name=None, conf=None, group=None,
+                                     inputs=None, outputs=None, options=None):
+        """Prepares a software configuration body."""
+        post_body = {}
+        if name is not None:
+            post_body["name"] = name
+        if conf is not None:
+            post_body["config"] = conf
+        if group is not None:
+            post_body["group"] = group
+        if inputs is not None:
+            post_body["inputs"] = inputs
+        if outputs is not None:
+            post_body["outputs"] = outputs
+        if options is not None:
+            post_body["options"] = options
+        body = json.dumps(post_body)
+
+        headers = self.get_headers()
+        return headers, body
+
+    def _prep_software_deploy_update(self, deploy_id=None, server_id=None,
+                                     config_id=None, action=None, status=None,
+                                     input_values=None, output_values=None,
+                                     status_reason=None,
+                                     signal_transport=None):
+        """Prepares a deployment create or update (if an id was given)."""
+        post_body = {}
+
+        if deploy_id is not None:
+            post_body["id"] = deploy_id
+        if server_id is not None:
+            post_body["server_id"] = server_id
+        if config_id is not None:
+            post_body["config_id"] = config_id
+        if action is not None:
+            post_body["action"] = action
+        if status is not None:
+            post_body["status"] = status
+        if input_values is not None:
+            post_body["input_values"] = input_values
+        if output_values is not None:
+            post_body["output_values"] = output_values
+        if status_reason is not None:
+            post_body["status_reason"] = status_reason
+        if signal_transport is not None:
+            post_body["signal_transport"] = signal_transport
+        body = json.dumps(post_body)
+
+        headers = self.get_headers()
+        return headers, body
diff --git a/tempest/services/queuing/json/queuing_client.py b/tempest/services/queuing/json/queuing_client.py
index 031c9c6..14960ad 100644
--- a/tempest/services/queuing/json/queuing_client.py
+++ b/tempest/services/queuing/json/queuing_client.py
@@ -16,7 +16,7 @@
 import json
 import urllib
 
-from tempest.api_schema.queuing.v1 import queues as queues_schema
+from tempest.api_schema.response.queuing.v1 import queues as queues_schema
 from tempest.common import rest_client
 from tempest.common.utils import data_utils
 from tempest import config
diff --git a/tempest/services/telemetry/telemetry_client_base.py b/tempest/services/telemetry/telemetry_client_base.py
index b45c239..a184a77 100644
--- a/tempest/services/telemetry/telemetry_client_base.py
+++ b/tempest/services/telemetry/telemetry_client_base.py
@@ -14,9 +14,10 @@
 #    under the License.
 
 import abc
-import six
 import urllib
 
+import six
+
 from tempest import config
 
 CONF = config.CONF
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 961c7da..90790e3 100644
--- a/tempest/services/volume/json/admin/volume_quotas_client.py
+++ b/tempest/services/volume/json/admin/volume_quotas_client.py
@@ -16,10 +16,9 @@
 
 import urllib
 
-from tempest.openstack.common import jsonutils
-
 from tempest.common import rest_client
 from tempest import config
+from tempest.openstack.common import jsonutils
 
 CONF = config.CONF
 
@@ -43,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):
@@ -53,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,
@@ -76,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 6839d3a..5ad2287 100644
--- a/tempest/services/volume/json/availability_zone_client.py
+++ b/tempest/services/volume/json/availability_zone_client.py
@@ -21,14 +21,21 @@
 CONF = config.CONF
 
 
-class VolumeAvailabilityZoneClientJSON(rest_client.RestClient):
+class BaseVolumeAvailabilityZoneClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(VolumeAvailabilityZoneClientJSON, self).__init__(
+        super(BaseVolumeAvailabilityZoneClientJSON, self).__init__(
             auth_provider)
         self.service = CONF.volume.catalog_type
 
     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']
+
+
+class VolumeAvailabilityZoneClientJSON(BaseVolumeAvailabilityZoneClientJSON):
+    """
+    Volume V1 availability zone client.
+    """
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 9e182ea..c84b186 100644
--- a/tempest/services/volume/json/extensions_client.py
+++ b/tempest/services/volume/json/extensions_client.py
@@ -21,14 +21,21 @@
 CONF = config.CONF
 
 
-class ExtensionsClientJSON(rest_client.RestClient):
+class BaseExtensionsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(ExtensionsClientJSON, self).__init__(auth_provider)
+        super(BaseExtensionsClientJSON, self).__init__(auth_provider)
         self.service = CONF.volume.catalog_type
 
     def list_extensions(self):
         url = 'extensions'
         resp, body = self.get(url)
         body = json.loads(body)
+        self.expected_success(200, resp.status)
         return resp, body['extensions']
+
+
+class ExtensionsClientJSON(BaseExtensionsClientJSON):
+    """
+    Volume V1 extensions client.
+    """
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/availability_zone_client.py b/tempest/services/volume/v2/json/availability_zone_client.py
new file mode 100644
index 0000000..047ba1b
--- /dev/null
+++ b/tempest/services/volume/v2/json/availability_zone_client.py
@@ -0,0 +1,26 @@
+# Copyright 2014 IBM Corp.
+# 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.services.volume.json import availability_zone_client
+
+
+class VolumeV2AvailabilityZoneClientJSON(
+        availability_zone_client.BaseVolumeAvailabilityZoneClientJSON):
+
+    def __init__(self, auth_provider):
+        super(VolumeV2AvailabilityZoneClientJSON, self).__init__(
+            auth_provider)
+
+        self.api_version = "v2"
diff --git a/tempest/api_schema/compute/v2/agents.py b/tempest/services/volume/v2/json/extensions_client.py
similarity index 63%
copy from tempest/api_schema/compute/v2/agents.py
copy to tempest/services/volume/v2/json/extensions_client.py
index 30f999f..cc5244c 100644
--- a/tempest/api_schema/compute/v2/agents.py
+++ b/tempest/services/volume/v2/json/extensions_client.py
@@ -1,4 +1,5 @@
-# Copyright 2014 NEC Corporation.  All rights reserved.
+# Copyright 2014 IBM Corp.
+# 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
@@ -12,13 +13,12 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api_schema.compute import agents
+from tempest.services.volume.json import extensions_client
 
-create_agent = {
-    'status_code': [200],
-    'response_body': agents.common_create_agent
-}
 
-delete_agent = {
-    'status_code': [200]
-}
+class ExtensionsV2ClientJSON(extensions_client.BaseExtensionsClientJSON):
+
+    def __init__(self, auth_provider):
+        super(ExtensionsV2ClientJSON, self).__init__(auth_provider)
+
+        self.api_version = "v2"
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/availability_zone_client.py b/tempest/services/volume/v2/xml/availability_zone_client.py
new file mode 100644
index 0000000..68ca39b
--- /dev/null
+++ b/tempest/services/volume/v2/xml/availability_zone_client.py
@@ -0,0 +1,26 @@
+# Copyright 2014 IBM Corp.
+# 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.services.volume.xml import availability_zone_client
+
+
+class VolumeV2AvailabilityZoneClientXML(
+        availability_zone_client.BaseVolumeAvailabilityZoneClientXML):
+
+    def __init__(self, auth_provider):
+        super(VolumeV2AvailabilityZoneClientXML, self).__init__(
+            auth_provider)
+
+        self.api_version = "v2"
diff --git a/tempest/api_schema/compute/v2/agents.py b/tempest/services/volume/v2/xml/extensions_client.py
similarity index 63%
copy from tempest/api_schema/compute/v2/agents.py
copy to tempest/services/volume/v2/xml/extensions_client.py
index 30f999f..13f333c 100644
--- a/tempest/api_schema/compute/v2/agents.py
+++ b/tempest/services/volume/v2/xml/extensions_client.py
@@ -1,4 +1,5 @@
-# Copyright 2014 NEC Corporation.  All rights reserved.
+# Copyright 2014 IBM Corp.
+# 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
@@ -12,13 +13,12 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest.api_schema.compute import agents
+from tempest.services.volume.xml import extensions_client
 
-create_agent = {
-    'status_code': [200],
-    'response_body': agents.common_create_agent
-}
 
-delete_agent = {
-    'status_code': [200]
-}
+class ExtensionsV2ClientXML(extensions_client.BaseExtensionsClientXML):
+
+    def __init__(self, auth_provider):
+        super(ExtensionsV2ClientXML, self).__init__(auth_provider)
+
+        self.api_version = "v2"
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 a38410b..acf9102 100644
--- a/tempest/services/volume/xml/admin/volume_quotas_client.py
+++ b/tempest/services/volume/xml/admin/volume_quotas_client.py
@@ -15,6 +15,7 @@
 #    under the License.
 
 import ast
+
 from lxml import etree
 
 from tempest.common import xml_utils as xml
@@ -47,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,
@@ -67,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 e4a004a..b956d3f 100644
--- a/tempest/services/volume/xml/availability_zone_client.py
+++ b/tempest/services/volume/xml/availability_zone_client.py
@@ -22,11 +22,11 @@
 CONF = config.CONF
 
 
-class VolumeAvailabilityZoneClientXML(rest_client.RestClient):
+class BaseVolumeAvailabilityZoneClientXML(rest_client.RestClient):
     TYPE = "xml"
 
     def __init__(self, auth_provider):
-        super(VolumeAvailabilityZoneClientXML, self).__init__(
+        super(BaseVolumeAvailabilityZoneClientXML, self).__init__(
             auth_provider)
         self.service = CONF.volume.catalog_type
 
@@ -36,4 +36,11 @@
     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
+
+
+class VolumeAvailabilityZoneClientXML(BaseVolumeAvailabilityZoneClientXML):
+    """
+    Volume V1 availability zone client.
+    """
diff --git a/tempest/services/volume/xml/extensions_client.py b/tempest/services/volume/xml/extensions_client.py
index 2986fcd..f2b2e02 100644
--- a/tempest/services/volume/xml/extensions_client.py
+++ b/tempest/services/volume/xml/extensions_client.py
@@ -22,11 +22,11 @@
 CONF = config.CONF
 
 
-class ExtensionsClientXML(rest_client.RestClient):
+class BaseExtensionsClientXML(rest_client.RestClient):
     TYPE = "xml"
 
     def __init__(self, auth_provider):
-        super(ExtensionsClientXML, self).__init__(auth_provider)
+        super(BaseExtensionsClientXML, self).__init__(auth_provider)
         self.service = CONF.volume.catalog_type
 
     def _parse_array(self, node):
@@ -39,4 +39,11 @@
         url = 'extensions'
         resp, body = self.get(url)
         body = self._parse_array(etree.fromstring(body))
+        self.expected_success(200, resp.status)
         return resp, body
+
+
+class ExtensionsClientXML(BaseExtensionsClientXML):
+    """
+    Volume V1 extensions client.
+    """
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 2d4a9e9..a8c1ae5 100644
--- a/tempest/services/volume/xml/volumes_client.py
+++ b/tempest/services/volume/xml/volumes_client.py
@@ -15,9 +15,9 @@
 
 import time
 import urllib
+from xml.sax import saxutils
 
 from lxml import etree
-from xml.sax import saxutils
 
 from tempest.common import rest_client
 from tempest.common import xml_utils as common
@@ -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/stress/README.rst b/tempest/stress/README.rst
index 0a63679..4f1f56c 100644
--- a/tempest/stress/README.rst
+++ b/tempest/stress/README.rst
@@ -1,3 +1,5 @@
+.. _stress_field_guide:
+
 Tempest Field Guide to Stress Tests
 ===================================
 
diff --git a/tempest/stress/actions/volume_attach_delete.py b/tempest/stress/actions/volume_attach_delete.py
index b438f52..e0238d3 100644
--- a/tempest/stress/actions/volume_attach_delete.py
+++ b/tempest/stress/actions/volume_attach_delete.py
@@ -48,7 +48,7 @@
 
         # Step 3: attach volume to vm
         self.logger.info("attach volume (%s) to vm %s" %
-                        (volume['id'], server_id))
+                         (volume['id'], server_id))
         resp, body = self.manager.servers_client.attach_volume(server_id,
                                                                volume['id'],
                                                                '/dev/vdc')
diff --git a/tempest/stress/actions/volume_attach_verify.py b/tempest/stress/actions/volume_attach_verify.py
index a3ca0b7..0d3cb23 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -192,7 +192,7 @@
             self._create_volume()
         servers_client = self.manager.servers_client
         self.logger.info("attach volume (%s) to vm %s" %
-                        (self.volume['id'], self.server_id))
+                         (self.volume['id'], self.server_id))
         resp, body = servers_client.attach_volume(self.server_id,
                                                   self.volume['id'],
                                                   self.part_name)
diff --git a/tempest/stress/stressaction.py b/tempest/stress/stressaction.py
index f6770ab..286e022 100644
--- a/tempest/stress/stressaction.py
+++ b/tempest/stress/stressaction.py
@@ -12,12 +12,16 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import abc
 import signal
 import sys
 
+import six
+
 from tempest.openstack.common import log as logging
 
 
+@six.add_metaclass(abc.ABCMeta)
 class StressAction(object):
 
     def __init__(self, manager, max_runs=None, stop_on_error=False):
@@ -83,6 +87,7 @@
                     self.tearDown()
                     sys.exit(1)
 
+    @abc.abstractmethod
     def run(self):
         """This method is where the stress test code runs."""
-        raise NotImplemented()
+        return
diff --git a/tempest/test.py b/tempest/test.py
index afe7a96..f34933e 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -70,7 +70,7 @@
     """A decorator used to wrap the setUpClass for cleaning up resources
        when setUpClass failed.
     """
-
+    @functools.wraps(f)
     def decorator(cls):
             try:
                 f(cls)
@@ -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
     }
 
@@ -215,6 +215,8 @@
         'network': CONF.network_feature_enabled.api_extensions,
         'object': CONF.object_storage_feature_enabled.discoverable_apis,
     }
+    if len(config_dict[service]) == 0:
+        return False
     if config_dict[service][0] == 'all':
         return True
     if extension_name in config_dict[service]:
@@ -397,20 +399,6 @@
         cls.admin_client = os_admin.negative_client
 
     @staticmethod
-    def load_schema(file):
-        """
-        Loads a schema from a file on a specified location.
-
-        :param file: the file name
-        """
-        # NOTE(mkoderer): must be extended for xml support
-        fn = os.path.join(
-            os.path.abspath(os.path.dirname(os.path.dirname(__file__))),
-            "etc", "schemas", file)
-        LOG.debug("Open schema file: %s" % (fn))
-        return json.load(open(fn))
-
-    @staticmethod
     def load_tests(*args):
         """
         Wrapper for testscenarios to set the mandatory scenarios variable
@@ -423,17 +411,21 @@
             standard_tests, module, loader = args
         for test in testtools.iterate_tests(standard_tests):
             schema_file = getattr(test, '_schema_file', None)
+            schema = getattr(test, '_schema', None)
             if schema_file is not None:
                 setattr(test, 'scenarios',
                         NegativeAutoTest.generate_scenario(schema_file))
+            elif schema is not None:
+                setattr(test, 'scenarios',
+                        NegativeAutoTest.generate_scenario(schema))
         return testscenarios.load_tests_apply_scenarios(*args)
 
     @staticmethod
-    def generate_scenario(description_file):
+    def generate_scenario(description):
         """
         Generates the test scenario list for a given description.
 
-        :param description: A dictionary with the following entries:
+        :param description: A file or dictionary with the following entries:
             name (required) name for the api
             http-method (required) one of HEAD,GET,PUT,POST,PATCH,DELETE
             url (required) the url to be appended to the catalog url with '%s'
@@ -449,7 +441,6 @@
                 the data is used to generate query strings appended to the url,
                 otherwise for the body of the http call.
         """
-        description = NegativeAutoTest.load_schema(description_file)
         LOG.debug(description)
         generator = importutils.import_class(
             CONF.negative.test_generator)()
@@ -479,13 +470,14 @@
         LOG.debug(scenario_list)
         return scenario_list
 
-    def execute(self, description_file):
+    def execute(self, description):
         """
         Execute a http call on an api that are expected to
         result in client errors. First it uses invalid resources that are part
         of the url, and then invalid data for queries and http request bodies.
 
-        :param description: A dictionary with the following entries:
+        :param description: A json file or dictionary with the following
+        entries:
             name (required) name for the api
             http-method (required) one of HEAD,GET,PUT,POST,PATCH,DELETE
             url (required) the url to be appended to the catalog url with '%s'
@@ -502,7 +494,6 @@
                 otherwise for the body of the http call.
 
         """
-        description = NegativeAutoTest.load_schema(description_file)
         LOG.info("Executing %s" % description["name"])
         LOG.debug(description)
         method = description["http-method"]
@@ -592,7 +583,8 @@
     """
     @attr(type=['negative', 'gate'])
     def generic_test(self):
-        self.execute(self._schema_file)
+        if hasattr(self, '_schema'):
+            self.execute(self._schema)
 
     cn = klass.__name__
     cn = cn.replace('JSON', '')
@@ -621,7 +613,6 @@
     while now < timeout:
         if func():
             return True
-        LOG.debug("Sleeping for %d seconds", sleep_for)
         time.sleep(sleep_for)
         now = time.time()
     return False
diff --git a/tempest/tests/README.rst b/tempest/tests/README.rst
index 33d321f..e54d4c0 100644
--- a/tempest/tests/README.rst
+++ b/tempest/tests/README.rst
@@ -1,3 +1,5 @@
+.. _unit_tests_field_guide:
+
 Tempest Field Guide to Unit tests
 =================================
 
diff --git a/tempest/tests/base.py b/tempest/tests/base.py
index f4df3b9..27eb2c4 100644
--- a/tempest/tests/base.py
+++ b/tempest/tests/base.py
@@ -13,7 +13,6 @@
 #    under the License.
 
 import mock
-
 from oslotest import base
 from oslotest import moxstubout
 
diff --git a/tempest/tests/cli/test_cli.py b/tempest/tests/cli/test_cli.py
new file mode 100644
index 0000000..1fd5ccb
--- /dev/null
+++ b/tempest/tests/cli/test_cli.py
@@ -0,0 +1,59 @@
+# Copyright 2014 IBM Corp.
+#
+#    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 mock
+import testtools
+
+from tempest import cli
+from tempest import exceptions
+from tempest.tests import base
+
+
+class TestMinClientVersion(base.TestCase):
+    """Tests for the min_client_version decorator.
+    """
+
+    def _test_min_version(self, required, installed, expect_skip):
+
+        @cli.min_client_version(client='nova', version=required)
+        def fake(self, expect_skip):
+            if expect_skip:
+                # If we got here, the decorator didn't raise a skipException as
+                # expected so we need to fail.
+                self.fail('Should not have gotten past the decorator.')
+
+        with mock.patch.object(cli, 'execute',
+                               return_value=installed) as mock_cmd:
+            if expect_skip:
+                self.assertRaises(testtools.TestCase.skipException, fake,
+                                  self, expect_skip)
+            else:
+                fake(self, expect_skip)
+            mock_cmd.assert_called_once_with('nova', '', params='--version',
+                                             merge_stderr=True)
+
+    def test_min_client_version(self):
+        # required, installed, expect_skip
+        cases = (('2.17.0', '2.17.0', False),
+                 ('2.17.0', '2.18.0', False),
+                 ('2.18.0', '2.17.0', True))
+
+        for case in cases:
+            self._test_min_version(*case)
+
+    @mock.patch.object(cli, 'execute', return_value=' ')
+    def test_check_client_version_empty_output(self, mock_execute):
+        # Tests that an exception is raised if the command output is empty.
+        self.assertRaises(exceptions.TempestException,
+                          cli.check_client_version, 'nova', '2.18.0')
diff --git a/tempest/tests/cli/test_command_failed.py b/tempest/tests/cli/test_command_failed.py
new file mode 100644
index 0000000..36a4fc8
--- /dev/null
+++ b/tempest/tests/cli/test_command_failed.py
@@ -0,0 +1,30 @@
+#    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 import exceptions
+from tempest.tests import base
+
+
+class TestOutputParser(base.TestCase):
+
+    def test_command_failed_exception(self):
+        returncode = 1
+        cmd = "foo"
+        stdout = "output"
+        stderr = "error"
+        try:
+            raise exceptions.CommandFailed(returncode, cmd, stdout, stderr)
+        except exceptions.CommandFailed as e:
+            self.assertIn(str(returncode), str(e))
+            self.assertIn(cmd, str(e))
+            self.assertIn(stdout, str(e))
+            self.assertIn(stderr, str(e))
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_accounts.py
new file mode 100644
index 0000000..c24bfb6
--- /dev/null
+++ b/tempest/tests/common/test_accounts.py
@@ -0,0 +1,187 @@
+# Copyright 2014 Hewlett-Packard Development Company, L.P.
+#
+#    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 hashlib
+import os
+import tempfile
+
+import mock
+from oslo.config import cfg
+from oslotest import mockpatch
+
+from tempest import auth
+from tempest.common import accounts
+from tempest.common import http
+from tempest import config
+from tempest import exceptions
+from tempest.tests import base
+from tempest.tests import fake_config
+from tempest.tests import fake_identity
+
+
+class TestAccount(base.TestCase):
+
+    def setUp(self):
+        super(TestAccount, self).setUp()
+        self.useFixture(fake_config.ConfigFixture())
+        self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
+        self.temp_dir = tempfile.mkdtemp()
+        cfg.CONF.set_default('lock_path', self.temp_dir)
+        self.addCleanup(os.rmdir, self.temp_dir)
+        self.test_accounts = [
+            {'username': 'test_user1', 'tenant_name': 'test_tenant1',
+             'password': 'p'},
+            {'username': 'test_user2', 'tenant_name': 'test_tenant2',
+             'password': 'p'},
+            {'username': 'test_user3', 'tenant_name': 'test_tenant3',
+             'password': 'p'},
+            {'username': 'test_user4', 'tenant_name': 'test_tenant4',
+             'password': 'p'},
+            {'username': 'test_user5', 'tenant_name': 'test_tenant5',
+             'password': 'p'},
+            {'username': 'test_user6', 'tenant_name': 'test_tenant6',
+             'password': 'p'},
+        ]
+        self.useFixture(mockpatch.Patch(
+            'tempest.common.accounts.read_accounts_yaml',
+            return_value=self.test_accounts))
+        cfg.CONF.set_default('test_accounts_file', '', group='auth')
+
+    def _get_hash_list(self, accounts_list):
+        hash_list = []
+        for account in accounts_list:
+            hash = hashlib.md5()
+            hash.update(str(account))
+            hash_list.append(hash.hexdigest())
+        return hash_list
+
+    def test_get_hash(self):
+        self.stubs.Set(http.ClosingHttp, 'request',
+                       fake_identity._fake_v2_response)
+        test_account_class = accounts.Accounts('test_name')
+        hash_list = self._get_hash_list(self.test_accounts)
+        test_cred_dict = self.test_accounts[3]
+        test_creds = auth.get_credentials(**test_cred_dict)
+        results = test_account_class.get_hash(test_creds)
+        self.assertEqual(hash_list[3], results)
+
+    def test_get_hash_dict(self):
+        test_account_class = accounts.Accounts('test_name')
+        hash_dict = test_account_class.get_hash_dict(self.test_accounts)
+        hash_list = self._get_hash_list(self.test_accounts)
+        for hash in hash_list:
+            self.assertIn(hash, hash_dict.keys())
+            self.assertIn(hash_dict[hash], self.test_accounts)
+
+    def test_create_hash_file_previous_file(self):
+        # Emulate the lock existing on the filesystem
+        self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
+        with mock.patch('__builtin__.open', mock.mock_open(), create=True):
+            test_account_class = accounts.Accounts('test_name')
+            res = test_account_class._create_hash_file('12345')
+        self.assertFalse(res, "_create_hash_file should return False if the "
+                         "pseudo-lock file already exists")
+
+    def test_create_hash_file_no_previous_file(self):
+        # Emulate the lock not existing on the filesystem
+        self.useFixture(mockpatch.Patch('os.path.isfile', return_value=False))
+        with mock.patch('__builtin__.open', mock.mock_open(), create=True):
+            test_account_class = accounts.Accounts('test_name')
+            res = test_account_class._create_hash_file('12345')
+        self.assertTrue(res, "_create_hash_file should return True if the "
+                        "pseudo-lock doesn't already exist")
+
+    @mock.patch('tempest.openstack.common.lockutils.lock')
+    def test_get_free_hash_no_previous_accounts(self, lock_mock):
+        # Emulate no pre-existing lock
+        self.useFixture(mockpatch.Patch('os.path.isdir', return_value=False))
+        hash_list = self._get_hash_list(self.test_accounts)
+        mkdir_mock = self.useFixture(mockpatch.Patch('os.mkdir'))
+        self.useFixture(mockpatch.Patch('os.path.isfile', return_value=False))
+        test_account_class = accounts.Accounts('test_name')
+        with mock.patch('__builtin__.open', mock.mock_open(),
+                        create=True) as open_mock:
+            test_account_class._get_free_hash(hash_list)
+            lock_path = os.path.join(accounts.CONF.lock_path, 'test_accounts',
+                                     hash_list[0])
+            open_mock.assert_called_once_with(lock_path, 'w')
+        mkdir_path = os.path.join(accounts.CONF.lock_path, 'test_accounts')
+        mkdir_mock.mock.assert_called_once_with(mkdir_path)
+
+    @mock.patch('tempest.openstack.common.lockutils.lock')
+    def test_get_free_hash_no_free_accounts(self, lock_mock):
+        hash_list = self._get_hash_list(self.test_accounts)
+        # Emulate pre-existing lock dir
+        self.useFixture(mockpatch.Patch('os.path.isdir', return_value=True))
+        # Emulate all lcoks in list are in use
+        self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
+        test_account_class = accounts.Accounts('test_name')
+        self.assertRaises(exceptions.InvalidConfiguration,
+                          test_account_class._get_free_hash, hash_list)
+
+    @mock.patch('tempest.openstack.common.lockutils.lock')
+    def test_get_free_hash_some_in_use_accounts(self, lock_mock):
+        # Emulate no pre-existing lock
+        self.useFixture(mockpatch.Patch('os.path.isdir', return_value=True))
+        hash_list = self._get_hash_list(self.test_accounts)
+        test_account_class = accounts.Accounts('test_name')
+
+        def _fake_is_file(path):
+            # Fake isfile() to return that the path exists unless a specific
+            # hash is in the path
+            if hash_list[3] in path:
+                return False
+            return True
+
+        self.stubs.Set(os.path, 'isfile', _fake_is_file)
+        with mock.patch('__builtin__.open', mock.mock_open(),
+                        create=True) as open_mock:
+            test_account_class._get_free_hash(hash_list)
+            lock_path = os.path.join(accounts.CONF.lock_path, 'test_accounts',
+                                     hash_list[3])
+            open_mock.assert_called_once_with(lock_path, 'w')
+
+    @mock.patch('tempest.openstack.common.lockutils.lock')
+    def test_remove_hash_last_account(self, lock_mock):
+        hash_list = self._get_hash_list(self.test_accounts)
+        # Pretend the pseudo-lock is there
+        self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
+        # Pretend the lock dir is empty
+        self.useFixture(mockpatch.Patch('os.listdir', return_value=[]))
+        test_account_class = accounts.Accounts('test_name')
+        remove_mock = self.useFixture(mockpatch.Patch('os.remove'))
+        rmdir_mock = self.useFixture(mockpatch.Patch('os.rmdir'))
+        test_account_class.remove_hash(hash_list[2])
+        hash_path = os.path.join(accounts.CONF.lock_path, 'test_accounts',
+                                 hash_list[2])
+        lock_path = os.path.join(accounts.CONF.lock_path, 'test_accounts')
+        remove_mock.mock.assert_called_once_with(hash_path)
+        rmdir_mock.mock.assert_called_once_with(lock_path)
+
+    @mock.patch('tempest.openstack.common.lockutils.lock')
+    def test_remove_hash_not_last_account(self, lock_mock):
+        hash_list = self._get_hash_list(self.test_accounts)
+        # Pretend the pseudo-lock is there
+        self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
+        # Pretend the lock dir is empty
+        self.useFixture(mockpatch.Patch('os.listdir', return_value=[
+            hash_list[1], hash_list[4]]))
+        test_account_class = accounts.Accounts('test_name')
+        remove_mock = self.useFixture(mockpatch.Patch('os.remove'))
+        rmdir_mock = self.useFixture(mockpatch.Patch('os.rmdir'))
+        test_account_class.remove_hash(hash_list[2])
+        hash_path = os.path.join(accounts.CONF.lock_path, 'test_accounts',
+                                 hash_list[2])
+        remove_mock.mock.assert_called_once_with(hash_path)
+        rmdir_mock.mock.assert_not_called()
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/tempest/tests/fake_config.py b/tempest/tests/fake_config.py
index 4bed0c2..9e56916 100644
--- a/tempest/tests/fake_config.py
+++ b/tempest/tests/fake_config.py
@@ -58,6 +58,7 @@
 
 
 class FakePrivate(config.TempestConfigPrivate):
-    def __init__(self):
+    def __init__(self, parse_conf=True, config_path=None):
         cfg.CONF([], default_config_files=[])
         self._set_attrs()
+        self.lock_path = cfg.CONF.lock_path
diff --git a/tempest/tests/fake_http.py b/tempest/tests/fake_http.py
index ce2b2c0..7d77484 100644
--- a/tempest/tests/fake_http.py
+++ b/tempest/tests/fake_http.py
@@ -13,6 +13,7 @@
 #    under the License.
 
 import copy
+
 import httplib2
 
 
diff --git a/tempest/tests/fake_identity.py b/tempest/tests/fake_identity.py
index 1900fc9..97098e1 100644
--- a/tempest/tests/fake_identity.py
+++ b/tempest/tests/fake_identity.py
@@ -13,9 +13,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import json
 
 import httplib2
-import json
 
 
 TOKEN = "fake_token"
diff --git a/tempest/tests/negative/test_negative_auto_test.py b/tempest/tests/negative/test_negative_auto_test.py
index 7a1909a..dddd083 100644
--- a/tempest/tests/negative/test_negative_auto_test.py
+++ b/tempest/tests/negative/test_negative_auto_test.py
@@ -13,8 +13,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
-
 from tempest import config
 import tempest.test as test
 from tempest.tests import base
@@ -30,9 +28,9 @@
                        "http-method": "GET",
                        "url": "flavors/detail",
                        "json-schema": {"type": "object",
-                                      "properties":
-                                      {"minRam": {"type": "integer"},
-                                       "minDisk": {"type": "integer"}}
+                                       "properties":
+                                       {"minRam": {"type": "integer"},
+                                        "minDisk": {"type": "integer"}}
                                        },
                        "resources": ["flavor", "volume", "image"]
                        }
@@ -56,11 +54,9 @@
         for entry in entries:
             self.assertIsNotNone(entry[1]['resource'])
 
-    @mock.patch('tempest.test.NegativeAutoTest.load_schema')
-    def test_generate_scenario(self, open_mock):
-        open_mock.return_value = self.fake_input_desc
+    def test_generate_scenario(self):
         scenarios = test.NegativeAutoTest.\
-            generate_scenario(None)
+            generate_scenario(self.fake_input_desc)
 
         self.assertIsInstance(scenarios, list)
         for scenario in scenarios:
diff --git a/tempest/tests/negative/test_negative_generators.py b/tempest/tests/negative/test_negative_generators.py
index c77faca..a7af619 100644
--- a/tempest/tests/negative/test_negative_generators.py
+++ b/tempest/tests/negative/test_negative_generators.py
@@ -102,7 +102,7 @@
                                      }
                       }
 
-    unkown_type_schema = {
+    unknown_type_schema = {
         "type": "not_defined"
     }
 
@@ -131,7 +131,7 @@
 
     def test_generate_with_unknown_type(self):
         self.assertRaises(TypeError, self.generator.generate,
-                          self.unkown_type_schema)
+                          self.unknown_type_schema)
 
 
 class TestNegativeValidGenerator(base.TestCase, BaseNegativeGenerator):
diff --git a/tempest/tests/test_auth.py b/tempest/tests/test_auth.py
index 1dcddad..6a2e335 100644
--- a/tempest/tests/test_auth.py
+++ b/tempest/tests/test_auth.py
@@ -59,12 +59,24 @@
     obviously don't test not implemented method or the ones which strongly
     depends on them.
     """
-    _auth_provider_class = auth.AuthProvider
 
-    def test_check_credentials_class(self):
-        self.assertRaises(NotImplementedError,
-                          self.auth_provider.check_credentials,
-                          auth.Credentials())
+    class FakeAuthProviderImpl(auth.AuthProvider):
+        def _decorate_request():
+            pass
+
+        def _fill_credentials():
+            pass
+
+        def _get_auth():
+            pass
+
+        def base_url():
+            pass
+
+        def is_expired():
+            pass
+
+    _auth_provider_class = FakeAuthProviderImpl
 
     def test_check_credentials_bad_type(self):
         self.assertFalse(self.auth_provider.check_credentials([]))
@@ -74,16 +86,6 @@
         auth_provider = self._auth(credentials={})
         self.assertIsInstance(auth_provider.credentials, auth.Credentials)
 
-    def test_instantiate_with_bad_credentials_type(self):
-        """
-        Assure that credentials with bad type fail with TypeError
-        """
-        self.assertRaises(TypeError, self._auth, [])
-
-    def test_auth_data_property(self):
-        self.assertRaises(NotImplementedError, getattr, self.auth_provider,
-                          'auth_data')
-
     def test_auth_data_property_when_cache_exists(self):
         self.auth_provider.cache = 'foo'
         self.useFixture(mockpatch.PatchObject(self.auth_provider,
@@ -110,9 +112,10 @@
         self.assertIsNone(self.auth_provider.alt_part)
         self.assertIsNone(self.auth_provider.alt_auth_data)
 
-    def test_fill_credentials(self):
-        self.assertRaises(NotImplementedError,
-                          self.auth_provider.fill_credentials)
+    def test_auth_class(self):
+        self.assertRaises(TypeError,
+                          auth.AuthProvider,
+                          fake_credentials.FakeCredentials)
 
 
 class TestKeystoneV2AuthProvider(BaseAuthTestsSetUp):
diff --git a/tempest/tests/test_commands.py b/tempest/tests/test_commands.py
index 1e2925b..2379741 100644
--- a/tempest/tests/test_commands.py
+++ b/tempest/tests/test_commands.py
@@ -12,9 +12,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import mock
 import subprocess
 
+import mock
+
 from tempest.common import commands
 from tempest.tests import base
 
diff --git a/tempest/tests/test_decorators.py b/tempest/tests/test_decorators.py
index 6b678f7..12104ec 100644
--- a/tempest/tests/test_decorators.py
+++ b/tempest/tests/test_decorators.py
@@ -237,7 +237,7 @@
 class TestSimpleNegativeDecorator(BaseDecoratorsTest):
     @test.SimpleNegativeAutoTest
     class FakeNegativeJSONTest(test.NegativeAutoTest):
-        _schema_file = 'fake/schemas/file.json'
+        _schema = {}
 
     def test_testfunc_exist(self):
         self.assertIn("test_fake_negative", dir(self.FakeNegativeJSONTest))
@@ -247,4 +247,4 @@
         obj = self.FakeNegativeJSONTest("test_fake_negative")
         self.assertIn("test_fake_negative", dir(obj))
         obj.test_fake_negative()
-        mock.assert_called_once_with(self.FakeNegativeJSONTest._schema_file)
+        mock.assert_called_once_with(self.FakeNegativeJSONTest._schema)
diff --git a/tempest/tests/test_glance_http.py b/tempest/tests/test_glance_http.py
index 88b8129..9a6c9de 100644
--- a/tempest/tests/test_glance_http.py
+++ b/tempest/tests/test_glance_http.py
@@ -15,9 +15,10 @@
 
 import httplib
 import json
+import socket
+
 import mock
 import six
-import socket
 
 from tempest.common import glance_http
 from tempest import exceptions
@@ -41,17 +42,17 @@
 
         self.fake_auth.base_url = mock.MagicMock(return_value=self.endpoint)
 
-        self.useFixture(mockpatch.PatchObject(httplib.HTTPConnection,
-                        'request',
-                        side_effect=self.fake_http.request(self.endpoint)[1]))
+        self.useFixture(mockpatch.PatchObject(
+            httplib.HTTPConnection,
+            'request',
+            side_effect=self.fake_http.request(self.endpoint)[1]))
         self.client = glance_http.HTTPClient(self.fake_auth, {})
 
     def _set_response_fixture(self, header, status, resp_body):
         resp = fake_http.fake_httplib(header, status=status,
                                       body=six.StringIO(resp_body))
         self.useFixture(mockpatch.PatchObject(httplib.HTTPConnection,
-                        'getresponse',
-                        return_value=resp))
+                        'getresponse', return_value=resp))
         return resp
 
     def test_json_request_without_content_type_header_in_response(self):
diff --git a/tempest/tests/test_rest_client.py b/tempest/tests/test_rest_client.py
index a351bd5..5f55ca2 100644
--- a/tempest/tests/test_rest_client.py
+++ b/tempest/tests/test_rest_client.py
@@ -12,9 +12,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import httplib2
 import json
 
+import httplib2
 from oslotest import mockpatch
 
 from tempest.common import rest_client
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index bbc3d15..eddbb1d 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -335,9 +335,11 @@
         remove_router_interface_mock = self.patch(
             'tempest.services.network.json.network_client.NetworkClientJSON.'
             'remove_router_interface_with_subnet_id')
+        return_values = ({'status': 200}, {'ports': []})
         port_list_mock = mock.patch.object(iso_creds.network_admin_client,
-                                           'list_ports', return_value=(
-                                           {'status': 200}, {'ports': []}))
+                                           'list_ports',
+                                           return_value=return_values)
+
         port_list_mock.start()
         iso_creds.clear_isolated_creds()
         # Verify remove router interface calls
diff --git a/tempest/tests/test_waiters.py b/tempest/tests/test_waiters.py
index a29cb46..1f9825e 100644
--- a/tempest/tests/test_waiters.py
+++ b/tempest/tests/test_waiters.py
@@ -15,7 +15,6 @@
 import time
 
 import mock
-import testtools
 
 from tempest.common import waiters
 from tempest import exceptions
@@ -48,221 +47,3 @@
         self.assertRaises(exceptions.AddImageException,
                           waiters.wait_for_image_status,
                           self.client, 'fake_image_id', 'active')
-
-
-class TestServerWaiters(base.TestCase):
-    def setUp(self):
-        super(TestServerWaiters, self).setUp()
-        self.client = mock.MagicMock()
-        self.client.build_timeout = 1
-        self.client.build_interval = 1
-
-    def test_wait_for_server_status(self):
-        self.client.get_server.return_value = (None, {'status':
-                                                      'active'}
-                                               )
-        start_time = int(time.time())
-        waiters.wait_for_server_status(self.client, 'fake_svr_id',
-                                       'active'
-                                       )
-        end_time = int(time.time())
-        # Ensure waiter returns before build_timeout
-        self.assertTrue((end_time - start_time) < 2)
-
-    def test_wait_for_server_status_BUILD_from_not_UNKNOWN(self):
-        self.client.get_server.return_value = (None, {'status': 'active'})
-        start_time = int(time.time())
-        waiters.wait_for_server_status(self.client, 'fake_svr_id',
-                                       'BUILD')
-        end_time = int(time.time())
-        # Ensure waiter returns before build_timeout
-        self.assertTrue((end_time - start_time) < 2)
-
-    def test_wait_for_server_status_ready_wait_with_BUILD(self):
-        self.client.get_server.return_value = (None, {'status': 'BUILD'})
-        start_time = int(time.time())
-        waiters.wait_for_server_status(self.client, 'fake_svr_id',
-                                       'BUILD', True)
-        end_time = int(time.time())
-        # Ensure waiter returns before build_timeout
-        self.assertTrue((end_time - start_time) < 2)
-
-    def test_wait_for_server_status_ready_wait(self):
-        self.client.get_server.return_value = (None, {'status':
-                                                      'ERROR',
-                                                      'OS-EXT-STS:task_state':
-                                                      'n/a'
-                                                      }
-                                               )
-        self.client.get_console_output.return_value = (None,
-                          {'output': 'Server fake_svr_id failed to reach '
-                           'active status and task state n/a within the '
-                           'required time (1 s).\nCurrent status: SUSPENDED.'
-                           '\nCurrent task state: None.'}
-        )
-        self.assertRaises(exceptions.BuildErrorException,
-                          waiters.wait_for_server_status,
-                          self.client, 'fake_svr_id', 'active',
-                          ready_wait=True, extra_timeout=0,
-                          raise_on_error=True
-                          )
-
-    def test_wait_for_server_status_no_ready_wait(self):
-        self.client.get_server.return_value = (None, {'status':
-                                                      'ERROR',
-                                                      'OS-EXT-STS:task_state':
-                                                      'n/a'
-                                                      }
-                                               )
-        start_time = int(time.time())
-        waiters.wait_for_server_status(self.client, 'fake_svr_id',
-                                       'ERROR', ready_wait=False,
-                                       extra_timeout=10, raise_on_error=True
-                                       )
-        end_time = int(time.time())
-        # Ensure waiter returns before build_timeout + extra_timeout
-        self.assertTrue((end_time - start_time) < 12)
-
-    def test_wait_for_server_status_timeout(self):
-        self.client.get_server.return_value = (None, {'status': 'SUSPENDED'})
-        self.client.get_console_output.return_value = (None,
-                          {'output': 'Server fake_svr_id failed to reach '
-                           'active status and task state n/a within the '
-                           'required time (1 s).\nCurrent status: SUSPENDED.'
-                           '\nCurrent task state: None.'}
-        )
-        self.assertRaises(exceptions.TimeoutException,
-                          waiters.wait_for_server_status,
-                         self.client, 'fake_svr_id', 'active')
-
-    def test_wait_for_server_status_extra_timeout(self):
-        self.client.get_server.return_value = (None, {'status': 'SUSPENDED'})
-        start_time = int(time.time())
-        self.client.get_console_output.return_value = (None,
-                          {'output': 'Server fake_svr_id failed to reach '
-                           'active status and task state n/a within the '
-                           'required time (10 s). \nCurrent status: SUSPENDED.'
-                           '\nCurrent task state: None.'}
-        )
-        self.assertRaises(exceptions.TimeoutException,
-                          waiters.wait_for_server_status,
-                          self.client, 'fake_svr_id',
-                          'active', ready_wait=True,
-                          extra_timeout=10, raise_on_error=True
-                          )
-        end_time = int(time.time())
-        # Ensure waiter returns after build_timeout but
-        #   before build_timeout+extra timeout
-        self.assertTrue(10 < (end_time - start_time) < 12)
-
-    def test_wait_for_server_status_error_on_server_create(self):
-        self.client.get_server.return_value = (None, {'status': 'ERROR'})
-        self.client.get_console_output.return_value = (None,
-                          {'output': 'Server fake_svr_id failed to reach '
-                           'activestatus and task state n/a within the '
-                           'required time (1 s).\nCurrent status: ERROR.'
-                           '\nCurrent task state: None.'}
-        )
-        self.assertRaises(exceptions.BuildErrorException,
-                          waiters.wait_for_server_status,
-                          self.client, 'fake_svr_id', 'active')
-
-    def test_wait_for_server_status_no_raise_on_error(self):
-        self.client.get_server.return_value = (None, {'status': 'ERROR'})
-        self.client.get_console_output.return_value = (None,
-                          {'output': 'Server fake_svr_id failed to reach '
-                           'activestatus and task state n/a within the '
-                           'required time (1 s).\nCurrent status: ERROR.'
-                           '\nCurrent task state: None.'}
-        )
-        self.assertRaises(exceptions.TimeoutException,
-                          waiters.wait_for_server_status,
-                          self.client, 'fake_svr_id', 'active',
-                          ready_wait=True, extra_timeout=0,
-                          raise_on_error=False
-                          )
-
-    def test_wait_for_server_status_no_ready_wait_timeout(self):
-        self.client.get_server.return_value = (None, {'status': 'ERROR'})
-        self.client.get_console_output.return_value = (None,
-                          {'output': 'Server fake_svr_id failed to reach '
-                           'active status and task state n/a within the '
-                           'required time (11 s).\nCurrent status: ERROR.'
-                           '\nCurrent task state: None.'}
-        )
-        expected_msg = '''Request timed out
-Details: (TestServerWaiters:test_wait_for_server_status_no_ready_wait_timeout)\
- Server fake_svr_id failed to reach active status and task state "n/a" within\
- the required time (11 s). Current status: ERROR. Current task state: None.\
-'''
-        with testtools.ExpectedException(exceptions.TimeoutException,
-                                         testtools.matchers.AfterPreprocessing(
-                str,
-                testtools.matchers.Equals(expected_msg)
-                )
-            ):
-            waiters.wait_for_server_status(self.client, 'fake_svr_id',
-                                           'active', ready_wait=False,
-                                           extra_timeout=10,
-                                           raise_on_error=False
-                                           )
-
-    def test_wait_for_server_status_ready_wait_timeout(self):
-        self.client.get_server.return_value = (None, {'status': 'ERROR'})
-        self.client.get_console_output.return_value = (None,
-                          {'output': 'Server fake_svr_id failed to reach '
-                           'activestatus and task state n/a within the '
-                           'required time (11 s).\nCurrent status: ERROR.'
-                           '\nCurrent task state: None.'}
-        )
-        expected_msg = '''Request timed out
-Details: (TestServerWaiters:test_wait_for_server_status_ready_wait_timeout)\
- Server fake_svr_id failed to reach active status and task state "None" within\
- the required time (11 s). Current status: ERROR. Current task state: None.\
-'''
-        with testtools.ExpectedException(exceptions.TimeoutException,
-                                         testtools.matchers.AfterPreprocessing(
-                str,
-                testtools.matchers.Equals(expected_msg)
-                )
-            ):
-            waiters.wait_for_server_status(self.client, 'fake_svr_id',
-                                           'active', ready_wait=True,
-                                           extra_timeout=10,
-                                           raise_on_error=False
-                                           )
-
-    def test_wait_for_changing_server_status(self):
-        self.client.get_server.side_effect = [(None, {'status': 'BUILD'}),
-                                              (None, {'status': 'active'})]
-        start_time = int(time.time())
-        waiters.wait_for_server_status(self.client, 'fake_svr_id',
-                                       'active', ready_wait=True,
-                                       extra_timeout=10,
-                                       raise_on_error=True
-                                       )
-        end_time = int(time.time())
-        # Ensure waiter returns before build_timeout + extra_timeout
-        self.assertTrue((end_time - start_time) < 12)
-
-    def test_wait_for_changing_server_task_status(self):
-        self.client.get_server.side_effect = [(None, {'status': 'BUILD',
-                                                      'OS-EXT-STS:task_state':
-                                                      'n/a'
-                                                      }
-                                               ),
-                                              (None, {'status': 'active',
-                                                      'OS-EXT-STS:task_state':
-                                                      'None'
-                                                      }
-                                               )
-                                              ]
-        start_time = int(time.time())
-        waiters.wait_for_server_status(self.client, 'fake_svr_id',
-                                       'active', ready_wait=True,
-                                       extra_timeout=10,
-                                       raise_on_error=True
-                                       )
-        end_time = int(time.time())
-        # Ensure waiter returns before build_timeout + extra_timeout
-        self.assertTrue((end_time - start_time) < 12)
diff --git a/tempest/tests/test_xml_utils.py b/tempest/tests/test_xml_utils.py
new file mode 100644
index 0000000..53e31c4
--- /dev/null
+++ b/tempest/tests/test_xml_utils.py
@@ -0,0 +1,35 @@
+#
+# Copyright 2014 Hewlett-Packard Development Company, L.P.
+#
+# 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 xml_utils
+from tempest.tests import base
+
+
+class TestDocumentXML(base.TestCase):
+    def test_xml_document_ordering_version_encoding(self):
+        expected = '<?xml version="1.0" encoding="UTF-8"?>'
+        xml_out = str(xml_utils.Document())
+        self.assertEqual(expected, xml_out.strip())
+
+        xml_out = str(xml_utils.Document(encoding='UTF-8', version='1.0'))
+        self.assertEqual(expected, xml_out.strip())
+
+        xml_out = str(xml_utils.Document(version='1.0', encoding='UTF-8'))
+        self.assertEqual(expected, xml_out.strip())
+
+    def test_xml_document_additonal_attrs(self):
+        expected = '<?xml version="1.0" encoding="UTF-8" foo="bar"?>'
+        xml_out = str(xml_utils.Document(foo='bar'))
+        self.assertEqual(expected, xml_out.strip())
diff --git a/tempest/thirdparty/README.rst b/tempest/thirdparty/README.rst
index 53cb54b..b0bfdf7 100644
--- a/tempest/thirdparty/README.rst
+++ b/tempest/thirdparty/README.rst
@@ -1,3 +1,5 @@
+.. _third_party_field_guide:
+
 Tempest Field Guide to Third Party API tests
 ============================================
 
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
index d3cbc4b..4bf71f3 100644
--- a/tempest/thirdparty/boto/test.py
+++ b/tempest/thirdparty/boto/test.py
@@ -17,7 +17,6 @@
 import logging as orig_logging
 import os
 import re
-import six
 import urlparse
 
 import boto
@@ -25,6 +24,7 @@
 from boto import exception
 from boto import s3
 import keystoneclient.exceptions
+import six
 
 import tempest.clients
 from tempest.common.utils import file_utils
@@ -187,7 +187,7 @@
         if len(args):
             string += ", "
     string += ", ".join("=".join(map(str, (key, value)))
-              for (key, value) in kwargs.items())
+                        for (key, value) in kwargs.items())
     return string + ")"
 
 
@@ -592,83 +592,83 @@
 
 
 for code in (('AccessDenied', 403),
-            ('AccountProblem', 403),
-            ('AmbiguousGrantByEmailAddress', 400),
-            ('BadDigest', 400),
-            ('BucketAlreadyExists', 409),
-            ('BucketAlreadyOwnedByYou', 409),
-            ('BucketNotEmpty', 409),
-            ('CredentialsNotSupported', 400),
-            ('CrossLocationLoggingProhibited', 403),
-            ('EntityTooSmall', 400),
-            ('EntityTooLarge', 400),
-            ('ExpiredToken', 400),
-            ('IllegalVersioningConfigurationException', 400),
-            ('IncompleteBody', 400),
-            ('IncorrectNumberOfFilesInPostRequest', 400),
-            ('InlineDataTooLarge', 400),
-            ('InvalidAccessKeyId', 403),
+             ('AccountProblem', 403),
+             ('AmbiguousGrantByEmailAddress', 400),
+             ('BadDigest', 400),
+             ('BucketAlreadyExists', 409),
+             ('BucketAlreadyOwnedByYou', 409),
+             ('BucketNotEmpty', 409),
+             ('CredentialsNotSupported', 400),
+             ('CrossLocationLoggingProhibited', 403),
+             ('EntityTooSmall', 400),
+             ('EntityTooLarge', 400),
+             ('ExpiredToken', 400),
+             ('IllegalVersioningConfigurationException', 400),
+             ('IncompleteBody', 400),
+             ('IncorrectNumberOfFilesInPostRequest', 400),
+             ('InlineDataTooLarge', 400),
+             ('InvalidAccessKeyId', 403),
              'InvalidAddressingHeader',
-            ('InvalidArgument', 400),
-            ('InvalidBucketName', 400),
-            ('InvalidBucketState', 409),
-            ('InvalidDigest', 400),
-            ('InvalidLocationConstraint', 400),
-            ('InvalidPart', 400),
-            ('InvalidPartOrder', 400),
-            ('InvalidPayer', 403),
-            ('InvalidPolicyDocument', 400),
-            ('InvalidRange', 416),
-            ('InvalidRequest', 400),
-            ('InvalidSecurity', 403),
-            ('InvalidSOAPRequest', 400),
-            ('InvalidStorageClass', 400),
-            ('InvalidTargetBucketForLogging', 400),
-            ('InvalidToken', 400),
-            ('InvalidURI', 400),
-            ('KeyTooLong', 400),
-            ('MalformedACLError', 400),
-            ('MalformedPOSTRequest', 400),
-            ('MalformedXML', 400),
-            ('MaxMessageLengthExceeded', 400),
-            ('MaxPostPreDataLengthExceededError', 400),
-            ('MetadataTooLarge', 400),
-            ('MethodNotAllowed', 405),
-            ('MissingAttachment'),
-            ('MissingContentLength', 411),
-            ('MissingRequestBodyError', 400),
-            ('MissingSecurityElement', 400),
-            ('MissingSecurityHeader', 400),
-            ('NoLoggingStatusForKey', 400),
-            ('NoSuchBucket', 404),
-            ('NoSuchKey', 404),
-            ('NoSuchLifecycleConfiguration', 404),
-            ('NoSuchUpload', 404),
-            ('NoSuchVersion', 404),
-            ('NotSignedUp', 403),
-            ('NotSuchBucketPolicy', 404),
-            ('OperationAborted', 409),
-            ('PermanentRedirect', 301),
-            ('PreconditionFailed', 412),
-            ('Redirect', 307),
-            ('RequestIsNotMultiPartContent', 400),
-            ('RequestTimeout', 400),
-            ('RequestTimeTooSkewed', 403),
-            ('RequestTorrentOfBucketError', 400),
-            ('SignatureDoesNotMatch', 403),
-            ('TemporaryRedirect', 307),
-            ('TokenRefreshRequired', 400),
-            ('TooManyBuckets', 400),
-            ('UnexpectedContent', 400),
-            ('UnresolvableGrantByEmailAddress', 400),
-            ('UserKeyMustBeSpecified', 400)):
+             ('InvalidArgument', 400),
+             ('InvalidBucketName', 400),
+             ('InvalidBucketState', 409),
+             ('InvalidDigest', 400),
+             ('InvalidLocationConstraint', 400),
+             ('InvalidPart', 400),
+             ('InvalidPartOrder', 400),
+             ('InvalidPayer', 403),
+             ('InvalidPolicyDocument', 400),
+             ('InvalidRange', 416),
+             ('InvalidRequest', 400),
+             ('InvalidSecurity', 403),
+             ('InvalidSOAPRequest', 400),
+             ('InvalidStorageClass', 400),
+             ('InvalidTargetBucketForLogging', 400),
+             ('InvalidToken', 400),
+             ('InvalidURI', 400),
+             ('KeyTooLong', 400),
+             ('MalformedACLError', 400),
+             ('MalformedPOSTRequest', 400),
+             ('MalformedXML', 400),
+             ('MaxMessageLengthExceeded', 400),
+             ('MaxPostPreDataLengthExceededError', 400),
+             ('MetadataTooLarge', 400),
+             ('MethodNotAllowed', 405),
+             ('MissingAttachment'),
+             ('MissingContentLength', 411),
+             ('MissingRequestBodyError', 400),
+             ('MissingSecurityElement', 400),
+             ('MissingSecurityHeader', 400),
+             ('NoLoggingStatusForKey', 400),
+             ('NoSuchBucket', 404),
+             ('NoSuchKey', 404),
+             ('NoSuchLifecycleConfiguration', 404),
+             ('NoSuchUpload', 404),
+             ('NoSuchVersion', 404),
+             ('NotSignedUp', 403),
+             ('NotSuchBucketPolicy', 404),
+             ('OperationAborted', 409),
+             ('PermanentRedirect', 301),
+             ('PreconditionFailed', 412),
+             ('Redirect', 307),
+             ('RequestIsNotMultiPartContent', 400),
+             ('RequestTimeout', 400),
+             ('RequestTimeTooSkewed', 403),
+             ('RequestTorrentOfBucketError', 400),
+             ('SignatureDoesNotMatch', 403),
+             ('TemporaryRedirect', 307),
+             ('TokenRefreshRequired', 400),
+             ('TooManyBuckets', 400),
+             ('UnexpectedContent', 400),
+             ('UnresolvableGrantByEmailAddress', 400),
+             ('UserKeyMustBeSpecified', 400)):
     _add_matcher_class(BotoTestCase.s3_error_code.client,
                        code, base=ClientError)
 
 
 for code in (('InternalError', 500),
-            ('NotImplemented', 501),
-            ('ServiceUnavailable', 503),
-            ('SlowDown', 503)):
+             ('NotImplemented', 501),
+             ('ServiceUnavailable', 503),
+             ('SlowDown', 503)):
     _add_matcher_class(BotoTestCase.s3_error_code.server,
                        code, base=ServerError)
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index 7713931..2c68d6b 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -177,7 +177,10 @@
             instance.remove_tag('key1', value='value1')
 
         tags = self.ec2_client.get_all_tags()
-        self.assertEqual(len(tags), 0, str(tags))
+
+        # NOTE: Volume-attach and detach causes metadata (tags) to be created
+        # for the volume. So exclude them while asserting.
+        self.assertNotIn('key1', tags)
 
         for instance in reservation.instances:
             instance.stop()
diff --git a/tools/check_logs.py b/tools/check_logs.py
index bc4eaca..eab9f73 100755
--- a/tools/check_logs.py
+++ b/tools/check_logs.py
@@ -22,6 +22,7 @@
 import StringIO
 import sys
 import urllib2
+
 import yaml
 
 
diff --git a/tools/colorizer.py b/tools/colorizer.py
index a3a0616..e7152f2 100755
--- a/tools/colorizer.py
+++ b/tools/colorizer.py
@@ -42,10 +42,10 @@
 """Display a subunit stream through a colorized unittest test runner."""
 
 import heapq
-import subunit
 import sys
 import unittest
 
+import subunit
 import testtools
 
 
diff --git a/tools/find_stack_traces.py b/tools/find_stack_traces.py
index c905976..4862d01 100755
--- a/tools/find_stack_traces.py
+++ b/tools/find_stack_traces.py
@@ -16,12 +16,13 @@
 #    under the License.
 
 import gzip
+import pprint
 import re
 import StringIO
 import sys
 import urllib2
 
-import pprint
+
 pp = pprint.PrettyPrinter()
 
 NOVA_TIMESTAMP = r"\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\.\d\d\d"
diff --git a/tools/subunit-trace.py b/tools/subunit-trace.py
index c6f8eab..8ad59bb 100755
--- a/tools/subunit-trace.py
+++ b/tools/subunit-trace.py
@@ -263,7 +263,7 @@
     parser = argparse.ArgumentParser()
     parser.add_argument('--no-failure-debug', '-n', action='store_true',
                         dest='print_failures', help='Disable printing failure '
-                        'debug infomation in realtime')
+                        'debug information in realtime')
     parser.add_argument('--fails', '-f', action='store_true',
                         dest='post_fails', help='Print failure debug '
                         'information after the stream is proccesed')
diff --git a/tox.ini b/tox.ini
index 4f2465a..a071d4b 100644
--- a/tox.ini
+++ b/tox.ini
@@ -6,28 +6,32 @@
 [testenv]
 setenv = VIRTUAL_ENV={envdir}
          OS_TEST_PATH=./tempest/test_discover
+         PYTHONHASHSEED=0
 usedevelop = True
 install_command = pip install -U {opts} {packages}
 
 [testenv:py26]
 setenv = OS_TEST_PATH=./tempest/tests
+         PYTHONHASHSEED=0
 commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
 
 [testenv:py33]
 setenv = OS_TEST_PATH=./tempest/tests
+         PYTHONHASHSEED=0
 commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
 
 [testenv:py27]
 setenv = OS_TEST_PATH=./tempest/tests
+         PYTHONHASHSEED=0
 commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
 
 [testenv:cover]
 setenv = OS_TEST_PATH=./tempest/tests
+         PYTHONHASHSEED=0
 commands = python setup.py testr --coverage --testr-arg='tempest\.tests {posargs}'
 
 [testenv:all]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 commands =
   bash tools/pretty_tox.sh '{posargs}'
 
@@ -104,7 +108,10 @@
 [flake8]
 # E125 is a won't fix until https://github.com/jcrocholl/pep8/issues/126 is resolved.  For further detail see https://review.openstack.org/#/c/36788/
 # H402 skipped because some docstrings aren't sentences
-# Skipped because of new hacking 0.9: H407,H405,H904,H305,E123,H307,E122,E129,E128
-ignore = E125,H402,H404,H407,H405,H904,H305,E123,H307,E122,E129,E128
+# 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,H305
 show-source = True
 exclude = .git,.venv,.tox,dist,doc,openstack,*egg