Merge "Check Floating ip status before load balancer check"
diff --git a/README.rst b/README.rst
index 5284bbf..7af0025 100644
--- a/README.rst
+++ b/README.rst
@@ -124,14 +124,14 @@
 Python 2.6
 ----------
 
-Tempest can be run with Python 2.6 however the unit tests and the gate
-currently only run with Python 2.7, so there are no guarantees about the state
-of tempest when running with Python 2.6. Additionally, to enable testr to work
-with tempest using python 2.6 the discover module from the unittest-ext
-project has to be patched to switch the unittest.TestSuite to use
-unittest2.TestSuite instead. See:
-
-https://code.google.com/p/unittest-ext/issues/detail?id=79
+Starting in the kilo release the OpenStack services dropped all support for
+python 2.6. This change has been mirrored in tempest, starting after the
+tempest-2 tag. This means that proposed changes to tempest which only fix
+python 2.6 compatibility will be rejected, and moving forward more features not
+present in python 2.6 will be used. If you're running you're OpenStack services
+on an earlier release with python 2.6 you can easily run tempest against it
+from a remote system running python 2.7. (or deploy a cloud guest in your cloud
+that has python 2.7)
 
 Branchless Tempest Considerations
 ---------------------------------
diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst
new file mode 100644
index 0000000..08f37cc
--- /dev/null
+++ b/doc/source/configuration.rst
@@ -0,0 +1,115 @@
+Tempest Configuration Guide
+===========================
+
+Auth/Credentials
+----------------
+
+Tempest currently has 2 different ways in configuration to provide credentials
+to use when running tempest. One is a traditional set of configuration options
+in the tempest.conf file. These options are in the identity section and let you
+specify a regular user, a global admin user, and a alternate user set of
+credentials. (which consist of a username, password, and project/tenant name)
+These options should be clearly labelled in the sample config file in the
+identity section.
+
+The other method to provide credentials is using the accounts.yaml file. This
+file is used to specify an arbitrary number of users available to run tests
+with. You can specify the location of the file in the
+auth section in the tempest.conf file. To see the specific format used in
+the file please refer to the accounts.yaml.sample file included in tempest.
+Currently users that are specified in the accounts.yaml file are assumed to
+have the same set of roles which can be used for executing all the tests you
+are running. This will be addressed in the future, but is a current limitation.
+Eventually the config options for providing credentials to tempest will be
+deprecated and removed in favor of the accounts.yaml file.
+
+Credential Provider Mechanisms
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+Tempest currently also has 3 different internal methods for providing
+authentication to tests. Tenant isolation, locking test accounts, and
+non-locking test accounts. Depending on which one is in use the configuration
+of tempest is slightly different.
+
+Tenant Isolation
+""""""""""""""""
+Tenant isolation was originally create to enable running tempest in parallel.
+For each test class it creates a unique set of user credentials to use for the
+tests in the class. It can create up to 3 sets of username, password, and
+tenant/project names for a primary user, an admin user, and an alternate user.
+To enable and use tenant isolation you only need to configure 2 things:
+
+ #. A set of admin credentials with permissions to create users and
+    tenants/projects. This is specified in the identity section with the
+    admin_username, admin_tenant_name, and admin_password options
+ #. To enable tenant_isolation in the auth section with the
+    allow_tenant_isolation option.
+
+
+Locking Test Accounts
+"""""""""""""""""""""
+For a long time using tenant isolation was the only method available if you
+wanted to enable parallel execution of tempest tests. However this was
+insufficient for certain use cases because of the admin credentials requirement
+to create the credential sets on demand. To get around that the accounts.yaml
+file was introduced and with that a new internal credential provider to enable
+using the list of credentials instead of creating them on demand. With locking
+test accounts each test class will reserve a set of credentials from the
+accounts.yaml before executing any of its tests so that each class is isolated
+like in tenant isolation.
+
+Currently, this mechanism has some limitations, first only non-admin users with
+the same role set can be used at one time. The second limitation is around
+networking, locking test accounts will only work with a single flat network as
+the default for each tenant/project. If another network configuration is used
+in your cloud you might face unexpected failures.
+
+To enable and use locking test accounts you need do a few things:
+
+ #. Enable the locking test account provider with the
+    locking_credentials_provider option in the auth section
+ #. Create a accounts.yaml file which contains the set of pre-existing
+    credentials to use for testing. To make sure you don't have a credentials
+    starvation issue when running in parallel make sure you have at least 2
+    times the number of parallel workers you are using to execute tempest
+    available in the file.
+ #. Provide tempest with the location of you accounts.yaml file with the
+    test_accounts_file option in the auth section
+
+
+Non-locking test accounts
+"""""""""""""""""""""""""
+When tempest was refactored to allow for locking test accounts, the original
+non-tenant isolated case was converted to support the new accounts.yaml file.
+This mechanism is the non-locking test accounts provider. It only makes sense
+to use it if parallel execution isn't needed. If the role restrictions were too
+limiting with the locking accounts provider and tenant isolation is not wanted
+then you can use the non-locking test accounts credential provider without the
+accounts.yaml file. This is also the currently the default configuration for
+tempest, since it doesn't require elevated permissions or the extra file.
+
+To use the non-locking test accounts provider you have 2 ways to configure it.
+First you can specify the sets of credentials in the configuration file like
+detailed above with following 9 options in the identity section:
+
+ #. username
+ #. password
+ #. tenant_name
+ #. admin_username
+ #. admin_password
+ #. admin_tenant_name
+ #. alt_username
+ #. alt_password
+ #. alt_tenant_name
+
+You should use this if you need to specify credentials with different roles.
+(i.e. you want to use admin credentials) However, this isn't a requirement for
+its usage.
+
+You also can use the accounts.yaml file to specify the credentials used for
+testing. This will just allocate them serially so you only need to provide
+a pair of credentials. Do note that all the restrictions associated with
+locking test accounts applies to using the accounts.yaml file this way too.
+The procedure for doing this is very similar to with the locking accounts
+provider just don't set the locking_credentials_provider to true and you
+only should need a single pair of credentials.
diff --git a/doc/source/index.rst b/doc/source/index.rst
index 1f06bc5..cb1c504 100644
--- a/doc/source/index.rst
+++ b/doc/source/index.rst
@@ -29,6 +29,15 @@
    field_guide/thirdparty
    field_guide/unit_tests
 
+---------------------------
+Tempest Configuration Guide
+---------------------------
+
+.. toctree::
+   :maxdepth: 2
+
+   configuration
+
 ---------------------
 Command Documentation
 ---------------------
diff --git a/etc/accounts.yaml.sample b/etc/accounts.yaml.sample
index 54fdcad..64ff8a7 100644
--- a/etc/accounts.yaml.sample
+++ b/etc/accounts.yaml.sample
@@ -9,3 +9,27 @@
 - username: 'user_2'
   tenant_name: 'test_tenant_2'
   password: 'test_password'
+
+# To specify which roles a user has list them under the roles field
+- username: 'multi_role_user'
+  tenant_name: 'test_tenant_42'
+  password: 'test_password'
+  roles:
+    - 'fun_role'
+    - 'not_an_admin'
+    - 'an_admin'
+
+# To specify a user has a role specified in the config file you can use the
+# type field to specify it, valid values are admin, operator, and reseller_admin
+- username: 'swift_pseudo_admin_user_1'
+  tenant_name: 'admin_tenant_1'
+  password: 'test_password'
+  types:
+     - 'reseller_admin'
+     - 'operator'
+
+- username: 'admin_user_1'
+  tenant_name: 'admin_tenant_1'
+  password: 'test_password'
+  types:
+     - 'admin'
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index bc4198f..d81d3bb 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -125,7 +125,7 @@
 # achieved configuring a list of test accounts (boolean value)
 # Deprecated group/name - [compute]/allow_tenant_isolation
 # Deprecated group/name - [orchestration]/allow_tenant_isolation
-#allow_tenant_isolation = false
+#allow_tenant_isolation = true
 
 # If set to True it enables the Accounts provider, which locks
 # credentials to allow for parallel execution with pre-provisioned
diff --git a/tempest/api/compute/servers/test_delete_server.py b/tempest/api/compute/servers/test_delete_server.py
index 8842899..6155958 100644
--- a/tempest/api/compute/servers/test_delete_server.py
+++ b/tempest/api/compute/servers/test_delete_server.py
@@ -123,7 +123,7 @@
         device = '/dev/%s' % CONF.compute.volume_device_name
         server = self.create_test_server(wait_until='ACTIVE')
 
