Merge "Drop the legacy and un-used _interface"
diff --git a/tempest/api/data_processing/base.py b/tempest/api/data_processing/base.py
index 6c376fb..5992921 100644
--- a/tempest/api/data_processing/base.py
+++ b/tempest/api/data_processing/base.py
@@ -24,14 +24,25 @@
 class BaseDataProcessingTest(tempest.test.BaseTestCase):
 
     @classmethod
-    def resource_setup(cls):
-        super(BaseDataProcessingTest, cls).resource_setup()
+    def skip_checks(cls):
+        super(BaseDataProcessingTest, cls).skip_checks()
         if not CONF.service_available.sahara:
             raise cls.skipException('Sahara support is required')
 
+    @classmethod
+    def setup_credentials(cls):
+        super(BaseDataProcessingTest, cls).setup_credentials()
         cls.os = cls.get_client_manager()
+
+    @classmethod
+    def setup_clients(cls):
+        super(BaseDataProcessingTest, cls).setup_clients()
         cls.client = cls.os.data_processing_client
 
+    @classmethod
+    def resource_setup(cls):
+        super(BaseDataProcessingTest, cls).resource_setup()
+
         cls.flavor_ref = CONF.compute.flavor_ref
 
         # add lists for watched resources
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 6107265..fd62004 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -16,8 +16,8 @@
 from tempest_lib import exceptions as lib_exc
 
 from tempest.api.identity import base
-from tempest import auth
 from tempest import clients
+from tempest.common import cred_provider
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest import exceptions
@@ -89,7 +89,7 @@
         self.assertIsNotNone(self.trustee_user_id)
 
         # Initialize a new client with the trustor credentials
-        creds = auth.get_credentials(
+        creds = cred_provider.get_credentials(
             username=self.trustor_username,
             password=self.trustor_password,
             tenant_name=self.trustor_project_name)
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 7521823..8f07a6a 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -15,8 +15,8 @@
 
 from tempest_lib import exceptions as lib_exc
 
-from tempest import auth
 from tempest import clients
+from tempest.common import cred_provider
 from tempest.common.utils import data_utils
 from tempest import config
 from tempest.openstack.common import log as logging
@@ -149,11 +149,11 @@
 
         @property
         def test_credentials(self):
-            return auth.get_credentials(username=self.test_user,
-                                        user_id=self.user['id'],
-                                        password=self.test_password,
-                                        tenant_name=self.test_tenant,
-                                        tenant_id=self.tenant['id'])
+            return cred_provider.get_credentials(username=self.test_user,
+                                                 user_id=self.user['id'],
+                                                 password=self.test_password,
+                                                 tenant_name=self.test_tenant,
+                                                 tenant_id=self.tenant['id'])
 
         def setup_test_user(self):
             """Set up a test user."""
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index 6d9c438..2a49210 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -37,15 +37,6 @@
         self.client.delete_volume(volume_id)
         self.client.wait_for_resource_deletion(volume_id)
 
-    def _is_true(self, val):
-        # NOTE(jdg): Temporary conversion method to get cinder patch
-        # merged.  Then we'll make this strict again and
-        # specifically check "true" or "false"
-        if val in ['true', 'True', True]:
-            return True
-        else:
-            return False
-
     def _volume_create_get_update_delete(self, **kwargs):
         # Create a volume, Get it's details and Delete the volume
         volume = {}
@@ -79,13 +70,10 @@
                         'The fetched Volume metadata misses data '
                         'from the created Volume')
 
-        # NOTE(jdg): Revert back to strict true/false checking
-        # after fix for bug #1227837 merges
-        boot_flag = self._is_true(fetched_volume['bootable'])
         if 'imageRef' in kwargs:
-            self.assertEqual(boot_flag, True)
+            self.assertEqual('true', fetched_volume['bootable'])
         if 'imageRef' not in kwargs:
-            self.assertEqual(boot_flag, False)
+            self.assertEqual('false', fetched_volume['bootable'])
 
         # Update Volume
         # Test volume update when display_name is same with original value
@@ -125,13 +113,10 @@
                   self.descrip_field: volume[self.descrip_field]}
         self.client.update_volume(new_volume['id'], **params)
 
-        # NOTE(jdg): Revert back to strict true/false checking
-        # after fix for bug #1227837 merges
-        boot_flag = self._is_true(updated_volume['bootable'])
         if 'imageRef' in kwargs:
-            self.assertEqual(boot_flag, True)
+            self.assertEqual('true', updated_volume['bootable'])
         if 'imageRef' not in kwargs:
-            self.assertEqual(boot_flag, False)
+            self.assertEqual('false', updated_volume['bootable'])
 
     @test.attr(type='smoke')
     def test_volume_create_get_update_delete(self):
diff --git a/tempest/auth.py b/tempest/auth.py
index c0c67c0..7e1928f 100644
--- a/tempest/auth.py
+++ b/tempest/auth.py
@@ -42,7 +42,6 @@
         """
         :param credentials: credentials for authentication
         """
-        credentials = self._convert_credentials(credentials)
         if self.check_credentials(credentials):
             self.credentials = credentials
         else:
@@ -51,13 +50,6 @@
         self.alt_auth_data = None
         self.alt_part = None
 
-    def _convert_credentials(self, credentials):
-        # Support dict credentials for backwards compatibility
-        if isinstance(credentials, dict):
-            return get_credentials(**credentials)
-        else:
-            return credentials
-
     def __str__(self):
         return "Creds :{creds}, cached auth data: {cache}".format(
             creds=self.credentials, cache=self.cache)
@@ -435,7 +427,11 @@
             datetime.datetime.utcnow()
 
 
-def get_credentials(fill_in=True, **kwargs):
+def is_identity_version_supported(identity_version):
+    return identity_version in IDENTITY_VERSION
+
+
+def get_credentials(fill_in=True, identity_version='v2', **kwargs):
     """
     Builds a credentials object based on the configured auth_version
 
@@ -443,6 +439,8 @@
            details provided by the identity service. When fill_in is not
            specified, credentials are not validated. Validation can be invoked
            by invoking ``is_valid()``
+    :param identity_version (string): identity API version is used to
+           select the matching auth provider and credentials class
     :param kwargs (dict): Dict of credential key/value pairs
 
     Examples:
@@ -453,14 +451,13 @@
         Returns credentials including IDs:
         >>> get_credentials(username='foo', password='bar', fill_in=True)
     """
-    if CONF.identity.auth_version == 'v2':
-        credential_class = KeystoneV2Credentials
-        auth_provider_class = KeystoneV2AuthProvider
-    elif CONF.identity.auth_version == 'v3':
-        credential_class = KeystoneV3Credentials
-        auth_provider_class = KeystoneV3AuthProvider
-    else:
-        raise exceptions.InvalidConfiguration('Unsupported auth version')
+    if not is_identity_version_supported(identity_version):
+        raise exceptions.InvalidIdentityVersion(
+            identity_version=identity_version)
+
+    credential_class, auth_provider_class = IDENTITY_VERSION.get(
+        identity_version)
+
     creds = credential_class(**kwargs)
     # Fill in the credentials fields that were not specified
     if fill_in:
@@ -633,3 +630,7 @@
              self.project_id is not None,
              self.project_name is not None and valid_project_domain])
         return all([self.password is not None, valid_user, valid_project])
