[Lldb-commits] [lldb] r136636 - /lldb/trunk/test/lldbtest.py

Johnny Chen johnny.chen at apple.com
Mon Aug 1 11:46:13 PDT 2011


Author: johnny
Date: Mon Aug  1 13:46:13 2011
New Revision: 136636

URL: http://llvm.org/viewvc/llvm-project?rev=136636&view=rev
Log:
Start refactoring lldbtest.TestBase so that it inherits from a newly created lldbtest.Base class,
while its API clients remain unchanged.  The new lldbtest.Base class is to capture common behaviors
when working with the test driver to accomplish things.  The clients of lldbtest.Base can be
lldb command line and api tests as well as other generic tests like a benchmark test.

Modified:
    lldb/trunk/test/lldbtest.py

Modified: lldb/trunk/test/lldbtest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=136636&r1=136635&r2=136636&view=diff
==============================================================================
--- lldb/trunk/test/lldbtest.py (original)
+++ lldb/trunk/test/lldbtest.py Mon Aug  1 13:46:13 2011
@@ -231,42 +231,6 @@
     a_pointer = ctypes.c_void_p(0xffff)
     return 8 * ctypes.sizeof(a_pointer)
 
-from functools import wraps
-def python_api_test(func):
-    """Decorate the item as a Python API only test."""
-    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
-        raise Exception("@python_api_test can only be used to decorate a test method")
-    @wraps(func)
-    def wrapper(self, *args, **kwargs):
-        try:
-            if lldb.dont_do_python_api_test:
-                self.skipTest("python api tests")
-        except AttributeError:
-            pass
-        return func(self, *args, **kwargs)
-
-    # Mark this function as such to separate them from lldb command line tests.
-    wrapper.__python_api_test__ = True
-    return wrapper
-
-from functools import wraps
-def benchmarks_test(func):
-    """Decorate the item as a benchmarks test."""
-    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
-        raise Exception("@benchmarks_test can only be used to decorate a test method")
-    @wraps(func)
-    def wrapper(self, *args, **kwargs):
-        try:
-            if not lldb.just_do_benchmarks_test:
-                self.skipTest("benchmarks tests")
-        except AttributeError:
-            pass
-        return func(self, *args, **kwargs)
-
-    # Mark this function as such to separate them from the regular tests.
-    wrapper.__benchmarks_test__ = True
-    return wrapper
-
 class recording(StringIO.StringIO):
     """
     A nice little context manager for recording the debugger interactions into
@@ -363,80 +327,56 @@
 def builder_module():
     return __import__("builder_" + sys.platform)
 
-class TestBase(unittest2.TestCase):
-    """
-    This abstract base class is meant to be subclassed.  It provides default
-    implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
-    among other things.
-
-    Important things for test class writers:
+#
+# Decorators for categorizing test cases.
+#
 
-        - Overwrite the mydir class attribute, otherwise your test class won't
-          run.  It specifies the relative directory to the top level 'test' so
-          the test harness can change to the correct working directory before
-          running your test.
-
-        - The setUp method sets up things to facilitate subsequent interactions
-          with the debugger as part of the test.  These include:
-              - populate the test method name
-              - create/get a debugger set with synchronous mode (self.dbg)
-              - get the command interpreter from with the debugger (self.ci)
-              - create a result object for use with the command interpreter
-                (self.res)
-              - plus other stuffs
+from functools import wraps
+def python_api_test(func):
+    """Decorate the item as a Python API only test."""
+    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
+        raise Exception("@python_api_test can only be used to decorate a test method")
+    @wraps(func)
+    def wrapper(self, *args, **kwargs):
+        try:
+            if lldb.dont_do_python_api_test:
+                self.skipTest("python api tests")
+        except AttributeError:
+            pass
+        return func(self, *args, **kwargs)
 