-        volume = volumes_client.create_volume(1)
+        volume = volumes_client.create_volume()
         self.addCleanup(volumes_client.delete_volume, volume['id'])
         volumes_client.wait_for_volume_status(volume['id'], 'available')
         self.client.attach_volume(server['id'],
diff --git a/tempest/api/compute/servers/test_server_rescue_negative.py b/tempest/api/compute/servers/test_server_rescue_negative.py
index 6e23334..7564758 100644
--- a/tempest/api/compute/servers/test_server_rescue_negative.py
+++ b/tempest/api/compute/servers/test_server_rescue_negative.py
@@ -58,7 +58,7 @@
 
     def _create_volume(self):
         volume = self.volumes_extensions_client.create_volume(
-            1, display_name=data_utils.rand_name(
+            CONF.volume.volume_size, display_name=data_utils.rand_name(
                 self.__class__.__name__ + '_volume'))
         self.addCleanup(self.delete_volume, volume['id'])
         self.volumes_extensions_client.wait_for_volume_status(
diff --git a/tempest/api/compute/test_live_block_migration.py b/tempest/api/compute/test_live_block_migration.py
index a933f81..d2221e1 100644
--- a/tempest/api/compute/test_live_block_migration.py
+++ b/tempest/api/compute/test_live_block_migration.py
@@ -115,7 +115,7 @@
         actual_host = self._get_host_for_server(server_id)
         target_host = self._get_host_other_than(actual_host)
 
-        volume = self.volumes_client.create_volume(1, display_name='test')
+        volume = self.volumes_client.create_volume(display_name='test')
 
         self.volumes_client.wait_for_volume_status(volume['id'],
                                                    'available')
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 43d2302..12d5b0e 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -70,7 +70,7 @@
 
         # Create a volume and wait for it to become ready
         self.volume = self.volumes_client.create_volume(
-            1, display_name='test')
+            CONF.volume.volume_size, display_name='test')
         self.addCleanup(self._delete_volume)
         self.volumes_client.wait_for_volume_status(self.volume['id'],
                                                    'available')
diff --git a/tempest/api/compute/volumes/test_volumes_get.py b/tempest/api/compute/volumes/test_volumes_get.py
index 207476d..5f84c73 100644
--- a/tempest/api/compute/volumes/test_volumes_get.py
+++ b/tempest/api/compute/volumes/test_volumes_get.py
@@ -46,8 +46,7 @@
         v_name = data_utils.rand_name('Volume')
         metadata = {'Type': 'work'}
         # Create volume
-        volume = self.client.create_volume(size=1,
-                                           display_name=v_name,
+        volume = self.client.create_volume(display_name=v_name,
                                            metadata=metadata)
         self.addCleanup(self.delete_volume, volume['id'])
         self.assertIn('id', volume)
diff --git a/tempest/api/compute/volumes/test_volumes_list.py b/tempest/api/compute/volumes/test_volumes_list.py
index 501e9ed..bd126d8 100644
--- a/tempest/api/compute/volumes/test_volumes_list.py
+++ b/tempest/api/compute/volumes/test_volumes_list.py
@@ -53,8 +53,7 @@
             v_name = data_utils.rand_name('volume')
             metadata = {'Type': 'work'}
             try:
-                volume = cls.client.create_volume(size=1,
-                                                  display_name=v_name,
+                volume = cls.client.create_volume(display_name=v_name,
                                                   metadata=metadata)
                 cls.client.wait_for_volume_status(volume['id'], 'available')
                 volume = cls.client.get_volume(volume['id'])
diff --git a/tempest/services/identity/json/__init__.py b/tempest/api/identity/admin/v2/__init__.py
similarity index 100%
copy from tempest/services/identity/json/__init__.py
copy to tempest/api/identity/admin/v2/__init__.py
diff --git a/tempest/api/identity/admin/test_roles.py b/tempest/api/identity/admin/v2/test_roles.py
similarity index 100%
rename from tempest/api/identity/admin/test_roles.py
rename to tempest/api/identity/admin/v2/test_roles.py
diff --git a/tempest/api/identity/admin/test_roles_negative.py b/tempest/api/identity/admin/v2/test_roles_negative.py
similarity index 100%
rename from tempest/api/identity/admin/test_roles_negative.py
rename to tempest/api/identity/admin/v2/test_roles_negative.py
diff --git a/tempest/api/identity/admin/test_services.py b/tempest/api/identity/admin/v2/test_services.py
similarity index 100%
rename from tempest/api/identity/admin/test_services.py
rename to tempest/api/identity/admin/v2/test_services.py
diff --git a/tempest/api/identity/admin/test_tenant_negative.py b/tempest/api/identity/admin/v2/test_tenant_negative.py
similarity index 100%
rename from tempest/api/identity/admin/test_tenant_negative.py
rename to tempest/api/identity/admin/v2/test_tenant_negative.py
diff --git a/tempest/api/identity/admin/test_tenants.py b/tempest/api/identity/admin/v2/test_tenants.py
similarity index 100%
rename from tempest/api/identity/admin/test_tenants.py
rename to tempest/api/identity/admin/v2/test_tenants.py
diff --git a/tempest/api/identity/admin/test_tokens.py b/tempest/api/identity/admin/v2/test_tokens.py
similarity index 100%
rename from tempest/api/identity/admin/test_tokens.py
rename to tempest/api/identity/admin/v2/test_tokens.py
diff --git a/tempest/api/identity/admin/test_users.py b/tempest/api/identity/admin/v2/test_users.py
similarity index 100%
rename from tempest/api/identity/admin/test_users.py
rename to tempest/api/identity/admin/v2/test_users.py
diff --git a/tempest/api/identity/admin/test_users_negative.py b/tempest/api/identity/admin/v2/test_users_negative.py
similarity index 100%
rename from tempest/api/identity/admin/test_users_negative.py
rename to tempest/api/identity/admin/v2/test_users_negative.py
diff --git a/tempest/api/identity/admin/v3/test_domains.py b/tempest/api/identity/admin/v3/test_domains.py
index 6c634b8..0441f6d 100644
--- a/tempest/api/identity/admin/v3/test_domains.py
+++ b/tempest/api/identity/admin/v3/test_domains.py
@@ -83,3 +83,16 @@
         self.assertEqual(new_name, fetched_domain['name'])
         self.assertEqual(new_desc, fetched_domain['description'])
         self.assertEqual('true', str(fetched_domain['enabled']).lower())
+
+    @test.attr(type='smoke')
+    @test.idempotent_id('036df86e-bb5d-42c0-a7c2-66b9db3a6046')
+    def test_create_domain_with_disabled_status(self):
+        # Create domain with enabled status as false
+        d_name = data_utils.rand_name('domain-')
+        d_desc = data_utils.rand_name('domain-desc-')
+        domain = self.client.create_domain(
+            d_name, description=d_desc, enabled=False)
+        self.addCleanup(self.client.delete_domain, domain['id'])
+        self.assertEqual(d_name, domain['name'])
+        self.assertFalse(domain['enabled'])
+        self.assertEqual(d_desc, domain['description'])
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 4b5075c..db64a5b 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -120,7 +120,7 @@
         self.assertIsNotNone(trust['id'])
         self.assertEqual(impersonate, trust['impersonation'])
         if expires is not None:
-            # Omit microseconds of the expiry time
+            # Omit microseconds component of the expiry time
             trust_expires_at = re.sub(r'\.([0-9]){6}', '', trust['expires_at'])
             self.assertEqual(expires, trust_expires_at)
         else:
@@ -220,11 +220,14 @@
         # with an expiry specified
         expires_at = timeutils.utcnow() + datetime.timedelta(hours=1)
         # NOTE(ylobankov) In some cases the expiry time may be rounded up
-        # because of microseconds. For example, we have the following expiry
-        # time for a trust: 2015-02-17T17:34:01.907051Z. However, if we make
-        # a GET request on the trust, the response may contain the time
-        # rounded up to 2015-02-17T17:34:02.000000Z. That is why we should
-        # omit microseconds when creating a trust.
+        # because of microseconds. In fact, it depends on database and its
+        # version. At least MySQL 5.6.16 does this.
+        # For example, when creating a trust, we will set the expiry time of
+        # the trust to 2015-02-17T17:34:01.907051Z. However, if we make a GET
+        # request on the trust, the response will contain the time rounded up
+        # to 2015-02-17T17:34:02.000000Z. That is why we shouldn't set flag
+        # "subsecond" to True when we invoke timeutils.isotime(...) to avoid
+        # problems with rounding.
         expires_str = timeutils.isotime(at=expires_at)
 
         trust = self.create_trust(expires=expires_str)
diff --git a/tempest/api/network/admin/test_external_network_extension.py b/tempest/api/network/admin/test_external_network_extension.py
index 20b4e31..d942641 100644
--- a/tempest/api/network/admin/test_external_network_extension.py
+++ b/tempest/api/network/admin/test_external_network_extension.py
@@ -101,7 +101,8 @@
         self.addCleanup(self._try_delete_resource,
                         client.delete_network,
                         external_network['id'])
-        subnet = self.create_subnet(external_network, client=client)
+        subnet = self.create_subnet(external_network, client=client,
+                                    enable_dhcp=False)
         body = client.create_floatingip(
             floating_network_id=external_network['id'])
         created_floating_ip = body['floatingip']
diff --git a/tempest/api/network/test_metering_extensions.py b/tempest/api/network/test_metering_extensions.py
index f794f5a..8e4ee87 100644
--- a/tempest/api/network/test_metering_extensions.py
+++ b/tempest/api/network/test_metering_extensions.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
 #
-# Author: Emilien Macchi <emilien.macchi@enovance.com>
-#
 # 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
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 8479013..79d2046 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -176,7 +176,7 @@
         sg_id = group_create_body['security_group']['id']
         direction = 'ingress'
         protocol = 'icmp'
-        icmp_type_codes = [(3, 2), (2, 3), (3, 0), (2, None)]
+        icmp_type_codes = [(3, 2), (3, 0), (8, 0), (0, 0), (11, None)]
         for icmp_type, icmp_code in icmp_type_codes:
             self._create_verify_security_group_rule(sg_id, direction,
                                                     self.ethertype, protocol,
diff --git a/tempest/api/object_storage/test_account_quotas.py b/tempest/api/object_storage/test_account_quotas.py
index 29f314d..9b379f4 100644
--- a/tempest/api/object_storage/test_account_quotas.py
+++ b/tempest/api/object_storage/test_account_quotas.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
diff --git a/tempest/api/object_storage/test_account_quotas_negative.py b/tempest/api/object_storage/test_account_quotas_negative.py
index 548c619..7d4008c 100644
--- a/tempest/api/object_storage/test_account_quotas_negative.py
+++ b/tempest/api/object_storage/test_account_quotas_negative.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
diff --git a/tempest/api/object_storage/test_account_services_negative.py b/tempest/api/object_storage/test_account_services_negative.py
index a913bd7..f329675 100644
--- a/tempest/api/object_storage/test_account_services_negative.py
+++ b/tempest/api/object_storage/test_account_services_negative.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 #    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
diff --git a/tempest/api/object_storage/test_container_acl_negative.py b/tempest/api/object_storage/test_container_acl_negative.py
index 644c3b1..5892340 100644
--- a/tempest/api/object_storage/test_container_acl_negative.py
+++ b/tempest/api/object_storage/test_container_acl_negative.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 #    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
diff --git a/tempest/api/object_storage/test_container_staticweb.py b/tempest/api/object_storage/test_container_staticweb.py
index 102c9cd..45ecfec 100644
--- a/tempest/api/object_storage/test_container_staticweb.py
+++ b/tempest/api/object_storage/test_container_staticweb.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
diff --git a/tempest/api/object_storage/test_crossdomain.py b/tempest/api/object_storage/test_crossdomain.py
index 16ff95e..9d49a73 100644
--- a/tempest/api/object_storage/test_crossdomain.py
+++ b/tempest/api/object_storage/test_crossdomain.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
diff --git a/tempest/api/object_storage/test_healthcheck.py b/tempest/api/object_storage/test_healthcheck.py
index a2a4497..2ca0a9f 100644
--- a/tempest/api/object_storage/test_healthcheck.py
+++ b/tempest/api/object_storage/test_healthcheck.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
diff --git a/tempest/api/object_storage/test_object_formpost.py b/tempest/api/object_storage/test_object_formpost.py
index 5425eaa..3e0fc7b 100644
--- a/tempest/api/object_storage/test_object_formpost.py
+++ b/tempest/api/object_storage/test_object_formpost.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Christian Schwede <christian.schwede@enovance.com>
-#
 # 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
diff --git a/tempest/api/object_storage/test_object_formpost_negative.py b/tempest/api/object_storage/test_object_formpost_negative.py
index d8fc077..d92a2e5 100644
--- a/tempest/api/object_storage/test_object_formpost_negative.py
+++ b/tempest/api/object_storage/test_object_formpost_negative.py
@@ -1,5 +1,4 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
 #
 # 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
diff --git a/tempest/api/object_storage/test_object_temp_url.py b/tempest/api/object_storage/test_object_temp_url.py
index 4563bfd..e6b0b05 100644
--- a/tempest/api/object_storage/test_object_temp_url.py
+++ b/tempest/api/object_storage/test_object_temp_url.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
diff --git a/tempest/api/object_storage/test_object_temp_url_negative.py b/tempest/api/object_storage/test_object_temp_url_negative.py
index af927a8..343749e 100644
--- a/tempest/api/object_storage/test_object_temp_url_negative.py
+++ b/tempest/api/object_storage/test_object_temp_url_negative.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
-#
 # 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
diff --git a/tempest/api/orchestration/stacks/test_resource_types.py b/tempest/api/orchestration/stacks/test_resource_types.py
index 33d2f9e..32b0b8e 100644
--- a/tempest/api/orchestration/stacks/test_resource_types.py
+++ b/tempest/api/orchestration/stacks/test_resource_types.py
@@ -43,5 +43,7 @@
         """Verify it is possible to get template about resource types."""
         type_template = self.client.get_resource_type_template(
             'OS::Nova::Server')
-        self.assert_fields_in_dict(type_template, 'Outputs',
-            'Parameters', 'Resources')
\ No newline at end of file
+        self.assert_fields_in_dict(
+            type_template,
+            'Outputs',
+            'Parameters', 'Resources')
diff --git a/tempest/api/orchestration/stacks/test_swift_resources.py b/tempest/api/orchestration/stacks/test_swift_resources.py
index efbf695..1290dfe 100644
--- a/tempest/api/orchestration/stacks/test_swift_resources.py
+++ b/tempest/api/orchestration/stacks/test_swift_resources.py
@@ -1,8 +1,6 @@
 # -*- coding: utf-8 -*-
 # Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
 #
-# Author: Chmouel Boudjnah <chmouel@enovance.com>
-#
 # 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
diff --git a/tempest/api/volume/admin/test_multi_backend.py b/tempest/api/volume/admin/test_multi_backend.py
index 97dd104..2e4b614 100644
--- a/tempest/api/volume/admin/test_multi_backend.py
+++ b/tempest/api/volume/admin/test_multi_backend.py
@@ -70,8 +70,7 @@
 
         params = {self.name_field: vol_name, 'volume_type': type_name}
 
-        self.volume = self.admin_volume_client.create_volume(size=1,
-                                                             **params)
+        self.volume = self.admin_volume_client.create_volume(**params)
         if with_prefix:
             self.volume_id_list_with_prefix.append(self.volume['id'])
         else:
diff --git a/tempest/api/volume/admin/test_snapshots_actions.py b/tempest/api/volume/admin/test_snapshots_actions.py
index 469f13e..4834be1 100644
--- a/tempest/api/volume/admin/test_snapshots_actions.py
+++ b/tempest/api/volume/admin/test_snapshots_actions.py
@@ -34,7 +34,7 @@
         cls.name_field = cls.special_fields['name_field']
         params = {cls.name_field: vol_name}
         cls.volume = \
-            cls.volumes_client.create_volume(size=1, **params)
+            cls.volumes_client.create_volume(**params)
         cls.volumes_client.wait_for_volume_status(cls.volume['id'],
                                                   'available')
 
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 9b436aa..cd91552 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
 #
-# Author: Sylvain Baubeau <sylvain.baubeau@enovance.com>
-#
 #    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
@@ -86,7 +84,7 @@
         quota_usage = self.quotas_client.get_quota_usage(
             self.demo_tenant_id)
 
-        volume = self.create_volume(size=1)
+        volume = self.create_volume()
         self.addCleanup(self.admin_volume_client.delete_volume,
                         volume['id'])
 
diff --git a/tempest/api/volume/admin/test_volume_quotas_negative.py b/tempest/api/volume/admin/test_volume_quotas_negative.py
index 67edd09..98b7143 100644
--- a/tempest/api/volume/admin/test_volume_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_quotas_negative.py
@@ -48,8 +48,7 @@
     @test.idempotent_id('bf544854-d62a-47f2-a681-90f7a47d86b6')
     def test_quota_volumes(self):
         self.assertRaises(lib_exc.OverLimit,
-                          self.volumes_client.create_volume,
-                          size=1)
+                          self.volumes_client.create_volume)
 
     @test.attr(type='negative')
     @test.idempotent_id('02bbf63f-6c05-4357-9d98-2926a94064ff')
@@ -73,8 +72,7 @@
             self.demo_tenant_id,
             **new_quota_set)
         self.assertRaises(lib_exc.OverLimit,
-                          self.volumes_client.create_volume,
-                          size=1)
+                          self.volumes_client.create_volume)
 
         new_quota_set = {'gigabytes': 2, 'volumes': 1, 'snapshots': 2}
         self.quotas_client.update_quota_set(
diff --git a/tempest/api/volume/admin/test_volume_types.py b/tempest/api/volume/admin/test_volume_types.py
index 8705f6f..01242f9 100644
--- a/tempest/api/volume/admin/test_volume_types.py
+++ b/tempest/api/volume/admin/test_volume_types.py
@@ -60,7 +60,7 @@
                   'volume_type': volume_types[0]['id']}
 
         # Create volume
-        volume = self.volumes_client.create_volume(size=1, **params)
+        volume = self.volumes_client.create_volume(**params)
         self.addCleanup(self._delete_volume, volume['id'])
         self.assertEqual(volume_types[0]['name'], volume["volume_type"])
         self.assertEqual(volume[self.name_field], vol_name,
diff --git a/tempest/api/volume/admin/test_volume_types_negative.py b/tempest/api/volume/admin/test_volume_types_negative.py
index eb46a54..d2bf777 100644
--- a/tempest/api/volume/admin/test_volume_types_negative.py
+++ b/tempest/api/volume/admin/test_volume_types_negative.py
@@ -31,8 +31,7 @@
         params = {self.name_field: str(uuid.uuid4()),
                   'volume_type': str(uuid.uuid4())}
         self.assertRaises(lib_exc.NotFound,
-                          self.volumes_client.create_volume, size=1,
-                          **params)
+                          self.volumes_client.create_volume, **params)
 
     @test.attr(type='gate')
     @test.idempotent_id('878b4e57-faa2-4659-b0d1-ce740a06ae81')
diff --git a/tempest/api/volume/admin/test_volumes_actions.py b/tempest/api/volume/admin/test_volumes_actions.py
index b0013e6..dc96839 100644
--- a/tempest/api/volume/admin/test_volumes_actions.py
+++ b/tempest/api/volume/admin/test_volumes_actions.py
@@ -34,8 +34,7 @@
         cls.name_field = cls.special_fields['name_field']
         params = {cls.name_field: vol_name}
 
-        cls.volume = cls.client.create_volume(size=1,
-                                              **params)
+        cls.volume = cls.client.create_volume(**params)
         cls.client.wait_for_volume_status(cls.volume['id'], 'available')
 
     @classmethod
@@ -61,8 +60,7 @@
         # Create a temp volume for force delete tests
         vol_name = utils.rand_name('Volume')
         params = {self.name_field: vol_name}
-        temp_volume = self.client.create_volume(size=1,
-                                                **params)
+        temp_volume = self.client.create_volume(**params)
         self.client.wait_for_volume_status(temp_volume['id'], 'available')
 
         return temp_volume
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index c672607..4f94f34 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -106,7 +106,7 @@
         super(BaseVolumeTest, cls).resource_cleanup()
 
     @classmethod
-    def create_volume(cls, size=1, **kwargs):
+    def create_volume(cls, size=None, **kwargs):
         """Wrapper utility that returns a test volume."""
         name = data_utils.rand_name('Volume')
 
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index 007b0db..d03bd8d 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -108,7 +108,7 @@
         new_v_desc = data_utils.rand_name('@#$%^* description')
         params = {self.descrip_field: new_v_desc,
                   'availability_zone': volume['availability_zone']}
-        new_volume = self.client.create_volume(size=1, **params)
+        new_volume = self.client.create_volume(**params)
         self.assertIn('id', new_volume)
         self.addCleanup(self._delete_volume, new_volume['id'])
         self.client.wait_for_volume_status(new_volume['id'], 'available')
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 3c1cce3..b6cdd6b 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -181,7 +181,6 @@
         snapshot = self.create_snapshot(self.volume_origin['id'])
         # NOTE(gfidente): size is required also when passing snapshot_id
         volume = self.volumes_client.create_volume(
-            size=1,
             snapshot_id=snapshot['id'])
         self.volumes_client.wait_for_volume_status(volume['id'], 'available')
         self.volumes_client.delete_volume(volume['id'])
diff --git a/tempest/api_schema/response/compute/flavors.py b/tempest/api_schema/response/compute/flavors.py
index 44020d2..65f2c28 100644
--- a/tempest/api_schema/response/compute/flavors.py
+++ b/tempest/api_schema/response/compute/flavors.py
@@ -30,8 +30,11 @@
                     },
                     'required': ['name', 'links', 'id']
                 }
