Merge "Add test case for floating_ip response body"
diff --git a/doc/source/index.rst b/doc/source/index.rst
index bc4fc46..1f06bc5 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -37,6 +37,7 @@
    :maxdepth: 1
 
    cleanup
+   javelin
 
 ==================
 Indices and tables
diff --git a/doc/source/javelin.rst b/doc/source/javelin.rst
new file mode 100644
index 0000000..01090ca
--- /dev/null
+++ b/doc/source/javelin.rst
@@ -0,0 +1,5 @@
+----------------------------------------------------------
+Javelin2 - How to check that resources survived an upgrade
+----------------------------------------------------------
+
+.. automodule:: tempest.cmd.javelin
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 86dda80..2e1d6f3 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -33,28 +33,25 @@
 # Deprecated group/name - [DEFAULT]/log_config
 #log_config_append = <None>
 
-# Format string for %%(asctime)s in log records. Default: %(default)s
-# . (string value)
-#log_date_format = %Y-%m-%d %H:%M:%S
-
-# (Optional) The base directory used for relative --log-file paths.
-# (string value)
-# Deprecated group/name - [DEFAULT]/logdir
-#log_dir = <None>
-
-# (Optional) Name of log file to output to. If no default is set,
-# logging will go to stdout. (string value)
-# Deprecated group/name - [DEFAULT]/logfile
-#log_file = <None>
-
 # DEPRECATED. A logging.Formatter log message format string which may
 # use any of the available logging.LogRecord attributes. This option
 # is deprecated.  Please use logging_context_format_string and
 # logging_default_format_string instead. (string value)
 #log_format = <None>
 
-# Syslog facility to receive log lines. (string value)
-#syslog_log_facility = LOG_USER
+# Format string for %%(asctime)s in log records. Default: %(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 set,
+# logging will go to stdout. (string value)
+# Deprecated group/name - [DEFAULT]/logfile
+#log_file = <None>
+
+# (Optional) The base directory used for relative --log-file paths.
+# (string value)
+# Deprecated group/name - [DEFAULT]/logdir
+#log_dir = <None>
 
 # Use syslog for logging. Existing syslog format is DEPRECATED during
 # I, and will change in J to honor RFC5424. (boolean value)
@@ -66,6 +63,9 @@
 # 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
+
 #
 # From tempest.config
 #
@@ -77,9 +77,26 @@
 # From tempest.config
 #
 
+# 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. (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 value)
+#logging_debug_format_suffix = %(funcName)s %(pathname)s:%(lineno)d
+
+# 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,oslo.messaging=INFO,iso8601=WARN,requests.packages.urllib3.connectionpool=WARN,urllib3.connectionpool=WARN,websocket=WARN,keystonemiddleware=WARN,routes.middleware=WARN,stevedore=WARN
 
+# Enables or disables publication of error events. (boolean value)
+#publish_errors = false
+
 # Enables or disables fatal status of deprecations. (boolean value)
 #fatal_deprecations = false
 
@@ -91,23 +108,6 @@
 # (string value)
 #instance_uuid_format = "[instance: %(uuid)s] "
 
-# 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
-
-# Data to append to log format when level is DEBUG. (string value)
-#logging_debug_format_suffix = %(funcName)s %(pathname)s:%(lineno)d
-
-# 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
-
-# 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
-
-# Enables or disables publication of error events. (boolean value)
-#publish_errors = false
-
 
 [auth]
 
@@ -115,6 +115,10 @@
 # From tempest.config
 #
 
+# Path to the yaml file that contains the list of credentials to use
+# for running tests (string value)
+#test_accounts_file = etc/accounts.yaml
+
 # Allows test cases to create/destroy tenants and users. This option
 # requires that OpenStack Identity API admin credentials are known. If
 # false, isolated test cases and parallel execution, can still be
@@ -131,10 +135,6 @@
 # concurrent test processes. (boolean value)
 #locking_credentials_provider = false
 
-# Path to the yaml file that contains the list of credentials to use
-# for running tests (string value)
-#test_accounts_file = etc/accounts.yaml
-
 
 [baremetal]
 
@@ -142,6 +142,19 @@
 # From tempest.config
 #
 
+# Catalog type of the baremetal provisioning service (string value)
+#catalog_type = baremetal
+
+# Whether the Ironic nova-compute driver is enabled (boolean value)
+#driver_enabled = false
+
+# Driver name which Ironic uses (string value)
+#driver = fake
+
+# The endpoint type to use for the baremetal provisioning service
+# (string value)
+#endpoint_type = publicURL
+
 # Timeout for Ironic node to completely provision (integer value)
 #active_timeout = 300
 
@@ -149,19 +162,6 @@
 # value)
 #association_timeout = 30
 
-# Catalog type of the baremetal provisioning service (string value)
-#catalog_type = baremetal
-
-# Driver name which Ironic uses (string value)
-#driver = fake
-
-# Whether the Ironic nova-compute driver is enabled (boolean value)
-#driver_enabled = false
-
-# The endpoint type to use for the baremetal provisioning service
-# (string value)
-#endpoint_type = publicURL
-
 # Timeout for Ironic power transitions. (integer value)
 #power_timeout = 60
 
@@ -175,47 +175,47 @@
 # From tempest.config
 #
 
-# AKI Kernel Image manifest (string value)
-#aki_manifest = cirros-0.3.0-x86_64-vmlinuz.manifest.xml
+# EC2 URL (string value)
+#ec2_url = http://localhost:8773/services/Cloud
 
-# AMI Machine Image manifest (string value)
-#ami_manifest = cirros-0.3.0-x86_64-blank.img.manifest.xml
-
-# ARI Ramdisk Image manifest (string value)
-#ari_manifest = cirros-0.3.0-x86_64-initrd.manifest.xml
-
-# AWS Access Key (string value)
-#aws_access = <None>
+# S3 URL (string value)
+#s3_url = http://localhost:8080
 
 # AWS Secret Key (string value)
 #aws_secret = <None>
 
+# AWS Access Key (string value)
+#aws_access = <None>
+
 # AWS Zone for EC2 tests (string value)
 #aws_zone = nova
 
-# Status Change Test Interval (integer value)
-#build_interval = 1
-
-# Status Change Timeout (integer value)
-#build_timeout = 60
-
-# EC2 URL (string value)
-#ec2_url = http://localhost:8773/services/Cloud
-
-# boto Http socket timeout (integer value)
-#http_socket_timeout = 3
-
-# Instance type (string value)
-#instance_type = m1.tiny
-
-# boto num_retries on error (integer value)
-#num_retries = 1
-
 # S3 Materials Path (string value)
 #s3_materials_path = /opt/stack/devstack/files/images/s3-materials/cirros-0.3.0
 
-# S3 URL (string value)
-#s3_url = http://localhost:8080
+# ARI Ramdisk Image manifest (string value)
+#ari_manifest = cirros-0.3.0-x86_64-initrd.manifest.xml
+
+# AMI Machine Image manifest (string value)
+#ami_manifest = cirros-0.3.0-x86_64-blank.img.manifest.xml
+
+# AKI Kernel Image manifest (string value)
+#aki_manifest = cirros-0.3.0-x86_64-vmlinuz.manifest.xml
+
+# Instance type (string value)
+#instance_type = m1.tiny
+
+# boto Http socket timeout (integer value)
+#http_socket_timeout = 3
+
+# boto num_retries on error (integer value)
+#num_retries = 1
+
+# Status Change Timeout (integer value)
+#build_timeout = 60
+
+# Status Change Test Interval (integer value)
+#build_interval = 1
 
 
 [cli]
@@ -224,12 +224,12 @@
 # From tempest.config
 #
 
-# directory where python client binaries are located (string value)
-#cli_dir = /usr/local/bin
-
 # enable cli tests (boolean value)
 #enabled = true
 
+# directory where python client binaries are located (string value)
+#cli_dir = /usr/local/bin
+
 # Whether the tempest run location has access to the *-manage
 # commands. In a pure blackbox environment it will not. (boolean
 # value)
@@ -245,44 +245,6 @@
 # From tempest.config
 #
 
-# Time in seconds between build status checks. (integer value)
-#build_interval = 1
-
-# Timeout in seconds to wait for an instance to build. (integer value)
-#build_timeout = 300
-
-# Catalog type of the Compute service. (string value)
-#catalog_type = compute
-
-# Catalog type of the Compute v3 service. (string value)
-#catalog_v3_type = computev3
-
-# The endpoint type to use for the compute service. (string value)
-#endpoint_type = publicURL
-
-# Name of the fixed network that is visible to all test tenants.
-# (string value)
-#fixed_network_name = private
-
-# Valid primary flavor to use in tests. (string value)
-#flavor_ref = 1
-
-# Valid secondary flavor to be used in tests. (string value)
-#flavor_ref_alt = 2
-
-# Unallocated floating IP range, which will be used to test the
-# floating IP bulk feature for CRUD operation. This block must not
-# overlap an existing floating IP pool. (string value)
-#floating_ip_range = 10.0.0.0/29
-
-# Password used to authenticate to an instance using the alternate
-# image. (string value)
-#image_alt_ssh_password = password
-
-# User name used to authenticate to an instance using the alternate
-# image. (string value)
-#image_alt_ssh_user = root
-
 # Valid primary image reference to be used in tests. This is a
 # required option (string value)
 #image_ref = <None>
@@ -292,44 +254,37 @@
 # value of image_ref above (string value)
 #image_ref_alt = <None>
 
-# Password used to authenticate to an instance. (string value)
-#image_ssh_password = password
+# Valid primary flavor to use in tests. (string value)
+#flavor_ref = 1
+
+# Valid secondary flavor to be used in tests. (string value)
+#flavor_ref_alt = 2
 
 # User name used to authenticate to an instance. (string value)
 #image_ssh_user = root
 
-# IP version used for SSH connections. (integer value)
-#ip_version_for_ssh = 4
+# Password used to authenticate to an instance. (string value)
+#image_ssh_password = password
 
-# Network used for SSH connections. Ignored if
-# use_floatingip_for_ssh=true or run_ssh=false. (string value)
-#network_for_ssh = public
+# User name used to authenticate to an instance using the alternate
+# image. (string value)
+#image_alt_ssh_user = root
 
-# Path to a private key file for SSH access to remote hosts (string
+# Password used to authenticate to an instance using the alternate
+# image. (string value)
+#image_alt_ssh_password = password
+
+# Time in seconds between build status checks. (integer value)
+#build_interval = 1
+
+# Timeout in seconds to wait for an instance to build. Other services
+# that do not define build_timeout will inherit this value. (integer
 # value)
-#path_to_private_key = <None>
-
-# Timeout in seconds to wait for ping to succeed. (integer value)
-#ping_timeout = 120
-
-# Additional wait time for clean state, when there is no OS-EXT-STS
-# extension available (integer value)
-#ready_wait = 0
-
-# The compute region name to use. If empty, the value of
-# identity.region is used instead. If no such region is found in the
-# service catalog, the first found one is used. (string value)
-#region =
+#build_timeout = 300
 
 # Should the tests ssh to instances? (boolean value)
 #run_ssh = false
 
-# Time in seconds before a shelved instance is eligible for removing
-# from a host.  -1 never offload, 0 offload when shelved. This time
-# should be the same as the time of nova.conf, and some tests will run
-# for as long as the time. (integer value)
-#shelved_offload_time = 0
-
 # Auth method used for authenticate to the instance. Valid choices
 # are: keypair, configured, adminpass. keypair: start the servers with
 # an ssh keypair. configured: use the configured user and password.
@@ -337,49 +292,72 @@
 # when it is an option. (string value)
 #ssh_auth_method = keypair
 
-# Timeout in seconds to wait for output from ssh channel. (integer
-# value)
-#ssh_channel_timeout = 60
-
 # How to connect to the instance? fixed: using the first ip belongs
 # the fixed network floating: creating and using a floating ip (string
 # value)
 #ssh_connect_method = fixed
 
+# User name used to authenticate to an instance. (string value)
+#ssh_user = root
+
+# Timeout in seconds to wait for ping to succeed. (integer value)
+#ping_timeout = 120
+
 # Timeout in seconds to wait for authentication to succeed. (integer
 # value)
 #ssh_timeout = 300
 
-# User name used to authenticate to an instance. (string value)
-#ssh_user = root
+# Additional wait time for clean state, when there is no OS-EXT-STS
+# extension available (integer value)
+#ready_wait = 0
+
+# Timeout in seconds to wait for output from ssh channel. (integer
+# value)
+#ssh_channel_timeout = 60
+
+# Name of the fixed network that is visible to all test tenants.
+# (string value)
+#fixed_network_name = private
+
+# Network used for SSH connections. Ignored if
+# use_floatingip_for_ssh=true or run_ssh=false. (string value)
+#network_for_ssh = public
+
+# IP version used for SSH connections. (integer value)
+#ip_version_for_ssh = 4
 
 # Does SSH use Floating IPs? (boolean value)
 #use_floatingip_for_ssh = true
 
+# Catalog type of the Compute service. (string value)
+#catalog_type = compute
+
+# The compute region name to use. If empty, the value of
+# identity.region is used instead. If no such region is found in the
+# service catalog, the first found one is used. (string value)
+#region =
+
+# The endpoint type to use for the compute service. (string value)
+#endpoint_type = publicURL
+
+# Path to a private key file for SSH access to remote hosts (string
+# value)
+#path_to_private_key = <None>
+
 # Expected device name when a volume is attached to an instance
 # (string value)
 #volume_device_name = vdb
 
+# Time in seconds before a shelved instance is eligible for removing
+# from a host.  -1 never offload, 0 offload when shelved. This time
+# should be the same as the time of nova.conf, and some tests will run
+# for as long as the time. (integer value)
+#shelved_offload_time = 0
 
-[compute-admin]
-
-#
-# From tempest.config
-#
-
-# Domain name for authentication as admin (Keystone V3).The same
-# domain applies to user and project (string value)
-#domain_name = <None>
-
-# API key to use when authenticating as admin. (string value)
-#password = <None>
-
-# Administrative Tenant name to use for Nova API requests. (string
-# value)
-#tenant_name = <None>
-
-# Administrative Username to use for Nova API requests. (string value)
-#username = <None>
+# Unallocated floating IP range, which will be used to test the
+# floating IP bulk feature for CRUD operation. This block must not
+# overlap an existing floating IP pool. (string value)
+#floating_ip_range = 10.0.0.0/29
 
 
 [compute-feature-enabled]
@@ -388,29 +366,15 @@
 # From tempest.config
 #
 
+# If false, skip disk config tests (boolean value)
+#disk_config = true
+
 # A list of enabled compute extensions with a special entry all which
 # indicates every extension is enabled. Each extension should be
 # specified with alias name. Empty list indicates all extensions are
 # disabled (list value)
 #api_extensions = all
 
-# If false, skip all nova v3 tests. (boolean value)
-#api_v3 = false
-
-# A list of enabled v3 extensions with a special entry all which
-# indicates every extension is enabled. Each extension should be
-# specified with alias name. Empty list indicates all extensions are
-# disabled (list value)
-#api_v3_extensions = all
-
-# Does the test environment block migration support cinder iSCSI
-# volumes (boolean value)
-#block_migrate_cinder_iscsi = false
-
-# Does the test environment use block devices for live migration
-# (boolean value)
-#block_migration_for_live_migration = false
-
 # Does the test environment support changing the admin password?
 # (boolean value)
 #change_password = false
@@ -419,23 +383,38 @@
 # output? (boolean value)
 #console_output = true
 
-# If false, skip disk config tests (boolean value)
-#disk_config = true
+# Does the test environment support resizing? (boolean value)
+#resize = false
 
-# Enables returning of the instance password by the relevant server
-# API calls such as create, rebuild or rescue. (boolean value)
-#enable_instance_password = true
+# Does the test environment support pausing? (boolean value)
+#pause = true
 
-# Does the test environment support dynamic network interface
-# attachment? (boolean value)
-#interface_attach = true
+# Does the test environment support shelving/unshelving? (boolean
+# value)
+#shelve = true
+
+# Does the test environment support suspend/resume? (boolean value)
+#suspend = true
 
 # Does the test environment support live migration available? (boolean
 # value)
 #live_migration = true
 
-# Does the test environment support pausing? (boolean value)
-#pause = true
+# Does the test environment use block devices for live migration
+# (boolean value)
+#block_migration_for_live_migration = false
+
+# Does the test environment block migration support cinder iSCSI
+# volumes (boolean value)
+#block_migrate_cinder_iscsi = false
+
+# Enable VNC console. This configuration value should be same as
+# [nova.vnc]->vnc_enabled in nova.conf (boolean value)
+#vnc_console = false
+
+# Enable Spice console. This configuration value should be same as
+# [nova.spice]->enabled in nova.conf (boolean value)
+#spice_console = false
 
 # Enable RDP console. This configuration value should be same as
 # [nova.rdp]->enabled in nova.conf (boolean value)
@@ -445,28 +424,18 @@
 # value)
 #rescue = true
 
-# Does the test environment support resizing? (boolean value)
-#resize = false
+# Enables returning of the instance password by the relevant server
+# API calls such as create, rebuild or rescue. (boolean value)
+#enable_instance_password = true
 
-# Does the test environment support shelving/unshelving? (boolean
-# value)
-#shelve = true
+# Does the test environment support dynamic network interface
+# attachment? (boolean value)
+#interface_attach = true
 
 # Does the test environment support creating snapshot images of
 # running instances? (boolean value)
 #snapshot = true
 
-# Enable Spice console. This configuration value should be same as
-# [nova.spice]->enabled in nova.conf (boolean value)
-#spice_console = false
-
-# Does the test environment support suspend/resume? (boolean value)
-#suspend = true
-
-# Enable VNC console. This configuration value should be same as
-# [nova.vnc]->vnc_enabled in nova.conf (boolean value)
-#vnc_console = false
-
 
 [dashboard]
 
@@ -504,12 +473,12 @@
 # Catalog type of the Database service. (string value)
 #catalog_type = database
 
-# Current database version to use in database tests. (string value)
-#db_current_version = v1.0
-
 # Valid primary flavor to use in database tests. (string value)
 #db_flavor_ref = 1
 
+# Current database version to use in database tests. (string value)
+#db_current_version = v1.0
+
 
 [debug]
 
@@ -538,71 +507,15 @@
 # From tempest.config
 #
 
-# Admin domain name for authentication (Keystone V3).The same domain
-# applies to user and project (string value)
-#admin_domain_name = <None>
-
-# API key to use when authenticating as admin. (string value)
-#admin_password = <None>
-
-# Role required to administrate keystone. (string value)
-#admin_role = admin
-
-# Administrative Tenant name to use for Keystone API requests. (string
-# value)
-#admin_tenant_name = <None>
-
-# Administrative Username to use for Keystone API requests. (string
-# value)
-#admin_username = <None>
-
-# Alternate domain name for authentication (Keystone V3).The same
-# domain applies to user and project (string value)
-#alt_domain_name = <None>
-
-# API key to use when authenticating as alternate user. (string value)
-#alt_password = <None>
-
-# Alternate user's Tenant name to use for Nova API requests. (string
-# value)
-#alt_tenant_name = <None>
-
-# Username of alternate user to use for Nova API requests. (string
-# value)
-#alt_username = <None>
-
-# Identity API version to be used for authentication for API tests.
-# (string value)
-#auth_version = v2
-
-# Specify a CA bundle file to use in verifying a TLS (https) server
-# certificate. (string value)
-#ca_certificates_file = <None>
-
 # Catalog type of the Identity service. (string value)
 #catalog_type = identity
 
 # Set to True if using self-signed SSL certificates. (boolean value)
 #disable_ssl_certificate_validation = false
 
-# Domain name for authentication (Keystone V3).The same domain applies
-# to user and project (string value)
-#domain_name = <None>
-
-# The endpoint type to use for the identity service. (string value)
-#endpoint_type = publicURL
-
-# API key to use when authenticating. (string value)
-#password = <None>
-
-# The identity region name to use. Also used as the other services'
-# region name unless they are set explicitly. If no such region is
-# found in the service catalog, the first found one is used. (string
-# value)
-#region = RegionOne
-
-# Tenant name to use for Nova API requests. (string value)
-#tenant_name = <None>
+# Specify a CA bundle file to use in verifying a TLS (https) server
+# certificate. (string value)
+#ca_certificates_file = <None>
 
 # Full URI of the OpenStack Identity API (Keystone), v2 (string value)
 #uri = <None>
@@ -610,9 +523,65 @@
 # Full URI of the OpenStack Identity API (Keystone), v3 (string value)
 #uri_v3 = <None>
 
+# Identity API version to be used for authentication for API tests.
+# (string value)
+#auth_version = v2
+
+# The identity region name to use. Also used as the other services'
+# region name unless they are set explicitly. If no such region is
+# found in the service catalog, the first found one is used. (string
+# value)
+#region = RegionOne
+
+# The endpoint type to use for the identity service. (string value)
+#endpoint_type = publicURL
+
 # Username to use for Nova API requests. (string value)
 #username = <None>
 
+# Tenant name to use for Nova API requests. (string value)
+#tenant_name = <None>
+
+# Role required to administrate keystone. (string value)
+#admin_role = admin
+
+# API key to use when authenticating. (string value)
+#password = <None>
+
+# Domain name for authentication (Keystone V3).The same domain applies
+# to user and project (string value)
+#domain_name = <None>
+
+# Username of alternate user to use for Nova API requests. (string
+# value)
+#alt_username = <None>
+
+# Alternate user's Tenant name to use for Nova API requests. (string
+# value)
+#alt_tenant_name = <None>
+
+# API key to use when authenticating as alternate user. (string value)
+#alt_password = <None>
+
+# Alternate domain name for authentication (Keystone V3).The same
+# domain applies to user and project (string value)
+#alt_domain_name = <None>
+
+# Administrative Username to use for Keystone API requests. (string
+# value)
+#admin_username = <None>
+
+# Administrative Tenant name to use for Keystone API requests. (string
+# value)
+#admin_tenant_name = <None>
+
+# API key to use when authenticating as admin. (string value)
+#admin_password = <None>
+
+# Admin domain name for authentication (Keystone V3).The same domain
+# applies to user and project (string value)
+#admin_domain_name = <None>
+
 
 [identity-feature-enabled]
 
@@ -620,16 +589,16 @@
 # From tempest.config
 #
 
+# Does the identity service have delegation and impersonation enabled
+# (boolean value)
+#trust = true
+
 # Is the v2 identity API enabled (boolean value)
 #api_v2 = true
 
 # Is the v3 identity API enabled (boolean value)
 #api_v3 = true
 
-# Does the identity service have delegation and impersonation enabled
-# (boolean value)
-#trust = true
-
 
 [image]
 
@@ -640,16 +609,24 @@
 # Catalog type of the Image service. (string value)
 #catalog_type = image
 
+# The image region name to use. If empty, the value of identity.region
+# is used instead. If no such region is found in the service catalog,
+# the first found one is used. (string value)
+#region =
+
 # The endpoint type to use for the image service. (string value)
 #endpoint_type = publicURL
 
 # http accessible image (string value)
 #http_image = http://download.cirros-cloud.net/0.3.1/cirros-0.3.1-x86_64-uec.tar.gz
 
-# The image region name to use. If empty, the value of identity.region
-# is used instead. If no such region is found in the service catalog,
-# the first found one is used. (string value)
-#region =
+# Timeout in seconds to wait for an image to become available.
+# (integer value)
+#build_timeout = 300
+
+# Time in seconds between image operation status checks. (integer
+# value)
+#build_interval = 1
 
 
 [image-feature-enabled]
@@ -658,12 +635,12 @@
 # From tempest.config
 #
 
-# Is the v1 image API enabled (boolean value)
-#api_v1 = true
-
 # Is the v2 image API enabled (boolean value)
 #api_v2 = true
 
+# Is the v1 image API enabled (boolean value)
+#api_v1 = true
+
 
 [input-scenario]
 
@@ -671,12 +648,12 @@
 # From tempest.config
 #
 
-# Matching flavors become parameters for scenario tests (string value)
-#flavor_regex = ^m1.nano$
-
 # Matching images become parameters for scenario tests (string value)
 #image_regex = ^cirros-0.3.1-x86_64-uec$
 
+# Matching flavors become parameters for scenario tests (string value)
+#flavor_regex = ^m1.nano$
+
 # SSH verification in tests is skippedfor matching images (string
 # value)
 #non_ssh_image_regex = ^.*[Ww]in.*$
@@ -694,31 +671,31 @@
 # Catalog type of the Messaging service. (string value)
 #catalog_type = messaging
 
-# The maximum grace period for a claim (integer value)
-#max_claim_grace = 43200
+# The maximum number of queue records per page when listing queues
+# (integer value)
+#max_queues_per_page = 20
 
-# The maximum ttl for a claim (integer value)
-#max_claim_ttl = 43200
-
-# The maximum size of a message body (integer value)
-#max_message_size = 262144
-
-# The maximum ttl for a message (integer value)
-#max_message_ttl = 1209600
-
-# The maximum number of messages per claim (integer value)
-#max_messages_per_claim = 20
+# The maximum metadata size for a queue (integer value)
+#max_queue_metadata = 65536
 
 # The maximum number of queue message per page when listing (or)
 # posting messages (integer value)
 #max_messages_per_page = 20
 
-# The maximum metadata size for a queue (integer value)
-#max_queue_metadata = 65536
+# The maximum size of a message body (integer value)
+#max_message_size = 262144
 
-# The maximum number of queue records per page when listing queues
-# (integer value)
-#max_queues_per_page = 20
+# The maximum number of messages per claim (integer value)
+#max_messages_per_claim = 20
+
+# The maximum ttl for a message (integer value)
+#max_message_ttl = 1209600
+
+# The maximum ttl for a claim (integer value)
+#max_claim_ttl = 43200
+
+# The maximum grace period for a claim (integer value)
+#max_claim_grace = 43200
 
 
 [negative]
@@ -737,39 +714,17 @@
 # From tempest.config
 #
 
-# Time in seconds between network operation status checks. (integer
-# value)
-#build_interval = 1
-
-# Timeout in seconds to wait for network operation to complete.
-# (integer value)
-#build_timeout = 300
-
 # Catalog type of the Neutron service. (string value)
 #catalog_type = network
 
-# List of dns servers whichs hould be used for subnet creation (list
-# value)
-#dns_servers = 8.8.8.8,8.8.4.4
-
-# The endpoint type to use for the network service. (string value)
-#endpoint_type = publicURL
-
-# Id of the public network that provides external connectivity (string
-# value)
-#public_network_id =
-
-# Id of the public router that provides external connectivity. This
-# should only be used when Neutron's 'allow_overlapping_ips' is set to
-# 'False' in neutron.conf. usually not needed past 'Grizzly' release
-# (string value)
-#public_router_id =
-
 # The network region name to use. If empty, the value of
 # identity.region is used instead. If no such region is found in the
 # service catalog, the first found one is used. (string value)
 #region =
 
+# The endpoint type to use for the network service. (string value)
+#endpoint_type = publicURL
+
 # The cidr block to allocate tenant ipv4 subnets from (string value)
 #tenant_network_cidr = 10.100.0.0/16
 
@@ -786,6 +741,28 @@
 # (boolean value)
 #tenant_networks_reachable = false
 
+# Id of the public network that provides external connectivity (string
+# value)
+#public_network_id =
+
+# Id of the public router that provides external connectivity. This
+# should only be used when Neutron's 'allow_overlapping_ips' is set to
+# 'False' in neutron.conf. usually not needed past 'Grizzly' release
+# (string value)
+#public_router_id =
+
+# Timeout in seconds to wait for network operation to complete.
+# (integer value)
+#build_timeout = 300
+
+# Time in seconds between network operation status checks. (integer
+# value)
+#build_interval = 1
+
+# List of dns servers which should be used for subnet creation (list
+# value)
+#dns_servers = 8.8.8.8,8.8.4.4
+
 
 [network-feature-enabled]
 
@@ -793,14 +770,14 @@
 # From tempest.config
 #
 
+# Allow the execution of IPv6 tests (boolean value)
+#ipv6 = true
+
 # A list of enabled network extensions with a special entry all which
 # indicates every extension is enabled. Empty list indicates all
 # extensions are disabled (list value)
 #api_extensions = all
 
-# Allow the execution of IPv6 tests (boolean value)
-#ipv6 = true
-
 # Allow the execution of IPv6 subnet tests that use the extended IPv6
 # attributes ipv6_ra_mode and ipv6_address_mode (boolean value)
 #ipv6_subnet_attributes = false
@@ -815,27 +792,27 @@
 # Catalog type of the Object-Storage service. (string value)
 #catalog_type = object-store
 
-# Number of seconds to wait while looping to check the status of a
-# container to container synchronization (integer value)
-#container_sync_interval = 5
-
-# Number of seconds to time on waiting for a container to container
-# synchronization complete. (integer value)
-#container_sync_timeout = 120
+# The object-storage region name to use. If empty, the value of
+# identity.region is used instead. If no such region is found in the
+# service catalog, the first found one is used. (string value)
+#region =
 
 # The endpoint type to use for the object-store service. (string
 # value)
 #endpoint_type = publicURL
 
+# Number of seconds to time on waiting for a container to container
+# synchronization complete. (integer value)
+#container_sync_timeout = 120
+
+# Number of seconds to wait while looping to check the status of a
+# container to container synchronization (integer value)
+#container_sync_interval = 5
+
 # Role to add to users created for swift tests to enable creating
 # containers (string value)
 #operator_role = Member
 
-# The object-storage region name to use. If empty, the value of
-# identity.region is used instead. If no such region is found in the
-# service catalog, the first found one is used. (string value)
-#region =
-
 # User role that has reseller admin (string value)
 #reseller_admin_role = ResellerAdmin
 
@@ -846,20 +823,20 @@
 # From tempest.config
 #
 
-# Execute (old style) container-sync tests (boolean value)
-#container_sync = true
-
-# Execute discoverability tests (boolean value)
-#discoverability = true
-
 # A list of the enabled optional discoverable apis. A single entry,
 # all, indicates that all of these features are expected to be enabled
 # (list value)
 #discoverable_apis = all
 
+# Execute (old style) container-sync tests (boolean value)
+#container_sync = true
+
 # Execute object-versioning tests (boolean value)
 #object_versioning = true
 
+# Execute discoverability tests (boolean value)
+#discoverability = true
+
 
 [orchestration]
 
@@ -867,42 +844,42 @@
 # From tempest.config
 #
 
+# Catalog type of the Orchestration service. (string value)
+#catalog_type = orchestration
+
+# The orchestration region name to use. If empty, the value of
+# identity.region is used instead. If no such region is found in the
+# service catalog, the first found one is used. (string value)
+#region =
+
+# The endpoint type to use for the orchestration service. (string
+# value)
+#endpoint_type = publicURL
+
 # Time in seconds between build status checks. (integer value)
 #build_interval = 1
 
 # Timeout in seconds to wait for a stack to build. (integer value)
 #build_timeout = 1200
 
-# Catalog type of the Orchestration service. (string value)
-#catalog_type = orchestration
-
-# The endpoint type to use for the orchestration service. (string
-# value)
-#endpoint_type = publicURL
+# Instance type for tests. Needs to be big enough for a full OS plus
+# the test workload (string value)
+#instance_type = m1.micro
 
 # Name of heat-cfntools enabled image to use when launching test
 # instances. (string value)
 #image_ref = <None>
 
-# Instance type for tests. Needs to be big enough for a full OS plus
-# the test workload (string value)
-#instance_type = m1.micro
-
 # Name of existing keypair to launch servers with. (string value)
 #keypair_name = <None>
 
 # Value must match heat configuration of the same name. (integer
 # value)
-#max_resources_per_stack = 1000
+#max_template_size = 524288
 
 # Value must match heat configuration of the same name. (integer
 # value)
-#max_template_size = 524288
-
-# The orchestration region name to use. If empty, the value of
-# identity.region is used instead. If no such region is found in the
-# service catalog, the first found one is used. (string value)
-#region =
+#max_resources_per_stack = 1000
 
 
 [scenario]
@@ -911,8 +888,18 @@
 # From tempest.config
 #
 
-# AKI image file name (string value)
-#aki_img_file = cirros-0.3.1-x86_64-vmlinuz
+# Directory containing image files (string value)
+#img_dir = /opt/stack/new/devstack/files/images/cirros-0.3.1-x86_64-uec
+
+# Image file name (string value)
+# Deprecated group/name - [DEFAULT]/qcow2_img_file
+#img_file = cirros-0.3.1-x86_64-disk.img
+
+# Image disk format (string value)
+#img_disk_format = qcow2
+
+# Image container format (string value)
+#img_container_format = bare
 
 # AMI image file name (string value)
 #ami_img_file = cirros-0.3.1-x86_64-blank.img
@@ -920,26 +907,16 @@
 # ARI image file name (string value)
 #ari_img_file = cirros-0.3.1-x86_64-initrd
 
-# Image container format (string value)
-#img_container_format = bare
+# AKI image file name (string value)
+#aki_img_file = cirros-0.3.1-x86_64-vmlinuz
 
-# Directory containing image files (string value)
-#img_dir = /opt/stack/new/devstack/files/images/cirros-0.3.1-x86_64-uec
-
-# Image disk format (string value)
-#img_disk_format = qcow2
-
-# Image file name (string value)
-# Deprecated group/name - [DEFAULT]/qcow2_img_file
-#img_file = cirros-0.3.1-x86_64-disk.img
+# ssh username for the image file (string value)
+#ssh_user = cirros
 
 # specifies how many resources to request at once. Used for large
 # operations testing. (integer value)
 #large_ops_number = 0
 
-# ssh username for the image file (string value)
-#ssh_user = cirros
-
 
 [service_available]
 
@@ -947,36 +924,36 @@
 # From tempest.config
 #
 
-# Whether or not Ceilometer is expected to be available (boolean
-# value)
-#ceilometer = true
-
 # Whether or not cinder is expected to be available (boolean value)
 #cinder = true
 
-# Whether or not glance is expected to be available (boolean value)
-#glance = true
-
-# Whether or not Heat is expected to be available (boolean value)
-#heat = false
-
-# Whether or not Horizon is expected to be available (boolean value)
-#horizon = true
-
-# Whether or not Ironic is expected to be available (boolean value)
-#ironic = false
-
 # Whether or not neutron is expected to be available (boolean value)
 #neutron = false
 
+# Whether or not glance is expected to be available (boolean value)
+#glance = true
+
+# Whether or not swift is expected to be available (boolean value)
+#swift = true
+
 # Whether or not nova is expected to be available (boolean value)
 #nova = true
 
