Merge "Skip baremetal tests if driver not supported"
diff --git a/doc/source/index.rst b/doc/source/index.rst
index c45273e..25bc900 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -1,8 +1,3 @@
-.. Tempest documentation master file, created by
-   sphinx-quickstart on Tue May 21 17:43:32 2013.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
 =======================
 Tempest Testing Project
 =======================
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 858fce9..8a7ad9c 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -23,47 +23,48 @@
 # of default WARNING level). (boolean value)
 #verbose=false
 
-# Log output to standard error (boolean value)
+# Log output to standard error. (boolean value)
 #use_stderr=true
 
-# format string to use for log messages with context (string
+# Format string to use for log messages with context. (string
 # value)
 #logging_context_format_string=%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [%(request_id)s %(user_identity)s] %(instance)s%(message)s
 
-# format string to use for log messages without context
+# Format string to use for log messages without context.
 # (string value)
 #logging_default_format_string=%(asctime)s.%(msecs)03d %(process)d %(levelname)s %(name)s [-] %(instance)s%(message)s
 
-# data to append to log format when level is DEBUG (string
+# Data to append to log format when level is DEBUG. (string
 # value)
 #logging_debug_format_suffix=%(funcName)s %(pathname)s:%(lineno)d
 
-# prefix each line of exception output with this format
+# Prefix each line of exception output with this format.
 # (string value)
 #logging_exception_prefix=%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s
 
-# list of logger=LEVEL pairs (list value)
-#default_log_levels=amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,iso8601=WARN
+# List of logger=LEVEL pairs. (list value)
+#default_log_levels=amqp=WARN,amqplib=WARN,boto=WARN,qpid=WARN,sqlalchemy=WARN,suds=INFO,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN
 
-# publish error events (boolean value)
+# Enables or disables publication of error events. (boolean
+# value)
 #publish_errors=false
 
-# make deprecations fatal (boolean value)
+# Enables or disables fatal status of deprecations. (boolean
+# value)
 #fatal_deprecations=false
 
-# If an instance is passed with the log message, format it
-# like this (string value)
+# The format for an instance that is passed with the log
+# message. (string value)
 #instance_format="[instance: %(uuid)s] "
 
-# If an instance UUID is passed with the log message, format
-# it like this (string value)
+# The format for an instance UUID that is passed with the log
+# message. (string value)
 #instance_uuid_format="[instance: %(uuid)s] "
 
-# The name of logging configuration file. It does not disable
-# existing loggers, but just appends specified logging
-# configuration to any other existing logging options. Please
-# see the Python logging module documentation for details on
-# logging configuration files. (string value)
+# The name of a logging configuration file. This file is
+# appended to any existing logging configuration files. For
+# details about logging configuration files, see the Python
+# logging module documentation. (string value)
 # Deprecated group/name - [DEFAULT]/log_config
 #log_config_append=<None>
 
@@ -75,7 +76,7 @@
 #log_format=<None>
 
 # Format string for %%(asctime)s in log records. Default:
-# %(default)s (string value)
+# %(default)s . (string value)
 #log_date_format=%Y-%m-%d %H:%M:%S
 
 # (Optional) Name of log file to output to. If no default is
@@ -84,14 +85,23 @@
 #log_file=<None>
 
 # (Optional) The base directory used for relative --log-file
-# paths (string value)
+# paths. (string value)
 # Deprecated group/name - [DEFAULT]/logdir
 #log_dir=<None>
 
-# Use syslog for logging. (boolean value)
+# Use syslog for logging. Existing syslog format is DEPRECATED
+# during I, and will change in J to honor RFC5424. (boolean
+# value)
 #use_syslog=false
 
-# syslog facility to receive log lines (string value)
+# (Optional) Enables or disables syslog rfc5424 format for
+# logging. If enabled, prefixes the MSG part of the syslog
+# message with APP-NAME (RFC5424). The format without the APP-
+# NAME is deprecated in I, and will be removed in J. (boolean
+# value)
+#use_syslog_rfc_format=false
+
+# Syslog facility to receive log lines. (string value)
 #syslog_log_facility=LOG_USER
 
 
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 dbac809..18c7cf3 100644
--- a/tempest/README.rst
+++ b/tempest/README.rst
@@ -62,13 +62,10 @@
 stress
 ------
 
-Stress tests are designed to stress an OpenStack environment by
-running a high workload against it and seeing what breaks. Tools may
-be provided to help detect breaks (stack traces in the logs).
-
-TODO: old stress tests deleted, new_stress that david is working on
-moves into here.
-
+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
 ----------
diff --git a/tempest/api/compute/admin/test_availability_zone.py b/tempest/api/compute/admin/test_availability_zone.py
index 9555367..3a6de36 100644
--- a/tempest/api/compute/admin/test_availability_zone.py
+++ b/tempest/api/compute/admin/test_availability_zone.py
@@ -26,7 +26,7 @@
     @classmethod
     def setUpClass(cls):
         super(AZAdminV3Test, cls).setUpClass()
-        cls.client = cls.os_adm.availability_zone_client
+        cls.client = cls.availability_zone_admin_client
 
     @test.attr(type='gate')
     def test_get_availability_zone_list(self):
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_simple_tenant_usage_negative.py b/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
index d69c43c..1031b24 100644
--- a/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
+++ b/tempest/api/compute/admin/test_simple_tenant_usage_negative.py
@@ -51,7 +51,6 @@
         # Get usage for tenant with invalid date
         params = {'start': self.end,
                   'end': self.start}
-        resp, tenants = self.identity_client.list_tenants()
         self.assertRaises(exceptions.BadRequest,
                           self.adm_client.get_tenant_usage,
                           self.client.tenant_id, params)
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index caf4174..70a9604 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -392,8 +392,11 @@
                 msg = ("Missing Compute Admin API credentials "
                        "in configuration.")
                 raise cls.skipException(msg)
+        if cls._api_version == 2:
+            cls.availability_zone_admin_client = (
+                cls.os_adm.availability_zone_client)
 
-        if cls._api_version == 3:
+        else:
             cls.servers_admin_client = cls.os_adm.servers_v3_client
             cls.services_admin_client = cls.os_adm.services_v3_client
             cls.availability_zone_admin_client = \
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/identity/admin/test_roles.py b/tempest/api/identity/admin/test_roles.py
index a29f27e..7a6d07f 100644
--- a/tempest/api/identity/admin/test_roles.py
+++ b/tempest/api/identity/admin/test_roles.py
@@ -29,7 +29,7 @@
         super(RolesTestJSON, cls).setUpClass()
         for _ in moves.xrange(5):
             role_name = data_utils.rand_name(name='role-')
-            resp, role = cls.client.create_role(role_name)
+            _, role = cls.client.create_role(role_name)
             cls.data.roles.append(role)
 
     def _get_role_params(self):
@@ -50,7 +50,7 @@
     @test.attr(type='gate')
     def test_list_roles(self):
         # Return a list of all roles
-        resp, body = self.client.list_roles()
+        _, body = self.client.list_roles()
         found = [role for role in body if role in self.data.roles]
         self.assertTrue(any(found))
         self.assertEqual(len(found), len(self.data.roles))
@@ -59,18 +59,16 @@
     def test_role_create_delete(self):
         # Role should be created, verified, and deleted
         role_name = data_utils.rand_name(name='role-test-')
-        resp, body = self.client.create_role(role_name)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.create_role(role_name)
         self.assertEqual(role_name, body['name'])
 
-        resp, body = self.client.list_roles()
+        _, body = self.client.list_roles()
         found = [role for role in body if role['name'] == role_name]
         self.assertTrue(any(found))
 
-        resp, body = self.client.delete_role(found[0]['id'])
-        self.assertEqual(204, resp.status)
+        _, body = self.client.delete_role(found[0]['id'])
 
-        resp, body = self.client.list_roles()
+        _, body = self.client.list_roles()
         found = [role for role in body if role['name'] == role_name]
         self.assertFalse(any(found))
 
@@ -80,9 +78,7 @@
         self.data.setup_test_role()
         role_id = self.data.role['id']
         role_name = self.data.role['name']
-        resp, body = self.client.get_role(role_id)
-        self.assertIn('status', resp)
-        self.assertTrue('200', resp['status'])
+        _, body = self.client.get_role(role_id)
         self.assertEqual(role_id, body['id'])
         self.assertEqual(role_name, body['name'])
 
@@ -91,25 +87,24 @@
         # 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'])
-        resp, roles = self.client.list_user_roles(tenant['id'], user['id'])
+        _, roles = self.client.list_user_roles(tenant['id'], user['id'])
         self.assert_role_in_role_list(role, roles)
 
     @test.attr(type='gate')
     def test_remove_user_role(self):
         # Remove a role assigned to a user on a tenant
         (user, tenant, role) = self._get_role_params()
-        resp, user_role = self.client.assign_user_role(tenant['id'],
-                                                       user['id'], role['id'])
-        resp, body = self.client.remove_user_role(tenant['id'], user['id'],
-                                                  user_role['id'])
-        self.assertEqual(204, resp.status)
+        _, user_role = self.client.assign_user_role(tenant['id'],
+                                                    user['id'], role['id'])
+        self.client.remove_user_role(tenant['id'], user['id'],
+                                     user_role['id'])
 
     @test.attr(type='gate')
     def test_list_user_roles(self):
         # 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'])
-        resp, roles = self.client.list_user_roles(tenant['id'], user['id'])
+        _, roles = self.client.list_user_roles(tenant['id'], user['id'])
         self.assert_role_in_role_list(role, roles)
 
 
diff --git a/tempest/api/identity/admin/test_roles_negative.py b/tempest/api/identity/admin/test_roles_negative.py
index 6f8f9b5..37a981e 100644
--- a/tempest/api/identity/admin/test_roles_negative.py
+++ b/tempest/api/identity/admin/test_roles_negative.py
@@ -72,9 +72,8 @@
     def test_role_create_duplicate(self):
         # Role names should be unique
         role_name = data_utils.rand_name(name='role-dup-')
-        resp, body = self.client.create_role(role_name)
+        _, body = self.client.create_role(role_name)
         role1_id = body.get('id')
-        self.assertEqual(200, resp.status)
         self.addCleanup(self.client.delete_role, role1_id)
         self.assertRaises(exceptions.Conflict, self.client.create_role,
                           role_name)
@@ -83,8 +82,7 @@
     def test_delete_role_by_unauthorized_user(self):
         # Non-administrator user should not be able to delete role
         role_name = data_utils.rand_name(name='role-')