-            }
+            },
+            'flavors_links': parameter_types.links
         },
+        # NOTE(gmann): flavors_links attribute is not necessary
+        # to be present always So it is not 'required'.
         'required': ['flavors']
     }
 }
diff --git a/tempest/api_schema/response/compute/v2/flavors.py b/tempest/api_schema/response/compute/v2/flavors.py
index 811ea84..76c4cee 100644
--- a/tempest/api_schema/response/compute/v2/flavors.py
+++ b/tempest/api_schema/response/compute/v2/flavors.py
@@ -15,6 +15,7 @@
 import copy
 
 from tempest.api_schema.response.compute import flavors
+from tempest.api_schema.response.compute import parameter_types
 
 list_flavors_details = copy.deepcopy(flavors.common_flavor_list_details)
 
@@ -23,6 +24,12 @@
 list_flavors_details['response_body']['properties']['flavors']['items'][
     'properties']['swap'] = {'type': ['string', 'integer']}
 
+# Defining 'flavors_links' attributes for V2 flavor schema
+list_flavors_details['response_body'][
+    'properties'].update({'flavors_links': parameter_types.links})
+# NOTE(gmann): flavors_links attribute is not necessary to be
+# present always So it is not 'required'.
+
 # Defining extra attributes for V2 flavor schema
 list_flavors_details['response_body']['properties']['flavors']['items'][
     'properties'].update({'OS-FLV-DISABLED:disabled': {'type': 'boolean'},
diff --git a/tempest/api_schema/response/compute/v2/floating_ips.py b/tempest/api_schema/response/compute/v2/floating_ips.py
index def0a78..7250773 100644
--- a/tempest/api_schema/response/compute/v2/floating_ips.py
+++ b/tempest/api_schema/response/compute/v2/floating_ips.py
@@ -146,8 +146,14 @@
                         'instance_uuid': {'type': ['string', 'null']},
                         'interface': {'type': ['string', 'null']},
                         'pool': {'type': ['string', 'null']},
-                        'project_id': {'type': ['string', 'null']}
+                        'project_id': {'type': ['string', 'null']},
+                        'fixed_ip': {
+                            'type': ['string', 'null'],
+                            'format': 'ip-address'
+                        }
                     },
+                    # NOTE: fixed_ip is introduced after JUNO release,
+                    # So it is not defined as 'required'.
                     'required': ['address', 'instance_uuid', 'interface',
                                  'pool', 'project_id']
                 }
diff --git a/tempest/api_schema/response/compute/v2/limits.py b/tempest/api_schema/response/compute/v2/limits.py
index b9857f1..a7decb7 100644
--- a/tempest/api_schema/response/compute/v2/limits.py
+++ b/tempest/api_schema/response/compute/v2/limits.py
@@ -38,8 +38,15 @@
                             'maxSecurityGroupRules': {'type': 'integer'},
                             'maxTotalKeypairs': {'type': 'integer'},
                             'totalRAMUsed': {'type': 'integer'},
-                            'totalInstancesUsed': {'type': 'integer'}
+                            'totalInstancesUsed': {'type': 'integer'},
+                            'maxServerGroupMembers': {'type': 'integer'},
+                            'maxServerGroups': {'type': 'integer'},
+                            'totalServerGroupsUsed': {'type': 'integer'}
                         },
+                        # NOTE(gmann): maxServerGroupMembers,  maxServerGroups
+                        # and totalServerGroupsUsed are API extension,
+                        # and some environments return a response without these
+                        # attributes.So they are not 'required'.
                         'required': ['maxImageMeta',
                                      'maxPersonality',
                                      'maxPersonalitySize',
diff --git a/tempest/api_schema/response/compute/v2/servers.py b/tempest/api_schema/response/compute/v2/servers.py
index 09abaed..0132350 100644
--- a/tempest/api_schema/response/compute/v2/servers.py
+++ b/tempest/api_schema/response/compute/v2/servers.py
@@ -30,10 +30,10 @@
                     'links': parameter_types.links,
                     'OS-DCF:diskConfig': {'type': 'string'}
                 },
-                # NOTE: OS-DCF:diskConfig is API extension, and some
-                # environments return a response without the attribute.
-                # So it is not 'required'.
-                'required': ['id', 'security_groups', 'links']
+                # NOTE: OS-DCF:diskConfig & security_groups are API extension,
+                # and some environments return a response without these
+                # attributes.So they are not 'required'.
+                'required': ['id', 'links']
             }
         },
         'required': ['server']