-        - The tearDown method tries to perform some necessary cleanup on behalf
-          of the test to return the debugger to a good state for the next test.
-          These include:
-              - execute any tearDown hooks registered by the test method with
-                TestBase.addTearDownHook(); examples can be found in
-                settings/TestSettings.py
-              - kill the inferior process associated with each target, if any,
-                and, then delete the target from the debugger's target list
-              - perform build cleanup before running the next test method in the
-                same test class; examples of registering for this service can be
-                found in types/TestIntegerTypes.py with the call:
-                    - self.setTearDownCleanup(dictionary=d)
+    # Mark this function as such to separate them from lldb command line tests.
+    wrapper.__python_api_test__ = True
+    return wrapper
 
-        - Similarly setUpClass and tearDownClass perform classwise setup and
-          teardown fixtures.  The tearDownClass method invokes a default build
-          cleanup for the entire test class;  also, subclasses can implement the
-          classmethod classCleanup(cls) to perform special class cleanup action.
+from functools import wraps
+def benchmarks_test(func):
+    """Decorate the item as a benchmarks test."""
+    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
+        raise Exception("@benchmarks_test can only be used to decorate a test method")
+    @wraps(func)
+    def wrapper(self, *args, **kwargs):
+        try:
+            if not lldb.just_do_benchmarks_test:
+                self.skipTest("benchmarks tests")
+        except AttributeError:
+            pass
+        return func(self, *args, **kwargs)
 
-        - The instance methods runCmd and expect are used heavily by existing
-          test cases to send a command to the command interpreter and to perform
-          string/pattern matching on the output of such command execution.  The
-          expect method also provides a mode to peform string/pattern matching
-          without running a command.
+    # Mark this function as such to separate them from the regular tests.
+    wrapper.__benchmarks_test__ = True
+    return wrapper
 
-        - The build methods buildDefault, buildDsym, and buildDwarf are used to
-          build the binaries used during a particular test scenario.  A plugin
-          should be provided for the sys.platform running the test suite.  The
-          Mac OS X implementation is located in plugins/darwin.py.
+class Base(unittest2.TestCase):
+    """
+    Abstract base for performing lldb (see TestBase) or other generic tests (see
+    BenchBase for one example).  lldbtest.Base works with the test driver to
+    accomplish things.
+    
     """
-
-    @classmethod
-    def skipLongRunningTest(cls):
-        """
-        By default, we skip long running test case.
-        This can be overridden by passing '-l' to the test driver (dotest.py).
-        """
-        if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
-            return False
-        else:
-            return True
-
     # The concrete subclass should override this attribute.
     mydir = None
 
-    # Maximum allowed attempts when launching the inferior process.
-    # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
-    maxLaunchCount = 3;
-
-    # Time to wait before the next launching attempt in second(s).
-    # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
-    timeWaitNextLaunch = 1.0;
-
     # Keep track of the old current working directory.
     oldcwd = None
 
@@ -488,6 +428,110 @@
             print >> sys.stderr, "Restore dir to:", cls.oldcwd
         os.chdir(cls.oldcwd)
 
