summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cbuildbot/failures_lib.py14
-rwxr-xr-xcbuildbot/failures_lib_unittest.py8
-rw-r--r--cbuildbot/stages/generic_stages.py4
-rwxr-xr-xlib/parallel_unittest.py2
4 files changed, 20 insertions, 8 deletions
diff --git a/cbuildbot/failures_lib.py b/cbuildbot/failures_lib.py
index d3d5e14d6..e7d2b7918 100644
--- a/cbuildbot/failures_lib.py
+++ b/cbuildbot/failures_lib.py
@@ -79,12 +79,22 @@ class CompoundFailure(StepFailure):
"""
self.exc_infos = exc_infos if exc_infos else []
if not message:
- # By default, print all stored ExceptInfo objects.
- message = '\n'.join(['%s: %s\n%s' % e for e in self.exc_infos])
+ # By default, print the type and string of each ExceptInfo object.
+ message = '\n'.join(['%s: %s' % (e.type, e.str) for e in self.exc_infos])
super(CompoundFailure, self).__init__(message=message,
possibly_flaky=possibly_flaky)
+ def ToFullMessage(self):
+ """Returns a string with all information in self.exc_infos."""
+ if self.HasEmptyList():
+ # Fall back to return self.message if list is empty.
+ return self.message
+ else:
+ # This includes the textual traceback(s).
+ return '\n'.join(['{e.type}: {e.str} {e.traceback}'.format(e=ex) for
+ ex in self.exc_infos])
+
def HasEmptyList(self):
"""Returns True if self.exc_infos is empty."""
return not bool(self.exc_infos)
diff --git a/cbuildbot/failures_lib_unittest.py b/cbuildbot/failures_lib_unittest.py
index f3fce4dfb..417d3f362 100755
--- a/cbuildbot/failures_lib_unittest.py
+++ b/cbuildbot/failures_lib_unittest.py
@@ -72,10 +72,10 @@ class CompoundFailureTest(cros_test_lib.TestCase):
exc = failures_lib.CompoundFailure(exc_infos=exc_infos)
self.assertTrue('bar1' in str(exc))
self.assertTrue('bar2' in str(exc))
- self.assertTrue('foo1' in str(exc))
- self.assertTrue('foo2' in str(exc))
self.assertTrue('KeyError' in str(exc))
self.assertTrue('ValueError' in str(exc))
+ self.assertTrue('foo1' in exc.ToFullMessage())
+ self.assertTrue('foo2' in exc.ToFullMessage())
class SetFailureTypeTest(cros_test_lib.TestCase):
@@ -144,8 +144,8 @@ class SetFailureTypeTest(cros_test_lib.TestCase):
self.assertEqual(e.exc_infos, org_infos)
# All essential inforamtion should be included in the message of
# the new excpetion.
- self.assertTrue(tb1 in str(e))
- self.assertTrue(tb2 in str(e))
+ self.assertTrue(tb1 in e.ToFullMessage())
+ self.assertTrue(tb2 in e.ToFullMessage())
self.assertTrue(str(ValueError) in str(e))
self.assertTrue(str(OSError) in str(e))
self.assertTrue(str('No taco') in str(e))
diff --git a/cbuildbot/stages/generic_stages.py b/cbuildbot/stages/generic_stages.py
index 7539d563c..3d70508ad 100644
--- a/cbuildbot/stages/generic_stages.py
+++ b/cbuildbot/stages/generic_stages.py
@@ -265,7 +265,9 @@ class BuilderStage(object):
A string description of the exception.
"""
exc_type, exc_value = exc_info[:2]
- if issubclass(exc_type, failures_lib.StepFailure):
+ if issubclass(exc_type, failures_lib.CompoundFailure):
+ return exc_value.ToFullMessage()
+ elif issubclass(exc_type, failures_lib.StepFailure):
return str(exc_value)
else:
return ''.join(traceback.format_exception(*exc_info))
diff --git a/lib/parallel_unittest.py b/lib/parallel_unittest.py
index f07f3591d..ef1cb2117 100755
--- a/lib/parallel_unittest.py
+++ b/lib/parallel_unittest.py
@@ -351,8 +351,8 @@ class TestExceptions(cros_test_lib.MockOutputTestCase):
ex_str = str(ex)
self.assertTrue(exc_type in [x.type for x in ex.exc_infos])
- self.assertTrue('Traceback' in ex_str)
self.assertEqual(output_str, _GREETING)
+ self.assertTrue(str(exc_type) in ex_str)
def testExceptionRaising(self):
"""Tests the exceptions are raised correctly."""