@@ -64,6 +64,7 @@
 get_server['response_body']['properties']['server']['properties'].update({
     'key_name': {'type': ['string', 'null']},
     'hostId': {'type': 'string'},
+    'security_groups': {'type': 'array'},
 
     # NOTE: Non-admin users also can see "OS-SRV-USG" and "OS-EXT-AZ"
     # attributes.
@@ -288,10 +289,11 @@
     'properties'].update({
         'hostId': {'type': 'string'},
         'OS-DCF:diskConfig': {'type': 'string'},
+        'security_groups': {'type': 'array'},
         'accessIPv4': parameter_types.access_ip_v4,
         'accessIPv6': parameter_types.access_ip_v6
     })
-# NOTE(GMann): OS-DCF:diskConfig and accessIPv4/v6 are API
+# NOTE(GMann): OS-DCF:diskConfig, security_groups and accessIPv4/v6 are API
 # extensions, and some environments return a response
 # without these attributes. So they are not 'required'.
 list_servers_detail['response_body']['properties']['servers']['items'][
diff --git a/tempest/auth.py b/tempest/auth.py
index 5e76a88..9d8341c 100644
--- a/tempest/auth.py
+++ b/tempest/auth.py
@@ -23,7 +23,7 @@
 import six
 
 from tempest.openstack.common import log as logging
-from tempest.services.identity.json import token_client as json_id
+from tempest.services.identity.v2.json import token_client as json_v2id
 from tempest.services.identity.v3.json import token_client as json_v3id
 
 
@@ -242,7 +242,7 @@
     EXPIRY_DATE_FORMAT = '%Y-%m-%dT%H:%M:%SZ'
 
     def _auth_client(self, auth_url):
-        return json_id.TokenClientJSON(
+        return json_v2id.TokenClientJSON(
             auth_url, disable_ssl_certificate_validation=self.dsvm,
             ca_certs=self.ca_certs, trace_requests=self.trace_requests)
 
diff --git a/tempest/cli/__init__.py b/tempest/cli/__init__.py
index 4782129..6733204 100644
--- a/tempest/cli/__init__.py
+++ b/tempest/cli/__init__.py
@@ -68,14 +68,22 @@
 
 
 class ClientTestBase(test.BaseTestCase):
+
+    @classmethod
+    def skip_checks(cls):
+        super(ClientTestBase, cls).skip_checks()
+        if not CONF.identity_feature_enabled.api_v2:
+            raise cls.skipException("CLI clients rely on identity v2 API, "
+                                    "which is configured as not available")
+
     @classmethod
     def resource_setup(cls):
         if not CONF.cli.enabled:
             msg = "cli testing disabled"
             raise cls.skipException(msg)
         super(ClientTestBase, cls).resource_setup()
-        cls.cred_prov = credentials.get_isolated_credentials(cls.__name__)
-        cls.creds = cls.cred_prov.get_admin_creds()
+        cls.isolated_creds = credentials.get_isolated_credentials(cls.__name__)
+        cls.creds = cls.isolated_creds.get_admin_creds()
 
     def _get_clients(self):
         clients = base.CLIClient(self.creds.username,
diff --git a/tempest/cli/simple_read_only/identity/__init__.py b/tempest/cli/simple_read_only/identity/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/cli/simple_read_only/identity/__init__.py
+++ /dev/null
diff --git a/tempest/cli/simple_read_only/identity/test_keystone.py b/tempest/cli/simple_read_only/identity/test_keystone.py
deleted file mode 100644
index 10a26d5..0000000
--- a/tempest/cli/simple_read_only/identity/test_keystone.py
+++ /dev/null
@@ -1,155 +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 re
-
-from tempest_lib import exceptions
-
-from tempest import cli
-from tempest import config
-from tempest.openstack.common import log as logging
-from tempest import test
-
-CONF = config.CONF
-
-
-LOG = logging.getLogger(__name__)
-
-
-class SimpleReadOnlyKeystoneClientTest(cli.ClientTestBase):
-    """Basic, read-only tests for Keystone CLI client.
-
-    Checks return values and output of read-only commands.
-    These tests do not presume any content, nor do they create
-    their own. They only verify the structure of output if present.
-    """
-
-    def keystone(self, *args, **kwargs):
-        return self.clients.keystone(*args, **kwargs)
-
-    @test.idempotent_id('19c3ae95-3c19-4bba-8ba3-48ad19939b71')
-    def test_admin_fake_action(self):
-        self.assertRaises(exceptions.CommandFailed,
-                          self.keystone,
-                          'this-does-not-exist')
-
-    @test.idempotent_id('a1100917-c7c5-4887-a4da-f7d7f13194f5')
-    def test_admin_catalog_list(self):
-        out = self.keystone('catalog')
-        catalog = self.parser.details_multiple(out, with_label=True)
-        for svc in catalog:
-            if svc.get('__label'):
-                self.assertTrue(svc['__label'].startswith('Service:'),
-                                msg=('Invalid beginning of service block: '
-                                     '%s' % svc['__label']))
-            # check that region and publicURL exists. One might also
-            # check for adminURL and internalURL. id seems to be optional
-            # and is missing in the catalog backend
-            self.assertIn('publicURL', svc.keys())
-            self.assertIn('region', svc.keys())
-
-    @test.idempotent_id('35c73506-eab6-4abc-956e-42da90aba8ec')
-    def test_admin_endpoint_list(self):
-        out = self.keystone('endpoint-list')
-        endpoints = self.parser.listing(out)
-        self.assertTableStruct(endpoints, [
-            'id', 'region', 'publicurl', 'internalurl',
-            'adminurl', 'service_id'])
-
-    @test.idempotent_id('f17cb155-bd16-4f32-9956-1b073752fc07')
-    def test_admin_endpoint_service_match(self):
-        endpoints = self.parser.listing(self.keystone('endpoint-list'))
-        services = self.parser.listing(self.keystone('service-list'))
-        svc_by_id = {}
-        for svc in services:
-            svc_by_id[svc['id']] = svc
-        for endpoint in endpoints:
-            self.assertIn(endpoint['service_id'], svc_by_id)
-
-    @test.idempotent_id('be7176f2-9c34-4d84-bb7d-b4bc85d06a33')
-    def test_admin_role_list(self):
-        roles = self.parser.listing(self.keystone('role-list'))
-        self.assertTableStruct(roles, ['id', 'name'])
-
-    @test.idempotent_id('96a4de8d-aa9e-4ca5-89f0-985809eccd66')
-    def test_admin_service_list(self):
-        services = self.parser.listing(self.keystone('service-list'))
-        self.assertTableStruct(services, ['id', 'name', 'type', 'description'])
-
-    @test.idempotent_id('edb45480-0f7b-49eb-8f95-7562cbba96da')
-    def test_admin_tenant_list(self):
-        tenants = self.parser.listing(self.keystone('tenant-list'))
-        self.assertTableStruct(tenants, ['id', 'name', 'enabled'])
-
-    @test.idempotent_id('25a2753d-6bd1-40c0-addc-32864b00cb2d')
-    def test_admin_user_list(self):
-        users = self.parser.listing(self.keystone('user-list'))
-        self.assertTableStruct(users, [
-            'id', 'name', 'enabled', 'email'])
-
-    @test.idempotent_id('f92bf8d4-b27b-47c9-8450-e27c57758de9')
-    def test_admin_user_role_list(self):
-        user_roles = self.parser.listing(self.keystone('user-role-list'))
-        self.assertTableStruct(user_roles, [
-            'id', 'name', 'user_id', 'tenant_id'])
-
-    @test.idempotent_id('14a2687b-3ce1-404c-9f78-a0e28e2f8f7b')
-    def test_admin_discover(self):
-        discovered = self.keystone('discover')
-        self.assertIn('Keystone found at http', discovered)
-        self.assertIn('supports version', discovered)
-
-    @test.idempotent_id('9a567c8c-3787-4e5f-9c30-bed55f2b75c0')
-    def test_admin_help(self):
-        help_text = self.keystone('help')
-        lines = help_text.split('\n')
-        self.assertFirstLineStartsWith(lines, 'usage: keystone')
-
-        commands = []
-        cmds_start = lines.index('Positional arguments:')
-        cmds_end = lines.index('Optional arguments:')
-        command_pattern = re.compile('^ {4}([a-z0-9\-\_]+)')
-        for line in lines[cmds_start:cmds_end]:
-            match = command_pattern.match(line)
-            if match:
-                commands.append(match.group(1))
-        commands = set(commands)
-        wanted_commands = set(('catalog', 'endpoint-list', 'help',
-                               'token-get', 'discover', 'bootstrap'))
-        self.assertFalse(wanted_commands - commands)
-
-    @test.idempotent_id('a7b9e1fe-db31-4846-82c5-52a7aa9863c3')
-    def test_admin_bashcompletion(self):
-        self.keystone('bash-completion')
-
-    @test.idempotent_id('5328c681-df8b-4874-a65c-8fa278f0af8f')
-    def test_admin_ec2_credentials_list(self):
-        creds = self.keystone('ec2-credentials-list')
-        creds = self.parser.listing(creds)
-        self.assertTableStruct(creds, ['tenant', 'access', 'secret'])
-
-    # Optional arguments:
-
-    @test.idempotent_id('af95e809-ce95-4505-8627-170d803b1d13')
-    def test_admin_version(self):
-        self.keystone('', flags='--version')
-
-    @test.idempotent_id('9e26521f-7bfa-4d8e-9d61-fd364f0c20c0')
-    def test_admin_debug_list(self):
-        self.keystone('catalog', flags='--debug')
-
-    @test.idempotent_id('097b3a52-725f-4df7-84b6-277a2b6f6e38')
-    def test_admin_timeout(self):
-        self.keystone('catalog', flags='--timeout %d' % CONF.cli.timeout)
diff --git a/tempest/clients.py b/tempest/clients.py
index 7a41f32..e5f41eb 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -74,8 +74,9 @@
     DatabaseLimitsClientJSON
 from tempest.services.database.json.versions_client import \
     DatabaseVersionsClientJSON
-from tempest.services.identity.json.identity_client import IdentityClientJSON
-from tempest.services.identity.json.token_client import TokenClientJSON
+from tempest.services.identity.v2.json.identity_client import \
+    IdentityClientJSON
+from tempest.services.identity.v2.json.token_client import TokenClientJSON
 from tempest.services.identity.v3.json.credentials_client import \
     CredentialsClientJSON
 from tempest.services.identity.v3.json.endpoints_client import \
@@ -194,8 +195,22 @@
                 endpoint_type=CONF.telemetry.endpoint_type,
                 **self.default_params_with_timeout_values)
         if CONF.service_available.glance:
-            self.image_client = ImageClientJSON(self.auth_provider)
-            self.image_client_v2 = ImageClientV2JSON(self.auth_provider)
+            self.image_client = ImageClientJSON(
+                self.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.default_params)
+            self.image_client_v2 = ImageClientV2JSON(
+                self.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.default_params)
         self.orchestration_client = OrchestrationClient(
             self.auth_provider,
             CONF.orchestration.catalog_type,
@@ -239,7 +254,11 @@
             SecurityGroupDefaultRulesClientJSON(self.auth_provider, **params))
         self.certificates_client = CertificatesClientJSON(self.auth_provider,
                                                           **params)
-        self.servers_client = ServersClientJSON(self.auth_provider, **params)
+        self.servers_client = ServersClientJSON(
+            self.auth_provider,
+            enable_instance_password=CONF.compute_feature_enabled
+                .enable_instance_password,
+            **params)
         self.limits_client = LimitsClientJSON(self.auth_provider, **params)
         self.images_client = ImagesClientJSON(self.auth_provider, **params)
         self.keypairs_client = KeyPairsClientJSON(self.auth_provider, **params)
@@ -282,7 +301,8 @@
             'build_timeout': CONF.volume.build_timeout
         })
         self.volumes_extensions_client = VolumesExtensionsClientJSON(
-            self.auth_provider, **params_volume)
+            self.auth_provider, default_volume_size=CONF.volume.volume_size,
+            **params_volume)
 
     def _set_database_clients(self):
         self.database_flavors_client = DatabaseFlavorsClientJSON(
diff --git a/tempest/cmd/javelin.py b/tempest/cmd/javelin.py
index aff4087..4c09bd2 100755
--- a/tempest/cmd/javelin.py
+++ b/tempest/cmd/javelin.py
@@ -120,7 +120,7 @@
 from tempest.services.compute.json import flavors_client
 from tempest.services.compute.json import security_groups_client
 from tempest.services.compute.json import servers_client
-from tempest.services.identity.json import identity_client
+from tempest.services.identity.v2.json import identity_client
 from tempest.services.image.v2.json import image_client
 from tempest.services.network.json import network_client
 from tempest.services.object_storage import container_client
@@ -200,7 +200,14 @@
                                                   **object_storage_params)
         self.containers = container_client.ContainerClient(
             _auth, **object_storage_params)