+# Whether or not Heat is expected to be available (boolean value)
+#heat = false
+
+# Whether or not Ceilometer is expected to be available (boolean
+# value)
+#ceilometer = true
+
+# Whether or not Horizon is expected to be available (boolean value)
+#horizon = true
+
 # Whether or not Sahara is expected to be available (boolean value)
 #sahara = false
 
-# Whether or not swift is expected to be available (boolean value)
-#swift = true
+# Whether or not Ironic is expected to be available (boolean value)
+#ironic = false
 
 # Whether or not Trove is expected to be available (boolean value)
 #trove = false
@@ -991,40 +968,40 @@
 # From tempest.config
 #
 
+# Directory containing log files on the compute nodes (string value)
+#nova_logdir = <None>
+
+# Maximum number of instances to create during test. (integer value)
+#max_instances = 16
+
 # Controller host. (string value)
 #controller = <None>
 
+# Controller host. (string value)
+#target_controller = <None>
+
+# ssh user. (string value)
+#target_ssh_user = <None>
+
+# Path to private key. (string value)
+#target_private_key_path = <None>
+
+# regexp for list of log files. (string value)
+#target_logfiles = <None>
+
+# time (in seconds) between log file error checks. (integer value)
+#log_check_interval = 60
+
 # The number of threads created while stress test. (integer value)
 #default_thread_number_per_action = 4
 
-# Allows a full cleaning process after a stress test. Caution : this
-# cleanup will remove every objects of every tenant. (boolean value)
-#full_clean_stack = false
-
 # Prevent the cleaning (tearDownClass()) between each stress test run
 # if an exception occurs during this run. (boolean value)
 #leave_dirty_stack = false
 
-# time (in seconds) between log file error checks. (integer value)
-#log_check_interval = 60
-
-# Maximum number of instances to create during test. (integer value)
-#max_instances = 16
-
-# Directory containing log files on the compute nodes (string value)
-#nova_logdir = <None>
-
-# Controller host. (string value)
-#target_controller = <None>
-
-# regexp for list of log files. (string value)
-#target_logfiles = <None>
-
-# Path to private key. (string value)
-#target_private_key_path = <None>
-
-# ssh user. (string value)
-#target_ssh_user = <None>
+# Allows a full cleaning process after a stress test. Caution : this
+# cleanup will remove every objects of every tenant. (boolean value)
+#full_clean_stack = false
 
 
 [telemetry]
@@ -1050,14 +1027,6 @@
 # From tempest.config
 #
 
-# Name of the backend1 (must be declared in cinder.conf) (string
-# value)
-#backend1_name = BACKEND_1
-
-# Name of the backend2 (must be declared in cinder.conf) (string
-# value)
-#backend2_name = BACKEND_2
-
 # Time in seconds between volume availability checks. (integer value)
 #build_interval = 1
 
@@ -1068,23 +1037,31 @@
 # Catalog type of the Volume Service (string value)
 #catalog_type = volume
 
-# Disk format to use when copying a volume to image (string value)
-#disk_format = raw
-
-# The endpoint type to use for the volume service. (string value)
-#endpoint_type = publicURL
-
 # The volume region name to use. If empty, the value of
 # identity.region is used instead. If no such region is found in the
 # service catalog, the first found one is used. (string value)
 #region =
 
+# The endpoint type to use for the volume service. (string value)
+#endpoint_type = publicURL
+
+# Name of the backend1 (must be declared in cinder.conf) (string
+# value)
+#backend1_name = BACKEND_1
+
+# Name of the backend2 (must be declared in cinder.conf) (string
+# value)
+#backend2_name = BACKEND_2
+
 # Backend protocol to target when creating volume types (string value)
 #storage_protocol = iSCSI
 
 # Backend vendor to target when creating volume types (string value)
 #vendor_name = Open Source
 
+# Disk format to use when copying a volume to image (string value)
+#disk_format = raw
+
 # Default size in GB for volumes created by volumes tests (integer
 # value)
 #volume_size = 1
@@ -1096,6 +1073,15 @@
 # From tempest.config
 #
 
+# Runs Cinder multi-backend test (requires 2 backends) (boolean value)
+#multi_backend = false
+
+# Runs Cinder volumes backup test (boolean value)
+#backup = true
+
+# Runs Cinder volume snapshot test (boolean value)
+#snapshot = true
+
 # A list of enabled volume extensions with a special entry all which
 # indicates every extension is enabled. Empty list indicates all
 # extensions are disabled (list value)
@@ -1106,12 +1092,3 @@
 
 # Is the v2 volume API enabled (boolean value)
 #api_v2 = true
-
-# Runs Cinder volumes backup test (boolean value)
-#backup = true
-
-# Runs Cinder multi-backend test (requires 2 backends) (boolean value)
-#multi_backend = false
-
-# Runs Cinder volume snapshot test (boolean value)
-#snapshot = true
diff --git a/requirements.txt b/requirements.txt
index f9d8036..a6e7dd1 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -10,7 +10,7 @@
 paramiko>=1.13.0
 netaddr>=0.7.12
 python-ceilometerclient>=1.0.6
-python-glanceclient>=0.14.0
+python-glanceclient>=0.15.0
 python-keystoneclient>=0.11.1
 python-novaclient>=2.18.0
 python-neutronclient>=2.3.6,<3
diff --git a/tempest/api/compute/images/test_image_metadata.py b/tempest/api/compute/images/test_image_metadata.py
index 5105e2f..38e55b1 100644
--- a/tempest/api/compute/images/test_image_metadata.py
+++ b/tempest/api/compute/images/test_image_metadata.py
@@ -37,10 +37,10 @@
         cls.image_id = None
 
         name = data_utils.rand_name('image')
-        resp, body = cls.glance_client.create_image(name=name,
-                                                    container_format='bare',
-                                                    disk_format='raw',
-                                                    is_public=False)
+        body = cls.glance_client.create_image(name=name,
+                                              container_format='bare',
+                                              disk_format='raw',
+                                              is_public=False)
         cls.image_id = body['id']
         cls.images.append(cls.image_id)
         image_file = StringIO.StringIO(('*' * 1024))
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index ceab4f9..d9a7201 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -42,10 +42,10 @@
 
         def _create_image():
             name = data_utils.rand_name('image')
-            _, body = cls.glance_client.create_image(name=name,
-                                                     container_format='bare',
-                                                     disk_format='raw',
-                                                     is_public=False)
+            body = cls.glance_client.create_image(name=name,
+                                                  container_format='bare',
+                                                  disk_format='raw',
+                                                  is_public=False)
             image_id = body['id']
             cls.images.append(image_id)
             # Wait 1 second between creation and upload to ensure a delta
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index 049736c..4b14dc4 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -37,7 +37,7 @@
         cls.client = cls.os.interfaces_client
 
     def _check_interface(self, iface, port_id=None, network_id=None,
-                         fixed_ip=None):
+                         fixed_ip=None, mac_addr=None):
         self.assertIn('port_state', iface)
         if port_id:
             self.assertEqual(iface['port_id'], port_id)
@@ -45,6 +45,8 @@
             self.assertEqual(iface['net_id'], network_id)
         if fixed_ip:
             self.assertEqual(iface['fixed_ips'][0]['ip_address'], fixed_ip)
+        if mac_addr:
+            self.assertEqual(iface['mac_addr'], mac_addr)
 
     def _create_server_get_interfaces(self):
         resp, server = self.create_test_server(wait_until='ACTIVE')
@@ -78,7 +80,10 @@
         resp, _iface = self.client.show_interface(server['id'],
                                                   iface['port_id'])
         self.assertEqual(200, resp.status)
-        self.assertEqual(iface, _iface)
+        self._check_interface(iface, port_id=_iface['port_id'],
+                              network_id=_iface['net_id'],
+                              fixed_ip=_iface['fixed_ips'][0]['ip_address'],
+                              mac_addr=_iface['mac_addr'])
 
     def _test_delete_interface(self, server, ifs):
         # NOTE(danms): delete not the first or last, but one in the middle
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 28deaa7..76c858b 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -290,12 +290,11 @@
             'backup_type': "daily",
             'instance_uuid': self.server_id,
         }
