Merge "Add a pformat() failure method and use it in the conductor"

This commit is contained in:
Jenkins
2014-08-21 21:31:55 +00:00
committed by Gerrit Code Review
3 changed files with 52 additions and 7 deletions

View File

@@ -96,17 +96,24 @@ class SingleThreadedConductor(base.Conductor):
engine.run() engine.run()
except excp.WrappedFailure as e: except excp.WrappedFailure as e:
if all((f.check(*NO_CONSUME_EXCEPTIONS) for f in e)): if all((f.check(*NO_CONSUME_EXCEPTIONS) for f in e)):
LOG.warn("Job execution failed (consumption being"
" skipped): %s", job, exc_info=True)
consume = False consume = False
else: if LOG.isEnabledFor(logging.WARNING):
LOG.warn("Job execution failed: %s", job, exc_info=True) if consume:
LOG.warn("Job execution failed (consumption being"
" skipped): %s [%s failures]", job, len(e))
else:
LOG.warn("Job execution failed (consumption"
" proceeding): %s [%s failures]", job, len(e))
# Show the failure/s + traceback (if possible)...
for i, f in enumerate(e):
LOG.warn("%s. %s", i + 1, f.pformat(traceback=True))
except NO_CONSUME_EXCEPTIONS: except NO_CONSUME_EXCEPTIONS:
LOG.warn("Job execution failed (consumption being" LOG.warn("Job execution failed (consumption being"
" skipped): %s", job, exc_info=True) " skipped): %s", job, exc_info=True)
consume = False consume = False
except Exception: except Exception:
LOG.warn("Job execution failed: %s", job, exc_info=True) LOG.warn("Job execution failed (consumption proceeding): %s",
job, exc_info=True)
else: else:
LOG.info("Job completed successfully: %s", job) LOG.info("Job completed successfully: %s", job)
return consume return consume

View File

@@ -42,6 +42,10 @@ class GeneralFailureObjTestsMixin(object):
self.assertEqual(list(self.fail_obj), self.assertEqual(list(self.fail_obj),
test_utils.RUNTIME_ERROR_CLASSES[:-2]) test_utils.RUNTIME_ERROR_CLASSES[:-2])
def test_pformat_no_traceback(self):
text = self.fail_obj.pformat()
self.assertNotIn("Traceback", text)
def test_check_str(self): def test_check_str(self):
val = 'Exception' val = 'Exception'
self.assertEqual(self.fail_obj.check(val), val) self.assertEqual(self.fail_obj.check(val), val)
@@ -91,6 +95,10 @@ class ReCreatedFailureTestCase(test.TestCase, GeneralFailureObjTestsMixin):
def test_no_exc_info(self): def test_no_exc_info(self):
self.assertIs(self.fail_obj.exc_info, None) self.assertIs(self.fail_obj.exc_info, None)
def test_pformat_traceback(self):
text = self.fail_obj.pformat(traceback=True)
self.assertIn("Traceback (most recent call last):", text)
def test_reraises(self): def test_reraises(self):
exc = self.assertRaises(exceptions.WrappedFailure, exc = self.assertRaises(exceptions.WrappedFailure,
self.fail_obj.reraise) self.fail_obj.reraise)
@@ -103,6 +111,10 @@ class FromExceptionTestCase(test.TestCase, GeneralFailureObjTestsMixin):
super(FromExceptionTestCase, self).setUp() super(FromExceptionTestCase, self).setUp()
self.fail_obj = misc.Failure.from_exception(RuntimeError('Woot!')) self.fail_obj = misc.Failure.from_exception(RuntimeError('Woot!'))
def test_pformat_no_traceback(self):
text = self.fail_obj.pformat(traceback=True)
self.assertIn("Traceback not available", text)
class FailureObjectTestCase(test.TestCase): class FailureObjectTestCase(test.TestCase):
@@ -188,6 +200,17 @@ class FailureObjectTestCase(test.TestCase):
self.assertNotEqual(captured, None) self.assertNotEqual(captured, None)
self.assertFalse(captured.matches(None)) self.assertFalse(captured.matches(None))
def test_pformat_traceback(self):
captured = _captured_failure('Woot!')
text = captured.pformat(traceback=True)
self.assertIn("Traceback (most recent call last):", text)
def test_pformat_traceback_captured_no_exc_info(self):
captured = _captured_failure('Woot!')
captured = misc.Failure.from_dict(captured.to_dict())
text = captured.pformat(traceback=True)
self.assertIn("Traceback (most recent call last):", text)
class WrappedFailureTestCase(test.TestCase): class WrappedFailureTestCase(test.TestCase):

View File

@@ -696,8 +696,23 @@ class Failure(object):
return None return None
def __str__(self): def __str__(self):
return 'Failure: %s: %s' % (self._exc_type_names[0], return self.pformat()
self._exception_str)
def pformat(self, traceback=False):
buf = six.StringIO()
buf.write(
'Failure: %s: %s' % (self._exc_type_names[0], self._exception_str))
if traceback:
if self._traceback_str is not None:
traceback_str = self._traceback_str.rstrip()
else:
traceback_str = None
if traceback_str:
buf.write('\nTraceback (most recent call last):\n')
buf.write(traceback_str)
else:
buf.write('\nTraceback not available.')
return buf.getvalue()
def __iter__(self): def __iter__(self):
"""Iterate over exception type names.""" """Iterate over exception type names."""