Merge "Only use accounts.yaml with locking provider"
This commit is contained in:
@@ -84,13 +84,11 @@ 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.
|
||||
times the number of worker processes you are using to execute tempest
|
||||
available in the file. (if running serially the worker count is 1)
|
||||
|
||||
You can check the sample file packaged in tempest for the yaml format
|
||||
#. Provide tempest with the location of you accounts.yaml file with the
|
||||
@@ -125,15 +123,3 @@ The only restriction with using the traditional config options for credentials
|
||||
is that if a test requires specific roles on accounts these tests can not be
|
||||
run. This is because the config options do not give sufficient flexibility to
|
||||
describe the roles assigned to a user for running the tests.
|
||||
|
||||
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,
|
||||
except since you can't run in parallel only 2 of each type of credential is
|
||||
required to run. However, the limitation on tests which require specific roles
|
||||
does not apply here.
|
||||
|
||||
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.
|
||||
|
@@ -94,8 +94,12 @@
|
||||
#
|
||||
|
||||
# Path to the yaml file that contains the list of credentials to use
|
||||
# for running tests (string value)
|
||||
#test_accounts_file = etc/accounts.yaml
|
||||
# for running tests. If used when running in parallel you have to make
|
||||
# sure sufficient credentials are provided in the accounts file. For
|
||||
# example if no tests with roles are being run it requires at least `2
|
||||
# * CONC` distinct accounts configured in the `test_accounts_file`,
|
||||
# with CONC == the number of concurrent test processes. (string value)
|
||||
#test_accounts_file = <None>
|
||||
|
||||
# Allows test cases to create/destroy tenants and users. This option
|
||||
# requires that OpenStack Identity API admin credentials are known. If
|
||||
@@ -105,14 +109,6 @@
|
||||
# Deprecated group/name - [orchestration]/allow_tenant_isolation
|
||||
#allow_tenant_isolation = true
|
||||
|
||||
# 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
|
||||
|
||||
# Roles to assign to all users created by tempest (list value)
|
||||
#tempest_roles =
|
||||
|
||||
|
@@ -261,18 +261,14 @@ class NotLockingAccounts(Accounts):
|
||||
|
||||
def _unique_creds(self, cred_arg=None):
|
||||
"""Verify that the configured credentials are valid and distinct """
|
||||
if self.use_default_creds:
|
||||
try:
|
||||
user = self.get_primary_creds()
|
||||
alt_user = self.get_alt_creds()
|
||||
return getattr(user, cred_arg) != getattr(alt_user, cred_arg)
|
||||
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['creds']) > 1
|
||||
try:
|
||||
user = self.get_primary_creds()
|
||||
alt_user = self.get_alt_creds()
|
||||
return getattr(user, cred_arg) != getattr(alt_user, cred_arg)
|
||||
except exceptions.InvalidCredentials as ic:
|
||||
msg = "At least one of the configured credentials is " \
|
||||
"not valid: %s" % ic.message
|
||||
raise exceptions.InvalidConfiguration(msg)
|
||||
|
||||
def is_multi_user(self):
|
||||
return self._unique_creds('username')
|
||||
@@ -280,42 +276,20 @@ class NotLockingAccounts(Accounts):
|
||||
def is_multi_tenant(self):
|
||||
return self._unique_creds('tenant_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 = hashes[id]
|
||||
except IndexError:
|
||||
msg = 'Insufficient number of users provided'
|
||||
raise exceptions.InvalidConfiguration(msg)
|
||||
return self.hash_dict['creds'][_hash]
|
||||
|
||||
def get_primary_creds(self):
|
||||
if self.isolated_creds.get('primary'):
|
||||
return self.isolated_creds.get('primary')
|
||||
if not self.use_default_creds:
|
||||
creds = self.get_creds(0)
|
||||
primary_credential = cred_provider.get_credentials(
|
||||
identity_version=self.identity_version, **creds)
|
||||
else:
|
||||
primary_credential = cred_provider.get_configured_credentials(
|
||||
credential_type='user', identity_version=self.identity_version)
|
||||
primary_credential = cred_provider.get_configured_credentials(
|
||||
credential_type='user', identity_version=self.identity_version)
|
||||
self.isolated_creds['primary'] = primary_credential
|
||||
return primary_credential
|
||||
|
||||
def get_alt_creds(self):
|
||||
if self.isolated_creds.get('alt'):
|
||||
return self.isolated_creds.get('alt')
|
||||
if not self.use_default_creds:
|
||||
creds = self.get_creds(1)
|
||||
alt_credential = cred_provider.get_credentials(
|
||||
identity_version=self.identity_version, **creds)
|
||||
else:
|
||||
alt_credential = cred_provider.get_configured_credentials(
|
||||
credential_type='alt_user',
|
||||
identity_version=self.identity_version)
|
||||
alt_credential = cred_provider.get_configured_credentials(
|
||||
credential_type='alt_user',
|
||||
identity_version=self.identity_version)
|
||||
self.isolated_creds['alt'] = alt_credential
|
||||
return alt_credential
|
||||
|
||||
@@ -323,35 +297,14 @@ class NotLockingAccounts(Accounts):
|
||||
self.isolated_creds = {}
|
||||
|
||||
def get_admin_creds(self):
|
||||
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
|
||||
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
|
||||
msg = "Credentials being specified through the config file can not be"\
|
||||
" used with tests that specify using credentials by roles. "\
|
||||
"Either exclude/skip the tests doing this or use either an "\
|
||||
"test_accounts_file or tenant isolation."
|
||||
raise exceptions.InvalidConfiguration(msg)
|
||||
|
@@ -38,7 +38,7 @@ def get_isolated_credentials(name, network_resources=None,
|
||||
network_resources=network_resources,
|
||||
identity_version=identity_version)
|
||||
else:
|
||||
if CONF.auth.locking_credentials_provider:
|
||||
if os.path.isfile(CONF.auth.test_accounts_file):
|
||||
# Most params are not relevant for pre-created accounts
|
||||
return accounts.Accounts(name=name,
|
||||
identity_version=identity_version)
|
||||
|
@@ -35,9 +35,14 @@ auth_group = cfg.OptGroup(name='auth',
|
||||
|
||||
AuthGroup = [
|
||||
cfg.StrOpt('test_accounts_file',
|
||||
default='etc/accounts.yaml',
|
||||
help="Path to the yaml file that contains the list of "
|
||||
"credentials to use for running tests"),
|
||||
"credentials to use for running tests. If used when "
|
||||
"running in parallel you have to make sure sufficient "
|
||||
"credentials are provided in the accounts file. For "
|
||||
"example if no tests with roles are being run it requires "
|
||||
"at least `2 * CONC` distinct accounts configured in "
|
||||
" the `test_accounts_file`, with CONC == the "
|
||||
"number of concurrent test processes."),
|
||||
cfg.BoolOpt('allow_tenant_isolation',
|
||||
default=True,
|
||||
help="Allows test cases to create/destroy tenants and "
|
||||
@@ -49,15 +54,6 @@ AuthGroup = [
|
||||
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."),
|
||||
cfg.ListOpt('tempest_roles',
|
||||
help="Roles to assign to all users created by tempest",
|
||||
default=[]),
|
||||
|
@@ -297,12 +297,8 @@ class TestNotLockingAccount(base.TestCase):
|
||||
cfg.CONF.set_default('test_accounts_file', '', group='auth')
|
||||
self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
|
||||
|
||||
def test_get_creds(self):
|
||||
def test_get_creds_roles_nonlocking_invalid(self):
|
||||
test_accounts_class = accounts.NotLockingAccounts('v2', 'test_name')
|
||||
for i in xrange(len(self.test_accounts)):
|
||||
creds = test_accounts_class.get_creds(i)
|
||||
msg = "Empty credentials returned for ID %s" % str(i)
|
||||
self.assertIsNotNone(creds, msg)
|
||||
self.assertRaises(exceptions.InvalidConfiguration,
|
||||
test_accounts_class.get_creds,
|
||||
id=len(self.test_accounts))
|
||||
test_accounts_class.get_creds_by_roles,
|
||||
['fake_role'])
|
||||
|
Reference in New Issue
Block a user