diff --git a/tobiko/__init__.py b/tobiko/__init__.py index c92669274..7e9330edd 100644 --- a/tobiko/__init__.py +++ b/tobiko/__init__.py @@ -15,7 +15,7 @@ from __future__ import absolute_import from tobiko.common.managers import fixture from tobiko.common.managers import testcase as testcase_manager from tobiko.common.managers import loader as loader_manager - +from tobiko.common import exceptions load_object = loader_manager.load_object load_module = loader_manager.load_module @@ -32,3 +32,6 @@ setup_fixture = fixture.setup_fixture cleanup_fixture = fixture.cleanup_fixture list_required_fixtures = fixture.list_required_fixtures SharedFixture = fixture.SharedFixture + +TobikoException = exceptions.TobikoException +FailureException = exceptions.FailureException diff --git a/tobiko/common/exceptions.py b/tobiko/common/exceptions.py index 37b187856..ee1e7ced3 100644 --- a/tobiko/common/exceptions.py +++ b/tobiko/common/exceptions.py @@ -13,6 +13,8 @@ # under the License. from __future__ import absolute_import +import testtools + class TobikoException(Exception): """Base Tobiko Exception. @@ -20,23 +22,27 @@ class TobikoException(Exception): To use this class, inherit from it and define a 'message' property. """ - message = "An unknown exception occurred." + message = None def __init__(self, **properties): super(TobikoException, self).__init__() self._properties = properties message = self.message # pylint: disable=exception-message-attribute - if properties: - message = message % properties - self._message = message + if message: + if properties: + message = message % properties + self._message = message or "unknown reason" def __str__(self): return self._message - def __getattr(self, name): + def __getattr__(self, name): try: return self._properties[name] except KeyError: - pass - msg = ("'{!r}' object has no attribute {!r}").format(self, name) - raise AttributeError(msg) + msg = ("{!r} object has no attribute {!r}").format(self, name) + raise AttributeError(msg) + + +class FailureException(TobikoException, testtools.TestCase.failureException): + pass diff --git a/tobiko/openstack/heat/_stack.py b/tobiko/openstack/heat/_stack.py index d079ec7e1..5a1202853 100644 --- a/tobiko/openstack/heat/_stack.py +++ b/tobiko/openstack/heat/_stack.py @@ -20,7 +20,6 @@ from heatclient import exc from oslo_log import log import tobiko -from tobiko.common import exceptions from tobiko.openstack.heat import _client from tobiko.openstack.heat import _template @@ -245,15 +244,15 @@ def check_stack_status(stack, expected): status_reason=stack.stack_status_reason) -class InvalidHeatStackOutputKey(exceptions.TobikoException): - message = "Output key %(key)r not found in stack %(name)." +class InvalidHeatStackOutputKey(tobiko.TobikoException): + message = "Output key %(key)r not found in stack %(name)r." -class HeatStackNotFound(exceptions.TobikoException): +class HeatStackNotFound(tobiko.TobikoException): message = "Stack %(name)r not found" -class InvalidHeatStackStatus(exceptions.TobikoException): +class InvalidHeatStackStatus(tobiko.TobikoException): message = ("Stack %(name)r status %(observed)r not in %(expected)r.\n" "%(status_reason)s") diff --git a/tobiko/openstack/keystone/_credentials.py b/tobiko/openstack/keystone/_credentials.py index ef5926a30..7d68c0154 100644 --- a/tobiko/openstack/keystone/_credentials.py +++ b/tobiko/openstack/keystone/_credentials.py @@ -18,7 +18,6 @@ import collections from oslo_log import log import tobiko -from tobiko.common import exceptions LOG = log.getLogger(__name__) @@ -74,7 +73,7 @@ def keystone_credentials(api_version=None, auth_url=None, project_domain_name=project_domain_name) -class InvalidKeystoneCredentials(exceptions.TobikoException): +class InvalidKeystoneCredentials(tobiko.TobikoException): message = "Invalid Keystone credentials (%(credentials)r): %(reason)s."