Try to register all service clients

Accumulate all exceptions from service client registrations,
and raise them together at the end, so in case more than one
service client has issues, we provide a full error report.

Change-Id: I902cfdea0af371dfa222a9bbf41edc4ea2765926
This commit is contained in:
Andrea Frittoli (andreaf) 2016-08-08 10:34:31 +01:00 committed by Andrea Frittoli
parent c7a403debd
commit ff50cc5b52
3 changed files with 72 additions and 5 deletions

View File

@ -44,6 +44,9 @@ class TempestException(Exception):
def __str__(self):
return self._error_string
def __repr__(self):
return self._error_string
class RestClientException(TempestException,
testtools.TestCase.failureException):

View File

@ -17,10 +17,12 @@
import copy
import importlib
import inspect
import sys
import warnings
from debtcollector import removals
from oslo_log import log as logging
import testtools
from tempest.lib import auth
from tempest.lib.common.utils import misc
@ -85,6 +87,7 @@ def available_modules():
extra_service_versions = set([])
_tempest_modules = set(tempest_modules())
plugin_services = ClientsRegistry().get_service_clients()
name_conflicts = []
for plugin_name in plugin_services:
plug_service_versions = set([x['service_version'] for x in
plugin_services[plugin_name]])
@ -96,8 +99,8 @@ def available_modules():
'claimed by another one' % (plugin_name,
extra_service_versions &
plug_service_versions))
raise exceptions.PluginRegistrationException(
name=plugin_name, detailed_error=detailed_error)
name_conflicts.append(exceptions.PluginRegistrationException(
name=plugin_name, detailed_error=detailed_error))
# NOTE(andreaf) Once all tempest clients are stable, the following
# if will have to be removed.
if not plug_service_versions.isdisjoint(
@ -107,9 +110,14 @@ def available_modules():
'claimed by a Tempest one' % (plugin_name,
_tempest_internal_modules() &
plug_service_versions))
raise exceptions.PluginRegistrationException(
name=plugin_name, detailed_error=detailed_error)
name_conflicts.append(exceptions.PluginRegistrationException(
name=plugin_name, detailed_error=detailed_error))
extra_service_versions |= plug_service_versions
if name_conflicts:
LOG.error(
'Failed to list available modules due to name conflicts: %s',
name_conflicts)
raise testtools.MultipleExceptions(*name_conflicts)
return _tempest_modules | extra_service_versions
@ -375,6 +383,7 @@ class ServiceClients(object):
# Register service clients from the registry (__tempest__ and plugins)
clients_registry = ClientsRegistry()
plugin_service_clients = clients_registry.get_service_clients()
registration_errors = []
for plugin in plugin_service_clients:
service_clients = plugin_service_clients[plugin]
# Each plugin returns a list of service client parameters
@ -385,10 +394,12 @@ class ServiceClients(object):
try:
self.register_service_client_module(**service_client)
except Exception:
registration_errors.append(sys.exc_info())
LOG.exception(
'Failed to register service client from plugin %s '
'with parameters %s', plugin, service_client)
raise
if registration_errors:
raise testtools.MultipleExceptions(*registration_errors)
def register_service_client_module(self, name, service_version,
module_path, client_names, **kwargs):

View File

@ -16,6 +16,7 @@ import types
import fixtures
import mock
import six
import testtools
from tempest.lib import auth
@ -258,6 +259,58 @@ class TestServiceClients(base.TestCase):
clients.ServiceClients(creds, identity_uri=uri,
client_parameters=params)
def test___init___plugin_service_clients_cannot_load(self):
creds = fake_credentials.FakeKeystoneV3Credentials()
uri = 'fake_uri'
fake_service_clients = {
'service1': [{'name': 'client1',
'service_version': 'client1.v1',
'module_path': 'I cannot load this',
'client_names': ['SomeClient1']}],
'service2': [{'name': 'client2',
'service_version': 'client2.v1',
'module_path': 'This neither',
'client_names': ['SomeClient1']}]}
msg = "(?=.*{0})(?=.*{1})".format(
*[x[1][0]['module_path'] for x in six.iteritems(
fake_service_clients)])
self.useFixture(fixtures.MockPatchObject(
clients.ClientsRegistry(), 'get_service_clients',
return_value=fake_service_clients))
with testtools.ExpectedException(
testtools.MultipleExceptions, value_re=msg):
clients.ServiceClients(creds, identity_uri=uri)
def test___init___plugin_service_clients_name_conflict(self):
creds = fake_credentials.FakeKeystoneV3Credentials()
uri = 'fake_uri'
fake_service_clients = {
'serviceA': [{'name': 'client1',
'service_version': 'client1.v1',
'module_path': 'fake_path_1',
'client_names': ['SomeClient1']}],
'serviceB': [{'name': 'client1',
'service_version': 'client1.v2',
'module_path': 'fake_path_2',
'client_names': ['SomeClient2']}],
'serviceC': [{'name': 'client1',
'service_version': 'client1.v1',
'module_path': 'fake_path_2',
'client_names': ['SomeClient1']}],
'serviceD': [{'name': 'client1',
'service_version': 'client1.v2',
'module_path': 'fake_path_2',
'client_names': ['SomeClient2']}]}
msg = "(?=.*{0})(?=.*{1})".format(
*[x[1][0]['service_version'] for x in six.iteritems(
fake_service_clients)])
self.useFixture(fixtures.MockPatchObject(
clients.ClientsRegistry(), 'get_service_clients',
return_value=fake_service_clients))
with testtools.ExpectedException(
testtools.MultipleExceptions, value_re=msg):
clients.ServiceClients(creds, identity_uri=uri)
def _get_manager(self, init_region='fake_region'):
# Get a manager to invoke _setup_parameters on
creds = fake_credentials.FakeKeystoneV2Credentials()