Merge "Do not test subnetpools in TF case" into mcp/caracal
diff --git a/tempest/api/compute/admin/test_auto_allocate_network.py b/tempest/api/compute/admin/test_auto_allocate_network.py
index e8011a6..7cfbeb0 100644
--- a/tempest/api/compute/admin/test_auto_allocate_network.py
+++ b/tempest/api/compute/admin/test_auto_allocate_network.py
@@ -37,8 +37,6 @@
calls to Neutron to automatically allocate the network topology.
"""
- force_tenant_isolation = True
-
min_microversion = '2.37'
max_microversion = 'latest'
@@ -53,12 +51,6 @@
'auto-allocated-topology extension is not available')
@classmethod
- def setup_credentials(cls):
- # Do not create network resources for these tests.
- cls.set_network_resources()
- super(AutoAllocateNetworkTest, cls).setup_credentials()
-
- @classmethod
def setup_clients(cls):
super(AutoAllocateNetworkTest, cls).setup_clients()
cls.networks_client = cls.os_primary.networks_client
diff --git a/tempest/common/credentials_factory.py b/tempest/common/credentials_factory.py
index 2d486a7..8d699ab 100644
--- a/tempest/common/credentials_factory.py
+++ b/tempest/common/credentials_factory.py
@@ -122,8 +122,7 @@
:param name: When provided, it makes it possible to associate credential
artifacts back to the owner (test class).
:param network_resources: Dictionary of network resources to be allocated
- for each test account. Only valid for the dynamic
- credentials provider.
+ for each test account.
:param force_tenant_isolation: Always return a `DynamicCredentialProvider`,
regardless of the configuration.
:param identity_version: Use the specified identity API version, regardless
@@ -144,6 +143,9 @@
# Most params are not relevant for pre-created accounts
return preprov_creds.PreProvisionedCredentialProvider(
name=name,
+ network_resources=network_resources,
+ separate_projects_by_network_existence=(
+ CONF.auth.separate_projects_by_network_existence),
**get_preprov_provider_params(identity_version))
else:
raise exceptions.InvalidConfiguration(
diff --git a/tempest/config.py b/tempest/config.py
index 986c917..c8578ae 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -110,6 +110,14 @@
"This must be set to 'all' if using the "
"[oslo_policy]/enforce_scope=true option for the "
"identity service."),
+ cfg.BoolOpt('separate_projects_by_network_existence',
+ default=False,
+ help="If use_dynamic_credentials is set to False and "
+ "separate_projects_by_network_existence is set to True "
+ "Tempest divides projects with networks and without "
+ "networks. To be compatible with old behavior the config "
+ "option is set to False and project are treated the same "
+ "regardless their network resources.")
]
identity_group = cfg.OptGroup(name='identity',
diff --git a/tempest/lib/common/preprov_creds.py b/tempest/lib/common/preprov_creds.py
index 54f9cd5..2938a9d 100644
--- a/tempest/lib/common/preprov_creds.py
+++ b/tempest/lib/common/preprov_creds.py
@@ -75,10 +75,13 @@
HASH_CRED_FIELDS = (set(auth.KeystoneV2Credentials.ATTRIBUTES) &
set(auth.KeystoneV3Credentials.ATTRIBUTES))
- def __init__(self, identity_version, test_accounts_file,
- accounts_lock_dir, name=None, credentials_domain=None,
- admin_role=None, object_storage_operator_role=None,
- object_storage_reseller_admin_role=None, identity_uri=None):
+ def __init__(
+ self, identity_version, test_accounts_file, accounts_lock_dir,
+ name=None, credentials_domain=None, admin_role=None,
+ object_storage_operator_role=None,
+ object_storage_reseller_admin_role=None, identity_uri=None,
+ network_resources=None,
+ separate_projects_by_network_existence=False):
super(PreProvisionedCredentialProvider, self).__init__(
identity_version=identity_version, name=name,
admin_role=admin_role, credentials_domain=credentials_domain,
@@ -90,7 +93,8 @@
raise lib_exc.InvalidCredentials("No accounts file specified")
self.hash_dict = self.get_hash_dict(
accounts, admin_role, object_storage_operator_role,
- object_storage_reseller_admin_role)
+ object_storage_reseller_admin_role, network_resources,
+ separate_projects_by_network_existence)
self.accounts_dir = accounts_lock_dir
self._creds = {}
self._used_projects_file = os.path.join(self.accounts_dir,
@@ -112,14 +116,21 @@
return hash_dict
@classmethod
- def get_hash_dict(cls, accounts, admin_role,
- object_storage_operator_role=None,
- object_storage_reseller_admin_role=None):
+ def get_hash_dict(
+ cls, accounts, admin_role, object_storage_operator_role=None,
+ object_storage_reseller_admin_role=None, network_resources=None,
+ separate_projects_by_network_existence=False):
hash_dict = {'roles': {}, 'creds': {}, 'networks': {},
'scoped_roles': {}, 'projects': {}}
+ tests_require_projects_with_networks = \
+ cls.do_tests_require_projects_with_networks(network_resources)
# Loop over the accounts read from the yaml file
for account in accounts:
+ if not cls.is_account_needed(
+ tests_require_projects_with_networks, account,
+ separate_projects_by_network_existence):
+ continue
roles = []
types = []
scope = None
@@ -182,7 +193,9 @@
'Unknown resource type %s, ignoring this field',
resource
)
- hash_dict = cls._append_project(account, temp_hash_key, hash_dict)
+ if scope == 'project':
+ hash_dict = cls._append_project(account, temp_hash_key,
+ hash_dict)
return hash_dict
def is_multi_user(self):
@@ -200,16 +213,18 @@
return False
def _process_project(self, hash_, used_projects=None, use=True):
+ project = self.hash_dict['creds'][hash_].get('project_name')
+ if not project:
+ project = self.hash_dict['creds'][hash_].get('tenant_name')
+ if not project:
+ return
if used_projects is None:
used_projects = self._get_used_projects()
- if 'tenant_name' in self.hash_dict['creds'][hash_]:
- project = self.hash_dict['creds'][hash_]['tenant_name']
- else:
- project = self.hash_dict['creds'][hash_]['project_name']
method = 'append' if use else 'remove'
getattr(used_projects, method)(project)
with open(self._used_projects_file, 'w') as file:
file.write('\n'.join(used_projects) + '\n')
+ return project
def _get_used_projects(self):
used_projects = []
@@ -296,11 +311,14 @@
return temp_creds
def _get_creds(self, roles=None, scope=None):
- useable_hashes = self._get_match_hash_list(roles, scope)
- if not useable_hashes:
+ usable_hashes = self._get_match_hash_list(roles, scope)
+ if not usable_hashes:
msg = 'No users configured for type/roles %s' % roles
raise lib_exc.InvalidCredentials(msg)
- free_hash = self._get_free_hash(useable_hashes)
+ if scope == 'system':
+ free_hash = next(iter(usable_hashes))
+ else:
+ free_hash = self._get_free_hash(usable_hashes)
clean_creds = self._sanitize_creds(
self.hash_dict['creds'][free_hash])
LOG.info('%s allocated creds for roles %s in scope %s:\n%s',
@@ -309,15 +327,15 @@
@lockutils.synchronized('test_accounts_io', external=True)
def remove_hash(self, hash_string):
- self._process_project(hash_string, use=False)
- hash_path = os.path.join(self.accounts_dir, hash_string)
- if not os.path.isfile(hash_path):
- LOG.warning('Expected an account lock file %s to remove, but '
- 'one did not exist', hash_path)
- else:
- os.remove(hash_path)
- if not os.listdir(self.accounts_dir):
- os.rmdir(self.accounts_dir)
+ if self._process_project(hash_string, use=False):
+ hash_path = os.path.join(self.accounts_dir, hash_string)
+ if not os.path.isfile(hash_path):
+ LOG.warning('Expected an account lock file %s to remove, but '
+ 'one did not exist', hash_path)
+ else:
+ os.remove(hash_path)
+ if not os.listdir(self.accounts_dir):
+ os.rmdir(self.accounts_dir)
def get_hash(self, creds):
for _hash in self.hash_dict['creds']:
@@ -521,5 +539,36 @@
def _exclude_used_projects(self, hashes, used_projects):
excluded_accounts = []
for project in used_projects:
- excluded_accounts.extend(self.hash_dict['projects'][project])
+ if project in self.hash_dict['projects']:
+ excluded_accounts.extend(self.hash_dict['projects'][project])
return set(hashes) - set(excluded_accounts)
+
+ @staticmethod
+ def do_tests_require_projects_with_networks(network_resources):
+ """take projects with networks or projects without networks
+
+ :return: boolean value
+ """
+ if isinstance(network_resources, dict):
+ if any(network_resources.values()):
+ return True
+ return False
+
+ @staticmethod
+ def is_account_needed(tests_require_projects_with_networks, account,
+ separate_projects_by_network_existence=False):
+ """decides whether we need account for test class
+
+ :param tests_require_projects_with_networks: need projects with or
+ without network
+ :param account: dictionary which contains username, password, resources
+ :param separate_projects_by_network_existence: should we separate
+ accounts with and without networks
+ :return: boolean value
+ """
+ if ({'project_name', 'tenant_name'} & account.keys()) and \
+ separate_projects_by_network_existence:
+ is_network_in_resources = 'network' in account.get('resources', {})
+ return is_network_in_resources ==\
+ tests_require_projects_with_networks
+ return True
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index fa43e58..ef81558 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -492,7 +492,9 @@
self.assertFalse(
verify_tempest_config.contains_version('v5.', ['v1.0', 'v2.0']))
- def test_check_service_availability(self):
+ @mock.patch('tempest.cmd.verify_tempest_config.CONF._config',
+ new_callable=fake_config.FakePrivate)
+ def test_check_service_availability(self, mock_config):
class FakeAuthProvider:
def get_auth(self):
return ('token',
@@ -505,7 +507,6 @@
class Fake_os:
auth_provider = FakeAuthProvider()
auth_version = 'v2'
- verify_tempest_config.CONF._config = fake_config.FakePrivate()
services = verify_tempest_config.check_service_availability(
Fake_os(), True)
self.assertEqual(
diff --git a/tempest/tests/common/test_credentials_factory.py b/tempest/tests/common/test_credentials_factory.py
index 8a1158d..bff3506 100644
--- a/tempest/tests/common/test_credentials_factory.py
+++ b/tempest/tests/common/test_credentials_factory.py
@@ -129,14 +129,14 @@
mock_preprov_provider_params.return_value = expected_params
expected_name = 'my_name'
expected_identity_version = 'identity_version'
- cf.get_credentials_provider(
- expected_name,
- force_tenant_isolation=False,
- identity_version=expected_identity_version)
+ cf.get_credentials_provider(expected_name,
+ identity_version=expected_identity_version)
mock_preprov_provider_params.assert_called_once_with(
expected_identity_version)
mock_preprov_credentials_provider_class.assert_called_once_with(
- name=expected_name, **expected_params)
+ name=expected_name, network_resources=None,
+ separate_projects_by_network_existence=False,
+ **expected_params)
def test_get_credentials_provider_preprov_no_file(self):
cfg.CONF.set_default('use_dynamic_credentials', False, group='auth')
diff --git a/tempest/tests/lib/common/test_preprov_creds.py b/tempest/tests/lib/common/test_preprov_creds.py
index c1a8e72..04e6771 100644
--- a/tempest/tests/lib/common/test_preprov_creds.py
+++ b/tempest/tests/lib/common/test_preprov_creds.py
@@ -342,7 +342,7 @@
'tempest.lib.common.preprov_creds.read_accounts_yaml',
return_value=test_accounts))
test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
- **self.fixed_params)
+ network_resources={"test": "test"}, **self.fixed_params)
with mock.patch('tempest.lib.services.network.networks_client.'
'NetworksClient.list_networks',
return_value={'networks': [{'name': 'network-2',