Handle SetupError exception to avoid spamming into log files.
Change-Id: Id360d6e1638fc5bfb6adaa41412a977526795fe5
This commit is contained in:
parent
6395db0bb6
commit
2dcf72cda3
@ -123,18 +123,23 @@ def exc_info(reraise=True):
|
||||
return info
|
||||
|
||||
|
||||
def log_unhandled_exception(exc_type, exc_value, ex_tb):
|
||||
LOG.exception("Unhandled exception",
|
||||
exc_info=(exc_type, exc_value, ex_tb))
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def handle_multiple_exceptions():
|
||||
def handle_multiple_exceptions(handle_exception=log_unhandled_exception):
|
||||
try:
|
||||
yield
|
||||
except testtools.MultipleExceptions as exc:
|
||||
except testtools.MultipleExceptions as ex:
|
||||
exc_infos = list_exc_infos()
|
||||
if exc_infos:
|
||||
for info in exc_infos[1:]:
|
||||
LOG.exception("Unhandled exception:", exc_info=info)
|
||||
handle_exception(*info)
|
||||
reraise(*exc_infos[0])
|
||||
else:
|
||||
LOG.debug('empty MultipleExceptions: %s', str(exc))
|
||||
LOG.debug(f"Empty MultipleExceptions: '{ex}'")
|
||||
|
||||
|
||||
def list_exc_infos(exc_info=None):
|
||||
|
@ -13,6 +13,7 @@
|
||||
# under the License.
|
||||
from __future__ import absolute_import
|
||||
|
||||
import json
|
||||
import os
|
||||
import inspect
|
||||
|
||||
@ -99,11 +100,24 @@ def remove_fixture(obj, fixture_id=None, manager=None):
|
||||
def setup_fixture(obj, fixture_id=None, manager=None):
|
||||
'''Get registered fixture and setup it up'''
|
||||
fixture = get_fixture(obj, fixture_id=fixture_id, manager=manager)
|
||||
with _exception.handle_multiple_exceptions():
|
||||
with _exception.handle_multiple_exceptions(
|
||||
handle_exception=handle_setup_error):
|
||||
fixture.setUp()
|
||||
return fixture
|
||||
|
||||
|
||||
def handle_setup_error(ex_type, ex_value, ex_tb):
|
||||
if issubclass(ex_type, fixtures.SetupError):
|
||||
details = ex_value.args[0]
|
||||
if details:
|
||||
details = {k: v.as_text() for k, v in details.items()}
|
||||
pretty_details = json.dumps(details, indent=4, sort_keys=True)
|
||||
LOG.debug(f"Fixture setup error details:\n{pretty_details}\n")
|
||||
else:
|
||||
LOG.exception("Unhandled setup exception",
|
||||
exc_info=(ex_type, ex_value, ex_tb))
|
||||
|
||||
|
||||
def reset_fixture(obj, fixture_id=None, manager=None):
|
||||
'''Get registered fixture and reset it'''
|
||||
fixture = get_fixture(obj, fixture_id=fixture_id, manager=manager)
|
||||
|
@ -210,6 +210,28 @@ class TestHandleMultipleExceptions(unit.TobikoUnitTest):
|
||||
ex = self.assertRaises(RuntimeError, run)
|
||||
self.assertEqual(a[1], ex)
|
||||
|
||||
def test_handle_multiple_exceptions_with_handle_exceptions(self):
|
||||
a = make_exception(RuntimeError, 'a')
|
||||
b = make_exception(ValueError, 'b')
|
||||
c = make_exception(TypeError, 'c')
|
||||
d = make_exception(IndexError, 'd')
|
||||
inner = make_exception(testtools.MultipleExceptions, b, c)
|
||||
|
||||
handled_exceptions = []
|
||||
|
||||
def handle_exception(ex_type, ex_value, ex_tb):
|
||||
self.assertIsInstance(ex_value, ex_type)
|
||||
handled_exceptions.append((ex_type, ex_value, ex_tb))
|
||||
|
||||
def run():
|
||||
with tobiko.handle_multiple_exceptions(
|
||||
handle_exception=handle_exception):
|
||||
raise testtools.MultipleExceptions(a, inner, d)
|
||||
|
||||
ex = self.assertRaises(RuntimeError, run)
|
||||
self.assertIs(a[1], ex)
|
||||
self.assertEqual([b, c, d], handled_exceptions)
|
||||
|
||||
|
||||
def make_exception(cls, *args, **kwargs):
|
||||
try:
|
||||
|
@ -19,6 +19,7 @@ import sys
|
||||
import fixtures
|
||||
import mock
|
||||
import testtools
|
||||
from testtools import content
|
||||
|
||||
import tobiko
|
||||
from tobiko.tests import unit
|
||||
@ -228,6 +229,13 @@ class FailingFixture(tobiko.SharedFixture):
|
||||
def cleanup_fixture(self):
|
||||
raise RuntimeError('raised by cleanup_fixture')
|
||||
|
||||
def getDetails(self):
|
||||
content_object = tobiko.details_content(
|
||||
content_type=content.UTF8_TEXT,
|
||||
content_id=self.fixture_name,
|
||||
get_text=lambda: 'My failure details')
|
||||
return {'failing fixture': content_object}
|
||||
|
||||
|
||||
class FailingSetupFixtureWhenFailingTest(unit.TobikoUnitTest):
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user