[Lldb-commits] [lldb] r116648 - in /lldb/trunk/test: lldbtest.py plugins/darwin.py types/AbstractBase.py

Johnny Chen johnny.chen at apple.com
Fri Oct 15 16:55:05 PDT 2010


Author: johnny
Date: Fri Oct 15 18:55:05 2010
New Revision: 116648

URL: http://llvm.org/viewvc/llvm-project?rev=116648&view=rev
Log:
Some re-achitecturing of the plugins interface.  The caller is now required to
pass in a 'sender' arg to the buildDefault(), buildDsym(), buildDwarf(), and
cleanup() functions.  The sender arg will be the test instance itself (i.e.,
an instance of TestBase).  This is so that the relevant command execution can be
recorded in the TestBase.session object if sender is available.

The lldbtest.system() command has been modified to pop the 'sender' arg out of
the keyword arguments dictionary and use it as the test instance to facilitate
seesion recordings.  An example is in test/types/AbstractBase.py:

    def generic_type_tester(self, atoms, quotedDisplay=False):
        """Test that variables with basic types are displayed correctly."""

        # First, capture the golden output emitted by the oracle, i.e., the
        # series of printf statements.
        go = system("./a.out", sender=self)

There are cases when sender is None.  This is the case when the @classmethod is
involved in the use of these APIs.  When this happens, there is no recording
into a session object, but printing on the sys.stderr is still honored if the
trace flag is ON.

An example is in test/settings/TestSettings.py:

    @classmethod
    def classCleanup(cls):
        system(["/bin/sh", "-c", "rm -f output.txt"])
        system(["/bin/sh", "-c", "rm -f stdout.txt"])


Modified:
    lldb/trunk/test/lldbtest.py
    lldb/trunk/test/plugins/darwin.py
    lldb/trunk/test/types/AbstractBase.py

Modified: lldb/trunk/test/lldbtest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=116648&r1=116647&r2=116648&view=diff
==============================================================================
--- lldb/trunk/test/lldbtest.py (original)
+++ lldb/trunk/test/lldbtest.py Fri Oct 15 18:55:05 2010
@@ -185,52 +185,6 @@
 def EnvArray():
     return map(lambda k,v: k+"="+v, os.environ.keys(), os.environ.values())
 
-# From 2.7's subprocess.check_output() convenience function.
-def system(*popenargs, **kwargs):
-    r"""Run command with arguments and return its output as a byte string.
-
-    If the exit code was non-zero it raises a CalledProcessError.  The
-    CalledProcessError object will have the return code in the returncode
-    attribute and output in the output attribute.
-
-    The arguments are the same as for the Popen constructor.  Example:
-
-    >>> check_output(["ls", "-l", "/dev/null"])
-    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
-
-    The stdout argument is not allowed as it is used internally.
-    To capture standard error in the result, use stderr=STDOUT.
-
-    >>> check_output(["/bin/sh", "-c",
-    ...               "ls -l non_existent_file ; exit 0"],
-    ...              stderr=STDOUT)
-    'ls: non_existent_file: No such file or directory\n'
-    """
-    if 'stdout' in kwargs:
-        raise ValueError('stdout argument not allowed, it will be overridden.')
-    process = Popen(stdout=PIPE, *popenargs, **kwargs)
-    output, error = process.communicate()
-    retcode = process.poll()
-
-    if traceAlways:
-        if isinstance(popenargs, types.StringTypes):
-            args = [popenargs]
-        else:
-            args = list(popenargs)
-        print >> sys.stderr
-        print >> sys.stderr, "os command:", args
-        print >> sys.stderr, "stdout:", output
-        print >> sys.stderr, "stderr:", error
-        print >> sys.stderr, "retcode:", retcode
-        print >> sys.stderr
-
-    if retcode:
-        cmd = kwargs.get("args")
-        if cmd is None:
-            cmd = popenargs[0]
-        raise CalledProcessError(retcode, cmd)
-    return output
-
 def line_number(filename, string_to_match):
     """Helper function to return the line number of the first matched string."""
     with open(filename, 'r') as f:
@@ -254,10 +208,9 @@
     into the stderr.
     """
     def __init__(self, test, trace):
-        """Create a StringIO instance; record session, stderr, and trace."""
+        """Create a StringIO instance; record the session obj and trace flag."""
         StringIO.StringIO.__init__(self)
-        self.session = test.session
-        self.stderr = test.old_stderr
+        self.session = test.session if test else None
         self.trace = trace
 
     def __enter__(self):
@@ -274,10 +227,61 @@
         recordings to our session object.  And close the StringIO object, too.
         """
         if self.trace:
-            print >> self.stderr, self.getvalue()
-        print >> self.session, self.getvalue()
+            print >> sys.stderr, self.getvalue()
+        if self.session:
+            print >> self.session, self.getvalue()
         self.close()
 
+# From 2.7's subprocess.check_output() convenience function.
+def system(*popenargs, **kwargs):
+    r"""Run command with arguments and return its output as a byte string.
+
+    If the exit code was non-zero it raises a CalledProcessError.  The
+    CalledProcessError object will have the return code in the returncode
+    attribute and output in the output attribute.
+
+    The arguments are the same as for the Popen constructor.  Example:
+
+    >>> check_output(["ls", "-l", "/dev/null"])
+    'crw-rw-rw- 1 root root 1, 3 Oct 18  2007 /dev/null\n'
+
+    The stdout argument is not allowed as it is used internally.
+    To capture standard error in the result, use stderr=STDOUT.
+
+    >>> check_output(["/bin/sh", "-c",
+    ...               "ls -l non_existent_file ; exit 0"],
+    ...              stderr=STDOUT)
+    'ls: non_existent_file: No such file or directory\n'
+    """
+
+    # Assign the sender object to variable 'test' and remove it from kwargs.
+    test = kwargs.pop('sender', None)
+
+    if 'stdout' in kwargs:
+        raise ValueError('stdout argument not allowed, it will be overridden.')
+    process = Popen(stdout=PIPE, *popenargs, **kwargs)
+    output, error = process.communicate()
+    retcode = process.poll()
+
+    with recording(test, traceAlways) as sbuf:
+        if isinstance(popenargs, types.StringTypes):
+            args = [popenargs]
+        else:
+            args = list(popenargs)
+        print >> sbuf
+        print >> sbuf, "os command:", args
+        print >> sbuf, "stdout:", output
+        print >> sbuf, "stderr:", error
+        print >> sbuf, "retcode:", retcode
+        print >> sbuf
+
+    if retcode:
+        cmd = kwargs.get("args")
+        if cmd is None:
+            cmd = popenargs[0]
+        raise CalledProcessError(retcode, cmd)
+    return output
+
 class TestBase(unittest2.TestCase):
     """This LLDB abstract base class is meant to be subclassed."""
 
@@ -403,16 +407,10 @@
         self.dict = None
         self.doTearDownCleanup = False
 
-        # Create a string buffer to record the session info.
+        # Create a string buffer to record the session info, to be dumped into a
+        # test case specific file if test failure is encountered.
         self.session = StringIO.StringIO()
 
-        # Substitute self.session as the sys.stderr and restore it at the end of
-        # the test during tearDown().  If trace is ON, we dump the session info
-        # into the real stderr as well.  The session info will be dumped into a
-        # test case specific file if a failure is encountered.
-        self.old_stderr = sys.stderr
-        sys.stderr = self.session
-
         # Optimistically set self.__failed__ to False initially.  If the test
         # failed, the session info (self.session) is then dumped into a session
         # specific file for diagnosis.
@@ -469,9 +467,6 @@
         if self.__failed__:
             self.dumpSessionInfo()
 