-        self.images = image_client.ImageClientV2JSON(_auth)
+        self.images = image_client.ImageClientV2JSON(
+            _auth,
+            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,
+            **default_params)
         self.telemetry = telemetry_client.TelemetryClientJSON(
             _auth,
             CONF.telemetry.catalog_type,
diff --git a/tempest/common/accounts.py b/tempest/common/accounts.py
index 9ecf596..89de69b 100644
--- a/tempest/common/accounts.py
+++ b/tempest/common/accounts.py
@@ -37,6 +37,7 @@
 
     def __init__(self, name):
         super(Accounts, self).__init__(name)
+        self.name = name
         if os.path.isfile(CONF.auth.test_accounts_file):
             accounts = read_accounts_yaml(CONF.auth.test_accounts_file)
             self.use_default_creds = False
@@ -48,12 +49,46 @@
         self.isolated_creds = {}
 
     @classmethod
+    def _append_role(cls, role, account_hash, hash_dict):
+        if role in hash_dict['roles']:
+            hash_dict['roles'][role].append(account_hash)
+        else:
+            hash_dict['roles'][role] = [account_hash]
+        return hash_dict
+
+    @classmethod
     def get_hash_dict(cls, accounts):
-        hash_dict = {}
+        hash_dict = {'roles': {}, 'creds': {}}
+        # Loop over the accounts read from the yaml file
         for account in accounts:
+            roles = []
+            types = []
+            if 'roles' in account:
+                roles = account.pop('roles')
+            if 'types' in account:
+                types = account.pop('types')
             temp_hash = hashlib.md5()
             temp_hash.update(str(account))
-            hash_dict[temp_hash.hexdigest()] = account
+            temp_hash_key = temp_hash.hexdigest()
+            hash_dict['creds'][temp_hash_key] = account
+            for role in roles:
+                hash_dict = cls._append_role(role, temp_hash_key,
+                                             hash_dict)
+            # If types are set for the account append the matching role
+            # subdict with the hash
+            for type in types:
+                if type == 'admin':
+                    hash_dict = cls._append_role(CONF.identity.admin_role,
+                                                 temp_hash_key, hash_dict)
+                elif type == 'operator':
+                    hash_dict = cls._append_role(
+                        CONF.object_storage.operator_role, temp_hash_key,
+                        hash_dict)
+                elif type == 'reseller_admin':
+                    hash_dict = cls._append_role(
+                        CONF.object_storage.reseller_admin_role,
+                        temp_hash_key,
+                        hash_dict)
         return hash_dict
 
     def is_multi_user(self):
@@ -62,7 +97,7 @@
             raise exceptions.InvalidConfiguration(
                 "Account file %s doesn't exist" % CONF.auth.test_accounts_file)
         else:
-            return len(self.hash_dict) > 1
+            return len(self.hash_dict['creds']) > 1
 
     def is_multi_tenant(self):
         return self.is_multi_user()
@@ -70,30 +105,74 @@
     def _create_hash_file(self, hash_string):
         path = os.path.join(os.path.join(self.accounts_dir, hash_string))
         if not os.path.isfile(path):
-            open(path, 'w').close()
+            with open(path, 'w') as fd:
+                fd.write(self.name)
             return True
         return False
 
     @lockutils.synchronized('test_accounts_io', external=True)
     def _get_free_hash(self, hashes):
+        # Cast as a list because in some edge cases a set will be passed in
+        hashes = list(hashes)
         if not os.path.isdir(self.accounts_dir):
             os.mkdir(self.accounts_dir)
             # Create File from first hash (since none are in use)
             self._create_hash_file(hashes[0])
             return hashes[0]
+        names = []
         for _hash in hashes:
             res = self._create_hash_file(_hash)
             if res:
                 return _hash
-        msg = 'Insufficient number of users provided'
+            else:
+                path = os.path.join(os.path.join(self.accounts_dir,
+                                                 _hash))
+                with open(path, 'r') as fd:
+                    names.append(fd.read())
+        msg = ('Insufficient number of users provided. %s have allocated all '
+               'the credentials for this allocation request' % ','.join(names))
         raise exceptions.InvalidConfiguration(msg)
 
-    def _get_creds(self):
+    def _get_match_hash_list(self, roles=None):
+        hashes = []
+        if roles:
+            # Loop over all the creds for each role in the subdict and generate
+            # a list of cred lists for each role
+            for role in roles:
+                temp_hashes = self.hash_dict['roles'].get(role, None)
+                if not temp_hashes:
+                    raise exceptions.InvalidConfiguration(
+                        "No credentials with role: %s specified in the "
+                        "accounts ""file" % role)
+                hashes.append(temp_hashes)
+            # Take the list of lists and do a boolean and between each list to
+            # find the creds which fall under all the specified roles
+            temp_list = set(hashes[0])
+            for hash_list in hashes[1:]:
+                temp_list = temp_list & set(hash_list)
+            hashes = temp_list
+        else:
+            hashes = self.hash_dict['creds'].keys()
+        # NOTE(mtreinish): admin is a special case because of the increased
+        # privlege set which could potentially cause issues on tests where that
+        # is not expected. So unless the admin role isn't specified do not
+        # allocate admin.
+        admin_hashes = self.hash_dict['roles'].get(CONF.identity.admin_role,
+                                                   None)
+        if ((not roles or CONF.identity.admin_role not in roles) and
+                admin_hashes):
+            useable_hashes = [x for x in hashes if x not in admin_hashes]
+        else:
+            useable_hashes = hashes
+        return useable_hashes
+
+    def _get_creds(self, roles=None):
         if self.use_default_creds:
             raise exceptions.InvalidConfiguration(
                 "Account file %s doesn't exist" % CONF.auth.test_accounts_file)
-        free_hash = self._get_free_hash(self.hash_dict.keys())
-        return self.hash_dict[free_hash]
+        useable_hashes = self._get_match_hash_list(roles)
+        free_hash = self._get_free_hash(useable_hashes)
+        return self.hash_dict['creds'][free_hash]
 
     @lockutils.synchronized('test_accounts_io', external=True)
     def remove_hash(self, hash_string):
@@ -107,10 +186,10 @@
                 os.rmdir(self.accounts_dir)
 
     def get_hash(self, creds):
-        for _hash in self.hash_dict:
-            # Comparing on the attributes that were read from the YAML
-            if all([getattr(creds, k) == self.hash_dict[_hash][k] for k in
-                    creds.get_init_attributes()]):
+        for _hash in self.hash_dict['creds']:
+            # Comparing on the attributes that are expected in the YAML
+            if all([getattr(creds, k) == self.hash_dict['creds'][_hash][k] for
+                   k in creds.get_init_attributes()]):
                 return _hash
         raise AttributeError('Invalid credentials %s' % creds)
 
@@ -134,14 +213,33 @@
         self.isolated_creds['alt'] = alt_credential
         return alt_credential
 
+    def get_creds_by_roles(self, roles, force_new=False):
+        roles = list(set(roles))
+        exist_creds = self.isolated_creds.get(str(roles), None)
+        # The force kwarg is used to allocate an additional set of creds with
+        # the same role list. The index used for the previously allocation
+        # in the isolated_creds dict will be moved.
+        if exist_creds and not force_new:
+            return exist_creds
+        elif exist_creds and force_new:
+            new_index = str(roles) + '-' + str(len(self.isolated_creds))
+            self.isolated_creds[new_index] = exist_creds
+        creds = self._get_creds(roles=roles)
+        role_credential = cred_provider.get_credentials(**creds)
+        self.isolated_creds[str(roles)] = role_credential
+        return role_credential
+
     def clear_isolated_creds(self):
         for creds in self.isolated_creds.values():
             self.remove_credentials(creds)
 
     def get_admin_creds(self):
-        msg = ('If admin credentials are available tenant_isolation should be'
-               ' used instead')
-        raise NotImplementedError(msg)
+        return self.get_creds_by_roles([CONF.identity.admin_role])
+
+    def admin_available(self):
+        if not self.hash_dict['roles'].get(CONF.identity.admin_role):
+            return False
+        return True
 
 
 class NotLockingAccounts(Accounts):
@@ -164,7 +262,7 @@
                 raise exceptions.InvalidConfiguration(msg)
         else:
             # TODO(andreaf) Add a uniqueness check here
-            return len(self.hash_dict) > 1
+            return len(self.hash_dict['creds']) > 1
 
     def is_multi_user(self):
         return self._unique_creds('username')
@@ -172,16 +270,17 @@
     def is_multi_tenant(self):
         return self._unique_creds('tenant_id')
 
-    def get_creds(self, id):
+    def get_creds(self, id, roles=None):
         try:
+            hashes = self._get_match_hash_list(roles)
             # No need to sort the dict as within the same python process
             # the HASH seed won't change, so subsequent calls to keys()
             # will return the same result
-            _hash = self.hash_dict.keys()[id]
+            _hash = hashes[id]
         except IndexError:
             msg = 'Insufficient number of users provided'
             raise exceptions.InvalidConfiguration(msg)
-        return self.hash_dict[_hash]
+        return self.hash_dict['creds'][_hash]
 
     def get_primary_creds(self):
         if self.isolated_creds.get('primary'):
@@ -211,5 +310,35 @@
         self.isolated_creds = {}
 
     def get_admin_creds(self):
-        return cred_provider.get_configured_credentials(
-            "identity_admin", fill_in=False)
+        if not self.use_default_creds:
+            return self.get_creds_by_roles([CONF.identity.admin_role])
+        else:
+            creds = cred_provider.get_configured_credentials(
+                "identity_admin", fill_in=False)
+            self.isolated_creds['admin'] = creds
+            return creds
+
+    def get_creds_by_roles(self, roles, force_new=False):
+        roles = list(set(roles))
+        exist_creds = self.isolated_creds.get(str(roles), None)
+        index = 0
+        if exist_creds and not force_new:
+            return exist_creds
+        elif exist_creds and force_new:
+            new_index = str(roles) + '-' + str(len(self.isolated_creds))
+            self.isolated_creds[new_index] = exist_creds
+            # Figure out how many existing creds for this roles set are present
+            # use this as the index the returning hash list to ensure separate
+            # creds are returned with force_new being True
+            for creds_names in self.isolated_creds:
+                if str(roles) in creds_names:
+                    index = index + 1
+        if not self.use_default_creds:
+            creds = self.get_creds(index, roles=roles)
+            role_credential = cred_provider.get_credentials(**creds)
+            self.isolated_creds[str(roles)] = role_credential
+        else:
+            msg = "Default credentials can not be used with specifying "\
+                  "credentials by roles"
+            raise exceptions.InvalidConfiguration(msg)
+        return role_credential
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index 033410e..c22dc1f 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -113,3 +113,7 @@
     @abc.abstractmethod
     def is_multi_tenant(self):
         return
+
+    @abc.abstractmethod
+    def get_creds_by_roles(self, roles, force_new=False):
+        return
diff --git a/tempest/common/credentials.py b/tempest/common/credentials.py
index 40761c8..3794b66 100644
--- a/tempest/common/credentials.py
+++ b/tempest/common/credentials.py
@@ -11,6 +11,8 @@
 #    See the License for the specific language governing permissions and
 #    limitations under the License.
 
+import os
+
 from tempest.common import accounts
 from tempest.common import cred_provider
 from tempest.common import isolated_creds
@@ -46,24 +48,17 @@
 # creds area vailable.
 def is_admin_available():
     is_admin = True
-    # In the case of a pre-provisioned account, if even if creds were
-    # configured, the admin credentials won't be available
-    if (CONF.auth.locking_credentials_provider and
-        not CONF.auth.allow_tenant_isolation):
-        is_admin = False
+    # If tenant isolation is enabled admin will be available
+    if CONF.auth.allow_tenant_isolation:
+        return is_admin
+    # Check whether test accounts file has the admin specified or not
+    elif os.path.isfile(CONF.auth.test_accounts_file):
+        check_accounts = accounts.Accounts(name='check_admin')
+        if not check_accounts.admin_available():
+            is_admin = False
     else:
         try:
             cred_provider.get_configured_credentials('identity_admin')
-        # NOTE(mtreinish) This should never be caught because of the if above.
-        # NotImplementedError is only raised if admin credentials are requested
-        # and the locking test accounts cred provider is being used.
-        except NotImplementedError:
-            is_admin = False
-        # NOTE(mtreinish): This will be raised by the non-locking accounts
-        # provider if there aren't admin credentials provided in the config
-        # file. This exception originates from the auth call to get configured
-        # credentials
         except exceptions.InvalidConfiguration:
             is_admin = False
-
     return is_admin
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index 3eed689..b0531fd 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -90,7 +90,7 @@
             self._cleanup_default_secgroup(tenant)
         self.identity_admin_client.delete_tenant(tenant)
 
-    def _create_creds(self, suffix="", admin=False):
+    def _create_creds(self, suffix="", admin=False, roles=None):
         """Create random credentials under the following schema.
 
         If the name contains a '.' is the full class path of something, and
@@ -121,8 +121,13 @@
             self._assign_user_role(tenant, user, swift_operator_role)
         if admin:
             self._assign_user_role(tenant, user, CONF.identity.admin_role)
-        for role in CONF.auth.tempest_roles:
-            self._assign_user_role(tenant, user, role)
+        # Add roles specified in config file
+        for conf_role in CONF.auth.tempest_roles:
+            self._assign_user_role(tenant, user, conf_role)
+        # Add roles requested by caller
+        if roles:
+            for role in roles:
+                self._assign_user_role(tenant, user, role)
         return self._get_credentials(user, tenant)
 
     def _get_credentials(self, user, tenant):
@@ -247,12 +252,15 @@
         return self.isolated_net_resources.get('alt')[2]
 
     def get_credentials(self, credential_type):
-        if self.isolated_creds.get(credential_type):
-            credentials = self.isolated_creds[credential_type]
+        if self.isolated_creds.get(str(credential_type)):
+            credentials = self.isolated_creds[str(credential_type)]
         else:
-            is_admin = (credential_type == 'admin')
-            credentials = self._create_creds(admin=is_admin)
-            self.isolated_creds[credential_type] = credentials
+            if credential_type in ['primary', 'alt', 'admin']:
+                is_admin = (credential_type == 'admin')
+                credentials = self._create_creds(admin=is_admin)
+            else:
+                credentials = self._create_creds(roles=credential_type)
+            self.isolated_creds[str(credential_type)] = credentials
             # Maintained until tests are ported
             LOG.info("Acquired isolated creds:\n credentials: %s"
                      % credentials)
@@ -260,7 +268,7 @@
                 not CONF.baremetal.driver_enabled):
                 network, subnet, router = self._create_network_resources(
                     credentials.tenant_id)
-                self.isolated_net_resources[credential_type] = (
+                self.isolated_net_resources[str(credential_type)] = (
                     network, subnet, router,)
                 LOG.info("Created isolated network resources for : \n"
                          + " credentials: %s" % credentials)
@@ -275,6 +283,26 @@
     def get_alt_creds(self):
         return self.get_credentials('alt')
 
+    def get_creds_by_roles(self, roles, force_new=False):
+        roles = list(set(roles))
+        # The roles list as a str will become the index as the dict key for
+        # the created credentials set in the isolated_creds dict.
+        exist_creds = self.isolated_creds.get(str(roles))
+        # If force_new flag is True 2 cred sets with the same roles are needed
+        # handle this by creating a separate index for old one to store it
+        # separately for cleanup
+        if exist_creds and force_new:
+            new_index = str(roles) + '-' + str(len(self.isolated_creds))
+            self.isolated_creds[new_index] = exist_creds
+            del self.isolated_creds[str(roles)]
+            # Handle isolated neutron resouces if they exist too
+            if CONF.service_available.neutron:
+                exist_net = self.isolated_net_resources.get(str(roles))
+                if exist_net:
+                    self.isolated_net_resources[new_index] = exist_net
+                    del self.isolated_net_resources[str(roles)]
+        return self.get_credentials(roles)
+
     def _clear_isolated_router(self, router_id, router_name):
         net_client = self.network_admin_client
         try:
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 6e61c55..1f1414f 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -23,7 +23,7 @@
 CONF = config.CONF
 
 
-class RemoteClient():
+class RemoteClient(object):
 
     # NOTE(afazekas): It should always get an address instead of server
     def __init__(self, server, username, password=None, pkey=None):
@@ -163,4 +163,4 @@
                                                   % dhcp_client)
         if dhcp_client == 'udhcpc' and not fixed_ip:
             raise ValueError("need to set 'fixed_ip' for udhcpc client")
-        return getattr(self, '_renew_lease_' + dhcp_client)(fixed_ip=fixed_ip)
\ No newline at end of file
+        return getattr(self, '_renew_lease_' + dhcp_client)(fixed_ip=fixed_ip)
diff --git a/tempest/config.py b/tempest/config.py
index 4588b20..a66aa9b 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -40,7 +40,7 @@
                help="Path to the yaml file that contains the list of "
                     "credentials to use for running tests"),
     cfg.BoolOpt('allow_tenant_isolation',
-                default=False,
+                default=True,
                 help="Allows test cases to create/destroy tenants and "
                      "users. This option requires that OpenStack Identity "
                      "API admin credentials are known. If false, isolated "
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 968c8ca..f24a22a 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -207,7 +207,7 @@
         self.assertEqual(server['name'], name)
         return server
 
-    def create_volume(self, size=1, name=None, snapshot_id=None,
+    def create_volume(self, size=None, name=None, snapshot_id=None,
                       imageRef=None, volume_type=None, wait_on_delete=True):
         if name is None:
             name = data_utils.rand_name(self.__class__.__name__)
diff --git a/tempest/scenario/test_encrypted_cinder_volumes.py b/tempest/scenario/test_encrypted_cinder_volumes.py
index 1069908..eed3d0b 100644
--- a/tempest/scenario/test_encrypted_cinder_volumes.py
+++ b/tempest/scenario/test_encrypted_cinder_volumes.py
@@ -62,4 +62,4 @@
         self.launch_instance()
         self.create_encrypted_volume('nova.volume.encryptors.'
                                      'cryptsetup.CryptsetupEncryptor')
-        self.attach_detach_volume()
\ No newline at end of file
+        self.attach_detach_volume()
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index f29fecf..4199b2c 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -435,13 +435,15 @@
             "admin_state_up of router to True")
 
     @test.idempotent_id('d8bb918e-e2df-48b2-97cd-b73c95450980')
+    @testtools.skipIf(CONF.baremetal.driver_enabled,
+                      'network isolation not available for baremetal nodes')
     @testtools.skipUnless(CONF.scenario.dhcp_client,
                           "DHCP client is not available.")
     @test.attr(type='smoke')
     @test.services('compute', 'network')
     def test_subnet_details(self):
         """Tests that subnet's extra configuration details are affecting
-        the VMs
+        the VMs. This test relies on non-shared, isolated tenant networks.
 
          NOTE: Neutron subnets push data to servers via dhcp-agent, so any
          update in subnet requires server to actively renew its DHCP lease.
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 979953f..d5d2d77 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -12,6 +12,7 @@
 #    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 functools
 import netaddr
 from tempest import config
 from tempest.openstack.common import log as logging
@@ -118,14 +119,28 @@
         ssh1, srv1 = self.prepare_server()
         ssh2, srv2 = self.prepare_server()
 
+        def guest_has_address(ssh, addr):
+            return addr in ssh.get_ip_list()
+
+        srv1_v6_addr_assigned = functools.partial(
+            guest_has_address, ssh1, srv1['accessIPv6'])
+        srv2_v6_addr_assigned = functools.partial(
+            guest_has_address, ssh2, srv2['accessIPv6'])
+
         result = ssh1.get_ip_list()
         self.assertIn(srv1['accessIPv4'], result)
         # v6 should be configured since the image supports it
-        self.assertIn(srv1['accessIPv6'], result)
+        # It can take time for ipv6 automatic address to get assigned
+        self.assertTrue(
+            test.call_until_true(srv1_v6_addr_assigned,
+                                 CONF.compute.ping_timeout, 1))
         result = ssh2.get_ip_list()
         self.assertIn(srv2['accessIPv4'], result)
         # v6 should be configured since the image supports it
-        self.assertIn(srv2['accessIPv6'], result)
+        # It can take time for ipv6 automatic address to get assigned
+        self.assertTrue(
+            test.call_until_true(srv2_v6_addr_assigned,
+                                 CONF.compute.ping_timeout, 1))
         result = ssh1.ping_host(srv2['accessIPv4'])
         self.assertIn('0% packet loss', result)
         result = ssh2.ping_host(srv1['accessIPv4'])
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index f3c1f85..4fbadb0 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -91,7 +91,7 @@
             its own router connected to the public network
     """
 
-    class TenantProperties():
+    class TenantProperties(object):
         """
         helper class to save tenant details
             id
diff --git a/tempest/scenario/test_swift_telemetry_middleware.py b/tempest/scenario/test_swift_telemetry_middleware.py
index 2427f0f..8305641 100644
--- a/tempest/scenario/test_swift_telemetry_middleware.py
+++ b/tempest/scenario/test_swift_telemetry_middleware.py
@@ -1,7 +1,5 @@
-#
 # Copyright 2014 Red Hat
 #
-# Author: Chris Dent <chdent@redhat.com>
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index b01fbf1..bd4fd0e 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -24,14 +24,17 @@
 from tempest.api_schema.response.compute.v2 import servers as schema
 from tempest.common import service_client
 from tempest.common import waiters
-from tempest import config
 from tempest import exceptions
 
-CONF = config.CONF
-
 
 class ServersClientJSON(service_client.ServiceClient):
 
+    def __init__(self, auth_provider, service, region,
+                 enable_instance_password=True, **kwargs):
+        super(ServersClientJSON, self).__init__(
+            auth_provider, service, region, **kwargs)
+        self.enable_instance_password = enable_instance_password
+
     def create_server(self, name, image_ref, flavor_ref, **kwargs):
         """
         Creates an instance of a server.
@@ -93,7 +96,7 @@
         # with return reservation id set True
         if 'reservation_id' in body:
             return service_client.ResponseBody(resp, body)
-        if CONF.compute_feature_enabled.enable_instance_password:
+        if self.enable_instance_password:
             create_schema = schema.create_server_with_admin_pass
         else:
             create_schema = schema.create_server
@@ -275,7 +278,7 @@
         if 'disk_config' in kwargs:
             kwargs['OS-DCF:diskConfig'] = kwargs['disk_config']
             del kwargs['disk_config']
-        if CONF.compute_feature_enabled.enable_instance_password:
+        if self.enable_instance_password:
             rebuild_schema = schema.rebuild_server_with_admin_pass
         else:
             rebuild_schema = schema.rebuild_server
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index a9cada8..b2d5cf9 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -26,6 +26,12 @@
 
 class VolumesExtensionsClientJSON(service_client.ServiceClient):
 
+    def __init__(self, auth_provider, service, region,
+                 default_volume_size=1, **kwargs):
+        super(VolumesExtensionsClientJSON, self).__init__(
+            auth_provider, service, region, **kwargs)
+        self.default_volume_size = default_volume_size
+
     def list_volumes(self, params=None):
         """List all the volumes created."""
         url = 'os-volumes'
@@ -56,7 +62,7 @@
         self.validate_response(schema.create_get_volume, resp, body)
         return service_client.ResponseBody(resp, body['volume'])
 
-    def create_volume(self, size, **kwargs):
+    def create_volume(self, size=None, **kwargs):
         """
         Creates a new Volume.
         size(Required): Size of volume in GB.
@@ -64,6 +70,8 @@
         display_name: Optional Volume Name.
         metadata: A dictionary of values to be used as metadata.
         """
+        if size is None:
+            size = self.default_volume_size
         post_body = {
             'size': size
         }
diff --git a/tempest/services/identity/json/__init__.py b/tempest/services/identity/v2/__init__.py
similarity index 100%
copy from tempest/services/identity/json/__init__.py
copy to tempest/services/identity/v2/__init__.py
diff --git a/tempest/services/identity/json/__init__.py b/tempest/services/identity/v2/json/__init__.py
similarity index 100%
rename from tempest/services/identity/json/__init__.py
rename to tempest/services/identity/v2/json/__init__.py
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/v2/json/identity_client.py
similarity index 100%
rename from tempest/services/identity/json/identity_client.py
rename to tempest/services/identity/v2/json/identity_client.py
diff --git a/tempest/services/identity/json/token_client.py b/tempest/services/identity/v2/json/token_client.py
similarity index 100%
rename from tempest/services/identity/json/token_client.py
rename to tempest/services/identity/v2/json/token_client.py
diff --git a/tempest/services/image/v1/json/image_client.py b/tempest/services/image/v1/json/image_client.py
index 4ea710f..50f75b3 100644
--- a/tempest/services/image/v1/json/image_client.py
+++ b/tempest/services/image/v1/json/image_client.py
@@ -25,26 +25,32 @@
 from tempest.common import glance_http
 from tempest.common import service_client
 from tempest.common.utils import misc as misc_utils
-from tempest import config
 from tempest import exceptions
 from tempest.openstack.common import log as logging
 
-CONF = config.CONF
-
 LOG = logging.getLogger(__name__)
 
 
 class ImageClientJSON(service_client.ServiceClient):
 
-    def __init__(self, auth_provider):
+    def __init__(self, auth_provider, catalog_type, region, endpoint_type=None,
+                 build_interval=None, build_timeout=None,
+                 disable_ssl_certificate_validation=None,
+                 ca_certs=None, **kwargs):
         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)
+            catalog_type,
+            region,
+            endpoint_type=endpoint_type,
+            build_interval=build_interval,
+            build_timeout=build_timeout,
+            disable_ssl_certificate_validation=(
+                disable_ssl_certificate_validation),
+            ca_certs=ca_certs,
+            **kwargs)
         self._http = None
+        self.dscv = disable_ssl_certificate_validation
+        self.ca_certs = ca_certs
 
     def _image_meta_from_headers(self, headers):
         meta = {'properties': {}}
@@ -112,11 +118,10 @@
             return None
 
     def _get_http(self):
-        dscv = CONF.identity.disable_ssl_certificate_validation
-        ca_certs = CONF.identity.ca_certificates_file
         return glance_http.HTTPClient(auth_provider=self.auth_provider,
                                       filters=self.filters,
-                                      insecure=dscv, ca_certs=ca_certs)
+                                      insecure=self.dscv,
+                                      ca_certs=self.ca_certs)
 
     def _create_with_data(self, headers, data):
         resp, body_iter = self.http.raw_request('POST', '/v1/images',
@@ -138,8 +143,7 @@
     @property
     def http(self):
         if self._http is None:
-            if CONF.service_available.glance:
-                self._http = self._get_http()
+            self._http = self._get_http()
         return self._http
 
     def create_image(self, name, container_format, disk_format, **kwargs):
diff --git a/tempest/services/image/v2/json/image_client.py b/tempest/services/image/v2/json/image_client.py
index 50f273c..e55a824 100644
--- a/tempest/services/image/v2/json/image_client.py
+++ b/tempest/services/image/v2/json/image_client.py
@@ -21,29 +21,34 @@
 
 from tempest.common import glance_http
 from tempest.common import service_client
-from tempest import config
-
-CONF = config.CONF
 
 
 class ImageClientV2JSON(service_client.ServiceClient):
 
-    def __init__(self, auth_provider):
+    def __init__(self, auth_provider, catalog_type, region, endpoint_type=None,
+                 build_interval=None, build_timeout=None,
+                 disable_ssl_certificate_validation=None, ca_certs=None,
+                 **kwargs):
         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)
+            catalog_type,
+            region,
+            endpoint_type=endpoint_type,
+            build_interval=build_interval,
+            build_timeout=build_timeout,
+            disable_ssl_certificate_validation=(
+                disable_ssl_certificate_validation),
+            ca_certs=ca_certs,
+            **kwargs)
         self._http = None
+        self.dscv = disable_ssl_certificate_validation
+        self.ca_certs = ca_certs
 
     def _get_http(self):
-        dscv = CONF.identity.disable_ssl_certificate_validation
-        ca_certs = CONF.identity.ca_certificates_file
         return glance_http.HTTPClient(auth_provider=self.auth_provider,
                                       filters=self.filters,
-                                      insecure=dscv, ca_certs=ca_certs)
+                                      insecure=self.dscv,
+                                      ca_certs=self.ca_certs)
 
     def _validate_schema(self, body, type='image'):
         if type in ['image', 'images']:
@@ -56,8 +61,7 @@
     @property
     def http(self):
         if self._http is None:
-            if CONF.service_available.glance:
-                self._http = self._get_http()
+            self._http = self._get_http()
         return self._http
 
     def update_image(self, image_id, patch):
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index ba069e8..87f1332 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -262,9 +262,8 @@
         # expecting response in form
         # {'resources': [ res1, res2] } => when pagination disabled
         # {'resources': [..], 'resources_links': {}} => if pagination enabled
-        pagination_suffix = "_links"
         for k in res.keys():
-            if k[-len(pagination_suffix):] == pagination_suffix:
+            if k.endswith("_links"):
                 continue
             return res[k]
 
diff --git a/tempest/services/volume/json/admin/volume_quotas_client.py b/tempest/services/volume/json/admin/volume_quotas_client.py
index 19d320f..616f8e4 100644
--- a/tempest/services/volume/json/admin/volume_quotas_client.py
+++ b/tempest/services/volume/json/admin/volume_quotas_client.py
@@ -1,7 +1,5 @@
 # Copyright (C) 2014 eNovance SAS <licensing@enovance.com>
 #
-# Author: Sylvain Baubeau <sylvain.baubeau@enovance.com>
-#
 #    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
diff --git a/tempest/stress/actions/volume_attach_delete.py b/tempest/stress/actions/volume_attach_delete.py
index 2e1d623..a5e393f 100644
--- a/tempest/stress/actions/volume_attach_delete.py
+++ b/tempest/stress/actions/volume_attach_delete.py
@@ -29,7 +29,6 @@
         name = data_utils.rand_name("volume")
         self.logger.info("creating volume: %s" % name)
         volume = self.manager.volumes_client.create_volume(
-            size=1,
             display_name=name)
         self.manager.volumes_client.wait_for_volume_status(volume['id'],
                                                            'available')
diff --git a/tempest/stress/actions/volume_attach_verify.py b/tempest/stress/actions/volume_attach_verify.py
index c013af3..a6abd82 100644
--- a/tempest/stress/actions/volume_attach_verify.py
+++ b/tempest/stress/actions/volume_attach_verify.py
@@ -78,7 +78,6 @@
         self.logger.info("creating volume: %s" % name)
         volumes_client = self.manager.volumes_client
         self.volume = volumes_client.create_volume(
-            size=1,
             display_name=name)
         volumes_client.wait_for_volume_status(self.volume['id'],
                                               'available')
diff --git a/tempest/stress/actions/volume_create_delete.py b/tempest/stress/actions/volume_create_delete.py
index 93402d9..4870055 100644
--- a/tempest/stress/actions/volume_create_delete.py
+++ b/tempest/stress/actions/volume_create_delete.py
@@ -20,8 +20,7 @@
         name = data_utils.rand_name("volume")
         self.logger.info("creating %s" % name)
         volumes_client = self.manager.volumes_client
-        volume = volumes_client.create_volume(size=1,
-                                              display_name=name)
+        volume = volumes_client.create_volume(display_name=name)
         vol_id = volume['id']
         volumes_client.wait_for_volume_status(vol_id, 'available')
         self.logger.info("created %s" % volume['id'])
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_accounts.py
index a836a20..58e3c0c 100644
--- a/tempest/tests/common/test_accounts.py
+++ b/tempest/tests/common/test_accounts.py
@@ -24,7 +24,7 @@
 from tempest.common import accounts
 from tempest import config
 from tempest import exceptions
-from tempest.services.identity.json import token_client
+from tempest.services.identity.v2.json import token_client
 from tempest.tests import base
 from tempest.tests import fake_config
 from tempest.tests import fake_identity
@@ -51,7 +51,19 @@
             {'username': 'test_user5', 'tenant_name': 'test_tenant5',
              'password': 'p'},
             {'username': 'test_user6', 'tenant_name': 'test_tenant6',
-             'password': 'p'},
+             'password': 'p', 'roles': ['role1', 'role2']},
+            {'username': 'test_user7', 'tenant_name': 'test_tenant7',
+             'password': 'p', 'roles': ['role2', 'role3']},
+            {'username': 'test_user8', 'tenant_name': 'test_tenant8',
+             'password': 'p', 'roles': ['role4', 'role1']},
+            {'username': 'test_user9', 'tenant_name': 'test_tenant9',
+             'password': 'p', 'roles': ['role1', 'role2', 'role3', 'role4']},
+            {'username': 'test_user10', 'tenant_name': 'test_tenant10',
+             'password': 'p', 'roles': ['role1', 'role2', 'role3', 'role4']},
+            {'username': 'test_user11', 'tenant_name': 'test_tenant11',
+             'password': 'p', 'roles': [cfg.CONF.identity.admin_role]},
+            {'username': 'test_user12', 'tenant_name': 'test_tenant12',
+             'password': 'p', 'roles': [cfg.CONF.identity.admin_role]},
         ]
         self.useFixture(mockpatch.Patch(
             'tempest.common.accounts.read_accounts_yaml',
@@ -64,7 +76,8 @@
         for account in accounts_list:
             hash = hashlib.md5()
             hash.update(str(account))
-            hash_list.append(hash.hexdigest())
+            temp_hash = hash.hexdigest()
+            hash_list.append(temp_hash)
         return hash_list
 
     def test_get_hash(self):
@@ -83,8 +96,8 @@
         hash_dict = test_account_class.get_hash_dict(self.test_accounts)
         hash_list = self._get_hash_list(self.test_accounts)
         for hash in hash_list:
-            self.assertIn(hash, hash_dict.keys())
-            self.assertIn(hash_dict[hash], self.test_accounts)
+            self.assertIn(hash, hash_dict['creds'].keys())
+            self.assertIn(hash_dict['creds'][hash], self.test_accounts)
 
     def test_create_hash_file_previous_file(self):
         # Emulate the lock existing on the filesystem
@@ -129,8 +142,9 @@
         # Emulate all lcoks in list are in use
         self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
         test_account_class = accounts.Accounts('test_name')
-        self.assertRaises(exceptions.InvalidConfiguration,
-                          test_account_class._get_free_hash, hash_list)
+        with mock.patch('__builtin__.open', mock.mock_open(), create=True):
+            self.assertRaises(exceptions.InvalidConfiguration,
+                              test_account_class._get_free_hash, hash_list)
 
     @mock.patch('tempest.openstack.common.lockutils.lock')
     def test_get_free_hash_some_in_use_accounts(self, lock_mock):
@@ -152,7 +166,7 @@
             test_account_class._get_free_hash(hash_list)
             lock_path = os.path.join(accounts.CONF.lock_path, 'test_accounts',
                                      hash_list[3])
-            open_mock.assert_called_once_with(lock_path, 'w')
+            open_mock.assert_has_calls([mock.call(lock_path, 'w')])
 
     @mock.patch('tempest.openstack.common.lockutils.lock')
     def test_remove_hash_last_account(self, lock_mock):
@@ -200,6 +214,62 @@
         test_accounts_class = accounts.Accounts('test_name')
         self.assertFalse(test_accounts_class.is_multi_user())
 
+    def test__get_creds_by_roles_one_role(self):
+        self.useFixture(mockpatch.Patch(
+            'tempest.common.accounts.read_accounts_yaml',
+            return_value=self.test_accounts))
+        test_accounts_class = accounts.Accounts('test_name')
+        hashes = test_accounts_class.hash_dict['roles']['role4']
+        temp_hash = hashes[0]
+        get_free_hash_mock = self.useFixture(mockpatch.PatchObject(
+            test_accounts_class, '_get_free_hash', return_value=temp_hash))
+        # Test a single role returns all matching roles
+        test_accounts_class._get_creds(roles=['role4'])
+        calls = get_free_hash_mock.mock.mock_calls
+        self.assertEqual(len(calls), 1)
+        args = calls[0][1][0]
+        for i in hashes:
+            self.assertIn(i, args)
+
+    def test__get_creds_by_roles_list_role(self):
+        self.useFixture(mockpatch.Patch(
+            'tempest.common.accounts.read_accounts_yaml',
+            return_value=self.test_accounts))
+        test_accounts_class = accounts.Accounts('test_name')
+        hashes = test_accounts_class.hash_dict['roles']['role4']
+        hashes2 = test_accounts_class.hash_dict['roles']['role2']
+        hashes = list(set(hashes) & set(hashes2))
+        temp_hash = hashes[0]
+        get_free_hash_mock = self.useFixture(mockpatch.PatchObject(
+            test_accounts_class, '_get_free_hash', return_value=temp_hash))
+        # Test an intersection of multiple roles
+        test_accounts_class._get_creds(roles=['role2', 'role4'])
+        calls = get_free_hash_mock.mock.mock_calls
+        self.assertEqual(len(calls), 1)
+        args = calls[0][1][0]
+        for i in hashes:
+            self.assertIn(i, args)
+
+    def test__get_creds_by_roles_no_admin(self):
+        self.useFixture(mockpatch.Patch(
+            'tempest.common.accounts.read_accounts_yaml',
+            return_value=self.test_accounts))
+        test_accounts_class = accounts.Accounts('test_name')
+        hashes = test_accounts_class.hash_dict['creds'].keys()
+        admin_hashes = test_accounts_class.hash_dict['roles'][
+            cfg.CONF.identity.admin_role]
+        temp_hash = hashes[0]
+        get_free_hash_mock = self.useFixture(mockpatch.PatchObject(
+            test_accounts_class, '_get_free_hash', return_value=temp_hash))
+        # Test an intersection of multiple roles
+        test_accounts_class._get_creds()
+        calls = get_free_hash_mock.mock.mock_calls
+        self.assertEqual(len(calls), 1)
+        args = calls[0][1][0]
+        self.assertEqual(len(args), 10)
+        for i in admin_hashes:
+            self.assertNotIn(i, args)
+
 
 class TestNotLockingAccount(base.TestCase):
 
diff --git a/tempest/tests/common/test_cred_provider.py b/tempest/tests/common/test_cred_provider.py
index 160ecaa..3f7c0f8 100644
--- a/tempest/tests/common/test_cred_provider.py
+++ b/tempest/tests/common/test_cred_provider.py
@@ -17,7 +17,7 @@
 from tempest import auth
 from tempest.common import cred_provider
 from tempest.common import tempest_fixtures as fixtures
-from tempest.services.identity.json import token_client as v2_client
+from tempest.services.identity.v2.json import token_client as v2_client
 from tempest.services.identity.v3.json import token_client as v3_client
 from tempest.tests import fake_identity
 # Note: eventually the auth module will move to tempest-lib, and so wil its
diff --git a/tempest/tests/common/test_custom_matchers.py b/tempest/tests/common/test_custom_matchers.py
index 57217e3..2656a47 100644
--- a/tempest/tests/common/test_custom_matchers.py
+++ b/tempest/tests/common/test_custom_matchers.py
@@ -63,4 +63,4 @@
          "  b: expected 2, actual None\n",
          {'a': 1, 'b': None, 'foo': 1},
          matches_matcher)
-    ]
\ No newline at end of file
+    ]
diff --git a/tempest/tests/common/test_service_clients.py b/tempest/tests/common/test_service_clients.py
index afe4abc..9bb58b0 100644
--- a/tempest/tests/common/test_service_clients.py
+++ b/tempest/tests/common/test_service_clients.py
@@ -46,7 +46,7 @@
 from tempest.services.data_processing.v1_1 import data_processing_client
 from tempest.services.database.json import flavors_client as db_flavor_client
 from tempest.services.database.json import versions_client as db_version_client
-from tempest.services.identity.json import identity_client as \
+from tempest.services.identity.v2.json import identity_client as \
     identity_v2_identity_client
 from tempest.services.identity.v3.json import credentials_client
 from tempest.services.identity.v3.json import endpoints_client
@@ -55,6 +55,8 @@
 from tempest.services.identity.v3.json import policy_client
 from tempest.services.identity.v3.json import region_client
 from tempest.services.identity.v3.json import service_client
+from tempest.services.image.v1.json import image_client
+from tempest.services.image.v2.json import image_client as image_v2_client
 from tempest.services.messaging.json import messaging_client
 from tempest.services.network.json import network_client
 from tempest.services.object_storage import account_client
@@ -163,7 +165,9 @@
             identity_v3_identity_client.IdentityV3ClientJSON,
             policy_client.PolicyClientJSON,
             region_client.RegionClientJSON,
-            service_client.ServiceClientJSON
+            service_client.ServiceClientJSON,
+            image_client.ImageClientJSON,
+            image_v2_client.ImageClientV2JSON
         ]
 
         for client in test_clients:
diff --git a/tempest/tests/test_auth.py b/tempest/tests/test_auth.py
index c236dbe..f54ff4f 100644
--- a/tempest/tests/test_auth.py
+++ b/tempest/tests/test_auth.py
@@ -21,7 +21,7 @@
 from tempest import auth
 from tempest import config
 from tempest import exceptions
-from tempest.services.identity.json import token_client as v2_client
+from tempest.services.identity.v2.json import token_client as v2_client
 from tempest.services.identity.v3.json import token_client as v3_client
 from tempest.tests import base
 from tempest.tests import fake_config
diff --git a/tempest/tests/test_credentials.py b/tempest/tests/test_credentials.py
index 54a3360..350b190 100644
--- a/tempest/tests/test_credentials.py
+++ b/tempest/tests/test_credentials.py
@@ -19,7 +19,7 @@
 from tempest.common import tempest_fixtures as fixtures
 from tempest import config
 from tempest import exceptions
-from tempest.services.identity.json import token_client as v2_client
+from tempest.services.identity.v2.json import token_client as v2_client
 from tempest.services.identity.v3.json import token_client as v3_client
 from tempest.tests import base
 from tempest.tests import fake_config
diff --git a/tempest/tests/test_tenant_isolation.py b/tempest/tests/test_tenant_isolation.py
index 6c80496..a18ad46 100644
--- a/tempest/tests/test_tenant_isolation.py
+++ b/tempest/tests/test_tenant_isolation.py
@@ -20,8 +20,9 @@
 from tempest import config
 from tempest import exceptions
 from tempest.openstack.common.fixture import mockpatch
-from tempest.services.identity.json import identity_client as json_iden_client
-from tempest.services.identity.json import token_client as json_token_client
+from tempest.services.identity.v2.json import identity_client as \
+    json_iden_client
+from tempest.services.identity.v2.json import token_client as json_token_client
 from tempest.services.network.json import network_client as json_network_client
 from tempest.tests import base
 from tempest.tests import fake_config
@@ -74,6 +75,17 @@
                             {'id': '1', 'name': 'FakeRole'}]))))
         return roles_fix
 
+    def _mock_list_2_roles(self):
+        roles_fix = self.useFixture(mockpatch.PatchObject(
+            json_iden_client.IdentityClientJSON,
+            'list_roles',
+            return_value=(service_client.ResponseBodyList
+                          (200,
+                           [{'id': '1234', 'name': 'role1'},
+                            {'id': '1', 'name': 'FakeRole'},
+                            {'id': '12345', 'name': 'role2'}]))))
+        return roles_fix
+
     def _mock_assign_user_role(self):
         tenant_fix = self.useFixture(mockpatch.PatchObject(
             json_iden_client.IdentityClientJSON,
@@ -153,6 +165,35 @@
         self.assertEqual(admin_creds.user_id, '1234')
 
     @mock.patch('tempest_lib.common.rest_client.RestClient')
+    def test_role_creds(self, MockRestClient):
+        cfg.CONF.set_default('neutron', False, 'service_available')
+        iso_creds = isolated_creds.IsolatedCreds('test class',
+                                                 password='fake_password')
+        self._mock_list_2_roles()
+        self._mock_user_create('1234', 'fake_role_user')
+        self._mock_tenant_create('1234', 'fake_role_tenant')
+
+        user_mock = mock.patch.object(json_iden_client.IdentityClientJSON,
+                                      'assign_user_role')
+        user_mock.start()
+        self.addCleanup(user_mock.stop)
+        with mock.patch.object(json_iden_client.IdentityClientJSON,
+                               'assign_user_role') as user_mock:
+            role_creds = iso_creds.get_creds_by_roles(roles=['role1', 'role2'])
+        calls = user_mock.mock_calls
+        # Assert that the role creation is called with the 2 specified roles
+        self.assertEqual(len(calls), 3)
+        args = map(lambda x: x[1], calls)
+        self.assertIn(('1234', '1234', '1'), args)
+        self.assertIn(('1234', '1234', '1234'), args)
+        self.assertIn(('1234', '1234', '12345'), args)
+        self.assertEqual(role_creds.username, 'fake_role_user')
+        self.assertEqual(role_creds.tenant_name, 'fake_role_tenant')
+        # Verify IDs
+        self.assertEqual(role_creds.tenant_id, '1234')
+        self.assertEqual(role_creds.user_id, '1234')
+
+    @mock.patch('tempest_lib.common.rest_client.RestClient')
     def test_all_cred_cleanup(self, MockRestClient):
         cfg.CONF.set_default('neutron', False, 'service_available')
         iso_creds = isolated_creds.IsolatedCreds('test class',
@@ -175,10 +216,10 @@
         self._mock_list_roles('123456', 'admin')
         iso_creds.get_admin_creds()
         user_mock = self.patch(
-            'tempest.services.identity.json.identity_client.'
+            'tempest.services.identity.v2.json.identity_client.'
             'IdentityClientJSON.delete_user')
         tenant_mock = self.patch(
-            'tempest.services.identity.json.identity_client.'
+            'tempest.services.identity.v2.json.identity_client.'
             'IdentityClientJSON.delete_tenant')
         iso_creds.clear_isolated_creds()
         # Verify user delete calls
@@ -293,9 +334,9 @@
         router_fix = self._mock_router_create('123456', 'fake_admin_router')
         self._mock_list_roles('123456', 'admin')
         iso_creds.get_admin_creds()
-        self.patch('tempest.services.identity.json.identity_client.'
+        self.patch('tempest.services.identity.v2.json.identity_client.'
                    'IdentityClientJSON.delete_user')
-        self.patch('tempest.services.identity.json.identity_client.'
+        self.patch('tempest.services.identity.v2.json.identity_client.'
                    'IdentityClientJSON.delete_tenant')
         net = mock.patch.object(iso_creds.network_admin_client,
                                 'delete_network')
diff --git a/tempest/thirdparty/boto/test.py b/tempest/thirdparty/boto/test.py
index edd9de1..5b2ed70 100644
--- a/tempest/thirdparty/boto/test.py
+++ b/tempest/thirdparty/boto/test.py
@@ -201,10 +201,14 @@
             raise cls.skipException("The EC2 API is not available")
 
     @classmethod
+    def setup_credentials(cls):
+        super(BotoTestCase, cls).setup_credentials()
+        cls.os = cls.get_client_manager()
+
+    @classmethod
     def resource_setup(cls):
         super(BotoTestCase, cls).resource_setup()
         cls.conclusion = decision_maker()
-        cls.os = cls.get_client_manager()
         # The trash contains cleanup functions and paramaters in tuples
         # (function, *args, **kwargs)
         cls._resource_trash_bin = {}
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index 822bf34..4a2bd23 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -31,13 +31,17 @@
 class InstanceRunTest(boto_test.BotoTestCase):
 
     @classmethod
+    def setup_clients(cls):
+        super(InstanceRunTest, cls).setup_clients()
+        cls.s3_client = cls.os.s3_client
+        cls.ec2_client = cls.os.ec2api_client
+
+    @classmethod
     def resource_setup(cls):
         super(InstanceRunTest, cls).resource_setup()
         if not cls.conclusion['A_I_IMAGES_READY']:
             raise cls.skipException("".join(("EC2 ", cls.__name__,
                                     ": requires ami/aki/ari manifest")))
-        cls.s3_client = cls.os.s3_client
-        cls.ec2_client = cls.os.ec2api_client
         cls.zone = CONF.boto.aws_zone
         cls.materials_path = CONF.boto.s3_materials_path
         ami_manifest = CONF.boto.ami_manifest
@@ -245,7 +249,8 @@
 
         self.addResourceCleanUp(self.destroy_reservation,
                                 reservation)
-        volume = self.ec2_client.create_volume(1, self.zone)
+        volume = self.ec2_client.create_volume(CONF.volume.volume_size,
+                                               self.zone)
         LOG.debug("Volume created - status: %s", volume.status)
 
         self.addResourceCleanUp(self.destroy_volume_wait, volume)
diff --git a/tempest/thirdparty/boto/test_ec2_keys.py b/tempest/thirdparty/boto/test_ec2_keys.py
index 36c3386..acf797a 100644
--- a/tempest/thirdparty/boto/test_ec2_keys.py
+++ b/tempest/thirdparty/boto/test_ec2_keys.py
@@ -26,9 +26,13 @@
 class EC2KeysTest(boto_test.BotoTestCase):
 
     @classmethod
+    def setup_clients(cls):
+        super(EC2KeysTest, cls).setup_clients()
+        cls.client = cls.os.ec2api_client
+
+    @classmethod
     def resource_setup(cls):
         super(EC2KeysTest, cls).resource_setup()
-        cls.client = cls.os.ec2api_client
         cls.ec = cls.ec2_error_code
 
 # TODO(afazekas): merge create, delete, get test cases
diff --git a/tempest/thirdparty/boto/test_ec2_network.py b/tempest/thirdparty/boto/test_ec2_network.py
index c7ed00d..ce20156 100644
--- a/tempest/thirdparty/boto/test_ec2_network.py
+++ b/tempest/thirdparty/boto/test_ec2_network.py
@@ -20,8 +20,8 @@
 class EC2NetworkTest(boto_test.BotoTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        super(EC2NetworkTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(EC2NetworkTest, cls).setup_clients()
         cls.ec2_client = cls.os.ec2api_client
 
     # Note(afazekas): these tests for things duable without an instance
diff --git a/tempest/thirdparty/boto/test_ec2_security_groups.py b/tempest/thirdparty/boto/test_ec2_security_groups.py
index 92fe59d..7f9568b 100644
--- a/tempest/thirdparty/boto/test_ec2_security_groups.py
+++ b/tempest/thirdparty/boto/test_ec2_security_groups.py
@@ -21,8 +21,8 @@
 class EC2SecurityGroupTest(boto_test.BotoTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        super(EC2SecurityGroupTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(EC2SecurityGroupTest, cls).setup_clients()
         cls.client = cls.os.ec2api_client
 
     @test.idempotent_id('519b566e-0c38-4629-905e-7d6b6355f524')
diff --git a/tempest/thirdparty/boto/test_ec2_volumes.py b/tempest/thirdparty/boto/test_ec2_volumes.py
index 4616851..9a6d13f 100644
--- a/tempest/thirdparty/boto/test_ec2_volumes.py
+++ b/tempest/thirdparty/boto/test_ec2_volumes.py
@@ -30,20 +30,26 @@
 class EC2VolumesTest(boto_test.BotoTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        super(EC2VolumesTest, cls).resource_setup()
-
+    def skip_checks(cls):
+        super(EC2VolumesTest, cls).skip_checks()
         if not CONF.service_available.cinder:
             skip_msg = ("%s skipped as Cinder is not available" % cls.__name__)
             raise cls.skipException(skip_msg)
 
+    @classmethod
+    def setup_clients(cls):
+        super(EC2VolumesTest, cls).setup_clients()
         cls.client = cls.os.ec2api_client
+
+    @classmethod
+    def resource_setup(cls):
+        super(EC2VolumesTest, cls).resource_setup()
         cls.zone = CONF.boto.aws_zone
 
     @test.idempotent_id('663f0077-c743-48ad-8ae0-46821cbc0918')
     def test_create_get_delete(self):
         # EC2 Create, get, delete Volume
-        volume = self.client.create_volume(1, self.zone)
+        volume = self.client.create_volume(CONF.volume.volume_size, self.zone)
         cuk = self.addResourceCleanUp(self.client.delete_volume, volume.id)
         self.assertIn(volume.status, self.valid_volume_status)
         retrieved = self.client.get_all_volumes((volume.id,))
@@ -56,14 +62,15 @@
     @test.idempotent_id('c6b60d7a-1af7-4f8e-af21-d539d9496149')
     def test_create_volume_from_snapshot(self):
         # EC2 Create volume from snapshot
-        volume = self.client.create_volume(1, self.zone)
+        volume = self.client.create_volume(CONF.volume.volume_size, self.zone)
         self.addResourceCleanUp(self.client.delete_volume, volume.id)
         self.assertVolumeStatusWait(volume, "available")
         snap = self.client.create_snapshot(volume.id)
         self.addResourceCleanUp(self.destroy_snapshot_wait, snap)
         self.assertSnapshotStatusWait(snap, "completed")
 
-        svol = self.client.create_volume(1, self.zone, snapshot=snap)
+        svol = self.client.create_volume(CONF.volume.volume_size, self.zone,
+                                         snapshot=snap)
         cuk = self.addResourceCleanUp(svol.delete)
         self.assertVolumeStatusWait(svol, "available")
         svol.delete()
diff --git a/tempest/thirdparty/boto/test_s3_buckets.py b/tempest/thirdparty/boto/test_s3_buckets.py
index e3a265e..bf04803 100644
--- a/tempest/thirdparty/boto/test_s3_buckets.py
+++ b/tempest/thirdparty/boto/test_s3_buckets.py
@@ -21,8 +21,8 @@
 class S3BucketsTest(boto_test.BotoTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        super(S3BucketsTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(S3BucketsTest, cls).setup_clients()
         cls.client = cls.os.s3_client
 
     @test.idempotent_id('4678525d-8da0-4518-81c1-f1f67d595b00')
diff --git a/tempest/thirdparty/boto/test_s3_ec2_images.py b/tempest/thirdparty/boto/test_s3_ec2_images.py
index 773a193..21ea984 100644
--- a/tempest/thirdparty/boto/test_s3_ec2_images.py
+++ b/tempest/thirdparty/boto/test_s3_ec2_images.py
@@ -27,13 +27,17 @@
 class S3ImagesTest(boto_test.BotoTestCase):
 
     @classmethod
+    def setup_clients(cls):
+        super(S3ImagesTest, cls).setup_clients()
+        cls.s3_client = cls.os.s3_client
+        cls.images_client = cls.os.ec2api_client
+
+    @classmethod
     def resource_setup(cls):
         super(S3ImagesTest, cls).resource_setup()
         if not cls.conclusion['A_I_IMAGES_READY']:
             raise cls.skipException("".join(("EC2 ", cls.__name__,
                                     ": requires ami/aki/ari manifest")))
-        cls.s3_client = cls.os.s3_client
-        cls.images_client = cls.os.ec2api_client
         cls.materials_path = CONF.boto.s3_materials_path
         cls.ami_manifest = CONF.boto.ami_manifest
         cls.aki_manifest = CONF.boto.aki_manifest
diff --git a/tempest/thirdparty/boto/test_s3_objects.py b/tempest/thirdparty/boto/test_s3_objects.py
index bc32686..2d8152d 100644
--- a/tempest/thirdparty/boto/test_s3_objects.py
+++ b/tempest/thirdparty/boto/test_s3_objects.py
@@ -25,8 +25,8 @@
 class S3BucketsTest(boto_test.BotoTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        super(S3BucketsTest, cls).resource_setup()
+    def setup_clients(cls):
+        super(S3BucketsTest, cls).setup_clients()
         cls.client = cls.os.s3_client
 
     @test.idempotent_id('4eea567a-b46a-405b-a475-6097e1faebde')
diff --git a/test-requirements.txt b/test-requirements.txt
index 6eefeee..6a9111e 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,7 +1,7 @@
 # The order of packages is significant, because pip processes them in the order
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
-hacking>=0.9.2,<0.10
+hacking<0.11,>=0.10.0
 # needed for doc build
 sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
 python-subunit>=0.0.18
diff --git a/tox.ini b/tox.ini
index f3fc8b7..ef98e90 100644
--- a/tox.ini
+++ b/tox.ini
@@ -125,11 +125,9 @@
 
 [flake8]
 # E125 is a won't fix until https://github.com/jcrocholl/pep8/issues/126 is resolved.  For further detail see https://review.openstack.org/#/c/36788/
-# H402 skipped because some docstrings aren't sentences
 # E123 skipped because it is ignored by default in the default pep8
 # E129 skipped because it is too limiting when combined with other rules
-# H305 skipped because it is inconsistent between python versions
-# Skipped because of new hacking 0.9: H405,H904
-ignore = E125,H402,E123,E129,H404,H405,H904,H305
+# Skipped because of new hacking 0.9: H405
+ignore = E125,E123,E129,H404,H405
 show-source = True
 exclude = .git,.venv,.tox,dist,doc,openstack,*egg