Introduce creds_provider in test.py

A lot of code works on the assumption that test classes has
an attribute exactly called "isolated_creds".
Define a new property on test classes that provides a
credential provider for the tests.

Change-Id: I404357be4c9fb2079332eed614bd61eee6ae6dc1
Partially-implements: bp/resource-cleanup
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index eca634d..1a84cbf 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -52,7 +52,6 @@
     def setup_credentials(cls):
         cls.set_network_resources()
         super(BaseComputeTest, cls).setup_credentials()
-        cls.multi_user = cls.check_multi_user()
 
     @classmethod
     def setup_clients(cls):
@@ -112,14 +111,6 @@
         super(BaseComputeTest, cls).resource_cleanup()
 
     @classmethod
-    def check_multi_user(cls):
-        # We have a list of accounts now, so just checking if the list is gt 2
-        if not cls.isolated_creds.is_multi_user():
-            msg = "Not enough users available for multi-user testing"
-            raise exceptions.InvalidConfiguration(msg)
-        return True
-
-    @classmethod
     def clear_servers(cls):
         LOG.debug('Clearing servers: %s', ','.join(
             server['id'] for server in cls.servers))
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 258ff1f..9f007bf 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -92,9 +92,11 @@
 
     @classmethod
     def resource_cleanup(cls):
-        if cls.multi_user:
+        if hasattr(cls, 'image'):
             cls.images_client.delete_image(cls.image['id'])
+        if hasattr(cls, 'keypairname'):
             cls.keypairs_client.delete_keypair(cls.keypairname)
+        if hasattr(cls, 'security_group'):
             cls.security_client.delete_security_group(cls.security_group['id'])
         super(AuthorizationTestJSON, cls).resource_cleanup()
 
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 03d338b..37d4844 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -441,7 +441,7 @@
     @test.idempotent_id('e79f879e-debb-440c-a7e4-efeda05b6848')
     @test.services('compute', 'network')
     def test_cross_tenant_traffic(self):
-        if not self.isolated_creds.is_multi_tenant():
+        if not self.credentials_provider.is_multi_tenant():
             raise self.skipException("No secondary tenant defined")
         try:
             # deploy new tenant
diff --git a/tempest/test.py b/tempest/test.py
index 4474423..bac2085 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -399,6 +399,30 @@
                                                    format=self.log_format,
                                                    level=None))
 
+    @property
+    def credentials_provider(self):
+        return self._get_credentials_provider()
+
+    @classmethod
+    def _get_credentials_provider(cls):
+        """Returns a credentials provider
+
+        If no credential provider exists yet creates one.
+        It uses self.identity_version if defined, or the configuration value
+        """
+        if (not hasattr(cls, '_creds_provider') or not cls._creds_provider or
+                not cls._creds_provider.name == cls.__name__):
+            force_tenant_isolation = getattr(cls, 'force_tenant_isolation',
+                                             False)
+            identity_version = getattr(cls, 'identity_version', None)
+            identity_version = identity_version or CONF.identity.auth_version
+
+            cls._creds_provider = credentials.get_isolated_credentials(
+                name=cls.__name__, network_resources=cls.network_resources,
+                force_tenant_isolation=force_tenant_isolation,
+                identity_version=identity_version)
+        return cls._creds_provider
+
     @classmethod
     def get_client_manager(cls, identity_version=None,
                            credential_type=None, roles=None, force_new=None):
@@ -419,21 +443,11 @@
             raise ValueError(msg)
         if not any([roles, credential_type]):
             credential_type = 'primary'
-
-        force_tenant_isolation = getattr(cls, 'force_tenant_isolation', None)
-        identity_version = identity_version or CONF.identity.auth_version
-
-        if (not hasattr(cls, 'isolated_creds') or
-            not cls.isolated_creds.name == cls.__name__):
-            cls.isolated_creds = credentials.get_isolated_credentials(
-                name=cls.__name__, network_resources=cls.network_resources,
-                force_tenant_isolation=force_tenant_isolation,
-                identity_version=identity_version
-            )
-
+        cls.identity_version = identity_version
+        cred_provider = cls._get_credentials_provider()
         if roles:
             for role in roles:
-                if not cls.isolated_creds.is_role_available(role):
+                if not cred_provider.is_role_available(role):
                     skip_msg = (
                         "%s skipped because the configured credential provider"
                         " is not able to provide credentials with the %s role "
@@ -442,11 +456,11 @@
             params = dict(roles=roles)
             if force_new is not None:
                 params.update(force_new=force_new)
-            creds = cls.isolated_creds.get_creds_by_roles(**params)
+            creds = cred_provider.get_creds_by_roles(**params)
         else:
             credentials_method = 'get_%s_creds' % credential_type
-            if hasattr(cls.isolated_creds, credentials_method):
-                creds = getattr(cls.isolated_creds, credentials_method)()
+            if hasattr(cred_provider, credentials_method):
+                creds = getattr(cred_provider, credentials_method)()
             else:
                 raise exceptions.InvalidCredentials(
                     "Invalid credentials type %s" % credential_type)
@@ -457,8 +471,8 @@
         """
         Clears isolated creds if set
         """
-        if hasattr(cls, 'isolated_creds'):
-            cls.isolated_creds.clear_isolated_creds()
+        if hasattr(cls, '_cred_provider'):
+            cls._creds_provider.clear_isolated_creds()
 
     @classmethod
     def set_network_resources(cls, network=False, router=False, subnet=False,
@@ -489,16 +503,16 @@
         """
         # Make sure isolated_creds exists and get a network client
         networks_client = cls.get_client_manager().networks_client
-        isolated_creds = getattr(cls, 'isolated_creds', None)
+        cred_provider = cls._get_credentials_provider()
         # In case of nova network, isolated tenants are not able to list the
         # network configured in fixed_network_name, even if the can use it
         # for their servers, so using an admin network client to validate
         # the network name
         if (not CONF.service_available.neutron and
                 credentials.is_admin_available()):
-            admin_creds = isolated_creds.get_admin_creds()
+            admin_creds = cred_provider.get_admin_creds()
             networks_client = clients.Manager(admin_creds).networks_client
-        return fixed_network.get_tenant_network(isolated_creds,
+        return fixed_network.get_tenant_network(cred_provider,
                                                 networks_client)
 
     def assertEmpty(self, list, msg=None):
@@ -648,7 +662,7 @@
                 msg = ("Missing Identity Admin API credentials in"
                        "configuration.")
                 raise self.skipException(msg)
-            creds = self.isolated_creds.get_admin_creds()
+            creds = self.credentials_provider.get_admin_creds()
             os_adm = clients.Manager(credentials=creds)
             client = os_adm.negative_client
         else: