Merge "Improving test_volumes_get testcase"
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index 150e8af..3754637 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -49,6 +49,9 @@
name=snapshot_name,
wait_until='SAVING')
self.client.delete_image(image['id'])
+ msg = ('The image with ID {image_id} failed to be deleted'
+ .format(image_id=image['id']))
+ self.assertTrue(self.client.is_resource_deleted(image['id']), msg)
@test.idempotent_id('aaacd1d0-55a2-4ce8-818a-b5439df8adc9')
def test_create_image_from_stopped_server(self):
diff --git a/tempest/api/identity/admin/v3/test_credentials.py b/tempest/api/identity/admin/v3/test_credentials.py
index 7c2e8e0..12b236f 100644
--- a/tempest/api/identity/admin/v3/test_credentials.py
+++ b/tempest/api/identity/admin/v3/test_credentials.py
@@ -37,7 +37,7 @@
cls.projects.append(cls.project['id'])
cls.user_body = cls.users_client.create_user(
- u_name, description=u_desc, password=u_password,
+ name=u_name, description=u_desc, password=u_password,
email=u_email, project_id=cls.projects[0])['user']
@classmethod
diff --git a/tempest/api/identity/admin/v3/test_default_project_id.py b/tempest/api/identity/admin/v3/test_default_project_id.py
index a540da7..3616e77 100644
--- a/tempest/api/identity/admin/v3/test_default_project_id.py
+++ b/tempest/api/identity/admin/v3/test_default_project_id.py
@@ -54,7 +54,7 @@
# default project
user_name = data_utils.rand_name('user')
user_body = self.users_client.create_user(
- user_name,
+ name=user_name,
password=user_name,
domain_id=dom_id,
default_project_id=proj_id)['user']
diff --git a/tempest/api/identity/admin/v3/test_groups.py b/tempest/api/identity/admin/v3/test_groups.py
index 59fcec6..48e5f02 100644
--- a/tempest/api/identity/admin/v3/test_groups.py
+++ b/tempest/api/identity/admin/v3/test_groups.py
@@ -83,7 +83,8 @@
for i in range(3):
name = data_utils.rand_name('User')
password = data_utils.rand_password()
- user = self.users_client.create_user(name, password)['user']
+ user = self.users_client.create_user(name=name,
+ password=password)['user']
users.append(user)
self.addCleanup(self.users_client.delete_user, user['id'])
self.groups_client.add_group_user(group['id'], user['id'])
@@ -103,7 +104,8 @@
def test_list_user_groups(self):
# create a user
user = self.users_client.create_user(
- data_utils.rand_name('User'), data_utils.rand_password())['user']
+ name=data_utils.rand_name('User'),
+ password=data_utils.rand_password())['user']
self.addCleanup(self.users_client.delete_user, user['id'])
# create two groups, and add user into them
groups = []
diff --git a/tempest/api/identity/admin/v3/test_inherits.py b/tempest/api/identity/admin/v3/test_inherits.py
index fe20349..0d3d1d6 100644
--- a/tempest/api/identity/admin/v3/test_inherits.py
+++ b/tempest/api/identity/admin/v3/test_inherits.py
@@ -44,7 +44,7 @@
name=data_utils.rand_name('group-'), project_id=cls.project['id'],
domain_id=cls.domain['id'])['group']
cls.user = cls.users_client.create_user(
- u_name, description=u_desc, password=u_password,
+ name=u_name, description=u_desc, password=u_password,
email=u_email, project_id=cls.project['id'],
domain_id=cls.domain['id'])['user']
diff --git a/tempest/api/identity/admin/v3/test_list_users.py b/tempest/api/identity/admin/v3/test_list_users.py
index 9691ee8..99df559 100644
--- a/tempest/api/identity/admin/v3/test_list_users.py
+++ b/tempest/api/identity/admin/v3/test_list_users.py
@@ -25,7 +25,7 @@
# assert the response based on expected and not_expected
# expected: user expected in the list response
# not_expected: user, which should not be present in list response
- body = self.users_client.list_users(params)['users']
+ body = self.users_client.list_users(**params)['users']
self.assertIn(expected[key], map(lambda x: x[key], body))
self.assertNotIn(not_expected[key],
map(lambda x: x[key], body))
@@ -42,13 +42,13 @@
cls.users = list()
u1_name = data_utils.rand_name('test_user')
cls.domain_enabled_user = cls.users_client.create_user(
- u1_name, password=alt_password,
+ name=u1_name, password=alt_password,
email=cls.alt_email, domain_id=cls.domain['id'])['user']
cls.users.append(cls.domain_enabled_user)
# Create default not enabled user
u2_name = data_utils.rand_name('test_user')
cls.non_domain_enabled_user = cls.users_client.create_user(
- u2_name, password=alt_password,
+ name=u2_name, password=alt_password,
email=cls.alt_email, enabled=False)['user']
cls.users.append(cls.non_domain_enabled_user)
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index 1879e46..1137191 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -200,7 +200,7 @@
u_email = u_name + '@testmail.tm'
u_password = data_utils.rand_password()
user = self.users_client.create_user(
- u_name, description=u_desc, password=u_password,
+ name=u_name, description=u_desc, password=u_password,
email=u_email, project_id=project['id'])['user']
# Delete the User at the end of this method
self.addCleanup(self.users_client.delete_user, user['id'])
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index 2b77023..4ecf0a5 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -44,7 +44,7 @@
name=data_utils.rand_name('Group'), project_id=cls.project['id'],
domain_id=cls.domain['id'])['group']
cls.user_body = cls.users_client.create_user(
- u_name, description=u_desc, password=cls.u_password,
+ name=u_name, description=u_desc, password=cls.u_password,
email=u_email, project_id=cls.project['id'],
domain_id=cls.domain['id'])['user']
cls.role = cls.roles_client.create_role(
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index 89cfd5b..fcf4772 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -32,7 +32,7 @@
u_email = '%s@testmail.tm' % u_name
u_password = data_utils.rand_password()
user = self.users_client.create_user(
- u_name, description=u_desc, password=u_password,
+ name=u_name, description=u_desc, password=u_password,
email=u_email)['user']
self.addCleanup(self.users_client.delete_user, user['id'])
# Perform Authentication
@@ -62,7 +62,7 @@
# Create a user.
user_name = data_utils.rand_name(name='user')
user_password = data_utils.rand_password()
- user = self.users_client.create_user(user_name,
+ user = self.users_client.create_user(name=user_name,
password=user_password)['user']
self.addCleanup(self.users_client.delete_user, user['id'])
diff --git a/tempest/api/identity/admin/v3/test_trusts.py b/tempest/api/identity/admin/v3/test_trusts.py
index 9c8f1f6..58e2ab8 100644
--- a/tempest/api/identity/admin/v3/test_trusts.py
+++ b/tempest/api/identity/admin/v3/test_trusts.py
@@ -57,7 +57,7 @@
u_email = self.trustor_username + '@testmail.xx'
self.trustor_password = data_utils.rand_password()
user = self.users_client.create_user(
- self.trustor_username,
+ name=self.trustor_username,
description=u_desc,
password=self.trustor_password,
email=u_email,
diff --git a/tempest/api/identity/admin/v3/test_users.py b/tempest/api/identity/admin/v3/test_users.py
index f200095..1bcec62 100644
--- a/tempest/api/identity/admin/v3/test_users.py
+++ b/tempest/api/identity/admin/v3/test_users.py
@@ -31,7 +31,7 @@
u_email = u_name + '@testmail.tm'
u_password = data_utils.rand_password()
user = self.users_client.create_user(
- u_name, description=u_desc, password=u_password,
+ name=u_name, description=u_desc, password=u_password,
email=u_email, enabled=False)['user']
# Delete the User at the end of this method
self.addCleanup(self.users_client.delete_user, user['id'])
@@ -71,7 +71,7 @@
u_name = data_utils.rand_name('user')
original_password = data_utils.rand_password()
user = self.users_client.create_user(
- u_name, password=original_password)['user']
+ name=u_name, password=original_password)['user']
# Delete the User at the end all test methods
self.addCleanup(self.users_client.delete_user, user['id'])
# Update user with new password
@@ -107,7 +107,7 @@
u_email = u_name + '@testmail.tm'
u_password = data_utils.rand_password()
user_body = self.users_client.create_user(
- u_name, description=u_desc, password=u_password,
+ name=u_name, description=u_desc, password=u_password,
email=u_email, enabled=False, project_id=u_project['id'])['user']
# Delete the User at the end of this method
self.addCleanup(self.users_client.delete_user, user_body['id'])
diff --git a/tempest/api/identity/admin/v3/test_users_negative.py b/tempest/api/identity/admin/v3/test_users_negative.py
index 71e8bc5..5b0fc97 100644
--- a/tempest/api/identity/admin/v3/test_users_negative.py
+++ b/tempest/api/identity/admin/v3/test_users_negative.py
@@ -29,7 +29,7 @@
u_email = u_name + '@testmail.tm'
u_password = data_utils.rand_password()
self.assertRaises(lib_exc.NotFound, self.users_client.create_user,
- u_name, u_password,
+ name=u_name, password=u_password,
email=u_email,
domain_id=data_utils.rand_uuid_hex())
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index ce052e6..b512d50 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -39,7 +39,7 @@
def get_user_by_name(cls, name, domain_id=None):
if domain_id:
params = {'domain_id': domain_id}
- users = cls.users_client.list_users(params)['users']
+ users = cls.users_client.list_users(**params)['users']
else:
users = cls.users_client.list_users()['users']
user = [u for u in users if u['name'] == name]
@@ -200,7 +200,7 @@
@classmethod
def disable_user(cls, user_name, domain_id=None):
user = cls.get_user_by_name(user_name, domain_id)
- cls.users_client.update_user(user['id'], user_name, enabled=False)
+ cls.users_client.update_user(user['id'], name=user_name, enabled=False)
@classmethod
def create_domain(cls):
@@ -221,7 +221,7 @@
project = self.setup_test_project()
username = data_utils.rand_name('test_user')
email = username + '@testmail.tm'
- user = self._create_test_user(user_name=username, email=email,
+ user = self._create_test_user(name=username, email=email,
project_id=project['id'],
password=password)
return user
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index f7176f4..b5ef7c0 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -61,20 +61,11 @@
# Create 3 test volumes
cls.volume_list = []
- cls.volume_id_list = []
cls.metadata = {'Type': 'work'}
for i in range(3):
volume = cls.create_volume(metadata=cls.metadata)
volume = cls.client.show_volume(volume['id'])['volume']
cls.volume_list.append(volume)
- cls.volume_id_list.append(volume['id'])
-
- @classmethod
- def resource_cleanup(cls):
- # Delete the created volumes
- for volid in cls.volume_id_list:
- cls.delete_volume(cls.client, volid)
- super(VolumesV2ListTestJSON, cls).resource_cleanup()
def _list_by_param_value_and_assert(self, params, with_detail=False):
"""list or list_details with given params and validates result"""
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index 1fdcb49..c501ffc 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -42,22 +42,13 @@
super(VolumesV2ListTestJSON, cls).resource_setup()
# Create 3 test volumes
- cls.volume_list = []
cls.volume_id_list = []
cls.metadata = {'Type': 'work'}
for i in range(3):
volume = cls.create_volume(metadata=cls.metadata)
volume = cls.client.show_volume(volume['id'])['volume']
- cls.volume_list.append(volume)
cls.volume_id_list.append(volume['id'])
- @classmethod
- def resource_cleanup(cls):
- # Delete the created volumes
- for volid in cls.volume_id_list:
- cls.delete_volume(cls.client, volid)
- super(VolumesV2ListTestJSON, cls).resource_cleanup()
-
@test.idempotent_id('2a7064eb-b9c3-429b-b888-33928fc5edd3')
def test_volume_list_details_with_multiple_params(self):
# List volumes detail using combined condition
diff --git a/tempest/clients.py b/tempest/clients.py
index 406f9d5..e14f6f8 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -97,19 +97,16 @@
This uses `config.service_client_config` for all services to collect
most configuration items needed to init the clients.
"""
- # NOTE(andreaf) Configuration items will be passed in future patches
- # into ClientFactory objects, but for now we update all the
- # _set_*_client methods to consume them so we can verify that the
- # configuration collected is correct
+ # NOTE(andreaf) Once all service clients in Tempest are migrated
+ # to tempest.lib, their configuration will be picked up from the
+ # registry, and this method will become redundant.
configuration = {}
- # Setup the parameters for all Tempest services.
+ # Setup the parameters for all Tempest services which are not in lib.
# NOTE(andreaf) Since client.py is an internal module of Tempest,
# it doesn't have to consider plugin configuration.
- all_tempest_modules = (set(clients.tempest_modules()) |
- clients._tempest_internal_modules())
- for service in all_tempest_modules:
+ for service in clients._tempest_internal_modules():
try:
# NOTE(andreaf) Use the unversioned service name to fetch
# the configuration since configuration is not versioned.
diff --git a/tempest/cmd/init.py b/tempest/cmd/init.py
index e3788ab..bf7289a 100644
--- a/tempest/cmd/init.py
+++ b/tempest/cmd/init.py
@@ -89,18 +89,28 @@
with open(testr_conf_path, 'w+') as testr_conf_file:
testr_conf_file.write(testr_conf)
- def update_local_conf(self, conf_path, lock_dir, log_dir):
+ def get_configparser(self, conf_path):
config_parse = moves.configparser.SafeConfigParser()
config_parse.optionxform = str
- with open(conf_path, 'a+') as conf_file:
- # Set local lock_dir in tempest conf
- if not config_parse.has_section('oslo_concurrency'):
- config_parse.add_section('oslo_concurrency')
- config_parse.set('oslo_concurrency', 'lock_path', lock_dir)
- # Set local log_dir in tempest conf
- config_parse.set('DEFAULT', 'log_dir', log_dir)
- # Set default log filename to tempest.log
- config_parse.set('DEFAULT', 'log_file', 'tempest.log')
+ # get any existing values if a config file already exists
+ if os.path.isfile(conf_path):
+ # use read() for Python 2 and 3 compatibility
+ config_parse.read(conf_path)
+ return config_parse
+
+ def update_local_conf(self, conf_path, lock_dir, log_dir):
+ config_parse = self.get_configparser(conf_path)
+ # Set local lock_dir in tempest conf
+ if not config_parse.has_section('oslo_concurrency'):
+ config_parse.add_section('oslo_concurrency')
+ config_parse.set('oslo_concurrency', 'lock_path', lock_dir)
+ # Set local log_dir in tempest conf
+ config_parse.set('DEFAULT', 'log_dir', log_dir)
+ # Set default log filename to tempest.log
+ config_parse.set('DEFAULT', 'log_file', 'tempest.log')
+
+ # write out a new file with the updated configurations
+ with open(conf_path, 'w+') as conf_file:
config_parse.write(conf_file)
def copy_config(self, etc_dir, config_dir):
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 77b88f9..9947f2a 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -147,6 +147,10 @@
contains_version('v2.', versions)):
print_and_or_update('api_v2', 'volume-feature-enabled',
not CONF.volume_feature_enabled.api_v2, update)
+ if (CONF.volume_feature_enabled.api_v3 !=
+ contains_version('v3.', versions)):
+ print_and_or_update('api_v3', 'volume-feature-enabled',
+ not CONF.volume_feature_enabled.api_v3, update)
def verify_api_versions(os, service, update):
diff --git a/tempest/common/cred_client.py b/tempest/common/cred_client.py
index 2ca9f40..4e3c395 100644
--- a/tempest/common/cred_client.py
+++ b/tempest/common/cred_client.py
@@ -40,8 +40,10 @@
self.roles_client = roles_client
def create_user(self, username, password, project, email):
- params = self._create_user_params(username, password,
- project['id'], email)
+ params = {'name': username,
+ 'password': password,
+ self.project_id_param: project['id'],
+ 'email': email}
user = self.users_client.create_user(**params)
if 'user' in user:
user = user['user']
@@ -94,6 +96,7 @@
class V2CredsClient(CredsClient):
+ project_id_param = 'tenantId'
def __init__(self, identity_client, projects_client, users_client,
roles_client):
@@ -102,13 +105,6 @@
users_client,
roles_client)
- def _create_user_params(self, username, password, project_id, email):
- params = {'name': username,
- 'password': password,
- 'tenantId': project_id,
- 'email': email}
- return params
-
def create_project(self, name, description):
tenant = self.projects_client.create_tenant(
name=name, description=description)['tenant']
@@ -135,6 +131,7 @@
class V3CredsClient(CredsClient):
+ project_id_param = 'project_id'
def __init__(self, identity_client, projects_client, users_client,
roles_client, domains_client, domain_name):
@@ -152,13 +149,6 @@
msg = "Requested domain %s could not be found" % domain_name
raise lib_exc.InvalidCredentials(msg)
- def _create_user_params(self, username, password, project_id, email):
- params = {'user_name': username,
- 'password': password,
- 'project_id': project_id,
- 'email': email}
- return params
-
def create_project(self, name, description):
project = self.projects_client.create_project(
name=name, description=description,
diff --git a/tempest/config.py b/tempest/config.py
index 84edede..3fd20ab 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -26,6 +26,7 @@
import testtools
from tempest.lib import exceptions
+from tempest.lib.services import clients
from tempest.test_discover import plugins
@@ -1288,6 +1289,15 @@
lockutils.set_defaults(lock_dir)
self._config = TempestConfigPrivate(config_path=self._path)
+ # Pushing tempest internal service client configuration to the
+ # service clients register. Doing this in the config module ensures
+ # that the configuration is available by the time we register the
+ # service clients.
+ # NOTE(andreaf) This has to be done at the time the first
+ # attribute is accessed, to ensure all plugins have been already
+ # loaded, options registered, and _config is set.
+ _register_tempest_service_clients()
+
return getattr(self._config, attr)
def set_config_path(self, path):
@@ -1447,3 +1457,29 @@
# Set service
_parameters['service'] = getattr(options, 'catalog_type')
return _parameters
+
+
+def _register_tempest_service_clients():
+ # Register tempest own service clients using the same mechanism used
+ # for external plugins.
+ # The configuration data is pushed to the registry so that automatic
+ # configuration of tempest own service clients is possible both for
+ # tempest as well as for the plugins.
+ service_clients = clients.tempest_modules()
+ registry = clients.ClientsRegistry()
+ all_clients = []
+ for service_client in service_clients:
+ module = service_clients[service_client]
+ configs = service_client.split('.')[0]
+ service_client_data = dict(
+ name=service_client.replace('.', '_'),
+ service_version=service_client,
+ module_path=module.__name__,
+ client_names=module.__all__,
+ **service_client_config(configs)
+ )
+ all_clients.append(service_client_data)
+ # NOTE(andreaf) Internal service clients do not actually belong
+ # to a plugin, so using '__tempest__' to indicate a virtual plugin
+ # which holds internal service clients.
+ registry.register_service_client('__tempest__', all_clients)
diff --git a/tempest/lib/services/clients.py b/tempest/lib/services/clients.py
index e782321..adf666b 100644
--- a/tempest/lib/services/clients.py
+++ b/tempest/lib/services/clients.py
@@ -18,7 +18,6 @@
import importlib
import inspect
import logging
-import six
from tempest.lib import auth
from tempest.lib.common.utils import misc
@@ -90,11 +89,14 @@
plug_service_versions))
raise exceptions.PluginRegistrationException(
name=plugin_name, detailed_error=detailed_error)
- if not plug_service_versions.isdisjoint(_tempest_modules):
+ # NOTE(andreaf) Once all tempest clients are stable, the following
+ # if will have to be removed.
+ if not plug_service_versions.isdisjoint(
+ _tempest_internal_modules()):
detailed_error = (
'Plugin %s is trying to register a service %s already '
'claimed by a Tempest one' % (plugin_name,
- _tempest_modules &
+ _tempest_internal_modules() &
plug_service_versions))
raise exceptions.PluginRegistrationException(
name=plugin_name, detailed_error=detailed_error)
@@ -351,15 +353,7 @@
raise exceptions.UnknownServiceClient(
services=list(client_parameters.keys()))
- # Register service clients owned by tempest
- for service, module in six.iteritems(tempest_modules()):
- attribute = service.replace('.', '_')
- configs = service.split('.')[0]
- self.register_service_client_module(
- attribute, service, module.__name__,
- module.__all__, **self.parameters[configs])
-
- # Register service clients from plugins
+ # Register service clients from the registry (__tempest__ and plugins)
clients_registry = ClientsRegistry()
plugin_service_clients = clients_registry.get_service_clients()
for plugin in plugin_service_clients:
@@ -432,6 +426,8 @@
@property
def registered_services(self):
+ # NOTE(andreaf) Once all tempest modules are stable this needs to
+ # be updated to remove _tempest_internal_modules
return self._registered_services | _tempest_internal_modules()
def _setup_parameters(self, parameters):
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 952c0c2..6da0570 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -127,6 +127,21 @@
wait_dict['client'] = waiter_client
self.cleanup_waits.append(wait_dict)
+ def _create_port(self, network_id, client=None, namestart='port-quotatest',
+ **kwargs):
+ if not client:
+ client = self.ports_client
+ name = data_utils.rand_name(namestart)
+ result = client.create_port(
+ name=name,
+ network_id=network_id,
+ **kwargs)
+ self.assertIsNotNone(result, 'Unable to allocate port')
+ port = result['port']
+ self.addCleanup(test_utils.call_and_ignore_notfound_exc,
+ client.delete_port, port['id'])
+ return port
+
def _wait_for_cleanups(self):
# To handle async delete actions, a list of waits is added
# which will be iterated over as the last step of clearing the
@@ -209,18 +224,18 @@
networks = []
# If there are no networks passed to us we look up
- # for the project's private networks and create a port
- # if there is only one private network. The same behaviour
- # as we would expect when passing the call to the clients
- # with no networks
+ # for the project's private networks and create a port.
+ # The same behaviour as we would expect when passing
+ # the call to the clients with no networks
if not networks:
networks = clients.networks_client.list_networks(
- filters={'router:external': False})
- self.assertEqual(1, len(networks),
- "There is more than one"
- " network for the tenant")
+ **{'router:external': False, 'fields': 'id'})['networks']
+
+ # It's net['uuid'] if networks come from kwargs
+ # and net['id'] if they come from
+ # clients.networks_client.list_networks
for net in networks:
- net_id = net['uuid']
+ net_id = net.get('uuid', net['id'])
if 'port' not in net:
port = self._create_port(network_id=net_id,
client=clients.ports_client,
@@ -813,21 +828,6 @@
return subnet
- def _create_port(self, network_id, client=None, namestart='port-quotatest',
- **kwargs):
- if not client:
- client = self.ports_client
- name = data_utils.rand_name(namestart)
- result = client.create_port(
- name=name,
- network_id=network_id,
- **kwargs)
- self.assertIsNotNone(result, 'Unable to allocate port')
- port = result['port']
- self.addCleanup(test_utils.call_and_ignore_notfound_exc,
- client.delete_port, port['id'])
- return port
-
def _get_server_port_id_and_ip4(self, server, ip_addr=None):
ports = self._list_ports(device_id=server['id'], fixed_ip=ip_addr)
# A port can have more then one IP address in some cases.
diff --git a/tempest/services/identity/v3/json/groups_client.py b/tempest/services/identity/v3/json/groups_client.py
index 1a495f8..628b3e1 100644
--- a/tempest/services/identity/v3/json/groups_client.py
+++ b/tempest/services/identity/v3/json/groups_client.py
@@ -18,6 +18,7 @@
"""
from oslo_serialization import jsonutils as json
+from six.moves.urllib import parse as urllib
from tempest.lib.common import rest_client
@@ -44,9 +45,16 @@
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
- def list_groups(self):
- """Lists the groups."""
- resp, body = self.get('groups')
+ def list_groups(self, **params):
+ """Lists the groups.
+
+ Available params: see http://developer.openstack.org/
+ api-ref/identity/v3/#list-groups
+ """
+ url = 'groups'
+ if params:
+ url += '?%s' % urllib.urlencode(params)
+ resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
@@ -76,9 +84,16 @@
self.expected_success(204, resp.status)
return rest_client.ResponseBody(resp, body)
- def list_group_users(self, group_id):
- """List users in group."""
- resp, body = self.get('groups/%s/users' % group_id)
+ def list_group_users(self, group_id, **params):
+ """List users in group.
+
+ Available params: see http://developer.openstack.org/
+ api-ref/identity/v3/#list-users-in-group
+ """
+ url = 'groups/%s/users' % group_id
+ if params:
+ url += '?%s' % urllib.urlencode(params)
+ resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/services/identity/v3/json/users_clients.py b/tempest/services/identity/v3/json/users_clients.py
index 73bd343..0dcdacd 100644
--- a/tempest/services/identity/v3/json/users_clients.py
+++ b/tempest/services/identity/v3/json/users_clients.py
@@ -21,56 +21,27 @@
class UsersClient(rest_client.RestClient):
api_version = "v3"
- def create_user(self, user_name, password=None, project_id=None,
- email=None, domain_id='default', **kwargs):
- """Creates a user."""
- en = kwargs.get('enabled', True)
- description = kwargs.get('description', None)
- default_project_id = kwargs.get('default_project_id')
- post_body = {
- 'project_id': project_id,
- 'default_project_id': default_project_id,
- 'description': description,
- 'domain_id': domain_id,
- 'email': email,
- 'enabled': en,
- 'name': user_name,
- 'password': password
- }
- post_body = json.dumps({'user': post_body})
+ def create_user(self, **kwargs):
+ """Creates a user.
+
+ Available params: see http://developer.openstack.org/
+ api-ref/identity/v3/#create-user
+ """
+ post_body = json.dumps({'user': kwargs})
resp, body = self.post('users', post_body)
self.expected_success(201, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
- def update_user(self, user_id, name, **kwargs):
+ def update_user(self, user_id, **kwargs):
"""Updates a user.
Available params: see http://developer.openstack.org/
api-ref-identity-v3.html#updateUser
"""
- body = self.show_user(user_id)['user']
- email = kwargs.get('email', body['email'])
- en = kwargs.get('enabled', body['enabled'])
- project_id = kwargs.get('project_id', body['project_id'])
- if 'default_project_id' in body.keys():
- default_project_id = kwargs.get('default_project_id',
- body['default_project_id'])
- else:
- default_project_id = kwargs.get('default_project_id')
- description = kwargs.get('description', body['description'])
- domain_id = kwargs.get('domain_id', body['domain_id'])
- post_body = {
- 'name': name,
- 'email': email,
- 'enabled': en,
- 'project_id': project_id,
- 'default_project_id': default_project_id,
- 'id': user_id,
- 'domain_id': domain_id,
- 'description': description
- }
- post_body = json.dumps({'user': post_body})
+ if 'id' not in kwargs:
+ kwargs['id'] = user_id
+ post_body = json.dumps({'user': kwargs})
resp, body = self.patch('users/%s' % user_id, post_body)
self.expected_success(200, resp.status)
body = json.loads(body)
@@ -87,15 +58,26 @@
self.expected_success(204, resp.status)
return rest_client.ResponseBody(resp)
- def list_user_projects(self, user_id):
- """Lists the projects on which a user has roles assigned."""
- resp, body = self.get('users/%s/projects' % user_id)
+ def list_user_projects(self, user_id, **params):
+ """Lists the projects on which a user has roles assigned.
+
+ Available params: see http://developer.openstack.org/
+ api-ref/identity/v3/#list-projects-for-user
+ """
+ url = 'users/%s/projects' % user_id
+ if params:
+ url += '?%s' % urllib.urlencode(params)
+ resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
- def list_users(self, params=None):
- """Get the list of users."""
+ def list_users(self, **params):
+ """Get the list of users.
+
+ Available params: see http://developer.openstack.org/
+ api-ref/identity/v3/#list-users
+ """
url = 'users'
if params:
url += '?%s' % urllib.urlencode(params)
@@ -117,9 +99,16 @@
self.expected_success(204, resp.status)
return rest_client.ResponseBody(resp, body)
- def list_user_groups(self, user_id):
- """Lists groups which a user belongs to."""
- resp, body = self.get('users/%s/groups' % user_id)
+ def list_user_groups(self, user_id, **params):
+ """Lists groups which a user belongs to.
+
+ Available params: see http://developer.openstack.org/
+ api-ref/identity/v3/#list-groups-to-which-a-user-belongs
+ """
+ url = 'users/%s/groups' % user_id
+ if params:
+ url += '?%s' % urllib.urlencode(params)
+ resp, body = self.get(url)
self.expected_success(200, resp.status)
body = json.loads(body)
return rest_client.ResponseBody(resp, body)
diff --git a/tempest/tests/cmd/test_tempest_init.py b/tempest/tests/cmd/test_tempest_init.py
index 031bf4d..2844371 100644
--- a/tempest/tests/cmd/test_tempest_init.py
+++ b/tempest/tests/cmd/test_tempest_init.py
@@ -45,6 +45,7 @@
init_cmd = init.TempestInit(None, None)
local_sample_conf_file = os.path.join(etc_dir_path,
'tempest.conf.sample')
+
# Verify no sample config file exist
self.assertFalse(os.path.isfile(local_sample_conf_file))
init_cmd.generate_sample_config(local_dir.path)
@@ -53,6 +54,52 @@
self.assertTrue(os.path.isfile(local_sample_conf_file))
self.assertGreater(os.path.getsize(local_sample_conf_file), 0)
+ def test_update_local_conf(self):
+ local_dir = self.useFixture(fixtures.TempDir())
+ etc_dir_path = os.path.join(local_dir.path, 'etc/')
+ os.mkdir(etc_dir_path)
+ lock_dir = os.path.join(local_dir.path, 'tempest_lock')
+ config_path = os.path.join(etc_dir_path, 'tempest.conf')
+ log_dir = os.path.join(local_dir.path, 'logs')
+
+ init_cmd = init.TempestInit(None, None)
+
+ # Generate the config file
+ init_cmd.generate_sample_config(local_dir.path)
+
+ # Create a conf file with populated values
+ config_parser_pre = init_cmd.get_configparser(config_path)
+ with open(config_path, 'w+') as conf_file:
+ # create the same section init will check for and add values to
+ config_parser_pre.add_section('oslo_concurrency')
+ config_parser_pre.set('oslo_concurrency', 'TEST', local_dir.path)
+ # create a new section
+ config_parser_pre.add_section('TEST')
+ config_parser_pre.set('TEST', 'foo', "bar")
+ config_parser_pre.write(conf_file)
+
+ # Update the config file the same way tempest init does
+ init_cmd.update_local_conf(config_path, lock_dir, log_dir)
+
+ # parse the new config file to verify it
+ config_parser_post = init_cmd.get_configparser(config_path)
+
+ # check that our value in oslo_concurrency wasn't overwritten
+ self.assertTrue(config_parser_post.has_section('oslo_concurrency'))
+ self.assertEqual(config_parser_post.get('oslo_concurrency', 'TEST'),
+ local_dir.path)
+ # check that the lock directory was set correctly
+ self.assertEqual(config_parser_post.get('oslo_concurrency',
+ 'lock_path'), lock_dir)
+
+ # check that our new section still exists and wasn't modified
+ self.assertTrue(config_parser_post.has_section('TEST'))
+ self.assertEqual(config_parser_post.get('TEST', 'foo'), 'bar')
+
+ # check that the DEFAULT values are correct
+ # NOTE(auggy): has_section ignores DEFAULT
+ self.assertEqual(config_parser_post.get('DEFAULT', 'log_dir'), log_dir)
+
def test_create_working_dir_with_existing_local_dir_non_empty(self):
fake_local_dir = self.useFixture(fixtures.TempDir())
fake_local_conf_dir = self.useFixture(fixtures.TempDir())
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 70cbf87..00b4542 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -188,34 +188,54 @@
False, True)
@mock.patch('tempest.lib.common.http.ClosingHttp.request')
- def test_verify_cinder_api_versions_no_v2(self, mock_request):
+ def test_verify_cinder_api_versions_no_v3(self, mock_request):
self.useFixture(mockpatch.PatchObject(
verify_tempest_config, '_get_unversioned_endpoint',
return_value='http://fake_endpoint:5000'))
- fake_resp = {'versions': [{'id': 'v1.0'}]}
+ fake_resp = {'versions': [{'id': 'v1.0'}, {'id': 'v2.0'}]}
fake_resp = json.dumps(fake_resp)
mock_request.return_value = (None, fake_resp)
fake_os = mock.MagicMock()
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_cinder_api_versions(fake_os, True)
- print_mock.assert_called_once_with('api_v2', 'volume-feature-enabled',
- False, True)
+ print_mock.assert_not_called()
+
+ @mock.patch('tempest.lib.common.http.ClosingHttp.request')
+ def test_verify_cinder_api_versions_no_v2(self, mock_request):
+ self.useFixture(mockpatch.PatchObject(
+ verify_tempest_config, '_get_unversioned_endpoint',
+ return_value='http://fake_endpoint:5000'))
+ fake_resp = {'versions': [{'id': 'v1.0'}, {'id': 'v3.0'}]}
+ fake_resp = json.dumps(fake_resp)
+ mock_request.return_value = (None, fake_resp)
+ fake_os = mock.MagicMock()
+ with mock.patch.object(verify_tempest_config,
+ 'print_and_or_update') as print_mock:
+ verify_tempest_config.verify_cinder_api_versions(fake_os, True)
+ print_mock.assert_any_call('api_v2', 'volume-feature-enabled',
+ False, True)
+ print_mock.assert_any_call('api_v3', 'volume-feature-enabled',
+ True, True)
+ self.assertEqual(2, print_mock.call_count)
@mock.patch('tempest.lib.common.http.ClosingHttp.request')
def test_verify_cinder_api_versions_no_v1(self, mock_request):
self.useFixture(mockpatch.PatchObject(
verify_tempest_config, '_get_unversioned_endpoint',
return_value='http://fake_endpoint:5000'))
- fake_resp = {'versions': [{'id': 'v2.0'}]}
+ fake_resp = {'versions': [{'id': 'v2.0'}, {'id': 'v3.0'}]}
fake_resp = json.dumps(fake_resp)
mock_request.return_value = (None, fake_resp)
fake_os = mock.MagicMock()
with mock.patch.object(verify_tempest_config,
'print_and_or_update') as print_mock:
verify_tempest_config.verify_cinder_api_versions(fake_os, True)
- print_mock.assert_called_once_with('api_v1', 'volume-feature-enabled',
- False, True)
+ print_mock.assert_any_call('api_v1', 'volume-feature-enabled',
+ False, True)
+ print_mock.assert_any_call('api_v3', 'volume-feature-enabled',
+ True, True)
+ self.assertEqual(2, print_mock.call_count)
def test_verify_glance_version_no_v2_with_v1_1(self):
def fake_get_versions():