+
+
+IDENTITY_VERSION = {'v2': (KeystoneV2Credentials, KeystoneV2AuthProvider),
+                    'v3': (KeystoneV3Credentials, KeystoneV3AuthProvider)}
diff --git a/tempest/cli/simple_read_only/compute/__init__.py b/tempest/cli/simple_read_only/compute/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/cli/simple_read_only/compute/__init__.py
+++ /dev/null
diff --git a/tempest/cli/simple_read_only/compute/test_nova.py b/tempest/cli/simple_read_only/compute/test_nova.py
deleted file mode 100644
index aee92fa..0000000
--- a/tempest/cli/simple_read_only/compute/test_nova.py
+++ /dev/null
@@ -1,209 +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.
-
-from tempest_lib import decorators
-from tempest_lib import exceptions
-import testtools
-
-from tempest import cli
-from tempest import config
-from tempest.openstack.common import log as logging
-
-CONF = config.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-class SimpleReadOnlyNovaClientTest(cli.ClientTestBase):
-
-    """
-    This is a first pass at a simple read only python-novaclient test. This
-    only exercises client commands that are read only.
-
-    This should test commands:
-    * as a regular user
-    * as a admin user
-    * with and without optional parameters
-    * initially just check return codes, and later test command outputs
-
-    """
-
-    @classmethod
-    def resource_setup(cls):
-        if not CONF.service_available.nova:
-            msg = ("%s skipped as Nova is not available" % cls.__name__)
-            raise cls.skipException(msg)
-        super(SimpleReadOnlyNovaClientTest, cls).resource_setup()
-
-    def nova(self, *args, **kwargs):
-        return self.clients.nova(*args,
-                                 endpoint_type=CONF.compute.endpoint_type,
-                                 **kwargs)
-
-    def test_admin_fake_action(self):
-        self.assertRaises(exceptions.CommandFailed,
-                          self.nova,
-                          'this-does-nova-exist')
-
-    # NOTE(jogo): Commands in order listed in 'nova help'
-
-    # Positional arguments:
-
-    def test_admin_absolute_limites(self):
-        self.nova('absolute-limits')
-        self.nova('absolute-limits', params='--reserved')
-
-    def test_admin_aggregate_list(self):
-        self.nova('aggregate-list')
-
-    def test_admin_availability_zone_list(self):
-        self.assertIn("internal", self.nova('availability-zone-list'))
-
-    def test_admin_cloudpipe_list(self):
-        self.nova('cloudpipe-list')
-
-    def test_admin_credentials(self):
-        self.nova('credentials')
-
-    @testtools.skipIf(CONF.service_available.neutron,
-                      "Neutron does not provide this feature")
-    def test_admin_dns_domains(self):
-        self.nova('dns-domains')
-
-    @decorators.skip_because(bug="1157349")
-    def test_admin_dns_list(self):
-        self.nova('dns-list')
-
-    def test_admin_endpoints(self):
-        self.nova('endpoints')
-
-    def test_admin_flavor_acces_list(self):
-        self.assertRaises(exceptions.CommandFailed,
-                          self.nova,
-                          'flavor-access-list')
-        # Failed to get access list for public flavor type
-        self.assertRaises(exceptions.CommandFailed,
-                          self.nova,
-                          'flavor-access-list',
-                          params='--flavor m1.tiny')
-
-    def test_admin_flavor_list(self):
-        self.assertIn("Memory_MB", self.nova('flavor-list'))
-
-    def test_admin_floating_ip_bulk_list(self):
-        self.nova('floating-ip-bulk-list')
-
-    def test_admin_floating_ip_list(self):
-        self.nova('floating-ip-list')
-
-    def test_admin_floating_ip_pool_list(self):
-        self.nova('floating-ip-pool-list')
-
-    def test_admin_host_list(self):
-        self.nova('host-list')
-
-    def test_admin_hypervisor_list(self):
-        self.nova('hypervisor-list')
-
-    def test_admin_image_list(self):
-        self.nova('image-list')
-
-    @decorators.skip_because(bug="1157349")
-    def test_admin_interface_list(self):
-        self.nova('interface-list')
-
-    def test_admin_keypair_list(self):
-        self.nova('keypair-list')
-
-    def test_admin_list(self):
-        self.nova('list')
-        self.nova('list', params='--all-tenants 1')
-        self.nova('list', params='--all-tenants 0')
-        self.assertRaises(exceptions.CommandFailed,
-                          self.nova,
-                          'list',
-                          params='--all-tenants bad')
-
-    def test_admin_network_list(self):
-        self.nova('network-list')
-
-    def test_admin_rate_limits(self):
-        self.nova('rate-limits')
-
-    def test_admin_secgroup_list(self):
-        self.nova('secgroup-list')
-
-    @decorators.skip_because(bug="1157349")
-    def test_admin_secgroup_list_rules(self):
-        self.nova('secgroup-list-rules')
-
-    @cli.min_client_version(client='nova', version='2.18')
-    def test_admin_server_group_list(self):
-        self.nova('server-group-list')
-
-    def test_admin_servce_list(self):
-        self.nova('service-list')
-
-    def test_admin_usage(self):
-        self.nova('usage')
-
-    def test_admin_usage_list(self):
-        self.nova('usage-list')
-
-    @testtools.skipIf(not CONF.service_available.cinder,
-                      "Skipped as Cinder is not available")
-    def test_admin_volume_list(self):
-        self.nova('volume-list')
-
-    @testtools.skipIf(not CONF.service_available.cinder,
-                      "Skipped as Cinder is not available")
-    def test_admin_volume_snapshot_list(self):
-        self.nova('volume-snapshot-list')
-
-    @testtools.skipIf(not CONF.service_available.cinder,
-                      "Skipped as Cinder is not available")
-    def test_admin_volume_type_list(self):
-        self.nova('volume-type-list')
-
-    def test_admin_help(self):
-        self.nova('help')
-
-    def test_admin_list_extensions(self):
-        self.nova('list-extensions')
-
-    def test_admin_net_list(self):
-        self.nova('net-list')
-
-    def test_agent_list(self):
-        self.nova('agent-list')
-        self.nova('agent-list', flags='--debug')
-
-    def test_migration_list(self):
-        self.nova('migration-list')
-        self.nova('migration-list', flags='--debug')
-
-    # Optional arguments:
-
-    def test_admin_version(self):
-        self.nova('', flags='--version')
-
-    def test_admin_debug_list(self):
-        self.nova('list', flags='--debug')
-
-    def test_admin_timeout(self):
-        self.nova('list', flags='--timeout %d' % CONF.cli.timeout)
-
-    def test_admin_timing(self):
-        self.nova('list', flags='--timing')
diff --git a/tempest/cmd/cleanup.py b/tempest/cmd/cleanup.py
index 28992b9..c52704a 100755
--- a/tempest/cmd/cleanup.py
+++ b/tempest/cmd/cleanup.py
@@ -54,9 +54,9 @@
 import json
 import sys
 
