Changes the semantics of UnhandledError. First, it takes in a root
exception to wrap, rather than implicitly grabbing the last caught
exception. Second, it displays the root exception message instead
of wrapping it in a new message and only displaying the root cause
in a pre-collected traceback.

Signed-off-by: John Admanski <jadmanski@google.com>



git-svn-id: http://test.kernel.org/svn/autotest/trunk@1710 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/client/bin/job_unittest.py b/client/bin/job_unittest.py
index bbed311..839d1ad 100644
--- a/client/bin/job_unittest.py
+++ b/client/bin/job_unittest.py
@@ -2,11 +2,22 @@
 
 import os, unittest, pickle, shutil, sys
 import common
+
 from autotest_lib.client.bin import job, boottool, config, sysinfo, harness
-from autotest_lib.client.common_lib import utils
+from autotest_lib.client.bin import test
+from autotest_lib.client.common_lib import utils, error
 from autotest_lib.client.common_lib.test_utils import mock
 
 
+class first_line_comparator(mock.argument_comparator):
+    def __init__(self, first_line):
+        self.first_line = first_line
+
+
+    def is_satisfied_by(self, parameter):
+        return self.first_line == parameter.splitlines()[0]
+
+
 class TestBaseJob(unittest.TestCase):
     def setUp(self):
         # make god
@@ -50,6 +61,7 @@
         self.god.stub_function(self.job, 'config_get')
         self.god.stub_function(self.job, 'record')
         self.god.stub_function(self.job, '_increment_group_level')
+        self.god.stub_function(self.job, '_decrement_group_level')
         self.god.stub_function(self.job, 'get_state')
 
         # other setup
@@ -217,5 +229,71 @@
         self.god.check_playback()
 
 
+    def test_run_test_logs_test_error_from_unhandled_error(self):
+        self.construct_job(True)
+
+        # set up stubs
+        self.god.stub_function(test, "testname")
+        self.god.stub_function(self.job, "_runtest")
+
+        # create an unhandled error object
+        class MyError(error.TestError):
+            pass
+        real_error = MyError("this is the real error message")
+        unhandled_error = error.UnhandledError(real_error)
+
+        # set up the recording
+        testname = "error_test"
+        outputdir = os.path.join(self.job.resultdir, testname)
+        test.testname.expect_call(testname).and_return(("", testname))
+        os.path.exists.expect_call(outputdir).and_return(False)
+        os.mkdir.expect_call(outputdir)
+        self.job.record.expect_call("START", testname, testname)
+        self.job._increment_group_level.expect_call()
+        self.job._runtest.expect_call(testname, "", (), {}).and_raises(
+            unhandled_error)
+        self.job.record.expect_call("FAIL", testname, testname,
+                                    first_line_comparator(str(real_error)))
+        self.job._decrement_group_level.expect_call()
+        self.job.record.expect_call("END FAIL", testname, testname,
+                                    first_line_comparator(str(real_error)))
+
+        # run and check
+        self.job.run_test(testname)
+        self.god.check_playback()
+
+
+    def test_run_test_logs_non_test_error_from_unhandled_error(self):
+        self.construct_job(True)
+
+        # set up stubs
+        self.god.stub_function(test, "testname")
+        self.god.stub_function(self.job, "_runtest")
+
+        # create an unhandled error object
+        class MyError(Exception):
+            pass
+        real_error = MyError("this is the real error message")
+        unhandled_error = error.UnhandledError(real_error)
+        reason = first_line_comparator("Unhandled MyError: %s" % real_error)
+
+        # set up the recording
+        testname = "error_test"
+        outputdir = os.path.join(self.job.resultdir, testname)
+        test.testname.expect_call(testname).and_return(("", testname))
+        os.path.exists.expect_call(outputdir).and_return(False)
+        os.mkdir.expect_call(outputdir)
+        self.job.record.expect_call("START", testname, testname)
+        self.job._increment_group_level.expect_call()
+        self.job._runtest.expect_call(testname, "", (), {}).and_raises(
+            unhandled_error)
+        self.job.record.expect_call("FAIL", testname, testname, reason)
+        self.job._decrement_group_level.expect_call()
+        self.job.record.expect_call("END FAIL", testname, testname, reason)
+
+        # run and check
+        self.job.run_test(testname)
+        self.god.check_playback()
+
 if __name__ == "__main__":
     unittest.main()