summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Frittoli <andrea.frittoli@hp.com>2014-07-17 13:28:58 +0100
committerAndrea Frittoli <andrea.frittoli@hp.com>2014-10-09 12:14:37 +0100
commit8283b4ebc7de969c86898ec5cf7f9f5cf20fa01e (patch)
tree818994f3ff7b9441b408cb6cbc88a6607c2cb6a3
parentbea1b3c1a223a5a586025bb9e391c77be3c13076 (diff)
downloadtempest-8283b4ebc7de969c86898ec5cf7f9f5cf20fa01e.tar.gz
Add Credentials Provider factory
Add a method to select the appropriate credentials provider based on configuration, and replace all the flow branches based on allow_tenant_isolation to use the factory. This also includes handling NotImplemented exceptions on admin creds for scenarios tests which is a new potential condition by using the factory. Partially-implements bp:test-accounts Change-Id: I280f2b1659c593e14ab9213a161b55bcfc08fa5c
-rw-r--r--etc/tempest.conf.sample30
-rw-r--r--tempest/api/compute/base.py51
-rw-r--r--tempest/api/compute/servers/test_list_server_filters.py12
-rw-r--r--tempest/api/compute/servers/test_servers_negative.py5
-rw-r--r--tempest/api/compute/test_authorization.py8
-rw-r--r--tempest/api/compute/v3/servers/test_list_server_filters.py11
-rw-r--r--tempest/api/compute/v3/servers/test_servers_negative.py5
-rw-r--r--tempest/api/image/base.py17
-rw-r--r--tempest/api/network/base.py16
-rw-r--r--tempest/api/object_storage/base.py18
-rw-r--r--tempest/api/volume/admin/test_volume_quotas.py3
-rw-r--r--tempest/api/volume/base.py19
-rw-r--r--tempest/api/volume/test_volume_transfers.py19
-rw-r--r--tempest/common/accounts.py22
-rw-r--r--tempest/common/cred_provider.py7
-rw-r--r--tempest/common/credentials.py39
-rw-r--r--tempest/common/isolated_creds.py3
-rw-r--r--tempest/config.py33
-rw-r--r--tempest/scenario/manager.py27
-rw-r--r--tempest/test.py39
20 files changed, 196 insertions, 188 deletions
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index dfcbaba6b..4c977a352 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -115,6 +115,24 @@
# to use for running tests (string value)
#test_accounts_file=etc/accounts.yaml
+# Allows test cases to create/destroy tenants and users. This
+# option requires that OpenStack Identity API admin
+# credentials are known. If false, isolated test cases and
+# parallel execution, can still be 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
+
+# If set to True it enables the Accounts provider, which locks
+# credentials to allow for parallel execution with pre-
+# provisioned accounts. It can only be used to run tests that
+# ensure credentials cleanup happens. It requires at least `2
+# * CONC` distinct accounts configured in
+# `test_accounts_file`, with CONC == the number of concurrent
+# test processes. (boolean value)
+#locking_credentials_provider=false
+
[baremetal]
@@ -229,12 +247,6 @@
# Options defined in tempest.config
#
-# Allows test cases to create/destroy tenants and users. This
-# option enables isolated test cases and better parallel
-# execution, but also requires that OpenStack Identity API
-# admin credentials are known. (boolean value)
-#allow_tenant_isolation=false
-
# Valid primary image reference to be used in tests. This is a
# required option (string value)
#image_ref=<None>
@@ -356,12 +368,6 @@
# value)
#floating_ip_range=10.0.0.0/29
-# Allows test cases to create/destroy tenants and users. This
-# option enables isolated test cases and better parallel
-# execution, but also requires that OpenStack Identity API
-# admin credentials are known. (boolean value)
-#allow_tenant_isolation=false
-
# Time in seconds between build status checks. (integer value)
#build_interval=1
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 6c93d3392..6496176d2 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -44,9 +44,9 @@ class BaseComputeTest(tempest.test.BaseTestCase):
# TODO(andreaf) WE should care also for the alt_manager here
# but only once client lazy load in the manager is done
- os = cls.get_client_manager()
+ cls.os = cls.get_client_manager()
+ cls.multi_user = cls.check_multi_user()
- cls.os = os
cls.build_interval = CONF.compute.build_interval
cls.build_timeout = CONF.compute.build_timeout
cls.ssh_user = CONF.compute.ssh_user
@@ -58,7 +58,6 @@ class BaseComputeTest(tempest.test.BaseTestCase):
cls.image_ssh_password = CONF.compute.image_ssh_password
cls.servers = []
cls.images = []
- cls.multi_user = cls.get_multi_user()
cls.security_groups = []
cls.server_groups = []
@@ -118,27 +117,12 @@ class BaseComputeTest(tempest.test.BaseTestCase):
raise exceptions.InvalidConfiguration(message=msg)
@classmethod
- def get_multi_user(cls):
- multi_user = True
- # Determine if there are two regular users that can be
- # used in testing. If the test cases are allowed to create
- # users (config.compute.allow_tenant_isolation is true,
- # then we allow multi-user.
- if not CONF.compute.allow_tenant_isolation:
- user1 = CONF.identity.username
- user2 = CONF.identity.alt_username
- if not user2 or user1 == user2:
- multi_user = False
- else:
- user2_password = CONF.identity.alt_password
- user2_tenant_name = CONF.identity.alt_tenant_name
- if not user2_password or not user2_tenant_name:
- msg = ("Alternate user specified but not alternate "
- "tenant or password: alt_tenant_name=%s "
- "alt_password=%s"
- % (user2_tenant_name, user2_password))
- raise exceptions.InvalidConfiguration(msg)
- return multi_user
+ 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):
@@ -390,19 +374,14 @@ class BaseComputeAdminTest(BaseComputeTest):
@classmethod
def resource_setup(cls):
super(BaseComputeAdminTest, cls).resource_setup()
- if (CONF.compute.allow_tenant_isolation or
- cls.force_tenant_isolation is True):
+ try:
creds = cls.isolated_creds.get_admin_creds()
- cls.os_adm = clients.Manager(credentials=creds,
- interface=cls._interface)
- else:
- try:
- cls.os_adm = clients.ComputeAdminManager(
- interface=cls._interface)
- except exceptions.InvalidCredentials:
- msg = ("Missing Compute Admin API credentials "
- "in configuration.")
- raise cls.skipException(msg)
+ cls.os_adm = clients.Manager(
+ credentials=creds, interface=cls._interface)
+ except NotImplementedError:
+ msg = ("Missing Compute Admin API credentials in configuration.")
+ raise cls.skipException(msg)
+
if cls._api_version == 2:
cls.availability_zone_admin_client = (
cls.os_adm.availability_zone_client)
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index 98fe387d2..e660f0030 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -69,12 +69,12 @@ class ListServerFiltersTestJSON(base.BaseV2ComputeTest):
resp, cls.s3 = cls.create_test_server(name=cls.s3_name,
flavor=cls.flavor_ref_alt,
wait_until='ACTIVE')
- if (CONF.service_available.neutron and
- CONF.compute.allow_tenant_isolation):
- network = cls.isolated_creds.get_primary_network()
- cls.fixed_network_name = network['name']
- else:
- cls.fixed_network_name = CONF.compute.fixed_network_name
+
+ cls.fixed_network_name = CONF.compute.fixed_network_name
+ if CONF.service_available.neutron:
+ if hasattr(cls.isolated_creds, 'get_primary_network'):
+ network = cls.isolated_creds.get_primary_network()
+ cls.fixed_network_name = network['name']
@utils.skip_unless_attr('multiple_images', 'Only one image found')
@test.attr(type='gate')
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index b86ee0657..034926012 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -45,10 +45,7 @@ class ServersNegativeTestJSON(base.BaseV2ComputeTest):
def resource_setup(cls):
super(ServersNegativeTestJSON, cls).resource_setup()
cls.client = cls.servers_client
- if CONF.compute.allow_tenant_isolation:
- cls.alt_os = clients.Manager(cls.isolated_creds.get_alt_creds())
- else:
- cls.alt_os = clients.AltManager()
+ cls.alt_os = clients.Manager(cls.isolated_creds.get_alt_creds())
cls.alt_client = cls.alt_os.servers_client
resp, server = cls.create_test_server(wait_until='ACTIVE')
cls.server_id = server['id']
diff --git a/tempest/api/compute/test_authorization.py b/tempest/api/compute/test_authorization.py
index 015d9f580..175f008b2 100644
--- a/tempest/api/compute/test_authorization.py
+++ b/tempest/api/compute/test_authorization.py
@@ -45,12 +45,8 @@ class AuthorizationTestJSON(base.BaseV2ComputeTest):
cls.keypairs_client = cls.os.keypairs_client
cls.security_client = cls.os.security_groups_client
- if CONF.compute.allow_tenant_isolation:
- creds = cls.isolated_creds.get_alt_creds()
- cls.alt_manager = clients.Manager(credentials=creds)
- else:
- # Use the alt_XXX credentials in the config file
- cls.alt_manager = clients.AltManager()
+ creds = cls.isolated_creds.get_alt_creds()
+ cls.alt_manager = clients.Manager(credentials=creds)
cls.alt_client = cls.alt_manager.servers_client
cls.alt_images_client = cls.alt_manager.images_client
diff --git a/tempest/api/compute/v3/servers/test_list_server_filters.py b/tempest/api/compute/v3/servers/test_list_server_filters.py
index 209d29361..73844cf68 100644
--- a/tempest/api/compute/v3/servers/test_list_server_filters.py
+++ b/tempest/api/compute/v3/servers/test_list_server_filters.py
@@ -70,12 +70,11 @@ class ListServerFiltersV3Test(base.BaseV3ComputeTest):
flavor=cls.flavor_ref_alt,
wait_until='ACTIVE')
- if (CONF.service_available.neutron and
- CONF.compute.allow_tenant_isolation):
- network = cls.isolated_creds.get_primary_network()
- cls.fixed_network_name = network['name']
- else:
- cls.fixed_network_name = CONF.compute.fixed_network_name
+ cls.fixed_network_name = CONF.compute.fixed_network_name
+ if CONF.service_available.neutron:
+ if hasattr(cls.isolated_creds, 'get_primary_network'):
+ network = cls.isolated_creds.get_primary_network()
+ cls.fixed_network_name = network['name']
@utils.skip_unless_attr('multiple_images', 'Only one image found')
@test.attr(type='gate')
diff --git a/tempest/api/compute/v3/servers/test_servers_negative.py b/tempest/api/compute/v3/servers/test_servers_negative.py
index 30ac0ac7c..4b1fe04d5 100644
--- a/tempest/api/compute/v3/servers/test_servers_negative.py
+++ b/tempest/api/compute/v3/servers/test_servers_negative.py
@@ -45,10 +45,7 @@ class ServersNegativeV3Test(base.BaseV3ComputeTest):
def resource_setup(cls):
super(ServersNegativeV3Test, cls).resource_setup()
cls.client = cls.servers_client
- if CONF.compute.allow_tenant_isolation:
- cls.alt_os = clients.Manager(cls.isolated_creds.get_alt_creds())
- else:
- cls.alt_os = clients.AltManager()
+ cls.alt_os = clients.Manager(cls.isolated_creds.get_alt_creds())
cls.alt_client = cls.alt_os.servers_v3_client
resp, server = cls.create_test_server(wait_until='ACTIVE')
cls.server_id = server['id']
diff --git a/tempest/api/image/base.py b/tempest/api/image/base.py
index 08767e388..74baba6b3 100644
--- a/tempest/api/image/base.py
+++ b/tempest/api/image/base.py
@@ -41,10 +41,7 @@ class BaseImageTest(tempest.test.BaseTestCase):
if not CONF.service_available.glance:
skip_msg = ("%s skipped as glance is not available" % cls.__name__)
raise cls.skipException(skip_msg)
- if CONF.compute.allow_tenant_isolation:
- cls.os = clients.Manager(cls.isolated_creds.get_primary_creds())
- else:
- cls.os = clients.Manager()
+ cls.os = clients.Manager(cls.isolated_creds.get_primary_creds())
@classmethod
def resource_cleanup(cls):
@@ -91,10 +88,7 @@ class BaseV1ImageMembersTest(BaseV1ImageTest):
@classmethod
def resource_setup(cls):
super(BaseV1ImageMembersTest, cls).resource_setup()
- if CONF.compute.allow_tenant_isolation:
- cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds())
- else:
- cls.os_alt = clients.AltManager()
+ cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds())
cls.alt_img_cli = cls.os_alt.image_client
cls.alt_tenant_id = cls.alt_img_cli.tenant_id
@@ -126,11 +120,8 @@ class BaseV2MemberImageTest(BaseV2ImageTest):
@classmethod
def resource_setup(cls):
super(BaseV2MemberImageTest, cls).resource_setup()
- if CONF.compute.allow_tenant_isolation:
- creds = cls.isolated_creds.get_alt_creds()
- cls.os_alt = clients.Manager(creds)
- else:
- cls.os_alt = clients.AltManager()
+ creds = cls.isolated_creds.get_alt_creds()
+ cls.os_alt = clients.Manager(creds)
cls.os_img_client = cls.os.image_client_v2
cls.alt_img_client = cls.os_alt.image_client_v2
cls.alt_tenant_id = cls.alt_img_client.tenant_id
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 834c01034..ec6973e35 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -365,19 +365,15 @@ class BaseAdminNetworkTest(BaseNetworkTest):
@classmethod
def resource_setup(cls):
super(BaseAdminNetworkTest, cls).resource_setup()
- admin_username = CONF.compute_admin.username
- admin_password = CONF.compute_admin.password
- admin_tenant = CONF.compute_admin.tenant_name
- if not (admin_username and admin_password and admin_tenant):
+
+ try:
+ creds = cls.isolated_creds.get_admin_creds()
+ cls.os_adm = clients.Manager(
+ credentials=creds, interface=cls._interface)
+ except NotImplementedError:
msg = ("Missing Administrative Network API credentials "
"in configuration.")
raise cls.skipException(msg)
- if (CONF.compute.allow_tenant_isolation or
- cls.force_tenant_isolation is True):
- cls.os_adm = clients.Manager(cls.isolated_creds.get_admin_creds(),
- interface=cls._interface)
- else:
- cls.os_adm = clients.ComputeAdminManager(interface=cls._interface)
cls.admin_client = cls.os_adm.network_client
@classmethod
diff --git a/tempest/api/object_storage/base.py b/tempest/api/object_storage/base.py
index 6a5fd3d05..2e39cf945 100644
--- a/tempest/api/object_storage/base.py
+++ b/tempest/api/object_storage/base.py
@@ -36,18 +36,12 @@ class BaseObjectTest(tempest.test.BaseTestCase):
raise cls.skipException(skip_msg)
cls.isolated_creds = isolated_creds.IsolatedCreds(
cls.__name__, network_resources=cls.network_resources)
- if CONF.compute.allow_tenant_isolation:
- # Get isolated creds for normal user
- cls.os = clients.Manager(cls.isolated_creds.get_primary_creds())
- # Get isolated creds for admin user
- cls.os_admin = clients.Manager(
- cls.isolated_creds.get_admin_creds())
- # Get isolated creds for alt user
- cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds())
- else:
- cls.os = clients.Manager()
- cls.os_admin = clients.AdminManager()
- cls.os_alt = clients.AltManager()
+ # Get isolated creds for normal user
+ cls.os = clients.Manager(cls.isolated_creds.get_primary_creds())
+ # Get isolated creds for admin user
+ cls.os_admin = clients.Manager(cls.isolated_creds.get_admin_creds())
+ # Get isolated creds for alt user
+ cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds())
cls.object_client = cls.os.object_client
cls.container_client = cls.os.container_client
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 7e24fa47b..ece4299c0 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -71,7 +71,8 @@ class VolumeQuotasAdminTestJSON(base.BaseVolumeV1AdminTest):
@test.attr(type='gate')
def test_show_quota_usage(self):
- _, quota_usage = self.quotas_client.get_quota_usage(self.adm_tenant)
+ _, quota_usage = self.quotas_client.get_quota_usage(
+ self.os_adm.credentials.tenant_name)
for key in QUOTA_KEYS:
self.assertIn(key, quota_usage)
for usage_key in QUOTA_USAGE_KEYS:
diff --git a/tempest/api/volume/base.py b/tempest/api/volume/base.py
index 7f5361d86..78fd61d4d 100644
--- a/tempest/api/volume/base.py
+++ b/tempest/api/volume/base.py
@@ -154,19 +154,14 @@ class BaseVolumeAdminTest(BaseVolumeTest):
@classmethod
def resource_setup(cls):
super(BaseVolumeAdminTest, cls).resource_setup()
- cls.adm_user = CONF.identity.admin_username
- cls.adm_pass = CONF.identity.admin_password
- cls.adm_tenant = CONF.identity.admin_tenant_name
- if not all((cls.adm_user, cls.adm_pass, cls.adm_tenant)):
- msg = ("Missing Volume Admin API credentials "
- "in configuration.")
- raise cls.skipException(msg)
- if CONF.compute.allow_tenant_isolation:
- cls.os_adm = clients.Manager(cls.isolated_creds.get_admin_creds(),
- interface=cls._interface)
- else:
- cls.os_adm = clients.AdminManager(interface=cls._interface)
+ try:
+ cls.adm_creds = cls.isolated_creds.get_admin_creds()
+ cls.os_adm = clients.Manager(
+ credentials=cls.adm_creds, interface=cls._interface)
+ except NotImplementedError:
+ msg = "Missing Volume Admin API credentials in configuration."
+ raise cls.skipException(msg)
cls.qos_specs = []
diff --git a/tempest/api/volume/test_volume_transfers.py b/tempest/api/volume/test_volume_transfers.py
index 90ac9c123..fe217c19e 100644
--- a/tempest/api/volume/test_volume_transfers.py
+++ b/tempest/api/volume/test_volume_transfers.py
@@ -30,15 +30,16 @@ class VolumesV2TransfersTest(base.BaseVolumeTest):
super(VolumesV2TransfersTest, cls).resource_setup()
# Add another tenant to test volume-transfer
- if CONF.compute.allow_tenant_isolation:
- cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds(),
- interface=cls._interface)
- # Add admin tenant to cleanup resources
- cls.os_adm = clients.Manager(cls.isolated_creds.get_admin_creds(),
- interface=cls._interface)
- else:
- cls.os_alt = clients.AltManager()
- cls.os_adm = clients.ComputeAdminManager(interface=cls._interface)
+ cls.os_alt = clients.Manager(cls.isolated_creds.get_alt_creds(),
+ interface=cls._interface)
+ # Add admin tenant to cleanup resources
+ try:
+ creds = cls.isolated_creds.get_admin_creds()
+ cls.os_adm = clients.Manager(
+ credentials=creds, interface=cls._interface)
+ except NotImplementedError:
+ msg = "Missing Volume Admin API credentials in configuration."
+ raise cls.skipException(msg)
cls.client = cls.volumes_client
cls.alt_client = cls.os_alt.volumes_client
diff --git a/tempest/common/accounts.py b/tempest/common/accounts.py
index 7423c17e7..88e8ced08 100644
--- a/tempest/common/accounts.py
+++ b/tempest/common/accounts.py
@@ -58,7 +58,12 @@ class Accounts(cred_provider.CredentialProvider):
return hash_dict
def is_multi_user(self):
- return len(self.hash_dict) > 1
+ # Default credentials is not a valid option with locking Account
+ if self.use_default_creds:
+ raise exceptions.InvalidConfiguration(
+ "Account file %s doesn't exist" % CONF.auth.test_accounts_file)
+ else:
+ return len(self.hash_dict) > 1
def _create_hash_file(self, hash_string):
path = os.path.join(os.path.join(self.accounts_dir, hash_string))
@@ -144,6 +149,21 @@ class NotLockingAccounts(Accounts):
to preserve the current behaviour of the serial tempest run.
"""
+ def is_multi_user(self):
+ if self.use_default_creds:
+ # Verify that the configured users are valid and distinct
+ try:
+ user = self.get_primary_creds()
+ alt_user = self.get_alt_creds()
+ return user.username != alt_user.username
+ except exceptions.InvalidCredentials as ic:
+ msg = "At least one of the configured credentials is " \
+ "not valid: %s" % ic.message
+ raise exceptions.InvalidConfiguration(msg)
+ else:
+ # TODO(andreaf) Add a uniqueness check here
+ return len(self.hash_dict) > 1
+
def get_creds(self, id):
try:
# No need to sort the dict as within the same python process
diff --git a/tempest/common/cred_provider.py b/tempest/common/cred_provider.py
index 56d34a57c..b09c9641b 100644
--- a/tempest/common/cred_provider.py
+++ b/tempest/common/cred_provider.py
@@ -1,4 +1,5 @@
-# (c) 2014 Deutsche Telekom AG
+# Copyright (c) 2014 Deutsche Telekom AG
+# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
# 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
@@ -43,3 +44,7 @@ class CredentialProvider(object):
@abc.abstractmethod
def clear_isolated_creds(self):
return
+
+ @abc.abstractmethod
+ def is_multi_user(self):
+ return
diff --git a/tempest/common/credentials.py b/tempest/common/credentials.py
new file mode 100644
index 000000000..08b592f92
--- /dev/null
+++ b/tempest/common/credentials.py
@@ -0,0 +1,39 @@
+# Copyright (c) 2014 Hewlett-Packard Development Company, L.P.
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+from tempest.common import accounts
+from tempest.common import isolated_creds
+from tempest import config
+
+CONF = config.CONF
+
+
+# Return the right implementation of CredentialProvider based on config
+# Dropping interface and password, as they are never used anyways
+# TODO(andreaf) Drop them from the CredentialsProvider interface completely
+def get_isolated_credentials(name, network_resources=None,
+ force_tenant_isolation=False):
+ # If a test requires a new account to work, it can have it via forcing
+ # tenant isolation. A new account will be produced only for that test.
+ # In case admin credentials are not available for the account creation,
+ # the test should be skipped else it would fail.
+ if CONF.auth.allow_tenant_isolation or force_tenant_isolation:
+ return isolated_creds.IsolatedCreds(
+ name=name,
+ network_resources=network_resources)
+ else:
+ if CONF.auth.locking_credentials_provider:
+ # Most params are not relevant for pre-created accounts
+ return accounts.Accounts(name=name)
+ else:
+ return accounts.NotLockingAccounts(name=name)
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index b2edfee09..2d16107b8 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -351,3 +351,6 @@ class IsolatedCreds(cred_provider.CredentialProvider):
except exceptions.NotFound:
LOG.warn("tenant with name: %s not found for delete" %
creds.tenant_name)
+
+ def is_multi_user(self):
+ return True
diff --git a/tempest/config.py b/tempest/config.py
index 174a895c8..6bd4755e6 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -38,9 +38,28 @@ AuthGroup = [
default='etc/accounts.yaml',
help="Path to the yaml file that contains the list of "
"credentials to use for running tests"),
+ cfg.BoolOpt('allow_tenant_isolation',
+ default=False,
+ help="Allows test cases to create/destroy tenants and "
+ "users. This option requires that OpenStack Identity "
+ "API admin credentials are known. If false, isolated "
+ "test cases and parallel execution, can still be "
+ "achieved configuring a list of test accounts",
+ deprecated_opts=[cfg.DeprecatedOpt('allow_tenant_isolation',
+ group='compute'),
+ cfg.DeprecatedOpt('allow_tenant_isolation',
+ group='orchestration')]),
+ cfg.BoolOpt('locking_credentials_provider',
+ default=False,
+ help="If set to True it enables the Accounts provider, "
+ "which locks credentials to allow for parallel execution "
+ "with pre-provisioned accounts. It can only be used to "
+ "run tests that ensure credentials cleanup happens. "
+ "It requires at least `2 * CONC` distinct accounts "
+ "configured in `test_accounts_file`, with CONC == the "
+ "number of concurrent test processes."),
]
-
identity_group = cfg.OptGroup(name='identity',
title="Keystone Configuration Options")
@@ -129,12 +148,6 @@ compute_group = cfg.OptGroup(name='compute',
title='Compute Service Options')
ComputeGroup = [
- cfg.BoolOpt('allow_tenant_isolation',
- default=False,
- help="Allows test cases to create/destroy tenants and "
- "users. This option enables isolated test cases and "
- "better parallel execution, but also requires that "
- "OpenStack Identity API admin credentials are known."),
cfg.StrOpt('image_ref',
help="Valid primary image reference to be used in tests. "
"This is a required option"),
@@ -666,12 +679,6 @@ OrchestrationGroup = [
choices=['public', 'admin', 'internal',
'publicURL', 'adminURL', 'internalURL'],
help="The endpoint type to use for the orchestration service."),
- cfg.BoolOpt('allow_tenant_isolation',
- default=False,
- help="Allows test cases to create/destroy tenants and "
- "users. This option enables isolated test cases and "
- "better parallel execution, but also requires that "
- "OpenStack Identity API admin credentials are known."),
cfg.IntOpt('build_interval',
default=1,
help="Time in seconds between build status checks."),
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 79207cd93..7946e067b 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -23,8 +23,8 @@ import six
from tempest import auth
from tempest import clients
+from tempest.common import credentials
from tempest.common import debug
-from tempest.common import isolated_creds
from tempest.common.utils import data_utils
from tempest.common.utils.linux import remote_client
from tempest import config
@@ -51,8 +51,9 @@ class ScenarioTest(tempest.test.BaseTestCase):
@classmethod
def resource_setup(cls):
super(ScenarioTest, cls).resource_setup()
- # Using tempest client for isolated credentials as well
- cls.isolated_creds = isolated_creds.IsolatedCreds(
+ # TODO(andreaf) Some of the code from this resource_setup could be
+ # moved into `BaseTestCase`
+ cls.isolated_creds = credentials.get_isolated_credentials(
cls.__name__, network_resources=cls.network_resources)
cls.manager = clients.Manager(
credentials=cls.credentials()
@@ -79,27 +80,19 @@ class ScenarioTest(tempest.test.BaseTestCase):
cls.orchestration_client = cls.manager.orchestration_client
@classmethod
- def _get_credentials(cls, get_creds, ctype):
- if CONF.compute.allow_tenant_isolation:
- creds = get_creds()
- else:
- creds = auth.get_default_credentials(ctype)
- return creds
-
- @classmethod
def credentials(cls):
- return cls._get_credentials(cls.isolated_creds.get_primary_creds,
- 'user')
+ return cls.isolated_creds.get_primary_creds()
@classmethod
def alt_credentials(cls):
- return cls._get_credentials(cls.isolated_creds.get_alt_creds,
- 'alt_user')
+ return cls.isolated_creds.get_alt_creds()
@classmethod
def admin_credentials(cls):
- return cls._get_credentials(cls.isolated_creds.get_admin_creds,
- 'identity_admin')
+ try:
+ return cls.isolated_creds.get_admin_creds()
+ except NotImplementedError:
+ raise cls.skipException('Admin Credentials are not available')
# ## Methods to handle sync and async deletes
diff --git a/tempest/test.py b/tempest/test.py
index 4a22b1b08..1c94ed436 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -29,8 +29,8 @@ import testscenarios
import testtools
from tempest import clients
+from tempest.common import credentials
import tempest.common.generator.valid_generator as valid
-from tempest.common import isolated_creds
from tempest import config
from tempest import exceptions
from tempest.openstack.common import importutils
@@ -362,31 +362,20 @@ class BaseTestCase(BaseDeps):
"""
Returns an OpenStack client manager
"""
- cls.isolated_creds = isolated_creds.IsolatedCreds(
- cls.__name__, network_resources=cls.network_resources)
-
force_tenant_isolation = getattr(cls, 'force_tenant_isolation', None)
- if CONF.compute.allow_tenant_isolation or force_tenant_isolation:
- creds = cls.isolated_creds.get_primary_creds()
- if getattr(cls, '_interface', None):
- os = clients.Manager(credentials=creds,
- interface=cls._interface,
- service=cls._service)
- elif interface:
- os = clients.Manager(credentials=creds,
- interface=interface,
- service=cls._service)
- else:
- os = clients.Manager(credentials=creds,
- service=cls._service)
- else:
- if getattr(cls, '_interface', None):
- os = clients.Manager(interface=cls._interface,
- service=cls._service)
- elif interface:
- os = clients.Manager(interface=interface, service=cls._service)
- else:
- os = clients.Manager(service=cls._service)
+
+ cls.isolated_creds = credentials.get_isolated_credentials(
+ name=cls.__name__, network_resources=cls.network_resources,
+ force_tenant_isolation=force_tenant_isolation,
+ )
+
+ creds = cls.isolated_creds.get_primary_creds()
+ params = dict(credentials=creds, service=cls._service)
+ if getattr(cls, '_interface', None):
+ interface = cls._interface
+ if interface:
+ params['interface'] = interface
+ os = clients.Manager(**params)
return os
@classmethod