Merge "Factor up (most) CONF value in clients.Manager"
This commit is contained in:
commit
d519cb7195
@ -0,0 +1,6 @@
|
||||
---
|
||||
features:
|
||||
- A new helper method `service_client_config` has been added
|
||||
to the stable module config.py that returns extracts from
|
||||
configuration into a dictionary the configuration settings
|
||||
relevant for the initisialisation of a service client.
|
@ -21,6 +21,7 @@ from tempest.common import negative_rest_client
|
||||
from tempest import config
|
||||
from tempest import exceptions
|
||||
from tempest.lib import auth
|
||||
from tempest.lib import exceptions as lib_exc
|
||||
from tempest.lib.services import compute
|
||||
from tempest.lib.services import image
|
||||
from tempest.lib.services import network
|
||||
@ -39,15 +40,10 @@ LOG = logging.getLogger(__name__)
|
||||
class Manager(service_clients.ServiceClients):
|
||||
"""Top level manager for OpenStack tempest clients"""
|
||||
|
||||
default_params = {
|
||||
'disable_ssl_certificate_validation':
|
||||
CONF.identity.disable_ssl_certificate_validation,
|
||||
'ca_certs': CONF.identity.ca_certificates_file,
|
||||
'trace_requests': CONF.debug.trace_requests
|
||||
}
|
||||
default_params = config.service_client_config()
|
||||
|
||||
# NOTE: Tempest uses timeout values of compute API if project specific
|
||||
# timeout values don't exist.
|
||||
# TODO(andreaf) This is only used by data_processing and baremetal clients,
|
||||
# and should be removed once they are out of Tempest
|
||||
default_params_with_timeout_values = {
|
||||
'build_interval': CONF.compute.build_interval,
|
||||
'build_timeout': CONF.compute.build_timeout
|
||||
@ -65,7 +61,11 @@ class Manager(service_clients.ServiceClients):
|
||||
_, identity_uri = get_auth_provider_class(credentials)
|
||||
super(Manager, self).__init__(
|
||||
credentials=credentials, identity_uri=identity_uri, scope=scope,
|
||||
region=CONF.identity.region, **self.default_params)
|
||||
region=CONF.identity.region,
|
||||
client_parameters=self._prepare_configuration())
|
||||
# TODO(andreaf) When clients are initialised without the right
|
||||
# parameters available, the calls below will trigger a KeyError.
|
||||
# We should catch that and raise a better error.
|
||||
self._set_compute_clients()
|
||||
self._set_identity_clients()
|
||||
self._set_volume_clients()
|
||||
@ -96,15 +96,38 @@ class Manager(service_clients.ServiceClients):
|
||||
self.negative_client = negative_rest_client.NegativeRestClient(
|
||||
self.auth_provider, service, **self.default_params)
|
||||
|
||||
def _prepare_configuration(self):
|
||||
"""Map values from CONF into Manager parameters
|
||||
|
||||
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
|
||||
|
||||
configuration = {}
|
||||
|
||||
# Setup the parameters for all Tempest services.
|
||||
# NOTE(andreaf) Since client.py is an internal module of Tempest,
|
||||
# it doesn't have to consider plugin configuration.
|
||||
for service in service_clients.tempest_modules():
|
||||
try:
|
||||
# NOTE(andreaf) Use the unversioned service name to fetch
|
||||
# the configuration since configuration is not versioned.
|
||||
service_for_config = service.split('.')[0]
|
||||
if service_for_config not in configuration:
|
||||
configuration[service_for_config] = (
|
||||
config.service_client_config(service_for_config))
|
||||
except lib_exc.UnknownServiceClient:
|
||||
LOG.warn(
|
||||
'Could not load configuration for service %s' % service)
|
||||
|
||||
return configuration
|
||||
|
||||
def _set_network_clients(self):
|
||||
params = {
|
||||
'service': CONF.network.catalog_type,
|
||||
'region': CONF.network.region or CONF.identity.region,
|
||||
'endpoint_type': CONF.network.endpoint_type,
|
||||
'build_interval': CONF.network.build_interval,
|
||||
'build_timeout': CONF.network.build_timeout
|
||||
}
|
||||
params.update(self.default_params)
|
||||
params = self.parameters['network']
|
||||
self.network_agents_client = network.AgentsClient(
|
||||
self.auth_provider, **params)
|
||||
self.network_extensions_client = network.ExtensionsClient(
|
||||
@ -135,20 +158,13 @@ class Manager(service_clients.ServiceClients):
|
||||
self.auth_provider, **params)
|
||||
|
||||
def _set_image_clients(self):
|
||||
params = {
|
||||
'service': CONF.image.catalog_type,
|
||||
'region': CONF.image.region or CONF.identity.region,
|
||||
'endpoint_type': CONF.image.endpoint_type,
|
||||
'build_interval': CONF.image.build_interval,
|
||||
'build_timeout': CONF.image.build_timeout
|
||||
}
|
||||
params.update(self.default_params)
|
||||
|
||||
if CONF.service_available.glance:
|
||||
params = self.parameters['image']
|
||||
self.image_client = image.v1.ImagesClient(
|
||||
self.auth_provider, **params)
|
||||
self.image_member_client = image.v1.ImageMembersClient(
|
||||
self.auth_provider, **params)
|
||||
|
||||
self.image_client_v2 = image.v2.ImagesClient(
|
||||
self.auth_provider, **params)
|
||||
self.image_member_client_v2 = image.v2.ImageMembersClient(
|
||||
@ -161,14 +177,7 @@ class Manager(service_clients.ServiceClients):
|
||||
self.auth_provider, **params)
|
||||
|
||||
def _set_compute_clients(self):
|
||||
params = {
|
||||
'service': CONF.compute.catalog_type,
|
||||
'region': CONF.compute.region or CONF.identity.region,
|
||||
'endpoint_type': CONF.compute.endpoint_type,
|
||||
'build_interval': CONF.compute.build_interval,
|
||||
'build_timeout': CONF.compute.build_timeout
|
||||
}
|
||||
params.update(self.default_params)
|
||||
params = self.parameters['compute']
|
||||
|
||||
self.agents_client = compute.AgentsClient(self.auth_provider, **params)
|
||||
self.compute_networks_client = compute.NetworksClient(
|
||||
@ -234,10 +243,11 @@ class Manager(service_clients.ServiceClients):
|
||||
# NOTE: The following client needs special timeout values because
|
||||
# the API is a proxy for the other component.
|
||||
params_volume = copy.deepcopy(params)
|
||||
params_volume.update({
|
||||
'build_interval': CONF.volume.build_interval,
|
||||
'build_timeout': CONF.volume.build_timeout
|
||||
})
|
||||
# Optional parameters
|
||||
for _key in ('build_interval', 'build_timeout'):
|
||||
_value = self.parameters['volume'].get(_key)
|
||||
if _value:
|
||||
params_volume[_key] = _value
|
||||
self.volumes_extensions_client = compute.VolumesClient(
|
||||
self.auth_provider, **params_volume)
|
||||
self.compute_versions_client = compute.VersionsClient(
|
||||
@ -246,14 +256,10 @@ class Manager(service_clients.ServiceClients):
|
||||
self.auth_provider, **params_volume)
|
||||
|
||||
def _set_identity_clients(self):
|
||||
params = {
|
||||
'service': CONF.identity.catalog_type,
|
||||
'region': CONF.identity.region
|
||||
}
|
||||
params.update(self.default_params_with_timeout_values)
|
||||
params = self.parameters['identity']
|
||||
|
||||
# Clients below use the admin endpoint type of Keystone API v2
|
||||
params_v2_admin = params.copy()
|
||||
params_v2_admin = copy.copy(params)
|
||||
params_v2_admin['endpoint_type'] = CONF.identity.v2_admin_endpoint_type
|
||||
self.endpoints_client = identity.v2.EndpointsClient(self.auth_provider,
|
||||
**params_v2_admin)
|
||||
@ -269,7 +275,7 @@ class Manager(service_clients.ServiceClients):
|
||||
self.auth_provider, **params_v2_admin)
|
||||
|
||||
# Clients below use the public endpoint type of Keystone API v2
|
||||
params_v2_public = params.copy()
|
||||
params_v2_public = copy.copy(params)
|
||||
params_v2_public['endpoint_type'] = (
|
||||
CONF.identity.v2_public_endpoint_type)
|
||||
self.identity_public_client = identity.v2.IdentityClient(
|
||||
@ -279,8 +285,9 @@ class Manager(service_clients.ServiceClients):
|
||||
self.users_public_client = identity.v2.UsersClient(
|
||||
self.auth_provider, **params_v2_public)
|
||||
|
||||
# Clients below use the endpoint type of Keystone API v3
|
||||
params_v3 = params.copy()
|
||||
# Clients below use the endpoint type of Keystone API v3, which is set
|
||||
# in endpoint_type
|
||||
params_v3 = copy.copy(params)
|
||||
params_v3['endpoint_type'] = CONF.identity.v3_endpoint_type
|
||||
self.domains_client = identity.v3.DomainsClient(self.auth_provider,
|
||||
**params_v3)
|
||||
@ -326,14 +333,8 @@ class Manager(service_clients.ServiceClients):
|
||||
raise exceptions.InvalidConfiguration(msg)
|
||||
|
||||
def _set_volume_clients(self):
|
||||
params = {
|
||||
'service': CONF.volume.catalog_type,
|
||||
'region': CONF.volume.region or CONF.identity.region,
|
||||
'endpoint_type': CONF.volume.endpoint_type,
|
||||
'build_interval': CONF.volume.build_interval,
|
||||
'build_timeout': CONF.volume.build_timeout
|
||||
}
|
||||
params.update(self.default_params)
|
||||
# Mandatory parameters (always defined)
|
||||
params = self.parameters['volume']
|
||||
|
||||
self.volume_qos_client = volume.v1.QosSpecsClient(self.auth_provider,
|
||||
**params)
|
||||
@ -381,12 +382,8 @@ class Manager(service_clients.ServiceClients):
|
||||
volume.v2.AvailabilityZoneClient(self.auth_provider, **params)
|
||||
|
||||
def _set_object_storage_clients(self):
|
||||
params = {
|
||||
'service': CONF.object_storage.catalog_type,
|
||||
'region': CONF.object_storage.region or CONF.identity.region,
|
||||
'endpoint_type': CONF.object_storage.endpoint_type
|
||||
}
|
||||
params.update(self.default_params_with_timeout_values)
|
||||
# Mandatory parameters (always defined)
|
||||
params = self.parameters['object-storage']
|
||||
|
||||
self.account_client = object_storage.AccountClient(self.auth_provider,
|
||||
**params)
|
||||
@ -404,12 +401,8 @@ def get_auth_provider_class(credentials):
|
||||
|
||||
|
||||
def get_auth_provider(credentials, pre_auth=False, scope='project'):
|
||||
default_params = {
|
||||
'disable_ssl_certificate_validation':
|
||||
CONF.identity.disable_ssl_certificate_validation,
|
||||
'ca_certs': CONF.identity.ca_certificates_file,
|
||||
'trace_requests': CONF.debug.trace_requests
|
||||
}
|
||||
# kwargs for auth provider match the common ones used by service clients
|
||||
default_params = config.service_client_config()
|
||||
if credentials is None:
|
||||
raise exceptions.InvalidCredentials(
|
||||
'Credentials must be specified')
|
||||
|
@ -25,6 +25,7 @@ from oslo_config import cfg
|
||||
from oslo_log import log as logging
|
||||
import testtools
|
||||
|
||||
from tempest.lib import exceptions
|
||||
from tempest.test_discover import plugins
|
||||
|
||||
|
||||
@ -1350,3 +1351,84 @@ def skip_if_config(*args):
|
||||
return f(self, *func_args, **func_kwargs)
|
||||
return wrapper
|
||||
return decorator
|
||||
|
||||
|
||||
def service_client_config(service_client_name=None):
|
||||
"""Return a dict with the parameters to init service clients
|
||||
|
||||
Extracts from CONF the settings specific to the service_client_name and
|
||||
api_version, and formats them as dict ready to be passed to the service
|
||||
clients __init__:
|
||||
|
||||
* `region` (default to identity)
|
||||
* `catalog_type`
|
||||
* `endpoint_type`
|
||||
* `build_timeout` (object-storage and identity default to compute)
|
||||
* `build_interval` (object-storage and identity default to compute)
|
||||
|
||||
The following common settings are always returned, even if
|
||||
`service_client_name` is None:
|
||||
|
||||
* `disable_ssl_certificate_validation`
|
||||
* `ca_certs`
|
||||
* `trace_requests`
|
||||
|
||||
The dict returned by this does not fit a few service clients:
|
||||
|
||||
* The endpoint type is not returned for identity client, since it takes
|
||||
three different values for v2 admin, v2 public and v3
|
||||
* The `ServersClient` from compute accepts an optional
|
||||
`enable_instance_password` parameter, which is not returned.
|
||||
* The `VolumesClient` for both v1 and v2 volume accept an optional
|
||||
`default_volume_size` parameter, which is not returned.
|
||||
* The `TokenClient` and `V3TokenClient` have a very different
|
||||
interface, only auth_url is needed for them.
|
||||
|
||||
:param service_client_name: str Name of the service. Supported values are
|
||||
'compute', 'identity', 'image', 'network', 'object-storage', 'volume'
|
||||
:return: dictionary of __init__ parameters for the service clients
|
||||
:rtype: dict
|
||||
"""
|
||||
_parameters = {
|
||||
'disable_ssl_certificate_validation':
|
||||
CONF.identity.disable_ssl_certificate_validation,
|
||||
'ca_certs': CONF.identity.ca_certificates_file,
|
||||
'trace_requests': CONF.debug.trace_requests
|
||||
}
|
||||
|
||||
if service_client_name is None:
|
||||
return _parameters
|
||||
|
||||
# Get the group of options first, by normalising the service_group_name
|
||||
# Services with a '-' in the name have an '_' in the option group name
|
||||
config_group = service_client_name.replace('-', '_')
|
||||
# NOTE(andreaf) Check if the config group exists. This allows for this
|
||||
# helper to be used for settings from registered plugins as well
|
||||
try:
|
||||
options = getattr(CONF, config_group)
|
||||
except cfg.NoSuchOptError:
|
||||
# Option group not defined
|
||||
raise exceptions.UnknownServiceClient(services=service_client_name)
|
||||
# Set endpoint_type
|
||||
# Identity uses different settings depending on API version, so do not
|
||||
# return the endpoint at all.
|
||||
if service_client_name != 'identity':
|
||||
_parameters['endpoint_type'] = getattr(options, 'endpoint_type')
|
||||
# Set build_*
|
||||
# Object storage and identity groups do not have conf settings for
|
||||
# build_* parameters, and we default to compute in any case
|
||||
for setting in ['build_timeout', 'build_interval']:
|
||||
if not hasattr(options, setting) or not getattr(options, setting):
|
||||
_parameters[setting] = getattr(CONF.compute, setting)
|
||||
else:
|
||||
_parameters[setting] = getattr(options, setting)
|
||||
# Set region
|
||||
# If a service client does not define region or region is not set
|
||||
# default to the identity region
|
||||
if not hasattr(options, 'region') or not getattr(options, 'region'):
|
||||
_parameters['region'] = CONF.identity.region
|
||||
else:
|
||||
_parameters['region'] = getattr(options, 'region')
|
||||
# Set service
|
||||
_parameters['service'] = getattr(options, 'catalog_type')
|
||||
return _parameters
|
||||
|
@ -225,3 +225,7 @@ class SSHExecCommandFailed(TempestException):
|
||||
message = ("Command '%(command)s', exit status: %(exit_status)d, "
|
||||
"stderr:\n%(stderr)s\n"
|
||||
"stdout:\n%(stdout)s")
|
||||
|
||||
|
||||
class UnknownServiceClient(TempestException):
|
||||
message = "Service clients named %(services)s are not known"
|
||||
|
@ -18,6 +18,22 @@ from tempest.lib import auth
|
||||
from tempest.lib import exceptions
|
||||
|
||||
|
||||
def tempest_modules():
|
||||
"""List of service client modules available in Tempest.
|
||||
|
||||
Provides a list of service modules available Tempest.
|
||||
"""
|
||||
return set(['compute', 'identity.v2', 'identity.v3', 'image.v1',
|
||||
'image.v2', 'network', 'object-storage', 'volume.v1',
|
||||
'volume.v2', 'volume.v3'])
|
||||
|
||||
|
||||
def available_modules():
|
||||
"""List of service client modules available in Tempest and plugins"""
|
||||
# TODO(andreaf) For now this returns only tempest_modules
|
||||
return tempest_modules()
|
||||
|
||||
|
||||
class ServiceClients(object):
|
||||
"""Service client provider class
|
||||
|
||||
@ -30,7 +46,8 @@ class ServiceClients(object):
|
||||
|
||||
>>> from tempest import service_clients
|
||||
>>> johndoe = cred_provider.get_creds_by_role(['johndoe'])
|
||||
>>> johndoe_clients = service_clients.ServiceClients(johndoe)
|
||||
>>> johndoe_clients = service_clients.ServiceClients(johndoe,
|
||||
>>> identity_uri)
|
||||
>>> johndoe_servers = johndoe_clients.servers_client.list_servers()
|
||||
|
||||
"""
|
||||
@ -40,17 +57,45 @@ class ServiceClients(object):
|
||||
# initialises this class using values from tempest CONF object. The wrapper
|
||||
# class should only be used by tests hosted in Tempest.
|
||||
|
||||
def __init__(self, credentials, identity_uri, region=None,
|
||||
scope='project', disable_ssl_certificate_validation=True,
|
||||
ca_certs=None, trace_requests=''):
|
||||
def __init__(self, credentials, identity_uri, region=None, scope='project',
|
||||
disable_ssl_certificate_validation=True, ca_certs=None,
|
||||
trace_requests='', client_parameters=None):
|
||||
"""Service Clients provider
|
||||
|
||||
Instantiate a `ServiceClients` object, from a set of credentials and an
|
||||
identity URI. The identity version is inferred from the credentials
|
||||
object. Optionally auth scope can be provided.
|
||||
|
||||
A few parameters can be given a value which is applied as default
|
||||
for all service clients: region, dscv, ca_certs, trace_requests.
|
||||
|
||||
Parameters dscv, ca_certs and trace_requests all apply to the auth
|
||||
provider as well as any service clients provided by this manager.
|
||||
|
||||
Any other client parameter must be set via client_parameters.
|
||||
The list of available parameters is defined in the service clients
|
||||
interfaces. For reference, most clients will accept 'region',
|
||||
'service', 'endpoint_type', 'build_timeout' and 'build_interval', which
|
||||
are all inherited from RestClient.
|
||||
|
||||
The `config` module in Tempest exposes an helper function
|
||||
`service_client_config` that can be used to extract from configuration
|
||||
a dictionary ready to be injected in kwargs.
|
||||
|
||||
Exceptions are:
|
||||
- Token clients for 'identity' have a very different interface
|
||||
- Volume client for 'volume' accepts 'default_volume_size'
|
||||
- Servers client from 'compute' accepts 'enable_instance_password'
|
||||
|
||||
Examples:
|
||||
|
||||
>>> identity_params = config.service_client_config('identity')
|
||||
>>> params = {
|
||||
>>> 'identity': identity_params,
|
||||
>>> 'compute': {'region': 'region2'}}
|
||||
>>> manager = lib_manager.Manager(
|
||||
>>> my_creds, identity_uri, client_parameters=params)
|
||||
|
||||
:param credentials: An instance of `auth.Credentials`
|
||||
:param identity_uri: URI of the identity API. This should be a
|
||||
mandatory parameter, and it will so soon.
|
||||
@ -60,12 +105,26 @@ class ServiceClients(object):
|
||||
service clients.
|
||||
:param ca_certs Applies to auth and to all service clients.
|
||||
:param trace_requests Applies to auth and to all service clients.
|
||||
:param client_parameters Dictionary with parameters for service
|
||||
clients. Keys of the dictionary are the service client service
|
||||
name, as declared in `service_clients.available_modules()` except
|
||||
for the version. Values are dictionaries of parameters that are
|
||||
going to be passed to all clients in the service client module.
|
||||
|
||||
Examples:
|
||||
|
||||
>>> params_service_x = {'param_name': 'param_value'}
|
||||
>>> client_parameters = { 'service_x': params_service_x }
|
||||
|
||||
>>> params_service_y = config.service_client_config('service_y')
|
||||
>>> client_parameters['service_y'] = params_service_y
|
||||
|
||||
"""
|
||||
self.credentials = credentials
|
||||
self.identity_uri = identity_uri
|
||||
if not identity_uri:
|
||||
raise exceptions.InvalidCredentials(
|
||||
'Manager requires a non-empty identity_uri.')
|
||||
'ServiceClients requires a non-empty identity_uri.')
|
||||
self.region = region
|
||||
# Check if passed or default credentials are valid
|
||||
if not self.credentials.is_valid():
|
||||
@ -88,3 +147,32 @@ class ServiceClients(object):
|
||||
self.credentials, self.identity_uri, scope=scope,
|
||||
disable_ssl_certificate_validation=self.dscv,
|
||||
ca_certs=self.ca_certs, trace_requests=self.trace_requests)
|
||||
# Setup some defaults for client parameters of registered services
|
||||
client_parameters = client_parameters or {}
|
||||
self.parameters = {}
|
||||
# Parameters are provided for unversioned services
|
||||
unversioned_services = set(
|
||||
[x.split('.')[0] for x in available_modules()])
|
||||
for service in unversioned_services:
|
||||
self.parameters[service] = self._setup_parameters(
|
||||
client_parameters.pop(service, {}))
|
||||
# Check that no client parameters was supplied for unregistered clients
|
||||
if client_parameters:
|
||||
raise exceptions.UnknownServiceClient(
|
||||
services=list(client_parameters.keys()))
|
||||
|
||||
def _setup_parameters(self, parameters):
|
||||
"""Setup default values for client parameters
|
||||
|
||||
Region by default is the region passed as an __init__ parameter.
|
||||
Checks that no parameter for an unknown service is provided.
|
||||
"""
|
||||
_parameters = {}
|
||||
# Use region from __init__
|
||||
if self.region:
|
||||
_parameters['region'] = self.region
|
||||
# Update defaults with specified parameters
|
||||
_parameters.update(parameters)
|
||||
# If any parameter is left, parameters for an unknown service were
|
||||
# provided as input. Fail rather than ignore silently.
|
||||
return _parameters
|
||||
|
@ -57,3 +57,57 @@ class FakePrivate(config.TempestConfigPrivate):
|
||||
def __init__(self, parse_conf=True, config_path=None):
|
||||
self._set_attrs()
|
||||
self.lock_path = cfg.CONF.oslo_concurrency.lock_path
|
||||
|
||||
fake_service1_group = cfg.OptGroup(name='fake-service1', title='Fake service1')
|
||||
|
||||
FakeService1Group = [
|
||||
cfg.StrOpt('catalog_type', default='fake-service1'),
|
||||
cfg.StrOpt('endpoint_type', default='faketype'),
|
||||
cfg.StrOpt('region', default='fake_region'),
|
||||
cfg.IntOpt('build_timeout', default=99),
|
||||
cfg.IntOpt('build_interval', default=9)]
|
||||
|
||||
fake_service2_group = cfg.OptGroup(name='fake-service2', title='Fake service2')
|
||||
|
||||
FakeService2Group = [
|
||||
cfg.StrOpt('catalog_type', default='fake-service2'),
|
||||
cfg.StrOpt('endpoint_type', default='faketype')]
|
||||
|
||||
|
||||
class ServiceClientsConfigFixture(conf_fixture.Config):
|
||||
|
||||
def __init__(self):
|
||||
cfg.CONF([], default_config_files=[])
|
||||
config._opts.append((fake_service1_group, FakeService1Group))
|
||||
config._opts.append((fake_service2_group, FakeService2Group))
|
||||
config.register_opts()
|
||||
super(ServiceClientsConfigFixture, self).__init__()
|
||||
|
||||
def setUp(self):
|
||||
super(ServiceClientsConfigFixture, self).setUp()
|
||||
# Debug default values
|
||||
self.conf.set_default('trace_requests', 'fake_module', 'debug')
|
||||
# Identity default values
|
||||
self.conf.set_default('disable_ssl_certificate_validation', True,
|
||||
group='identity')
|
||||
self.conf.set_default('ca_certificates_file', '/fake/certificates',
|
||||
group='identity')
|
||||
self.conf.set_default('region', 'fake_region', 'identity')
|
||||
# Identity endpoints
|
||||
self.conf.set_default('v3_endpoint_type', 'fake_v3_uri', 'identity')
|
||||
self.conf.set_default('v2_public_endpoint_type', 'fake_v2_public_uri',
|
||||
'identity')
|
||||
self.conf.set_default('v2_admin_endpoint_type', 'fake_v2_admin_uri',
|
||||
'identity')
|
||||
# Compute default values
|
||||
self.conf.set_default('build_interval', 88, group='compute')
|
||||
self.conf.set_default('build_timeout', 8, group='compute')
|
||||
|
||||
|
||||
class ServiceClientsFakePrivate(config.TempestConfigPrivate):
|
||||
def __init__(self, parse_conf=True, config_path=None):
|
||||
self._set_attrs()
|
||||
self.fake_service1 = cfg.CONF['fake-service1']
|
||||
self.fake_service2 = cfg.CONF['fake-service2']
|
||||
print('Services registered')
|
||||
self.lock_path = cfg.CONF.oslo_concurrency.lock_path
|
||||
|
89
tempest/tests/test_config.py
Normal file
89
tempest/tests/test_config.py
Normal file
@ -0,0 +1,89 @@
|
||||
# Copyright (c) 2016 Hewlett-Packard Enterprise 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.
|
||||
|
||||
import testtools
|
||||
|
||||
from tempest import config
|
||||
from tempest.lib import exceptions
|
||||
from tempest.tests import base
|
||||
from tempest.tests import fake_config
|
||||
|
||||
|
||||
class TestServiceClientConfig(base.TestCase):
|
||||
|
||||
expected_common_params = set(['disable_ssl_certificate_validation',
|
||||
'ca_certs', 'trace_requests'])
|
||||
expected_extra_params = set(['service', 'endpoint_type', 'region',
|
||||
'build_timeout', 'build_interval'])
|
||||
|
||||
def setUp(self):
|
||||
super(TestServiceClientConfig, self).setUp()
|
||||
self.useFixture(fake_config.ServiceClientsConfigFixture())
|
||||
self.patchobject(config, 'CONF',
|
||||
fake_config.ServiceClientsFakePrivate())
|
||||
self.CONF = config.CONF
|
||||
|
||||
def test_service_client_config_no_service(self):
|
||||
params = config.service_client_config()
|
||||
for param_name in self.expected_common_params:
|
||||
self.assertIn(param_name, params)
|
||||
for param_name in self.expected_extra_params:
|
||||
self.assertNotIn(param_name, params)
|
||||
self.assertEqual(
|
||||
self.CONF.identity.disable_ssl_certificate_validation,
|
||||
params['disable_ssl_certificate_validation'])
|
||||
self.assertEqual(self.CONF.identity.ca_certificates_file,
|
||||
params['ca_certs'])
|
||||
self.assertEqual(self.CONF.debug.trace_requests,
|
||||
params['trace_requests'])
|
||||
|
||||
def test_service_client_config_service_all(self):
|
||||
params = config.service_client_config(
|
||||
service_client_name='fake-service1')
|
||||
for param_name in self.expected_common_params:
|
||||
self.assertIn(param_name, params)
|
||||
for param_name in self.expected_extra_params:
|
||||
self.assertIn(param_name, params)
|
||||
self.assertEqual(self.CONF.fake_service1.catalog_type,
|
||||
params['service'])
|
||||
self.assertEqual(self.CONF.fake_service1.endpoint_type,
|
||||
params['endpoint_type'])
|
||||
self.assertEqual(self.CONF.fake_service1.region, params['region'])
|
||||
self.assertEqual(self.CONF.fake_service1.build_timeout,
|
||||
params['build_timeout'])
|
||||
self.assertEqual(self.CONF.fake_service1.build_interval,
|
||||
params['build_interval'])
|
||||
|
||||
def test_service_client_config_service_minimal(self):
|
||||
params = config.service_client_config(
|
||||
service_client_name='fake-service2')
|
||||
for param_name in self.expected_common_params:
|
||||
self.assertIn(param_name, params)
|
||||
for param_name in self.expected_extra_params:
|
||||
self.assertIn(param_name, params)
|
||||
self.assertEqual(self.CONF.fake_service2.catalog_type,
|
||||
params['service'])
|
||||
self.assertEqual(self.CONF.fake_service2.endpoint_type,
|
||||
params['endpoint_type'])
|
||||
self.assertEqual(self.CONF.identity.region, params['region'])
|
||||
self.assertEqual(self.CONF.compute.build_timeout,
|
||||
params['build_timeout'])
|
||||
self.assertEqual(self.CONF.compute.build_interval,
|
||||
params['build_interval'])
|
||||
|
||||
def test_service_client_config_service_unknown(self):
|
||||
unknown_service = 'unknown_service'
|
||||
with testtools.ExpectedException(exceptions.UnknownServiceClient,
|
||||
'.*' + unknown_service + '.*'):
|
||||
config.service_client_config(service_client_name=unknown_service)
|
@ -12,6 +12,7 @@
|
||||
# License for the specific language governing permissions and limitations under
|
||||
# the License.
|
||||
|
||||
import fixtures
|
||||
import testtools
|
||||
|
||||
from tempest.lib import auth
|
||||
@ -23,7 +24,13 @@ from tempest.tests.lib import fake_credentials
|
||||
|
||||
class TestServiceClients(base.TestCase):
|
||||
|
||||
def test__init__creds_v2_uri(self):
|
||||
def setUp(self):
|
||||
super(TestServiceClients, self).setUp()
|
||||
self.useFixture(fixtures.MockPatch(
|
||||
'tempest.service_clients.tempest_modules',
|
||||
return_value=set(['fake_service1', 'fake_service2'])))
|
||||
|
||||
def test___init___creds_v2_uri(self):
|
||||
# Verify that no API request is made, since no mock
|
||||
# is required to run the test successfully
|
||||
creds = fake_credentials.FakeKeystoneV2Credentials()
|
||||
@ -32,7 +39,7 @@ class TestServiceClients(base.TestCase):
|
||||
self.assertIsInstance(_manager.auth_provider,
|
||||
auth.KeystoneV2AuthProvider)
|
||||
|
||||
def test__init__creds_v3_uri(self):
|
||||
def test___init___creds_v3_uri(self):
|
||||
# Verify that no API request is made, since no mock
|
||||
# is required to run the test successfully
|
||||
creds = fake_credentials.FakeKeystoneV3Credentials()
|
||||
@ -41,22 +48,79 @@ class TestServiceClients(base.TestCase):
|
||||
self.assertIsInstance(_manager.auth_provider,
|
||||
auth.KeystoneV3AuthProvider)
|
||||
|
||||
def test__init__base_creds_uri(self):
|
||||
def test___init___base_creds_uri(self):
|
||||
creds = fake_credentials.FakeCredentials()
|
||||
uri = 'fake_uri'
|
||||
with testtools.ExpectedException(exceptions.InvalidCredentials):
|
||||
service_clients.ServiceClients(creds, identity_uri=uri)
|
||||
|
||||
def test__init__invalid_creds_uri(self):
|
||||
def test___init___invalid_creds_uri(self):
|
||||
creds = fake_credentials.FakeKeystoneV2Credentials()
|
||||
delattr(creds, 'username')
|
||||
uri = 'fake_uri'
|
||||
with testtools.ExpectedException(exceptions.InvalidCredentials):
|
||||
service_clients.ServiceClients(creds, identity_uri=uri)
|
||||
|
||||
def test__init__creds_uri_none(self):
|
||||
def test___init___creds_uri_none(self):
|
||||
creds = fake_credentials.FakeKeystoneV2Credentials()
|
||||
msg = "Invalid Credentials\nDetails: Manager requires a non-empty"
|
||||
msg = ("Invalid Credentials\nDetails: ServiceClients requires a "
|
||||
"non-empty")
|
||||
with testtools.ExpectedException(exceptions.InvalidCredentials,
|
||||
value_re=msg):
|
||||
service_clients.ServiceClients(creds, None)
|
||||
|
||||
def test___init___creds_uri_params(self):
|
||||
creds = fake_credentials.FakeKeystoneV2Credentials()
|
||||
expeted_params = {'fake_param1': 'fake_value1',
|
||||
'fake_param2': 'fake_value2'}
|
||||
params = {'fake_service1': expeted_params}
|
||||
uri = 'fake_uri'
|
||||
_manager = service_clients.ServiceClients(creds, identity_uri=uri,
|
||||
client_parameters=params)
|
||||
self.assertIn('fake_service1', _manager.parameters.keys())
|
||||
for _key in expeted_params.keys():
|
||||
self.assertIn(_key, _manager.parameters['fake_service1'].keys())
|
||||
self.assertEqual(expeted_params[_key],
|
||||
_manager.parameters['fake_service1'].get(_key))
|
||||
|
||||
def test___init___creds_uri_params_unknown_services(self):
|
||||
creds = fake_credentials.FakeKeystoneV2Credentials()
|
||||
fake_params = {'fake_param1': 'fake_value1'}
|
||||
params = {'unknown_service1': fake_params,
|
||||
'unknown_service2': fake_params}
|
||||
uri = 'fake_uri'
|
||||
msg = "(?=.*{0})(?=.*{1})".format(*list(params.keys()))
|
||||
with testtools.ExpectedException(
|
||||
exceptions.UnknownServiceClient, value_re=msg):
|
||||
service_clients.ServiceClients(creds, identity_uri=uri,
|
||||
client_parameters=params)
|
||||
|
||||
def _get_manager(self, init_region='fake_region'):
|
||||
# Get a manager to invoke _setup_parameters on
|
||||
creds = fake_credentials.FakeKeystoneV2Credentials()
|
||||
return service_clients.ServiceClients(creds, identity_uri='fake_uri',
|
||||
region=init_region)
|
||||
|
||||
def test__setup_parameters_none_no_region(self):
|
||||
kwargs = {}
|
||||
_manager = self._get_manager(init_region=None)
|
||||
_params = _manager._setup_parameters(kwargs)
|
||||
self.assertNotIn('region', _params)
|
||||
|
||||
def test__setup_parameters_none(self):
|
||||
kwargs = {}
|
||||
_manager = self._get_manager()
|
||||
_params = _manager._setup_parameters(kwargs)
|
||||
self.assertIn('region', _params)
|
||||
self.assertEqual('fake_region', _params['region'])
|
||||
|
||||
def test__setup_parameters_all(self):
|
||||
expected_params = {'region': 'fake_region1',
|
||||
'catalog_type': 'fake_service2_mod',
|
||||
'fake_param1': 'fake_value1',
|
||||
'fake_param2': 'fake_value2'}
|
||||
_manager = self._get_manager()
|
||||
_params = _manager._setup_parameters(expected_params)
|
||||
for _key in _params.keys():
|
||||
self.assertEqual(expected_params[_key],
|
||||
_params[_key])
|
||||
|
Loading…
Reference in New Issue
Block a user