-        resp, body = self.client.create_role(role_name)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.create_role(role_name)
         self.data.roles.append(body)
         role_id = body.get('id')
         self.assertRaises(exceptions.Unauthorized,
@@ -94,8 +92,7 @@
     def test_delete_role_request_without_token(self):
         # Request to delete role without a valid token should fail
         role_name = data_utils.rand_name(name='role-')
-        resp, body = self.client.create_role(role_name)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.create_role(role_name)
         self.data.roles.append(body)
         role_id = body.get('id')
         token = self.client.auth_provider.get_token()
diff --git a/tempest/api/identity/admin/test_services.py b/tempest/api/identity/admin/test_services.py
index 5926488..a9782a9 100644
--- a/tempest/api/identity/admin/test_services.py
+++ b/tempest/api/identity/admin/test_services.py
@@ -26,8 +26,7 @@
 
     def _del_service(self, service_id):
         # Deleting the service created in this method
-        resp, _ = self.client.delete_service(service_id)
-        self.assertEqual(204, resp.status)
+        self.client.delete_service(service_id)
         # Checking whether service is deleted successfully
         self.assertRaises(exceptions.NotFound, self.client.get_service,
                           service_id)
@@ -39,11 +38,10 @@
         name = data_utils.rand_name('service-')
         type = data_utils.rand_name('type--')
         description = data_utils.rand_name('description-')
-        resp, service_data = self.client.create_service(
+        _, service_data = self.client.create_service(
             name, type, description=description)
         self.assertFalse(service_data['id'] is None)
         self.addCleanup(self._del_service, service_data['id'])
-        self.assertEqual(200, resp.status)
         # Verifying response body of create service
         self.assertIn('id', service_data)
         self.assertIn('name', service_data)
@@ -53,8 +51,7 @@
         self.assertIn('description', service_data)
         self.assertEqual(description, service_data['description'])
         # Get service
-        resp, fetched_service = self.client.get_service(service_data['id'])
-        self.assertEqual(200, resp.status)
+        _, fetched_service = self.client.get_service(service_data['id'])
         # verifying the existence of service created
         self.assertIn('id', fetched_service)
         self.assertEqual(fetched_service['id'], service_data['id'])
@@ -71,9 +68,8 @@
         # Create a service only with name and type
         name = data_utils.rand_name('service-')
         type = data_utils.rand_name('type--')
-        resp, service = self.client.create_service(name, type)
+        _, service = self.client.create_service(name, type)
         self.assertIn('id', service)
-        self.assertTrue('200', resp['status'])
         self.addCleanup(self._del_service, service['id'])
         self.assertIn('name', service)
         self.assertEqual(name, service['name'])
@@ -88,7 +84,7 @@
             name = data_utils.rand_name('service-')
             type = data_utils.rand_name('type--')
             description = data_utils.rand_name('description-')
-            resp, service = self.client.create_service(
+            _, service = self.client.create_service(
                 name, type, description=description)
             services.append(service)
         service_ids = map(lambda x: x['id'], services)
@@ -99,8 +95,7 @@
 
         self.addCleanup(delete_services)
         # List and Verify Services
-        resp, body = self.client.list_services()
-        self.assertEqual(200, resp.status)
+        _, body = self.client.list_services()
         found = [serv for serv in body if serv['id'] in service_ids]
         self.assertEqual(len(found), len(services), 'Services not found')
 
diff --git a/tempest/api/identity/admin/test_tenant_negative.py b/tempest/api/identity/admin/test_tenant_negative.py
index 622ad81..dcfacee 100644
--- a/tempest/api/identity/admin/test_tenant_negative.py
+++ b/tempest/api/identity/admin/test_tenant_negative.py
@@ -42,8 +42,7 @@
     def test_tenant_delete_by_unauthorized_user(self):
         # Non-administrator user should not be able to delete a tenant
         tenant_name = data_utils.rand_name(name='tenant-')
-        resp, tenant = self.client.create_tenant(tenant_name)
-        self.assertEqual(200, resp.status)
+        _, tenant = self.client.create_tenant(tenant_name)
         self.data.tenants.append(tenant)
         self.assertRaises(exceptions.Unauthorized,
                           self.non_admin_client.delete_tenant, tenant['id'])
@@ -52,8 +51,7 @@
     def test_tenant_delete_request_without_token(self):
         # Request to delete a tenant without a valid token should fail
         tenant_name = data_utils.rand_name(name='tenant-')
-        resp, tenant = self.client.create_tenant(tenant_name)
-        self.assertEqual(200, resp.status)
+        _, tenant = self.client.create_tenant(tenant_name)
         self.data.tenants.append(tenant)
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
@@ -71,8 +69,7 @@
     def test_tenant_create_duplicate(self):
         # Tenant names should be unique
         tenant_name = data_utils.rand_name(name='tenant-')
-        resp, body = self.client.create_tenant(tenant_name)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.create_tenant(tenant_name)
         tenant = body
         self.data.tenants.append(tenant)
         tenant1_id = body.get('id')
@@ -122,8 +119,7 @@
     def test_tenant_update_by_unauthorized_user(self):
         # Non-administrator user should not be able to update a tenant
         tenant_name = data_utils.rand_name(name='tenant-')
-        resp, tenant = self.client.create_tenant(tenant_name)
-        self.assertEqual(200, resp.status)
+        _, tenant = self.client.create_tenant(tenant_name)
         self.data.tenants.append(tenant)
         self.assertRaises(exceptions.Unauthorized,
                           self.non_admin_client.update_tenant, tenant['id'])
@@ -132,8 +128,7 @@
     def test_tenant_update_request_without_token(self):
         # Request to update a tenant without a valid token should fail
         tenant_name = data_utils.rand_name(name='tenant-')
-        resp, tenant = self.client.create_tenant(tenant_name)
-        self.assertEqual(200, resp.status)
+        _, tenant = self.client.create_tenant(tenant_name)
         self.data.tenants.append(tenant)
         token = self.client.auth_provider.get_token()
         self.client.delete_token(token)
diff --git a/tempest/api/identity/admin/test_tenants.py b/tempest/api/identity/admin/test_tenants.py
index 93734d2..8d3b402 100644
--- a/tempest/api/identity/admin/test_tenants.py
+++ b/tempest/api/identity/admin/test_tenants.py
@@ -29,22 +29,19 @@
         tenants = []
         for _ in moves.xrange(3):
             tenant_name = data_utils.rand_name(name='tenant-new')
-            resp, tenant = self.client.create_tenant(tenant_name)
-            self.assertEqual(200, resp.status)
+            _, tenant = self.client.create_tenant(tenant_name)
             self.data.tenants.append(tenant)
             tenants.append(tenant)
         tenant_ids = map(lambda x: x['id'], tenants)
-        resp, body = self.client.list_tenants()
-        self.assertEqual(200, resp.status)
+        _, body = self.client.list_tenants()
         found = [t for t in body if t['id'] in tenant_ids]
         self.assertEqual(len(found), len(tenants), 'Tenants not created')
 
         for tenant in tenants:
-            resp, body = self.client.delete_tenant(tenant['id'])
-            self.assertEqual(204, resp.status)
+            self.client.delete_tenant(tenant['id'])
             self.data.tenants.remove(tenant)
 
-        resp, body = self.client.list_tenants()
+        _, body = self.client.list_tenants()
         found = [tenant for tenant in body if tenant['id'] in tenant_ids]
         self.assertFalse(any(found), 'Tenants failed to delete')
 
@@ -53,16 +50,15 @@
         # Create tenant with a description
         tenant_name = data_utils.rand_name(name='tenant-')
         tenant_desc = data_utils.rand_name(name='desc-')
-        resp, body = self.client.create_tenant(tenant_name,
-                                               description=tenant_desc)
+        _, body = self.client.create_tenant(tenant_name,
+                                            description=tenant_desc)
         tenant = body
         self.data.tenants.append(tenant)
         tenant_id = body['id']
         desc1 = body['description']
-        self.assertEqual(200, resp.status)
         self.assertEqual(desc1, tenant_desc, 'Description should have '
                          'been sent in response for create')
-        resp, body = self.client.get_tenant(tenant_id)
+        _, body = self.client.get_tenant(tenant_id)
         desc2 = body['description']
         self.assertEqual(desc2, tenant_desc, 'Description does not appear'
                          'to be set')
@@ -73,14 +69,13 @@
     def test_tenant_create_enabled(self):
         # Create a tenant that is enabled
         tenant_name = data_utils.rand_name(name='tenant-')
-        resp, body = self.client.create_tenant(tenant_name, enabled=True)
+        _, body = self.client.create_tenant(tenant_name, enabled=True)
         tenant = body
         self.data.tenants.append(tenant)
         tenant_id = body['id']
         en1 = body['enabled']
-        self.assertEqual(200, resp.status)
         self.assertTrue(en1, 'Enable should be True in response')
-        resp, body = self.client.get_tenant(tenant_id)
+        _, body = self.client.get_tenant(tenant_id)
         en2 = body['enabled']
         self.assertTrue(en2, 'Enable should be True in lookup')
         self.client.delete_tenant(tenant_id)
@@ -90,15 +85,14 @@
     def test_tenant_create_not_enabled(self):
         # Create a tenant that is not enabled
         tenant_name = data_utils.rand_name(name='tenant-')
-        resp, body = self.client.create_tenant(tenant_name, enabled=False)
+        _, body = self.client.create_tenant(tenant_name, enabled=False)
         tenant = body
         self.data.tenants.append(tenant)
         tenant_id = body['id']
         en1 = body['enabled']
-        self.assertEqual(200, resp.status)
         self.assertEqual('false', str(en1).lower(),
                          'Enable should be False in response')
-        resp, body = self.client.get_tenant(tenant_id)
+        _, body = self.client.get_tenant(tenant_id)
         en2 = body['enabled']
         self.assertEqual('false', str(en2).lower(),
                          'Enable should be False in lookup')
@@ -109,8 +103,7 @@
     def test_tenant_update_name(self):
         # Update name attribute of a tenant
         t_name1 = data_utils.rand_name(name='tenant-')
-        resp, body = self.client.create_tenant(t_name1)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.create_tenant(t_name1)
         tenant = body
         self.data.tenants.append(tenant)
 
@@ -118,12 +111,11 @@
         resp1_name = body['name']
 
         t_name2 = data_utils.rand_name(name='tenant2-')
-        resp, body = self.client.update_tenant(t_id, name=t_name2)
+        _, body = self.client.update_tenant(t_id, name=t_name2)
         resp2_name = body['name']
-        self.assertEqual(200, resp.status)
         self.assertNotEqual(resp1_name, resp2_name)
 
-        resp, body = self.client.get_tenant(t_id)
+        _, body = self.client.get_tenant(t_id)
         resp3_name = body['name']
 
         self.assertNotEqual(resp1_name, resp3_name)
@@ -138,8 +130,7 @@
         # Update description attribute of a tenant
         t_name = data_utils.rand_name(name='tenant-')
         t_desc = data_utils.rand_name(name='desc-')
-        resp, body = self.client.create_tenant(t_name, description=t_desc)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.create_tenant(t_name, description=t_desc)
         tenant = body
         self.data.tenants.append(tenant)
 
@@ -147,12 +138,11 @@
         resp1_desc = body['description']
 
         t_desc2 = data_utils.rand_name(name='desc2-')
-        resp, body = self.client.update_tenant(t_id, description=t_desc2)
+        _, body = self.client.update_tenant(t_id, description=t_desc2)
         resp2_desc = body['description']
-        self.assertEqual(200, resp.status)
         self.assertNotEqual(resp1_desc, resp2_desc)
 
-        resp, body = self.client.get_tenant(t_id)
+        _, body = self.client.get_tenant(t_id)
         resp3_desc = body['description']
 
         self.assertNotEqual(resp1_desc, resp3_desc)
@@ -167,8 +157,7 @@
         # Update the enabled attribute of a tenant
         t_name = data_utils.rand_name(name='tenant-')
         t_en = False
-        resp, body = self.client.create_tenant(t_name, enabled=t_en)
-        self.assertEqual(200, resp.status)
+        _, body = self.client.create_tenant(t_name, enabled=t_en)
         tenant = body
         self.data.tenants.append(tenant)
 
@@ -176,12 +165,11 @@
         resp1_en = body['enabled']
 
         t_en2 = True
-        resp, body = self.client.update_tenant(t_id, enabled=t_en2)
+        _, body = self.client.update_tenant(t_id, enabled=t_en2)
         resp2_en = body['enabled']
-        self.assertEqual(200, resp.status)
         self.assertNotEqual(resp1_en, resp2_en)
 
-        resp, body = self.client.get_tenant(t_id)
+        _, body = self.client.get_tenant(t_id)
         resp3_en = body['enabled']
 
         self.assertNotEqual(resp1_en, resp3_en)
diff --git a/tempest/api/identity/admin/test_tokens.py b/tempest/api/identity/admin/test_tokens.py
index 08e12f0..e1db008 100644
--- a/tempest/api/identity/admin/test_tokens.py
+++ b/tempest/api/identity/admin/test_tokens.py
@@ -28,13 +28,11 @@
         user_password = data_utils.rand_name(name='pass-')
         # first:create a tenant
         tenant_name = data_utils.rand_name(name='tenant-')
-        resp, tenant = self.client.create_tenant(tenant_name)
-        self.assertEqual(200, resp.status)
+        _, tenant = self.client.create_tenant(tenant_name)
         self.data.tenants.append(tenant)
         # second:create a user
-        resp, user = self.client.create_user(user_name, user_password,
-                                             tenant['id'], '')
-        self.assertEqual(200, resp.status)
+        _, user = self.client.create_user(user_name, user_password,
+                                          tenant['id'], '')
         self.data.users.append(user)
         # then get a token for the user
         rsp, body = self.token_client.auth(user_name,
@@ -45,16 +43,14 @@
                          tenant['name'])
         # Perform GET Token
         token_id = body['token']['id']
-        resp, token_details = self.client.get_token(token_id)
-        self.assertEqual(resp['status'], '200')
+        _, token_details = self.client.get_token(token_id)
         self.assertEqual(token_id, token_details['token']['id'])
         self.assertEqual(user['id'], token_details['user']['id'])
         self.assertEqual(user_name, token_details['user']['name'])
         self.assertEqual(tenant['name'],
                          token_details['token']['tenant']['name'])
         # then delete the token
-        resp, body = self.client.delete_token(token_id)
-        self.assertEqual(resp['status'], '204')
+        self.client.delete_token(token_id)
 
     @test.attr(type='gate')
     def test_rescope_token(self):
@@ -67,56 +63,51 @@
         user_password = data_utils.rand_name(name='pass-')
         tenant_id = None  # No default tenant so will get unscoped token.
         email = ''
-        resp, user = self.client.create_user(user_name, user_password,
-                                             tenant_id, email)
-        self.assertEqual(200, resp.status)
+        _, user = self.client.create_user(user_name, user_password,
+                                          tenant_id, email)
         self.data.users.append(user)
 
         # Create a couple tenants.
         tenant1_name = data_utils.rand_name(name='tenant-')
-        resp, tenant1 = self.client.create_tenant(tenant1_name)
-        self.assertEqual(200, resp.status)
+        _, tenant1 = self.client.create_tenant(tenant1_name)
         self.data.tenants.append(tenant1)
 
         tenant2_name = data_utils.rand_name(name='tenant-')
-        resp, tenant2 = self.client.create_tenant(tenant2_name)
-        self.assertEqual(200, resp.status)
+        _, tenant2 = self.client.create_tenant(tenant2_name)
         self.data.tenants.append(tenant2)
 
         # Create a role
         role_name = data_utils.rand_name(name='role-')
-        resp, role = self.client.create_role(role_name)
-        self.assertEqual(200, resp.status)
+        _, role = self.client.create_role(role_name)
         self.data.roles.append(role)
 
         # Grant the user the role on the tenants.
-        resp, _ = self.client.assign_user_role(tenant1['id'], user['id'],
-                                               role['id'])
-        self.assertEqual(200, resp.status)
+        self.client.assign_user_role(tenant1['id'], user['id'],
+                                     role['id'])
 
-        resp, _ = self.client.assign_user_role(tenant2['id'], user['id'],
-                                               role['id'])
-        self.assertEqual(200, resp.status)
+        self.client.assign_user_role(tenant2['id'], user['id'],
+                                     role['id'])
 
         # Get an unscoped token.
-        rsp, body = self.token_client.auth(user_name, user_password)
+        resp, body = self.token_client.auth(user_name, user_password)
         self.assertEqual(200, resp.status)
 
         token_id = body['token']['id']
 
         # Use the unscoped token to get a token scoped to tenant1
-        rsp, body = self.token_client.auth_token(token_id, tenant=tenant1_name)
+        resp, body = self.token_client.auth_token(token_id,
+                                                  tenant=tenant1_name)
         self.assertEqual(200, resp.status)
 
         scoped_token_id = body['token']['id']
 
         # Revoke the scoped token
-        resp, body = self.client.delete_token(scoped_token_id)
-        self.assertEqual(204, resp.status)
+        self.client.delete_token(scoped_token_id)
 
         # Use the unscoped token to get a token scoped to tenant2
-        rsp, body = self.token_client.auth_token(token_id, tenant=tenant2_name)
-        self.assertEqual(204, resp.status)
+        resp, body = self.token_client.auth_token(token_id,
+                                                  tenant=tenant2_name)
+        self.assertEqual(200, resp.status)
 
 
 class TokensTestXML(TokensTestJSON):
diff --git a/tempest/api/identity/admin/test_users.py b/tempest/api/identity/admin/test_users.py
index e2c1066..5838da3 100644
--- a/tempest/api/identity/admin/test_users.py
+++ b/tempest/api/identity/admin/test_users.py
@@ -34,11 +34,10 @@
     def test_create_user(self):
         # Create a user
         self.data.setup_test_tenant()
-        resp, user = self.client.create_user(self.alt_user, self.alt_password,
-                                             self.data.tenant['id'],
-                                             self.alt_email)
+        _, user = self.client.create_user(self.alt_user, self.alt_password,
+                                          self.data.tenant['id'],
+                                          self.alt_email)
         self.data.users.append(user)
-        self.assertEqual('200', resp['status'])
         self.assertEqual(self.alt_user, user['name'])
 
     @test.attr(type='smoke')
@@ -46,11 +45,10 @@
         # Create a user with enabled : False
         self.data.setup_test_tenant()
         name = data_utils.rand_name('test_user_')
-        resp, user = self.client.create_user(name, self.alt_password,
-                                             self.data.tenant['id'],
-                                             self.alt_email, enabled=False)
+        _, user = self.client.create_user(name, self.alt_password,
+                                          self.data.tenant['id'],
+                                          self.alt_email, enabled=False)
         self.data.users.append(user)
-        self.assertEqual('200', resp['status'])
         self.assertEqual(name, user['name'])
         self.assertEqual('false', str(user['enabled']).lower())
         self.assertEqual(self.alt_email, user['email'])
@@ -60,24 +58,22 @@
         # Test case to check if updating of user attributes is successful.
         test_user = data_utils.rand_name('test_user_')
         self.data.setup_test_tenant()
-        resp, user = self.client.create_user(test_user, self.alt_password,
-                                             self.data.tenant['id'],
-                                             self.alt_email)
+        _, user = self.client.create_user(test_user, self.alt_password,
+                                          self.data.tenant['id'],
+                                          self.alt_email)
         # Delete the User at the end of this method
         self.addCleanup(self.client.delete_user, user['id'])
         # Updating user details with new values
         u_name2 = data_utils.rand_name('user2-')
         u_email2 = u_name2 + '@testmail.tm'
-        resp, update_user = self.client.update_user(user['id'], name=u_name2,
-                                                    email=u_email2,
-                                                    enabled=False)
-        # Assert response body of update user.
-        self.assertEqual(200, resp.status)
+        _, update_user = self.client.update_user(user['id'], name=u_name2,
+                                                 email=u_email2,
+                                                 enabled=False)
         self.assertEqual(u_name2, update_user['name'])
         self.assertEqual(u_email2, update_user['email'])
         self.assertEqual('false', str(update_user['enabled']).lower())
         # GET by id after updating
-        resp, updated_user = self.client.get_user(user['id'])
+        _, updated_user = self.client.get_user(user['id'])
         # Assert response body of GET after updating
         self.assertEqual(u_name2, updated_user['name'])
         self.assertEqual(u_email2, updated_user['email'])
@@ -88,12 +84,10 @@
         # Delete a user
         test_user = data_utils.rand_name('test_user_')
         self.data.setup_test_tenant()
-        resp, user = self.client.create_user(test_user, self.alt_password,
-                                             self.data.tenant['id'],
-                                             self.alt_email)
-        self.assertEqual('200', resp['status'])
-        resp, body = self.client.delete_user(user['id'])
-        self.assertEqual('204', resp['status'])
+        _, user = self.client.create_user(test_user, self.alt_password,
+                                          self.data.tenant['id'],
+                                          self.alt_email)
+        self.client.delete_user(user['id'])
 
     @test.attr(type='smoke')
     def test_user_authentication(self):
@@ -129,7 +123,7 @@
     def test_get_users(self):
         # Get a list of users and find the test user
         self.data.setup_test_user()
-        resp, users = self.client.get_users()
+        _, users = self.client.get_users()
         self.assertThat([u['name'] for u in users],
                         matchers.Contains(self.data.test_user),
                         "Could not find %s" % self.data.test_user)
@@ -141,23 +135,20 @@
         user_ids = list()
         fetched_user_ids = list()
         alt_tenant_user1 = data_utils.rand_name('tenant_user1_')
-        resp, user1 = self.client.create_user(alt_tenant_user1, 'password1',
-                                              self.data.tenant['id'],
-                                              'user1@123')
-        self.assertEqual('200', resp['status'])
+        _, user1 = self.client.create_user(alt_tenant_user1, 'password1',
+                                           self.data.tenant['id'],
+                                           'user1@123')
         user_ids.append(user1['id'])
         self.data.users.append(user1)
 
         alt_tenant_user2 = data_utils.rand_name('tenant_user2_')
-        resp, user2 = self.client.create_user(alt_tenant_user2, 'password2',
-                                              self.data.tenant['id'],
-                                              'user2@123')
-        self.assertEqual('200', resp['status'])
+        _, user2 = self.client.create_user(alt_tenant_user2, 'password2',
+                                           self.data.tenant['id'],
+                                           'user2@123')
         user_ids.append(user2['id'])
         self.data.users.append(user2)
         # List of users for the respective tenant ID
-        resp, body = self.client.list_users_for_tenant(self.data.tenant['id'])
-        self.assertIn(resp['status'], ('200', '203'))
+        _, body = self.client.list_users_for_tenant(self.data.tenant['id'])
         for i in body:
             fetched_user_ids.append(i['id'])
         # verifying the user Id in the list
@@ -179,24 +170,20 @@
         user_ids = list()
         fetched_user_ids = list()
         user_ids.append(user['id'])
-        resp, role = self.client.assign_user_role(tenant['id'], user['id'],
-                                                  role['id'])
-        self.assertEqual('200', resp['status'])
+        _, role = self.client.assign_user_role(tenant['id'], user['id'],
+                                               role['id'])
 
         alt_user2 = data_utils.rand_name('second_user_')
-        resp, second_user = self.client.create_user(alt_user2, 'password1',
-                                                    self.data.tenant['id'],
-                                                    'user2@123')
-        self.assertEqual('200', resp['status'])
+        _, second_user = self.client.create_user(alt_user2, 'password1',
+                                                 self.data.tenant['id'],
+                                                 'user2@123')
         user_ids.append(second_user['id'])
         self.data.users.append(second_user)
-        resp, role = self.client.assign_user_role(tenant['id'],
-                                                  second_user['id'],
-                                                  role['id'])
-        self.assertEqual('200', resp['status'])
+        _, role = self.client.assign_user_role(tenant['id'],
+                                               second_user['id'],
+                                               role['id'])
         # List of users with roles for the respective tenant ID
-        resp, body = self.client.list_users_for_tenant(self.data.tenant['id'])
-        self.assertEqual('200', resp['status'])
+        _, body = self.client.list_users_for_tenant(self.data.tenant['id'])
         for i in body:
             fetched_user_ids.append(i['id'])
         # verifying the user Id in the list
@@ -212,10 +199,8 @@
         self.data.setup_test_user()
         # Updating the user with new password
         new_pass = data_utils.rand_name('pass-')
-        resp, update_user = self.client.update_user_password(
+        _, update_user = self.client.update_user_password(
             self.data.user['id'], new_pass)
-        # Assert response body of update user.
-        self.assertEqual(200, resp.status)
         self.assertEqual(update_user['id'], self.data.user['id'])
 
         # Validate the updated password
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index 6bb0ebe..d40e0f3 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.py
@@ -33,28 +33,20 @@
         u_email = '%s@testmail.tm' % u_name
         u_password = data_utils.rand_name('pass-')
         for i in range(2):
-            resp, cls.project = cls.client.create_project(
+            _, cls.project = cls.client.create_project(
                 data_utils.rand_name('project-'),
                 description=data_utils.rand_name('project-desc-'))
-            assert resp['status'] == '201', (
-                "Expected 201, but got: %s" % resp['status'])
             cls.projects.append(cls.project['id'])
 
-        resp, cls.user_body = cls.client.create_user(
+        _, cls.user_body = cls.client.create_user(
             u_name, description=u_desc, password=u_password,
             email=u_email, project_id=cls.projects[0])
-        assert resp['status'] == '201', (
-            "Expected 201, but got: %s" % resp['status'])
 
     @classmethod
     def tearDownClass(cls):
-        resp, _ = cls.client.delete_user(cls.user_body['id'])
-        assert resp['status'] == '204', (
-            "Expected 204, but got: %s" % resp['status'])
+        cls.client.delete_user(cls.user_body['id'])
         for p in cls.projects:
-            resp, _ = cls.client.delete_project(p)
-            assert resp['status'] == '204', (
-                "Expected 204, but got: %s" % resp['status'])
+            cls.client.delete_project(p)
         super(CredentialsTestJSON, cls).tearDownClass()
 
     def _delete_credential(self, cred_id):
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index a1e6cde..5b73df1 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -25,9 +25,8 @@
     def _delete_domain(self, domain_id):
         # It is necessary to disable the domain before deleting,
         # or else it would result in unauthorized error
-        _, body = self.client.update_domain(domain_id, enabled=False)
-        resp, _ = self.client.delete_domain(domain_id)
-        self.assertEqual(204, resp.status)
+        self.client.update_domain(domain_id, enabled=False)
+        self.client.delete_domain(domain_id)
 
     @test.attr(type='smoke')
     def test_list_domains(self):
@@ -42,8 +41,7 @@
             self.addCleanup(self._delete_domain, domain['id'])
             domain_ids.append(domain['id'])
         # List and Verify Domains
-        resp, body = self.client.list_domains()
-        self.assertEqual(resp['status'], '200')
+        _, body = self.client.list_domains()
         for d in body:
             fetched_ids.append(d['id'])
         missing_doms = [d for d in domain_ids if d not in fetched_ids]
@@ -53,9 +51,8 @@
     def test_create_update_delete_domain(self):
         d_name = data_utils.rand_name('domain-')
         d_desc = data_utils.rand_name('domain-desc-')
-        resp_1, domain = self.client.create_domain(
+        _, domain = self.client.create_domain(
             d_name, description=d_desc)
-        self.assertEqual(resp_1['status'], '201')
         self.addCleanup(self._delete_domain, domain['id'])
         self.assertIn('id', domain)
         self.assertIn('description', domain)
@@ -72,9 +69,8 @@
         new_desc = data_utils.rand_name('new-desc-')
         new_name = data_utils.rand_name('new-name-')
 
-        resp_2, updated_domain = self.client.update_domain(
+        _, updated_domain = self.client.update_domain(
             domain['id'], name=new_name, description=new_desc)
-        self.assertEqual(resp_2['status'], '200')
         self.assertIn('id', updated_domain)
         self.assertIn('description', updated_domain)
         self.assertIn('name', updated_domain)
@@ -85,8 +81,7 @@
         self.assertEqual(new_desc, updated_domain['description'])
         self.assertEqual('true', str(updated_domain['enabled']).lower())
 
-        resp_3, fetched_domain = self.client.get_domain(domain['id'])
-        self.assertEqual(resp_3['status'], '200')
+        _, fetched_domain = self.client.get_domain(domain['id'])
         self.assertEqual(new_name, fetched_domain['name'])
         self.assertEqual(new_desc, fetched_domain['description'])
         self.assertEqual('true', str(fetched_domain['enabled']).lower())
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index 881f69e..1548f89 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -31,7 +31,7 @@
         s_name = data_utils.rand_name('service-')
         s_type = data_utils.rand_name('type--')
         s_description = data_utils.rand_name('description-')
-        resp, cls.service_data =\
+        _, cls.service_data =\
             cls.service_client.create_service(s_name, s_type,
                                               description=s_description)
         cls.service_id = cls.service_data['id']
@@ -108,7 +108,7 @@
         s_name = data_utils.rand_name('service-')
         s_type = data_utils.rand_name('type--')
         s_description = data_utils.rand_name('description-')
-        resp, service2 =\
+        _, service2 =\
             self.service_client.create_service(s_name, s_type,
                                                description=s_description)
         self.service_ids.append(service2['id'])
diff --git a/tempest/api/identity/admin/v3/test_endpoints_negative.py b/tempest/api/identity/admin/v3/test_endpoints_negative.py
index 5b46f89..1d63cce 100644
--- a/tempest/api/identity/admin/v3/test_endpoints_negative.py
+++ b/tempest/api/identity/admin/v3/test_endpoints_negative.py
@@ -33,7 +33,7 @@
         s_name = data_utils.rand_name('service-')
         s_type = data_utils.rand_name('type--')
         s_description = data_utils.rand_name('description-')
-        resp, cls.service_data = (
+        _, cls.service_data = (
             cls.service_client.create_service(s_name, s_type,
                                               description=s_description))
         cls.service_id = cls.service_data['id']
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 056f713..4d2cc46 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -29,24 +29,21 @@
     def test_group_create_update_get(self):
         name = data_utils.rand_name('Group')
         description = data_utils.rand_name('Description')
-        resp, group = self.client.create_group(name,
-                                               description=description)
+        _, group = self.client.create_group(name,
+                                            description=description)
         self.addCleanup(self.client.delete_group, group['id'])
-        self.assertEqual(resp['status'], '201')
         self.assertEqual(group['name'], name)
         self.assertEqual(group['description'], description)
 
         new_name = data_utils.rand_name('UpdateGroup')
         new_desc = data_utils.rand_name('UpdateDescription')
-        resp, updated_group = self.client.update_group(group['id'],
-                                                       name=new_name,
-                                                       description=new_desc)
-        self.assertEqual(resp['status'], '200')
+        _, updated_group = self.client.update_group(group['id'],
+                                                    name=new_name,
+                                                    description=new_desc)
         self.assertEqual(updated_group['name'], new_name)
         self.assertEqual(updated_group['description'], new_desc)
 
-        resp, new_group = self.client.get_group(group['id'])
-        self.assertEqual(resp['status'], '200')
+        _, new_group = self.client.get_group(group['id'])
         self.assertEqual(group['id'], new_group['id'])
         self.assertEqual(new_name, new_group['name'])
         self.assertEqual(new_desc, new_group['description'])
@@ -54,33 +51,31 @@
     @test.attr(type='smoke')
     def test_group_users_add_list_delete(self):
         name = data_utils.rand_name('Group')
-        resp, group = self.client.create_group(name)
+        _, group = self.client.create_group(name)
         self.addCleanup(self.client.delete_group, group['id'])
         # add user into group
         users = []
         for i in range(3):
             name = data_utils.rand_name('User')
-            resp, user = self.client.create_user(name)
+            _, user = self.client.create_user(name)
             users.append(user)
             self.addCleanup(self.client.delete_user, user['id'])
             self.client.add_group_user(group['id'], user['id'])
 
         # list users in group
-        resp, group_users = self.client.list_group_users(group['id'])
-        self.assertEqual(resp['status'], '200')
+        _, group_users = self.client.list_group_users(group['id'])
         self.assertEqual(sorted(users), sorted(group_users))
         # delete user in group
         for user in users:
-            resp, body = self.client.delete_group_user(group['id'],
-                                                       user['id'])
-            self.assertEqual(resp['status'], '204')
-        resp, group_users = self.client.list_group_users(group['id'])
+            self.client.delete_group_user(group['id'],
+                                          user['id'])
+        _, group_users = self.client.list_group_users(group['id'])
         self.assertEqual(len(group_users), 0)
 
     @test.attr(type='smoke')
     def test_list_user_groups(self):
         # create a user
-        resp, user = self.client.create_user(
+        _, user = self.client.create_user(
             data_utils.rand_name('User-'),
             password=data_utils.rand_name('Pass-'))
         self.addCleanup(self.client.delete_user, user['id'])
@@ -88,13 +83,12 @@
         groups = []
         for i in range(2):
             name = data_utils.rand_name('Group-')
-            resp, group = self.client.create_group(name)
+            _, group = self.client.create_group(name)
             groups.append(group)
             self.addCleanup(self.client.delete_group, group['id'])
             self.client.add_group_user(group['id'], user['id'])
         # list groups which user belongs to
-        resp, user_groups = self.client.list_user_groups(user['id'])
-        self.assertEqual('200', resp['status'])
+        _, user_groups = self.client.list_user_groups(user['id'])
         self.assertEqual(sorted(groups), sorted(user_groups))
         self.assertEqual(2, len(user_groups))
 
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index 79717b1..77acd57 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -25,8 +25,7 @@
     _interface = 'json'
 
     def _delete_project(self, project_id):
-        resp, _ = self.client.delete_project(project_id)
-        self.assertEqual(resp['status'], '204')
+        self.client.delete_project(project_id)
         self.assertRaises(
             exceptions.NotFound, self.client.get_project, project_id)
 
@@ -34,14 +33,13 @@
     def test_project_list_delete(self):
         # Create several projects and delete them
         for _ in moves.xrange(3):
-            resp, project = self.client.create_project(
+            _, project = self.client.create_project(
                 data_utils.rand_name('project-new'))
             self.addCleanup(self._delete_project, project['id'])
 
-        resp, list_projects = self.client.list_projects()
-        self.assertEqual(resp['status'], '200')
+        _, list_projects = self.client.list_projects()
 
-        resp, get_project = self.client.get_project(project['id'])
+        _, get_project = self.client.get_project(project['id'])
         self.assertIn(get_project, list_projects)
 
     @test.attr(type='gate')
@@ -49,16 +47,14 @@
         # Create project with a description
         project_name = data_utils.rand_name('project-')
         project_desc = data_utils.rand_name('desc-')
-        resp, project = self.client.create_project(
+        _, project = self.client.create_project(
             project_name, description=project_desc)
         self.data.projects.append(project)
-        st1 = resp['status']
         project_id = project['id']
         desc1 = project['description']
-        self.assertEqual(st1, '201')
         self.assertEqual(desc1, project_desc, 'Description should have '
                          'been sent in response for create')
-        resp, body = self.client.get_project(project_id)
+        _, body = self.client.get_project(project_id)
         desc2 = body['description']
         self.assertEqual(desc2, project_desc, 'Description does not appear'
                          'to be set')
@@ -67,15 +63,13 @@
     def test_project_create_enabled(self):
         # Create a project that is enabled
         project_name = data_utils.rand_name('project-')
-        resp, project = self.client.create_project(
+        _, project = self.client.create_project(
             project_name, enabled=True)
         self.data.projects.append(project)
         project_id = project['id']
-        st1 = resp['status']
         en1 = project['enabled']
-        self.assertEqual(st1, '201')
         self.assertTrue(en1, 'Enable should be True in response')
-        resp, body = self.client.get_project(project_id)
+        _, body = self.client.get_project(project_id)
         en2 = body['enabled']
         self.assertTrue(en2, 'Enable should be True in lookup')
 
@@ -83,15 +77,13 @@
     def test_project_create_not_enabled(self):
         # Create a project that is not enabled
         project_name = data_utils.rand_name('project-')
-        resp, project = self.client.create_project(
+        _, project = self.client.create_project(
             project_name, enabled=False)
         self.data.projects.append(project)
-        st1 = resp['status']
         en1 = project['enabled']
-        self.assertEqual(st1, '201')
         self.assertEqual('false', str(en1).lower(),
                          'Enable should be False in response')
-        resp, body = self.client.get_project(project['id'])
+        _, body = self.client.get_project(project['id'])
         en2 = body['enabled']
         self.assertEqual('false', str(en2).lower(),
                          'Enable should be False in lookup')
@@ -100,19 +92,17 @@
     def test_project_update_name(self):
         # Update name attribute of a project
         p_name1 = data_utils.rand_name('project-')
-        resp, project = self.client.create_project(p_name1)
+        _, project = self.client.create_project(p_name1)
         self.data.projects.append(project)
 
         resp1_name = project['name']
 
         p_name2 = data_utils.rand_name('project2-')
-        resp, body = self.client.update_project(project['id'], name=p_name2)
-        st2 = resp['status']
+        _, body = self.client.update_project(project['id'], name=p_name2)
         resp2_name = body['name']
-        self.assertEqual(st2, '200')
         self.assertNotEqual(resp1_name, resp2_name)
 
-        resp, body = self.client.get_project(project['id'])
+        _, body = self.client.get_project(project['id'])
         resp3_name = body['name']
 
         self.assertNotEqual(resp1_name, resp3_name)
@@ -124,20 +114,18 @@
         # Update description attribute of a project
         p_name = data_utils.rand_name('project-')
         p_desc = data_utils.rand_name('desc-')
-        resp, project = self.client.create_project(
+        _, project = self.client.create_project(
             p_name, description=p_desc)
         self.data.projects.append(project)
         resp1_desc = project['description']
 
         p_desc2 = data_utils.rand_name('desc2-')
-        resp, body = self.client.update_project(
+        _, body = self.client.update_project(
             project['id'], description=p_desc2)
-        st2 = resp['status']
         resp2_desc = body['description']
-        self.assertEqual(st2, '200')
         self.assertNotEqual(resp1_desc, resp2_desc)
 
-        resp, body = self.client.get_project(project['id'])
+        _, body = self.client.get_project(project['id'])
         resp3_desc = body['description']
 
         self.assertNotEqual(resp1_desc, resp3_desc)
@@ -149,20 +137,18 @@
         # Update the enabled attribute of a project
         p_name = data_utils.rand_name('project-')
         p_en = False
-        resp, project = self.client.create_project(p_name, enabled=p_en)
+        _, project = self.client.create_project(p_name, enabled=p_en)
         self.data.projects.append(project)
 
         resp1_en = project['enabled']
 
         p_en2 = True
-        resp, body = self.client.update_project(
+        _, body = self.client.update_project(
             project['id'], enabled=p_en2)
-        st2 = resp['status']
         resp2_en = body['enabled']
-        self.assertEqual(st2, '200')
         self.assertNotEqual(resp1_en, resp2_en)
 
-        resp, body = self.client.get_project(project['id'])
+        _, body = self.client.get_project(project['id'])
         resp3_en = body['enabled']
 
         self.assertNotEqual(resp1_en, resp3_en)
@@ -174,7 +160,7 @@
         # Associate a user to a project
         # Create a Project
         p_name = data_utils.rand_name('project-')
-        resp, project = self.client.create_project(p_name)
+        _, project = self.client.create_project(p_name)
         self.data.projects.append(project)
 
         # Create a User
@@ -182,15 +168,14 @@
         u_desc = u_name + 'description'
         u_email = u_name + '@testmail.tm'
         u_password = data_utils.rand_name('pass-')
-        resp, user = self.client.create_user(
+        _, user = self.client.create_user(
             u_name, description=u_desc, password=u_password,
             email=u_email, project_id=project['id'])
-        self.assertEqual(resp['status'], '201')
         # Delete the User at the end of this method
         self.addCleanup(self.client.delete_user, user['id'])
 
         # Get User To validate the user details
-        resp, new_user_get = self.client.get_user(user['id'])
+        _, new_user_get = self.client.get_user(user['id'])
         # Assert response body of GET
         self.assertEqual(u_name, new_user_get['name'])
         self.assertEqual(u_desc, new_user_get['description'])
diff --git a/tempest/api/identity/admin/v3/test_projects_negative.py b/tempest/api/identity/admin/v3/test_projects_negative.py
index 6b60d04..9e8f613 100644
--- a/tempest/api/identity/admin/v3/test_projects_negative.py
+++ b/tempest/api/identity/admin/v3/test_projects_negative.py
@@ -32,7 +32,7 @@
     def test_project_create_duplicate(self):
         # Project names should be unique
         project_name = data_utils.rand_name('project-dup-')
-        resp, project = self.client.create_project(project_name)
+        _, project = self.client.create_project(project_name)
         self.data.projects.append(project)
 
         self.assertRaises(
@@ -63,7 +63,7 @@
     def test_project_delete_by_unauthorized_user(self):
         # Non-admin user should not be able to delete a project
         project_name = data_utils.rand_name('project-')
-        resp, project = self.client.create_project(project_name)
+        _, project = self.client.create_project(project_name)
         self.data.projects.append(project)
         self.assertRaises(
             exceptions.Unauthorized, self.non_admin_client.delete_project,
diff --git a/tempest/api/identity/admin/v3/test_regions.py b/tempest/api/identity/admin/v3/test_regions.py
index 03974e4..c8b034f 100644
--- a/tempest/api/identity/admin/v3/test_regions.py
+++ b/tempest/api/identity/admin/v3/test_regions.py
@@ -1,4 +1,4 @@
-# Copyright 2014 OpenStack Foundation
+# Copyright 2014 Hewlett-Packard Development Company, L.P
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index b680b64..2e732fe 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -34,126 +34,108 @@
         u_desc = '%s description' % u_name
         u_email = '%s@testmail.tm' % u_name
         cls.u_password = data_utils.rand_name('pass-')
-        resp = [None] * 5
-        resp[0], cls.domain = cls.client.create_domain(
+        _, cls.domain = cls.client.create_domain(
             data_utils.rand_name('domain-'),
             description=data_utils.rand_name('domain-desc-'))
-        resp[1], cls.project = cls.client.create_project(
+        _, cls.project = cls.client.create_project(
             data_utils.rand_name('project-'),
             description=data_utils.rand_name('project-desc-'),
             domain_id=cls.domain['id'])
-        resp[2], cls.group_body = cls.client.create_group(
+        _, cls.group_body = cls.client.create_group(
             data_utils.rand_name('Group-'), project_id=cls.project['id'],
             domain_id=cls.domain['id'])
-        resp[3], cls.user_body = cls.client.create_user(
+        _, cls.user_body = cls.client.create_user(
             u_name, description=u_desc, password=cls.u_password,
             email=u_email, project_id=cls.project['id'],
             domain_id=cls.domain['id'])
-        resp[4], cls.role = cls.client.create_role(
+        _, cls.role = cls.client.create_role(
             data_utils.rand_name('Role-'))
-        for r in resp:
-            assert r['status'] == '201', (
-                "Expected 201, but got: %s" % r['status'])
 
     @classmethod
     def tearDownClass(cls):
-        resp = [None] * 5
-        resp[0], _ = cls.client.delete_role(cls.role['id'])
-        resp[1], _ = cls.client.delete_group(cls.group_body['id'])
-        resp[2], _ = cls.client.delete_user(cls.user_body['id'])
-        resp[3], _ = cls.client.delete_project(cls.project['id'])
+        cls.client.delete_role(cls.role['id'])
+        cls.client.delete_group(cls.group_body['id'])
+        cls.client.delete_user(cls.user_body['id'])
+        cls.client.delete_project(cls.project['id'])
         # NOTE(harika-vakadi): It is necessary to disable the domain
         # before deleting,or else it would result in unauthorized error
         cls.client.update_domain(cls.domain['id'], enabled=False)
-        resp[4], _ = cls.client.delete_domain(cls.domain['id'])
-        for r in resp:
-            assert r['status'] == '204', (
-                "Expected 204, but got: %s" % r['status'])
+        cls.client.delete_domain(cls.domain['id'])
         super(RolesV3TestJSON, cls).tearDownClass()
 
-    def _list_assertions(self, resp, body, fetched_role_ids, role_id):
-        self.assertEqual(resp['status'], '200')
+    def _list_assertions(self, body, fetched_role_ids, role_id):
         self.assertEqual(len(body), 1)
         self.assertIn(role_id, fetched_role_ids)
 
     @test.attr(type='smoke')
     def test_role_create_update_get_list(self):
         r_name = data_utils.rand_name('Role-')
-        resp, role = self.client.create_role(r_name)
+        _, role = self.client.create_role(r_name)
         self.addCleanup(self.client.delete_role, role['id'])
-        self.assertEqual(resp['status'], '201')
         self.assertIn('name', role)
         self.assertEqual(role['name'], r_name)
 
         new_name = data_utils.rand_name('NewRole-')
-        resp, updated_role = self.client.update_role(new_name, role['id'])
-        self.assertEqual(resp['status'], '200')
+        _, updated_role = self.client.update_role(new_name, role['id'])
         self.assertIn('name', updated_role)
         self.assertIn('id', updated_role)
         self.assertIn('links', updated_role)
         self.assertNotEqual(r_name, updated_role['name'])
 
-        resp, new_role = self.client.get_role(role['id'])
-        self.assertEqual(resp['status'], '200')
+        _, new_role = self.client.get_role(role['id'])
         self.assertEqual(new_name, new_role['name'])
         self.assertEqual(updated_role['id'], new_role['id'])
 
-        resp, roles = self.client.list_roles()
-        self.assertEqual(resp['status'], '200')
+        _, roles = self.client.list_roles()
         self.assertIn(role['id'], [r['id'] for r in roles])
 
     @test.attr(type='smoke')
     def test_grant_list_revoke_role_to_user_on_project(self):
-        resp, _ = self.client.assign_user_role_on_project(
+        self.client.assign_user_role_on_project(
             self.project['id'], self.user_body['id'], self.role['id'])
-        self.assertEqual(resp['status'], '204')
 
-        resp, roles = self.client.list_user_roles_on_project(
+        _, roles = self.client.list_user_roles_on_project(
             self.project['id'], self.user_body['id'])
 
         for i in roles:
             self.fetched_role_ids.append(i['id'])
 
-        self._list_assertions(resp, roles, self.fetched_role_ids,
+        self._list_assertions(roles, self.fetched_role_ids,
                               self.role['id'])
 
-        resp, _ = self.client.revoke_role_from_user_on_project(
+        self.client.revoke_role_from_user_on_project(
             self.project['id'], self.user_body['id'], self.role['id'])
-        self.assertEqual(resp['status'], '204')
 
     @test.attr(type='smoke')
     def test_grant_list_revoke_role_to_user_on_domain(self):
-        resp, _ = self.client.assign_user_role_on_domain(
+        self.client.assign_user_role_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
-        self.assertEqual(resp['status'], '204')
 
-        resp, roles = self.client.list_user_roles_on_domain(
+        _, roles = self.client.list_user_roles_on_domain(
             self.domain['id'], self.user_body['id'])
 
         for i in roles:
             self.fetched_role_ids.append(i['id'])
 
-        self._list_assertions(resp, roles, self.fetched_role_ids,
+        self._list_assertions(roles, self.fetched_role_ids,
                               self.role['id'])
 
-        resp, _ = self.client.revoke_role_from_user_on_domain(
+        self.client.revoke_role_from_user_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
-        self.assertEqual(resp['status'], '204')
 
     @test.attr(type='smoke')
     def test_grant_list_revoke_role_to_group_on_project(self):
         # Grant role to group on project
-        resp, _ = self.client.assign_group_role_on_project(
+        self.client.assign_group_role_on_project(
             self.project['id'], self.group_body['id'], self.role['id'])
-        self.assertEqual(resp['status'], '204')
         # List group roles on project
-        resp, roles = self.client.list_group_roles_on_project(
+        _, roles = self.client.list_group_roles_on_project(
             self.project['id'], self.group_body['id'])
 
         for i in roles:
             self.fetched_role_ids.append(i['id'])
 
-        self._list_assertions(resp, roles, self.fetched_role_ids,
+        self._list_assertions(roles, self.fetched_role_ids,
                               self.role['id'])
         # Add user to group, and insure user has role on project
         self.client.add_group_user(self.group_body['id'], self.user_body['id'])
@@ -167,34 +149,30 @@
         self.assertEqual(len(roles), 1)
         self.assertEqual(roles[0]['id'], self.role['id'])
         # Revoke role to group on project
-        resp, _ = self.client.revoke_role_from_group_on_project(
+        self.client.revoke_role_from_group_on_project(
             self.project['id'], self.group_body['id'], self.role['id'])
-        self.assertEqual(resp['status'], '204')
 
     @test.attr(type='smoke')
     def test_grant_list_revoke_role_to_group_on_domain(self):
-        resp, _ = self.client.assign_group_role_on_domain(
+        self.client.assign_group_role_on_domain(
             self.domain['id'], self.group_body['id'], self.role['id'])
-        self.assertEqual(resp['status'], '204')
 
-        resp, roles = self.client.list_group_roles_on_domain(
+        _, roles = self.client.list_group_roles_on_domain(
             self.domain['id'], self.group_body['id'])
 
         for i in roles:
             self.fetched_role_ids.append(i['id'])
 
-        self._list_assertions(resp, roles, self.fetched_role_ids,
+        self._list_assertions(roles, self.fetched_role_ids,
                               self.role['id'])
 
-        resp, _ = self.client.revoke_role_from_group_on_domain(
+        self.client.revoke_role_from_group_on_domain(
             self.domain['id'], self.group_body['id'], self.role['id'])
-        self.assertEqual(resp['status'], '204')
 
     @test.attr(type='gate')
     def test_list_roles(self):
         # Return a list of all roles
-        resp, body = self.client.list_roles()
-        self.assertEqual(200, resp.status)
+        _, body = self.client.list_roles()
         found = [role for role in body if role in self.data.v3_roles]
         self.assertEqual(len(found), len(self.data.v3_roles))
 
diff --git a/tempest/api/identity/admin/v3/test_services.py b/tempest/api/identity/admin/v3/test_services.py
index 36e5327..f6078da 100644
--- a/tempest/api/identity/admin/v3/test_services.py
+++ b/tempest/api/identity/admin/v3/test_services.py
@@ -28,9 +28,8 @@
         name = data_utils.rand_name('service-')
         serv_type = data_utils.rand_name('type--')
         desc = data_utils.rand_name('description-')
-        resp, body = self.service_client.create_service(name, serv_type,
-                                                        description=desc)
-        self.assertEqual('201', resp['status'])
+        _, body = self.service_client.create_service(name, serv_type,
+                                                     description=desc)
         # Deleting the service created in this method
         self.addCleanup(self.service_client.delete_service, body['id'])
 
@@ -38,14 +37,13 @@
         resp1_desc = body['description']
 
         s_desc2 = data_utils.rand_name('desc2-')
-        resp, body = self.service_client.update_service(
+        _, body = self.service_client.update_service(
             s_id, description=s_desc2)
         resp2_desc = body['description']
-        self.assertEqual('200', resp['status'])
         self.assertNotEqual(resp1_desc, resp2_desc)
 
         # Get service
-        resp, body = self.service_client.get_service(s_id)
+        _, body = self.service_client.get_service(s_id)
         resp3_desc = body['description']
 
         self.assertNotEqual(resp1_desc, resp3_desc)
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index fe3eb03..e61b738 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -30,23 +30,21 @@
         u_desc = '%s-description' % u_name
         u_email = '%s@testmail.tm' % u_name
         u_password = data_utils.rand_name('pass-')
-        resp, user = self.client.create_user(
+        _, user = self.client.create_user(
             u_name, description=u_desc, password=u_password,
             email=u_email)
-        self.assertEqual(201, resp.status)
         self.addCleanup(self.client.delete_user, user['id'])
         # Perform Authentication
         resp, body = self.token.auth(user['id'], u_password)
         self.assertEqual(201, resp.status)
         subject_token = resp['x-subject-token']
         # Perform GET Token
-        resp, token_details = self.client.get_token(subject_token)
-        self.assertEqual(200, resp.status)
+        _, 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)
         # Perform Delete Token
-        resp, _ = self.client.delete_token(subject_token)
+        self.client.delete_token(subject_token)
         self.assertRaises(exceptions.NotFound, self.client.get_token,
                           subject_token)
 
@@ -63,35 +61,29 @@
         # Create a user.
         user_name = data_utils.rand_name(name='user-')
         user_password = data_utils.rand_name(name='pass-')
-        resp, user = self.client.create_user(user_name, password=user_password)
-        self.assertEqual(201, resp.status)
+        _, user = self.client.create_user(user_name, password=user_password)
         self.addCleanup(self.client.delete_user, user['id'])
 
         # Create a couple projects
         project1_name = data_utils.rand_name(name='project-')
-        resp, project1 = self.client.create_project(project1_name)
-        self.assertEqual(201, resp.status)
+        _, project1 = self.client.create_project(project1_name)
         self.addCleanup(self.client.delete_project, project1['id'])
 
         project2_name = data_utils.rand_name(name='project-')
-        resp, project2 = self.client.create_project(project2_name)
-        self.assertEqual(201, resp.status)
+        _, project2 = self.client.create_project(project2_name)
         self.addCleanup(self.client.delete_project, project2['id'])
 
         # Create a role
         role_name = data_utils.rand_name(name='role-')
-        resp, role = self.client.create_role(role_name)
-        self.assertEqual(201, resp.status)
+        _, role = self.client.create_role(role_name)
         self.addCleanup(self.client.delete_role, role['id'])
 
         # Grant the user the role on both projects.
-        resp, _ = self.client.assign_user_role(project1['id'], user['id'],
-                                               role['id'])
-        self.assertEqual(204, resp.status)
+        self.client.assign_user_role(project1['id'], user['id'],
+                                     role['id'])
 
-        resp, _ = self.client.assign_user_role(project2['id'], user['id'],
-                                               role['id'])
-        self.assertEqual(204, resp.status)
+        self.client.assign_user_role(project2['id'], user['id'],
+                                     role['id'])
 
         # Get an unscoped token.
         resp, token_auth = self.token.auth(user=user['id'],
@@ -145,8 +137,7 @@
         self.assertEqual(role['name'], token_auth['token']['roles'][0]['name'])
 
         # Revoke the unscoped token.
-        resp, _ = self.client.delete_token(token1_id)
-        self.assertEqual(204, resp.status)
+        self.client.delete_token(token1_id)
 
         # Now get another scoped token using the unscoped token.
         resp, token_auth = self.token.auth(token=token_id,
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index ac5efa1..fed5171 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -54,25 +54,22 @@
         u_desc = self.trustor_username + 'description'
         u_email = self.trustor_username + '@testmail.xx'
         self.trustor_password = data_utils.rand_name('pass-')
-        resp, user = self.client.create_user(
+        _, user = self.client.create_user(
             self.trustor_username,
             description=u_desc,
             password=self.trustor_password,
             email=u_email,
             project_id=self.trustor_project_id)
-        self.assertEqual(resp['status'], '201')
         self.trustor_user_id = user['id']
 
         # And two roles, one we'll delegate and one we won't
         self.delegated_role = data_utils.rand_name('DelegatedRole-')
         self.not_delegated_role = data_utils.rand_name('NotDelegatedRole-')
 
-        resp, role = self.client.create_role(self.delegated_role)
-        self.assertEqual(resp['status'], '201')
+        _, role = self.client.create_role(self.delegated_role)
         self.delegated_role_id = role['id']
 
-        resp, role = self.client.create_role(self.not_delegated_role)
-        self.assertEqual(resp['status'], '201')
+        _, role = self.client.create_role(self.not_delegated_role)
         self.not_delegated_role_id = role['id']
 
         # Assign roles to trustor
@@ -108,14 +105,13 @@
 
     def create_trust(self, impersonate=True, expires=None):
 
-        resp, trust_create = self.trustor_client.create_trust(
+        _, trust_create = self.trustor_client.create_trust(
             trustor_user_id=self.trustor_user_id,
             trustee_user_id=self.trustee_user_id,
             project_id=self.trustor_project_id,
             role_names=[self.delegated_role],
             impersonation=impersonate,
             expires_at=expires)
-        self.assertEqual('201', resp['status'])
         self.trust_id = trust_create['id']
         return trust_create
 
@@ -141,8 +137,7 @@
             self.assertEqual(1, len(trust['roles']))
 
     def get_trust(self):
-        resp, trust_get = self.trustor_client.get_trust(self.trust_id)
-        self.assertEqual('200', resp['status'])
+        _, trust_get = self.trustor_client.get_trust(self.trust_id)
         return trust_get
 
     def validate_role(self, role):
@@ -158,20 +153,23 @@
     @test.skip_because(bug='1334368')
     def check_trust_roles(self):
         # Check we find the delegated role
-        resp, roles_get = self.trustor_client.get_trust_roles(
+        _, roles_get = self.trustor_client.get_trust_roles(
             self.trust_id)
-        self.assertEqual('200', resp['status'])
         self.assertEqual(1, len(roles_get))
         self.validate_role(roles_get[0])
 
-        resp, role_get = self.trustor_client.get_trust_role(
+        _, role_get = self.trustor_client.get_trust_role(
             self.trust_id, self.delegated_role_id)
-        self.assertEqual('200', resp['status'])
         self.validate_role(role_get)
 
-        resp, role_get = self.trustor_client.check_trust_role(
+        _, role_get = self.trustor_client.check_trust_role(
             self.trust_id, self.delegated_role_id)
-        self.assertEqual('200', resp['status'])
+        # 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,
@@ -185,8 +183,7 @@
                           self.not_delegated_role_id)
 
     def delete_trust(self):
-        resp, trust_delete = self.trustor_client.delete_trust(self.trust_id)
-        self.assertEqual('204', resp['status'])
+        self.trustor_client.delete_trust(self.trust_id)
         self.assertRaises(exceptions.NotFound,
                           self.trustor_client.get_trust,
                           self.trust_id)
@@ -254,17 +251,15 @@
     @test.attr(type='smoke')
     def test_get_trusts_query(self):
         self.create_trust()
-        resp, trusts_get = self.trustor_client.get_trusts(
+        _, trusts_get = self.trustor_client.get_trusts(
             trustor_user_id=self.trustor_user_id)
-        self.assertEqual('200', resp['status'])
         self.assertEqual(1, len(trusts_get))
         self.validate_trust(trusts_get[0], summary=True)
 
     @test.attr(type='smoke')
     def test_get_trusts_all(self):
         self.create_trust()
-        resp, trusts_get = self.client.get_trusts()
-        self.assertEqual('200', resp['status'])
+        _, trusts_get = self.client.get_trusts()
         trusts = [t for t in trusts_get
                   if t['id'] == self.trust_id]
         self.assertEqual(1, len(trusts))
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index 7316c7f..558575e 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -29,13 +29,13 @@
         u_desc = u_name + 'description'
         u_email = u_name + '@testmail.tm'
         u_password = data_utils.rand_name('pass-')
-        resp, user = self.client.create_user(
+        _, user = self.client.create_user(
             u_name, description=u_desc, password=u_password,
             email=u_email, enabled=False)
         # Delete the User at the end of this method
         self.addCleanup(self.client.delete_user, user['id'])
         # Creating second project for updation
-        resp, project = self.client.create_project(
+        _, project = self.client.create_project(
             data_utils.rand_name('project-'),
             description=data_utils.rand_name('project-desc-'))
         # Delete the Project at the end of this method
@@ -44,12 +44,10 @@
         u_name2 = data_utils.rand_name('user2-')
         u_email2 = u_name2 + '@testmail.tm'
         u_description2 = u_name2 + ' description'
-        resp, update_user = self.client.update_user(
+        _, update_user = self.client.update_user(
             user['id'], name=u_name2, description=u_description2,
             project_id=project['id'],
             email=u_email2, enabled=False)
-        # Assert response body of update user.
-        self.assertEqual(200, resp.status)
         self.assertEqual(u_name2, update_user['name'])
         self.assertEqual(u_description2, update_user['description'])
         self.assertEqual(project['id'],
@@ -57,7 +55,7 @@
         self.assertEqual(u_email2, update_user['email'])
         self.assertEqual('false', str(update_user['enabled']).lower())
         # GET by id after updation
-        resp, new_user_get = self.client.get_user(user['id'])
+        _, new_user_get = self.client.get_user(user['id'])
         # Assert response body of GET after updation
         self.assertEqual(u_name2, new_user_get['name'])
         self.assertEqual(u_description2, new_user_get['description'])
@@ -107,8 +105,7 @@
                                          user['id'],
                                          role['id'])
             assigned_project_ids.append(project['id'])
-        resp, body = self.client.list_user_projects(user['id'])
-        self.assertEqual(200, resp.status)
+        _, body = self.client.list_user_projects(user['id'])
         for i in body:
             fetched_project_ids.append(i['id'])
         # verifying the project ids in list
@@ -124,7 +121,7 @@
     def test_get_user(self):
         # Get a user detail
         self.data.setup_test_v3_user()
-        resp, user = self.client.get_user(self.data.v3_user['id'])
+        _, user = self.client.get_user(self.data.v3_user['id'])
         self.assertEqual(self.data.v3_user['id'], user['id'])
 
 
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 697057f..0991576 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -136,17 +136,17 @@
             self.test_user = data_utils.rand_name('test_user_')
             self.test_password = data_utils.rand_name('pass_')
             self.test_email = self.test_user + '@testmail.tm'
-            resp, self.user = self.client.create_user(self.test_user,
-                                                      self.test_password,
-                                                      self.tenant['id'],
-                                                      self.test_email)
+            _, self.user = self.client.create_user(self.test_user,
+                                                   self.test_password,
+                                                   self.tenant['id'],
+                                                   self.test_email)
             self.users.append(self.user)
 
         def setup_test_tenant(self):
             """Set up a test tenant."""
             self.test_tenant = data_utils.rand_name('test_tenant_')
             self.test_description = data_utils.rand_name('desc_')
-            resp, self.tenant = self.client.create_tenant(
+            _, self.tenant = self.client.create_tenant(
                 name=self.test_tenant,
                 description=self.test_description)
             self.tenants.append(self.tenant)
@@ -154,7 +154,7 @@
         def setup_test_role(self):
             """Set up a test role."""
             self.test_role = data_utils.rand_name('role')
-            resp, self.role = self.client.create_role(self.test_role)
+            _, self.role = self.client.create_role(self.test_role)
             self.roles.append(self.role)
 
         def setup_test_v3_user(self):
@@ -163,7 +163,7 @@
             self.test_user = data_utils.rand_name('test_user_')
             self.test_password = data_utils.rand_name('pass_')
             self.test_email = self.test_user + '@testmail.tm'
-            resp, self.v3_user = self.client.create_user(
+            _, self.v3_user = self.client.create_user(
                 self.test_user,
                 password=self.test_password,
                 project_id=self.project['id'],
@@ -174,7 +174,7 @@
             """Set up a test project."""
             self.test_project = data_utils.rand_name('test_project_')
             self.test_description = data_utils.rand_name('desc_')
-            resp, self.project = self.client.create_project(
+            _, self.project = self.client.create_project(
                 name=self.test_project,
                 description=self.test_description)
             self.projects.append(self.project)
@@ -182,7 +182,7 @@
         def setup_test_v3_role(self):
             """Set up a test v3 role."""
             self.test_role = data_utils.rand_name('role')
-            resp, self.v3_role = self.client.create_role(self.test_role)
+            _, self.v3_role = self.client.create_role(self.test_role)
             self.v3_roles.append(self.v3_role)
 
         def teardown_all(self):
diff --git a/tempest/api/identity/test_extension.py b/tempest/api/identity/test_extension.py
index 67f20f4..a06ee53 100644
--- a/tempest/api/identity/test_extension.py
+++ b/tempest/api/identity/test_extension.py
@@ -23,8 +23,7 @@
     @test.attr(type='gate')
     def test_list_extensions(self):
         # List all the extensions
-        resp, body = self.non_admin_client.list_extensions()
-        self.assertEqual(200, resp.status)
+        _, body = self.non_admin_client.list_extensions()
         self.assertNotEmpty(body)
         keys = ['name', 'updated', 'alias', 'links',
                 'namespace', 'description']
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_schema/compute/servers.py b/tempest/api_schema/compute/servers.py
index ad0aa29..6b27f3d 100644
--- a/tempest/api_schema/compute/servers.py
+++ b/tempest/api_schema/compute/servers.py
@@ -48,50 +48,52 @@
     }
 }
 
+common_show_server = {
+    'type': 'object',
+    'properties': {
+        'id': {'type': 'string'},
+        'name': {'type': 'string'},
+        'status': {'type': 'string'},
+        'image': {
+            'type': 'object',
+            'properties': {
+                'id': {'type': 'string'},
+                'links': parameter_types.links
+            },
+            'required': ['id', 'links']
+        },
+        'flavor': {
+            'type': 'object',
+            'properties': {
+                'id': {'type': 'string'},
+                'links': parameter_types.links
+            },
+            'required': ['id', 'links']
+        },
+        'user_id': {'type': 'string'},
+        'tenant_id': {'type': 'string'},
+        'created': {'type': 'string'},
+        'updated': {'type': 'string'},
+        'progress': {'type': 'integer'},
+        'metadata': {'type': 'object'},
+        'links': parameter_types.links,
+        'addresses': parameter_types.addresses,
+    },
+    # NOTE(GMann): 'progress' attribute is present in the response
+    # only when server's status is one of the progress statuses
+    # ("ACTIVE","BUILD", "REBUILD", "RESIZE","VERIFY_RESIZE")
+    # So it is not defined as 'required'.
+    'required': ['id', 'name', 'status', 'image', 'flavor',
+                 'user_id', 'tenant_id', 'created', 'updated',
+                 'metadata', 'links', 'addresses']
+}
+
 base_update_get_server = {
     'status_code': [200],
     'response_body': {
         'type': 'object',
         'properties': {
-            'server': {
-                'type': 'object',
-                'properties': {
-                    'id': {'type': 'string'},
-                    'name': {'type': 'string'},
-                    'status': {'type': 'string'},
-                    'image': {
-                        'type': 'object',
-                        'properties': {
-                            'id': {'type': 'string'},
-                            'links': parameter_types.links
-                        },
-                        'required': ['id', 'links']
-                    },
-                    'flavor': {
-                        'type': 'object',
-                        'properties': {
-                            'id': {'type': 'string'},
-                            'links': parameter_types.links
-                        },
-                        'required': ['id', 'links']
-                    },
-                    'user_id': {'type': 'string'},
-                    'tenant_id': {'type': 'string'},
-                    'created': {'type': 'string'},
-                    'updated': {'type': 'string'},
-                    'progress': {'type': 'integer'},
-                    'metadata': {'type': 'object'},
-                    'links': parameter_types.links,
-                    'addresses': parameter_types.addresses,
-                },
-                # NOTE(GMann): 'progress' attribute is present in the response
-                # only when server's status is one of the progress statuses
-                # ("ACTIVE","BUILD", "REBUILD", "RESIZE","VERIFY_RESIZE")
-                # So it is not defined as 'required'.
-                'required': ['id', 'name', 'status', 'image', 'flavor',
-                             'user_id', 'tenant_id', 'created', 'updated',
-                             'metadata', 'links', 'addresses']
-            }
+            'server': common_show_server
         },
         'required': ['server']
     }
@@ -179,3 +181,17 @@
     'required': ['action', 'request_id', 'user_id', 'project_id',
                  'start_time', 'message']
 }
+
+base_list_servers_detail = {
+    'status_code': [200],
+    'response_body': {
+        'type': 'object',
+        'properties': {
+            'servers': {
+                'type': 'array',
+                'items': common_show_server
+            }
+        },
+        'required': ['servers']
+    }
+}
diff --git a/tempest/api_schema/compute/v2/servers.py b/tempest/api_schema/compute/v2/servers.py
index dc4054c..cd46f9b 100644
--- a/tempest/api_schema/compute/v2/servers.py
+++ b/tempest/api_schema/compute/v2/servers.py
@@ -240,3 +240,17 @@
         'required': ['instanceActions']
     }
 }
+
+list_servers_detail = copy.deepcopy(servers.base_list_servers_detail)
+list_servers_detail['response_body']['properties']['servers']['items'][
+    'properties'].update({
+        'hostId': {'type': 'string'},
+        'OS-DCF:diskConfig': {'type': 'string'},
+        'accessIPv4': parameter_types.access_ip_v4,
+        'accessIPv6': parameter_types.access_ip_v6
+    })
+# NOTE(GMann): OS-DCF:diskConfig and accessIPv4/v6 are API
+# extensions, and some environments return a response
+# without these attributes. So they are not 'required'.
+list_servers_detail['response_body']['properties']['servers']['items'][
+    'required'].append('hostId')
diff --git a/tempest/api_schema/compute/v3/servers.py b/tempest/api_schema/compute/v3/servers.py
index 3b50516..b6cb13b 100644
--- a/tempest/api_schema/compute/v3/servers.py
+++ b/tempest/api_schema/compute/v3/servers.py
@@ -151,3 +151,17 @@
         'required': ['server_actions']
     }
 }
+
+list_servers_detail = copy.deepcopy(servers.base_list_servers_detail)
+list_servers_detail['response_body']['properties']['servers']['items'][
+    'properties'].update({
+        'addresses': addresses_v3,
+        'host_id': {'type': 'string'},
+        'os-access-ips:access_ip_v4': parameter_types.access_ip_v4,
+        'os-access-ips:access_ip_v6': parameter_types.access_ip_v6
+    })
+# NOTE(GMann): os-access-ips:access_ip_v4/v6 are API extension,
+# and some environments return a response without these
+# attributes. So they are not 'required'.
+list_servers_detail['response_body']['properties']['servers']['items'][
+    'required'].append('host_id')
diff --git a/tempest/cli/__init__.py b/tempest/cli/__init__.py
index 0571f4f..ba94c82 100644
--- a/tempest/cli/__init__.py
+++ b/tempest/cli/__init__.py
@@ -95,14 +95,15 @@
         return self.cmd_with_auth(
             'neutron', action, flags, params, admin, fail_ok)
 
-    def sahara(self, action, flags='', params='', admin=True, fail_ok=False):
+    def sahara(self, action, flags='', params='', admin=True,
+               fail_ok=False, merge_stderr=True):
         """Executes sahara command for the given action."""
         flags += ' --endpoint-type %s' % CONF.data_processing.endpoint_type
         return self.cmd_with_auth(
-            'sahara', action, flags, params, admin, fail_ok)
+            'sahara', action, flags, params, admin, fail_ok, merge_stderr)
 
     def cmd_with_auth(self, cmd, action, flags='', params='',
-                      admin=True, fail_ok=False):
+                      admin=True, fail_ok=False, merge_stderr=False):
         """Executes given command with auth attributes appended."""
         # TODO(jogo) make admin=False work
         creds = ('--os-username %s --os-tenant-name %s --os-password %s '
@@ -112,7 +113,7 @@
                   CONF.identity.admin_password,
                   CONF.identity.uri))
         flags = creds + ' ' + flags
-        return self.cmd(cmd, action, flags, params, fail_ok)
+        return self.cmd(cmd, action, flags, params, fail_ok, merge_stderr)
 
     def cmd(self, cmd, action, flags='', params='', fail_ok=False,
             merge_stderr=False):
@@ -120,7 +121,7 @@
         cmd = ' '.join([os.path.join(CONF.cli.cli_dir, cmd),
                         flags, action, params])
         LOG.info("running: '%s'" % cmd)
-        cmd = shlex.split(cmd)
+        cmd = shlex.split(cmd.encode('utf-8'))
         result = ''
         result_err = ''
         stdout = subprocess.PIPE
diff --git a/tempest/cli/simple_read_only/test_sahara.py b/tempest/cli/simple_read_only/test_sahara.py
index 36cc324..f00dcae 100644
--- a/tempest/cli/simple_read_only/test_sahara.py
+++ b/tempest/cli/simple_read_only/test_sahara.py
@@ -12,8 +12,8 @@
 # implied.
 # See the License for the specific language governing permissions and
 # limitations under the License.
-
 import logging
+import re
 import subprocess
 
 from tempest import cli
@@ -138,3 +138,30 @@
             'cluster_id',
             'status'
         ])
+
+    def test_sahara_bash_completion(self):
+        self.sahara('bash-completion')
+
+    # Optional arguments
+    def test_sahara_help(self):
+        help_text = self.sahara('help')
+        lines = help_text.split('\n')
+        self.assertFirstLineStartsWith(lines, 'usage: sahara')
+
+        commands = []
+        cmds_start = lines.index('Positional arguments:')
+        cmds_end = lines.index('Optional arguments:')
+        command_pattern = re.compile('^ {4}([a-z0-9\-\_]+)')
+        for line in lines[cmds_start:cmds_end]:
+            match = command_pattern.match(line)
+            if match:
+                commands.append(match.group(1))
+        commands = set(commands)
+        wanted_commands = set(('cluster-create', 'data-source-create',
+                               'image-unregister', 'job-binary-create',
+                               'plugin-list', 'job-binary-create', 'help'))
+        self.assertFalse(wanted_commands - commands)
+
+    def test_sahara_version(self):
+        version = self.sahara('', flags='--version')
+        self.assertTrue(re.search('[0-9.]+', version))
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 1d46028..0b72b1c 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -169,7 +169,7 @@
 
 def collect_users(users):
     global USERS
-    LOG.info("Creating users")
+    LOG.info("Collecting users")
     admin = keystone_admin()
     for u in users:
         tenant = admin.identity.get_tenant_by_name(u['tenant'])
@@ -192,7 +192,9 @@
         self.check_users()
         self.check_objects()
         self.check_servers()
-        self.check_volumes()
+        # TODO(sdague): Volumes not yet working, bring it back once the
+        # code is self testing.
+        # self.check_volumes()
 
     def check_users(self):
         """Check that the users we expect to exist, do.
@@ -200,6 +202,7 @@
         We don't use the resource list for this because we need to validate
         that things like tenantId didn't drift across versions.
         """
+        LOG.info("checking users")
         for name, user in self.users.iteritems():
             client = keystone_admin()
             _, found = client.identity.get_user(user['id'])
@@ -215,6 +218,7 @@
 
     def check_objects(self):
         """Check that the objects created are still there."""
+        LOG.info("checking objects")
         for obj in self.res['objects']:
             client = client_for_user(obj['owner'])
             r, contents = client.objects.get_object(
@@ -224,6 +228,7 @@
 
     def check_servers(self):
         """Check that the servers are still up and running."""
+        LOG.info("checking servers")
         for server in self.res['servers']:
             client = client_for_user(server['owner'])
             found = _get_server_by_name(client, server['name'])
@@ -240,6 +245,7 @@
 
     def check_volumes(self):
         """Check that the volumes are still there and attached."""
+        LOG.info("checking volumes")
         for volume in self.res['volumes']:
             client = client_for_user(volume['owner'])
             found = _get_volume_by_name(client, volume['name'])
@@ -284,6 +290,12 @@
 #######################
 
 
+def _resolve_image(image, imgtype):
+    name = image[imgtype]
+    fname = os.path.join(OPTS.devstack_base, image['imgdir'], name)
+    return name, fname
+
+
 def create_images(images):
     for image in images:
         client = client_for_user(image['owner'])
@@ -297,20 +309,23 @@
         # special handling for 3 part image
         extras = {}
         if image['format'] == 'ami':
+            name, fname = _resolve_image(image, 'aki')
             r, aki = client.images.create_image(
-                'javelin_' + image['aki'], 'aki', 'aki')
-            client.images.store_image(aki.get('id'), open(image['aki'], 'r'))
+                'javelin_' + name, 'aki', 'aki')
+            client.images.store_image(aki.get('id'), open(fname, 'r'))
             extras['kernel_id'] = aki.get('id')
 
+            name, fname = _resolve_image(image, 'ari')
             r, ari = client.images.create_image(
-                'javelin_' + image['ari'], 'ari', 'ari')
-            client.images.store_image(ari.get('id'), open(image['ari'], 'r'))
+                'javelin_' + name, 'ari', 'ari')
+            client.images.store_image(ari.get('id'), open(fname, 'r'))
             extras['ramdisk_id'] = ari.get('id')
 
+        _, fname = _resolve_image(image, 'file')
         r, body = client.images.create_image(
             image['name'], image['format'], image['format'], **extras)
         image_id = body.get('id')
-        client.images.store_image(image_id, open(image['file'], 'r'))
+        client.images.store_image(image_id, open(fname, 'r'))
 
 
 #######################
@@ -407,8 +422,10 @@
     create_objects(RES['objects'])
     create_images(RES['images'])
     create_servers(RES['servers'])
-    create_volumes(RES['volumes'])
-    attach_volumes(RES['volumes'])
+    # TODO(sdague): volumes definition doesn't work yet, bring it
+    # back once we're actually executing the code
+    # create_volumes(RES['volumes'])
+    # attach_volumes(RES['volumes'])
 
 
 def get_options():
@@ -423,6 +440,11 @@
                         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')
     # auth bits, letting us also just source the devstack openrc
     parser.add_argument('--os-username',
                         metavar='<auth-user-name>',
diff --git a/tempest/cmd/resources.yaml b/tempest/cmd/resources.yaml
index a1f567b..3450e1f 100644
--- a/tempest/cmd/resources.yaml
+++ b/tempest/cmd/resources.yaml
@@ -27,6 +27,7 @@
 images:
   - name: javelin_cirros
     owner: javelin
+    imgdir: files/images/cirros-0.3.2-x86_64-uec
     file: cirros-0.3.2-x86_64-blank.img
     format: ami
     aki: cirros-0.3.2-x86_64-vmlinuz
diff --git a/tempest/common/commands.py b/tempest/common/commands.py
index 2ab008d..6583475 100644
--- a/tempest/common/commands.py
+++ b/tempest/common/commands.py
@@ -25,7 +25,7 @@
 
 
 def sudo_cmd_call(cmd):
-    args = shlex.split(cmd)
+    args = shlex.split(cmd.encode('utf-8'))
     subprocess_args = {'stdout': subprocess.PIPE,
                        'stderr': subprocess.STDOUT}
     proc = subprocess.Popen(['/usr/bin/sudo', '-n'] + args,
@@ -84,7 +84,7 @@
           "-i %(pkey)s %(file1)s %(dest)s" % {'pkey': pkey,
                                               'file1': file_from,
                                               'dest': dest}
-    args = shlex.split(cmd)
+    args = shlex.split(cmd.encode('utf-8'))
     subprocess_args = {'stdout': subprocess.PIPE,
                        'stderr': subprocess.STDOUT}
     proc = subprocess.Popen(args, **subprocess_args)
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index 8166de5..208f42f 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -57,7 +57,7 @@
 
     def _create_tenant(self, name, description):
         if self.tempest_client:
-            resp, tenant = self.identity_admin_client.create_tenant(
+            _, tenant = self.identity_admin_client.create_tenant(
                 name=name, description=description)
         else:
             tenant = self.identity_admin_client.tenants.create(
@@ -67,7 +67,7 @@
 
     def _get_tenant_by_name(self, name):
         if self.tempest_client:
-            resp, tenant = self.identity_admin_client.get_tenant_by_name(name)
+            _, tenant = self.identity_admin_client.get_tenant_by_name(name)
         else:
             tenants = self.identity_admin_client.tenants.list()
             for ten in tenants:
@@ -80,10 +80,10 @@
 
     def _create_user(self, username, password, tenant, email):
         if self.tempest_client:
-            resp, user = self.identity_admin_client.create_user(username,
-                                                                password,
-                                                                tenant['id'],
-                                                                email)
+            _, user = self.identity_admin_client.create_user(username,
+                                                             password,
+                                                             tenant['id'],
+                                                             email)
         else:
             user = self.identity_admin_client.users.create(username, password,
                                                            email,
@@ -92,7 +92,7 @@
 
     def _get_user(self, tenant, username):
         if self.tempest_client:
-            resp, user = self.identity_admin_client.get_user_by_username(
+            _, user = self.identity_admin_client.get_user_by_username(
                 tenant['id'],
                 username)
         else:
@@ -101,7 +101,7 @@
 
     def _list_roles(self):
         if self.tempest_client:
-            resp, roles = self.identity_admin_client.list_roles()
+            _, roles = self.identity_admin_client.list_roles()
         else:
             roles = self.identity_admin_client.roles.list()
         return roles
diff --git a/tempest/openstack/common/gettextutils.py b/tempest/openstack/common/gettextutils.py
index 6102e67..872d58e 100644
--- a/tempest/openstack/common/gettextutils.py
+++ b/tempest/openstack/common/gettextutils.py
@@ -23,7 +23,6 @@
 """
 
 import copy
-import functools
 import gettext
 import locale
 from logging import handlers
@@ -42,7 +41,7 @@
     """Create translator functions
     """
 
-    def __init__(self, domain, lazy=False, localedir=None):
+    def __init__(self, domain, localedir=None):
         """Establish a set of translation functions for the domain.
 
         :param domain: Name of translation domain,
@@ -55,7 +54,6 @@
         :type localedir: str
         """
         self.domain = domain
-        self.lazy = lazy
         if localedir is None:
             localedir = os.environ.get(domain.upper() + '_LOCALEDIR')
         self.localedir = localedir
@@ -75,16 +73,19 @@
         """
         if domain is None:
             domain = self.domain
-        if self.lazy:
-            return functools.partial(Message, domain=domain)
-        t = gettext.translation(
-            domain,
-            localedir=self.localedir,
-            fallback=True,
-        )
-        if six.PY3:
-            return t.gettext
-        return t.ugettext
+        t = gettext.translation(domain,
+                                localedir=self.localedir,
+                                fallback=True)
+        # Use the appropriate method of the translation object based
+        # on the python version.
+        m = t.gettext if six.PY3 else t.ugettext
+
+        def f(msg):
+            """oslo.i18n.gettextutils translation function."""
+            if USE_LAZY:
+                return Message(msg, domain=domain)
+            return m(msg)
+        return f
 
     @property
     def primary(self):
@@ -147,19 +148,11 @@
     your project is importing _ directly instead of using the
     gettextutils.install() way of importing the _ function.
     """
-    # FIXME(dhellmann): This function will be removed in oslo.i18n,
-    # because the TranslatorFactory makes it superfluous.
-    global _, _LI, _LW, _LE, _LC, USE_LAZY
-    tf = TranslatorFactory('tempest', lazy=True)
-    _ = tf.primary
-    _LI = tf.log_info
-    _LW = tf.log_warning
-    _LE = tf.log_error
-    _LC = tf.log_critical
+    global USE_LAZY
     USE_LAZY = True
 
 
-def install(domain, lazy=False):
+def install(domain):
     """Install a _() function using the given translation domain.
 
     Given a translation domain, install a _() function using gettext's
@@ -170,26 +163,14 @@
     a translation-domain-specific environment variable (e.g.
     NOVA_LOCALEDIR).
 
+    Note that to enable lazy translation, enable_lazy must be
+    called.
+
     :param domain: the translation domain
-    :param lazy: indicates whether or not to install the lazy _() function.
-                 The lazy _() introduces a way to do deferred translation
-                 of messages by installing a _ that builds Message objects,
-                 instead of strings, which can then be lazily translated into
-                 any available locale.
     """
-    if lazy:
-        from six import moves
-        tf = TranslatorFactory(domain, lazy=True)
-        moves.builtins.__dict__['_'] = tf.primary
-    else:
-        localedir = '%s_LOCALEDIR' % domain.upper()
-        if six.PY3:
-            gettext.install(domain,
-                            localedir=os.environ.get(localedir))
-        else:
-            gettext.install(domain,
-                            localedir=os.environ.get(localedir),
-                            unicode=True)
+    from six import moves
+    tf = TranslatorFactory(domain)
+    moves.builtins.__dict__['_'] = tf.primary
 
 
 class Message(six.text_type):
@@ -373,8 +354,8 @@
                'zh_Hant_HK': 'zh_HK',
                'zh_Hant': 'zh_TW',
                'fil': 'tl_PH'}
-    for (locale, alias) in six.iteritems(aliases):
-        if locale in language_list and alias not in language_list:
+    for (locale_, alias) in six.iteritems(aliases):
+        if locale_ in language_list and alias not in language_list:
             language_list.append(alias)
 
     _AVAILABLE_LANGUAGES[domain] = language_list
diff --git a/tempest/openstack/common/jsonutils.py b/tempest/openstack/common/jsonutils.py
index 53c0ad4..cb83557 100644
--- a/tempest/openstack/common/jsonutils.py
+++ b/tempest/openstack/common/jsonutils.py
@@ -31,25 +31,29 @@
 '''
 
 
+import codecs
 import datetime
 import functools
 import inspect
 import itertools
-import json
-try:
-    import xmlrpclib
-except ImportError:
-    # NOTE(jaypipes): xmlrpclib was renamed to xmlrpc.client in Python3
-    #                 however the function and object call signatures
-    #                 remained the same. This whole try/except block should
-    #                 be removed and replaced with a call to six.moves once
-    #                 six 1.4.2 is released. See http://bit.ly/1bqrVzu
-    import xmlrpc.client as xmlrpclib
+import sys
+
+if sys.version_info < (2, 7):
+    # On Python <= 2.6, json module is not C boosted, so try to use
+    # simplejson module if available
+    try:
+        import simplejson as json
+    except ImportError:
+        import json
+else:
+    import json
 
 import six
+import six.moves.xmlrpc_client as xmlrpclib
 
 from tempest.openstack.common import gettextutils
 from tempest.openstack.common import importutils
+from tempest.openstack.common import strutils
 from tempest.openstack.common import timeutils
 
 netaddr = importutils.try_import("netaddr")
@@ -164,12 +168,16 @@
     return json.dumps(value, default=default, **kwargs)
 
 
-def loads(s):
-    return json.loads(s)
+def dump(obj, fp, *args, **kwargs):
+    return json.dump(obj, fp, *args, **kwargs)
 
 
-def load(s):
-    return json.load(s)
+def loads(s, encoding='utf-8', **kwargs):
+    return json.loads(strutils.safe_decode(s, encoding), **kwargs)
+
+
+def load(fp, encoding='utf-8', **kwargs):
+    return json.load(codecs.getreader(encoding)(fp), **kwargs)
 
 
 try:
diff --git a/tempest/openstack/common/log.py b/tempest/openstack/common/log.py
index 7bebfdb..44102c0 100644
--- a/tempest/openstack/common/log.py
+++ b/tempest/openstack/common/log.py
@@ -15,7 +15,7 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-"""Openstack logging handler.
+"""OpenStack logging handler.
 
 This module adds to logging functionality by adding the option to specify
 a context object when calling the various log methods.  If the context object
@@ -33,7 +33,6 @@
 import logging.config
 import logging.handlers
 import os
-import re
 import sys
 import traceback
 
@@ -45,27 +44,13 @@
 from tempest.openstack.common import importutils
 from tempest.openstack.common import jsonutils
 from tempest.openstack.common import local
+# NOTE(flaper87): Pls, remove when graduating this module
+# from the incubator.
+from tempest.openstack.common.strutils import mask_password  # noqa
 
 
 _DEFAULT_LOG_DATE_FORMAT = "%Y-%m-%d %H:%M:%S"
 
-_SANITIZE_KEYS = ['adminPass', 'admin_pass', 'password', 'admin_password']
-
-# NOTE(ldbragst): Let's build a list of regex objects using the list of
-# _SANITIZE_KEYS we already have. This way, we only have to add the new key
-# to the list of _SANITIZE_KEYS and we can generate regular expressions
-# for XML and JSON automatically.
-_SANITIZE_PATTERNS = []
-_FORMAT_PATTERNS = [r'(%(key)s\s*[=]\s*[\"\']).*?([\"\'])',
-                    r'(<%(key)s>).*?(</%(key)s>)',
-                    r'([\"\']%(key)s[\"\']\s*:\s*[\"\']).*?([\"\'])',
-                    r'([\'"].*?%(key)s[\'"]\s*:\s*u?[\'"]).*?([\'"])']
-
-for key in _SANITIZE_KEYS:
-    for pattern in _FORMAT_PATTERNS:
-        reg_ex = re.compile(pattern % {'key': key}, re.DOTALL)
-        _SANITIZE_PATTERNS.append(reg_ex)
-
 
 common_cli_opts = [
     cfg.BoolOpt('debug',
@@ -84,14 +69,11 @@
     cfg.StrOpt('log-config-append',
                metavar='PATH',
                deprecated_name='log-config',
-               help='The name of logging configuration file. It does not '
-                    'disable existing loggers, but just appends specified '
-                    'logging configuration to any other existing logging '
-                    'options. Please see the Python logging module '
-                    'documentation for details on logging configuration '
-                    'files.'),
+               help='The name of a logging configuration file. This file '
+                    'is appended to any existing logging configuration '
+                    'files. For details about logging configuration files, '
+                    'see the Python logging module documentation.'),
     cfg.StrOpt('log-format',
-               default=None,
                metavar='FORMAT',
                help='DEPRECATED. '
                     'A logging.Formatter log message format string which may '
@@ -103,7 +85,7 @@
                default=_DEFAULT_LOG_DATE_FORMAT,
                metavar='DATE_FORMAT',
                help='Format string for %%(asctime)s in log records. '
-                    'Default: %(default)s'),
+                    'Default: %(default)s .'),
     cfg.StrOpt('log-file',
                metavar='PATH',
                deprecated_name='logfile',
@@ -112,67 +94,76 @@
     cfg.StrOpt('log-dir',
                deprecated_name='logdir',
                help='(Optional) The base directory used for relative '
-                    '--log-file paths'),
+                    '--log-file paths.'),
     cfg.BoolOpt('use-syslog',
                 default=False,
-                help='Use syslog for logging.'),
+                help='Use syslog for logging. '
+                     'Existing syslog format is DEPRECATED during I, '
+                     'and will change in J to honor RFC5424.'),
+    cfg.BoolOpt('use-syslog-rfc-format',
+                # TODO(bogdando) remove or use True after existing
+                #    syslog format deprecation in J
+                default=False,
+                help='(Optional) Enables or disables syslog rfc5424 format '
+                     'for logging. If enabled, prefixes the MSG part of the '
+                     'syslog message with APP-NAME (RFC5424). The '
+                     'format without the APP-NAME is deprecated in I, '
+                     'and will be removed in J.'),
     cfg.StrOpt('syslog-log-facility',
                default='LOG_USER',
-               help='syslog facility to receive log lines')
+               help='Syslog facility to receive log lines.')
 ]
 
 generic_log_opts = [
     cfg.BoolOpt('use_stderr',
                 default=True,
-                help='Log output to standard error')
+                help='Log output to standard error.')
 ]
 
+DEFAULT_LOG_LEVELS = ['amqp=WARN', 'amqplib=WARN', 'boto=WARN',
+                      'qpid=WARN', 'sqlalchemy=WARN', 'suds=INFO',
+                      'oslo.messaging=INFO', 'iso8601=WARN',
+                      'requests.packages.urllib3.connectionpool=WARN',
+                      'urllib3.connectionpool=WARN']
+
 log_opts = [
     cfg.StrOpt('logging_context_format_string',
                default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
                        '%(name)s [%(request_id)s %(user_identity)s] '
                        '%(instance)s%(message)s',
-               help='format string to use for log messages with context'),
+               help='Format string to use for log messages with context.'),
     cfg.StrOpt('logging_default_format_string',
                default='%(asctime)s.%(msecs)03d %(process)d %(levelname)s '
                        '%(name)s [-] %(instance)s%(message)s',
-               help='format string to use for log messages without context'),
+               help='Format string to use for log messages without context.'),
     cfg.StrOpt('logging_debug_format_suffix',
                default='%(funcName)s %(pathname)s:%(lineno)d',
-               help='data to append to log format when level is DEBUG'),
+               help='Data to append to log format when level is DEBUG.'),
     cfg.StrOpt('logging_exception_prefix',
                default='%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s '
                '%(instance)s',
-               help='prefix each line of exception output with this format'),
+               help='Prefix each line of exception output with this format.'),
     cfg.ListOpt('default_log_levels',
-                default=[
-                    'amqp=WARN',
-                    'amqplib=WARN',
-                    'boto=WARN',
-                    'qpid=WARN',
-                    'sqlalchemy=WARN',
-                    'suds=INFO',
-                    'iso8601=WARN',
-                ],
-                help='list of logger=LEVEL pairs'),
+                default=DEFAULT_LOG_LEVELS,
+                help='List of logger=LEVEL pairs.'),
     cfg.BoolOpt('publish_errors',
                 default=False,
-                help='publish error events'),
+                help='Enables or disables publication of error events.'),
     cfg.BoolOpt('fatal_deprecations',
                 default=False,
-                help='make deprecations fatal'),
+                help='Enables or disables fatal status of deprecations.'),
 
     # NOTE(mikal): there are two options here because sometimes we are handed
     # a full instance (and could include more information), and other times we
     # are just handed a UUID for the instance.
     cfg.StrOpt('instance_format',
                default='[instance: %(uuid)s] ',
-               help='If an instance is passed with the log message, format '
-                    'it like this'),
+               help='The format for an instance that is passed with the log '
+                    'message.'),
     cfg.StrOpt('instance_uuid_format',
                default='[instance: %(uuid)s] ',
-               help='If an instance UUID is passed with the log message, '
-                    'format it like this'),
+               help='The format for an instance UUID that is passed with the '
+                    'log message.'),
 ]
 
 CONF = cfg.CONF
@@ -231,40 +222,6 @@
     return None
 
 
-def mask_password(message, secret="***"):
-    """Replace password with 'secret' in message.
-
-    :param message: The string which includes security information.
-    :param secret: value with which to replace passwords.
-    :returns: The unicode value of message with the password fields masked.
-
-    For example:
-
-    >>> mask_password("'adminPass' : 'aaaaa'")
-    "'adminPass' : '***'"
-    >>> mask_password("'admin_pass' : 'aaaaa'")
-    "'admin_pass' : '***'"
-    >>> mask_password('"password" : "aaaaa"')
-    '"password" : "***"'
-    >>> mask_password("'original_password' : 'aaaaa'")
-    "'original_password' : '***'"
-    >>> mask_password("u'original_password' :   u'aaaaa'")
-    "u'original_password' :   u'***'"
-    """
-    message = six.text_type(message)
-
-    # NOTE(ldbragst): Check to see if anything in message contains any key
-    # specified in _SANITIZE_KEYS, if not then just return the message since
-    # we don't have to mask any passwords.
-    if not any(key in message for key in _SANITIZE_KEYS):
-        return message
-
-    secret = r'\g<1>' + secret + r'\g<2>'
-    for pattern in _SANITIZE_PATTERNS:
-        message = re.sub(pattern, secret, message)
-    return message
-
-
 class BaseLoggerAdapter(logging.LoggerAdapter):
 
     def audit(self, msg, *args, **kwargs):
@@ -282,6 +239,11 @@
     def logger(self):
         if not self._logger:
             self._logger = getLogger(self.name, self.version)
+            if six.PY3:
+                # In Python 3, the code fails because the 'manager' attribute
+                # cannot be found when using a LoggerAdapter as the
+                # underlying logger. Work around this issue.
+                self._logger.manager = self._logger.logger.manager
         return self._logger
 
 
@@ -292,18 +254,39 @@
         self.logger = logger
         self.project = project_name
         self.version = version_string
+        self._deprecated_messages_sent = dict()
 
     @property
     def handlers(self):
         return self.logger.handlers
 
     def deprecated(self, msg, *args, **kwargs):
+        """Call this method when a deprecated feature is used.
+
+        If the system is configured for fatal deprecations then the message
+        is logged at the 'critical' level and :class:`DeprecatedConfig` will
+        be raised.
+
+        Otherwise, the message will be logged (once) at the 'warn' level.
+
+        :raises: :class:`DeprecatedConfig` if the system is configured for
+                 fatal deprecations.
+
+        """
         stdmsg = _("Deprecated: %s") % msg
         if CONF.fatal_deprecations:
             self.critical(stdmsg, *args, **kwargs)
             raise DeprecatedConfig(msg=stdmsg)
-        else:
-            self.warn(stdmsg, *args, **kwargs)
+
+        # Using a list because a tuple with dict can't be stored in a set.
+        sent_args = self._deprecated_messages_sent.setdefault(msg, list())
+
+        if args in sent_args:
+            # Already logged this message, so don't log it again.
+            return
+
+        sent_args.append(args)
+        self.warn(stdmsg, *args, **kwargs)
 
     def process(self, msg, kwargs):
         # NOTE(mrodden): catch any Message/other object and
@@ -324,7 +307,7 @@
             extra.update(_dictify_context(context))
 
         instance = kwargs.pop('instance', None)
-        instance_uuid = (extra.get('instance_uuid', None) or
+        instance_uuid = (extra.get('instance_uuid') or
                          kwargs.pop('instance_uuid', None))
         instance_extra = ''
         if instance:
@@ -390,10 +373,10 @@
 
 def _create_logging_excepthook(product_name):
     def logging_excepthook(exc_type, value, tb):
-        extra = {}
-        if CONF.verbose:
-            extra['exc_info'] = (exc_type, value, tb)
-        getLogger(product_name).critical(str(value), **extra)
+        extra = {'exc_info': (exc_type, value, tb)}
+        getLogger(product_name).critical(
+            "".join(traceback.format_exception_only(exc_type, value)),
+            **extra)
     return logging_excepthook
 
 
@@ -414,23 +397,31 @@
     try:
         logging.config.fileConfig(log_config_append,
                                   disable_existing_loggers=False)
-    except moves.configparser.Error as exc:
-        raise LogConfigError(log_config_append, str(exc))
+    except (moves.configparser.Error, KeyError) as exc:
+        raise LogConfigError(log_config_append, six.text_type(exc))
 
 
-def setup(product_name):
+def setup(product_name, version='unknown'):
     """Setup logging."""
     if CONF.log_config_append:
         _load_log_config(CONF.log_config_append)
     else:
-        _setup_logging_from_conf()
+        _setup_logging_from_conf(product_name, version)
     sys.excepthook = _create_logging_excepthook(product_name)
 
 
-def set_defaults(logging_context_format_string):
-    cfg.set_defaults(log_opts,
-                     logging_context_format_string=
-                     logging_context_format_string)
+def set_defaults(logging_context_format_string,
+                 default_log_levels=None):
+    # Just in case the caller is not setting the
+    # default_log_level. This is insurance because
+    # we introduced the default_log_level parameter
+    # later in a backwards in-compatible change
+    if default_log_levels is None:
+        default_log_levels = DEFAULT_LOG_LEVELS
+    cfg.set_defaults(
+            log_opts,
+            logging_context_format_string=logging_context_format_string,
+            default_log_levels=default_log_levels)
 
 
 def _find_facility_from_conf():
@@ -457,15 +448,38 @@
     return facility
 
 
-def _setup_logging_from_conf():
+class RFCSysLogHandler(logging.handlers.SysLogHandler):
+    def __init__(self, *args, **kwargs):
+        self.binary_name = _get_binary_name()
+        # Do not use super() unless type(logging.handlers.SysLogHandler)
+        #  is 'type' (Python 2.7).
+        # Use old style calls, if the type is 'classobj' (Python 2.6)
+        logging.handlers.SysLogHandler.__init__(self, *args, **kwargs)
+
+    def format(self, record):
+        # Do not use super() unless type(logging.handlers.SysLogHandler)
+        #  is 'type' (Python 2.7).
+        # Use old style calls, if the type is 'classobj' (Python 2.6)
+        msg = logging.handlers.SysLogHandler.format(self, record)
+        msg = self.binary_name + ' ' + msg
+        return msg
+
+
+def _setup_logging_from_conf(project, version):
     log_root = getLogger(None).logger
     for handler in log_root.handlers:
         log_root.removeHandler(handler)
 
     if CONF.use_syslog:
         facility = _find_facility_from_conf()
-        syslog = logging.handlers.SysLogHandler(address='/dev/log',
-                                                facility=facility)
+        # TODO(bogdando) use the format provided by RFCSysLogHandler
+        #   after existing syslog format deprecation in J
+        if CONF.use_syslog_rfc_format:
+            syslog = RFCSysLogHandler(address='/dev/log',
+                                      facility=facility)
+        else:
+            syslog = logging.handlers.SysLogHandler(address='/dev/log',
+                                                    facility=facility)
         log_root.addHandler(syslog)
 
     logpath = _get_log_file_path()
@@ -484,9 +498,14 @@
         log_root.addHandler(streamlog)
 
     if CONF.publish_errors:
-        handler = importutils.import_object(
-            "tempest.openstack.common.log_handler.PublishErrorsHandler",
-            logging.ERROR)
+        try:
+            handler = importutils.import_object(
+                "tempest.openstack.common.log_handler.PublishErrorsHandler",
+                logging.ERROR)
+        except ImportError:
+            handler = importutils.import_object(
+                "oslo.messaging.notify.log_handler.PublishErrorsHandler",
+                logging.ERROR)
         log_root.addHandler(handler)
 
     datefmt = CONF.log_date_format
@@ -499,7 +518,9 @@
             log_root.info('Deprecated: log_format is now deprecated and will '
                           'be removed in the next release')
         else:
-            handler.setFormatter(ContextFormatter(datefmt=datefmt))
+            handler.setFormatter(ContextFormatter(project=project,
+                                                  version=version,
+                                                  datefmt=datefmt))
 
     if CONF.debug:
         log_root.setLevel(logging.DEBUG)
@@ -510,9 +531,15 @@
 
     for pair in CONF.default_log_levels:
         mod, _sep, level_name = pair.partition('=')
-        level = logging.getLevelName(level_name)
         logger = logging.getLogger(mod)
-        logger.setLevel(level)
+        # NOTE(AAzza) in python2.6 Logger.setLevel doesn't convert string name
+        # to integer code.
+        if sys.version_info < (2, 7):
+            level = logging.getLevelName(level_name)
+            logger.setLevel(level)
+        else:
+            logger.setLevel(level_name)
+
 
 _loggers = {}
 
@@ -543,7 +570,7 @@
         self.level = level
 
     def write(self, msg):
-        self.logger.log(self.level, msg)
+        self.logger.log(self.level, msg.rstrip())
 
 
 class ContextFormatter(logging.Formatter):
@@ -557,27 +584,64 @@
     For information about what variables are available for the formatter see:
     http://docs.python.org/library/logging.html#formatter
 
+    If available, uses the context value stored in TLS - local.store.context
+
     """
 
+    def __init__(self, *args, **kwargs):
+        """Initialize ContextFormatter instance
+
+        Takes additional keyword arguments which can be used in the message
+        format string.
+
+        :keyword project: project name
+        :type project: string
+        :keyword version: project version
+        :type version: string
+
+        """
+
+        self.project = kwargs.pop('project', 'unknown')
+        self.version = kwargs.pop('version', 'unknown')
+
+        logging.Formatter.__init__(self, *args, **kwargs)
+
     def format(self, record):
         """Uses contextstring if request_id is set, otherwise default."""
-        # NOTE(sdague): default the fancier formating params
+
+        # store project info
+        record.project = self.project
+        record.version = self.version
+
+        # store request info
+        context = getattr(local.store, 'context', None)
+        if context:
+            d = _dictify_context(context)
+            for k, v in d.items():
+                setattr(record, k, v)
+
+        # NOTE(sdague): default the fancier formatting params
         # to an empty string so we don't throw an exception if
         # they get used
-        for key in ('instance', 'color'):
+        for key in ('instance', 'color', 'user_identity'):
             if key not in record.__dict__:
                 record.__dict__[key] = ''
 
-        if record.__dict__.get('request_id', None):
-            self._fmt = CONF.logging_context_format_string
+        if record.__dict__.get('request_id'):
+            fmt = CONF.logging_context_format_string
         else:
-            self._fmt = CONF.logging_default_format_string
+            fmt = CONF.logging_default_format_string
 
         if (record.levelno == logging.DEBUG and
                 CONF.logging_debug_format_suffix):
-            self._fmt += " " + CONF.logging_debug_format_suffix
+            fmt += " " + CONF.logging_debug_format_suffix
 
-        # Cache this on the record, Logger will respect our formated copy
+        if sys.version_info < (3, 2):
+            self._fmt = fmt
+        else:
+            self._style = logging.PercentStyle(fmt)
+            self._fmt = self._style._fmt
+        # Cache this on the record, Logger will respect our formatted copy
         if record.exc_info:
             record.exc_text = self.formatException(record.exc_info, record)
         return logging.Formatter.format(self, record)
diff --git a/tempest/openstack/common/strutils.py b/tempest/openstack/common/strutils.py
new file mode 100644
index 0000000..605cc02
--- /dev/null
+++ b/tempest/openstack/common/strutils.py
@@ -0,0 +1,295 @@
+# Copyright 2011 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.
+
+"""
+System-level utilities and helper functions.
+"""
+
+import math
+import re
+import sys
+import unicodedata
+
+import six
+
+from tempest.openstack.common.gettextutils import _
+
+
+UNIT_PREFIX_EXPONENT = {
+    'k': 1,
+    'K': 1,
+    'Ki': 1,
+    'M': 2,
+    'Mi': 2,
+    'G': 3,
+    'Gi': 3,
+    'T': 4,
+    'Ti': 4,
+}
+UNIT_SYSTEM_INFO = {
+    'IEC': (1024, re.compile(r'(^[-+]?\d*\.?\d+)([KMGT]i?)?(b|bit|B)$')),
+    'SI': (1000, re.compile(r'(^[-+]?\d*\.?\d+)([kMGT])?(b|bit|B)$')),
+}
+
+TRUE_STRINGS = ('1', 't', 'true', 'on', 'y', 'yes')
+FALSE_STRINGS = ('0', 'f', 'false', 'off', 'n', 'no')
+
+SLUGIFY_STRIP_RE = re.compile(r"[^\w\s-]")
+SLUGIFY_HYPHENATE_RE = re.compile(r"[-\s]+")
+
+
+# NOTE(flaper87): The following 3 globals are used by `mask_password`
+_SANITIZE_KEYS = ['adminPass', 'admin_pass', 'password', 'admin_password']
+
+# NOTE(ldbragst): Let's build a list of regex objects using the list of
+# _SANITIZE_KEYS we already have. This way, we only have to add the new key
+# to the list of _SANITIZE_KEYS and we can generate regular expressions
+# for XML and JSON automatically.
+_SANITIZE_PATTERNS = []
+_FORMAT_PATTERNS = [r'(%(key)s\s*[=]\s*[\"\']).*?([\"\'])',
+                    r'(<%(key)s>).*?(</%(key)s>)',
+                    r'([\"\']%(key)s[\"\']\s*:\s*[\"\']).*?([\"\'])',
+                    r'([\'"].*?%(key)s[\'"]\s*:\s*u?[\'"]).*?([\'"])',
+                    r'([\'"].*?%(key)s[\'"]\s*,\s*\'--?[A-z]+\'\s*,\s*u?[\'"])'
+                    '.*?([\'"])',
+                    r'(%(key)s\s*--?[A-z]+\s*)\S+(\s*)']
+
+for key in _SANITIZE_KEYS:
+    for pattern in _FORMAT_PATTERNS:
+        reg_ex = re.compile(pattern % {'key': key}, re.DOTALL)
+        _SANITIZE_PATTERNS.append(reg_ex)
+
+
+def int_from_bool_as_string(subject):
+    """Interpret a string as a boolean and return either 1 or 0.
+
+    Any string value in:
+
+        ('True', 'true', 'On', 'on', '1')
+
+    is interpreted as a boolean True.
+
+    Useful for JSON-decoded stuff and config file parsing
+    """
+    return bool_from_string(subject) and 1 or 0
+
+
+def bool_from_string(subject, strict=False, default=False):
+    """Interpret a string as a boolean.
+
+    A case-insensitive match is performed such that strings matching 't',
+    'true', 'on', 'y', 'yes', or '1' are considered True and, when
+    `strict=False`, anything else returns the value specified by 'default'.
+
+    Useful for JSON-decoded stuff and config file parsing.
+
+    If `strict=True`, unrecognized values, including None, will raise a
+    ValueError which is useful when parsing values passed in from an API call.
+    Strings yielding False are 'f', 'false', 'off', 'n', 'no', or '0'.
+    """
+    if not isinstance(subject, six.string_types):
+        subject = six.text_type(subject)
+
+    lowered = subject.strip().lower()
+
+    if lowered in TRUE_STRINGS:
+        return True
+    elif lowered in FALSE_STRINGS:
+        return False
+    elif strict:
+        acceptable = ', '.join(
+            "'%s'" % s for s in sorted(TRUE_STRINGS + FALSE_STRINGS))
+        msg = _("Unrecognized value '%(val)s', acceptable values are:"
+                " %(acceptable)s") % {'val': subject,
+                                      'acceptable': acceptable}
+        raise ValueError(msg)
+    else:
+        return default
+
+
+def safe_decode(text, incoming=None, errors='strict'):
+    """Decodes incoming text/bytes string using `incoming` if they're not
+       already unicode.
+
+    :param incoming: Text's current encoding
+    :param errors: Errors handling policy. See here for valid
+        values http://docs.python.org/2/library/codecs.html
+    :returns: text or a unicode `incoming` encoded
+                representation of it.
+    :raises TypeError: If text is not an instance of str
+    """
+    if not isinstance(text, (six.string_types, six.binary_type)):
+        raise TypeError("%s can't be decoded" % type(text))
+
+    if isinstance(text, six.text_type):
+        return text
+
+    if not incoming:
+        incoming = (sys.stdin.encoding or
+                    sys.getdefaultencoding())
+
+    try:
+        return text.decode(incoming, errors)
+    except UnicodeDecodeError:
+        # Note(flaper87) If we get here, it means that
+        # sys.stdin.encoding / sys.getdefaultencoding
+        # didn't return a suitable encoding to decode
+        # text. This happens mostly when global LANG
+        # var is not set correctly and there's no
+        # default encoding. In this case, most likely
+        # python will use ASCII or ANSI encoders as
+        # default encodings but they won't be capable
+        # of decoding non-ASCII characters.
+        #
+        # Also, UTF-8 is being used since it's an ASCII
+        # extension.
+        return text.decode('utf-8', errors)
+
+
+def safe_encode(text, incoming=None,
+                encoding='utf-8', errors='strict'):
+    """Encodes incoming text/bytes string using `encoding`.
+
+    If incoming is not specified, text is expected to be encoded with
+    current python's default encoding. (`sys.getdefaultencoding`)
+
+    :param incoming: Text's current encoding
+    :param encoding: Expected encoding for text (Default UTF-8)
+    :param errors: Errors handling policy. See here for valid
+        values http://docs.python.org/2/library/codecs.html
+    :returns: text or a bytestring `encoding` encoded
+                representation of it.
+    :raises TypeError: If text is not an instance of str
+    """
+    if not isinstance(text, (six.string_types, six.binary_type)):
+        raise TypeError("%s can't be encoded" % type(text))
+
+    if not incoming:
+        incoming = (sys.stdin.encoding or
+                    sys.getdefaultencoding())
+
+    if isinstance(text, six.text_type):
+        return text.encode(encoding, errors)
+    elif text and encoding != incoming:
+        # Decode text before encoding it with `encoding`
+        text = safe_decode(text, incoming, errors)
+        return text.encode(encoding, errors)
+    else:
+        return text
+
+
+def string_to_bytes(text, unit_system='IEC', return_int=False):
+    """Converts a string into an float representation of bytes.
+
+    The units supported for IEC ::
+
+        Kb(it), Kib(it), Mb(it), Mib(it), Gb(it), Gib(it), Tb(it), Tib(it)
+        KB, KiB, MB, MiB, GB, GiB, TB, TiB
+
+    The units supported for SI ::
+
+        kb(it), Mb(it), Gb(it), Tb(it)
+        kB, MB, GB, TB
+
+    Note that the SI unit system does not support capital letter 'K'
+
+    :param text: String input for bytes size conversion.
+    :param unit_system: Unit system for byte size conversion.
+    :param return_int: If True, returns integer representation of text
+                       in bytes. (default: decimal)
+    :returns: Numerical representation of text in bytes.
+    :raises ValueError: If text has an invalid value.
+
+    """
+    try:
+        base, reg_ex = UNIT_SYSTEM_INFO[unit_system]
+    except KeyError:
+        msg = _('Invalid unit system: "%s"') % unit_system
+        raise ValueError(msg)
+    match = reg_ex.match(text)
+    if match:
+        magnitude = float(match.group(1))
+        unit_prefix = match.group(2)
+        if match.group(3) in ['b', 'bit']:
+            magnitude /= 8
+    else:
+        msg = _('Invalid string format: %s') % text
+        raise ValueError(msg)
+    if not unit_prefix:
+        res = magnitude
+    else:
+        res = magnitude * pow(base, UNIT_PREFIX_EXPONENT[unit_prefix])
+    if return_int:
+        return int(math.ceil(res))
+    return res
+
+
+def to_slug(value, incoming=None, errors="strict"):
+    """Normalize string.
+
+    Convert to lowercase, remove non-word characters, and convert spaces
+    to hyphens.
+
+    Inspired by Django's `slugify` filter.
+
+    :param value: Text to slugify
+    :param incoming: Text's current encoding
+    :param errors: Errors handling policy. See here for valid
+        values http://docs.python.org/2/library/codecs.html
+    :returns: slugified unicode representation of `value`
+    :raises TypeError: If text is not an instance of str
+    """
+    value = safe_decode(value, incoming, errors)
+    # NOTE(aababilov): no need to use safe_(encode|decode) here:
+    # encodings are always "ascii", error handling is always "ignore"
+    # and types are always known (first: unicode; second: str)
+    value = unicodedata.normalize("NFKD", value).encode(
+        "ascii", "ignore").decode("ascii")
+    value = SLUGIFY_STRIP_RE.sub("", value).strip().lower()
+    return SLUGIFY_HYPHENATE_RE.sub("-", value)
+
+
+def mask_password(message, secret="***"):
+    """Replace password with 'secret' in message.
+
+    :param message: The string which includes security information.
+    :param secret: value with which to replace passwords.
+    :returns: The unicode value of message with the password fields masked.
+
+    For example:
+
+    >>> mask_password("'adminPass' : 'aaaaa'")
+    "'adminPass' : '***'"
+    >>> mask_password("'admin_pass' : 'aaaaa'")
+    "'admin_pass' : '***'"
+    >>> mask_password('"password" : "aaaaa"')
+    '"password" : "***"'
+    >>> mask_password("'original_password' : 'aaaaa'")
+    "'original_password' : '***'"
+    >>> mask_password("u'original_password' :   u'aaaaa'")
+    "u'original_password' :   u'***'"
+    """
+    message = six.text_type(message)
+
+    # NOTE(ldbragst): Check to see if anything in message contains any key
+    # specified in _SANITIZE_KEYS, if not then just return the message since
+    # we don't have to mask any passwords.
+    if not any(key in message for key in _SANITIZE_KEYS):
+        return message
+
+    secret = r'\g<1>' + secret + r'\g<2>'
+    for pattern in _SANITIZE_PATTERNS:
+        message = re.sub(pattern, secret, message)
+    return message
diff --git a/tempest/openstack/common/timeutils.py b/tempest/openstack/common/timeutils.py
index d5ed81d..c48da95 100644
--- a/tempest/openstack/common/timeutils.py
+++ b/tempest/openstack/common/timeutils.py
@@ -114,7 +114,7 @@
 
 
 def iso8601_from_timestamp(timestamp):
-    """Returns a iso8601 formated date from timestamp."""
+    """Returns an iso8601 formatted date from timestamp."""
     return isotime(datetime.datetime.utcfromtimestamp(timestamp))
 
 
@@ -134,7 +134,7 @@
 
 def advance_time_delta(timedelta):
     """Advance overridden time using a datetime.timedelta."""
-    assert(not utcnow.override_time is None)
+    assert utcnow.override_time is not None
     try:
         for dt in utcnow.override_time:
             dt += timedelta
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/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 69d2f35..fea0d28 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -164,6 +164,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
+        self.validate_response(schema.list_servers_detail, resp, body)
         return resp, body
 
     def wait_for_server_status(self, server_id, status, extra_timeout=0,
diff --git a/tempest/services/compute/v3/json/servers_client.py b/tempest/services/compute/v3/json/servers_client.py
index d933998..932cc2c 100644
--- a/tempest/services/compute/v3/json/servers_client.py
+++ b/tempest/services/compute/v3/json/servers_client.py
@@ -166,6 +166,7 @@
 
         resp, body = self.get(url)
         body = json.loads(body)
+        self.validate_response(schema.list_servers_detail, resp, body)
         return resp, body
 
     def wait_for_server_status(self, server_id, status, extra_timeout=0,
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index b0cab8e..ac65f81 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -37,8 +37,12 @@
         """
         if hasattr(self, '_has_admin_extensions'):
             return self._has_admin_extensions
-        resp, body = self.list_roles()
-        self._has_admin_extensions = ('status' in resp and resp.status != 503)
+        # Try something that requires admin
+        try:
+            self.list_roles()
+            self._has_admin_extensions = True
+        except Exception:
+            self._has_admin_extensions = False
         return self._has_admin_extensions
 
     def create_role(self, name):
@@ -48,11 +52,13 @@
         }
         post_body = json.dumps({'role': post_body})
         resp, body = self.post('OS-KSADM/roles', post_body)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def get_role(self, role_id):
         """Get a role by its id."""
         resp, body = self.get('OS-KSADM/roles/%s' % role_id)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['role']
 
@@ -70,51 +76,63 @@
         }
         post_body = json.dumps({'tenant': post_body})
         resp, body = self.post('tenants', post_body)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def delete_role(self, role_id):
         """Delete a role."""
-        return self.delete('OS-KSADM/roles/%s' % str(role_id))
+        resp, body = self.delete('OS-KSADM/roles/%s' % str(role_id))
+        self.expected_success(204, resp.status)
+        return resp, body
 
     def list_user_roles(self, tenant_id, user_id):
         """Returns a list of roles assigned to a user for a tenant."""
         url = '/tenants/%s/users/%s/roles' % (tenant_id, user_id)
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def assign_user_role(self, tenant_id, user_id, role_id):
         """Add roles to a user on a tenant."""
         resp, body = self.put('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
                               (tenant_id, user_id, role_id), "")
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def remove_user_role(self, tenant_id, user_id, role_id):
         """Removes a role assignment for a user on a tenant."""
-        return self.delete('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
-                           (tenant_id, user_id, role_id))
+        resp, body = self.delete('/tenants/%s/users/%s/roles/OS-KSADM/%s' %
+                                 (tenant_id, user_id, role_id))
+        self.expected_success(204, resp.status)
+        return resp, body
 
     def delete_tenant(self, tenant_id):
         """Delete a tenant."""
-        return self.delete('tenants/%s' % str(tenant_id))
+        resp, body = self.delete('tenants/%s' % str(tenant_id))
+        self.expected_success(204, resp.status)
+        return resp, body
 
     def get_tenant(self, tenant_id):
         """Get tenant details."""
         resp, body = self.get('tenants/%s' % str(tenant_id))
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def list_roles(self):
         """Returns roles."""
         resp, body = self.get('OS-KSADM/roles')
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def list_tenants(self):
         """Returns tenants."""
         resp, body = self.get('tenants')
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['tenants']
 
     def get_tenant_by_name(self, tenant_name):
-        resp, tenants = self.list_tenants()
+        _, tenants = self.list_tenants()
         for tenant in tenants:
             if tenant['name'] == tenant_name:
                 return tenant
@@ -122,7 +140,7 @@
 
     def update_tenant(self, tenant_id, **kwargs):
         """Updates a tenant."""
-        resp, body = self.get_tenant(tenant_id)
+        _, body = self.get_tenant(tenant_id)
         name = kwargs.get('name', body['name'])
         desc = kwargs.get('description', body['description'])
         en = kwargs.get('enabled', body['enabled'])
@@ -134,6 +152,7 @@
         }
         post_body = json.dumps({'tenant': post_body})
         resp, body = self.post('tenants/%s' % tenant_id, post_body)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def create_user(self, name, password, tenant_id, email, **kwargs):
@@ -149,26 +168,32 @@
             post_body['enabled'] = kwargs.get('enabled')
         post_body = json.dumps({'user': post_body})
         resp, body = self.post('users', post_body)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def update_user(self, user_id, **kwargs):
         """Updates a user."""
         put_body = json.dumps({'user': kwargs})
         resp, body = self.put('users/%s' % user_id, put_body)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def get_user(self, user_id):
         """GET a user."""
         resp, body = self.get("users/%s" % user_id)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def delete_user(self, user_id):
         """Delete a user."""
-        return self.delete("users/%s" % user_id)
+        resp, body = self.delete("users/%s" % user_id)
+        self.expected_success(204, resp.status)
+        return resp, body
 
     def get_users(self):
         """Get the list of users."""
         resp, body = self.get("users")
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def enable_disable_user(self, user_id, enabled):
@@ -178,24 +203,29 @@
         }
         put_body = json.dumps({'user': put_body})
         resp, body = self.put('users/%s/enabled' % user_id, put_body)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def get_token(self, token_id):
         """Get token details."""
         resp, body = self.get("tokens/%s" % token_id)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def delete_token(self, token_id):
         """Delete a token."""
-        return self.delete("tokens/%s" % token_id)
+        resp, body = self.delete("tokens/%s" % token_id)
+        self.expected_success(204, resp.status)
+        return resp, body
 
     def list_users_for_tenant(self, tenant_id):
         """List users for a Tenant."""
         resp, body = self.get('/tenants/%s/users' % tenant_id)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def get_user_by_username(self, tenant_id, username):
-        resp, users = self.list_users_for_tenant(tenant_id)
+        _, users = self.list_users_for_tenant(tenant_id)
         for user in users:
             if user['name'] == username:
                 return user
@@ -210,23 +240,28 @@
         }
         post_body = json.dumps({'OS-KSADM:service': post_body})
         resp, body = self.post('/OS-KSADM/services', post_body)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def get_service(self, service_id):
         """Get Service."""
         url = '/OS-KSADM/services/%s' % service_id
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def list_services(self):
         """List Service - Returns Services."""
         resp, body = self.get('/OS-KSADM/services')
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def delete_service(self, service_id):
         """Delete Service."""
         url = '/OS-KSADM/services/%s' % service_id
-        return self.delete(url)
+        resp, body = self.delete(url)
+        self.expected_success(204, resp.status)
+        return resp, body
 
     def update_user_password(self, user_id, new_pass):
         """Update User Password."""
@@ -236,11 +271,13 @@
         }
         put_body = json.dumps({'user': put_body})
         resp, body = self.put('users/%s/OS-KSADM/password' % user_id, put_body)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def list_extensions(self):
         """List all the extensions."""
         resp, body = self.get('/extensions')
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['extensions']['values']
 
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index 6829333..8c72dfa 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -49,12 +49,13 @@
         }
         post_body = json.dumps({'user': post_body})
         resp, body = self.post('users', post_body)
+        self.expected_success(201, resp.status)
         body = json.loads(body)
         return resp, body['user']
 
     def update_user(self, user_id, name, **kwargs):
         """Updates a user."""
-        resp, body = self.get_user(user_id)
+        _, body = self.get_user(user_id)
         email = kwargs.get('email', body['email'])
         en = kwargs.get('enabled', body['enabled'])
         project_id = kwargs.get('project_id', body['project_id'])
@@ -71,30 +72,35 @@
         }
         post_body = json.dumps({'user': post_body})
         resp, body = self.patch('users/%s' % user_id, post_body)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['user']
 
     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)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['projects']
 
     def get_users(self):
         """Get the list of users."""
         resp, body = self.get("users")
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['users']
 
     def get_user(self, user_id):
         """GET a user."""
         resp, body = self.get("users/%s" % user_id)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['user']
 
     def delete_user(self, user_id):
         """Deletes a User."""
         resp, body = self.delete("users/%s" % user_id)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def create_project(self, name, **kwargs):
@@ -110,16 +116,18 @@
         }
         post_body = json.dumps({'project': post_body})
         resp, body = self.post('projects', post_body)
+        self.expected_success(201, resp.status)
         body = json.loads(body)
         return resp, body['project']
 
     def list_projects(self):
         resp, body = self.get("projects")
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['projects']
 
     def update_project(self, project_id, **kwargs):
-        resp, body = self.get_project(project_id)
+        _, body = self.get_project(project_id)
         name = kwargs.get('name', body['name'])
         desc = kwargs.get('description', body['description'])
         en = kwargs.get('enabled', body['enabled'])
@@ -133,18 +141,21 @@
         }
         post_body = json.dumps({'project': post_body})
         resp, body = self.patch('projects/%s' % project_id, post_body)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['project']
 
     def get_project(self, project_id):
         """GET a Project."""
         resp, body = self.get("projects/%s" % project_id)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['project']
 
     def delete_project(self, project_id):
         """Delete a project."""
         resp, body = self.delete('projects/%s' % str(project_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def create_role(self, name):
@@ -154,18 +165,21 @@
         }
         post_body = json.dumps({'role': post_body})
         resp, body = self.post('roles', post_body)
+        self.expected_success(201, resp.status)
         body = json.loads(body)
         return resp, body['role']
 
     def get_role(self, role_id):
         """GET a Role."""
         resp, body = self.get('roles/%s' % str(role_id))
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['role']
 
     def list_roles(self):
         """Get the list of Roles."""
         resp, body = self.get("roles")
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['roles']
 
@@ -176,18 +190,21 @@
         }
         post_body = json.dumps({'role': post_body})
         resp, body = self.patch('roles/%s' % str(role_id), post_body)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['role']
 
     def delete_role(self, role_id):
         """Delete a role."""
         resp, body = self.delete('roles/%s' % str(role_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def assign_user_role(self, project_id, user_id, role_id):
         """Add roles to a user on a project."""
         resp, body = self.put('projects/%s/users/%s/roles/%s' %
                               (project_id, user_id, role_id), None)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def create_domain(self, name, **kwargs):
@@ -201,23 +218,26 @@
         }
         post_body = json.dumps({'domain': post_body})
         resp, body = self.post('domains', post_body)
+        self.expected_success(201, resp.status)
         body = json.loads(body)
         return resp, body['domain']
 
     def delete_domain(self, domain_id):
         """Delete a domain."""
         resp, body = self.delete('domains/%s' % str(domain_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def list_domains(self):
         """List Domains."""
         resp, body = self.get('domains')
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['domains']
 
     def update_domain(self, domain_id, **kwargs):
         """Updates a domain."""
-        resp, body = self.get_domain(domain_id)
+        _, body = self.get_domain(domain_id)
         description = kwargs.get('description', body['description'])
         en = kwargs.get('enabled', body['enabled'])
         name = kwargs.get('name', body['name'])
@@ -228,12 +248,14 @@
         }
         post_body = json.dumps({'domain': post_body})
         resp, body = self.patch('domains/%s' % domain_id, post_body)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['domain']
 
     def get_domain(self, domain_id):
         """Get Domain details."""
         resp, body = self.get('domains/%s' % domain_id)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['domain']
 
@@ -241,6 +263,7 @@
         """Get token details."""
         headers = {'X-Subject-Token': resp_token}
         resp, body = self.get("auth/tokens", headers=headers)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['token']
 
@@ -248,6 +271,7 @@
         """Deletes token."""
         headers = {'X-Subject-Token': resp_token}
         resp, body = self.delete("auth/tokens", headers=headers)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def create_group(self, name, **kwargs):
@@ -263,18 +287,20 @@
         }
         post_body = json.dumps({'group': post_body})
         resp, body = self.post('groups', post_body)
+        self.expected_success(201, resp.status)
         body = json.loads(body)
         return resp, body['group']
 
     def get_group(self, group_id):
         """Get group details."""
         resp, body = self.get('groups/%s' % group_id)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['group']
 
     def update_group(self, group_id, **kwargs):
         """Updates a group."""
-        resp, body = self.get_group(group_id)
+        _, body = self.get_group(group_id)
         name = kwargs.get('name', body['name'])
         description = kwargs.get('description', body['description'])
         post_body = {
@@ -283,53 +309,62 @@
         }
         post_body = json.dumps({'group': post_body})
         resp, body = self.patch('groups/%s' % group_id, post_body)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['group']
 
     def delete_group(self, group_id):
         """Delete a group."""
         resp, body = self.delete('groups/%s' % str(group_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def add_group_user(self, group_id, user_id):
         """Add user into group."""
         resp, body = self.put('groups/%s/users/%s' % (group_id, user_id),
                               None)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def list_group_users(self, group_id):
         """List users in group."""
         resp, body = self.get('groups/%s/users' % group_id)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['users']
 
     def list_user_groups(self, user_id):
         """Lists groups which a user belongs to."""
         resp, body = self.get('users/%s/groups' % user_id)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['groups']
 
     def delete_group_user(self, group_id, user_id):
         """Delete user in group."""
         resp, body = self.delete('groups/%s/users/%s' % (group_id, user_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def assign_user_role_on_project(self, project_id, user_id, role_id):
         """Add roles to a user on a project."""
         resp, body = self.put('projects/%s/users/%s/roles/%s' %
                               (project_id, user_id, role_id), None)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def assign_user_role_on_domain(self, domain_id, user_id, role_id):
         """Add roles to a user on a domain."""
         resp, body = self.put('domains/%s/users/%s/roles/%s' %
                               (domain_id, user_id, role_id), None)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def list_user_roles_on_project(self, project_id, user_id):
         """list roles of a user on a project."""
         resp, body = self.get('projects/%s/users/%s/roles' %
                               (project_id, user_id))
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['roles']
 
@@ -337,6 +372,7 @@
         """list roles of a user on a domain."""
         resp, body = self.get('domains/%s/users/%s/roles' %
                               (domain_id, user_id))
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['roles']
 
@@ -344,30 +380,35 @@
         """Delete role of a user on a project."""
         resp, body = self.delete('projects/%s/users/%s/roles/%s' %
                                  (project_id, user_id, role_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def revoke_role_from_user_on_domain(self, domain_id, user_id, role_id):
         """Delete role of a user on a domain."""
         resp, body = self.delete('domains/%s/users/%s/roles/%s' %
                                  (domain_id, user_id, role_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def assign_group_role_on_project(self, project_id, group_id, role_id):
         """Add roles to a user on a project."""
         resp, body = self.put('projects/%s/groups/%s/roles/%s' %
                               (project_id, group_id, role_id), None)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def assign_group_role_on_domain(self, domain_id, group_id, role_id):
         """Add roles to a user on a domain."""
         resp, body = self.put('domains/%s/groups/%s/roles/%s' %
                               (domain_id, group_id, role_id), None)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def list_group_roles_on_project(self, project_id, group_id):
         """list roles of a user on a project."""
         resp, body = self.get('projects/%s/groups/%s/roles' %
                               (project_id, group_id))
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['roles']
 
@@ -375,6 +416,7 @@
         """list roles of a user on a domain."""
         resp, body = self.get('domains/%s/groups/%s/roles' %
                               (domain_id, group_id))
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['roles']
 
@@ -382,12 +424,14 @@
         """Delete role of a user on a project."""
         resp, body = self.delete('projects/%s/groups/%s/roles/%s' %
                                  (project_id, group_id, role_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def revoke_role_from_group_on_domain(self, domain_id, group_id, role_id):
         """Delete role of a user on a domain."""
         resp, body = self.delete('domains/%s/groups/%s/roles/%s' %
                                  (domain_id, group_id, role_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def create_trust(self, trustor_user_id, trustee_user_id, project_id,
@@ -404,12 +448,14 @@
         }
         post_body = json.dumps({'trust': post_body})
         resp, body = self.post('OS-TRUST/trusts', post_body)
+        self.expected_success(201, resp.status)
         body = json.loads(body)
         return resp, body['trust']
 
     def delete_trust(self, trust_id):
         """Deletes a trust."""
         resp, body = self.delete("OS-TRUST/trusts/%s" % trust_id)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def get_trusts(self, trustor_user_id=None, trustee_user_id=None):
@@ -422,18 +468,21 @@
                                   % trustee_user_id)
         else:
             resp, body = self.get("OS-TRUST/trusts")
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['trusts']
 
     def get_trust(self, trust_id):
         """GET trust."""
         resp, body = self.get("OS-TRUST/trusts/%s" % trust_id)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['trust']
 
     def get_trust_roles(self, trust_id):
         """GET roles delegated by a trust."""
         resp, body = self.get("OS-TRUST/trusts/%s/roles" % trust_id)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['roles']
 
@@ -441,6 +490,7 @@
         """GET role delegated by a trust."""
         resp, body = self.get("OS-TRUST/trusts/%s/roles/%s"
                               % (trust_id, role_id))
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['role']
 
@@ -448,6 +498,10 @@
         """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)
         return resp, body
 
 
diff --git a/tempest/services/identity/v3/json/region_client.py b/tempest/services/identity/v3/json/region_client.py
index f95d00f..c078765 100644
--- a/tempest/services/identity/v3/json/region_client.py
+++ b/tempest/services/identity/v3/json/region_client.py
@@ -1,4 +1,4 @@
-# Copyright 2014 OpenStack Foundation
+# Copyright 2014 Hewlett-Packard Development Company, L.P
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tempest/services/identity/v3/json/service_client.py b/tempest/services/identity/v3/json/service_client.py
index b66fb4a..82e8aad 100644
--- a/tempest/services/identity/v3/json/service_client.py
+++ b/tempest/services/identity/v3/json/service_client.py
@@ -42,6 +42,7 @@
         }
         patch_body = json.dumps({'service': patch_body})
         resp, body = self.patch('services/%s' % service_id, patch_body)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['service']
 
@@ -49,6 +50,7 @@
         """Get Service."""
         url = 'services/%s' % service_id
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return resp, body['service']
 
@@ -62,10 +64,12 @@
         }
         body = json.dumps({'service': body_dict})
         resp, body = self.post("services", body)
+        self.expected_success(201, resp.status)
         body = json.loads(body)
         return resp, body["service"]
 
     def delete_service(self, serv_id):
         url = "services/" + serv_id
         resp, body = self.delete(url)
+        self.expected_success(204, resp.status)
         return resp, body
diff --git a/tempest/services/identity/v3/xml/identity_client.py b/tempest/services/identity/v3/xml/identity_client.py
index 35295d7..242b032 100644
--- a/tempest/services/identity/v3/xml/identity_client.py
+++ b/tempest/services/identity/v3/xml/identity_client.py
@@ -104,12 +104,13 @@
                                    project_id=project_id,
                                    domain_id=domain_id)
         resp, body = self.post('users', str(common.Document(post_body)))
+        self.expected_success(201, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def update_user(self, user_id, name, **kwargs):
         """Updates a user."""
-        resp, body = self.get_user(user_id)
+        _, body = self.get_user(user_id)
         email = kwargs.get('email', body['email'])
         en = kwargs.get('enabled', body['enabled'])
         project_id = kwargs.get('project_id', body['project_id'])
@@ -125,30 +126,35 @@
                                      enabled=str(en).lower())
         resp, body = self.patch('users/%s' % user_id,
                                 str(common.Document(update_user)))
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     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)
+        self.expected_success(200, resp.status)
         body = self._parse_projects(etree.fromstring(body))
         return resp, body
 
     def get_users(self):
         """Get the list of users."""
         resp, body = self.get("users")
+        self.expected_success(200, resp.status)
         body = self._parse_array(etree.fromstring(body))
         return resp, body
 
     def get_user(self, user_id):
         """GET a user."""
         resp, body = self.get("users/%s" % user_id)
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def delete_user(self, user_id):
         """Deletes a User."""
         resp, body = self.delete("users/%s" % user_id)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def create_project(self, name, **kwargs):
@@ -164,12 +170,14 @@
                                    name=name)
         resp, body = self.post('projects',
                                str(common.Document(post_body)))
+        self.expected_success(201, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def list_projects(self):
         """Get the list of projects."""
         resp, body = self.get("projects")
+        self.expected_success(200, resp.status)
         body = self._parse_projects(etree.fromstring(body))
         return resp, body
 
@@ -188,18 +196,21 @@
                                    domain_id=domain_id)
         resp, body = self.patch('projects/%s' % project_id,
                                 str(common.Document(post_body)))
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def get_project(self, project_id):
         """GET a Project."""
         resp, body = self.get("projects/%s" % project_id)
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def delete_project(self, project_id):
         """Delete a project."""
         resp, body = self.delete('projects/%s' % str(project_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def create_role(self, name):
@@ -208,18 +219,21 @@
                                    xmlns=XMLNS,
                                    name=name)
         resp, body = self.post('roles', str(common.Document(post_body)))
+        self.expected_success(201, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def get_role(self, role_id):
         """GET a Role."""
         resp, body = self.get('roles/%s' % str(role_id))
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def list_roles(self):
         """Get the list of Roles."""
         resp, body = self.get("roles")
+        self.expected_success(200, resp.status)
         body = self._parse_roles(etree.fromstring(body))
         return resp, body
 
@@ -230,18 +244,21 @@
                                    name=name)
         resp, body = self.patch('roles/%s' % str(role_id),
                                 str(common.Document(post_body)))
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def delete_role(self, role_id):
         """Delete a role."""
         resp, body = self.delete('roles/%s' % str(role_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def assign_user_role(self, project_id, user_id, role_id):
         """Add roles to a user on a tenant."""
         resp, body = self.put('projects/%s/users/%s/roles/%s' %
                               (project_id, user_id, role_id), '')
+        self.expected_success(204, resp.status)
         return resp, body
 
     def create_domain(self, name, **kwargs):
@@ -254,23 +271,26 @@
                                    description=description,
                                    enabled=str(en).lower())
         resp, body = self.post('domains', str(common.Document(post_body)))
+        self.expected_success(201, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def list_domains(self):
         """Get the list of domains."""
         resp, body = self.get("domains")
+        self.expected_success(200, resp.status)
         body = self._parse_domains(etree.fromstring(body))
         return resp, body
 
     def delete_domain(self, domain_id):
         """Delete a domain."""
         resp, body = self.delete('domains/%s' % domain_id)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def update_domain(self, domain_id, **kwargs):
         """Updates a domain."""
-        resp, body = self.get_domain(domain_id)
+        _, body = self.get_domain(domain_id)
         description = kwargs.get('description', body['description'])
         en = kwargs.get('enabled', body['enabled'])
         name = kwargs.get('name', body['name'])
@@ -281,12 +301,14 @@
                                    enabled=str(en).lower())
         resp, body = self.patch('domains/%s' % domain_id,
                                 str(common.Document(post_body)))
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def get_domain(self, domain_id):
         """Get Domain details."""
         resp, body = self.get('domains/%s' % domain_id)
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -296,6 +318,7 @@
                    'Accept': 'application/xml',
                    'X-Subject-Token': resp_token}
         resp, body = self.get("auth/tokens", headers=headers)
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -303,6 +326,7 @@
         """Delete a Given Token."""
         headers = {'X-Subject-Token': resp_token}
         resp, body = self.delete("auth/tokens", headers=headers)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def create_group(self, name, **kwargs):
@@ -317,18 +341,20 @@
                                    domain_id=domain_id,
                                    project_id=project_id)
         resp, body = self.post('groups', str(common.Document(post_body)))
+        self.expected_success(201, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def get_group(self, group_id):
         """Get group details."""
         resp, body = self.get('groups/%s' % group_id)
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def update_group(self, group_id, **kwargs):
         """Updates a group."""
-        resp, body = self.get_group(group_id)
+        _, body = self.get_group(group_id)
         name = kwargs.get('name', body['name'])
         description = kwargs.get('description', body['description'])
         post_body = common.Element("group",
@@ -337,52 +363,61 @@
                                    description=description)
         resp, body = self.patch('groups/%s' % group_id,
                                 str(common.Document(post_body)))
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def delete_group(self, group_id):
         """Delete a group."""
         resp, body = self.delete('groups/%s' % group_id)
+        self.expected_success(204, resp.status)
         return resp, body
 
     def add_group_user(self, group_id, user_id):
         """Add user into group."""
         resp, body = self.put('groups/%s/users/%s' % (group_id, user_id), '')
+        self.expected_success(204, resp.status)
         return resp, body
 
     def list_group_users(self, group_id):
         """List users in group."""
         resp, body = self.get('groups/%s/users' % group_id)
+        self.expected_success(200, resp.status)
         body = self._parse_group_users(etree.fromstring(body))
         return resp, body
 
     def list_user_groups(self, user_id):
         """Lists the groups which a user belongs to."""
         resp, body = self.get('users/%s/groups' % user_id)
+        self.expected_success(200, resp.status)
         body = self._parse_groups(etree.fromstring(body))
         return resp, body
 
     def delete_group_user(self, group_id, user_id):
         """Delete user in group."""
         resp, body = self.delete('groups/%s/users/%s' % (group_id, user_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def assign_user_role_on_project(self, project_id, user_id, role_id):
         """Add roles to a user on a project."""
         resp, body = self.put('projects/%s/users/%s/roles/%s' %
                               (project_id, user_id, role_id), '')
+        self.expected_success(204, resp.status)
         return resp, body
 
     def assign_user_role_on_domain(self, domain_id, user_id, role_id):
         """Add roles to a user on a domain."""
         resp, body = self.put('domains/%s/users/%s/roles/%s' %
                               (domain_id, user_id, role_id), '')
+        self.expected_success(204, resp.status)
         return resp, body
 
     def list_user_roles_on_project(self, project_id, user_id):
         """list roles of a user on a project."""
         resp, body = self.get('projects/%s/users/%s/roles' %
                               (project_id, user_id))
+        self.expected_success(200, resp.status)
         body = self._parse_roles(etree.fromstring(body))
         return resp, body
 
@@ -390,6 +425,7 @@
         """list roles of a user on a domain."""
         resp, body = self.get('domains/%s/users/%s/roles' %
                               (domain_id, user_id))
+        self.expected_success(200, resp.status)
         body = self._parse_roles(etree.fromstring(body))
         return resp, body
 
@@ -397,30 +433,35 @@
         """Delete role of a user on a project."""
         resp, body = self.delete('projects/%s/users/%s/roles/%s' %
                                  (project_id, user_id, role_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def revoke_role_from_user_on_domain(self, domain_id, user_id, role_id):
         """Delete role of a user on a domain."""
         resp, body = self.delete('domains/%s/users/%s/roles/%s' %
                                  (domain_id, user_id, role_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def assign_group_role_on_project(self, project_id, group_id, role_id):
         """Add roles to a user on a project."""
         resp, body = self.put('projects/%s/groups/%s/roles/%s' %
                               (project_id, group_id, role_id), '')
+        self.expected_success(204, resp.status)
         return resp, body
 
     def assign_group_role_on_domain(self, domain_id, group_id, role_id):
         """Add roles to a user on a domain."""
         resp, body = self.put('domains/%s/groups/%s/roles/%s' %
                               (domain_id, group_id, role_id), '')
+        self.expected_success(204, resp.status)
         return resp, body
 
     def list_group_roles_on_project(self, project_id, group_id):
         """list roles of a user on a project."""
         resp, body = self.get('projects/%s/groups/%s/roles' %
                               (project_id, group_id))
+        self.expected_success(200, resp.status)
         body = self._parse_roles(etree.fromstring(body))
         return resp, body
 
@@ -428,6 +469,7 @@
         """list roles of a user on a domain."""
         resp, body = self.get('domains/%s/groups/%s/roles' %
                               (domain_id, group_id))
+        self.expected_success(200, resp.status)
         body = self._parse_roles(etree.fromstring(body))
         return resp, body
 
@@ -435,12 +477,14 @@
         """Delete role of a user on a project."""
         resp, body = self.delete('projects/%s/groups/%s/roles/%s' %
                                  (project_id, group_id, role_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
     def revoke_role_from_group_on_domain(self, domain_id, group_id, role_id):
         """Delete role of a user on a domain."""
         resp, body = self.delete('domains/%s/groups/%s/roles/%s' %
                                  (domain_id, group_id, role_id))
+        self.expected_success(204, resp.status)
         return resp, body
 
 
diff --git a/tempest/services/identity/v3/xml/region_client.py b/tempest/services/identity/v3/xml/region_client.py
index 9f9161d..f854138 100644
--- a/tempest/services/identity/v3/xml/region_client.py
+++ b/tempest/services/identity/v3/xml/region_client.py
@@ -1,4 +1,4 @@
-# Copyright 2014 OpenStack Foundation
+# Copyright 2014 Hewlett-Packard Development Company, L.P
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tempest/services/identity/v3/xml/service_client.py b/tempest/services/identity/v3/xml/service_client.py
index 37ed892..3beeb89 100644
--- a/tempest/services/identity/v3/xml/service_client.py
+++ b/tempest/services/identity/v3/xml/service_client.py
@@ -51,6 +51,7 @@
                                         type=type)
         resp, body = self.patch('services/%s' % service_id,
                                 str(common.Document(update_service)))
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -58,6 +59,7 @@
         """Get Service."""
         url = 'services/%s' % service_id
         resp, body = self.get(url)
+        self.expected_success(200, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
@@ -68,10 +70,12 @@
                                    description=description,
                                    type=serv_type)
         resp, body = self.post("services", str(common.Document(post_body)))
+        self.expected_success(201, resp.status)
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
     def delete_service(self, serv_id):
         url = "services/" + serv_id
         resp, body = self.delete(url)
+        self.expected_success(204, resp.status)
         return resp, body
diff --git a/tempest/services/identity/xml/identity_client.py b/tempest/services/identity/xml/identity_client.py
index 886ce7b..4ada46c 100644
--- a/tempest/services/identity/xml/identity_client.py
+++ b/tempest/services/identity/xml/identity_client.py
@@ -29,11 +29,13 @@
         create_role = xml.Element("role", xmlns=XMLNS, name=name)
         resp, body = self.post('OS-KSADM/roles',
                                str(xml.Document(create_role)))
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def get_role(self, role_id):
         """Get a role by its id."""
         resp, body = self.get('OS-KSADM/roles/%s' % role_id)
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def create_tenant(self, name, **kwargs):
@@ -50,16 +52,18 @@
                                     description=kwargs.get('description', ''),
                                     enabled=str(en).lower())
         resp, body = self.post('tenants', str(xml.Document(create_tenant)))
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def list_tenants(self):
         """Returns tenants."""
         resp, body = self.get('tenants')
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def update_tenant(self, tenant_id, **kwargs):
         """Updates a tenant."""
-        resp, body = self.get_tenant(tenant_id)
+        _, body = self.get_tenant(tenant_id)
         name = kwargs.get('name', body['name'])
         desc = kwargs.get('description', body['description'])
         en = kwargs.get('enabled', body['enabled'])
@@ -72,6 +76,7 @@
 
         resp, body = self.post('tenants/%s' % tenant_id,
                                str(xml.Document(update_tenant)))
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def create_user(self, name, password, tenant_id, email, **kwargs):
@@ -87,6 +92,7 @@
             create_user.add_attr('enabled', str(kwargs['enabled']).lower())
 
         resp, body = self.post('users', str(xml.Document(create_user)))
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def update_user(self, user_id, **kwargs):
@@ -97,6 +103,7 @@
 
         resp, body = self.put('users/%s' % user_id,
                               str(xml.Document(update_user)))
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def enable_disable_user(self, user_id, enabled):
@@ -104,6 +111,7 @@
         enable_user = xml.Element("user", enabled=str(enabled).lower())
         resp, body = self.put('users/%s/enabled' % user_id,
                               str(xml.Document(enable_user)))
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def create_service(self, name, service_type, **kwargs):
@@ -116,6 +124,7 @@
                                      description=kwargs.get('description'))
         resp, body = self.post('OS-KSADM/services',
                                str(xml.Document(create_service)))
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def update_user_password(self, user_id, new_pass):
@@ -125,11 +134,13 @@
                                password=new_pass)
         resp, body = self.put('users/%s/OS-KSADM/password' % user_id,
                               str(xml.Document(put_body)))
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
     def list_extensions(self):
         """List all the extensions."""
         resp, body = self.get('/extensions')
+        self.expected_success(200, resp.status)
         return resp, self._parse_resp(body)
 
 
diff --git a/tempest/services/orchestration/json/orchestration_client.py b/tempest/services/orchestration/json/orchestration_client.py
index c459f28..d325eb5 100644
--- a/tempest/services/orchestration/json/orchestration_client.py
+++ b/tempest/services/orchestration/json/orchestration_client.py
@@ -259,3 +259,140 @@
             'parameters': parameters,
         }
         return self._validate_template(post_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)
+        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)
+        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)
+
+    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)
+        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)
+        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)
+        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)
+        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)
+        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)
+
+    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/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/stress/test_stress.py b/tempest/tests/stress/test_stress.py
index 5a334c5..3dc2199 100644
--- a/tempest/tests/stress/test_stress.py
+++ b/tempest/tests/stress/test_stress.py
@@ -32,7 +32,7 @@
         cmd = ' '.join([cmd, param])
         LOG.info("running: '%s'" % cmd)
         cmd_str = cmd
-        cmd = shlex.split(cmd)
+        cmd = shlex.split(cmd.encode('utf-8'))
         result = ''
         result_err = ''
         try:
diff --git a/tempest/tests/test_waiters.py b/tempest/tests/test_waiters.py
index 1f9825e..a29cb46 100644
--- a/tempest/tests/test_waiters.py
+++ b/tempest/tests/test_waiters.py
@@ -15,6 +15,7 @@
 import time
 
 import mock
+import testtools
 
 from tempest.common import waiters
 from tempest import exceptions
@@ -47,3 +48,221 @@
         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/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/test-requirements.txt b/test-requirements.txt
index 13ef291..cd8154b 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,6 +1,5 @@
 hacking>=0.9.2,<0.10
 # needed for doc build
-docutils==0.9.1
 sphinx>=1.1.2,!=1.2.0,<1.3
 python-subunit>=0.0.18
 oslosphinx
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 7f69fad..4f2465a 100644
--- a/tox.ini
+++ b/tox.ini
@@ -84,6 +84,11 @@
 deps = -r{toxinidir}/requirements.txt
        -r{toxinidir}/test-requirements.txt
 
+[testenv:docs]
+commands = python setup.py build_sphinx {posargs}
+deps = -r{toxinidir}/requirements.txt
+       -r{toxinidir}/test-requirements.txt
+
 [testenv:pep8]
 commands =
    flake8 {posargs}