+    @classmethod
+    def skipLongRunningTest(cls):
+        """
+        By default, we skip long running test case.
+        This can be overridden by passing '-l' to the test driver (dotest.py).
+        """
+        if "LLDB_SKIP_LONG_RUNNING_TEST" in os.environ and "NO" == os.environ["LLDB_SKIP_LONG_RUNNING_TEST"]:
+            return False
+        else:
+            return True
+
+    def setUp(self):
+        """Works with the test driver to conditionally skip tests."""
+        #import traceback
+        #traceback.print_stack()
+
+        # Python API only test is decorated with @python_api_test,
+        # which also sets the "__python_api_test__" attribute of the
+        # function object to True.
+        try:
+            if lldb.just_do_python_api_test:
+                testMethod = getattr(self, self._testMethodName)
+                if getattr(testMethod, "__python_api_test__", False):
+                    pass
+                else:
+                    self.skipTest("non python api test")
+        except AttributeError:
+            pass
+
+        # Benchmarks test is decorated with @benchmarks_test,
+        # which also sets the "__benchmarks_test__" attribute of the
+        # function object to True.
+        try:
+            if lldb.just_do_benchmarks_test:
+                testMethod = getattr(self, self._testMethodName)
+                if getattr(testMethod, "__benchmarks_test__", False):
+                    pass
+                else:
+                    self.skipTest("non benchmarks test")
+        except AttributeError:
+            pass
+
+
+
+class TestBase(Base):
+    """
+    This abstract base class is meant to be subclassed.  It provides default
+    implementations for setUpClass(), tearDownClass(), setUp(), and tearDown(),
+    among other things.
+
+    Important things for test class writers:
+
+        - Overwrite the mydir class attribute, otherwise your test class won't
+          run.  It specifies the relative directory to the top level 'test' so
+          the test harness can change to the correct working directory before
+          running your test.
+
+        - The setUp method sets up things to facilitate subsequent interactions
+          with the debugger as part of the test.  These include:
+              - populate the test method name
+              - create/get a debugger set with synchronous mode (self.dbg)
+              - get the command interpreter from with the debugger (self.ci)
+              - create a result object for use with the command interpreter
+                (self.res)
+              - plus other stuffs
+
+        - The tearDown method tries to perform some necessary cleanup on behalf
+          of the test to return the debugger to a good state for the next test.
+          These include:
+              - execute any tearDown hooks registered by the test method with
+                TestBase.addTearDownHook(); examples can be found in
+                settings/TestSettings.py
+              - kill the inferior process associated with each target, if any,
+                and, then delete the target from the debugger's target list
+              - perform build cleanup before running the next test method in the
+                same test class; examples of registering for this service can be
+                found in types/TestIntegerTypes.py with the call:
+                    - self.setTearDownCleanup(dictionary=d)
+
+        - Similarly setUpClass and tearDownClass perform classwise setup and
+          teardown fixtures.  The tearDownClass method invokes a default build
+          cleanup for the entire test class;  also, subclasses can implement the
+          classmethod classCleanup(cls) to perform special class cleanup action.
+
+        - The instance methods runCmd and expect are used heavily by existing
+          test cases to send a command to the command interpreter and to perform
+          string/pattern matching on the output of such command execution.  The
+          expect method also provides a mode to peform string/pattern matching
+          without running a command.
+
+        - The build methods buildDefault, buildDsym, and buildDwarf are used to
+          build the binaries used during a particular test scenario.  A plugin
+          should be provided for the sys.platform running the test suite.  The
+          Mac OS X implementation is located in plugins/darwin.py.
+    """
+
+    # Maximum allowed attempts when launching the inferior process.
+    # Can be overridden by the LLDB_MAX_LAUNCH_COUNT environment variable.
+    maxLaunchCount = 3;
+
+    # Time to wait before the next launching attempt in second(s).
+    # Can be overridden by the LLDB_TIME_WAIT_NEXT_LAUNCH environment variable.
+    timeWaitNextLaunch = 1.0;
+
     def doDelay(self):
         """See option -w of dotest.py."""
         if ("LLDB_WAIT_BETWEEN_TEST_CASES" in os.environ and
@@ -501,6 +545,9 @@
         #import traceback
         #traceback.print_stack()
 
+        # Works with the test driver to conditionally skip tests via decorators.
+        Base.setUp(self)
+
         # Assign the test method name to self.testMethodName.
         #
         # For an example of the use of this attribute, look at test/types dir.
@@ -523,32 +570,6 @@
         except AttributeError:
             pass
 
-        # Python API only test is decorated with @python_api_test,
-        # which also sets the "__python_api_test__" attribute of the
-        # function object to True.
-        try:
-            if lldb.just_do_python_api_test:
-                testMethod = getattr(self, self._testMethodName)
-                if getattr(testMethod, "__python_api_test__", False):
-                    pass
-                else:
-                    self.skipTest("non python api test")
-        except AttributeError:
-            pass
-
-        # Benchmarks test is decorated with @benchmarks_test,
-        # which also sets the "__benchmarks_test__" attribute of the
-        # function object to True.
-        try:
-            if lldb.just_do_benchmarks_test:
-                testMethod = getattr(self, self._testMethodName)
-                if getattr(testMethod, "__benchmarks_test__", False):
-                    pass
-                else:
-                    self.skipTest("non benchmarks test")
-        except AttributeError:
-            pass
-
         # Insert some delay between successive test cases if specified.
         self.doDelay()
 





More information about the lldb-commits mailing list