-        # Restore the sys.stderr to what it was before.
-        sys.stderr = self.old_stderr
-
     def runCmd(self, cmd, msg=None, check=True, trace=False, setCookie=True):
         """
         Ask the command interpreter to handle the command and then check its
@@ -656,19 +651,19 @@
     def buildDefault(self, architecture=None, compiler=None, dictionary=None):
         """Platform specific way to build the default binaries."""
         module = __import__(sys.platform)
-        if not module.buildDefault(architecture, compiler, dictionary):
+        if not module.buildDefault(self, architecture, compiler, dictionary):
             raise Exception("Don't know how to build default binary")
 
     def buildDsym(self, architecture=None, compiler=None, dictionary=None):
         """Platform specific way to build binaries with dsym info."""
         module = __import__(sys.platform)
-        if not module.buildDsym(architecture, compiler, dictionary):
+        if not module.buildDsym(self, architecture, compiler, dictionary):
             raise Exception("Don't know how to build binary with dsym")
 
     def buildDwarf(self, architecture=None, compiler=None, dictionary=None):
         """Platform specific way to build binaries with dwarf maps."""
         module = __import__(sys.platform)
-        if not module.buildDwarf(architecture, compiler, dictionary):
+        if not module.buildDwarf(self, architecture, compiler, dictionary):
             raise Exception("Don't know how to build binary with dwarf")
 
     def DebugSBValue(self, frame, val):

Modified: lldb/trunk/test/plugins/darwin.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/plugins/darwin.py?rev=116648&r1=116647&r2=116648&view=diff
==============================================================================
--- lldb/trunk/test/plugins/darwin.py (original)
+++ lldb/trunk/test/plugins/darwin.py Fri Oct 15 18:55:05 2010
@@ -57,43 +57,46 @@
     return " " + cmdline
 
 
-def buildDefault(architecture=None, compiler=None, dictionary=None):
+def buildDefault(sender=None, architecture=None, compiler=None, dictionary=None):
     """Build the binaries the default way."""
     lldbtest.system(["/bin/sh", "-c",
                      "make clean" + getCmdLine(dictionary) + "; make"
                      + getArchSpec(architecture) + getCCSpec(compiler)
-                     + getCmdLine(dictionary)])
+                     + getCmdLine(dictionary)],
+                    sender=sender)
 
     # True signifies that we can handle building default.
     return True
 
-def buildDsym(architecture=None, compiler=None, dictionary=None):
+def buildDsym(sender=None, architecture=None, compiler=None, dictionary=None):
     """Build the binaries with dsym debug info."""
     lldbtest.system(["/bin/sh", "-c",
                      "make clean" + getCmdLine(dictionary)
                      + "; make MAKE_DSYM=YES"
                      + getArchSpec(architecture) + getCCSpec(compiler)
-                     + getCmdLine(dictionary)])
+                     + getCmdLine(dictionary)],
+                    sender=sender)
 
     # True signifies that we can handle building dsym.
     return True
 
-def buildDwarf(architecture=None, compiler=None, dictionary=None):
+def buildDwarf(sender=None, architecture=None, compiler=None, dictionary=None):
     """Build the binaries with dwarf debug info."""
     lldbtest.system(["/bin/sh", "-c",
                      "make clean" + getCmdLine(dictionary)
                      + "; make MAKE_DSYM=NO"
                      + getArchSpec(architecture) + getCCSpec(compiler)
-                     + getCmdLine(dictionary)])
+                     + getCmdLine(dictionary)],
+                    sender=sender)
 
     # True signifies that we can handle building dsym.
     return True
 
-def cleanup(dictionary=None):
+def cleanup(sender=None, dictionary=None):
     """Perform a platform-specific cleanup after the test."""
     if os.path.isfile("Makefile"):
-        lldbtest.system(["/bin/sh", "-c", "make clean" + getCmdLine(dictionary)]
-                        )
+        lldbtest.system(["/bin/sh", "-c", "make clean"+getCmdLine(dictionary)],
+                        sender=sender)
 
     # True signifies that we can handle building dsym.
     return True

Modified: lldb/trunk/test/types/AbstractBase.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/types/AbstractBase.py?rev=116648&r1=116647&r2=116648&view=diff
==============================================================================
--- lldb/trunk/test/types/AbstractBase.py (original)
+++ lldb/trunk/test/types/AbstractBase.py Fri Oct 15 18:55:05 2010
@@ -24,7 +24,7 @@
 
         # First, capture the golden output emitted by the oracle, i.e., the
         # series of printf statements.
-        go = system("./a.out")
+        go = system("./a.out", sender=self)
         # This golden list contains a list of (variable, value) pairs extracted
         # from the golden output.
         gl = []
@@ -102,7 +102,7 @@
 
         # First, capture the golden output emitted by the oracle, i.e., the
         # series of printf statements.
-        go = system("./a.out")
+        go = system("./a.out", sender=self)
         # This golden list contains a list of (variable, value) pairs extracted
         # from the golden output.
         gl = []





More information about the lldb-commits mailing list