Smarter way that tests handle default exceptions (unhandled errors) and also a cleanup on test exception classes.

From: [email protected]



git-svn-id: http://test.kernel.org/svn/autotest/trunk@1899 592f7852-d20e-0410-864c-8624ca9c26a4
diff --git a/client/bin/job.py b/client/bin/job.py
index fbd5fdd..07c739f 100755
--- a/client/bin/job.py
+++ b/client/bin/job.py
@@ -252,7 +252,7 @@
                 os.chdir(os.path.join(self.autodir, 'deps', dep))
                 utils.system('./' + dep + '.py')
             except Exception, e:
-                raise error.UnhandledError(e)
+                raise error.UnhandledTestError(e)
 
 
     def _runtest(self, url, tag, args, dargs):
@@ -260,10 +260,10 @@
             l = lambda : test.runtest(self, url, tag, args, dargs)
             pid = parallel.fork_start(self.resultdir, l)
             parallel.fork_waitfor(self.resultdir, pid)
-        except error.AutotestError:
+        except error.TestBaseException:
             raise
         except Exception, e:
-            raise error.UnhandledError(e)
+            raise error.UnhandledTestError(e)
 
 
     def run_test(self, url, *args, **dargs):
@@ -322,8 +322,7 @@
         def group_func():
             try:
                 self._runtest(url, tag, args, dargs)
-            except (error.TestNAError, error.TestUnknownError, error.TestError,
-                    error.TestFail), detail:
+            except error.TestBaseException, detail:
                 self.record(detail.exit_status, subdir, testname,
                             str(detail))
                 raise
@@ -338,7 +337,7 @@
         result, exc_info = self._rungroup(subdir, testname, group_func)
         if container:
             self.release_container()
-        if exc_info and isinstance(exc_info[1], error.TestError):
+        if exc_info and isinstance(exc_info[1], error.TestBaseException):
             return False
         elif exc_info:
             raise exc_info[0], exc_info[1], exc_info[2]
@@ -370,8 +369,7 @@
             result = function(*args, **dargs)
             self._decrement_group_level()
             self.record('END GOOD', subdir, testname)
-        except (error.TestNAError, error.TestError, error.TestFail,
-                error.TestUnknownError), e:
+        except error.TestBaseException, e:
             self._decrement_group_level()
             self.record('END %s' % e.exit_status, subdir, testname, str(e))
         except Exception, e:
diff --git a/client/bin/job_unittest.py b/client/bin/job_unittest.py
index fa23cb7..3d8abb7 100644
--- a/client/bin/job_unittest.py
+++ b/client/bin/job_unittest.py
@@ -312,7 +312,7 @@
         class MyError(error.TestError):
             pass
         real_error = MyError("this is the real error message")
-        unhandled_error = error.UnhandledError(real_error)
+        unhandled_error = error.UnhandledTestError(real_error)
 
         # set up the recording
         testname = "error_test"
@@ -346,7 +346,7 @@
         class MyError(Exception):
             pass
         real_error = MyError("this is the real error message")
-        unhandled_error = error.UnhandledError(real_error)
+        unhandled_error = error.UnhandledTestError(real_error)
         reason = first_line_comparator("Unhandled MyError: %s" % real_error)
 
         # set up the recording
diff --git a/client/bin/parallel.py b/client/bin/parallel.py
index af890a5..e8749db 100644
--- a/client/bin/parallel.py
+++ b/client/bin/parallel.py
@@ -21,7 +21,7 @@
             raise
 
         except Exception, e:
-            raise error.UnhandledError(e)
+            raise error.UnhandledTestError(e)
 
     except Exception, detail:
         ename = tmp + "/debug/error-%d" % (os.getpid())
diff --git a/client/common_lib/error.py b/client/common_lib/error.py
index 582810d..642860b 100644
--- a/client/common_lib/error.py
+++ b/client/common_lib/error.py
@@ -34,38 +34,62 @@
     pass
 
 
-class TestError(AutotestError):
+class TestBaseException(AutotestError):
+    """The parent of all test exceptions."""
+
+
+class TestError(TestBaseException):
     """Indicates that something went wrong with the test harness itself."""
     exit_status="ERROR"
     pass
 
 
-class TestUnknownError(AutotestError):
-    """Indicates an error which terminates and fails the test."""
-    exit_status="FAIL"
-    pass
-
-
-class TestNAError(AutotestError):
+class TestNAError(TestBaseException):
     """Indictates that the test is Not Applicable.  Should be thrown
     when various conditions are such that the test is inappropriate."""
     exit_status="TEST_NA"
     pass
 
 
-class TestFail(AutotestError):
+class TestFail(TestBaseException):
     """Indicates that the test failed, but the job will not continue."""
     exit_status="FAIL"
     pass
 
 
-class TestWarn(AutotestError):
+class TestWarn(TestBaseException):
     """Indicates that bad things (may) have happened, but not an explicit
     failure."""
     exit_status="WARN"
     pass
 
 
+class UnhandledTestError(TestError):
+    """Indicates an unhandled error in a test."""
+    def __init__(self, unhandled_exception):
+        if isinstance(unhandled_exception, TestError):
+            TestError.__init__(self, *unhandled_exception.args)
+        else:
+            msg = "Unhandled %s: %s"
+            msg %= (unhandled_exception.__class__.__name__,
+                    unhandled_exception)
+            msg += "\n" + traceback.format_exc()
+            TestError.__init__(self, msg)
+
+
+class UnhandledTestFail(TestFail):
+    """Indicates an unhandled fail in a test."""
+    def __init__(self, unhandled_exception):
+        if isinstance(unhandled_exception, TestFail):
+            TestFail.__init__(self, *unhandled_exception.args)
+        else:
+            msg = "Unhandled %s: %s"
+            msg %= (unhandled_exception.__class__.__name__,
+                    unhandled_exception)
+            msg += "\n" + traceback.format_exc()
+            TestFail.__init__(self, msg)
+
+
 class CmdError(TestError):
     """\
     Indicates that a command failed, is fatal to the test unless caught.
@@ -95,19 +119,6 @@
     pass
 
 
-class UnhandledError(TestUnknownError):
-    """Indicates an unhandled exception in a test."""
-    def __init__(self, unhandled_exception):
-        if isinstance(unhandled_exception, AutotestError):
-            TestUnknownError.__init__(self, *unhandled_exception.args)
-        else:
-            msg = "Unhandled %s: %s"
-            msg %= (unhandled_exception.__class__.__name__,
-                    unhandled_exception)
-            msg += "\n" + traceback.format_exc()
-            TestUnknownError.__init__(self, msg)
-
-
 class InstallError(JobError):
     """Indicates an installation error which Terminates and fails the job."""
     pass
diff --git a/client/common_lib/test.py b/client/common_lib/test.py
index 9735eab..c590d59 100644
--- a/client/common_lib/test.py
+++ b/client/common_lib/test.py
@@ -162,7 +162,12 @@
                 else:
                     p_args, p_dargs = _cherry_pick_args(self.execute,
                                                         args, dargs)
-                self.execute(*p_args, **p_dargs)
+                try:
+                    self.execute(*p_args, **p_dargs)
+                except error.AutotestError:
+                    raise
+                except Exception, e:
+                    raise error.UnhandledTestFail(e)
 
             finally:
                 self.cleanup()
@@ -171,7 +176,7 @@
         except error.AutotestError:
             raise
         except Exception, e:
-            raise error.UnhandledError(e)
+            raise error.UnhandledTestError(e)
 
 
 def _cherry_pick_args(func, args, dargs):