diff options
-rw-r--r-- | cbuildbot/failures_lib.py | 14 | ||||
-rwxr-xr-x | cbuildbot/failures_lib_unittest.py | 8 | ||||
-rw-r--r-- | cbuildbot/stages/generic_stages.py | 4 | ||||
-rwxr-xr-x | lib/parallel_unittest.py | 2 |
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.""" |