-from tempest import auth
 from tempest import clients
 from tempest.cmd import cleanup_service
+from tempest.common import cred_provider
 from tempest import config
 from tempest.openstack.common import log as logging
 
@@ -159,7 +159,8 @@
         kwargs = {"username": CONF.identity.admin_username,
                   "password": CONF.identity.admin_password,
                   "tenant_name": tenant['name']}
-        mgr = clients.Manager(credentials=auth.get_credentials(**kwargs))
+        mgr = clients.Manager(credentials=cred_provider.get_credentials(
+            **kwargs))
         kwargs = {'data': tenant_data,
                   'is_dry_run': is_dry_run,
                   'saved_state_json': None,
diff --git a/tempest/common/accounts.py b/tempest/common/accounts.py
index 35a1f86..dd8d498 100644
--- a/tempest/common/accounts.py
+++ b/tempest/common/accounts.py
@@ -17,7 +17,6 @@
 
 import yaml
 
-from tempest import auth
 from tempest.common import cred_provider
 from tempest import config
 from tempest import exceptions
@@ -123,7 +122,7 @@
         if self.isolated_creds.get('primary'):
             return self.isolated_creds.get('primary')
         creds = self._get_creds()
-        primary_credential = auth.get_credentials(**creds)
+        primary_credential = cred_provider.get_credentials(**creds)
         self.isolated_creds['primary'] = primary_credential
         return primary_credential
 
@@ -131,7 +130,7 @@
         if self.isolated_creds.get('alt'):
             return self.isolated_creds.get('alt')
         creds = self._get_creds()
-        alt_credential = auth.get_credentials(**creds)
+        alt_credential = cred_provider.get_credentials(**creds)
         self.isolated_creds['alt'] = alt_credential
         return alt_credential
 
@@ -189,7 +188,7 @@
             return self.isolated_creds.get('primary')
         if not self.use_default_creds:
             creds = self.get_creds(0)
-            primary_credential = auth.get_credentials(**creds)
+            primary_credential = cred_provider.get_credentials(**creds)
         else:
             primary_credential = cred_provider.get_configured_credentials(
                 'user')
@@ -201,7 +200,7 @@
             return self.isolated_creds.get('alt')
         if not self.use_default_creds:
             creds = self.get_creds(1)
-            alt_credential = auth.get_credentials(**creds)
+            alt_credential = cred_provider.get_credentials(**creds)
         else:
             alt_credential = cred_provider.get_configured_credentials(
                 'alt_user')
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index 40c1ad7..f40ed7a 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -56,7 +56,7 @@
             params[attr] = getattr(_section, prefix + "_" + attr)
     # Build and validate credentials. We are reading configured credentials,
     # so validate them even if fill_in is False
-    credentials = auth.get_credentials(fill_in=fill_in, **params)
+    credentials = get_credentials(fill_in=fill_in, **params)
     if not fill_in:
         if not credentials.is_valid():
             msg = ("The %s credentials are incorrectly set in the config file."
@@ -66,6 +66,15 @@
     return credentials
 
 
+# Wrapper around auth.get_credentials to use the configured identity version
+# is none is specified
+def get_credentials(fill_in=True, identity_version=None, **kwargs):
+    identity_version = identity_version or CONF.identity.auth_version
+    return auth.get_credentials(fill_in=fill_in,
+                                identity_version=identity_version,
+                                **kwargs)
+
+
 @six.add_metaclass(abc.ABCMeta)
 class CredentialProvider(object):
     def __init__(self, name, password='pass', network_resources=None):
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index cee610d..1cfb963 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -15,7 +15,6 @@
 import netaddr
 from tempest_lib import exceptions as lib_exc
 
-from tempest import auth
 from tempest import clients
 from tempest.common import cred_provider
 from tempest.common.utils import data_utils
@@ -127,7 +126,7 @@
         return self._get_credentials(user, tenant)
 
     def _get_credentials(self, user, tenant):
-        return auth.get_credentials(
+        return cred_provider.get_credentials(
             username=user['name'], user_id=user['id'],
             tenant_name=tenant['name'], tenant_id=tenant['id'],
             password=self.password)
diff --git a/tempest/exceptions.py b/tempest/exceptions.py
index 81db5d9..09f7016 100644
--- a/tempest/exceptions.py
+++ b/tempest/exceptions.py
@@ -63,6 +63,10 @@
     message = "Invalid service tag"
 
 
+class InvalidIdentityVersion(TempestException):
+    message = "Invalid version %(identity_version) of the identity service"
+
+
 class TimeoutException(TempestException):
     message = "Request timed out"
 
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index 49fac3d..1c27815 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -19,8 +19,8 @@
 
 from six import moves
 
-from tempest import auth
 from tempest import clients
+from tempest.common import cred_provider
 from tempest.common import ssh
 from tempest.common.utils import data_utils
 from tempest import config
@@ -148,9 +148,9 @@
                                             password,
                                             tenant['id'],
                                             "email")
-                creds = auth.get_credentials(username=username,
-                                             password=password,
-                                             tenant_name=tenant_name)
+                creds = cred_provider.get_credentials(username=username,
+                                                      password=password,
+                                                      tenant_name=tenant_name)
                 manager = clients.Manager(credentials=creds)
 
             test_obj = importutils.import_class(test['action'])
diff --git a/tempest/tests/test_auth.py b/tempest/tests/test_auth.py
index 785880d..0317ad6 100644
--- a/tempest/tests/test_auth.py
+++ b/tempest/tests/test_auth.py
@@ -30,7 +30,7 @@
 from tempest.tests import fake_identity
 
 
-def fake_get_credentials(fill_in=True, **kwargs):
+def fake_get_credentials(fill_in=True, identity_version='v2', **kwargs):
     return fake_credentials.FakeCredentials()
 
 
@@ -81,11 +81,6 @@
     def test_check_credentials_bad_type(self):
         self.assertFalse(self.auth_provider.check_credentials([]))
 
-    def test_instantiate_with_dict(self):
-        # Dict credentials are only supported for backward compatibility
-        auth_provider = self._auth(credentials={})
-        self.assertIsInstance(auth_provider.credentials, auth.Credentials)
-
     def test_auth_data_property_when_cache_exists(self):
         self.auth_provider.cache = 'foo'
         self.useFixture(mockpatch.PatchObject(self.auth_provider,
diff --git a/tempest/tests/test_credentials.py b/tempest/tests/test_credentials.py
index 3d0e171..7621f6e 100644
--- a/tempest/tests/test_credentials.py
+++ b/tempest/tests/test_credentials.py
@@ -15,8 +15,6 @@
 
 import copy
 
-from oslo.config import cfg
-
 from tempest import auth
 from tempest.common import tempest_fixtures as fixtures
 from tempest import config
@@ -78,6 +76,7 @@
     identity_response = fake_identity._fake_v2_response
     credentials_class = auth.KeystoneV2Credentials
     tokenclient_class = v2_client.TokenClientJSON
+    identity_version = 'v2'
 
     def setUp(self):
         super(KeystoneV2CredentialsTests, self).setUp()
@@ -85,7 +84,9 @@
                        self.identity_response)
 
     def _verify_credentials(self, credentials_class, creds_dict, filled=True):
-        creds = auth.get_credentials(fill_in=filled, **creds_dict)
+        creds = auth.get_credentials(fill_in=filled,
+                                     identity_version=self.identity_version,
+                                     **creds_dict)
         self._check(creds, credentials_class, filled)
 
     def test_get_credentials(self):
@@ -156,15 +157,7 @@
     credentials_class = auth.KeystoneV3Credentials
     identity_response = fake_identity._fake_v3_response
     tokenclient_class = v3_client.V3TokenClientJSON
-
-    def setUp(self):
-        super(KeystoneV3CredentialsTests, self).setUp()
-        # Additional config items reset by cfg fixture after each test
-        cfg.CONF.set_default('auth_version', 'v3', group='identity')
-        # Identity group items
-        for prefix in ['', 'alt_', 'admin_']:
-            cfg.CONF.set_default(prefix + 'domain_name', 'fake_domain_name',
-                                 group='identity')
+    identity_version = 'v3'
 
     def test_is_not_valid(self):
         # NOTE(mtreinish) For a Keystone V3 credential object a project name