-        resp, image_list = self.os.image_client.image_list_detail(
+        image_list = self.os.image_client.image_list_detail(
             properties,
             status='active',
             sort_key='created_at',
             sort_dir='asc')
-        self.assertEqual(200, resp.status)
         self.assertEqual(2, len(image_list))
         self.assertEqual((backup1, backup2),
                          (image_list[0]['name'], image_list[1]['name']))
@@ -315,12 +314,11 @@
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
         self.os.image_client.wait_for_resource_deletion(image1_id)
         oldest_backup_exist = False
-        resp, image_list = self.os.image_client.image_list_detail(
+        image_list = self.os.image_client.image_list_detail(
             properties,
             status='active',
             sort_key='created_at',
             sort_dir='asc')
-        self.assertEqual(200, resp.status)
         self.assertEqual(2, len(image_list),
                          'Unexpected number of images for '
                          'v2:test_create_backup; was the oldest backup not '
diff --git a/tempest/api/compute/servers/test_server_personality.py b/tempest/api/compute/servers/test_server_personality.py
index de5b6c1..c6d48bc 100644
--- a/tempest/api/compute/servers/test_server_personality.py
+++ b/tempest/api/compute/servers/test_server_personality.py
@@ -36,6 +36,8 @@
         personality = []
         max_file_limit = \
             self.user_client.get_specific_absolute_limit("maxPersonality")
+        if max_file_limit == -1:
+            raise self.skipException("No limit for personality files")
         for i in range(0, int(max_file_limit) + 1):
             path = 'etc/test' + str(i) + '.txt'
             personality.append({'path': path,
@@ -52,6 +54,8 @@
         file_contents = 'This is a test file.'
         max_file_limit = \
             self.user_client.get_specific_absolute_limit("maxPersonality")
+        if max_file_limit == -1:
+            raise self.skipException("No limit for personality files")
         person = []
         for i in range(0, int(max_file_limit)):
             path = 'etc/test' + str(i) + '.txt'
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 1f4f124..3dd6e34 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -57,13 +57,13 @@
         resp, cls.server = cls.client.get_server(server['id'])
 
         name = data_utils.rand_name('image')
-        resp, body = cls.glance_client.create_image(name=name,
-                                                    container_format='bare',
-                                                    disk_format='raw',
-                                                    is_public=False)
+        body = cls.glance_client.create_image(name=name,
+                                              container_format='bare',
+                                              disk_format='raw',
+                                              is_public=False)
         image_id = body['id']
         image_file = StringIO.StringIO(('*' * 1024))
-        resp, body = cls.glance_client.update_image(image_id, data=image_file)
+        body = cls.glance_client.update_image(image_id, data=image_file)
         cls.glance_client.wait_for_image_status(image_id, 'active')
         resp, cls.image = cls.images_client.get_image(image_id)
 
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index 9b30166..6f2f6d4 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.py
@@ -32,12 +32,12 @@
         u_email = '%s@testmail.tm' % u_name
         u_password = data_utils.rand_name('pass-')
         for i in range(2):
-            _, cls.project = cls.client.create_project(
+            cls.project = cls.client.create_project(
                 data_utils.rand_name('project-'),
                 description=data_utils.rand_name('project-desc-'))
             cls.projects.append(cls.project['id'])
 
-        _, 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])
 
@@ -55,7 +55,7 @@
     def test_credentials_create_get_update_delete(self):
         keys = [data_utils.rand_name('Access-'),
                 data_utils.rand_name('Secret-')]
-        _, cred = self.creds_client.create_credential(
+        cred = self.creds_client.create_credential(
             keys[0], keys[1], self.user_body['id'],
             self.projects[0])
         self.addCleanup(self._delete_credential, cred['id'])
@@ -66,7 +66,7 @@
 
         new_keys = [data_utils.rand_name('NewAccess-'),
                     data_utils.rand_name('NewSecret-')]
-        _, update_body = self.creds_client.update_credential(
+        update_body = self.creds_client.update_credential(
             cred['id'], access_key=new_keys[0], secret_key=new_keys[1],
             project_id=self.projects[1])
         self.assertEqual(cred['id'], update_body['id'])
@@ -75,7 +75,7 @@
         self.assertEqual(update_body['blob']['access'], new_keys[0])
         self.assertEqual(update_body['blob']['secret'], new_keys[1])
 
-        _, get_body = self.creds_client.get_credential(cred['id'])
+        get_body = self.creds_client.get_credential(cred['id'])
         for value1 in self.creds_list[0]:
             self.assertEqual(update_body[value1],
                              get_body[value1])
@@ -89,14 +89,14 @@
         fetched_cred_ids = list()
 
         for i in range(2):
-            _, cred = self.creds_client.create_credential(
+            cred = self.creds_client.create_credential(
                 data_utils.rand_name('Access-'),
                 data_utils.rand_name('Secret-'),
                 self.user_body['id'], self.projects[0])
             created_cred_ids.append(cred['id'])
             self.addCleanup(self._delete_credential, cred['id'])
 
-        _, creds = self.creds_client.list_credentials()
+        creds = self.creds_client.list_credentials()
 
         for i in creds:
             fetched_cred_ids.append(i['id'])
diff --git a/tempest/api/identity/admin/v3/test_default_project_id.py b/tempest/api/identity/admin/v3/test_default_project_id.py
index 8ffd1ed..bd29cb8 100644
--- a/tempest/api/identity/admin/v3/test_default_project_id.py
+++ b/tempest/api/identity/admin/v3/test_default_project_id.py
@@ -35,13 +35,13 @@
     def test_default_project_id(self):
         # create a domain
         dom_name = data_utils.rand_name('dom')
-        _, domain_body = self.client.create_domain(dom_name)
+        domain_body = self.client.create_domain(dom_name)
         dom_id = domain_body['id']
         self.addCleanup(self._delete_domain, dom_id)
 
         # create a project in the domain
         proj_name = data_utils.rand_name('proj')
-        _, proj_body = self.client.create_project(proj_name, domain_id=dom_id)
+        proj_body = self.client.create_project(proj_name, domain_id=dom_id)
         proj_id = proj_body['id']
         self.addCleanup(self.client.delete_project, proj_id)
         self.assertEqual(proj_body['domain_id'], dom_id,
@@ -51,9 +51,9 @@
         # create a user in the domain, with the previous project as his
         # default project
         user_name = data_utils.rand_name('user')
-        _, user_body = self.client.create_user(user_name, password=user_name,
-                                               domain_id=dom_id,
-                                               default_project_id=proj_id)
+        user_body = self.client.create_user(user_name, password=user_name,
+                                            domain_id=dom_id,
+                                            default_project_id=proj_id)
         user_id = user_body['id']
         self.addCleanup(self.client.delete_user, user_id)
         self.assertEqual(user_body['domain_id'], dom_id,
@@ -79,6 +79,6 @@
 
         # verify the user's token and see that it is scoped to the project
         token, auth_data = admin_client.auth_provider.get_auth()
-        _, result = admin_client.identity_v3_client.get_token(token)
+        result = admin_client.identity_v3_client.get_token(token)
         self.assertEqual(result['project']['domain']['id'], dom_id)
         self.assertEqual(result['project']['id'], proj_id)
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index 286ef97..c1bc705 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -34,14 +34,14 @@
         domain_ids = list()
         fetched_ids = list()
         for _ in range(3):
-            _, domain = self.client.create_domain(
+            domain = self.client.create_domain(
                 data_utils.rand_name('domain-'),
                 description=data_utils.rand_name('domain-desc-'))
             # Delete the domain at the end of this method
             self.addCleanup(self._delete_domain, domain['id'])
             domain_ids.append(domain['id'])
         # List and Verify Domains
-        _, body = self.client.list_domains()
+        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]
@@ -51,7 +51,7 @@
     def test_create_update_delete_domain(self):
         d_name = data_utils.rand_name('domain-')
         d_desc = data_utils.rand_name('domain-desc-')
-        _, domain = self.client.create_domain(
+        domain = self.client.create_domain(
             d_name, description=d_desc)
         self.addCleanup(self._delete_domain, domain['id'])
         self.assertIn('id', domain)
@@ -69,7 +69,7 @@
         new_desc = data_utils.rand_name('new-desc-')
         new_name = data_utils.rand_name('new-name-')
 
-        _, updated_domain = self.client.update_domain(
+        updated_domain = self.client.update_domain(
             domain['id'], name=new_name, description=new_desc)
         self.assertIn('id', updated_domain)
         self.assertIn('description', updated_domain)
@@ -81,7 +81,7 @@
         self.assertEqual(new_desc, updated_domain['description'])
         self.assertEqual('true', str(updated_domain['enabled']).lower())
 
-        _, fetched_domain = self.client.get_domain(domain['id'])
+        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 6044d2b..eed0eb5 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -30,7 +30,7 @@
         s_name = data_utils.rand_name('service-')
         s_type = data_utils.rand_name('type--')
         s_description = data_utils.rand_name('description-')
-        _, 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']
@@ -41,7 +41,7 @@
             region = data_utils.rand_name('region')
             url = data_utils.rand_url()
             interface = 'public'
-            resp, endpoint = cls.client.create_endpoint(
+            endpoint = cls.client.create_endpoint(
                 cls.service_id, interface, url, region=region, enabled=True)
             cls.setup_endpoints.append(endpoint)
 
@@ -56,7 +56,7 @@
     @test.attr(type='gate')
     def test_list_endpoints(self):
         # Get a list of endpoints
-        _, fetched_endpoints = self.client.list_endpoints()
+        fetched_endpoints = self.client.list_endpoints()
         # Asserting LIST endpoints
         missing_endpoints =\
             [e for e in self.setup_endpoints if e not in fetched_endpoints]
@@ -69,7 +69,7 @@
         region = data_utils.rand_name('region')
         url = data_utils.rand_url()
         interface = 'public'
-        _, endpoint =\
+        endpoint =\
             self.client.create_endpoint(self.service_id, interface, url,
                                         region=region, enabled=True)
         # Asserting Create Endpoint response body
@@ -77,13 +77,13 @@
         self.assertEqual(region, endpoint['region'])
         self.assertEqual(url, endpoint['url'])
         # Checking if created endpoint is present in the list of endpoints
-        resp, fetched_endpoints = self.client.list_endpoints()
+        fetched_endpoints = self.client.list_endpoints()
         fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
         self.assertIn(endpoint['id'], fetched_endpoints_id)
         # Deleting the endpoint created in this method
         self.client.delete_endpoint(endpoint['id'])
         # Checking whether endpoint is deleted successfully
-        resp, fetched_endpoints = self.client.list_endpoints()
+        fetched_endpoints = self.client.list_endpoints()
         fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
         self.assertNotIn(endpoint['id'], fetched_endpoints_id)
 
@@ -94,7 +94,7 @@
         region1 = data_utils.rand_name('region')
         url1 = data_utils.rand_url()
         interface1 = 'public'
-        resp, endpoint_for_update =\
+        endpoint_for_update =\
             self.client.create_endpoint(self.service_id, interface1,
                                         url1, region=region1,
                                         enabled=True)
@@ -103,7 +103,7 @@
         s_name = data_utils.rand_name('service-')
         s_type = data_utils.rand_name('type--')
         s_description = data_utils.rand_name('description-')
-        _, service2 =\
+        service2 =\
             self.service_client.create_service(s_name, s_type,
                                                description=s_description)
         self.service_ids.append(service2['id'])
@@ -111,7 +111,7 @@
         region2 = data_utils.rand_name('region')
         url2 = data_utils.rand_url()
         interface2 = 'internal'
-        _, endpoint = \
+        endpoint = \
             self.client.update_endpoint(endpoint_for_update['id'],
                                         service_id=service2['id'],
                                         interface=interface2, url=url2,
diff --git a/tempest/api/identity/admin/v3/test_endpoints_negative.py b/tempest/api/identity/admin/v3/test_endpoints_negative.py
index 4308d44..9da0a57 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-')
-        _, 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']
@@ -71,7 +71,7 @@
         region1 = data_utils.rand_name('region')
         url1 = data_utils.rand_url()
         interface1 = 'public'
-        resp, endpoint_for_update = (
+        endpoint_for_update = (
             self.client.create_endpoint(self.service_id, interface1,
                                         url1, region=region1, enabled=True))
         self.addCleanup(self.client.delete_endpoint, endpoint_for_update['id'])
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 3f2069d..64dba7d 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -29,21 +29,21 @@
     def test_group_create_update_get(self):
         name = data_utils.rand_name('Group')
         description = data_utils.rand_name('Description')
-        _, 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(group['name'], name)
         self.assertEqual(group['description'], description)
 
         new_name = data_utils.rand_name('UpdateGroup')
         new_desc = data_utils.rand_name('UpdateDescription')
-        _, updated_group = self.client.update_group(group['id'],
-                                                    name=new_name,
-                                                    description=new_desc)
+        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)
 
-        _, new_group = self.client.get_group(group['id'])
+        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'])
@@ -51,31 +51,31 @@
     @test.attr(type='smoke')
     def test_group_users_add_list_delete(self):
         name = data_utils.rand_name('Group')
-        _, 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')
-            _, 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
-        _, group_users = self.client.list_group_users(group['id'])
+        group_users = self.client.list_group_users(group['id'])
         self.assertEqual(sorted(users), sorted(group_users))
         # delete user in group
         for user in users:
             self.client.delete_group_user(group['id'],
                                           user['id'])
-        _, group_users = self.client.list_group_users(group['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
-        _, 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'])
@@ -83,11 +83,11 @@
         groups = []
         for i in range(2):
             name = data_utils.rand_name('Group-')
-            _, 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
-        _, user_groups = self.client.list_user_groups(user['id'])
+        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_list_projects.py b/tempest/api/identity/admin/v3/test_list_projects.py
index 2065de3..c0187f9 100644
--- a/tempest/api/identity/admin/v3/test_list_projects.py
+++ b/tempest/api/identity/admin/v3/test_list_projects.py
@@ -28,23 +28,23 @@
         cls.data.setup_test_domain()
         # Create project with domain
         cls.p1_name = data_utils.rand_name('project')
-        _, cls.p1 = cls.client.create_project(
+        cls.p1 = cls.client.create_project(
             cls.p1_name, enabled=False, domain_id=cls.data.domain['id'])
         cls.data.projects.append(cls.p1)
         cls.project_ids.append(cls.p1['id'])
         # Create default project
         p2_name = data_utils.rand_name('project')
-        _, cls.p2 = cls.client.create_project(p2_name)
+        cls.p2 = cls.client.create_project(p2_name)
         cls.data.projects.append(cls.p2)
         cls.project_ids.append(cls.p2['id'])
 
     @test.attr(type='gate')
     def test_projects_list(self):
         # List projects
-        resp, list_projects = self.client.list_projects()
+        list_projects = self.client.list_projects()
 
         for p in self.project_ids:
-            _, get_project = self.client.get_project(p)
+            get_project = self.client.get_project(p)
             self.assertIn(get_project, list_projects)
 
     @test.attr(type='gate')
@@ -64,6 +64,6 @@
         self._list_projects_with_params({'name': self.p1_name}, 'name')
 
     def _list_projects_with_params(self, params, key):
-        resp, body = self.client.list_projects(params)
+        body = self.client.list_projects(params)
         self.assertIn(self.p1[key], map(lambda x: x[key], body))
         self.assertNotIn(self.p2[key], map(lambda x: x[key], body))
diff --git a/tempest/api/identity/admin/v3/test_list_users.py b/tempest/api/identity/admin/v3/test_list_users.py
index 70c8ec6..e728867 100644
--- a/tempest/api/identity/admin/v3/test_list_users.py
+++ b/tempest/api/identity/admin/v3/test_list_users.py
@@ -26,7 +26,7 @@
         # assert the response based on expected and not_expected
         # expected: user expected in the list response
         # not_expected: user, which should not be present in list response
-        _, body = self.client.get_users(params)
+        body = self.client.get_users(params)
         self.assertIn(expected[key], map(lambda x: x[key], body))
         self.assertNotIn(not_expected[key],
                          map(lambda x: x[key], body))
@@ -40,13 +40,13 @@
         cls.data.setup_test_domain()
         # Create user with Domain
         u1_name = data_utils.rand_name('test_user')
-        _, cls.domain_enabled_user = cls.client.create_user(
+        cls.domain_enabled_user = cls.client.create_user(
             u1_name, password=alt_password,
             email=cls.alt_email, domain_id=cls.data.domain['id'])
         cls.data.v3_users.append(cls.domain_enabled_user)
         # Create default not enabled user
         u2_name = data_utils.rand_name('test_user')
-        _, cls.non_domain_enabled_user = cls.client.create_user(
+        cls.non_domain_enabled_user = cls.client.create_user(
             u2_name, password=alt_password,
             email=cls.alt_email, enabled=False)
         cls.data.v3_users.append(cls.non_domain_enabled_user)
@@ -78,7 +78,7 @@
     @test.attr(type='gate')
     def test_list_users(self):
         # List users
-        _, body = self.client.get_users()
+        body = self.client.get_users()
         fetched_ids = [u['id'] for u in body]
         missing_users = [u['id'] for u in self.data.v3_users
                          if u['id'] not in fetched_ids]
@@ -89,7 +89,7 @@
     @test.attr(type='gate')
     def test_get_user(self):
         # Get a user detail
-        _, user = self.client.get_user(self.data.v3_users[0]['id'])
+        user = self.client.get_user(self.data.v3_users[0]['id'])
         self.assertEqual(self.data.v3_users[0]['id'], user['id'])
         self.assertEqual(self.data.v3_users[0]['name'], user['name'])
         self.assertEqual(self.alt_email, user['email'])
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index e7fd2b5..2cf6458 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -26,14 +26,14 @@
         # Create project with a description
         project_name = data_utils.rand_name('project-')
         project_desc = data_utils.rand_name('desc-')
-        _, project = self.client.create_project(
+        project = self.client.create_project(
             project_name, description=project_desc)
         self.data.projects.append(project)
         project_id = project['id']
         desc1 = project['description']
         self.assertEqual(desc1, project_desc, 'Description should have '
                          'been sent in response for create')
-        _, 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')
@@ -43,13 +43,13 @@
         # Create project with a domain
         self.data.setup_test_domain()
         project_name = data_utils.rand_name('project')
-        resp, project = self.client.create_project(
+        project = self.client.create_project(
             project_name, domain_id=self.data.domain['id'])
         self.data.projects.append(project)
         project_id = project['id']
         self.assertEqual(project_name, project['name'])
         self.assertEqual(self.data.domain['id'], project['domain_id'])
-        _, body = self.client.get_project(project_id)
+        body = self.client.get_project(project_id)
         self.assertEqual(project_name, body['name'])
         self.assertEqual(self.data.domain['id'], body['domain_id'])
 
@@ -57,13 +57,13 @@
     def test_project_create_enabled(self):
         # Create a project that is enabled
         project_name = data_utils.rand_name('project-')
-        _, project = self.client.create_project(
+        project = self.client.create_project(
             project_name, enabled=True)
         self.data.projects.append(project)
         project_id = project['id']
         en1 = project['enabled']
         self.assertTrue(en1, 'Enable should be True in response')
-        _, 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')
 
@@ -71,13 +71,13 @@
     def test_project_create_not_enabled(self):
         # Create a project that is not enabled
         project_name = data_utils.rand_name('project-')
-        _, project = self.client.create_project(
+        project = self.client.create_project(
             project_name, enabled=False)
         self.data.projects.append(project)
         en1 = project['enabled']
         self.assertEqual('false', str(en1).lower(),
                          'Enable should be False in response')
-        _, 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')
@@ -86,17 +86,17 @@
     def test_project_update_name(self):
         # Update name attribute of a project
         p_name1 = data_utils.rand_name('project-')
-        _, 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-')
-        _, body = self.client.update_project(project['id'], name=p_name2)
+        body = self.client.update_project(project['id'], name=p_name2)
         resp2_name = body['name']
         self.assertNotEqual(resp1_name, resp2_name)
 
-        _, body = self.client.get_project(project['id'])
+        body = self.client.get_project(project['id'])
         resp3_name = body['name']
 
         self.assertNotEqual(resp1_name, resp3_name)
@@ -108,18 +108,18 @@
         # Update description attribute of a project
         p_name = data_utils.rand_name('project-')
         p_desc = data_utils.rand_name('desc-')
-        _, 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-')
-        _, body = self.client.update_project(
+        body = self.client.update_project(
             project['id'], description=p_desc2)
         resp2_desc = body['description']
         self.assertNotEqual(resp1_desc, resp2_desc)
 
-        _, body = self.client.get_project(project['id'])
+        body = self.client.get_project(project['id'])
         resp3_desc = body['description']
 
         self.assertNotEqual(resp1_desc, resp3_desc)
@@ -131,18 +131,18 @@
         # Update the enabled attribute of a project
         p_name = data_utils.rand_name('project-')
         p_en = False
-        _, 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
-        _, body = self.client.update_project(
+        body = self.client.update_project(
             project['id'], enabled=p_en2)
         resp2_en = body['enabled']
         self.assertNotEqual(resp1_en, resp2_en)
 
-        _, body = self.client.get_project(project['id'])
+        body = self.client.get_project(project['id'])
         resp3_en = body['enabled']
 
         self.assertNotEqual(resp1_en, resp3_en)
@@ -154,7 +154,7 @@
         # Associate a user to a project
         # Create a Project
         p_name = data_utils.rand_name('project-')
-        _, project = self.client.create_project(p_name)
+        project = self.client.create_project(p_name)
         self.data.projects.append(project)
 
         # Create a User
@@ -162,14 +162,14 @@
         u_desc = u_name + 'description'
         u_email = u_name + '@testmail.tm'
         u_password = data_utils.rand_name('pass-')
-        _, 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'])
         # Delete the User at the end of this method
         self.addCleanup(self.client.delete_user, user['id'])
 
         # Get User To validate the user details
-        _, 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 da35ace..f5e832b 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-')
-        _, 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-')
-        _, 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 4305060..c71cbf3 100644
--- a/tempest/api/identity/admin/v3/test_regions.py
+++ b/tempest/api/identity/admin/v3/test_regions.py
@@ -29,7 +29,7 @@
         cls.client = cls.region_client
         for i in range(2):
             r_description = data_utils.rand_name('description-')
-            _, region = cls.client.create_region(r_description)
+            region = cls.client.create_region(r_description)
             cls.setup_regions.append(region)
 
     @classmethod
@@ -46,7 +46,7 @@
     @test.attr(type='gate')
     def test_create_update_get_delete_region(self):
         r_description = data_utils.rand_name('description-')
-        _, region = self.client.create_region(
+        region = self.client.create_region(
             r_description, parent_region_id=self.setup_regions[0]['id'])
         self.addCleanup(self._delete_region, region['id'])
         self.assertEqual(r_description, region['description'])
@@ -54,7 +54,7 @@
                          region['parent_region_id'])
         # Update region with new description and parent ID
         r_alt_description = data_utils.rand_name('description-')
-        _, region = self.client.update_region(
+        region = self.client.update_region(
             region['id'],
             description=r_alt_description,
             parent_region_id=self.setup_regions[1]['id'])
@@ -62,7 +62,7 @@
         self.assertEqual(self.setup_regions[1]['id'],
                          region['parent_region_id'])
         # Get the details of region
-        _, region = self.client.get_region(region['id'])
+        region = self.client.get_region(region['id'])
         self.assertEqual(r_alt_description, region['description'])
         self.assertEqual(self.setup_regions[1]['id'],
                          region['parent_region_id'])
@@ -72,7 +72,7 @@
         # Create a region with a specific id
         r_region_id = data_utils.rand_uuid()
         r_description = data_utils.rand_name('description-')
-        _, region = self.client.create_region(
+        region = self.client.create_region(
             r_description, unique_region_id=r_region_id)
         self.addCleanup(self._delete_region, region['id'])
         # Asserting Create Region with specific id response body
@@ -82,7 +82,7 @@
     @test.attr(type='gate')
     def test_list_regions(self):
         # Get a list of regions
-        _, fetched_regions = self.client.list_regions()
+        fetched_regions = self.client.list_regions()
         missing_regions =\
             [e for e in self.setup_regions if e not in fetched_regions]
         # Asserting List Regions response
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index 3c0a180..b8b309d 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -26,28 +26,28 @@
         super(RolesV3TestJSON, cls).resource_setup()
         for _ in range(3):
             role_name = data_utils.rand_name(name='role-')
-            _, role = cls.client.create_role(role_name)
+            role = cls.client.create_role(role_name)
             cls.data.v3_roles.append(role)
         cls.fetched_role_ids = list()
         u_name = data_utils.rand_name('user-')
         u_desc = '%s description' % u_name
         u_email = '%s@testmail.tm' % u_name
         cls.u_password = data_utils.rand_name('pass-')
-        _, cls.domain = cls.client.create_domain(
+        cls.domain = cls.client.create_domain(
             data_utils.rand_name('domain-'),
             description=data_utils.rand_name('domain-desc-'))
-        _, 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'])
-        _, 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'])
-        _, 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'])
-        _, cls.role = cls.client.create_role(
+        cls.role = cls.client.create_role(
             data_utils.rand_name('Role-'))
 
     @classmethod
@@ -69,23 +69,23 @@
     @test.attr(type='smoke')
     def test_role_create_update_get_list(self):
         r_name = data_utils.rand_name('Role-')
-        _, role = self.client.create_role(r_name)
+        role = self.client.create_role(r_name)
         self.addCleanup(self.client.delete_role, role['id'])
         self.assertIn('name', role)
         self.assertEqual(role['name'], r_name)
 
         new_name = data_utils.rand_name('NewRole-')
-        _, updated_role = self.client.update_role(new_name, role['id'])
+        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'])
 
-        _, new_role = self.client.get_role(role['id'])
+        new_role = self.client.get_role(role['id'])
         self.assertEqual(new_name, new_role['name'])
         self.assertEqual(updated_role['id'], new_role['id'])
 
-        _, roles = self.client.list_roles()
+        roles = self.client.list_roles()
         self.assertIn(role['id'], [r['id'] for r in roles])
 
     @test.attr(type='smoke')
@@ -93,7 +93,7 @@
         self.client.assign_user_role_on_project(
             self.project['id'], self.user_body['id'], self.role['id'])
 
-        _, 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:
@@ -110,7 +110,7 @@
         self.client.assign_user_role_on_domain(
             self.domain['id'], self.user_body['id'], self.role['id'])
 
-        _, 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:
@@ -128,7 +128,7 @@
         self.client.assign_group_role_on_project(
             self.project['id'], self.group_body['id'], self.role['id'])
         # List group roles on project
-        _, 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:
@@ -140,9 +140,9 @@
         self.client.add_group_user(self.group_body['id'], self.user_body['id'])
         self.addCleanup(self.client.delete_group_user,
                         self.group_body['id'], self.user_body['id'])
-        _, body = self.token.auth(self.user_body['id'], self.u_password,
-                                  self.project['name'],
-                                  domain=self.domain['name'])
+        body = self.token.auth(self.user_body['id'], self.u_password,
+                               self.project['name'],
+                               domain=self.domain['name'])
         roles = body['token']['roles']
         self.assertEqual(len(roles), 1)
         self.assertEqual(roles[0]['id'], self.role['id'])
@@ -155,7 +155,7 @@
         self.client.assign_group_role_on_domain(
             self.domain['id'], self.group_body['id'], self.role['id'])
 
-        _, 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:
@@ -170,6 +170,6 @@
     @test.attr(type='gate')
     def test_list_roles(self):
         # Return a list of all roles
-        _, body = self.client.list_roles()
+        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 a871f17..9e45b50 100644
--- a/tempest/api/identity/admin/v3/test_services.py
+++ b/tempest/api/identity/admin/v3/test_services.py
@@ -35,7 +35,7 @@
         name = data_utils.rand_name('service')
         serv_type = data_utils.rand_name('type')
         desc = data_utils.rand_name('description')
-        _, create_service = self.service_client.create_service(
+        create_service = self.service_client.create_service(
             serv_type, name=name, description=desc)
         self.addCleanup(self._del_service, create_service['id'])
         self.assertIsNotNone(create_service['id'])
@@ -48,14 +48,14 @@
         s_id = create_service['id']
         resp1_desc = create_service['description']
         s_desc2 = data_utils.rand_name('desc2')
-        _, update_service = self.service_client.update_service(
+        update_service = self.service_client.update_service(
             s_id, description=s_desc2)
         resp2_desc = update_service['description']
 
         self.assertNotEqual(resp1_desc, resp2_desc)
 
         # Get service
-        _, fetched_service = self.service_client.get_service(s_id)
+        fetched_service = self.service_client.get_service(s_id)
         resp3_desc = fetched_service['description']
 
         self.assertEqual(resp2_desc, resp3_desc)
@@ -66,7 +66,7 @@
         # Create a service only with name and type
         name = data_utils.rand_name('service')
         serv_type = data_utils.rand_name('type')
-        _, service = self.service_client.create_service(
+        service = self.service_client.create_service(
             serv_type, name=name)
         self.addCleanup(self.service_client.delete_service, service['id'])
         self.assertIn('id', service)
@@ -80,14 +80,14 @@
         for _ in range(3):
             name = data_utils.rand_name('service')
             serv_type = data_utils.rand_name('type')
-            _, create_service = self.service_client.create_service(
+            create_service = self.service_client.create_service(
                 serv_type, name=name)
             self.addCleanup(self.service_client.delete_service,
                             create_service['id'])
             service_ids.append(create_service['id'])
 
         # List and Verify Services
-        _, services = self.service_client.list_services()
+        services = self.service_client.list_services()
         fetched_ids = [service['id'] for service in services]
         found = [s for s in fetched_ids if s in service_ids]
         self.assertEqual(len(found), len(service_ids))
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index aef8239..f0acfdf 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -30,15 +30,15 @@
         u_desc = '%s-description' % u_name
         u_email = '%s@testmail.tm' % u_name
         u_password = data_utils.rand_name('pass-')
-        _, user = self.client.create_user(
+        user = self.client.create_user(
             u_name, description=u_desc, password=u_password,
             email=u_email)
         self.addCleanup(self.client.delete_user, user['id'])
         # Perform Authentication
-        resp, _ = self.token.auth(user['id'], u_password)
+        resp = self.token.auth(user['id'], u_password).response
         subject_token = resp['x-subject-token']
         # Perform GET Token
-        _, token_details = self.client.get_token(subject_token)
+        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)
@@ -60,21 +60,21 @@
         # Create a user.
         user_name = data_utils.rand_name(name='user-')
         user_password = data_utils.rand_name(name='pass-')
-        _, user = self.client.create_user(user_name, password=user_password)
+        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-')
-        _, project1 = self.client.create_project(project1_name)
+        project1 = self.client.create_project(project1_name)
         self.addCleanup(self.client.delete_project, project1['id'])
 
         project2_name = data_utils.rand_name(name='project-')
-        _, project2 = self.client.create_project(project2_name)
+        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-')
-        _, role = self.client.create_role(role_name)
+        role = self.client.create_role(role_name)
         self.addCleanup(self.client.delete_role, role['id'])
 
         # Grant the user the role on both projects.
@@ -85,10 +85,10 @@
                                      role['id'])
 
         # Get an unscoped token.
-        resp, token_auth = self.token.auth(user=user['id'],
-                                           password=user_password)
+        token_auth = self.token.auth(user=user['id'],
+                                     password=user_password)
 
-        token_id = resp['x-subject-token']
+        token_id = token_auth.response['x-subject-token']
         orig_expires_at = token_auth['token']['expires_at']
         orig_issued_at = token_auth['token']['issued_at']
         orig_user = token_auth['token']['user']
@@ -107,10 +107,10 @@
         self.assertNotIn('roles', token_auth['token'])
 
         # Use the unscoped token to get a scoped token.
-        resp, token_auth = self.token.auth(token=token_id,
-                                           tenant=project1_name,
-                                           domain='Default')
-        token1_id = resp['x-subject-token']
+        token_auth = self.token.auth(token=token_id,
+                                     tenant=project1_name,
+                                     domain='Default')
+        token1_id = token_auth.response['x-subject-token']
 
         self.assertEqual(orig_expires_at, token_auth['token']['expires_at'],
                          'Expiration time should match original token')
@@ -137,9 +137,9 @@
         self.client.delete_token(token1_id)
 
         # Now get another scoped token using the unscoped token.
-        _, token_auth = self.token.auth(token=token_id,
-                                        tenant=project2_name,
-                                        domain='Default')
+        token_auth = self.token.auth(token=token_id,
+                                     tenant=project2_name,
+                                     domain='Default')
 
         self.assertEqual(project2['id'],
                          token_auth['token']['project']['id'])
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 886c808..cd28e96 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -55,7 +55,7 @@
         u_desc = self.trustor_username + 'description'
         u_email = self.trustor_username + '@testmail.xx'
         self.trustor_password = data_utils.rand_name('pass-')
-        _, user = self.client.create_user(
+        user = self.client.create_user(
             self.trustor_username,
             description=u_desc,
             password=self.trustor_password,
@@ -67,10 +67,10 @@
         self.delegated_role = data_utils.rand_name('DelegatedRole-')
         self.not_delegated_role = data_utils.rand_name('NotDelegatedRole-')
 
-        _, role = self.client.create_role(self.delegated_role)
+        role = self.client.create_role(self.delegated_role)
         self.delegated_role_id = role['id']
 
-        _, role = self.client.create_role(self.not_delegated_role)
+        role = self.client.create_role(self.not_delegated_role)
         self.not_delegated_role_id = role['id']
 
         # Assign roles to trustor
@@ -106,7 +106,7 @@
 
     def create_trust(self, impersonate=True, expires=None):
 
-        _, 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,
@@ -138,7 +138,7 @@
             self.assertEqual(1, len(trust['roles']))
 
     def get_trust(self):
-        _, trust_get = self.trustor_client.get_trust(self.trust_id)
+        trust_get = self.trustor_client.get_trust(self.trust_id)
         return trust_get
 
     def validate_role(self, role):
@@ -153,16 +153,16 @@
 
     def check_trust_roles(self):
         # Check we find the delegated role
-        _, roles_get = self.trustor_client.get_trust_roles(
+        roles_get = self.trustor_client.get_trust_roles(
             self.trust_id)
         self.assertEqual(1, len(roles_get))
         self.validate_role(roles_get[0])
 
-        _, role_get = self.trustor_client.get_trust_role(
+        role_get = self.trustor_client.get_trust_role(
             self.trust_id, self.delegated_role_id)
         self.validate_role(role_get)
 
-        _, role_get = self.trustor_client.check_trust_role(
+        role_get = self.trustor_client.check_trust_role(
             self.trust_id, self.delegated_role_id)
 
         # And that we don't find not_delegated_role
@@ -245,7 +245,7 @@
     @test.attr(type='smoke')
     def test_get_trusts_query(self):
         self.create_trust()
-        _, trusts_get = self.trustor_client.get_trusts(
+        trusts_get = self.trustor_client.get_trusts(
             trustor_user_id=self.trustor_user_id)
         self.assertEqual(1, len(trusts_get))
         self.validate_trust(trusts_get[0], summary=True)
@@ -253,7 +253,7 @@
     @test.attr(type='smoke')
     def test_get_trusts_all(self):
         self.create_trust()
-        _, trusts_get = self.client.get_trusts()
+        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 1b003c3..4f3ec05 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-')
-        _, 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
-        _, 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,7 +44,7 @@
         u_name2 = data_utils.rand_name('user2-')
         u_email2 = u_name2 + '@testmail.tm'
         u_description2 = u_name2 + ' description'
-        _, 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)
@@ -55,7 +55,7 @@
         self.assertEqual(u_email2, update_user['email'])
         self.assertEqual('false', str(update_user['enabled']).lower())
         # GET by id after updation
-        _, 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'])
@@ -69,7 +69,7 @@
         # Creating User to check password updation
         u_name = data_utils.rand_name('user')
         original_password = data_utils.rand_name('pass')
-        _, user = self.client.create_user(
+        user = self.client.create_user(
             u_name, password=original_password)
         # Delete the User at the end all test methods
         self.addCleanup(self.client.delete_user, user['id'])
@@ -77,10 +77,10 @@
         new_password = data_utils.rand_name('pass1')
         self.client.update_user_password(user['id'], new_password,
                                          original_password)
-        resp, _ = self.token.auth(user['id'], new_password)
+        resp = self.token.auth(user['id'], new_password).response
         subject_token = resp['x-subject-token']
         # Perform GET Token to verify and confirm password is updated
-        _, token_details = self.client.get_token(subject_token)
+        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)
@@ -90,7 +90,7 @@
         # List the projects that a user has access upon
         assigned_project_ids = list()
         fetched_project_ids = list()
-        _, u_project = self.client.create_project(
+        u_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
@@ -100,25 +100,25 @@
         u_desc = u_name + 'description'
         u_email = u_name + '@testmail.tm'
         u_password = data_utils.rand_name('pass-')
-        _, user_body = self.client.create_user(
+        user_body = self.client.create_user(
             u_name, description=u_desc, password=u_password,
             email=u_email, enabled=False, project_id=u_project['id'])
         # Delete the User at the end of this method
         self.addCleanup(self.client.delete_user, user_body['id'])
         # Creating Role
-        _, role_body = self.client.create_role(
+        role_body = self.client.create_role(
             data_utils.rand_name('role-'))
         # Delete the Role at the end of this method
         self.addCleanup(self.client.delete_role, role_body['id'])
 
-        _, user = self.client.get_user(user_body['id'])
-        _, role = self.client.get_role(role_body['id'])
+        user = self.client.get_user(user_body['id'])
+        role = self.client.get_role(role_body['id'])
         for i in range(2):
             # Creating project so as to assign role
-            _, project_body = self.client.create_project(
+            project_body = self.client.create_project(
                 data_utils.rand_name('project-'),
                 description=data_utils.rand_name('project-desc-'))
-            _, project = self.client.get_project(project_body['id'])
+            project = self.client.get_project(project_body['id'])
             # Delete the Project at the end of this method
             self.addCleanup(self.client.delete_project, project_body['id'])
             # Assigning roles to user on project
@@ -126,7 +126,7 @@
                                          user['id'],
                                          role['id'])
             assigned_project_ids.append(project['id'])
-        _, body = self.client.list_user_projects(user['id'])
+        body = self.client.list_user_projects(user['id'])
         for i in body:
             fetched_project_ids.append(i['id'])
         # verifying the project ids in list
@@ -142,5 +142,5 @@
     def test_get_user(self):
         # Get a user detail
         self.data.setup_test_v3_user()
-        _, 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 1e4973b..c9010ee 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -112,6 +112,27 @@
         cls.data.teardown_all()
         super(BaseIdentityV3AdminTest, cls).resource_cleanup()
 
+    @classmethod
+    def get_user_by_name(cls, name):
+        users = cls.client.get_users()
+        user = [u for u in users if u['name'] == name]
+        if len(user) > 0:
+            return user[0]
+
+    @classmethod
+    def get_tenant_by_name(cls, name):
+        tenants = cls.client.list_projects()
+        tenant = [t for t in tenants if t['name'] == name]
+        if len(tenant) > 0:
+            return tenant[0]
+
+    @classmethod
+    def get_role_by_name(cls, name):
+        roles = cls.client.list_roles()
+        role = [r for r in roles if r['name'] == name]
+        if len(role) > 0:
+            return role[0]
+
 
 class DataGenerator(object):
 
@@ -167,7 +188,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'
-            _, 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'],
@@ -178,7 +199,7 @@
             """Set up a test project."""
             self.test_project = data_utils.rand_name('test_project_')
             self.test_description = data_utils.rand_name('desc_')
-            _, 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)
@@ -186,14 +207,14 @@
         def setup_test_v3_role(self):
             """Set up a test v3 role."""
             self.test_role = data_utils.rand_name('role')
-            _, 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 setup_test_domain(self):
             """Set up a test domain."""
             self.test_domain = data_utils.rand_name('test_domain')
             self.test_description = data_utils.rand_name('desc')
-            _, self.domain = self.client.create_domain(
+            self.domain = self.client.create_domain(
                 name=self.test_domain,
                 description=self.test_description)
             self.domains.append(self.domain)
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index 76b6f17..12f3fdd 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -67,10 +67,10 @@
         container_format = kwargs.pop('container_format')
         disk_format = kwargs.pop('disk_format')
 
-        resp, image = cls.client.create_image(name, container_format,
-                                              disk_format, **kwargs)
+        image = cls.client.create_image(name, container_format,
+                                        disk_format, **kwargs)
         cls.created_images.append(image['id'])
-        return resp, image
+        return image
 
 
 class BaseV1ImageTest(BaseImageTest):
@@ -95,11 +95,10 @@
 
     def _create_image(self):
         image_file = StringIO.StringIO(data_utils.random_bytes())
-        resp, image = self.create_image(container_format='bare',
-                                        disk_format='raw',
-                                        is_public=False,
-                                        data=image_file)
-        self.assertEqual(201, resp.status)
+        image = self.create_image(container_format='bare',
+                                  disk_format='raw',
+                                  is_public=False,
+                                  data=image_file)
         image_id = image['id']
         return image_id
 
@@ -127,15 +126,15 @@
         cls.alt_tenant_id = cls.alt_img_client.tenant_id
 
     def _list_image_ids_as_alt(self):
-        _, image_list = self.alt_img_client.image_list()
+        image_list = self.alt_img_client.image_list()
         image_ids = map(lambda x: x['id'], image_list)
         return image_ids
 
     def _create_image(self):
         name = data_utils.rand_name('image')
-        _, image = self.os_img_client.create_image(name,
-                                                   container_format='bare',
-                                                   disk_format='raw')
+        image = self.os_img_client.create_image(name,
+                                                container_format='bare',
+                                                disk_format='raw')
         image_id = image['id']
         self.addCleanup(self.os_img_client.delete_image, image_id)
         return image_id
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index f91cb69..d18a274 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -23,7 +23,7 @@
     def test_add_image_member(self):
         image = self._create_image()
         self.client.add_member(self.alt_tenant_id, image)
-        _, body = self.client.get_image_membership(image)
+        body = self.client.get_image_membership(image)
         members = body['members']
         members = map(lambda x: x['member_id'], members)
         self.assertIn(self.alt_tenant_id, members)
@@ -36,7 +36,7 @@
         self.client.add_member(self.alt_tenant_id, image)
         share_image = self._create_image()
         self.client.add_member(self.alt_tenant_id, share_image)
-        _, body = self.client.get_shared_images(self.alt_tenant_id)
+        body = self.client.get_shared_images(self.alt_tenant_id)
         images = body['shared_images']
         images = map(lambda x: x['image_id'], images)
         self.assertIn(share_image, images)
@@ -47,6 +47,6 @@
         image_id = self._create_image()
         self.client.add_member(self.alt_tenant_id, image_id)
         self.client.delete_member(self.alt_tenant_id, image_id)
-        _, body = self.client.get_image_membership(image_id)
+        body = self.client.get_image_membership(image_id)
         members = body['members']
         self.assertEqual(0, len(members), str(members))
diff --git a/tempest/api/image/v1/test_images.py b/tempest/api/image/v1/test_images.py
index 38a623a..b9f12e6 100644
--- a/tempest/api/image/v1/test_images.py
+++ b/tempest/api/image/v1/test_images.py
@@ -30,11 +30,11 @@
     def test_register_then_upload(self):
         # Register, then upload an image
         properties = {'prop1': 'val1'}
-        _, body = self.create_image(name='New Name',
-                                    container_format='bare',
-                                    disk_format='raw',
-                                    is_public=False,
-                                    properties=properties)
+        body = self.create_image(name='New Name',
+                                 container_format='bare',
+                                 disk_format='raw',
+                                 is_public=False,
+                                 properties=properties)
         self.assertIn('id', body)
         image_id = body.get('id')
         self.assertEqual('New Name', body.get('name'))
@@ -45,19 +45,19 @@
 
         # Now try uploading an image file
         image_file = StringIO.StringIO(data_utils.random_bytes())
-        _, body = self.client.update_image(image_id, data=image_file)
+        body = self.client.update_image(image_id, data=image_file)
         self.assertIn('size', body)
         self.assertEqual(1024, body.get('size'))
 
     @test.attr(type='gate')
     def test_register_remote_image(self):
         # Register a new remote image
-        _, body = self.create_image(name='New Remote Image',
-                                    container_format='bare',
-                                    disk_format='raw', is_public=False,
-                                    location=CONF.image.http_image,
-                                    properties={'key1': 'value1',
-                                                'key2': 'value2'})
+        body = self.create_image(name='New Remote Image',
+                                 container_format='bare',
+                                 disk_format='raw', is_public=False,
+                                 location=CONF.image.http_image,
+                                 properties={'key1': 'value1',
+                                             'key2': 'value2'})
         self.assertIn('id', body)
         self.assertEqual('New Remote Image', body.get('name'))
         self.assertFalse(body.get('is_public'))
@@ -68,10 +68,10 @@
 
     @test.attr(type='gate')
     def test_register_http_image(self):
-        _, body = self.create_image(name='New Http Image',
-                                    container_format='bare',
-                                    disk_format='raw', is_public=False,
-                                    copy_from=CONF.image.http_image)
+        body = self.create_image(name='New Http Image',
+                                 container_format='bare',
+                                 disk_format='raw', is_public=False,
+                                 copy_from=CONF.image.http_image)
         self.assertIn('id', body)
         image_id = body.get('id')
         self.assertEqual('New Http Image', body.get('name'))
@@ -83,12 +83,12 @@
     def test_register_image_with_min_ram(self):
         # Register an image with min ram
         properties = {'prop1': 'val1'}
-        _, body = self.create_image(name='New_image_with_min_ram',
-                                    container_format='bare',
-                                    disk_format='raw',
-                                    is_public=False,
-                                    min_ram=40,
-                                    properties=properties)
+        body = self.create_image(name='New_image_with_min_ram',
+                                 container_format='bare',
+                                 disk_format='raw',
+                                 is_public=False,
+                                 min_ram=40,
+                                 properties=properties)
         self.assertIn('id', body)
         self.assertEqual('New_image_with_min_ram', body.get('name'))
         self.assertFalse(body.get('is_public'))
@@ -140,11 +140,11 @@
         """
         name = 'New Remote Image %s' % name
         location = CONF.image.http_image
-        _, image = cls.create_image(name=name,
-                                    container_format=container_format,
-                                    disk_format=disk_format,
-                                    is_public=False,
-                                    location=location)
+        image = cls.create_image(name=name,
+                                 container_format=container_format,
+                                 disk_format=disk_format,
+                                 is_public=False,
+                                 location=location)
         image_id = image['id']
         return image_id
 
@@ -158,24 +158,24 @@
         """
         image_file = StringIO.StringIO(data_utils.random_bytes(size))
         name = 'New Standard Image %s' % name
-        _, image = cls.create_image(name=name,
-                                    container_format=container_format,
-                                    disk_format=disk_format,
-                                    is_public=False, data=image_file)
+        image = cls.create_image(name=name,
+                                 container_format=container_format,
+                                 disk_format=disk_format,
+                                 is_public=False, data=image_file)
         image_id = image['id']
         return image_id
 
     @test.attr(type='gate')
     def test_index_no_params(self):
         # Simple test to see all fixture images returned
-        _, images_list = self.client.image_list()
+        images_list = self.client.image_list()
         image_list = map(lambda x: x['id'], images_list)
         for image_id in self.created_images:
             self.assertIn(image_id, image_list)
 
     @test.attr(type='gate')
     def test_index_disk_format(self):
-        _, images_list = self.client.image_list(disk_format='ami')
+        images_list = self.client.image_list(disk_format='ami')
         for image in images_list:
             self.assertEqual(image['disk_format'], 'ami')
         result_set = set(map(lambda x: x['id'], images_list))
@@ -184,7 +184,7 @@
 
     @test.attr(type='gate')
     def test_index_container_format(self):
-        _, images_list = self.client.image_list(container_format='bare')
+        images_list = self.client.image_list(container_format='bare')
         for image in images_list:
             self.assertEqual(image['container_format'], 'bare')
         result_set = set(map(lambda x: x['id'], images_list))
@@ -193,7 +193,7 @@
 
     @test.attr(type='gate')
     def test_index_max_size(self):
-        _, images_list = self.client.image_list(size_max=42)
+        images_list = self.client.image_list(size_max=42)
         for image in images_list:
             self.assertTrue(image['size'] <= 42)
         result_set = set(map(lambda x: x['id'], images_list))
@@ -202,7 +202,7 @@
 
     @test.attr(type='gate')
     def test_index_min_size(self):
-        _, images_list = self.client.image_list(size_min=142)
+        images_list = self.client.image_list(size_min=142)
         for image in images_list:
             self.assertTrue(image['size'] >= 142)
         result_set = set(map(lambda x: x['id'], images_list))
@@ -211,9 +211,9 @@
 
     @test.attr(type='gate')
     def test_index_status_active_detail(self):
-        _, images_list = self.client.image_list_detail(status='active',
-                                                       sort_key='size',
-                                                       sort_dir='desc')
+        images_list = self.client.image_list_detail(status='active',
+                                                    sort_key='size',
+                                                    sort_dir='desc')
         top_size = images_list[0]['size']  # We have non-zero sized images
         for image in images_list:
             size = image['size']
@@ -223,7 +223,7 @@
 
     @test.attr(type='gate')
     def test_index_name(self):
-        _, images_list = self.client.image_list_detail(
+        images_list = self.client.image_list_detail(
             name='New Remote Image dup')
         result_set = set(map(lambda x: x['id'], images_list))
         for image in images_list:
@@ -232,99 +232,6 @@
         self.assertFalse(self.created_set - self.dup_set <= result_set)
 
 
-class ListSnapshotImagesTest(base.BaseV1ImageTest):
-    @classmethod
-    def resource_setup(cls):
-        # This test class only uses nova v3 api to create snapshot
-        # as the similar test which uses nova v2 api already exists
-        # in nova v2 compute images api tests.
-        # Since nova v3 doesn't have images api proxy, this test
-        # class was added in the image api tests.
-        if not CONF.compute_feature_enabled.api_v3:
-            skip_msg = ("%s skipped as nova v3 api is not available" %
-                        cls.__name__)
-            raise cls.skipException(skip_msg)
-        super(ListSnapshotImagesTest, cls).resource_setup()
-        cls.servers_client = cls.os.servers_v3_client
-        cls.servers = []
-        # We add a few images here to test the listing functionality of
-        # the images API
-        cls.snapshot = cls._create_snapshot(
-            'snapshot', CONF.compute.image_ref,
-            CONF.compute.flavor_ref)
-        cls.snapshot_set = set((cls.snapshot,))
-
-        image_file = StringIO.StringIO('*' * 42)
-        _, image = cls.create_image(name="Standard Image",
-                                    container_format='ami',
-                                    disk_format='ami',
-                                    is_public=False, data=image_file)
-        cls.image_id = image['id']
-        cls.client.wait_for_image_status(image['id'], 'active')
-
-    @classmethod
-    def resource_cleanup(cls):
-        for server in getattr(cls, "servers", []):
-            cls.servers_client.delete_server(server['id'])
-        super(ListSnapshotImagesTest, cls).resource_cleanup()
-
-    @classmethod
-    def _create_snapshot(cls, name, image_id, flavor, **kwargs):
-        _, server = cls.servers_client.create_server(
-            name, image_id, flavor, **kwargs)
-        cls.servers.append(server)
-        cls.servers_client.wait_for_server_status(
-            server['id'], 'ACTIVE')
-        resp, _ = cls.servers_client.create_image(server['id'], name)
-        image_id = data_utils.parse_image_id(resp['location'])
-        cls.created_images.append(image_id)
-        cls.client.wait_for_image_status(image_id,
-                                         'active')
-        return image_id
-
-    @test.attr(type='gate')
-    @test.services('compute')
-    def test_index_server_id(self):
-        # The images should contain images filtered by server id
-        _, images = self.client.image_list_detail(
-            {'instance_uuid': self.servers[0]['id']})
-        result_set = set(map(lambda x: x['id'], images))
-        self.assertEqual(self.snapshot_set, result_set)
-
-    @test.attr(type='gate')
-    @test.services('compute')
-    def test_index_type(self):
-        # The list of servers should be filtered by image type
-        params = {'image_type': 'snapshot'}
-        _, images = self.client.image_list_detail(params)
-
-        result_set = set(map(lambda x: x['id'], images))
-        self.assertIn(self.snapshot, result_set)
-
-    @test.attr(type='gate')
-    @test.services('compute')
-    def test_index_limit(self):
-        # Verify only the expected number of results are returned
-        _, images = self.client.image_list_detail(limit=1)
-
-        self.assertEqual(1, len(images))
-
-    @test.attr(type='gate')
-    @test.services('compute')
-    def test_index_by_change_since(self):
-        # Verify an update image is returned
-        # Becoming ACTIVE will modify the updated time
-        # Filter by the image's created time
-        _, image = self.client.get_image_meta(self.snapshot)
-        self.assertEqual(self.snapshot, image['id'])
-        _, images = self.client.image_list_detail(
-            changes_since=image['updated_at'])
-
-        result_set = set(map(lambda x: x['id'], images))
-        self.assertIn(self.image_id, result_set)
-        self.assertNotIn(self.snapshot, result_set)
-
-
 class UpdateImageMetaTest(base.BaseV1ImageTest):
     @classmethod
     def resource_setup(cls):
@@ -340,18 +247,18 @@
         """
         image_file = StringIO.StringIO(data_utils.random_bytes(size))
         name = 'New Standard Image %s' % name
-        _, image = cls.create_image(name=name,
-                                    container_format=container_format,
-                                    disk_format=disk_format,
-                                    is_public=False, data=image_file,
-                                    properties={'key1': 'value1'})
+        image = cls.create_image(name=name,
+                                 container_format=container_format,
+                                 disk_format=disk_format,
+                                 is_public=False, data=image_file,
+                                 properties={'key1': 'value1'})
         image_id = image['id']
         return image_id
 
     @test.attr(type='gate')
     def test_list_image_metadata(self):
         # All metadata key/value pairs for an image should be returned
-        _, resp_metadata = self.client.get_image_meta(self.image_id)
+        resp_metadata = self.client.get_image_meta(self.image_id)
         expected = {'key1': 'value1'}
         self.assertEqual(expected, resp_metadata['properties'])
 
@@ -359,12 +266,12 @@
     def test_update_image_metadata(self):
         # The metadata for the image should match the updated values
         req_metadata = {'key1': 'alt1', 'key2': 'value2'}
-        _, metadata = self.client.get_image_meta(self.image_id)
+        metadata = self.client.get_image_meta(self.image_id)
         self.assertEqual(metadata['properties'], {'key1': 'value1'})
         metadata['properties'].update(req_metadata)
-        _, metadata = self.client.update_image(
+        metadata = self.client.update_image(
             self.image_id, properties=metadata['properties'])
 
-        _, resp_metadata = self.client.get_image_meta(self.image_id)
+        resp_metadata = self.client.get_image_meta(self.image_id)
         expected = {'key1': 'alt1', 'key2': 'value2'}
         self.assertEqual(expected, resp_metadata['properties'])
diff --git a/tempest/api/image/v2/test_images.py b/tempest/api/image/v2/test_images.py
index 7e018e5..e307c5c 100644
--- a/tempest/api/image/v2/test_images.py
+++ b/tempest/api/image/v2/test_images.py
@@ -37,11 +37,11 @@
 
         uuid = '00000000-1111-2222-3333-444455556666'
         image_name = data_utils.rand_name('image')
-        _, body = self.create_image(name=image_name,
-                                    container_format='bare',
-                                    disk_format='raw',
-                                    visibility='private',
-                                    ramdisk_id=uuid)
+        body = self.create_image(name=image_name,
+                                 container_format='bare',
+                                 disk_format='raw',
+                                 visibility='private',
+                                 ramdisk_id=uuid)
         self.assertIn('id', body)
         image_id = body.get('id')
         self.assertIn('name', body)
@@ -57,7 +57,7 @@
         self.client.store_image(image_id, image_file)
 
         # Now try to get image details
-        _, body = self.client.get_image(image_id)
+        body = self.client.get_image(image_id)
         self.assertEqual(image_id, body['id'])
         self.assertEqual(image_name, body['name'])
         self.assertEqual(uuid, body['ramdisk_id'])
@@ -74,10 +74,10 @@
 
         # Create image
         image_name = data_utils.rand_name('image')
-        _, body = self.client.create_image(name=image_name,
-                                           container_format='bare',
-                                           disk_format='raw',
-                                           visibility='private')
+        body = self.client.create_image(name=image_name,
+                                        container_format='bare',
+                                        disk_format='raw',
+                                        visibility='private')
         image_id = body['id']
 
         # Delete Image
@@ -85,7 +85,7 @@
         self.client.wait_for_resource_deletion(image_id)
 
         # Verifying deletion
-        _, images = self.client.image_list()
+        images = self.client.image_list()
         images_id = [item['id'] for item in images]
         self.assertNotIn(image_id, images_id)
 
@@ -95,10 +95,10 @@
 
         # Create image
         image_name = data_utils.rand_name('image')
-        _, body = self.client.create_image(name=image_name,
-                                           container_format='bare',
-                                           disk_format='iso',
-                                           visibility='private')
+        body = self.client.create_image(name=image_name,
+                                        container_format='bare',
+                                        disk_format='iso',
+                                        visibility='private')
         self.addCleanup(self.client.delete_image, body['id'])
         self.assertEqual('queued', body['status'])
         image_id = body['id']
@@ -109,12 +109,12 @@
 
         # Update Image
         new_image_name = data_utils.rand_name('new-image')
-        _, body = self.client.update_image(image_id, [
+        body = self.client.update_image(image_id, [
             dict(replace='/name', value=new_image_name)])
 
         # Verifying updating
 
-        _, body = self.client.get_image(image_id)
+        body = self.client.get_image(image_id)
         self.assertEqual(image_id, body['id'])
         self.assertEqual(new_image_name, body['name'])
 
@@ -147,10 +147,10 @@
         size = random.randint(1024, 4096)
         image_file = StringIO.StringIO(data_utils.random_bytes(size))
         name = data_utils.rand_name('image-')
-        _, body = cls.create_image(name=name,
-                                   container_format=container_format,
-                                   disk_format=disk_format,
-                                   visibility='private')
+        body = cls.create_image(name=name,
+                                container_format=container_format,
+                                disk_format=disk_format,
+                                visibility='private')
         image_id = body['id']
         cls.client.store_image(image_id, data=image_file)
 
@@ -160,7 +160,7 @@
         """
         Perform list action with given params and validates result.
         """
-        _, images_list = self.client.image_list(params=params)
+        images_list = self.client.image_list(params=params)
         # Validating params of fetched images
         for image in images_list:
             for key in params:
@@ -170,7 +170,7 @@
     @test.attr(type='gate')
     def test_index_no_params(self):
         # Simple test to see all fixture images returned
-        _, images_list = self.client.image_list()
+        images_list = self.client.image_list()
         image_list = map(lambda x: x['id'], images_list)
 
         for image in self.created_images:
@@ -199,7 +199,7 @@
         # Test to get all images by size
         image_id = self.created_images[1]
         # Get image metadata
-        _, image = self.client.get_image(image_id)
+        image = self.client.get_image(image_id)
 
         params = {"size": image['size']}
         self._list_by_param_value_and_assert(params)
@@ -209,11 +209,11 @@
         # Test to get all images with size between 2000 to 3000
         image_id = self.created_images[1]
         # Get image metadata
-        _, image = self.client.get_image(image_id)
+        image = self.client.get_image(image_id)
 
         size = image['size']
         params = {"size_min": size - 500, "size_max": size + 500}
-        _, images_list = self.client.image_list(params=params)
+        images_list = self.client.image_list(params=params)
         image_size_list = map(lambda x: x['size'], images_list)
 
         for image_size in image_size_list:
@@ -231,7 +231,7 @@
     def test_list_images_param_limit(self):
         # Test to get images by limit
         params = {"limit": 2}
-        _, images_list = self.client.image_list(params=params)
+        images_list = self.client.image_list(params=params)
 
         self.assertEqual(len(images_list), params['limit'],
                          "Failed to get images by limit")
@@ -240,12 +240,12 @@
     def test_get_image_schema(self):
         # Test to get image schema
         schema = "image"
-        _, body = self.client.get_schema(schema)
+        body = self.client.get_schema(schema)
         self.assertEqual("image", body['name'])
 
     @test.attr(type='gate')
     def test_get_images_schema(self):
         # Test to get images schema
         schema = "images"
-        _, body = self.client.get_schema(schema)
+        body = self.client.get_schema(schema)
         self.assertEqual("images", body['name'])
diff --git a/tempest/api/image/v2/test_images_member.py b/tempest/api/image/v2/test_images_member.py
index 5aaf578..ec1cf14 100644
--- a/tempest/api/image/v2/test_images_member.py
+++ b/tempest/api/image/v2/test_images_member.py
@@ -20,8 +20,8 @@
     @test.attr(type='gate')
     def test_image_share_accept(self):
         image_id = self._create_image()
-        _, member = self.os_img_client.add_member(image_id,
-                                                  self.alt_tenant_id)
+        member = self.os_img_client.add_member(image_id,
+                                               self.alt_tenant_id)
         self.assertEqual(member['member_id'], self.alt_tenant_id)
         self.assertEqual(member['image_id'], image_id)
         self.assertEqual(member['status'], 'pending')
@@ -30,7 +30,7 @@
                                                  self.alt_tenant_id,
                                                  'accepted')
         self.assertIn(image_id, self._list_image_ids_as_alt())
-        _, body = self.os_img_client.get_image_membership(image_id)
+        body = self.os_img_client.get_image_membership(image_id)
         members = body['members']
         member = members[0]
         self.assertEqual(len(members), 1, str(members))
@@ -41,8 +41,8 @@
     @test.attr(type='gate')
     def test_image_share_reject(self):
         image_id = self._create_image()
-        _, member = self.os_img_client.add_member(image_id,
-                                                  self.alt_tenant_id)
+        member = self.os_img_client.add_member(image_id,
+                                               self.alt_tenant_id)
         self.assertEqual(member['member_id'], self.alt_tenant_id)
         self.assertEqual(member['image_id'], image_id)
         self.assertEqual(member['status'], 'pending')
@@ -62,8 +62,8 @@
                                                  'accepted')
 
         self.assertIn(image_id, self._list_image_ids_as_alt())
-        _, member = self.os_img_client.get_member(image_id,
-                                                  self.alt_tenant_id)
+        member = self.os_img_client.get_member(image_id,
+                                               self.alt_tenant_id)
         self.assertEqual(self.alt_tenant_id, member['member_id'])
         self.assertEqual(image_id, member['image_id'])
         self.assertEqual('accepted', member['status'])
@@ -83,10 +83,10 @@
 
     @test.attr(type='gate')
     def test_get_image_member_schema(self):
-        _, body = self.os_img_client.get_schema("member")
+        body = self.os_img_client.get_schema("member")
         self.assertEqual("member", body['name'])
 
     @test.attr(type='gate')
     def test_get_image_members_schema(self):
-        _, body = self.os_img_client.get_schema("members")
+        body = self.os_img_client.get_schema("members")
         self.assertEqual("members", body['name'])
diff --git a/tempest/api/image/v2/test_images_member_negative.py b/tempest/api/image/v2/test_images_member_negative.py
index 7da6e65..1f8e3d0 100644
--- a/tempest/api/image/v2/test_images_member_negative.py
+++ b/tempest/api/image/v2/test_images_member_negative.py
@@ -21,8 +21,8 @@
     @test.attr(type=['negative', 'gate'])
     def test_image_share_invalid_status(self):
         image_id = self._create_image()
-        _, member = self.os_img_client.add_member(image_id,
-                                                  self.alt_tenant_id)
+        member = self.os_img_client.add_member(image_id,
+                                               self.alt_tenant_id)
         self.assertEqual(member['status'], 'pending')
         self.assertRaises(exceptions.BadRequest,
                           self.alt_img_client.update_member_status,
@@ -31,8 +31,8 @@
     @test.attr(type=['negative', 'gate'])
     def test_image_share_owner_cannot_accept(self):
         image_id = self._create_image()
-        _, member = self.os_img_client.add_member(image_id,
-                                                  self.alt_tenant_id)
+        member = self.os_img_client.add_member(image_id,
+                                               self.alt_tenant_id)
         self.assertEqual(member['status'], 'pending')
         self.assertNotIn(image_id, self._list_image_ids_as_alt())
         self.assertRaises(exceptions.Unauthorized,
diff --git a/tempest/api/image/v2/test_images_negative.py b/tempest/api/image/v2/test_images_negative.py
index 722929e..fc781b1 100644
--- a/tempest/api/image/v2/test_images_negative.py
+++ b/tempest/api/image/v2/test_images_negative.py
@@ -52,9 +52,9 @@
     def test_get_delete_deleted_image(self):
         # get and delete the deleted image
         # create and delete image
-        _, body = self.client.create_image(name='test',
-                                           container_format='bare',
-                                           disk_format='raw')
+        body = self.client.create_image(name='test',
+                                        container_format='bare',
+                                        disk_format='raw')
         image_id = body['id']
         self.client.delete_image(image_id)
         self.client.wait_for_resource_deletion(image_id)
diff --git a/tempest/api/image/v2/test_images_tags.py b/tempest/api/image/v2/test_images_tags.py
index a9db24b..4686de2 100644
--- a/tempest/api/image/v2/test_images_tags.py
+++ b/tempest/api/image/v2/test_images_tags.py
@@ -21,19 +21,19 @@
 
     @test.attr(type='gate')
     def test_update_delete_tags_for_image(self):
-        _, body = self.create_image(container_format='bare',
-                                    disk_format='raw',
-                                    visibility='private')
+        body = self.create_image(container_format='bare',
+                                 disk_format='raw',
+                                 visibility='private')
         image_id = body['id']
         tag = data_utils.rand_name('tag-')
         self.addCleanup(self.client.delete_image, image_id)
 
         # Creating image tag and verify it.
         self.client.add_image_tag(image_id, tag)
-        _, body = self.client.get_image(image_id)
+        body = self.client.get_image(image_id)
         self.assertIn(tag, body['tags'])
 
         # Deleting image tag and verify it.
         self.client.delete_image_tag(image_id, tag)
-        _, body = self.client.get_image(image_id)
+        body = self.client.get_image(image_id)
         self.assertNotIn(tag, body['tags'])
diff --git a/tempest/api/image/v2/test_images_tags_negative.py b/tempest/api/image/v2/test_images_tags_negative.py
index 8e42b7c..aa0a214 100644
--- a/tempest/api/image/v2/test_images_tags_negative.py
+++ b/tempest/api/image/v2/test_images_tags_negative.py
@@ -33,10 +33,10 @@
     @test.attr(type=['negative', 'gate'])
     def test_delete_non_existing_tag(self):
         # Delete non existing tag.
-        _, body = self.create_image(container_format='bare',
-                                    disk_format='raw',
-                                    visibility='private'
-                                    )
+        body = self.create_image(container_format='bare',
+                                 disk_format='raw',
+                                 visibility='private'
+                                 )
         image_id = body['id']
         tag = data_utils.rand_name('non-exist-tag-')
         self.addCleanup(self.client.delete_image, image_id)
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 12b2d13..10cda53 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -396,8 +396,11 @@
         body = cls.client.list_router_interfaces(router['id'])
         interfaces = body['ports']
         for i in interfaces:
-            cls.client.remove_router_interface_with_subnet_id(
-                router['id'], i['fixed_ips'][0]['subnet_id'])
+            try:
+                cls.client.remove_router_interface_with_subnet_id(
+                    router['id'], i['fixed_ips'][0]['subnet_id'])
+            except exceptions.NotFound:
+                pass
         cls.client.delete_router(router['id'])
 
     @classmethod
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index 15c5421..6ce1216 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -25,7 +25,6 @@
 
 
 class NetworksTestDHCPv6(base.BaseNetworkTest):
-    _interface = 'json'
     _ip_version = 6
 
     """ Test DHCPv6 specific features using SLAAC, stateless and
@@ -39,7 +38,7 @@
     """
 
     @classmethod
-    def resource_setup(cls):
+    def skip_checks(cls):
         msg = None
         if not CONF.network_feature_enabled.ipv6:
             msg = "IPv6 is not enabled"
@@ -47,6 +46,9 @@
             msg = "DHCPv6 attributes are not enabled."
         if msg:
             raise cls.skipException(msg)
+
+    @classmethod
+    def resource_setup(cls):
         super(NetworksTestDHCPv6, cls).resource_setup()
         cls.network = cls.create_network()
 
@@ -60,7 +62,7 @@
         body = self.client.list_ports()
         ports = body['ports']
         for port in ports:
-            if (port['device_owner'] == 'network:router_interface'
+            if (port['device_owner'].startswith('network:router_interface')
                 and port['device_id'] in [r['id'] for r in self.routers]):
                 self.client.remove_router_interface_with_port_id(
                     port['device_id'], port['id']
@@ -371,7 +373,6 @@
         for ra_mode, add_mode in (
                 ('dhcpv6-stateful', 'dhcpv6-stateful'),
                 ('dhcpv6-stateful', None),
-                (None, 'dhcpv6-stateful'),
         ):
             kwargs = {'ipv6_ra_mode': ra_mode,
                       'ipv6_address_mode': add_mode}
diff --git a/tempest/api/network/test_floating_ips_negative.py b/tempest/api/network/test_floating_ips_negative.py
new file mode 100644
index 0000000..82f0519
--- /dev/null
+++ b/tempest/api/network/test_floating_ips_negative.py
@@ -0,0 +1,78 @@
+# Copyright 2014 Hewlett-Packard Development Company, L.P.
+# Copyright 2014 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.network import base
+from tempest.common.utils import data_utils
+from tempest import config
+from tempest import exceptions
+from tempest import test
+
+CONF = config.CONF
+
+
+class FloatingIPNegativeTestJSON(base.BaseNetworkTest):
+    _interface = 'json'
+    """
+    Test the following negative  operations for floating ips:
+
+        Create floatingip with a port that is unreachable to external network
+        Create floatingip in private network
+        Associate floatingip with port that is unreachable to external network
+    """
+
+    @classmethod
+    def resource_setup(cls):
+        super(FloatingIPNegativeTestJSON, cls).resource_setup()
+        if not test.is_extension_enabled('router', 'network'):
+            msg = "router extension not enabled."
+            raise cls.skipException(msg)
+        cls.ext_net_id = CONF.network.public_network_id
+        # Create a network with a subnet connected to a router.
+        cls.network = cls.create_network()
+        cls.subnet = cls.create_subnet(cls.network)
+        cls.router = cls.create_router(data_utils.rand_name('router'))
+        cls.create_router_interface(cls.router['id'], cls.subnet['id'])
+        cls.port = cls.create_port(cls.network)
+
+    @test.attr(type=['negative', 'smoke'])
+    def test_create_floatingip_with_port_ext_net_unreachable(self):
+        self.assertRaises(exceptions.NotFound, self.client.create_floatingip,
+                          floating_network_id=self.ext_net_id,
+                          port_id=self.port['id'],
+                          fixed_ip_address=self.port['fixed_ips'][0]
+                                                    ['ip_address'])
+
+    @test.attr(type=['negative', 'smoke'])
+    def test_create_floatingip_in_private_network(self):
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.create_floatingip,
+                          floating_network_id=self.network['id'],
+                          port_id=self.port['id'],
+                          fixed_ip_address=self.port['fixed_ips'][0]
+                                                    ['ip_address'])
+
+    @test.attr(type=['negative', 'smoke'])
+    def test_associate_floatingip_port_ext_net_unreachable(self):
+        # Create floating ip
+        body = self.client.create_floatingip(
+            floating_network_id=self.ext_net_id)
+        floating_ip = body['floatingip']
+        self.addCleanup(self.client.delete_floatingip, floating_ip['id'])
+        # Associate floating IP to the other port
+        self.assertRaises(exceptions.NotFound, self.client.update_floatingip,
+                          floating_ip['id'], port_id=self.port['id'],
+                          fixed_ip_address=self.port['fixed_ips'][0]
+                          ['ip_address'])
diff --git a/tempest/api/network/test_load_balancer.py b/tempest/api/network/test_load_balancer.py
index 289da7e..b606115 100644
--- a/tempest/api/network/test_load_balancer.py
+++ b/tempest/api/network/test_load_balancer.py
@@ -422,5 +422,6 @@
         self.assertEqual(2, member['weight'])
 
 
+@test.skip_because(bug="1402007")
 class LoadBalancerIpV6TestJSON(LoadBalancerTestJSON):
     _ip_version = 6
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index 1f827da..e70519e 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -66,7 +66,8 @@
         super(NetworksTestJSON, cls).resource_setup()
         cls.network = cls.create_network()
         cls.name = cls.network['name']
-        cls.subnet = cls.create_subnet(cls.network)
+        cls.subnet = cls._create_subnet_with_last_subnet_block(cls.network,
+                                                               cls._ip_version)
         cls.cidr = cls.subnet['cidr']
         cls._subnet_data = {6: {'gateway':
                                 str(cls._get_gateway_from_tempest_conf(6)),
@@ -96,6 +97,23 @@
                                 'new_dns_nameservers': ['7.8.8.8', '7.8.4.4']}}
 
     @classmethod
+    def _create_subnet_with_last_subnet_block(cls, network, ip_version):
+        """Derive last subnet CIDR block from tenant CIDR and
+           create the subnet with that derived CIDR
+        """
+        if ip_version == 4:
+            cidr = netaddr.IPNetwork(CONF.network.tenant_network_cidr)
+            mask_bits = CONF.network.tenant_network_mask_bits
+        elif ip_version == 6:
+            cidr = netaddr.IPNetwork(CONF.network.tenant_network_v6_cidr)
+            mask_bits = CONF.network.tenant_network_v6_mask_bits
+
+        subnet_cidr = list(cidr.subnet(mask_bits))[-1]
+        gateway_ip = str(netaddr.IPAddress(subnet_cidr) + 1)
+        return cls.create_subnet(network, gateway=gateway_ip,
+                                 cidr=subnet_cidr, mask_bits=mask_bits)
+
+    @classmethod
     def _get_gateway_from_tempest_conf(cls, ip_version):
         """Return first subnet gateway for configured CIDR """
         if ip_version == 4:
@@ -129,6 +147,15 @@
         self.assertThat(actual, custom_matchers.MatchesDictExceptForKeys(
                         expected, exclude_keys))
 
+    def _delete_network(self, network):
+        # Deleting network also deletes its subnets if exists
+        self.client.delete_network(network['id'])
+        if network in self.networks:
+            self.networks.remove(network)
+        for subnet in self.subnets:
+            if subnet['network_id'] == network['id']:
+                self.subnets.remove(subnet)
+
     def _create_verify_delete_subnet(self, cidr=None, mask_bits=None,
                                      **kwargs):
         network = self.create_network()
@@ -156,6 +183,7 @@
         # Create a network
         name = data_utils.rand_name('network-')
         network = self.create_network(network_name=name)
+        self.addCleanup(self._delete_network, network)
         net_id = network['id']
         self.assertEqual('ACTIVE', network['status'])
         # Verify network update
@@ -312,6 +340,7 @@
     @test.attr(type='smoke')
     def test_update_subnet_gw_dns_host_routes_dhcp(self):
         network = self.create_network()
+        self.addCleanup(self._delete_network, network)
 
         subnet = self.create_subnet(
             network, **self.subnet_dict(['gateway', 'host_routes',
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 80097db..7ab5ebd 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -221,13 +221,17 @@
 
     @test.attr(type='smoke')
     def test_create_port_with_no_securitygroups(self):
-        port = self.create_port(self.create_network(), security_groups=[])
+        network = self.create_network()
+        self.create_subnet(network)
+        port = self.create_port(network, security_groups=[])
         self.assertIsNotNone(port['security_groups'])
         self.assertEmpty(port['security_groups'])
 
     @test.attr(type='smoke')
     def test_update_port_with_no_securitygroups(self):
-        port = self.create_port(self.create_network())
+        network = self.create_network()
+        self.create_subnet(network)
+        port = self.create_port(network)
         # Verify that port is created with default security group
         self.assertIsNotNone(port['security_groups'])
         self.assertNotEmpty(port['security_groups'])
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index 88aa3c9..d571e92 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -83,6 +83,24 @@
                           self.client.delete_router,
                           self.router['id'])
 
+    @test.attr(type=['negative', 'smoke'])
+    def test_show_non_existent_router_returns_404(self):
+        router = data_utils.rand_name('non_exist_router')
+        self.assertRaises(exceptions.NotFound, self.client.show_router,
+                          router)
+
+    @test.attr(type=['negative', 'smoke'])
+    def test_update_non_existent_router_returns_404(self):
+        router = data_utils.rand_name('non_exist_router')
+        self.assertRaises(exceptions.NotFound, self.client.update_router,
+                          router, name="new_name")
+
+    @test.attr(type=['negative', 'smoke'])
+    def test_delete_non_existent_router_returns_404(self):
+        router = data_utils.rand_name('non_exist_router')
+        self.assertRaises(exceptions.NotFound, self.client.delete_router,
+                          router)
+
 
 class RoutersNegativeIpV6Test(RoutersNegativeTest):
     _ip_version = 6
diff --git a/tempest/api/network/test_security_groups_negative.py b/tempest/api/network/test_security_groups_negative.py
index fa1f6ee..fb51e30 100644
--- a/tempest/api/network/test_security_groups_negative.py
+++ b/tempest/api/network/test_security_groups_negative.py
@@ -193,3 +193,22 @@
 class NegativeSecGroupIPv6Test(NegativeSecGroupTest):
     _ip_version = 6
     _tenant_network_cidr = CONF.network.tenant_network_v6_cidr
+
+    @test.attr(type=['negative', 'gate'])
+    def test_create_security_group_rule_wrong_ip_prefix_version(self):
+        group_create_body, _ = self._create_security_group()
+
+        # Create rule with bad remote_ip_prefix
+        pairs = ({'ethertype': 'IPv6',
+                  'ip_prefix': CONF.network.tenant_network_cidr},
+                 {'ethertype': 'IPv4',
+                  'ip_prefix': CONF.network.tenant_network_v6_cidr})
+        for pair in pairs:
+            self.assertRaisesRegexp(
+                exceptions.BadRequest,
+                "Conflicting value ethertype",
+                self.client.create_security_group_rule,
+                security_group_id=group_create_body['security_group']['id'],
+                protocol='tcp', direction='ingress',
+                ethertype=pair['ethertype'],
+                remote_ip_prefix=pair['ip_prefix'])
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 7fabb7d..fcb80f5 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -46,10 +46,8 @@
         cls.object_client = cls.os.object_client
         cls.container_client = cls.os.container_client
         cls.account_client = cls.os.account_client
-        cls.custom_object_client = cls.os.custom_object_client
         cls.token_client = cls.os_admin.token_client
         cls.identity_admin_client = cls.os_admin.identity_client
-        cls.custom_account_client = cls.os.custom_account_client
         cls.object_client_alt = cls.os_alt.object_client
         cls.container_client_alt = cls.os_alt.container_client
         cls.identity_client_alt = cls.os_alt.identity_client
@@ -58,8 +56,6 @@
         cls.object_client.auth_provider.clear_auth()
         cls.container_client.auth_provider.clear_auth()
         cls.account_client.auth_provider.clear_auth()
-        cls.custom_object_client.auth_provider.clear_auth()
-        cls.custom_account_client.auth_provider.clear_auth()
         cls.object_client_alt.auth_provider.clear_auth()
         cls.container_client_alt.auth_provider.clear_auth()
 
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index e75e971..1832b37 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -43,30 +43,30 @@
     def setUp(self):
         super(AccountQuotasTest, self).setUp()
 
-        # Set the reselleradmin auth in headers for next custom_account_client
+        # Set the reselleradmin auth in headers for next account_client
         # request
-        self.custom_account_client.auth_provider.set_alt_auth_data(
+        self.account_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.reselleradmin_auth_data
         )
         # Set a quota of 20 bytes on the user's account before each test
         headers = {"X-Account-Meta-Quota-Bytes": "20"}
 
-        self.os.custom_account_client.request("POST", url="", headers=headers,
-                                              body="")
+        self.os.account_client.request("POST", url="", headers=headers,
+                                       body="")
 
     def tearDown(self):
-        # Set the reselleradmin auth in headers for next custom_account_client
+        # Set the reselleradmin auth in headers for next account_client
         # request
-        self.custom_account_client.auth_provider.set_alt_auth_data(
+        self.account_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.reselleradmin_auth_data
         )
         # remove the quota from the container
         headers = {"X-Remove-Account-Meta-Quota-Bytes": "x"}
 
-        self.os.custom_account_client.request("POST", url="", headers=headers,
-                                              body="")
+        self.os.account_client.request("POST", url="", headers=headers,
+                                       body="")
         super(AccountQuotasTest, self).tearDown()
 
     @classmethod
@@ -91,7 +91,7 @@
         """Test that the ResellerAdmin is able to modify and remove the quota
         on a user's account.
 
-        Using the custom_account client, the test modifies the quota
+        Using the account client, the test modifies the quota
         successively to:
 
         * "25": a random value different from the initial quota value.
@@ -100,15 +100,15 @@
         """
         for quota in ("25", "", "20"):
 
-            self.custom_account_client.auth_provider.set_alt_auth_data(
+            self.account_client.auth_provider.set_alt_auth_data(
                 request_part='headers',
                 auth_data=self.reselleradmin_auth_data
             )
             headers = {"X-Account-Meta-Quota-Bytes": quota}
 
-            resp, _ = self.os.custom_account_client.request("POST", url="",
-                                                            headers=headers,
-                                                            body="")
+            resp, _ = self.os.account_client.request("POST", url="",
+                                                     headers=headers,
+                                                     body="")
 
             self.assertEqual(resp["status"], "204")
             self.assertHeaders(resp, 'Account', 'POST')
diff --git a/tempest/api/object_storage/test_account_quotas_negative.py b/tempest/api/object_storage/test_account_quotas_negative.py
index 6c1fb5a..a6ea6ee 100644
--- a/tempest/api/object_storage/test_account_quotas_negative.py
+++ b/tempest/api/object_storage/test_account_quotas_negative.py
@@ -43,30 +43,30 @@
 
     def setUp(self):
         super(AccountQuotasNegativeTest, self).setUp()
-        # Set the reselleradmin auth in headers for next custom_account_client
+        # Set the reselleradmin auth in headers for next account_client
         # request
-        self.custom_account_client.auth_provider.set_alt_auth_data(
+        self.account_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.reselleradmin_auth_data
         )
         # Set a quota of 20 bytes on the user's account before each test
         headers = {"X-Account-Meta-Quota-Bytes": "20"}
 
-        self.os.custom_account_client.request("POST", url="", headers=headers,
-                                              body="")
+        self.os.account_client.request("POST", url="", headers=headers,
+                                       body="")
 
     def tearDown(self):
-        # Set the reselleradmin auth in headers for next custom_account_client
+        # Set the reselleradmin auth in headers for next account_client
         # request
-        self.custom_account_client.auth_provider.set_alt_auth_data(
+        self.account_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.reselleradmin_auth_data
         )
         # remove the quota from the container
         headers = {"X-Remove-Account-Meta-Quota-Bytes": "x"}
 
-        self.os.custom_account_client.request("POST", url="", headers=headers,
-                                              body="")
+        self.os.account_client.request("POST", url="", headers=headers,
+                                       body="")
         super(AccountQuotasNegativeTest, self).tearDown()
 
     @classmethod
diff --git a/tempest/api/object_storage/test_account_services_negative.py b/tempest/api/object_storage/test_account_services_negative.py
index e4c46e2..ef04387 100644
--- a/tempest/api/object_storage/test_account_services_negative.py
+++ b/tempest/api/object_storage/test_account_services_negative.py
@@ -34,10 +34,10 @@
         test_auth_provider.auth_data
 
         # Get fresh auth for test user and set it to next auth request for
-        # custom_account_client
+        # account_client
         delattr(test_auth_provider, 'auth_data')
         test_auth_new_data = test_auth_provider.auth_data
-        self.custom_account_client.auth_provider.set_alt_auth_data(
+        self.account_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=test_auth_new_data
         )
@@ -45,5 +45,5 @@
         params = {'format': 'json'}
         # list containers with non-authorized user token
         self.assertRaises(exceptions.Unauthorized,
-                          self.custom_account_client.list_account_containers,
+                          self.account_client.list_account_containers,
                           params=params)
diff --git a/tempest/api/object_storage/test_container_acl.py b/tempest/api/object_storage/test_container_acl.py
index 2244900..205bc91 100644
--- a/tempest/api/object_storage/test_container_acl.py
+++ b/tempest/api/object_storage/test_container_acl.py
@@ -52,11 +52,11 @@
                                                    object_name, 'data')
         self.assertHeaders(resp, 'Object', 'PUT')
         # Trying to read the object with rights
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.test_auth_data
         )
-        resp, _ = self.custom_object_client.get_object(
+        resp, _ = self.object_client.get_object(
             self.container_name, object_name)
         self.assertHeaders(resp, 'Object', 'GET')
 
@@ -71,12 +71,12 @@
             metadata_prefix='')
         self.assertHeaders(resp_meta, 'Container', 'POST')
         # Trying to write the object with rights
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.test_auth_data
         )
         object_name = data_utils.rand_name(name='Object')
-        resp, _ = self.custom_object_client.create_object(
+        resp, _ = self.object_client.create_object(
             self.container_name,
-            object_name, 'data')
+            object_name, 'data', headers={})
         self.assertHeaders(resp, 'Object', 'PUT')
diff --git a/tempest/api/object_storage/test_container_acl_negative.py b/tempest/api/object_storage/test_container_acl_negative.py
index fed4549..138d25a 100644
--- a/tempest/api/object_storage/test_container_acl_negative.py
+++ b/tempest/api/object_storage/test_container_acl_negative.py
@@ -43,13 +43,13 @@
         # trying to create object with empty headers
         # X-Auth-Token is not provided
         object_name = data_utils.rand_name(name='Object')
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=None
         )
         self.assertRaises(exceptions.Unauthorized,
-                          self.custom_object_client.create_object,
-                          self.container_name, object_name, 'data')
+                          self.object_client.create_object,
+                          self.container_name, object_name, 'data', headers={})
 
     @test.attr(type=['negative', 'gate'])
     def test_delete_object_without_using_creds(self):
@@ -59,12 +59,12 @@
                                                    object_name, 'data')
         # trying to delete object with empty headers
         # X-Auth-Token is not provided
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=None
         )
         self.assertRaises(exceptions.Unauthorized,
-                          self.custom_object_client.delete_object,
+                          self.object_client.delete_object,
                           self.container_name, object_name)
 
     @test.attr(type=['negative', 'gate'])
@@ -73,13 +73,13 @@
         # User provided token is forbidden. ACL are not set
         object_name = data_utils.rand_name(name='Object')
         # trying to create object with non-authorized user
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.test_auth_data
         )
         self.assertRaises(exceptions.Unauthorized,
-                          self.custom_object_client.create_object,
-                          self.container_name, object_name, 'data')
+                          self.object_client.create_object,
+                          self.container_name, object_name, 'data', headers={})
 
     @test.attr(type=['negative', 'gate'])
     def test_read_object_with_non_authorized_user(self):
@@ -90,12 +90,12 @@
             self.container_name, object_name, 'data')
         self.assertHeaders(resp, 'Object', 'PUT')
         # trying to get object with non authorized user token
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.test_auth_data
         )
         self.assertRaises(exceptions.Unauthorized,
-                          self.custom_object_client.get_object,
+                          self.object_client.get_object,
                           self.container_name, object_name)
 
     @test.attr(type=['negative', 'gate'])
@@ -107,12 +107,12 @@
             self.container_name, object_name, 'data')
         self.assertHeaders(resp, 'Object', 'PUT')
         # trying to delete object with non-authorized user token
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.test_auth_data
         )
         self.assertRaises(exceptions.Unauthorized,
-                          self.custom_object_client.delete_object,
+                          self.object_client.delete_object,
                           self.container_name, object_name)
 
     @test.attr(type=['negative', 'smoke'])
@@ -130,12 +130,12 @@
                                                    object_name, 'data')
         self.assertHeaders(resp, 'Object', 'PUT')
         # Trying to read the object without rights
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.test_auth_data
         )
         self.assertRaises(exceptions.Unauthorized,
-                          self.custom_object_client.get_object,
+                          self.object_client.get_object,
                           self.container_name, object_name)
 
     @test.attr(type=['negative', 'smoke'])
@@ -148,15 +148,15 @@
             metadata_prefix='')
         self.assertHeaders(resp_meta, 'Container', 'POST')
         # Trying to write the object without rights
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.test_auth_data
         )
         object_name = data_utils.rand_name(name='Object')
         self.assertRaises(exceptions.Unauthorized,
-                          self.custom_object_client.create_object,
+                          self.object_client.create_object,
                           self.container_name,
-                          object_name, 'data')
+                          object_name, 'data', headers={})
 
     @test.attr(type=['negative', 'smoke'])
     def test_write_object_without_write_rights(self):
@@ -170,15 +170,15 @@
             metadata_prefix='')
         self.assertHeaders(resp_meta, 'Container', 'POST')
         # Trying to write the object without write rights
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.test_auth_data
         )
         object_name = data_utils.rand_name(name='Object')
         self.assertRaises(exceptions.Unauthorized,
-                          self.custom_object_client.create_object,
+                          self.object_client.create_object,
                           self.container_name,
-                          object_name, 'data')
+                          object_name, 'data', headers={})
 
     @test.attr(type=['negative', 'smoke'])
     def test_delete_object_without_write_rights(self):
@@ -197,11 +197,11 @@
                                                    object_name, 'data')
         self.assertHeaders(resp, 'Object', 'PUT')
         # Trying to delete the object without write rights
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=self.test_auth_data
         )
         self.assertRaises(exceptions.Unauthorized,
-                          self.custom_object_client.delete_object,
+                          self.object_client.delete_object,
                           self.container_name,
                           object_name)
diff --git a/tempest/api/object_storage/test_container_staticweb.py b/tempest/api/object_storage/test_container_staticweb.py
index 5c4e0bf..a8e5f9a 100644
--- a/tempest/api/object_storage/test_container_staticweb.py
+++ b/tempest/api/object_storage/test_container_staticweb.py
@@ -17,6 +17,7 @@
 from tempest.api.object_storage import base
 from tempest.common import custom_matchers
 from tempest.common.utils import data_utils
+from tempest import exceptions
 from tempest import test
 
 
@@ -58,15 +59,16 @@
             self.container_name, metadata=headers)
 
         # Maintain original headers, no auth added
-        self.custom_account_client.auth_provider.set_alt_auth_data(
+        self.account_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=None
         )
 
         # test GET on http://account_url/container_name
         # we should retrieve the self.object_name file
-        resp, body = self.custom_account_client.request("GET",
-                                                        self.container_name)
+        resp, body = self.account_client.request("GET",
+                                                 self.container_name,
+                                                 headers={})
         # This request is equivalent to GET object
         self.assertHeaders(resp, 'Object', 'GET')
         self.assertEqual(body, self.object_data)
@@ -89,8 +91,9 @@
 
         # test GET on http://account_url/container_name
         # we should retrieve a listing of objects
-        resp, body = self.custom_account_client.request("GET",
-                                                        self.container_name)
+        resp, body = self.account_client.request("GET",
+                                                 self.container_name,
+                                                 headers={})
         # The target of the request is not any Swift resource. Therefore, the
         # existence of response header is checked without a custom matcher.
         self.assertIn('content-length', resp)
@@ -120,15 +123,16 @@
             self.container_name, metadata=headers)
 
         # Maintain original headers, no auth added
-        self.custom_account_client.auth_provider.set_alt_auth_data(
+        self.account_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=None
         )
 
         # test GET on http://account_url/container_name
         # we should retrieve a listing of objects
-        resp, body = self.custom_account_client.request("GET",
-                                                        self.container_name)
+        resp, body = self.account_client.request("GET",
+                                                 self.container_name,
+                                                 headers={})
         self.assertIn(self.object_name, body)
         css = '<link rel="stylesheet" type="text/css" href="listings.css" />'
         self.assertIn(css, body)
@@ -150,13 +154,12 @@
                                          object_data_404)
 
         # Do not set auth in HTTP headers for next request
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=None
         )
 
         # Request non-existing object
-        resp, body = self.custom_object_client.get_object(self.container_name,
-                                                          "notexisting")
-        self.assertEqual(resp['status'], '404')
-        self.assertEqual(body, object_data_404)
+        self.assertRaises(
+            exceptions.NotFound, self.object_client.get_object,
+            self.container_name, "notexisting")
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index f78220c..cbca5e8 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -177,7 +177,7 @@
         object_name = data_utils.rand_name(name='TestObject')
         data = data_utils.arbitrary_string()
         metadata = {'Expect': '100-continue'}
-        resp = self.custom_object_client.create_object_continue(
+        resp = self.object_client.create_object_continue(
             self.container_name,
             object_name,
             data,
@@ -186,7 +186,7 @@
         self.assertIn('status', resp)
         self.assertEqual(resp['status'], '100')
 
-        self.custom_object_client.create_object_continue(
+        self.object_client.create_object_continue(
             self.container_name,
             object_name,
             data,
@@ -1014,11 +1014,11 @@
         self.assertEqual(resp_meta['x-container-read'], '.r:*,.rlistings')
 
         # trying to get object with empty headers as it is public readable
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=None
         )
-        resp, body = self.custom_object_client.get_object(
+        resp, body = self.object_client.get_object(
             self.container_name, object_name)
         self.assertHeaders(resp, 'Object', 'GET')
 
@@ -1052,12 +1052,12 @@
 
         # get auth token of alternative user
         alt_auth_data = self.identity_client_alt.auth_provider.auth_data
-        self.custom_object_client.auth_provider.set_alt_auth_data(
+        self.object_client.auth_provider.set_alt_auth_data(
             request_part='headers',
             auth_data=alt_auth_data
         )
         # access object using alternate user creds
-        resp, body = self.custom_object_client.get_object(
+        resp, body = self.object_client.get_object(
             self.container_name, object_name)
         self.assertHeaders(resp, 'Object', 'GET')
 
diff --git a/tempest/api/orchestration/base.py b/tempest/api/orchestration/base.py
index 6896362..21f2578 100644
--- a/tempest/api/orchestration/base.py
+++ b/tempest/api/orchestration/base.py
@@ -113,9 +113,9 @@
     def _create_image(cls, name_start='image-heat-', container_format='bare',
                       disk_format='iso'):
         image_name = data_utils.rand_name(name_start)
-        _, body = cls.images_v2_client.create_image(image_name,
-                                                    container_format,
-                                                    disk_format)
+        body = cls.images_v2_client.create_image(image_name,
+                                                 container_format,
+                                                 disk_format)
         image_id = body['id']
         cls.images.append(image_id)
         return body
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 21d0a86..b7e9422 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -70,11 +70,14 @@
         self.addCleanup(self.servers_client.delete_server, server['id'])
         self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
         mountpoint = '/dev/%s' % CONF.compute.volume_device_name
-        _, body = self.volumes_client.attach_volume(
-            self.volume_origin['id'], server['id'], mountpoint)
+        _, body = self.servers_client.attach_volume(
+            server['id'], self.volume_origin['id'], mountpoint)
         self.volumes_client.wait_for_volume_status(self.volume_origin['id'],
                                                    'in-use')
-        self.addCleanup(self._detach, self.volume_origin['id'])
+        self.addCleanup(self.volumes_client.wait_for_volume_status,
+                        self.volume_origin['id'], 'available')
+        self.addCleanup(self.servers_client.detach_volume, server['id'],
+                        self.volume_origin['id'])
         # Snapshot a volume even if it's attached to an instance
         snapshot = self.create_snapshot(self.volume_origin['id'],
                                         force=True)
diff --git a/tempest/api_schema/request/compute/servers.py b/tempest/api_schema/request/compute/servers.py
deleted file mode 100644
index 731649c..0000000
--- a/tempest/api_schema/request/compute/servers.py
+++ /dev/null
@@ -1,36 +0,0 @@
-# (c) 2014 Deutsche Telekom AG
-#    Licensed under the Apache License, Version 2.0 (the "License");
-#    you may not use this file except in compliance with the License.
-#    You may obtain a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#    See the License for the specific language governing permissions and
-#    limitations under the License.
-
-common_get_console_output = {
-    "name": "get-console-output",
-    "http-method": "POST",
-    "url": "servers/%s/action",
-    "resources": [
-        {"name": "server", "expected_result": 404}
-    ],
-    "json-schema": {
-        "type": "object",
-        "properties": {
-            "os-getConsoleOutput": {
-                "type": "object",
-                "properties": {
-                    "length": {
-                        "type": ["integer", "string"],
-                        "minimum": 0
-                    }
-                }
-            }
-        },
-        "additionalProperties": False
-    }
-}
diff --git a/tempest/api_schema/request/compute/v2/servers.py b/tempest/api_schema/request/compute/v2/servers.py
deleted file mode 100644
index c9002ed..0000000
--- a/tempest/api_schema/request/compute/v2/servers.py
+++ /dev/null
@@ -1,18 +0,0 @@
-# (c) 2014 Deutsche Telekom AG
-#    Licensed under the Apache License, Version 2.0 (the "License");
-#    you may not use this file except in compliance with the License.
-#    You may obtain a copy of the License at
-#
-#        http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS,
-#    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-#    See the License for the specific language governing permissions and
-#    limitations under the License.
-
-import copy
-
-from tempest.api_schema.request.compute import servers
-
-get_console_output = copy.deepcopy(servers.common_get_console_output)
diff --git a/tempest/auth.py b/tempest/auth.py
index 022a450..9687905 100644
--- a/tempest/auth.py
+++ b/tempest/auth.py
@@ -499,7 +499,6 @@
     ATTRIBUTES = []
     TYPES = {
         'identity_admin': ('identity', 'admin'),
-        'compute_admin': ('compute_admin', None),
         'user': ('identity', None),
         'alt_user': ('identity', 'alt')
     }
@@ -561,7 +560,10 @@
             raise exceptions.InvalidCredentials()
         creds = cls._get_default(credentials_type)
         if not creds.is_valid():
-            raise exceptions.InvalidConfiguration()
+            msg = ("The %s credentials are incorrectly set in the config file."
+                   " Double check that all required values are assigned" %
+                   credentials_type)
+            raise exceptions.InvalidConfiguration(msg)
         return creds
 
     @classmethod
diff --git a/tempest/clients.py b/tempest/clients.py
index 261b27c..8d59742 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -14,7 +14,7 @@
 #    under the License.
 
 from tempest import auth
-from tempest.common import rest_client
+from tempest.common import negative_rest_client
 from tempest import config
 from tempest import manager
 from tempest.openstack.common import log as logging
@@ -83,12 +83,8 @@
     MessagingClientJSON
 from tempest.services.network.json.network_client import NetworkClientJSON
 from tempest.services.object_storage.account_client import AccountClient
-from tempest.services.object_storage.account_client import \
-    AccountClientCustomizedHeader
 from tempest.services.object_storage.container_client import ContainerClient
 from tempest.services.object_storage.object_client import ObjectClient
-from tempest.services.object_storage.object_client import \
-    ObjectClientCustomizedHeader
 from tempest.services.orchestration.json.orchestration_client import \
     OrchestrationClient
 from tempest.services.telemetry.json.telemetry_client import \
@@ -157,9 +153,8 @@
         if CONF.service_available.ceilometer:
             self.telemetry_client = TelemetryClientJSON(
                 self.auth_provider)
-        self.negative_client = rest_client.NegativeRestClient(
-            self.auth_provider)
-        self.negative_client.service = service
+        self.negative_client = negative_rest_client.NegativeRestClient(
+            self.auth_provider, service)
 
         # TODO(andreaf) EC2 client still do their auth, v2 only
         ec2_client_args = (self.credentials.username,
@@ -178,10 +173,6 @@
             self.auth_provider)
         self.ec2api_client = botoclients.APIClientEC2(*ec2_client_args)
         self.s3_client = botoclients.ObjectClientS3(*ec2_client_args)
-        self.custom_object_client = ObjectClientCustomizedHeader(
-            self.auth_provider)
-        self.custom_account_client = \
-            AccountClientCustomizedHeader(self.auth_provider)
         self.data_processing_client = DataProcessingClient(
             self.auth_provider)
 
@@ -289,18 +280,3 @@
             credentials=auth.get_default_credentials('identity_admin'),
             interface=interface,
             service=service)
-
-
-class ComputeAdminManager(Manager):
-
-    """
-    Manager object that uses the compute_admin credentials for its
-    managed client objects
-    """
-
-    def __init__(self, interface='json', service=None):
-        base = super(ComputeAdminManager, self)
-        base.__init__(
-            credentials=auth.get_default_credentials('compute_admin'),
-            interface=interface,
-            service=service)
diff --git a/tempest/cmd/cleanup.py b/tempest/cmd/cleanup.py
index f36ef56..28f0aa8 100755
--- a/tempest/cmd/cleanup.py
+++ b/tempest/cmd/cleanup.py
@@ -19,18 +19,18 @@
 Runtime Arguments
 -----------------
 
---init-saved-state: Before you can execute cleanup you must initialize
-the saved state by running it with the --init-saved-state flag
+**--init-saved-state**: Before you can execute cleanup you must initialize
+the saved state by running it with the **--init-saved-state** flag
 (creating ./saved_state.json), which protects your deployment from
 cleanup deleting objects you want to keep.  Typically you would run
-cleanup with --init-saved-state prior to a tempest run. If this is not
+cleanup with **--init-saved-state** prior to a tempest run. If this is not
 the case saved_state.json must be edited, removing objects you want
 cleanup to delete.
 
---dry-run: Creates a report (dry_run.json) of the tenants that will be
+**--dry-run**: Creates a report (dry_run.json) of the tenants that will be
 cleaned up (in the "_tenants_to_clean" array), and the global objects
 that will be removed (tenants, users, flavors and images).  Once
-cleanup is executed in normal mode, running it again with --dry-run
+cleanup is executed in normal mode, running it again with **--dry-run**
 should yield an empty report.
 
 **NOTE**: The _tenants_to_clean array in dry-run.json lists the
@@ -38,17 +38,17 @@
 delete the tenant itself. This may differ from the tenants array as you
 can clean the tempest and alternate tempest tenants but by default,
 cleanup deletes the objects in the tempest and alternate tempest tenants
-but does not delete those tenants unless the --delete-tempest-conf-objects
+but does not delete those tenants unless the **--delete-tempest-conf-objects**
 flag is used to force their deletion.
 
 **Normal mode**: running with no arguments, will query your deployment and
 build a list of objects to delete after filtering out the objects found in
-saved_state.json and based on the --delete-tempest-conf-objects flag.
+saved_state.json and based on the **--delete-tempest-conf-objects** flag.
 
 By default the tempest and alternate tempest users and tenants are not
 deleted and the admin user specified in tempest.conf is never deleted.
 
-Please run with --help to see full list of options.
+Please run with **--help** to see full list of options.
 """
 import argparse
 import json
diff --git a/tempest/cmd/cleanup_service.py b/tempest/cmd/cleanup_service.py
index db862c7..0941008 100644
--- a/tempest/cmd/cleanup_service.py
+++ b/tempest/cmd/cleanup_service.py
@@ -845,7 +845,7 @@
 
     def list(self):
         client = self.client
-        _, images = client.list_images({"all_tenants": True})
+        images = client.list_images({"all_tenants": True})
         if not self.is_save_state:
             images = [image for image in images if image['id']
                       not in self.saved_state_json['images'].keys()]
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index 97aa62b..819f4e2 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -12,11 +12,94 @@
 # License for the specific language governing permissions and limitations
 # under the License.
 
-"""Javelin makes resources that should survive an upgrade.
-
-Javelin is a tool for creating, verifying, and deleting a small set of
+"""Javelin is a tool for creating, verifying, and deleting a small set of
 resources in a declarative way.
 
+Javelin is meant to be used as a way to validate quickly that resources can
+survive an upgrade process.
+
+Authentication
+--------------
+
+Javelin will be creating (and removing) users and tenants so it needs the admin
+credentials of your cloud to operate properly. The corresponding info can be
+given the usual way, either through CLI options or environment variables.
+
+You're probably familiar with these, but just in case::
+
+    +----------+------------------+----------------------+
+    | Param    | CLI              | Environment Variable |
+    +----------+------------------+----------------------+
+    | Username | --os-username    | OS_USERNAME          |
+    | Password | --os-password    | OS_PASSWORD          |
+    | Tenant   | --os-tenant-name | OS_TENANT_NAME       |
+    +----------+------------------+----------------------+
+
+
+Runtime Arguments
+-----------------
+
+**-m/--mode**: (Required) Has to be one of 'check', 'create' or 'destroy'. It
+indicates which actions javelin is going to perform.
+
+**-r/--resources**: (Required) The path to a YAML file describing the resources
+used by Javelin.
+
+**-d/--devstack-base**: (Required) The path to the devstack repo used to
+retrieve artefacts (like images) that will be referenced in the resource files.
+
+**-c/--config-file**: (Optional) The path to a valid Tempest config file
+describing your cloud. Javelin may use this to determine if certain services
+are enabled and modify its behavior accordingly.
+
+
+Resource file
+-------------
+
+The resource file is a valid YAML file describing the resources that will be
+created, checked and destroyed by javelin. Here's a canonical example of a
+resource file::
+
+  tenants:
+    - javelin
+    - discuss
+
+  users:
+    - name: javelin
+      pass: gungnir
+      tenant: javelin
+    - name: javelin2
+      pass: gungnir2
+      tenant: discuss
+
+  # resources that we want to create
+  images:
+    - name: javelin_cirros
+      owner: javelin
+      file: cirros-0.3.2-x86_64-blank.img
+      format: ami
+      aki: cirros-0.3.2-x86_64-vmlinuz
+      ari: cirros-0.3.2-x86_64-initrd
+
+  servers:
+    - name: peltast
+      owner: javelin
+      flavor: m1.small
+      image: javelin_cirros
+    - name: hoplite
+      owner: javelin
+      flavor: m1.medium
+      image: javelin_cirros
+
+
+An important piece of the resource definition is the *owner* field, which is
+the user (that we've created) that is the owner of that resource. All
+operations on that resource will happen as that regular user to ensure that
+admin level access does not mask issues.
+
+The check phase will act like a unit test, using well known assert methods to
+verify that the correct resources exist.
+
 """
 
 import argparse
@@ -445,7 +528,7 @@
 
 
 def _get_image_by_name(client, name):
-    r, body = client.images.image_list()
+    body = client.images.image_list()
     for image in body:
         if name == image['name']:
             return image
@@ -468,19 +551,19 @@
         extras = {}
         if image['format'] == 'ami':
             name, fname = _resolve_image(image, 'aki')
-            r, aki = client.images.create_image(
+            aki = client.images.create_image(
                 '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(
+            ari = client.images.create_image(
                 '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(
+        body = client.images.create_image(
             image['name'], image['format'], image['format'], **extras)
         image_id = body.get('id')
         client.images.store_image(image_id, open(fname, 'r'))
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index b2c2ffb..890c77a 100755
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -59,7 +59,7 @@
 
 def verify_glance_api_versions(os, update):
     # Check glance api versions
-    __, versions = os.image_client.get_versions()
+    versions = os.image_client.get_versions()
     if CONF.image_feature_enabled.api_v1 != ('v1.1' in versions or 'v1.0' in
                                              versions):
         print_and_or_update('api_v1', 'image_feature_enabled',
@@ -104,13 +104,6 @@
                             not CONF.identity_feature_enabled.api_v3, update)
 
 
-def verify_nova_api_versions(os, update):
-    versions = _get_api_versions(os, 'nova')
-    if CONF.compute_feature_enabled.api_v3 != ('v3.0' in versions):
-        print_and_or_update('api_v3', 'compute_feature_enabled',
-                            not CONF.compute_feature_enabled.api_v3, update)
-
-
 def verify_cinder_api_versions(os, update):
     # Check cinder api versions
     versions = _get_api_versions(os, 'cinder')
@@ -127,7 +120,6 @@
         'cinder': verify_cinder_api_versions,
         'glance': verify_glance_api_versions,
         'keystone': verify_keystone_api_versions,
-        'nova': verify_nova_api_versions,
     }
     if service not in verify:
         return
@@ -258,9 +250,9 @@
         'database': 'trove'
     }
     # Get catalog list for endpoints to use for validation
-    __, endpoints = os.endpoints_client.list_endpoints()
+    endpoints = os.endpoints_client.list_endpoints()
     for endpoint in endpoints:
-        __, service = os.service_client.get_service(endpoint['service_id'])
+        service = os.service_client.get_service(endpoint['service_id'])
         services.append(service['type'])
     # Pull all catalog types from config file and compare against endpoint list
     for cfgname in dir(CONF._config):
@@ -335,7 +327,7 @@
         CONF_PARSER = moves.configparser.SafeConfigParser()
         CONF_PARSER.optionxform = str
         CONF_PARSER.readfp(conf_file)
-    os = clients.ComputeAdminManager(interface='json')
+    os = clients.AdminManager(interface='json')
     services = check_service_availability(os, update)
     results = {}
     for service in ['nova', 'cinder', 'neutron', 'swift']:
diff --git a/tempest/common/custom_matchers.py b/tempest/common/custom_matchers.py
index 39e3a67..298a94e 100644
--- a/tempest/common/custom_matchers.py
+++ b/tempest/common/custom_matchers.py
@@ -122,33 +122,21 @@
 
     def match(self, actual):
         for key, value in actual.iteritems():
-            if key == 'content-length' and not value.isdigit():
+            if key in ('content-length', 'x-account-bytes-used',
+                       'x-account-container-count', 'x-account-object-count',
+                       'x-container-bytes-used', 'x-container-object-count')\
+                and not value.isdigit():
+                return InvalidFormat(key, value)
+            elif key in ('content-type', 'date', 'last-modified',
+                         'x-copied-from-last-modified') and not value:
                 return InvalidFormat(key, value)
             elif key == 'x-timestamp' and not re.match("^\d+\.?\d*\Z", value):
                 return InvalidFormat(key, value)
-            elif key == 'x-account-bytes-used' and not value.isdigit():
-                return InvalidFormat(key, value)
-            elif key == 'x-account-container-count' and not value.isdigit():
-                return InvalidFormat(key, value)
-            elif key == 'x-account-object-count' and not value.isdigit():
-                return InvalidFormat(key, value)
-            elif key == 'x-container-bytes-used' and not value.isdigit():
-                return InvalidFormat(key, value)
-            elif key == 'x-container-object-count' and not value.isdigit():
-                return InvalidFormat(key, value)
-            elif key == 'content-type' and not value:
-                return InvalidFormat(key, value)
             elif key == 'x-copied-from' and not re.match("\S+/\S+", value):
                 return InvalidFormat(key, value)
-            elif key == 'x-copied-from-last-modified' and not value:
-                return InvalidFormat(key, value)
             elif key == 'x-trans-id' and \
                 not re.match("^tx[0-9a-f]{21}-[0-9a-f]{10}.*", value):
                 return InvalidFormat(key, value)
-            elif key == 'date' and not value:
-                return InvalidFormat(key, value)
-            elif key == 'last-modified' and not value:
-                return InvalidFormat(key, value)
             elif key == 'accept-ranges' and not value == 'bytes':
                 return InvalidFormat(key, value)
             elif key == 'etag' and not value.isalnum():
diff --git a/tempest/common/negative_rest_client.py b/tempest/common/negative_rest_client.py
new file mode 100644
index 0000000..a9ae1c3
--- /dev/null
+++ b/tempest/common/negative_rest_client.py
@@ -0,0 +1,72 @@
+# (c) 2014 Deutsche Telekom AG
+# Copyright 2014 Red Hat, Inc.
+# Copyright 2014 NEC Corporation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.common import rest_client
+from tempest import config
+
+CONF = config.CONF
+
+
+class NegativeRestClient(rest_client.RestClient):
+    """
+    Version of RestClient that does not raise exceptions.
+    """
+
+    def __init__(self, auth_provider, service):
+        region = self._get_region(service)
+        super(NegativeRestClient, self).__init__(auth_provider,
+                                                 service, region)
+
+    def _get_region(self, service):
+        """
+        Returns the region for a specific service
+        """
+        service_region = None
+        for cfgname in dir(CONF._config):
+            # Find all config.FOO.catalog_type and assume FOO is a service.
+            cfg = getattr(CONF, cfgname)
+            catalog_type = getattr(cfg, 'catalog_type', None)
+            if catalog_type == service:
+                service_region = getattr(cfg, 'region', None)
+        if not service_region:
+            service_region = CONF.identity.region
+        return service_region
+
+    def _error_checker(self, method, url,
+                       headers, body, resp, resp_body):
+        pass
+
+    def send_request(self, method, url_template, resources, body=None):
+        url = url_template % tuple(resources)
+        if method == "GET":
+            resp, body = self.get(url)
+        elif method == "POST":
+            resp, body = self.post(url, body)
+        elif method == "PUT":
+            resp, body = self.put(url, body)
+        elif method == "PATCH":
+            resp, body = self.patch(url, body)
+        elif method == "HEAD":
+            resp, body = self.head(url)
+        elif method == "DELETE":
+            resp, body = self.delete(url)
+        elif method == "COPY":
+            resp, body = self.copy(url)
+        else:
+            assert False
+
+        return resp, body
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index c54f698..3802c9d 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -78,16 +78,19 @@
 
     LOG = logging.getLogger(__name__)
 
-    def __init__(self, auth_provider):
+    def __init__(self, auth_provider, service, region,
+                 endpoint_type='publicURL',
+                 build_interval=1, build_timeout=60):
         self.auth_provider = auth_provider
+        self.service = service
+        self.region = region
+        self.endpoint_type = endpoint_type
+        self.build_interval = build_interval
+        self.build_timeout = build_timeout
 
-        self.endpoint_url = None
-        self.service = None
         # The version of the API this client implements
         self.api_version = None
         self._skip_path = False
-        self.build_interval = CONF.compute.build_interval
-        self.build_timeout = CONF.compute.build_timeout
         self.general_header_lc = set(('cache-control', 'connection',
                                       'date', 'pragma', 'trailer',
                                       'transfer-encoding', 'via',
@@ -123,38 +126,6 @@
                              str(self.token)[0:STRING_LIMIT],
                              str(self.get_headers())[0:STRING_LIMIT])
 
-    def _get_region(self, service):
-        """
-        Returns the region for a specific service
-        """
-        service_region = None
-        for cfgname in dir(CONF._config):
-            # Find all config.FOO.catalog_type and assume FOO is a service.
-            cfg = getattr(CONF, cfgname)
-            catalog_type = getattr(cfg, 'catalog_type', None)
-            if catalog_type == service:
-                service_region = getattr(cfg, 'region', None)
-        if not service_region:
-            service_region = CONF.identity.region
-        return service_region
-
-    def _get_endpoint_type(self, service):
-        """
-        Returns the endpoint type for a specific service
-        """
-        # If the client requests a specific endpoint type, then be it
-        if self.endpoint_url:
-            return self.endpoint_url
-        endpoint_type = None
-        for cfgname in dir(CONF._config):
-            # Find all config.FOO.catalog_type and assume FOO is a service.
-            cfg = getattr(CONF, cfgname)
-            catalog_type = getattr(cfg, 'catalog_type', None)
-            if catalog_type == service:
-                endpoint_type = getattr(cfg, 'endpoint_type', 'publicURL')
-                break
-        return endpoint_type
-
     @property
     def user(self):
         return self.auth_provider.credentials.username
@@ -187,8 +158,8 @@
     def filters(self):
         _filters = dict(
             service=self.service,
-            endpoint_type=self._get_endpoint_type(self.service),
-            region=self._get_region(self.service)
+            endpoint_type=self.endpoint_type,
+            region=self.region
         )
         if self.api_version is not None:
             _filters['api_version'] = self.api_version
@@ -510,6 +481,11 @@
             else:
                 raise exceptions.RateLimitExceeded(resp_body)
 
+        if resp.status == 415:
+            if parse_resp:
+                resp_body = self._parse_resp(resp_body)
+            raise exceptions.InvalidContentType(resp_body)
+
         if resp.status == 422:
             if parse_resp:
                 resp_body = self._parse_resp(resp_body)
@@ -619,33 +595,3 @@
                 except jsonschema.ValidationError as ex:
                     msg = ("HTTP response header is invalid (%s)") % ex
                     raise exceptions.InvalidHTTPResponseHeader(msg)
-
-
-class NegativeRestClient(RestClient):
-    """
-    Version of RestClient that does not raise exceptions.
-    """
-    def _error_checker(self, method, url,
-                       headers, body, resp, resp_body):
-        pass
-
-    def send_request(self, method, url_template, resources, body=None):
-        url = url_template % tuple(resources)
-        if method == "GET":
-            resp, body = self.get(url)
-        elif method == "POST":
-            resp, body = self.post(url, body)
-        elif method == "PUT":
-            resp, body = self.put(url, body)
-        elif method == "PATCH":
-            resp, body = self.patch(url, body)
-        elif method == "HEAD":
-            resp, body = self.head(url)
-        elif method == "DELETE":
-            resp, body = self.delete(url)
-        elif method == "COPY":
-            resp, body = self.copy(url)
-        else:
-            assert False
-
-        return resp, body
diff --git a/tempest/common/waiters.py b/tempest/common/waiters.py
index 93f02c9..3066667 100644
--- a/tempest/common/waiters.py
+++ b/tempest/common/waiters.py
@@ -28,11 +28,7 @@
     """Waits for a server to reach a given status."""
 
     def _get_task_state(body):
-        if client.service == CONF.compute.catalog_v3_type:
-            task_state = body.get("os-extended-status:task_state", None)
-        else:
-            task_state = body.get('OS-EXT-STS:task_state', None)
-        return task_state
+        return body.get('OS-EXT-STS:task_state', None)
 
     # NOTE(afazekas): UNKNOWN status possible on ERROR
     # or in a very early stage.
diff --git a/tempest/config.py b/tempest/config.py
index cc6d626..1c0dabb 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -185,7 +185,9 @@
                help="Time in seconds between build status checks."),
     cfg.IntOpt('build_timeout',
                default=300,
-               help="Timeout in seconds to wait for an instance to build."),
+               help="Timeout in seconds to wait for an instance to build. "
+                    "Other services that do not define build_timeout will "
+                    "inherit this value."),
     cfg.BoolOpt('run_ssh',
                 default=False,
                 help="Should the tests ssh to instances?"),
@@ -249,9 +251,6 @@
                choices=['public', 'admin', 'internal',
                         'publicURL', 'adminURL', 'internalURL'],
                help="The endpoint type to use for the compute service."),
-    cfg.StrOpt('catalog_v3_type',
-               default='computev3',
-               help="Catalog type of the Compute v3 service."),
     cfg.StrOpt('path_to_private_key',
                help="Path to a private key file for SSH access to remote "
                     "hosts"),
@@ -278,9 +277,6 @@
                                       title="Enabled Compute Service Features")
 
 ComputeFeaturesGroup = [
-    cfg.BoolOpt('api_v3',
-                default=False,
-                help="If false, skip all nova v3 tests."),
     cfg.BoolOpt('disk_config',
                 default=True,
                 help="If false, skip disk config tests"),
@@ -290,12 +286,6 @@
                      'entry all which indicates every extension is enabled. '
                      'Each extension should be specified with alias name. '
                      'Empty list indicates all extensions are disabled'),
-    cfg.ListOpt('api_v3_extensions',
-                default=['all'],
-                help='A list of enabled v3 extensions with a special entry all'
-                     ' which indicates every extension is enabled. '
-                     'Each extension should be specified with alias name. '
-                     'Empty list indicates all extensions are disabled'),
     cfg.BoolOpt('change_password',
                 default=False,
                 help="Does the test environment support changing the admin "
@@ -360,23 +350,6 @@
 ]
 
 
-compute_admin_group = cfg.OptGroup(name='compute-admin',
-                                   title="Compute Admin Options")
-
-ComputeAdminGroup = [
-    cfg.StrOpt('username',
-               help="Administrative Username to use for Nova API requests."),
-    cfg.StrOpt('tenant_name',
-               help="Administrative Tenant name to use for Nova API "
-                    "requests."),
-    cfg.StrOpt('password',
-               help="API key to use when authenticating as admin.",
-               secret=True),
-    cfg.StrOpt('domain_name',
-               help="Domain name for authentication as admin (Keystone V3)."
-                    "The same domain applies to user and project"),
-]
-
 image_group = cfg.OptGroup(name='image',
                            title="Image Service Options")
 
@@ -398,7 +371,15 @@
     cfg.StrOpt('http_image',
                default='http://download.cirros-cloud.net/0.3.1/'
                'cirros-0.3.1-x86_64-uec.tar.gz',
-               help='http accessible image')
+               help='http accessible image'),
+    cfg.IntOpt('build_timeout',
+               default=300,
+               help="Timeout in seconds to wait for an image to "
+                    "become available."),
+    cfg.IntOpt('build_interval',
+               default=1,
+               help="Time in seconds between image operation status "
+                    "checks.")
 ]
 
 image_feature_group = cfg.OptGroup(name='image-feature-enabled',
@@ -467,7 +448,7 @@
                     "checks."),
     cfg.ListOpt('dns_servers',
                 default=["8.8.8.8", "8.8.4.4"],
-                help="List of dns servers whichs hould be used"
+                help="List of dns servers which should be used"
                      " for subnet creation")
 ]
 
@@ -1060,7 +1041,6 @@
     (dashboard_group, DashboardGroup),
     (data_processing_group, DataProcessingGroup),
     (boto_group, BotoGroup),
-    (compute_admin_group, ComputeAdminGroup),
     (stress_group, StressGroup),
     (scenario_group, ScenarioGroup),
     (service_available_group, ServiceAvailableGroup),
@@ -1131,7 +1111,6 @@
         self.dashboard = cfg.CONF.dashboard
         self.data_processing = cfg.CONF.data_processing
         self.boto = cfg.CONF.boto
-        self.compute_admin = cfg.CONF['compute-admin']
         self.stress = cfg.CONF.stress
         self.scenario = cfg.CONF.scenario
         self.service_available = cfg.CONF.service_available
@@ -1140,17 +1119,11 @@
         self.input_scenario = cfg.CONF['input-scenario']
         self.cli = cfg.CONF.cli
         self.negative = cfg.CONF.negative
-        if not self.compute_admin.username:
-            self.compute_admin.username = self.identity.admin_username
-            self.compute_admin.password = self.identity.admin_password
-            self.compute_admin.tenant_name = self.identity.admin_tenant_name
         cfg.CONF.set_default('domain_name', self.identity.admin_domain_name,
                              group='identity')
         cfg.CONF.set_default('alt_domain_name',
                              self.identity.admin_domain_name,
                              group='identity')
-        cfg.CONF.set_default('domain_name', self.identity.admin_domain_name,
-                             group='compute-admin')
 
     def __init__(self, parse_conf=True, config_path=None):
         """Initialize a configuration from a conf directory and conf file."""
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 61a7d2e..b417472 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -14,7 +14,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import logging
 import os
 import subprocess
 
@@ -36,13 +35,6 @@
 
 LOG = log.getLogger(__name__)
 
-# NOTE(afazekas): Workaround for the stdout logging
-LOG_nova_client = logging.getLogger('novaclient.client')
-LOG_nova_client.addHandler(log.NullHandler())
-
-LOG_cinder_client = logging.getLogger('cinderclient.client')
-LOG_cinder_client.addHandler(log.NullHandler())
-
 
 class ScenarioTest(tempest.test.BaseTestCase):
     """Base class for scenario tests. Uses tempest own clients. """
@@ -346,7 +338,7 @@
             'is_public': 'False',
         }
         params.update(properties)
-        _, image = self.image_client.create_image(**params)
+        image = self.image_client.create_image(**params)
         self.addCleanup(self.image_client.delete_image, image['id'])
         self.assertEqual("queued", image['status'])
         self.image_client.update_image(image['id'], data=image_file)
@@ -415,7 +407,7 @@
             thing_id=image_id, thing_id_param='id',
             cleanup_callable=self.delete_wrapper,
             cleanup_args=[_image_client.delete_image, image_id])
-        _, snapshot_image = _image_client.get_image_meta(image_id)
+        snapshot_image = _image_client.get_image_meta(image_id)
         image_name = snapshot_image['name']
         self.assertEqual(name, image_name)
         LOG.debug("Created snapshot image %s for server %s",
@@ -556,7 +548,7 @@
         if not client:
             client = self.network_client
         if not tenant_id:
-            tenant_id = client.rest_client.tenant_id
+            tenant_id = client.tenant_id
         name = data_utils.rand_name(namestart)
         result = client.create_network(name=name, tenant_id=tenant_id)
         network = net_resources.DeletableNetwork(client=client,
@@ -751,9 +743,9 @@
         # The target login is assumed to have been configured for
         # key-based authentication by cloud-init.
         try:
-            for net_name, ip_addresses in server['networks'].iteritems():
+            for net_name, ip_addresses in server['addresses'].iteritems():
                 for ip_address in ip_addresses:
-                    self.check_vm_connectivity(ip_address,
+                    self.check_vm_connectivity(ip_address['addr'],
                                                username,
                                                private_key,
                                                should_connect=should_connect)
@@ -791,7 +783,7 @@
         if client is None:
             client = self.network_client
         if tenant_id is None:
-            tenant_id = client.rest_client.tenant_id
+            tenant_id = client.tenant_id
         secgroup = self._create_empty_security_group(namestart=namestart,
                                                      client=client,
                                                      tenant_id=tenant_id)
@@ -817,7 +809,7 @@
         if client is None:
             client = self.network_client
         if not tenant_id:
-            tenant_id = client.rest_client.tenant_id
+            tenant_id = client.tenant_id
         sg_name = data_utils.rand_name(namestart)
         sg_desc = sg_name + " description"
         sg_dict = dict(name=sg_name,
@@ -842,7 +834,7 @@
         if client is None:
             client = self.network_client
         if not tenant_id:
-            tenant_id = client.rest_client.tenant_id
+            tenant_id = client.tenant_id
         sgs = [
             sg for sg in client.list_security_groups().values()[0]
             if sg['tenant_id'] == tenant_id and sg['name'] == 'default'
@@ -874,7 +866,7 @@
         if client is None:
             client = self.network_client
         if not tenant_id:
-            tenant_id = client.rest_client.tenant_id
+            tenant_id = client.tenant_id
         if secgroup is None:
             secgroup = self._default_security_group(client=client,
                                                     tenant_id=tenant_id)
@@ -986,7 +978,7 @@
         if not client:
             client = self.network_client
         if not tenant_id:
-            tenant_id = client.rest_client.tenant_id
+            tenant_id = client.tenant_id
         router_id = CONF.network.public_router_id
         network_id = CONF.network.public_network_id
         if router_id:
@@ -1005,7 +997,7 @@
         if not client:
             client = self.network_client
         if not tenant_id:
-            tenant_id = client.rest_client.tenant_id
+            tenant_id = client.tenant_id
         name = data_utils.rand_name(namestart)
         result = client.create_router(name=name,
                                       admin_state_up=True,
diff --git a/tempest/services/baremetal/base.py b/tempest/services/baremetal/base.py
index 4933300..c1ebba5 100644
--- a/tempest/services/baremetal/base.py
+++ b/tempest/services/baremetal/base.py
@@ -49,8 +49,11 @@
     """
 
     def __init__(self, auth_provider):
-        super(BaremetalClient, self).__init__(auth_provider)
-        self.service = CONF.baremetal.catalog_type
+        super(BaremetalClient, self).__init__(
+            auth_provider,
+            CONF.baremetal.catalog_type,
+            CONF.identity.region,
+            endpoint_type=CONF.baremetal.endpoint_type)
         self.uri_prefix = ''
 
     def serialize(self, object_type, object_dict):
diff --git a/tempest/services/compute/json/agents_client.py b/tempest/services/compute/json/agents_client.py
index 5b76a56..eacd367 100644
--- a/tempest/services/compute/json/agents_client.py
+++ b/tempest/services/compute/json/agents_client.py
@@ -17,21 +17,14 @@
 
 from tempest.api_schema.response.compute import agents as common_schema
 from tempest.api_schema.response.compute.v2 import agents as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class AgentsClientJSON(rest_client.RestClient):
+class AgentsClientJSON(base.ComputeClient):
     """
     Tests Agents API
     """
 
-    def __init__(self, auth_provider):
-        super(AgentsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
-
     def list_agents(self, params=None):
         """List all agent builds."""
         url = 'os-agents'
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index 09927d3..1539259 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -17,18 +17,11 @@
 
 from tempest.api_schema.response.compute import aggregates as schema
 from tempest.api_schema.response.compute.v2 import aggregates as v2_schema
-from tempest.common import rest_client
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class AggregatesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(AggregatesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class AggregatesClientJSON(base.ComputeClient):
 
     def list_aggregates(self):
         """Get aggregate list."""
diff --git a/tempest/services/compute/json/availability_zone_client.py b/tempest/services/compute/json/availability_zone_client.py
index 00f8330..b8bda68 100644
--- a/tempest/services/compute/json/availability_zone_client.py
+++ b/tempest/services/compute/json/availability_zone_client.py
@@ -16,18 +16,10 @@
 import json
 
 from tempest.api_schema.response.compute.v2 import availability_zone as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class AvailabilityZoneClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(AvailabilityZoneClientJSON, self).__init__(
-            auth_provider)
-        self.service = CONF.compute.catalog_type
+class AvailabilityZoneClientJSON(base.ComputeClient):
 
     def get_availability_zone_list(self):
         resp, body = self.get('os-availability-zone')
diff --git a/tempest/services/compute/json/base.py b/tempest/services/compute/json/base.py
new file mode 100644
index 0000000..cb4915b
--- /dev/null
+++ b/tempest/services/compute/json/base.py
@@ -0,0 +1,39 @@
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.common import rest_client
+from tempest import config
+
+CONF = config.CONF
+
+
+class ComputeClient(rest_client.RestClient):
+    """
+    Base compute client class
+    """
+
+    def __init__(self, auth_provider,
+                 build_interval=None, build_timeout=None):
+        if build_interval is None:
+            build_interval = CONF.compute.build_interval
+        if build_timeout is None:
+            build_timeout = CONF.compute.build_timeout
+
+        super(ComputeClient, self).__init__(
+            auth_provider,
+            CONF.compute.catalog_type,
+            CONF.compute.region or CONF.identity.region,
+            endpoint_type=CONF.compute.endpoint_type,
+            build_interval=build_interval,
+            build_timeout=build_timeout)
diff --git a/tempest/services/compute/json/certificates_client.py b/tempest/services/compute/json/certificates_client.py
index 356ded2..123f0b9 100644
--- a/tempest/services/compute/json/certificates_client.py
+++ b/tempest/services/compute/json/certificates_client.py
@@ -17,17 +17,10 @@
 
 from tempest.api_schema.response.compute import certificates as schema
 from tempest.api_schema.response.compute.v2 import certificates as v2schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class CertificatesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(CertificatesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class CertificatesClientJSON(base.ComputeClient):
 
     def get_certificate(self, id):
         url = "os-certificates/%s" % (id)
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index 41d1c4e..69ad7c0 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -16,17 +16,10 @@
 import json
 
 from tempest.api_schema.response.compute.v2 import extensions as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class ExtensionsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(ExtensionsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class ExtensionsClientJSON(base.ComputeClient):
 
     def list_extensions(self):
         url = 'extensions'
diff --git a/tempest/services/compute/json/fixed_ips_client.py b/tempest/services/compute/json/fixed_ips_client.py
index 5903334..8fd24b6 100644
--- a/tempest/services/compute/json/fixed_ips_client.py
+++ b/tempest/services/compute/json/fixed_ips_client.py
@@ -16,17 +16,10 @@
 import json
 
 from tempest.api_schema.response.compute.v2 import fixed_ips as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class FixedIPsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(FixedIPsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class FixedIPsClientJSON(base.ComputeClient):
 
     def get_fixed_ip_details(self, fixed_ip):
         url = "os-fixed-ips/%s" % (fixed_ip)
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 8faf8a7..6276d3c 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -21,17 +21,10 @@
 from tempest.api_schema.response.compute import flavors_extra_specs \
     as schema_extra_specs
 from tempest.api_schema.response.compute.v2 import flavors as v2schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class FlavorsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(FlavorsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class FlavorsClientJSON(base.ComputeClient):
 
     def list_flavors(self, params=None):
         url = 'flavors'
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 0ed1720..788b4d2 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -17,17 +17,11 @@
 import urllib
 
 from tempest.api_schema.response.compute.v2 import floating_ips as schema
-from tempest.common import rest_client
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class FloatingIPsClientJSON(rest_client.RestClient):
-    def __init__(self, auth_provider):
-        super(FloatingIPsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class FloatingIPsClientJSON(base.ComputeClient):
 
     def list_floating_ips(self, params=None):
         """Returns a list of all floating IPs filtered by any parameters."""
diff --git a/tempest/services/compute/json/hosts_client.py b/tempest/services/compute/json/hosts_client.py
index 8644173..5d306f9 100644
--- a/tempest/services/compute/json/hosts_client.py
+++ b/tempest/services/compute/json/hosts_client.py
@@ -17,17 +17,10 @@
 
 from tempest.api_schema.response.compute import hosts as schema
 from tempest.api_schema.response.compute.v2 import hosts as v2_schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class HostsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(HostsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class HostsClientJSON(base.ComputeClient):
 
     def list_hosts(self, params=None):
         """Lists all hosts."""
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index 8eacf61..52b50c8 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -17,17 +17,10 @@
 
 from tempest.api_schema.response.compute import hypervisors as common_schema
 from tempest.api_schema.response.compute.v2 import hypervisors as v2schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class HypervisorClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(HypervisorClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class HypervisorClientJSON(base.ComputeClient):
 
     def get_hypervisor_list(self):
         """List hypervisors information."""
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index 079a91e..a4cfe57 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -17,21 +17,12 @@
 import urllib
 
 from tempest.api_schema.response.compute.v2 import images as schema
-from tempest.common import rest_client
 from tempest.common import waiters
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class ImagesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(ImagesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
-        self.build_interval = CONF.compute.build_interval
-        self.build_timeout = CONF.compute.build_timeout
+class ImagesClientJSON(base.ComputeClient):
 
     def create_image(self, server_id, name, meta=None):
         """Creates an image of the original server."""
diff --git a/tempest/services/compute/json/instance_usage_audit_log_client.py b/tempest/services/compute/json/instance_usage_audit_log_client.py
index 4b0362b..f79c3de 100644
--- a/tempest/services/compute/json/instance_usage_audit_log_client.py
+++ b/tempest/services/compute/json/instance_usage_audit_log_client.py
@@ -17,18 +17,10 @@
 
 from tempest.api_schema.response.compute.v2 import instance_usage_audit_logs \
     as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class InstanceUsagesAuditLogClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(InstanceUsagesAuditLogClientJSON, self).__init__(
-            auth_provider)
-        self.service = CONF.compute.catalog_type
+class InstanceUsagesAuditLogClientJSON(base.ComputeClient):
 
     def list_instance_usage_audit_logs(self):
         url = 'os-instance_usage_audit_log'
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index 620ed68..f1e2660 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -19,18 +19,11 @@
 from tempest.api_schema.response.compute import interfaces as common_schema
 from tempest.api_schema.response.compute import servers as servers_schema
 from tempest.api_schema.response.compute.v2 import interfaces as schema
-from tempest.common import rest_client
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class InterfacesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(InterfacesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class InterfacesClientJSON(base.ComputeClient):
 
     def list_interfaces(self, server):
         resp, body = self.get('servers/%s/os-interface' % server)
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index 31c42a5..c4406f5 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -17,17 +17,10 @@
 
 from tempest.api_schema.response.compute import keypairs as common_schema
 from tempest.api_schema.response.compute.v2 import keypairs as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class KeyPairsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(KeyPairsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class KeyPairsClientJSON(base.ComputeClient):
 
     def list_keypairs(self):
         resp, body = self.get("os-keypairs")
diff --git a/tempest/services/compute/json/limits_client.py b/tempest/services/compute/json/limits_client.py
index 81c602b..66a0649 100644
--- a/tempest/services/compute/json/limits_client.py
+++ b/tempest/services/compute/json/limits_client.py
@@ -16,17 +16,10 @@
 import json
 
 from tempest.api_schema.response.compute.v2 import limits as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class LimitsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(LimitsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class LimitsClientJSON(base.ComputeClient):
 
     def get_absolute_limits(self):
         resp, body = self.get("limits")
diff --git a/tempest/services/compute/json/migrations_client.py b/tempest/services/compute/json/migrations_client.py
index f4abbb2..de183f1 100644
--- a/tempest/services/compute/json/migrations_client.py
+++ b/tempest/services/compute/json/migrations_client.py
@@ -16,17 +16,10 @@
 import urllib
 
 from tempest.api_schema.response.compute import migrations as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class MigrationsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(MigrationsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class MigrationsClientJSON(base.ComputeClient):
 
     def list_migrations(self, params=None):
         """Lists all migrations."""
diff --git a/tempest/services/compute/json/networks_client.py b/tempest/services/compute/json/networks_client.py
index 40eb1a6..5a2744d 100644
--- a/tempest/services/compute/json/networks_client.py
+++ b/tempest/services/compute/json/networks_client.py
@@ -15,17 +15,10 @@
 
 import json
 
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class NetworksClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(NetworksClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class NetworksClientJSON(base.ComputeClient):
 
     def list_networks(self):
         resp, body = self.get("os-networks")
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index b691529..0fee57a 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -18,17 +18,10 @@
 from tempest.api_schema.response.compute.v2\
     import quota_classes as classes_schema
 from tempest.api_schema.response.compute.v2 import quotas as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class QuotasClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(QuotasClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class QuotasClientJSON(base.ComputeClient):
 
     def get_quota_set(self, tenant_id, user_id=None):
         """List the quota set for a tenant."""
@@ -122,11 +115,7 @@
         return resp, body
 
 
-class QuotaClassesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(QuotaClassesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class QuotaClassesClientJSON(base.ComputeClient):
 
     def get_quota_class_set(self, quota_class_id):
         """List the quota class set for a quota class."""
diff --git a/tempest/services/compute/json/security_group_default_rules_client.py b/tempest/services/compute/json/security_group_default_rules_client.py
index 7743f9c..efaf329 100644
--- a/tempest/services/compute/json/security_group_default_rules_client.py
+++ b/tempest/services/compute/json/security_group_default_rules_client.py
@@ -17,18 +17,10 @@
 
 from tempest.api_schema.response.compute.v2 import \
     security_group_default_rule as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class SecurityGroupDefaultRulesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(SecurityGroupDefaultRulesClientJSON,
-              self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class SecurityGroupDefaultRulesClientJSON(base.ComputeClient):
 
     def create_security_default_group_rule(self, ip_protocol, from_port,
                                            to_port, **kwargs):
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index 733a50b..a301a0f 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -17,18 +17,11 @@
 import urllib
 
 from tempest.api_schema.response.compute.v2 import security_groups as schema
-from tempest.common import rest_client
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class SecurityGroupsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(SecurityGroupsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class SecurityGroupsClientJSON(base.ComputeClient):
 
     def list_security_groups(self, params=None):
         """List all security groups for a user."""
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 4268b1a..400f9a7 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -20,20 +20,15 @@
 
 from tempest.api_schema.response.compute import servers as common_schema
 from tempest.api_schema.response.compute.v2 import servers as schema
-from tempest.common import rest_client
 from tempest.common import waiters
 from tempest import config
 from tempest import exceptions
+from tempest.services.compute.json import base
 
 CONF = config.CONF
 
 
-class ServersClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(ServersClientJSON, self).__init__(auth_provider)
-
-        self.service = CONF.compute.catalog_type
+class ServersClientJSON(base.ComputeClient):
 
     def create_server(self, name, image_ref, flavor_ref, **kwargs):
         """
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
index e56263c..8d73c37 100644
--- a/tempest/services/compute/json/services_client.py
+++ b/tempest/services/compute/json/services_client.py
@@ -18,17 +18,10 @@
 import urllib
 
 from tempest.api_schema.response.compute import services as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class ServicesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(ServicesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class ServicesClientJSON(base.ComputeClient):
 
     def list_services(self, params=None):
         url = 'os-services'
diff --git a/tempest/services/compute/json/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
index a0b9b4a..eac23bb 100644
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ b/tempest/services/compute/json/tenant_usages_client.py
@@ -17,17 +17,10 @@
 import urllib
 
 from tempest.api_schema.response.compute.v2 import tenant_usages as schema
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.compute.json import base
 
 
-class TenantUsagesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(TenantUsagesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.compute.catalog_type
+class TenantUsagesClientJSON(base.ComputeClient):
 
     def list_tenant_usages(self, params=None):
         url = 'os-simple-tenant-usage'
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index afa6937..69b9bea 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -18,21 +18,20 @@
 import urllib
 
 from tempest.api_schema.response.compute.v2 import volumes as schema
-from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
+from tempest.services.compute.json import base
 
 CONF = config.CONF
 
 
-class VolumesExtensionsClientJSON(rest_client.RestClient):
+class VolumesExtensionsClientJSON(base.ComputeClient):
 
     def __init__(self, auth_provider):
         super(VolumesExtensionsClientJSON, self).__init__(
-            auth_provider)
-        self.service = CONF.compute.catalog_type
-        self.build_interval = CONF.volume.build_interval
-        self.build_timeout = CONF.volume.build_timeout
+            auth_provider,
+            build_interval=CONF.volume.build_interval,
+            build_timeout=CONF.volume.build_timeout)
 
     def list_volumes(self, params=None):
         """List all the volumes created."""
diff --git a/tempest/services/data_processing/v1_1/client.py b/tempest/services/data_processing/v1_1/client.py
index 7acbae7..1b6842d 100644
--- a/tempest/services/data_processing/v1_1/client.py
+++ b/tempest/services/data_processing/v1_1/client.py
@@ -21,9 +21,13 @@
 
 
 class DataProcessingClient(rest_client.RestClient):
+
     def __init__(self, auth_provider):
-        super(DataProcessingClient, self).__init__(auth_provider)
-        self.service = CONF.data_processing.catalog_type
+        super(DataProcessingClient, self).__init__(
+            auth_provider,
+            CONF.data_processing.catalog_type,
+            CONF.identity.region,
+            endpoint_type=CONF.data_processing.endpoint_type)
 
     def _request_and_check_resp(self, request_func, uri, resp_status):
         """Make a request using specified request_func and check response
diff --git a/tempest/services/database/json/flavors_client.py b/tempest/services/database/json/flavors_client.py
index f276a45..01be29a 100644
--- a/tempest/services/database/json/flavors_client.py
+++ b/tempest/services/database/json/flavors_client.py
@@ -24,8 +24,10 @@
 class DatabaseFlavorsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(DatabaseFlavorsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.database.catalog_type
+        super(DatabaseFlavorsClientJSON, self).__init__(
+            auth_provider,
+            CONF.database.catalog_type,
+            CONF.identity.region)
 
     def list_db_flavors(self, params=None):
         url = 'flavors'
diff --git a/tempest/services/database/json/versions_client.py b/tempest/services/database/json/versions_client.py
index 81c0e6c..8a408e9 100644
--- a/tempest/services/database/json/versions_client.py
+++ b/tempest/services/database/json/versions_client.py
@@ -24,9 +24,11 @@
 class DatabaseVersionsClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(DatabaseVersionsClientJSON, self).__init__(auth_provider)
+        super(DatabaseVersionsClientJSON, self).__init__(
+            auth_provider,
+            CONF.database.catalog_type,
+            CONF.identity.region)
         self.skip_path()
-        self.service = CONF.database.catalog_type
 
     def list_db_versions(self, params=None):
         """List all versions."""
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index 281464c..5a4ce72 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -22,9 +22,11 @@
 class IdentityClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(IdentityClientJSON, self).__init__(auth_provider)
-        self.service = CONF.identity.catalog_type
-        self.endpoint_url = 'adminURL'
+        super(IdentityClientJSON, self).__init__(
+            auth_provider,
+            CONF.identity.catalog_type,
+            CONF.identity.region,
+            endpoint_type='adminURL')
 
     def has_admin_extensions(self):
         """
diff --git a/tempest/services/identity/v3/json/base.py b/tempest/services/identity/v3/json/base.py
new file mode 100644
index 0000000..30d3886
--- /dev/null
+++ b/tempest/services/identity/v3/json/base.py
@@ -0,0 +1,32 @@
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.common import rest_client
+from tempest import config
+
+CONF = config.CONF
+
+
+class IdentityV3Client(rest_client.RestClient):
+    """
+    Base identity v3 client class
+    """
+
+    def __init__(self, auth_provider):
+        super(IdentityV3Client, self).__init__(
+            auth_provider,
+            CONF.identity.catalog_type,
+            CONF.identity.region,
+            endpoint_type='adminURL')
+        self.api_version = "v3"
diff --git a/tempest/services/identity/v3/json/credentials_client.py b/tempest/services/identity/v3/json/credentials_client.py
index d424f4c..83918f6 100644
--- a/tempest/services/identity/v3/json/credentials_client.py
+++ b/tempest/services/identity/v3/json/credentials_client.py
@@ -16,18 +16,10 @@
 import json
 
 from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.identity.v3.json import base
 
 
-class CredentialsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(CredentialsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.identity.catalog_type
-        self.endpoint_url = 'adminURL'
-        self.api_version = "v3"
+class CredentialsClientJSON(base.IdentityV3Client):
 
     def create_credential(self, access_key, secret_key, user_id, project_id):
         """Creates a credential."""
@@ -44,11 +36,11 @@
         self.expected_success(201, resp.status)
         body = json.loads(body)
         body['credential']['blob'] = json.loads(body['credential']['blob'])
-        return resp, body['credential']
+        return rest_client.ResponseBody(resp, body['credential'])
 
     def update_credential(self, credential_id, **kwargs):
         """Updates a credential."""
-        _, body = self.get_credential(credential_id)
+        body = self.get_credential(credential_id)
         cred_type = kwargs.get('type', body['type'])
         access_key = kwargs.get('access_key', body['blob']['access'])
         secret_key = kwargs.get('secret_key', body['blob']['secret'])
@@ -67,7 +59,7 @@
         self.expected_success(200, resp.status)
         body = json.loads(body)
         body['credential']['blob'] = json.loads(body['credential']['blob'])
-        return resp, body['credential']
+        return rest_client.ResponseBody(resp, body['credential'])
 
     def get_credential(self, credential_id):
         """To GET Details of a credential."""
@@ -75,17 +67,17 @@
         self.expected_success(200, resp.status)
         body = json.loads(body)
         body['credential']['blob'] = json.loads(body['credential']['blob'])
-        return resp, body['credential']
+        return rest_client.ResponseBody(resp, body['credential'])
 
     def list_credentials(self):
         """Lists out all the available credentials."""
         resp, body = self.get('credentials')
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['credentials']
+        return rest_client.ResponseBodyList(resp, body['credentials'])
 
     def delete_credential(self, credential_id):
         """Deletes a credential."""
         resp, body = self.delete('credentials/%s' % credential_id)
         self.expected_success(204, resp.status)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v3/json/endpoints_client.py b/tempest/services/identity/v3/json/endpoints_client.py
index c3fedb2..59bfa8c 100644
--- a/tempest/services/identity/v3/json/endpoints_client.py
+++ b/tempest/services/identity/v3/json/endpoints_client.py
@@ -16,25 +16,17 @@
 import json
 
 from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.identity.v3.json import base
 
 
-class EndPointClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(EndPointClientJSON, self).__init__(auth_provider)
-        self.service = CONF.identity.catalog_type
-        self.endpoint_url = 'adminURL'
-        self.api_version = "v3"
+class EndPointClientJSON(base.IdentityV3Client):
 
     def list_endpoints(self):
         """GET endpoints."""
         resp, body = self.get('endpoints')
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['endpoints']
+        return rest_client.ResponseBodyList(resp, body['endpoints'])
 
     def create_endpoint(self, service_id, interface, url, **kwargs):
         """Create endpoint.
@@ -59,7 +51,7 @@
         resp, body = self.post('endpoints', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
-        return resp, body['endpoint']
+        return rest_client.ResponseBody(resp, body['endpoint'])
 
     def update_endpoint(self, endpoint_id, service_id=None, interface=None,
                         url=None, region=None, enabled=None, **kwargs):
@@ -86,10 +78,10 @@
         resp, body = self.patch('endpoints/%s' % endpoint_id, post_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['endpoint']
+        return rest_client.ResponseBody(resp, body['endpoint'])
 
     def delete_endpoint(self, endpoint_id):
         """Delete endpoint."""
         resp_header, resp_body = self.delete('endpoints/%s' % endpoint_id)
         self.expected_success(204, resp_header.status)
-        return resp_header, resp_body
+        return rest_client.ResponseBody(resp_header, resp_body)
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index 6ac4901..59902bb 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -19,17 +19,12 @@
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
+from tempest.services.identity.v3.json import base
 
 CONF = config.CONF
 
 
-class IdentityV3ClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(IdentityV3ClientJSON, self).__init__(auth_provider)
-        self.service = CONF.identity.catalog_type
-        self.endpoint_url = 'adminURL'
-        self.api_version = "v3"
+class IdentityV3ClientJSON(base.IdentityV3Client):
 
     def create_user(self, user_name, password=None, project_id=None,
                     email=None, domain_id='default', **kwargs):
@@ -51,11 +46,11 @@
         resp, body = self.post('users', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
-        return resp, body['user']
+        return rest_client.ResponseBody(resp, body['user'])
 
     def update_user(self, user_id, name, **kwargs):
         """Updates a user."""
-        _, 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'])
@@ -80,7 +75,7 @@
         resp, body = self.patch('users/%s' % user_id, post_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['user']
+        return rest_client.ResponseBody(resp, body['user'])
 
     def update_user_password(self, user_id, password, original_password):
         """Updates a user password."""
@@ -91,14 +86,14 @@
         update_user = json.dumps({'user': update_user})
         resp, _ = self.post('users/%s/password' % user_id, update_user)
         self.expected_success(204, resp.status)
-        return resp
+        return rest_client.ResponseBody(resp)
 
     def list_user_projects(self, user_id):
         """Lists the projects on which a user has roles assigned."""
         resp, body = self.get('users/%s/projects' % user_id)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['projects']
+        return rest_client.ResponseBodyList(resp, body['projects'])
 
     def get_users(self, params=None):
         """Get the list of users."""
@@ -108,20 +103,20 @@
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['users']
+        return rest_client.ResponseBodyList(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']
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(resp, body)
 
     def create_project(self, name, **kwargs):
         """Creates a project."""
@@ -138,7 +133,7 @@
         resp, body = self.post('projects', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
-        return resp, body['project']
+        return rest_client.ResponseBody(resp, body['project'])
 
     def list_projects(self, params=None):
         url = "projects"
@@ -147,10 +142,10 @@
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['projects']
+        return rest_client.ResponseBodyList(resp, body['projects'])
 
     def update_project(self, project_id, **kwargs):
-        _, 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'])
@@ -166,20 +161,20 @@
         resp, body = self.patch('projects/%s' % project_id, post_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['project']
+        return rest_client.ResponseBody(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']
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(resp, body)
 
     def create_role(self, name):
         """Create a Role."""
@@ -190,21 +185,21 @@
         resp, body = self.post('roles', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
-        return resp, body['role']
+        return rest_client.ResponseBody(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']
+        return rest_client.ResponseBody(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']
+        return rest_client.ResponseBodyList(resp, body['roles'])
 
     def update_role(self, name, role_id):
         """Create a Role."""
@@ -215,20 +210,20 @@
         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']
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(resp, body)
 
     def create_domain(self, name, **kwargs):
         """Creates a domain."""
@@ -243,24 +238,24 @@
         resp, body = self.post('domains', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
-        return resp, body['domain']
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(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']
+        return rest_client.ResponseBodyList(resp, body['domains'])
 
     def update_domain(self, domain_id, **kwargs):
         """Updates a domain."""
-        _, 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'])
@@ -273,14 +268,14 @@
         resp, body = self.patch('domains/%s' % domain_id, post_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['domain']
+        return rest_client.ResponseBody(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']
+        return rest_client.ResponseBody(resp, body['domain'])
 
     def get_token(self, resp_token):
         """Get token details."""
@@ -288,14 +283,14 @@
         resp, body = self.get("auth/tokens", headers=headers)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['token']
+        return rest_client.ResponseBody(resp, body['token'])
 
     def delete_token(self, resp_token):
         """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
+        return rest_client.ResponseBody(resp, body)
 
     def create_group(self, name, **kwargs):
         """Creates a group."""
@@ -312,18 +307,18 @@
         resp, body = self.post('groups', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
-        return resp, body['group']
+        return rest_client.ResponseBody(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']
+        return rest_client.ResponseBody(resp, body['group'])
 
     def update_group(self, group_id, **kwargs):
         """Updates a group."""
-        _, 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 = {
@@ -334,54 +329,54 @@
         resp, body = self.patch('groups/%s' % group_id, post_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['group']
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(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']
+        return rest_client.ResponseBodyList(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']
+        return rest_client.ResponseBodyList(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
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(resp, body)
 
     def list_user_roles_on_project(self, project_id, user_id):
         """list roles of a user on a project."""
@@ -389,7 +384,7 @@
                               (project_id, user_id))
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['roles']
+        return rest_client.ResponseBodyList(resp, body['roles'])
 
     def list_user_roles_on_domain(self, domain_id, user_id):
         """list roles of a user on a domain."""
@@ -397,35 +392,35 @@
                               (domain_id, user_id))
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['roles']
+        return rest_client.ResponseBodyList(resp, body['roles'])
 
     def revoke_role_from_user_on_project(self, project_id, user_id, role_id):
         """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
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(resp, body)
 
     def list_group_roles_on_project(self, project_id, group_id):
         """list roles of a user on a project."""
@@ -433,7 +428,7 @@
                               (project_id, group_id))
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['roles']
+        return rest_client.ResponseBodyList(resp, body['roles'])
 
     def list_group_roles_on_domain(self, domain_id, group_id):
         """list roles of a user on a domain."""
@@ -441,21 +436,21 @@
                               (domain_id, group_id))
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['roles']
+        return rest_client.ResponseBodyList(resp, body['roles'])
 
     def revoke_role_from_group_on_project(self, project_id, group_id, role_id):
         """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
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(resp, body)
 
     def create_trust(self, trustor_user_id, trustee_user_id, project_id,
                      role_names, impersonation, expires_at):
@@ -473,13 +468,13 @@
         resp, body = self.post('OS-TRUST/trusts', post_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
-        return resp, body['trust']
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(resp, body)
 
     def get_trusts(self, trustor_user_id=None, trustee_user_id=None):
         """GET trusts."""
@@ -493,21 +488,21 @@
             resp, body = self.get("OS-TRUST/trusts")
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['trusts']
+        return rest_client.ResponseBodyList(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']
+        return rest_client.ResponseBody(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']
+        return rest_client.ResponseBodyList(resp, body['roles'])
 
     def get_trust_role(self, trust_id, role_id):
         """GET role delegated by a trust."""
@@ -515,20 +510,20 @@
                               % (trust_id, role_id))
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['role']
+        return rest_client.ResponseBody(resp, body['role'])
 
     def check_trust_role(self, trust_id, role_id):
         """HEAD Check if role is delegated by a trust."""
         resp, body = self.head("OS-TRUST/trusts/%s/roles/%s"
                                % (trust_id, role_id))
         self.expected_success(200, resp.status)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
 
 class V3TokenClientJSON(rest_client.RestClient):
 
     def __init__(self):
-        super(V3TokenClientJSON, self).__init__(None)
+        super(V3TokenClientJSON, self).__init__(None, None, None)
         auth_url = CONF.identity.uri_v3
         if not auth_url:
             raise exceptions.InvalidConfiguration('you must specify a v3 uri '
@@ -594,7 +589,7 @@
         body = json.dumps(creds)
         resp, body = self.post(self.auth_url, body=body)
         self.expected_success(201, resp.status)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
     def request(self, method, url, extra_headers=False, headers=None,
                 body=None):
@@ -629,10 +624,10 @@
         :param user: username
         Returns (token id, token data) for supplied credentials
         """
-        resp, body = self.auth(user, password, tenant, user_type='name',
-                               domain=domain)
+        body = self.auth(user, password, tenant, user_type='name',
+                         domain=domain)
 
-        token = resp.get('x-subject-token')
+        token = body.response.get('x-subject-token')
         if auth_data:
             return token, body['token']
         else:
diff --git a/tempest/services/identity/v3/json/policy_client.py b/tempest/services/identity/v3/json/policy_client.py
index 579243c..04374a2 100644
--- a/tempest/services/identity/v3/json/policy_client.py
+++ b/tempest/services/identity/v3/json/policy_client.py
@@ -16,18 +16,10 @@
 import json
 
 from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.identity.v3.json import base
 
 
-class PolicyClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(PolicyClientJSON, self).__init__(auth_provider)
-        self.service = CONF.identity.catalog_type
-        self.endpoint_url = 'adminURL'
-        self.api_version = "v3"
+class PolicyClientJSON(base.IdentityV3Client):
 
     def create_policy(self, blob, type):
         """Creates a Policy."""
diff --git a/tempest/services/identity/v3/json/region_client.py b/tempest/services/identity/v3/json/region_client.py
index becea6b..cab937e 100644
--- a/tempest/services/identity/v3/json/region_client.py
+++ b/tempest/services/identity/v3/json/region_client.py
@@ -17,18 +17,10 @@
 import urllib
 
 from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.identity.v3.json import base
 
 
-class RegionClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(RegionClientJSON, self).__init__(auth_provider)
-        self.service = CONF.identity.catalog_type
-        self.endpoint_url = 'adminURL'
-        self.api_version = "v3"
+class RegionClientJSON(base.IdentityV3Client):
 
     def create_region(self, description, **kwargs):
         """Create region."""
@@ -45,7 +37,7 @@
             resp, body = self.post('regions', req_body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
-        return resp, body['region']
+        return rest_client.ResponseBody(resp, body['region'])
 
     def update_region(self, region_id, **kwargs):
         """Updates a region."""
@@ -58,7 +50,7 @@
         resp, body = self.patch('regions/%s' % region_id, post_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['region']
+        return rest_client.ResponseBody(resp, body['region'])
 
     def get_region(self, region_id):
         """Get region."""
@@ -66,7 +58,7 @@
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['region']
+        return rest_client.ResponseBody(resp, body['region'])
 
     def list_regions(self, params=None):
         """List regions."""
@@ -76,10 +68,10 @@
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['regions']
+        return rest_client.ResponseBodyList(resp, body['regions'])
 
     def delete_region(self, region_id):
         """Delete region."""
         resp, body = self.delete('regions/%s' % region_id)
         self.expected_success(204, resp.status)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v3/json/service_client.py b/tempest/services/identity/v3/json/service_client.py
index 8e89957..c6595f6 100644
--- a/tempest/services/identity/v3/json/service_client.py
+++ b/tempest/services/identity/v3/json/service_client.py
@@ -16,22 +16,14 @@
 import json
 
 from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.identity.v3.json import base
 
 
-class ServiceClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(ServiceClientJSON, self).__init__(auth_provider)
-        self.service = CONF.identity.catalog_type
-        self.endpoint_url = 'adminURL'
-        self.api_version = "v3"
+class ServiceClientJSON(base.IdentityV3Client):
 
     def update_service(self, service_id, **kwargs):
         """Updates a service."""
-        resp, body = self.get_service(service_id)
+        body = self.get_service(service_id)
         name = kwargs.get('name', body['name'])
         type = kwargs.get('type', body['type'])
         desc = kwargs.get('description', body['description'])
@@ -44,7 +36,7 @@
         resp, body = self.patch('services/%s' % service_id, patch_body)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['service']
+        return rest_client.ResponseBody(resp, body['service'])
 
     def get_service(self, service_id):
         """Get Service."""
@@ -52,7 +44,7 @@
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['service']
+        return rest_client.ResponseBody(resp, body['service'])
 
     def create_service(self, serv_type, name=None, description=None,
                        enabled=True):
@@ -66,16 +58,16 @@
         resp, body = self.post("services", body)
         self.expected_success(201, resp.status)
         body = json.loads(body)
-        return resp, body["service"]
+        return rest_client.ResponseBody(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
+        return rest_client.ResponseBody(resp, body)
 
     def list_services(self):
         resp, body = self.get('services')
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['services']
+        return rest_client.ResponseBodyList(resp, body['services'])
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index d60c9d9..0d35ef5 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -35,8 +35,13 @@
 class ImageClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(ImageClientJSON, self).__init__(auth_provider)
-        self.service = CONF.image.catalog_type
+        super(ImageClientJSON, self).__init__(
+            auth_provider,
+            CONF.image.catalog_type,
+            CONF.image.region or CONF.identity.region,
+            endpoint_type=CONF.image.endpoint_type,
+            build_interval=CONF.image.build_interval,
+            build_timeout=CONF.image.build_timeout)
         self._http = None
 
     def _image_meta_from_headers(self, headers):
@@ -117,7 +122,7 @@
         self._error_checker('POST', '/v1/images', headers, data, resp,
                             body_iter)
         body = json.loads(''.join([c for c in body_iter]))
-        return resp, body['image']
+        return rest_client.ResponseBody(resp, body['image'])
 
     def _update_with_data(self, image_id, headers, data):
         url = '/v1/images/%s' % image_id
@@ -126,7 +131,7 @@
         self._error_checker('PUT', url, headers, data,
                             resp, body_iter)
         body = json.loads(''.join([c for c in body_iter]))
-        return resp, body['image']
+        return rest_client.ResponseBody(resp, body['image'])
 
     @property
     def http(self):
@@ -157,7 +162,7 @@
         resp, body = self.post('v1/images', None, headers)
         self.expected_success(201, resp.status)
         body = json.loads(body)
-        return resp, body['image']
+        return rest_client.ResponseBody(resp, body['image'])
 
     def update_image(self, image_id, name=None, container_format=None,
                      data=None, properties=None):
@@ -181,13 +186,13 @@
         resp, body = self.put(url, data, headers)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['image']
+        return rest_client.ResponseBody(resp, body['image'])
 
     def delete_image(self, image_id):
         url = 'v1/images/%s' % image_id
         resp, body = self.delete(url)
         self.expected_success(200, resp.status)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
     def image_list(self, **kwargs):
         url = 'v1/images'
@@ -198,7 +203,7 @@
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['images']
+        return rest_client.ResponseBodyList(resp, body['images'])
 
     def image_list_detail(self, properties=dict(), changes_since=None,
                           **kwargs):
@@ -219,19 +224,20 @@
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body['images']
+        return rest_client.ResponseBodyList(resp, body['images'])
 
     def get_image_meta(self, image_id):
         url = 'v1/images/%s' % image_id
         resp, __ = self.head(url)
         self.expected_success(200, resp.status)
         body = self._image_meta_from_headers(resp)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
     def get_image(self, image_id):
         url = 'v1/images/%s' % image_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
+        # We can't return a ResponseBody because the body is a string
         return resp, body
 
     def is_resource_deleted(self, id):
@@ -251,14 +257,14 @@
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
     def get_shared_images(self, member_id):
         url = 'v1/shared-images/%s' % member_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
     def add_member(self, member_id, image_id, can_share=False):
         url = 'v1/images/%s/members/%s' % (image_id, member_id)
@@ -267,17 +273,17 @@
             body = json.dumps({'member': {'can_share': True}})
         resp, __ = self.put(url, body)
         self.expected_success(204, resp.status)
-        return resp
+        return rest_client.ResponseBody(resp)
 
     def delete_member(self, member_id, image_id):
         url = 'v1/images/%s/members/%s' % (image_id, member_id)
         resp, __ = self.delete(url)
         self.expected_success(204, resp.status)
-        return resp
+        return rest_client.ResponseBody(resp)
 
     # NOTE(afazekas): just for the wait function
     def _get_image_status(self, image_id):
-        resp, meta = self.get_image_meta(image_id)
+        meta = self.get_image_meta(image_id)
         status = meta['status']
         return status
 
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 7421508..852832b 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -29,8 +29,13 @@
 class ImageClientV2JSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(ImageClientV2JSON, self).__init__(auth_provider)
-        self.service = CONF.image.catalog_type
+        super(ImageClientV2JSON, self).__init__(
+            auth_provider,
+            CONF.image.catalog_type,
+            CONF.image.region or CONF.identity.region,
+            endpoint_type=CONF.image.endpoint_type,
+            build_interval=CONF.image.build_interval,
+            build_timeout=CONF.image.build_timeout)
         self._http = None
 
     def _get_http(self):
@@ -42,7 +47,7 @@
 
     def _validate_schema(self, body, type='image'):
         if type in ['image', 'images']:
-            resp, schema = self.get_schema(type)
+            schema = self.get_schema(type)
         else:
             raise ValueError("%s is not a valid schema type" % type)
 
@@ -63,7 +68,7 @@
                                    "-json-patch"}
         resp, body = self.patch('v2/images/%s' % image_id, data, headers)
         self.expected_success(200, resp.status)
-        return resp, self._parse_resp(body)
+        return rest_client.ResponseBody(resp, self._parse_resp(body))
 
     def create_image(self, name, container_format, disk_format, **kwargs):
         params = {
@@ -85,12 +90,13 @@
         resp, body = self.post('v2/images', data)
         self.expected_success(201, resp.status)
         body = json.loads(body)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
     def delete_image(self, image_id):
         url = 'v2/images/%s' % image_id
         resp, _ = self.delete(url)
         self.expected_success(204, resp.status)
+        return rest_client.ResponseBody(resp)
 
     def image_list(self, params=None):
         url = 'v2/images'
@@ -102,14 +108,14 @@
         self.expected_success(200, resp.status)
         body = json.loads(body)
         self._validate_schema(body, type='images')
-        return resp, body['images']
+        return rest_client.ResponseBodyList(resp, body['images'])
 
     def get_image(self, image_id):
         url = 'v2/images/%s' % image_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
     def is_resource_deleted(self, id):
         try:
@@ -129,32 +135,33 @@
         resp, body = self.http.raw_request('PUT', url, headers=headers,
                                            body=data)
         self.expected_success(204, resp.status)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
     def get_image_file(self, image_id):
         url = 'v2/images/%s/file' % image_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
+        # We can't return a ResponseBody because the body is a string
         return resp, body
 
     def add_image_tag(self, image_id, tag):
         url = 'v2/images/%s/tags/%s' % (image_id, tag)
         resp, body = self.put(url, body=None)
         self.expected_success(204, resp.status)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
     def delete_image_tag(self, image_id, tag):
         url = 'v2/images/%s/tags/%s' % (image_id, tag)
         resp, _ = self.delete(url)
         self.expected_success(204, resp.status)
-        return resp
+        return rest_client.ResponseBody(resp)
 
     def get_image_membership(self, image_id):
         url = 'v2/images/%s/members' % image_id
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
     def add_member(self, image_id, member_id):
         url = 'v2/images/%s/members' % image_id
@@ -162,7 +169,7 @@
         resp, body = self.post(url, data)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
     def update_member_status(self, image_id, member_id, status):
         """Valid status are: ``pending``, ``accepted``,  ``rejected``."""
@@ -171,23 +178,23 @@
         resp, body = self.put(url, data)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
 
     def get_member(self, image_id, member_id):
         url = 'v2/images/%s/members/%s' % (image_id, member_id)
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
-        return resp, json.loads(body)
+        return rest_client.ResponseBody(resp, json.loads(body))
 
     def remove_member(self, image_id, member_id):
         url = 'v2/images/%s/members/%s' % (image_id, member_id)
         resp, _ = self.delete(url)
         self.expected_success(204, resp.status)
-        return resp
+        return rest_client.ResponseBody(resp)
 
     def get_schema(self, schema):
         url = 'v2/schemas/%s' % schema
         resp, body = self.get(url)
         self.expected_success(200, resp.status)
         body = json.loads(body)
-        return resp, body
+        return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/messaging/json/messaging_client.py b/tempest/services/messaging/json/messaging_client.py
index 2794ea9..45534c7 100644
--- a/tempest/services/messaging/json/messaging_client.py
+++ b/tempest/services/messaging/json/messaging_client.py
@@ -28,8 +28,10 @@
 class MessagingClientJSON(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(MessagingClientJSON, self).__init__(auth_provider)
-        self.service = CONF.messaging.catalog_type
+        super(MessagingClientJSON, self).__init__(
+            auth_provider,
+            CONF.messaging.catalog_type,
+            CONF.identity.region)
         self.version = '1'
         self.uri_prefix = 'v{0}'.format(self.version)
 
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 0a9a1fa..8f5ed5a 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -11,12 +11,18 @@
 #    under the License.
 
 import json
+import time
+import urllib
 
 from tempest.common import rest_client
-from tempest.services.network import network_client_base
+from tempest.common.utils import misc
+from tempest import config
+from tempest import exceptions
+
+CONF = config.CONF
 
 
-class NetworkClientJSON(network_client_base.NetworkClientBase):
+class NetworkClientJSON(rest_client.RestClient):
 
     """
     Tempest REST client for Neutron. Uses v2 of the Neutron API, since the
@@ -31,8 +37,231 @@
     quotas
     """
 
-    def get_rest_client(self, auth_provider):
-        return rest_client.RestClient(auth_provider)
+    def __init__(self, auth_provider):
+        super(NetworkClientJSON, self).__init__(
+            auth_provider,
+            CONF.network.catalog_type,
+            CONF.network.region or CONF.identity.region,
+            endpoint_type=CONF.network.endpoint_type,
+            build_interval=CONF.network.build_interval,
+            build_timeout=CONF.network.build_timeout)
+        self.version = '2.0'
+        self.uri_prefix = "v%s" % (self.version)
+
+    def get_uri(self, plural_name):
+        # get service prefix from resource name
+
+        # The following list represents resource names that do not require
+        # changing underscore to a hyphen
+        hyphen_exceptions = ["health_monitors", "firewall_rules",
+                             "firewall_policies"]
+        # the following map is used to construct proper URI
+        # for the given neutron resource
+        service_resource_prefix_map = {
+            'networks': '',
+            'subnets': '',
+            'ports': '',
+            'pools': 'lb',
+            'vips': 'lb',
+            'health_monitors': 'lb',
+            'members': 'lb',
+            'ipsecpolicies': 'vpn',
+            'vpnservices': 'vpn',
+            'ikepolicies': 'vpn',
+            'ipsecpolicies': 'vpn',
+            'metering_labels': 'metering',
+            'metering_label_rules': 'metering',
+            'firewall_rules': 'fw',
+            'firewall_policies': 'fw',
+            'firewalls': 'fw'
+        }
+        service_prefix = service_resource_prefix_map.get(
+            plural_name)
+        if plural_name not in hyphen_exceptions:
+            plural_name = plural_name.replace("_", "-")
+        if service_prefix:
+            uri = '%s/%s/%s' % (self.uri_prefix, service_prefix,
+                                plural_name)
+        else:
+            uri = '%s/%s' % (self.uri_prefix, plural_name)
+        return uri
+
+    def pluralize(self, resource_name):
+        # get plural from map or just add 's'
+
+        # map from resource name to a plural name
+        # needed only for those which can't be constructed as name + 's'
+        resource_plural_map = {
+            'security_groups': 'security_groups',
+            'security_group_rules': 'security_group_rules',
+            'ipsecpolicy': 'ipsecpolicies',
+            'ikepolicy': 'ikepolicies',
+            'ipsecpolicy': 'ipsecpolicies',
+            'quotas': 'quotas',
+            'firewall_policy': 'firewall_policies'
+        }
+        return resource_plural_map.get(resource_name, resource_name + 's')
+
+    def _lister(self, plural_name):
+        def _list(**filters):
+            uri = self.get_uri(plural_name)
+            if filters:
+                uri += '?' + urllib.urlencode(filters, doseq=1)
+            resp, body = self.get(uri)
+            result = {plural_name: self.deserialize_list(body)}
+            self.expected_success(200, resp.status)
+            return rest_client.ResponseBody(resp, result)
+
+        return _list
+
+    def _deleter(self, resource_name):
+        def _delete(resource_id):
+            plural = self.pluralize(resource_name)
+            uri = '%s/%s' % (self.get_uri(plural), resource_id)
+            resp, body = self.delete(uri)
+            self.expected_success(204, resp.status)
+            return rest_client.ResponseBody(resp, body)
+
+        return _delete
+
+    def _shower(self, resource_name):
+        def _show(resource_id, **fields):
+            # fields is a dict which key is 'fields' and value is a
+            # list of field's name. An example:
+            # {'fields': ['id', 'name']}
+            plural = self.pluralize(resource_name)
+            uri = '%s/%s' % (self.get_uri(plural), resource_id)
+            if fields:
+                uri += '?' + urllib.urlencode(fields, doseq=1)
+            resp, body = self.get(uri)
+            body = self.deserialize_single(body)
+            self.expected_success(200, resp.status)
+            return rest_client.ResponseBody(resp, body)
+
+        return _show
+
+    def _creater(self, resource_name):
+        def _create(**kwargs):
+            plural = self.pluralize(resource_name)
+            uri = self.get_uri(plural)
+            post_data = self.serialize({resource_name: kwargs})
+            resp, body = self.post(uri, post_data)
+            body = self.deserialize_single(body)
+            self.expected_success(201, resp.status)
+            return rest_client.ResponseBody(resp, body)
+
+        return _create
+
+    def _updater(self, resource_name):
+        def _update(res_id, **kwargs):
+            plural = self.pluralize(resource_name)
+            uri = '%s/%s' % (self.get_uri(plural), res_id)
+            post_data = self.serialize({resource_name: kwargs})
+            resp, body = self.put(uri, post_data)
+            body = self.deserialize_single(body)
+            self.expected_success(200, resp.status)
+            return rest_client.ResponseBody(resp, body)
+
+        return _update
+
+    def __getattr__(self, name):
+        method_prefixes = ["list_", "delete_", "show_", "create_", "update_"]
+        method_functors = [self._lister,
+                           self._deleter,
+                           self._shower,
+                           self._creater,
+                           self._updater]
+        for index, prefix in enumerate(method_prefixes):
+            prefix_len = len(prefix)
+            if name[:prefix_len] == prefix:
+                return method_functors[index](name[prefix_len:])
+        raise AttributeError(name)
+
+    # Common methods that are hard to automate
+    def create_bulk_network(self, names):
+        network_list = [{'name': name} for name in names]
+        post_data = {'networks': network_list}
+        body = self.serialize_list(post_data, "networks", "network")
+        uri = self.get_uri("networks")
+        resp, body = self.post(uri, body)
+        body = {'networks': self.deserialize_list(body)}
+        self.expected_success(201, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_bulk_subnet(self, subnet_list):
+        post_data = {'subnets': subnet_list}
+        body = self.serialize_list(post_data, 'subnets', 'subnet')
+        uri = self.get_uri('subnets')
+        resp, body = self.post(uri, body)
+        body = {'subnets': self.deserialize_list(body)}
+        self.expected_success(201, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def create_bulk_port(self, port_list):
+        post_data = {'ports': port_list}
+        body = self.serialize_list(post_data, 'ports', 'port')
+        uri = self.get_uri('ports')
+        resp, body = self.post(uri, body)
+        body = {'ports': self.deserialize_list(body)}
+        self.expected_success(201, resp.status)
+        return rest_client.ResponseBody(resp, body)
+
+    def wait_for_resource_deletion(self, resource_type, id):
+        """Waits for a resource to be deleted."""
+        start_time = int(time.time())
+        while True:
+            if self.is_resource_deleted(resource_type, id):
+                return
+            if int(time.time()) - start_time >= self.build_timeout:
+                raise exceptions.TimeoutException
+            time.sleep(self.build_interval)
+
+    def is_resource_deleted(self, resource_type, id):
+        method = 'show_' + resource_type
+        try:
+            getattr(self, method)(id)
+        except AttributeError:
+            raise Exception("Unknown resource type %s " % resource_type)
+        except exceptions.NotFound:
+            return True
+        return False
+
+    def wait_for_resource_status(self, fetch, status, interval=None,
+                                 timeout=None):
+        """
+        @summary: Waits for a network resource to reach a status
+        @param fetch: the callable to be used to query the resource status
+        @type fecth: callable that takes no parameters and returns the resource
+        @param status: the status that the resource has to reach
+        @type status: String
+        @param interval: the number of seconds to wait between each status
+          query
+        @type interval: Integer
+        @param timeout: the maximum number of seconds to wait for the resource
+          to reach the desired status
+        @type timeout: Integer
+        """
+        if not interval:
+            interval = self.build_interval
+        if not timeout:
+            timeout = self.build_timeout
+        start_time = time.time()
+
+        while time.time() - start_time <= timeout:
+            resource = fetch()
+            if resource['status'] == status:
+                return
+            time.sleep(interval)
+
+        # At this point, the wait has timed out
+        message = 'Resource %s' % (str(resource))
+        message += ' failed to reach status %s' % status
+        message += ' (current: %s)' % resource['status']
+        message += ' within the required time %s' % timeout
+        caller = misc.find_test_caller()
+        if caller:
+            message = '(%s) %s' % (caller, message)
+        raise exceptions.TimeoutException(message)
 
     def deserialize_single(self, body):
         return json.loads(body)
@@ -59,14 +288,14 @@
         body = json.dumps(put_body)
         uri = '%s/quotas/%s' % (self.uri_prefix, tenant_id)
         resp, body = self.put(uri, body)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body['quota'])
 
     def reset_quotas(self, tenant_id):
         uri = '%s/quotas/%s' % (self.uri_prefix, tenant_id)
         resp, body = self.delete(uri)
-        self.rest_client.expected_success(204, resp.status)
+        self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp, body)
 
     def create_router(self, name, admin_state_up=True, **kwargs):
@@ -76,14 +305,14 @@
         body = json.dumps(post_body)
         uri = '%s/routers' % (self.uri_prefix)
         resp, body = self.post(uri, body)
-        self.rest_client.expected_success(201, resp.status)
+        self.expected_success(201, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     def _update_router(self, router_id, set_enable_snat, **kwargs):
         uri = '%s/routers/%s' % (self.uri_prefix, router_id)
         resp, body = self.get(uri)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         update_body = {}
         update_body['name'] = kwargs.get('name', body['router']['name'])
@@ -103,7 +332,7 @@
         update_body = dict(router=update_body)
         update_body = json.dumps(update_body)
         resp, body = self.put(uri, update_body)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -130,7 +359,7 @@
         update_body = {"subnet_id": subnet_id}
         update_body = json.dumps(update_body)
         resp, body = self.put(uri, update_body)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -140,7 +369,7 @@
         update_body = {"port_id": port_id}
         update_body = json.dumps(update_body)
         resp, body = self.put(uri, update_body)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -150,7 +379,7 @@
         update_body = {"subnet_id": subnet_id}
         update_body = json.dumps(update_body)
         resp, body = self.put(uri, update_body)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -160,7 +389,7 @@
         update_body = {"port_id": port_id}
         update_body = json.dumps(update_body)
         resp, body = self.put(uri, update_body)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -175,7 +404,7 @@
         uri = '%s/lb/pools/%s/health_monitors' % (self.uri_prefix,
                                                   pool_id)
         resp, body = self.post(uri, body)
-        self.rest_client.expected_success(201, resp.status)
+        self.expected_success(201, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -184,13 +413,13 @@
         uri = '%s/lb/pools/%s/health_monitors/%s' % (self.uri_prefix, pool_id,
                                                      health_monitor_id)
         resp, body = self.delete(uri)
-        self.rest_client.expected_success(204, resp.status)
+        self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp, body)
 
     def list_router_interfaces(self, uuid):
         uri = '%s/ports?device_id=%s' % (self.uri_prefix, uuid)
         resp, body = self.get(uri)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -203,14 +432,14 @@
         agent = {"agent": agent_info}
         body = json.dumps(agent)
         resp, body = self.put(uri, body)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     def list_pools_hosted_by_one_lbaas_agent(self, agent_id):
         uri = '%s/agents/%s/loadbalancer-pools' % (self.uri_prefix, agent_id)
         resp, body = self.get(uri)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -218,21 +447,21 @@
         uri = ('%s/lb/pools/%s/loadbalancer-agent' %
                (self.uri_prefix, pool_id))
         resp, body = self.get(uri)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     def list_routers_on_l3_agent(self, agent_id):
         uri = '%s/agents/%s/l3-routers' % (self.uri_prefix, agent_id)
         resp, body = self.get(uri)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     def list_l3_agents_hosting_router(self, router_id):
         uri = '%s/routers/%s/l3-agents' % (self.uri_prefix, router_id)
         resp, body = self.get(uri)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -241,7 +470,7 @@
         post_body = {"router_id": router_id}
         body = json.dumps(post_body)
         resp, body = self.post(uri, body)
-        self.rest_client.expected_success(201, resp.status)
+        self.expected_success(201, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -249,20 +478,20 @@
         uri = '%s/agents/%s/l3-routers/%s' % (
             self.uri_prefix, agent_id, router_id)
         resp, body = self.delete(uri)
-        self.rest_client.expected_success(204, resp.status)
+        self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp, body)
 
     def list_dhcp_agent_hosting_network(self, network_id):
         uri = '%s/networks/%s/dhcp-agents' % (self.uri_prefix, network_id)
         resp, body = self.get(uri)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     def list_networks_hosted_by_one_dhcp_agent(self, agent_id):
         uri = '%s/agents/%s/dhcp-networks' % (self.uri_prefix, agent_id)
         resp, body = self.get(uri)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -270,7 +499,7 @@
         uri = '%s/agents/%s/dhcp-networks/%s' % (self.uri_prefix, agent_id,
                                                  network_id)
         resp, body = self.delete(uri)
-        self.rest_client.expected_success(204, resp.status)
+        self.expected_success(204, resp.status)
         return rest_client.ResponseBody(resp, body)
 
     def create_ikepolicy(self, name, **kwargs):
@@ -284,7 +513,7 @@
         body = json.dumps(post_body)
         uri = '%s/vpn/ikepolicies' % (self.uri_prefix)
         resp, body = self.post(uri, body)
-        self.rest_client.expected_success(201, resp.status)
+        self.expected_success(201, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -298,7 +527,7 @@
         }
         body = json.dumps(put_body)
         resp, body = self.put(uri, body)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -312,14 +541,14 @@
         }
         body = json.dumps(put_body)
         resp, body = self.put(uri, body)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
     def list_lb_pool_stats(self, pool_id):
         uri = '%s/lb/pools/%s/stats' % (self.uri_prefix, pool_id)
         resp, body = self.get(uri)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -328,7 +557,7 @@
         body = json.dumps(post_body)
         uri = '%s/agents/%s/dhcp-networks' % (self.uri_prefix, agent_id)
         resp, body = self.post(uri, body)
-        self.rest_client.expected_success(201, resp.status)
+        self.expected_success(201, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -344,7 +573,7 @@
         }
         body = json.dumps(body)
         resp, body = self.put(uri, body)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
 
@@ -355,6 +584,6 @@
         update_body = {"firewall_rule_id": firewall_rule_id}
         update_body = json.dumps(update_body)
         resp, body = self.put(uri, update_body)
-        self.rest_client.expected_success(200, resp.status)
+        self.expected_success(200, resp.status)
         body = json.loads(body)
         return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/network/network_client_base.py b/tempest/services/network/network_client_base.py
deleted file mode 100644
index 53fd222..0000000
--- a/tempest/services/network/network_client_base.py
+++ /dev/null
@@ -1,268 +0,0 @@
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import time
-import urllib
-
-from tempest.common import rest_client
-from tempest.common.utils import misc
-from tempest import config
-from tempest import exceptions
-
-CONF = config.CONF
-
-# the following map is used to construct proper URI
-# for the given neutron resource
-service_resource_prefix_map = {
-    'networks': '',
-    'subnets': '',
-    'ports': '',
-    'pools': 'lb',
-    'vips': 'lb',
-    'health_monitors': 'lb',
-    'members': 'lb',
-    'ipsecpolicies': 'vpn',
-    'vpnservices': 'vpn',
-    'ikepolicies': 'vpn',
-    'ipsecpolicies': 'vpn',
-    'metering_labels': 'metering',
-    'metering_label_rules': 'metering',
-    'firewall_rules': 'fw',
-    'firewall_policies': 'fw',
-    'firewalls': 'fw'
-}
-
-# The following list represents resource names that do not require
-# changing underscore to a hyphen
-hyphen_exceptions = ["health_monitors", "firewall_rules", "firewall_policies"]
-
-# map from resource name to a plural name
-# needed only for those which can't be constructed as name + 's'
-resource_plural_map = {
-    'security_groups': 'security_groups',
-    'security_group_rules': 'security_group_rules',
-    'ipsecpolicy': 'ipsecpolicies',
-    'ikepolicy': 'ikepolicies',
-    'ipsecpolicy': 'ipsecpolicies',
-    'quotas': 'quotas',
-    'firewall_policy': 'firewall_policies'
-}
-
-
-class NetworkClientBase(object):
-    def __init__(self, auth_provider):
-        self.rest_client = self.get_rest_client(
-            auth_provider)
-        self.rest_client.service = CONF.network.catalog_type
-        self.version = '2.0'
-        self.uri_prefix = "v%s" % (self.version)
-        self.build_timeout = CONF.network.build_timeout
-        self.build_interval = CONF.network.build_interval
-
-    def get_rest_client(self, auth_provider):
-        raise NotImplementedError
-
-    def post(self, uri, body, headers=None):
-        return self.rest_client.post(uri, body, headers)
-
-    def put(self, uri, body, headers=None):
-        return self.rest_client.put(uri, body, headers)
-
-    def get(self, uri, headers=None):
-        return self.rest_client.get(uri, headers)
-
-    def delete(self, uri, headers=None):
-        return self.rest_client.delete(uri, headers)
-
-    def deserialize_list(self, body):
-        raise NotImplementedError
-
-    def deserialize_single(self, body):
-        raise NotImplementedError
-
-    def get_uri(self, plural_name):
-        # get service prefix from resource name
-        service_prefix = service_resource_prefix_map.get(
-            plural_name)
-        if plural_name not in hyphen_exceptions:
-            plural_name = plural_name.replace("_", "-")
-        if service_prefix:
-            uri = '%s/%s/%s' % (self.uri_prefix, service_prefix,
-                                plural_name)
-        else:
-            uri = '%s/%s' % (self.uri_prefix, plural_name)
-        return uri
-
-    def pluralize(self, resource_name):
-        # get plural from map or just add 's'
-        return resource_plural_map.get(resource_name, resource_name + 's')
-
-    def _lister(self, plural_name):
-        def _list(**filters):
-            uri = self.get_uri(plural_name)
-            if filters:
-                uri += '?' + urllib.urlencode(filters, doseq=1)
-            resp, body = self.get(uri)
-            result = {plural_name: self.deserialize_list(body)}
-            self.rest_client.expected_success(200, resp.status)
-            return rest_client.ResponseBody(resp, result)
-
-        return _list
-
-    def _deleter(self, resource_name):
-        def _delete(resource_id):
-            plural = self.pluralize(resource_name)
-            uri = '%s/%s' % (self.get_uri(plural), resource_id)
-            resp, body = self.delete(uri)
-            self.rest_client.expected_success(204, resp.status)
-            return rest_client.ResponseBody(resp, body)
-
-        return _delete
-
-    def _shower(self, resource_name):
-        def _show(resource_id, **fields):
-            # fields is a dict which key is 'fields' and value is a
-            # list of field's name. An example:
-            # {'fields': ['id', 'name']}
-            plural = self.pluralize(resource_name)
-            uri = '%s/%s' % (self.get_uri(plural), resource_id)
-            if fields:
-                uri += '?' + urllib.urlencode(fields, doseq=1)
-            resp, body = self.get(uri)
-            body = self.deserialize_single(body)
-            self.rest_client.expected_success(200, resp.status)
-            return rest_client.ResponseBody(resp, body)
-
-        return _show
-
-    def _creater(self, resource_name):
-        def _create(**kwargs):
-            plural = self.pluralize(resource_name)
-            uri = self.get_uri(plural)
-            post_data = self.serialize({resource_name: kwargs})
-            resp, body = self.post(uri, post_data)
-            body = self.deserialize_single(body)
-            self.rest_client.expected_success(201, resp.status)
-            return rest_client.ResponseBody(resp, body)
-
-        return _create
-
-    def _updater(self, resource_name):
-        def _update(res_id, **kwargs):
-            plural = self.pluralize(resource_name)
-            uri = '%s/%s' % (self.get_uri(plural), res_id)
-            post_data = self.serialize({resource_name: kwargs})
-            resp, body = self.put(uri, post_data)
-            body = self.deserialize_single(body)
-            self.rest_client.expected_success(200, resp.status)
-            return rest_client.ResponseBody(resp, body)
-
-        return _update
-
-    def __getattr__(self, name):
-        method_prefixes = ["list_", "delete_", "show_", "create_", "update_"]
-        method_functors = [self._lister,
-                           self._deleter,
-                           self._shower,
-                           self._creater,
-                           self._updater]
-        for index, prefix in enumerate(method_prefixes):
-            prefix_len = len(prefix)
-            if name[:prefix_len] == prefix:
-                return method_functors[index](name[prefix_len:])
-        raise AttributeError(name)
-
-    # Common methods that are hard to automate
-    def create_bulk_network(self, names):
-        network_list = [{'name': name} for name in names]
-        post_data = {'networks': network_list}
-        body = self.serialize_list(post_data, "networks", "network")
-        uri = self.get_uri("networks")
-        resp, body = self.post(uri, body)
-        body = {'networks': self.deserialize_list(body)}
-        self.rest_client.expected_success(201, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_bulk_subnet(self, subnet_list):
-        post_data = {'subnets': subnet_list}
-        body = self.serialize_list(post_data, 'subnets', 'subnet')
-        uri = self.get_uri('subnets')
-        resp, body = self.post(uri, body)
-        body = {'subnets': self.deserialize_list(body)}
-        self.rest_client.expected_success(201, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def create_bulk_port(self, port_list):
-        post_data = {'ports': port_list}
-        body = self.serialize_list(post_data, 'ports', 'port')
-        uri = self.get_uri('ports')
-        resp, body = self.post(uri, body)
-        body = {'ports': self.deserialize_list(body)}
-        self.rest_client.expected_success(201, resp.status)
-        return rest_client.ResponseBody(resp, body)
-
-    def wait_for_resource_deletion(self, resource_type, id):
-        """Waits for a resource to be deleted."""
-        start_time = int(time.time())
-        while True:
-            if self.is_resource_deleted(resource_type, id):
-                return
-            if int(time.time()) - start_time >= self.build_timeout:
-                raise exceptions.TimeoutException
-            time.sleep(self.build_interval)
-
-    def is_resource_deleted(self, resource_type, id):
-        method = 'show_' + resource_type
-        try:
-            getattr(self, method)(id)
-        except AttributeError:
-            raise Exception("Unknown resource type %s " % resource_type)
-        except exceptions.NotFound:
-            return True
-        return False
-
-    def wait_for_resource_status(self, fetch, status, interval=None,
-                                 timeout=None):
-        """
-        @summary: Waits for a network resource to reach a status
-        @param fetch: the callable to be used to query the resource status
-        @type fecth: callable that takes no parameters and returns the resource
-        @param status: the status that the resource has to reach
-        @type status: String
-        @param interval: the number of seconds to wait between each status
-          query
-        @type interval: Integer
-        @param timeout: the maximum number of seconds to wait for the resource
-          to reach the desired status
-        @type timeout: Integer
-        """
-        if not interval:
-            interval = self.build_interval
-        if not timeout:
-            timeout = self.build_timeout
-        start_time = time.time()
-
-        while time.time() - start_time <= timeout:
-            resource = fetch()
-            if resource['status'] == status:
-                return
-            time.sleep(interval)
-
-        # At this point, the wait has timed out
-        message = 'Resource %s' % (str(resource))
-        message += ' failed to reach status %s' % status
-        message += ' (current: %s)' % resource['status']
-        message += ' within the required time %s' % timeout
-        caller = misc.find_test_caller()
-        if caller:
-            message = '(%s) %s' % (caller, message)
-        raise exceptions.TimeoutException(message)
diff --git a/tempest/services/object_storage/account_client.py b/tempest/services/object_storage/account_client.py
index a2044ef..c24bbba 100644
--- a/tempest/services/object_storage/account_client.py
+++ b/tempest/services/object_storage/account_client.py
@@ -17,18 +17,13 @@
 import urllib
 from xml.etree import ElementTree as etree
 
-from tempest.common import http
-from tempest.common import rest_client
 from tempest import config
-from tempest import exceptions
+from tempest.services.object_storage import base
 
 CONF = config.CONF
 
 
-class AccountClient(rest_client.RestClient):
-    def __init__(self, auth_provider):
-        super(AccountClient, self).__init__(auth_provider)
-        self.service = CONF.object_storage.catalog_type
+class AccountClient(base.ObjectStorageClient):
 
     def create_account(self, data=None,
                        params=None,
@@ -165,82 +160,3 @@
         body = json.loads(body)
         self.expected_success(200, resp.status)
         return resp, body
-
-
-class AccountClientCustomizedHeader(rest_client.RestClient):
-
-    # TODO(andreaf) This class is now redundant, to be removed in next patch
-
-    def __init__(self, auth_provider):
-        super(AccountClientCustomizedHeader, self).__init__(
-            auth_provider)
-        # Overwrites json-specific header encoding in rest_client.RestClient
-        self.service = CONF.object_storage.catalog_type
-        self.format = 'json'
-
-    def request(self, method, url, extra_headers=False, headers=None,
-                body=None):
-        """A simple HTTP request interface."""
-        dscv = CONF.identity.disable_ssl_certificate_validation
-        ca_certs = CONF.identity.ca_certificates_file
-        self.http_obj = http.ClosingHttp(
-            disable_ssl_certificate_validation=dscv,
-            ca_certs=ca_certs)
-        if headers is None:
-            headers = {}
-        elif extra_headers:
-            try:
-                headers.update(self.get_headers())
-            except (ValueError, TypeError):
-                headers = {}
-
-        # Authorize the request
-        req_url, req_headers, req_body = self.auth_provider.auth_request(
-            method=method, url=url, headers=headers, body=body,
-            filters=self.filters
-        )
-        # use original body
-        resp, resp_body = self.http_obj.request(req_url, method,
-                                                headers=req_headers,
-                                                body=req_body)
-        self._log_request(method, req_url, resp)
-
-        if resp.status == 401 or resp.status == 403:
-            raise exceptions.Unauthorized()
-
-        return resp, resp_body
-
-    def list_account_containers(self, params=None, metadata=None):
-        """
-        GET on the (base) storage URL
-        Given a valid X-Auth-Token, returns a list of all containers for the
-        account.
-
-        Optional Arguments:
-        limit=[integer value N]
-            Limits the number of results to at most N values
-            DEFAULT:  10,000
-
-        marker=[string value X]
-            Given string value X, return object names greater in value
-            than the specified marker.
-            DEFAULT: No Marker
-
-        format=[string value, either 'json' or 'xml']
-            Specify either json or xml to return the respective serialized
-            response.
-            DEFAULT:  Python-List returned in response body
-        """
-
-        url = '?format=%s' % self.format
-        if params:
-            url += '&%s' % urllib.urlencode(params)
-
-        headers = {}
-        if metadata:
-            for key in metadata:
-                headers[str(key)] = metadata[key]
-
-        resp, body = self.get(url, headers=headers)
-        self.expected_success(200, resp.status)
-        return resp, body
diff --git a/tempest/services/object_storage/base.py b/tempest/services/object_storage/base.py
new file mode 100644
index 0000000..655596f
--- /dev/null
+++ b/tempest/services/object_storage/base.py
@@ -0,0 +1,32 @@
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.common import rest_client
+from tempest import config
+
+CONF = config.CONF
+
+
+class ObjectStorageClient(rest_client.RestClient):
+    """
+    Base object storage client class
+    """
+
+    def __init__(self, auth_provider):
+        super(ObjectStorageClient, self).__init__(
+            auth_provider,
+            CONF.object_storage.catalog_type,
+            CONF.object_storage.region or CONF.identity.region,
+            endpoint_type=CONF.object_storage.endpoint_type)
+        self.format = 'json'
diff --git a/tempest/services/object_storage/container_client.py b/tempest/services/object_storage/container_client.py
index 182c4d0..c55826b 100644
--- a/tempest/services/object_storage/container_client.py
+++ b/tempest/services/object_storage/container_client.py
@@ -17,20 +17,10 @@
 import urllib
 from xml.etree import ElementTree as etree
 
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.object_storage import base
 
 
-class ContainerClient(rest_client.RestClient):
-    def __init__(self, auth_provider):
-        super(ContainerClient, self).__init__(auth_provider)
-
-        # Overwrites json-specific header encoding in rest_client.RestClient
-        self.headers = {}
-        self.service = CONF.object_storage.catalog_type
-        self.format = 'json'
+class ContainerClient(base.ObjectStorageClient):
 
     def create_container(
             self, container_name,
diff --git a/tempest/services/object_storage/object_client.py b/tempest/services/object_storage/object_client.py
index 7a69fa8..bb74fd7 100644
--- a/tempest/services/object_storage/object_client.py
+++ b/tempest/services/object_storage/object_client.py
@@ -17,25 +17,20 @@
 import urllib
 import urlparse
 
-from tempest.common import http
-from tempest.common import rest_client
 from tempest import config
-from tempest import exceptions
+from tempest.services.object_storage import base
 
 CONF = config.CONF
 
 
-class ObjectClient(rest_client.RestClient):
-    def __init__(self, auth_provider):
-        super(ObjectClient, self).__init__(auth_provider)
-
-        self.service = CONF.object_storage.catalog_type
+class ObjectClient(base.ObjectStorageClient):
 
     def create_object(self, container, object_name, data,
-                      params=None, metadata=None):
+                      params=None, metadata=None, headers=None):
         """Create storage object."""
 
-        headers = self.get_headers()
+        if headers is None:
+            headers = self.get_headers()
         if not data:
             headers['content-length'] = '0'
         if metadata:
@@ -181,89 +176,6 @@
         self.expected_success(201, resp.status)
         return resp.status, resp.reason, resp_headers
 
-
-class ObjectClientCustomizedHeader(rest_client.RestClient):
-
-    # TODO(andreaf) This class is now redundant, to be removed in next patch
-
-    def __init__(self, auth_provider):
-        super(ObjectClientCustomizedHeader, self).__init__(
-            auth_provider)
-        # Overwrites json-specific header encoding in rest_client.RestClient
-        self.service = CONF.object_storage.catalog_type
-        self.format = 'json'
-
-    def request(self, method, url, extra_headers=False, headers=None,
-                body=None):
-        """A simple HTTP request interface."""
-        dscv = CONF.identity.disable_ssl_certificate_validation
-        ca_certs = CONF.identity.ca_certificates_file
-        self.http_obj = http.ClosingHttp(
-            disable_ssl_certificate_validation=dscv,
-            ca_certs=ca_certs)
-        if headers is None:
-            headers = {}
-        elif extra_headers:
-            try:
-                headers.update(self.get_headers())
-            except (ValueError, TypeError):
-                headers = {}
-
-        # Authorize the request
-        req_url, req_headers, req_body = self.auth_provider.auth_request(
-            method=method, url=url, headers=headers, body=body,
-            filters=self.filters
-        )
-        # Use original method
-        resp, resp_body = self.http_obj.request(req_url, method,
-                                                headers=req_headers,
-                                                body=req_body)
-        self._log_request(method, req_url, resp)
-        if resp.status == 401 or resp.status == 403:
-            raise exceptions.Unauthorized()
-
-        return resp, resp_body
-
-    def get_object(self, container, object_name, metadata=None):
-        """Retrieve object's data."""
-        headers = {}
-        if metadata:
-            for key in metadata:
-                headers[str(key)] = metadata[key]
-
-        url = "{0}/{1}".format(container, object_name)
-        resp, body = self.get(url, headers=headers)
-        self.expected_success(200, resp.status)
-        return resp, body
-
-    def create_object(self, container, object_name, data, metadata=None):
-        """Create storage object."""
-
-        headers = {}
-        if metadata:
-            for key in metadata:
-                headers[str(key)] = metadata[key]
-
-        if not data:
-            headers['content-length'] = '0'
-        url = "%s/%s" % (str(container), str(object_name))
-        resp, body = self.put(url, data, headers=headers)
-        self.expected_success(201, resp.status)
-        return resp, body
-
-    def delete_object(self, container, object_name, metadata=None):
-        """Delete storage object."""
-
-        headers = {}
-        if metadata:
-            for key in metadata:
-                headers[str(key)] = metadata[key]
-
-        url = "%s/%s" % (str(container), str(object_name))
-        resp, body = self.delete(url, headers=headers)
-        self.expected_success(200, resp.status)
-        return resp, body
-
     def create_object_continue(self, container, object_name,
                                data, metadata=None):
         """Create storage object."""
diff --git a/tempest/services/orchestration/json/orchestration_client.py b/tempest/services/orchestration/json/orchestration_client.py
index 9b4700a..054f410 100644
--- a/tempest/services/orchestration/json/orchestration_client.py
+++ b/tempest/services/orchestration/json/orchestration_client.py
@@ -28,10 +28,13 @@
 class OrchestrationClient(rest_client.RestClient):
 
     def __init__(self, auth_provider):
-        super(OrchestrationClient, self).__init__(auth_provider)
-        self.service = CONF.orchestration.catalog_type
-        self.build_interval = CONF.orchestration.build_interval
-        self.build_timeout = CONF.orchestration.build_timeout
+        super(OrchestrationClient, self).__init__(
+            auth_provider,
+            CONF.orchestration.catalog_type,
+            CONF.orchestration.region or CONF.identity.region,
+            endpoint_type=CONF.orchestration.endpoint_type,
+            build_interval=CONF.orchestration.build_interval,
+            build_timeout=CONF.orchestration.build_timeout)
 
     def list_stacks(self, params=None):
         """Lists all stacks for a user."""
diff --git a/tempest/services/telemetry/json/telemetry_client.py b/tempest/services/telemetry/json/telemetry_client.py
index 996aceb..2b5dc1a 100644
--- a/tempest/services/telemetry/json/telemetry_client.py
+++ b/tempest/services/telemetry/json/telemetry_client.py
@@ -13,15 +13,25 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import urllib
+
 from tempest.common import rest_client
+from tempest import config
 from tempest.openstack.common import jsonutils as json
-import tempest.services.telemetry.telemetry_client_base as client
+
+CONF = config.CONF
 
 
-class TelemetryClientJSON(client.TelemetryClientBase):
+class TelemetryClientJSON(rest_client.RestClient):
 
-    def get_rest_client(self, auth_provider):
-        return rest_client.RestClient(auth_provider)
+    def __init__(self, auth_provider):
+        super(TelemetryClientJSON, self).__init__(
+            auth_provider,
+            CONF.telemetry.catalog_type,
+            CONF.identity.region,
+            endpoint_type=CONF.telemetry.endpoint_type)
+        self.version = '2'
+        self.uri_prefix = "v%s" % self.version
 
     def deserialize(self, body):
         return json.loads(body.replace("\n", ""))
@@ -42,4 +52,87 @@
 
     def create_sample(self, meter_name, sample_list):
         uri = "%s/meters/%s" % (self.uri_prefix, meter_name)
-        return self.post(uri, str(sample_list))
+        body = self.serialize(sample_list)
+        resp, body = self.post(uri, body)
+        body = self.deserialize(body)
+        return resp, body
+
+    def helper_list(self, uri, query=None, period=None):
+        uri_dict = {}
+        if query:
+            uri_dict = {'q.field': query[0],
+                        'q.op': query[1],
+                        'q.value': query[2]}
+        if period:
+            uri_dict['period'] = period
+        if uri_dict:
+            uri += "?%s" % urllib.urlencode(uri_dict)
+        resp, body = self.get(uri)
+        body = self.deserialize(body)
+        return resp, body
+
+    def list_resources(self, query=None):
+        uri = '%s/resources' % self.uri_prefix
+        return self.helper_list(uri, query)
+
+    def list_meters(self, query=None):
+        uri = '%s/meters' % self.uri_prefix
+        return self.helper_list(uri, query)
+
+    def list_alarms(self, query=None):
+        uri = '%s/alarms' % self.uri_prefix
+        return self.helper_list(uri, query)
+
+    def list_statistics(self, meter, period=None, query=None):
+        uri = "%s/meters/%s/statistics" % (self.uri_prefix, meter)
+        return self.helper_list(uri, query, period)
+
+    def list_samples(self, meter_id, query=None):
+        uri = '%s/meters/%s' % (self.uri_prefix, meter_id)
+        return self.helper_list(uri, query)
+
+    def get_resource(self, resource_id):
+        uri = '%s/resources/%s' % (self.uri_prefix, resource_id)
+        resp, body = self.get(uri)
+        body = self.deserialize(body)
+        return resp, body
+
+    def get_alarm(self, alarm_id):
+        uri = '%s/alarms/%s' % (self.uri_prefix, alarm_id)
+        resp, body = self.get(uri)
+        body = self.deserialize(body)
+        return resp, body
+
+    def delete_alarm(self, alarm_id):
+        uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id)
+        resp, body = self.delete(uri)
+        if body:
+            body = self.deserialize(body)
+        return resp, body
+
+    def create_alarm(self, **kwargs):
+        uri = "%s/alarms" % self.uri_prefix
+        body = self.serialize(kwargs)
+        resp, body = self.post(uri, body)
+        body = self.deserialize(body)
+        return resp, body
+
+    def update_alarm(self, alarm_id, **kwargs):
+        uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id)
+        body = self.serialize(kwargs)
+        resp, body = self.put(uri, body)
+        body = self.deserialize(body)
+        return resp, body
+
+    def alarm_get_state(self, alarm_id):
+        uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
+        resp, body = self.get(uri)
+        body = self.deserialize(body)
+        return resp, body
+
+    def alarm_set_state(self, alarm_id, state):
+        uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
+        body = self.serialize(state)
+        resp, body = self.put(uri, body)
+        body = self.deserialize(body)
+        return resp, body
diff --git a/tempest/services/telemetry/telemetry_client_base.py b/tempest/services/telemetry/telemetry_client_base.py
deleted file mode 100644
index a184a77..0000000
--- a/tempest/services/telemetry/telemetry_client_base.py
+++ /dev/null
@@ -1,151 +0,0 @@
-# Copyright 2013 OpenStack Foundation
-# All Rights Reserved.
-#
-#    Licensed under the Apache License, Version 2.0 (the "License"); you may
-#    not use this file except in compliance with the License. You may obtain
-#    a copy of the License at
-#
-#         http://www.apache.org/licenses/LICENSE-2.0
-#
-#    Unless required by applicable law or agreed to in writing, software
-#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-#    License for the specific language governing permissions and limitations
-#    under the License.
-
-import abc
-import urllib
-
-import six
-
-from tempest import config
-
-CONF = config.CONF
-
-
-@six.add_metaclass(abc.ABCMeta)
-class TelemetryClientBase(object):
-
-    """
-    Tempest REST client for Ceilometer V2 API.
-    Implements the following basic Ceilometer abstractions:
-    resources
-    meters
-    alarms
-    queries
-    statistics
-    """
-
-    def __init__(self, auth_provider):
-        self.rest_client = self.get_rest_client(auth_provider)
-        self.rest_client.service = CONF.telemetry.catalog_type
-        self.version = '2'
-        self.uri_prefix = "v%s" % self.version
-
-    @abc.abstractmethod
-    def get_rest_client(self, auth_provider):
-        """
-        :param config:
-        :param username:
-        :param password:
-        :param auth_url:
-        :param tenant_name:
-        :return: RestClient
-        """
-
-    @abc.abstractmethod
-    def deserialize(self, body):
-        """
-        :param body:
-        :return: Deserialize body
-        """
-
-    @abc.abstractmethod
-    def serialize(self, body):
-        """
-        :param body:
-        :return: Serialize body
-        """
-
-    def post(self, uri, body):
-        body = self.serialize(body)
-        resp, body = self.rest_client.post(uri, body)
-        body = self.deserialize(body)
-        return resp, body
-
-    def put(self, uri, body):
-        body = self.serialize(body)
-        resp, body = self.rest_client.put(uri, body)
-        body = self.deserialize(body)
-        return resp, body
-
-    def get(self, uri):
-        resp, body = self.rest_client.get(uri)
-        body = self.deserialize(body)
-        return resp, body
-
-    def delete(self, uri):
-        resp, body = self.rest_client.delete(uri)
-        if body:
-            body = self.deserialize(body)
-        return resp, body
-
-    def helper_list(self, uri, query=None, period=None):
-        uri_dict = {}
-        if query:
-            uri_dict = {'q.field': query[0],
-                        'q.op': query[1],
-                        'q.value': query[2]}
-        if period:
-            uri_dict['period'] = period
-        if uri_dict:
-            uri += "?%s" % urllib.urlencode(uri_dict)
-        return self.get(uri)
-
-    def list_resources(self, query=None):
-        uri = '%s/resources' % self.uri_prefix
-        return self.helper_list(uri, query)
-
-    def list_meters(self, query=None):
-        uri = '%s/meters' % self.uri_prefix
-        return self.helper_list(uri, query)
-
-    def list_alarms(self, query=None):
-        uri = '%s/alarms' % self.uri_prefix
-        return self.helper_list(uri, query)
-
-    def list_statistics(self, meter, period=None, query=None):
-        uri = "%s/meters/%s/statistics" % (self.uri_prefix, meter)
-        return self.helper_list(uri, query, period)
-
-    def list_samples(self, meter_id, query=None):
-        uri = '%s/meters/%s' % (self.uri_prefix, meter_id)
-        return self.helper_list(uri, query)
-
-    def get_resource(self, resource_id):
-        uri = '%s/resources/%s' % (self.uri_prefix, resource_id)
-        return self.get(uri)
-
-    def get_alarm(self, alarm_id):
-        uri = '%s/alarms/%s' % (self.uri_prefix, alarm_id)
-        return self.get(uri)
-
-    def delete_alarm(self, alarm_id):
-        uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id)
-        return self.delete(uri)
-
-    def create_alarm(self, **kwargs):
-        uri = "%s/alarms" % self.uri_prefix
-        return self.post(uri, kwargs)
-
-    def update_alarm(self, alarm_id, **kwargs):
-        uri = "%s/alarms/%s" % (self.uri_prefix, alarm_id)
-        return self.put(uri, kwargs)
-
-    def alarm_get_state(self, alarm_id):
-        uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
-        return self.get(uri)
-
-    def alarm_set_state(self, alarm_id, state):
-        uri = "%s/alarms/%s/state" % (self.uri_prefix, alarm_id)
-        return self.put(uri, state)
diff --git a/tempest/services/volume/json/admin/volume_hosts_client.py b/tempest/services/volume/json/admin/volume_hosts_client.py
index 10cb0be..e7add30 100644
--- a/tempest/services/volume/json/admin/volume_hosts_client.py
+++ b/tempest/services/volume/json/admin/volume_hosts_client.py
@@ -16,24 +16,14 @@
 import json
 import urllib
 
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.volume.json import base
 
 
-class BaseVolumeHostsClientJSON(rest_client.RestClient):
+class BaseVolumeHostsClientJSON(base.VolumeClient):
     """
     Client class to send CRUD Volume Hosts API requests to a Cinder endpoint
     """
 
-    def __init__(self, auth_provider):
-        super(BaseVolumeHostsClientJSON, self).__init__(auth_provider)
-
-        self.service = CONF.volume.catalog_type
-        self.build_interval = CONF.volume.build_interval
-        self.build_timeout = CONF.volume.build_timeout
-
     def list_hosts(self, params=None):
         """Lists all hosts."""
 
diff --git a/tempest/services/volume/json/admin/volume_quotas_client.py b/tempest/services/volume/json/admin/volume_quotas_client.py
index 5b49040..f08cb64 100644
--- a/tempest/services/volume/json/admin/volume_quotas_client.py
+++ b/tempest/services/volume/json/admin/volume_quotas_client.py
@@ -16,27 +16,17 @@
 
 import urllib
 
-from tempest.common import rest_client
-from tempest import config
 from tempest.openstack.common import jsonutils
-
-CONF = config.CONF
+from tempest.services.volume.json import base
 
 
-class BaseVolumeQuotasClientJSON(rest_client.RestClient):
+class BaseVolumeQuotasClientJSON(base.VolumeClient):
     """
     Client class to send CRUD Volume Quotas API requests to a Cinder endpoint
     """
 
     TYPE = "json"
 
-    def __init__(self, auth_provider):
-        super(BaseVolumeQuotasClientJSON, self).__init__(auth_provider)
-
-        self.service = CONF.volume.catalog_type
-        self.build_interval = CONF.volume.build_interval
-        self.build_timeout = CONF.volume.build_timeout
-
     def get_default_quota_set(self, tenant_id):
         """List the default volume quota set for a tenant."""
 
diff --git a/tempest/services/volume/json/admin/volume_services_client.py b/tempest/services/volume/json/admin/volume_services_client.py
index 88c6db0..5d4f9db 100644
--- a/tempest/services/volume/json/admin/volume_services_client.py
+++ b/tempest/services/volume/json/admin/volume_services_client.py
@@ -16,17 +16,10 @@
 import json
 import urllib
 
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.volume.json import base
 
 
-class BaseVolumesServicesClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(BaseVolumesServicesClientJSON, self).__init__(auth_provider)
-        self.service = CONF.volume.catalog_type
+class BaseVolumesServicesClientJSON(base.VolumeClient):
 
     def list_services(self, params=None):
         url = 'os-services'
diff --git a/tempest/services/volume/json/admin/volume_types_client.py b/tempest/services/volume/json/admin/volume_types_client.py
index eedf880..171ad35 100644
--- a/tempest/services/volume/json/admin/volume_types_client.py
+++ b/tempest/services/volume/json/admin/volume_types_client.py
@@ -16,25 +16,15 @@
 import json
 import urllib
 
-from tempest.common import rest_client
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.volume.json import base
 
 
-class BaseVolumeTypesClientJSON(rest_client.RestClient):
+class BaseVolumeTypesClientJSON(base.VolumeClient):
     """
     Client class to send CRUD Volume Types API requests to a Cinder endpoint
     """
 
-    def __init__(self, auth_provider):
-        super(BaseVolumeTypesClientJSON, self).__init__(auth_provider)
-
-        self.service = CONF.volume.catalog_type
-        self.build_interval = CONF.volume.build_interval
-        self.build_timeout = CONF.volume.build_timeout
-
     def is_resource_deleted(self, resource):
         # to use this method self.resource must be defined to respective value
         # Resource is a dictionary containing resource id and type
diff --git a/tempest/services/volume/json/availability_zone_client.py b/tempest/services/volume/json/availability_zone_client.py
index 5ad2287..9f2c570 100644
--- a/tempest/services/volume/json/availability_zone_client.py
+++ b/tempest/services/volume/json/availability_zone_client.py
@@ -15,18 +15,10 @@
 
 import json
 
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.volume.json import base
 
 
-class BaseVolumeAvailabilityZoneClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(BaseVolumeAvailabilityZoneClientJSON, self).__init__(
-            auth_provider)
-        self.service = CONF.volume.catalog_type
+class BaseVolumeAvailabilityZoneClientJSON(base.VolumeClient):
 
     def get_availability_zone_list(self):
         resp, body = self.get('os-availability-zone')
diff --git a/tempest/services/volume/json/backups_client.py b/tempest/services/volume/json/backups_client.py
index 51a017e..e2ba822 100644
--- a/tempest/services/volume/json/backups_client.py
+++ b/tempest/services/volume/json/backups_client.py
@@ -16,24 +16,15 @@
 import json
 import time
 
-from tempest.common import rest_client
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.volume.json import base
 
 
-class BaseBackupsClientJSON(rest_client.RestClient):
+class BaseBackupsClientJSON(base.VolumeClient):
     """
     Client class to send CRUD Volume backup API requests to a Cinder endpoint
     """
 
-    def __init__(self, auth_provider):
-        super(BaseBackupsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.volume.catalog_type
-        self.build_interval = CONF.volume.build_interval
-        self.build_timeout = CONF.volume.build_timeout
-
     def create_backup(self, volume_id, container=None, name=None,
                       description=None):
         """Creates a backup of volume."""
diff --git a/tempest/services/volume/json/base.py b/tempest/services/volume/json/base.py
new file mode 100644
index 0000000..ef316f2
--- /dev/null
+++ b/tempest/services/volume/json/base.py
@@ -0,0 +1,33 @@
+# Copyright 2014 NEC Corporation.  All rights reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.common import rest_client
+from tempest import config
+
+CONF = config.CONF
+
+
+class VolumeClient(rest_client.RestClient):
+    """
+    Base volume client class
+    """
+
+    def __init__(self, auth_provider):
+        super(VolumeClient, self).__init__(
+            auth_provider,
+            CONF.volume.catalog_type,
+            CONF.volume.region or CONF.identity.region,
+            endpoint_type=CONF.volume.endpoint_type,
+            build_interval=CONF.volume.build_interval,
+            build_timeout=CONF.volume.build_timeout)
diff --git a/tempest/services/volume/json/extensions_client.py b/tempest/services/volume/json/extensions_client.py
index c84b186..13b91c3 100644
--- a/tempest/services/volume/json/extensions_client.py
+++ b/tempest/services/volume/json/extensions_client.py
@@ -15,17 +15,10 @@
 
 import json
 
-from tempest.common import rest_client
-from tempest import config
-
-CONF = config.CONF
+from tempest.services.volume.json import base
 
 
-class BaseExtensionsClientJSON(rest_client.RestClient):
-
-    def __init__(self, auth_provider):
-        super(BaseExtensionsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.volume.catalog_type
+class BaseExtensionsClientJSON(base.VolumeClient):
 
     def list_extensions(self):
         url = 'extensions'
diff --git a/tempest/services/volume/json/qos_client.py b/tempest/services/volume/json/qos_client.py
index b647bc7..9c13cac 100644
--- a/tempest/services/volume/json/qos_client.py
+++ b/tempest/services/volume/json/qos_client.py
@@ -15,22 +15,13 @@
 import json
 import time
 
-from tempest.common import rest_client
-from tempest import config
 from tempest import exceptions
-
-CONF = config.CONF
+from tempest.services.volume.json import base
 
 
-class BaseQosSpecsClientJSON(rest_client.RestClient):
+class BaseQosSpecsClientJSON(base.VolumeClient):
     """Client class to send CRUD QoS API requests"""
 
-    def __init__(self, auth_provider):
-        super(BaseQosSpecsClientJSON, self).__init__(auth_provider)
-        self.service = CONF.volume.catalog_type
-        self.build_interval = CONF.volume.build_interval
-        self.build_timeout = CONF.volume.build_timeout
-
     def is_resource_deleted(self, qos_id):
         try:
             self.get_qos(qos_id)
diff --git a/tempest/services/volume/json/snapshots_client.py b/tempest/services/volume/json/snapshots_client.py
index e9d5b83..349d1b0 100644
--- a/tempest/services/volume/json/snapshots_client.py
+++ b/tempest/services/volume/json/snapshots_client.py
@@ -14,26 +14,18 @@
 import time
 import urllib
 
-from tempest.common import rest_client
-from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
+from tempest.services.volume.json import base
 
-CONF = config.CONF
 
 LOG = logging.getLogger(__name__)
 
 
-class BaseSnapshotsClientJSON(rest_client.RestClient):
+class BaseSnapshotsClientJSON(base.VolumeClient):
     """Base Client class to send CRUD Volume API requests."""
 
-    def __init__(self, auth_provider):
-        super(BaseSnapshotsClientJSON, self).__init__(auth_provider)
-
-        self.service = CONF.volume.catalog_type
-        self.build_interval = CONF.volume.build_interval
-        self.build_timeout = CONF.volume.build_timeout
-        self.create_resp = 200
+    create_resp = 200
 
     def list_snapshots(self, params=None):
         """List all the snapshot."""
diff --git a/tempest/services/volume/json/volumes_client.py b/tempest/services/volume/json/volumes_client.py
index 1e49e5a..f19718e 100644
--- a/tempest/services/volume/json/volumes_client.py
+++ b/tempest/services/volume/json/volumes_client.py
@@ -17,25 +17,19 @@
 import time
 import urllib
 
-from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
+from tempest.services.volume.json import base
 
 CONF = config.CONF
 
 
-class BaseVolumesClientJSON(rest_client.RestClient):
+class BaseVolumesClientJSON(base.VolumeClient):
     """
     Base client class to send CRUD Volume API requests to a Cinder endpoint
     """
 
-    def __init__(self, auth_provider):
-        super(BaseVolumesClientJSON, self).__init__(auth_provider)
-
-        self.service = CONF.volume.catalog_type
-        self.build_interval = CONF.volume.build_interval
-        self.build_timeout = CONF.volume.build_timeout
-        self.create_resp = 200
+    create_resp = 200
 
     def get_attachment_from_volume(self, volume):
         """Return the element 'attachment' from input volumes."""
diff --git a/tempest/test.py b/tempest/test.py
index 6deb42b..cc8370c 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -194,7 +194,6 @@
     """
     config_dict = {
         'compute': CONF.compute_feature_enabled.api_extensions,
-        'compute_v3': CONF.compute_feature_enabled.api_v3_extensions,
         'volume': CONF.volume_feature_enabled.api_extensions,
         'network': CONF.network_feature_enabled.api_extensions,
         'object': CONF.object_storage_feature_enabled.discoverable_apis,
@@ -274,8 +273,8 @@
             cls.resource_setup()
         except Exception:
             etype, value, trace = sys.exc_info()
-            LOG.info("%s in %s.setUpClass. Invoking tearDownClass." % (
-                cls.__name__, etype))
+            LOG.info("%s raised in %s.setUpClass. Invoking tearDownClass." % (
+                     etype, cls.__name__))
             cls.tearDownClass()
             try:
                 raise etype, value, trace
@@ -321,20 +320,6 @@
                 del trace  # to avoid circular refs
 
     @classmethod
-    def resource_setup(cls):
-        """Class level resource setup for test cases.
-        """
-        pass
-
-    @classmethod
-    def resource_cleanup(cls):
-        """Class level resource cleanup for test cases.
-        Resource cleanup must be able to handle the case of partially setup
-        resources, in case a failure during `resource_setup` should happen.
-        """
-        pass
-
-    @classmethod
     def skip_checks(cls):
         """Class level skip checks. Subclasses verify in here all
         conditions that might prevent the execution of the entire test class.
@@ -362,6 +347,20 @@
         # specify which client is `client` and nothing else.
         pass
 
+    @classmethod
+    def resource_setup(cls):
+        """Class level resource setup for test cases.
+        """
+        pass
+
+    @classmethod
+    def resource_cleanup(cls):
+        """Class level resource cleanup for test cases.
+        Resource cleanup must be able to handle the case of partially setup
+        resources, in case a failure during `resource_setup` should happen.
+        """
+        pass
+
     def setUp(self):
         super(BaseTestCase, self).setUp()
         if not self.setUpClassCalled:
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 3b9a990..a8adc7e 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -15,7 +15,6 @@
 import json
 
 import mock
-from oslo.config import cfg
 
 from tempest.cmd import verify_tempest_config
 from tempest import config
@@ -87,7 +86,7 @@
         self.assertIn('v3.0', versions)
 
     def test_verify_api_versions(self):
-        api_services = ['cinder', 'glance', 'keystone', 'nova']
+        api_services = ['cinder', 'glance', 'keystone']
         fake_os = mock.MagicMock()
         for svc in api_services:
             m = 'verify_%s_api_versions' % svc
@@ -96,7 +95,7 @@
                 verify_mock.assert_called_once_with(fake_os, True)
 
     def test_verify_api_versions_not_implemented(self):
-        api_services = ['cinder', 'glance', 'keystone', 'nova']
+        api_services = ['cinder', 'glance', 'keystone']
         fake_os = mock.MagicMock()
         for svc in api_services:
             m = 'verify_%s_api_versions' % svc
@@ -170,26 +169,9 @@
         print_mock.assert_called_once_with('api_v1', 'volume_feature_enabled',
                                            False, True)
 
-    def test_verify_nova_versions(self):
-        cfg.CONF.set_default('api_v3', True, 'compute-feature-enabled')
-        self.useFixture(mockpatch.PatchObject(
-            verify_tempest_config, '_get_unversioned_endpoint',
-            return_value='http://fake_endpoint:5000'))
-        fake_resp = {'versions': [{'id': 'v2.0'}]}
-        fake_resp = json.dumps(fake_resp)
-        self.useFixture(mockpatch.PatchObject(
-            verify_tempest_config.RAW_HTTP, 'request',
-            return_value=(None, fake_resp)))
-        fake_os = mock.MagicMock()
-        with mock.patch.object(verify_tempest_config,
-                               'print_and_or_update') as print_mock:
-            verify_tempest_config.verify_nova_api_versions(fake_os, True)
-        print_mock.assert_called_once_with('api_v3', 'compute_feature_enabled',
-                                           False, True)
-
     def test_verify_glance_version_no_v2_with_v1_1(self):
         def fake_get_versions():
-            return (None, ['v1.1'])
+            return (['v1.1'])
         fake_os = mock.MagicMock()
         fake_os.image_client.get_versions = fake_get_versions
         with mock.patch.object(verify_tempest_config,
@@ -200,7 +182,7 @@
 
     def test_verify_glance_version_no_v2_with_v1_0(self):
         def fake_get_versions():
-            return (None, ['v1.0'])
+            return (['v1.0'])
         fake_os = mock.MagicMock()
         fake_os.image_client.get_versions = fake_get_versions
         with mock.patch.object(verify_tempest_config,
@@ -211,7 +193,7 @@
 
     def test_verify_glance_version_no_v1(self):
         def fake_get_versions():
-            return (None, ['v2.0'])
+            return (['v2.0'])
         fake_os = mock.MagicMock()
         fake_os.image_client.get_versions = fake_get_versions
         with mock.patch.object(verify_tempest_config,
diff --git a/tempest/tests/fake_config.py b/tempest/tests/fake_config.py
index 9e56916..2f8efa1 100644
--- a/tempest/tests/fake_config.py
+++ b/tempest/tests/fake_config.py
@@ -52,9 +52,6 @@
                 self.conf.set_default(prefix + config_option,
                                       'fake_' + config_option,
                                       group='identity')
-            # Compute Admin group items
-            self.conf.set_default(config_option, 'fake_' + config_option,
-                                  group='compute-admin')
 
 
 class FakePrivate(config.TempestConfigPrivate):
diff --git a/tempest/tests/test_credentials.py b/tempest/tests/test_credentials.py
index fc80fe2..aa3df36 100644
--- a/tempest/tests/test_credentials.py
+++ b/tempest/tests/test_credentials.py
@@ -194,9 +194,6 @@
         for prefix in ['', 'alt_', 'admin_']:
             cfg.CONF.set_default(prefix + 'domain_name', 'fake_domain_name',
                                  group='identity')
-        # Compute Admin group items
-        cfg.CONF.set_default('domain_name', 'fake_domain_name',
-                             group='compute-admin')
 
     def test_default(self):
         self.useFixture(fixtures.LockFixture('auth_version'))
diff --git a/tempest/tests/test_list_tests.py b/tempest/tests/test_list_tests.py
index efdb413..19e4c9c 100644
--- a/tempest/tests/test_list_tests.py
+++ b/tempest/tests/test_list_tests.py
@@ -31,7 +31,7 @@
         ids, err = p.communicate()
         self.assertEqual(0, p.returncode,
                          "test discovery failed, one or more files cause an "
-                         "error on import")
+                         "error on import %s" % ids)
         ids = ids.split('\n')
         for test_id in ids:
             if re.match('(\w+\.){3}\w+', test_id):
diff --git a/tempest/tests/test_rest_client.py b/tempest/tests/test_rest_client.py
index 5b2ce7a..a133800 100644
--- a/tempest/tests/test_rest_client.py
+++ b/tempest/tests/test_rest_client.py
@@ -17,6 +17,7 @@
 import httplib2
 from oslotest import mockpatch
 
+from tempest.common import negative_rest_client
 from tempest.common import rest_client
 from tempest import config
 from tempest import exceptions
@@ -30,18 +31,13 @@
 
     url = 'fake_endpoint'
 
-    def _get_region(self):
-        return 'fake region'
-
     def setUp(self):
         super(BaseRestClientTestClass, self).setUp()
         self.useFixture(fake_config.ConfigFixture())
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.rest_client = rest_client.RestClient(
-            fake_auth_provider.FakeAuthProvider())
+            fake_auth_provider.FakeAuthProvider(), None, None)
         self.stubs.Set(httplib2.Http, 'request', self.fake_http.request)
-        self.useFixture(mockpatch.PatchObject(self.rest_client, '_get_region',
-                                              side_effect=self._get_region()))
         self.useFixture(mockpatch.PatchObject(self.rest_client,
                                               '_log_request'))
 
@@ -304,7 +300,7 @@
         self.useFixture(fake_config.ConfigFixture())
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.rest_client = rest_client.RestClient(
-            fake_auth_provider.FakeAuthProvider())
+            fake_auth_provider.FakeAuthProvider(), None, None)
 
     def test_response_less_than_400(self):
         self.rest_client._error_checker(**self.set_data("399"))
@@ -339,6 +335,11 @@
                           self.rest_client._error_checker,
                           **self.set_data("413"))
 
+    def test_response_415(self):
+        self.assertRaises(exceptions.InvalidContentType,
+                          self.rest_client._error_checker,
+                          **self.set_data("415"))
+
     def test_response_422(self):
         self.assertRaises(exceptions.UnprocessableEntity,
                           self.rest_client._error_checker,
@@ -433,8 +434,8 @@
     def setUp(self):
         self.fake_http = fake_http.fake_httplib2()
         super(TestNegativeRestClient, self).setUp()
-        self.negative_rest_client = rest_client.NegativeRestClient(
-            fake_auth_provider.FakeAuthProvider())
+        self.negative_rest_client = negative_rest_client.NegativeRestClient(
+            fake_auth_provider.FakeAuthProvider(), None)
         self.useFixture(mockpatch.PatchObject(self.negative_rest_client,
                                               '_log_request'))
 
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index f29ae5a..053dae1 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -320,8 +320,8 @@
 
         return_values = (fake_http.fake_httplib({}, status=204), {})
         remove_secgroup_mock = self.patch(
-            'tempest.services.network.network_client_base.'
-            'NetworkClientBase.delete', return_value=return_values)
+            'tempest.services.network.json.network_client.'
+            'NetworkClientJSON.delete', return_value=return_values)
         iso_creds.clear_isolated_creds()
         # Verify default security group delete
         calls = remove_secgroup_mock.mock_calls
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index 00b17d9..707590e 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -157,19 +157,24 @@
             instance.add_tag('key1', value='value1')
 
         tags = self.ec2_client.get_all_tags()
-        self.assertEqual(tags[0].name, 'key1')
-        self.assertEqual(tags[0].value, 'value1')
+        td = {item.name: item.value for item in tags}
+
+        self.assertIn('key1', td)
+        self.assertEqual('value1', td['key1'])
 
         tags = self.ec2_client.get_all_tags(filters={'key': 'key1'})
-        self.assertEqual(tags[0].name, 'key1')
-        self.assertEqual(tags[0].value, 'value1')
+        td = {item.name: item.value for item in tags}
+        self.assertIn('key1', td)
+        self.assertEqual('value1', td['key1'])
 
         tags = self.ec2_client.get_all_tags(filters={'value': 'value1'})
-        self.assertEqual(tags[0].name, 'key1')
-        self.assertEqual(tags[0].value, 'value1')
+        td = {item.name: item.value for item in tags}
+        self.assertIn('key1', td)
+        self.assertEqual('value1', td['key1'])
 
         tags = self.ec2_client.get_all_tags(filters={'key': 'value2'})
-        self.assertEqual(len(tags), 0, str(tags))
+        td = {item.name: item.value for item in tags}
+        self.assertNotIn('key1', td)
 
         for instance in reservation.instances:
             instance.remove_tag('key1', value='value1')
diff --git a/tox.ini b/tox.ini
index edfee15..fe2f79e 100644
--- a/tox.ini
+++ b/tox.ini
@@ -7,7 +7,8 @@
 sitepackages = True
 setenv = VIRTUAL_ENV={envdir}
          OS_TEST_PATH=./tempest/test_discover
-deps = -r{toxinidir}/requirements.txt
+deps = setuptools
+       -r{toxinidir}/requirements.txt
 
 [testenv]
 setenv = VIRTUAL_ENV={envdir}