[Lldb-commits] [lldb] r222750 - Add initial lldb-mi tests.

Hafiz Abid Qadeer hafiz_abid at mentor.com
Tue Nov 25 02:41:57 PST 2014


Author: abidh
Date: Tue Nov 25 04:41:57 2014
New Revision: 222750

URL: http://llvm.org/viewvc/llvm-project?rev=222750&view=rev
Log:
Add initial lldb-mi tests.

Test 'test_lldbmi_interrupt' is only enabled for Darwin as
it seems to cause a timeout error on Linux.
Patch from dawn at burble.org.


Added:
    lldb/trunk/test/tools/lldb-mi/
    lldb/trunk/test/tools/lldb-mi/Makefile
    lldb/trunk/test/tools/lldb-mi/TestMiBreakpoint.py
    lldb/trunk/test/tools/lldb-mi/TestMiEvaluate.py
    lldb/trunk/test/tools/lldb-mi/TestMiInterrupt.py
    lldb/trunk/test/tools/lldb-mi/TestMiLaunch.py
    lldb/trunk/test/tools/lldb-mi/TestMiProgramArgs.py
    lldb/trunk/test/tools/lldb-mi/a.c
    lldb/trunk/test/tools/lldb-mi/b.c
    lldb/trunk/test/tools/lldb-mi/loop.c
    lldb/trunk/test/tools/lldb-mi/main.c
Modified:
    lldb/trunk/test/dotest.py
    lldb/trunk/test/lldbtest.py

Modified: lldb/trunk/test/dotest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/dotest.py?rev=222750&r1=222749&r2=222750&view=diff
==============================================================================
--- lldb/trunk/test/dotest.py (original)
+++ lldb/trunk/test/dotest.py Tue Nov 25 04:41:57 2014
@@ -116,6 +116,12 @@ dont_do_python_api_test = False
 # By default, both command line and Python API tests are performed.
 just_do_python_api_test = False
 
+# By default, lldb-mi tests are performed if lldb-mi can be found.
+# Use @lldbmi_test decorator, defined in lldbtest.py, to mark a test as
+# a lldb-mi test.
+dont_do_lldbmi_test = False
+just_do_lldbmi_test = False
+
 # By default, benchmarks tests are not run.
 just_do_benchmarks_test = False
 
@@ -429,6 +435,8 @@ def parseOptionsAndInitTestdirs():
 
     global dont_do_python_api_test
     global just_do_python_api_test
+    global dont_do_lldbmi_test
+    global just_do_lldbmi_test
     global just_do_benchmarks_test
     global dont_do_dsym_test
     global dont_do_dwarf_test
@@ -504,6 +512,8 @@ def parseOptionsAndInitTestdirs():
     group.add_argument('-f', metavar='filterspec', action='append', help='Specify a filter, which consists of the test class name, a dot, followed by the test method, to only admit such test into the test suite')  # FIXME: Example?
     X('-g', 'If specified, the filterspec by -f is not exclusive, i.e., if a test module does not match the filterspec (testclass.testmethod), the whole module is still admitted to the test suite')
     X('-l', "Don't skip long running tests")
+    X('-m', "Don't do lldb-mi tests")
+    X('+m', "Just do lldb-mi tests. Do not specify along with '+m'", dest='plus_m')
     group.add_argument('-p', metavar='pattern', help='Specify a regexp filename pattern for inclusion in the test suite')
     group.add_argument('-X', metavar='directory', help="Exclude a directory from consideration for test discovery. -X types => if 'types' appear in the pathname components of a potential testfile, it will be ignored")
     group.add_argument('-G', '--category', metavar='category', action='append', dest='categoriesList', help=textwrap.dedent('''Specify categories of test cases of interest. Can be specified more than once.'''))
@@ -676,6 +686,15 @@ def parseOptionsAndInitTestdirs():
     if args.l:
         skip_long_running_test = False
 
+    if args.m:
+        dont_do_lldbmi_test = True
+
+    if args.plus_m:
+        if dont_do_lldbmi_test:
+            print "Warning: -m and +m can't both be specified! Using only -m"
+        else:
+            just_do_lldbmi_test = True
+
     if args.framework:
         lldbFrameworkPath = args.framework
 
@@ -763,6 +782,10 @@ def parseOptionsAndInitTestdirs():
     if dont_do_python_api_test and just_do_python_api_test:
         usage(parser)
 
+    # Do not specify both '-m' and '+m' at the same time.
+    if dont_do_lldbmi_test and just_do_lldbmi_test:
+        usage(parser)
+
     if args.lldb_platform_name:
         lldb_platform_name = args.lldb_platform_name
     if args.lldb_platform_url:
@@ -917,6 +940,7 @@ def setupSysPath():
     # We'll try to locate the appropriate executable right here.
 
     lldbExec = None
+    lldbMiExec = None
     if lldbExecutablePath:
         if is_exe(lldbExecutablePath):
             lldbExec = lldbExecutablePath
@@ -984,6 +1008,20 @@ def setupSysPath():
         os.environ["LLDB_EXEC"] = lldbExec
         #print "The 'lldb' from PATH env variable", lldbExec
 
+    # Assume lldb-mi is in same place as lldb
+    # If not found, disable the lldb-mi tests
+    global dont_do_lldbmi_test
+    if is_exe(lldbExec + "-mi"):
+        lldbMiExec = lldbExec + "-mi"
+    if not lldbMiExec:
+        dont_do_lldbmi_test = True
+        if just_do_lldbmi_test:
+            print "The 'lldb-mi' executable cannot be located.  The lldb-mi tests can not be run as a result."
+        else:
+            print "The 'lldb-mi' executable cannot be located.  Some of the tests may not be run as a result."
+    else:
+        os.environ["LLDBMI_EXEC"] = lldbMiExec
+
     # Skip printing svn/git information when running in parsable (lit-test compatibility) mode
     if not svn_silent and not parsable:
         if os.path.isdir(os.path.join(base, '.svn')) and which("svn") is not None:
@@ -1314,6 +1352,8 @@ lldb.lldbtest_remote_shell_template = ll
 # Put all these test decorators in the lldb namespace.
 lldb.dont_do_python_api_test = dont_do_python_api_test
 lldb.just_do_python_api_test = just_do_python_api_test
+lldb.dont_do_lldbmi_test = dont_do_lldbmi_test
+lldb.just_do_lldbmi_test = just_do_lldbmi_test
 lldb.just_do_benchmarks_test = just_do_benchmarks_test
 lldb.dont_do_dsym_test = dont_do_dsym_test
 lldb.dont_do_dwarf_test = dont_do_dwarf_test
@@ -1750,4 +1790,4 @@ if ("LLDB_TESTSUITE_FORCE_FINISH" in os.
     subprocess.Popen(["/bin/sh", "-c", "kill %s; exit 0" % (os.getpid())])
 
 # Exiting.
-exitTestSuite(failed)
\ No newline at end of file
+exitTestSuite(failed)

Modified: lldb/trunk/test/lldbtest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=222750&r1=222749&r2=222750&view=diff
==============================================================================
--- lldb/trunk/test/lldbtest.py (original)
+++ lldb/trunk/test/lldbtest.py Tue Nov 25 04:41:57 2014
@@ -334,6 +334,23 @@ def python_api_test(func):
     wrapper.__python_api_test__ = True
     return wrapper
 
+def lldbmi_test(func):
+    """Decorate the item as a lldb-mi only test."""
+    if isinstance(func, type) and issubclass(func, unittest2.TestCase):
+        raise Exception("@lldbmi_test can only be used to decorate a test method")
+    @wraps(func)
+    def wrapper(self, *args, **kwargs):
+        try:
+            if lldb.dont_do_lldbmi_test:
+                self.skipTest("lldb-mi tests")
+        except AttributeError:
+            pass
+        return func(self, *args, **kwargs)
+
+    # Mark this function as such to separate them from lldb command line tests.
+    wrapper.__lldbmi_test__ = True
+    return wrapper
+
 def benchmarks_test(func):
     """Decorate the item as a benchmarks test."""
     if isinstance(func, type) and issubclass(func, unittest2.TestCase):
@@ -773,6 +790,11 @@ class Base(unittest2.TestCase):
             self.lldbExec = os.environ["LLDB_EXEC"]
         else:
             self.lldbExec = None
+        if "LLDBMI_EXEC" in os.environ:
+            self.lldbMiExec = os.environ["LLDBMI_EXEC"]
+        else:
+            self.lldbMiExec = None
+            self.dont_do_lldbmi_test = True
         if "LLDB_HERE" in os.environ:
             self.lldbHere = os.environ["LLDB_HERE"]
         else:
@@ -805,6 +827,19 @@ class Base(unittest2.TestCase):
         except AttributeError:
             pass
 
+        # lldb-mi only test is decorated with @lldbmi_test,
+        # which also sets the "__lldbmi_test__" attribute of the
+        # function object to True.
+        try:
+            if lldb.just_do_lldbmi_test:
+                testMethod = getattr(self, self._testMethodName)
+                if getattr(testMethod, "__lldbmi_test__", False):
+                    pass
+                else:
+                    self.skipTest("non lldb-mi test")
+        except AttributeError:
+            pass
+
         # Benchmarks test is decorated with @benchmarks_test,
         # which also sets the "__benchmarks_test__" attribute of the
         # function object to True.

Added: lldb/trunk/test/tools/lldb-mi/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/Makefile?rev=222750&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/Makefile (added)
+++ lldb/trunk/test/tools/lldb-mi/Makefile Tue Nov 25 04:41:57 2014
@@ -0,0 +1,5 @@
+LEVEL = ../../make
+
+C_SOURCES := main.c a.c b.c loop.c
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/tools/lldb-mi/TestMiBreakpoint.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/TestMiBreakpoint.py?rev=222750&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/TestMiBreakpoint.py (added)
+++ lldb/trunk/test/tools/lldb-mi/TestMiBreakpoint.py Tue Nov 25 04:41:57 2014
@@ -0,0 +1,234 @@
+"""
+Test that the lldb-mi driver understands an MI breakpoint command.
+"""
+
+import os
+import unittest2
+import lldb
+from lldbtest import *
+
+class MiBreakpointTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+    myexe = "a.out"
+
+    @classmethod
+    def classCleanup(cls):
+        """Cleanup the test byproducts."""
+        try:
+            os.remove("child_send.txt")
+            os.remove("child_read.txt")
+            os.remove(cls.myexe)
+        except:
+            pass
+
+    @lldbmi_test
+    def test_lldbmi_pendbreakonsym(self):
+        """Test that 'lldb-mi --interpreter' works for pending symbol breakpoints."""
+        import pexpect
+        self.buildDefault()
+
+        # The default lldb-mi prompt (seriously?!).
+        prompt = "(gdb)"
+
+        # So that the child gets torn down after the test.
+        self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
+        child = self.child
+        child.setecho(True)
+        # Turn on logging for input/output to/from the child.
+        with open('child_send.txt', 'w') as f_send:
+            with open('child_read.txt', 'w') as f_read:
+                child.logfile_send = f_send
+                child.logfile_read = f_read
+
+                child.send("-file-exec-and-symbols " + self.myexe)
+                child.sendline('')
+                child.expect("\^done")
+
+                child.send("-break-insert -f a_MyFunction")
+                child.sendline('')
+                child.expect("\^done,bkpt={number=\"1\"")
+
+                child.send("-exec-run")
+                child.sendline('') # FIXME: lldb-mi hangs here, so the extra return below is needed
+                child.send("")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+                child.send("-exec-continue")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"exited-normally\"")
+                child.expect_exact(prompt)
+
+                child.send("quit")
+                child.sendline('')
+
+        # Now that the necessary logging is done, restore logfile to None to
+        # stop further logging.
+        child.logfile_send = None
+        child.logfile_read = None
+        
+        with open('child_send.txt', 'r') as fs:
+            if self.TraceOn():
+                print "\n\nContents of child_send.txt:"
+                print fs.read()
+        with open('child_read.txt', 'r') as fr:
+            from_child = fr.read()
+            if self.TraceOn():
+                print "\n\nContents of child_read.txt:"
+                print from_child
+
+            self.expect(from_child, exe=False,
+                substrs = ["breakpoint-hit"])
+
+    @lldbmi_test
+    def test_lldbmi_pendbreakonsrc(self):
+        """Test that 'lldb-mi --interpreter' works for pending source breakpoints."""
+        import pexpect
+        self.buildDefault()
+
+        # The default lldb-mi prompt (seriously?!).
+        prompt = "(gdb)"
+
+        # So that the child gets torn down after the test.
+        self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
+        child = self.child
+        child.setecho(True)
+        # Turn on logging for input/output to/from the child.
+        with open('child_send.txt', 'w') as f_send:
+            with open('child_read.txt', 'w') as f_read:
+                child.logfile_send = f_send
+                child.logfile_read = f_read
+
+                child.send("-file-exec-and-symbols " + self.myexe)
+                child.sendline('')
+                child.expect("\^done")
+
+                child.send("-break-insert -f main.c:22")
+                child.sendline('')
+                child.expect("\^done,bkpt={number=\"1\"")
+
+                child.send("-exec-run")
+                child.sendline('') # FIXME: lldb-mi hangs here, so the extra return below is needed
+                child.send("")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+                child.send("-exec-continue")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"exited-normally\"")
+                child.expect_exact(prompt)
+
+                child.send("quit")
+                child.sendline('')
+
+        # Now that the necessary logging is done, restore logfile to None to
+        # stop further logging.
+        child.logfile_send = None
+        child.logfile_read = None
+        
+        with open('child_send.txt', 'r') as fs:
+            if self.TraceOn():
+                print "\n\nContents of child_send.txt:"
+                print fs.read()
+        with open('child_read.txt', 'r') as fr:
+            from_child = fr.read()
+            if self.TraceOn():
+                print "\n\nContents of child_read.txt:"
+                print from_child
+
+            self.expect(from_child, exe=False,
+                substrs = ["breakpoint-hit"])
+
+    @lldbmi_test
+    def test_lldbmi_breakpoints(self):
+        """Test that 'lldb-mi --interpreter' works for breakpoints."""
+        import pexpect
+        self.buildDefault()
+
+        # The default lldb-mi prompt (seriously?!).
+        prompt = "(gdb)"
+
+        # So that the child gets torn down after the test.
+        self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
+        child = self.child
+        child.setecho(True)
+        # Turn on logging for input/output to/from the child.
+        with open('child_send.txt', 'w') as f_send:
+            with open('child_read.txt', 'w') as f_read:
+                child.logfile_send = f_send
+                child.logfile_read = f_read
+
+                child.send("-file-exec-and-symbols " + self.myexe)
+                child.sendline('')
+                child.expect("\^done")
+
+                child.send("-break-insert -f main")
+                child.sendline('')
+                child.expect("\^done,bkpt={number=\"1\"")
+
+                child.send("-exec-run")
+                child.sendline('') # FIXME: lldb-mi hangs here, so the extra return below is needed
+                child.send("")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+                #break on symbol
+                child.send("-break-insert a_MyFunction")
+                child.sendline('')
+                child.expect("\^done,bkpt={number=\"2\"")
+
+                child.send("-exec-continue")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+                #break on source
+                child.send("-break-insert main.c:29")
+                child.sendline('')
+                child.expect("\^done,bkpt={number=\"3\"")
+
+                child.send("-exec-continue")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+                #run to exit
+                child.send("-exec-continue")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"exited-normally\"")
+                child.expect_exact(prompt)
+
+                child.send("quit")
+                child.sendline('')
+
+        # Now that the necessary logging is done, restore logfile to None to
+        # stop further logging.
+        child.logfile_send = None
+        child.logfile_read = None
+        
+        with open('child_send.txt', 'r') as fs:
+            if self.TraceOn():
+                print "\n\nContents of child_send.txt:"
+                print fs.read()
+        with open('child_read.txt', 'r') as fr:
+            from_child = fr.read()
+            if self.TraceOn():
+                print "\n\nContents of child_read.txt:"
+                print from_child
+
+            self.expect(from_child, exe=False,
+                substrs = ["breakpoint-hit"])
+
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/tools/lldb-mi/TestMiEvaluate.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/TestMiEvaluate.py?rev=222750&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/TestMiEvaluate.py (added)
+++ lldb/trunk/test/tools/lldb-mi/TestMiEvaluate.py Tue Nov 25 04:41:57 2014
@@ -0,0 +1,162 @@
+"""
+Test that the lldb-mi driver can evaluate expressions.
+"""
+
+import os
+import unittest2
+import lldb
+from lldbtest import *
+
+class MiEvaluateTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+    myexe = "a.out"
+
+    @classmethod
+    def classCleanup(cls):
+        """Cleanup the test byproducts."""
+        try:
+            os.remove("child_send.txt")
+            os.remove("child_read.txt")
+            os.remove(cls.myexe)
+        except:
+            pass
+
+    @lldbmi_test
+    def test_lldbmi_eval(self):
+        """Test that 'lldb-mi --interpreter' works for evaluating."""
+        import pexpect
+        self.buildDefault()
+
+        # The default lldb-mi prompt (seriously?!).
+        prompt = "(gdb)"
+
+        # So that the child gets torn down after the test.
+        self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
+        child = self.child
+        child.setecho(True)
+        # Turn on logging for input/output to/from the child.
+        with open('child_send.txt', 'w') as f_send:
+            with open('child_read.txt', 'w') as f_read:
+                child.logfile_send = f_send
+                child.logfile_read = f_read
+
+                child.send("-file-exec-and-symbols " + self.myexe)
+                child.sendline('')
+                child.expect("\^done")
+
+                #run to main
+                child.send("-break-insert -f main")
+                child.sendline('')
+                child.expect("\^done,bkpt={number=\"1\"")
+
+                child.send("-exec-run")
+                child.sendline('') #FIXME: hangs here; extra return below is needed
+                child.send("")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+                #run to program return
+                child.send("-break-insert main.c:30") #BP_source
+                child.sendline('')
+                child.expect("\^done,bkpt={number=\"2\"")
+
+                child.send("-exec-continue")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+                #print non-existant variable
+                #child.send("-var-create var1 --thread 1 --frame 0 * undef")
+                #child.sendline('') #FIXME: shows undef as {...}
+                #child.expect("error")
+                #child.send("-data-evaluate-expression undef")
+                #child.sendline('') #FIXME: gets value="undef"
+                #child.expect("error")
+
+                #print global "g_MyVar"
+                child.send("-var-create var1 --thread 1 --frame 0 * g_MyVar")
+                child.sendline('') #FIXME: shows name=<unnamedvariable>"
+                child.expect("value=\"3\",type=\"int\"")
+                #child.send("-var-evaluate-expression var1")
+                #child.sendline('') #FIXME: gets var1 does not exist
+                child.send("-var-show-attributes var1")
+                child.sendline('')
+                child.expect("status=\"editable\"")
+                child.send("-var-delete var1")
+                child.sendline('')
+                child.expect("\^done")
+                child.send("-var-create var1 --thread 1 --frame 0 * g_MyVar")
+                child.sendline('')
+                child.expect("value=\"3\",type=\"int\"")
+
+                #print static "s_MyVar" and modify
+                child.send("-data-evaluate-expression s_MyVar")
+                child.sendline('')
+                child.expect("value=\"30\"")
+                child.send("-var-create var3 --thread 1 --frame 0 * \"s_MyVar=3\"")
+                child.sendline('')
+                child.expect("value=\"3\",type=\"int\"")
+                child.send("-data-evaluate-expression \"s_MyVar=30\"")
+                child.sendline('')
+                child.expect("value=\"30\"")
+
+                #print local "b" and modify
+                child.send("-data-evaluate-expression b")
+                child.sendline('')
+                child.expect("value=\"20\"")
+                child.send("-var-create var3 --thread 1 --frame 0 * \"b=3\"")
+                child.sendline('')
+                child.expect("value=\"3\",type=\"int\"")
+                child.send("-data-evaluate-expression \"b=20\"")
+                child.sendline('')
+                child.expect("value=\"20\"")
+
+                #print "a + b"
+                child.send("-data-evaluate-expression \"a + b\"")
+                child.sendline('')
+                child.expect("value=\"30\"")
+                child.send("-var-create var3 --thread 1 --frame 0 * \"a + b\"")
+                child.sendline('')
+                child.expect("value=\"30\",type=\"int\"")
+
+                #print "argv[0]"
+                child.send("-data-evaluate-expression \"argv[0]\"")
+                child.sendline('')
+                child.expect("value=\"0x")
+                child.send("-var-create var3 --thread 1 --frame 0 * \"argv[0]\"")
+                child.sendline('')
+                child.expect("numchild=\"1\",value=\"0x.*\",type=\"const char \*\"")
+
+                #run to exit
+                child.send("-exec-continue")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"exited-normally\"")
+                child.expect_exact(prompt)
+
+                child.send("quit")
+                child.sendline('')
+
+        # Now that the necessary logging is done, restore logfile to None to
+        # stop further logging.
+        child.logfile_send = None
+        child.logfile_read = None
+        
+        with open('child_send.txt', 'r') as fs:
+            if self.TraceOn():
+                print "\n\nContents of child_send.txt:"
+                print fs.read()
+        with open('child_read.txt', 'r') as fr:
+            from_child = fr.read()
+            if self.TraceOn():
+                print "\n\nContents of child_read.txt:"
+                print from_child
+
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/tools/lldb-mi/TestMiInterrupt.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/TestMiInterrupt.py?rev=222750&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/TestMiInterrupt.py (added)
+++ lldb/trunk/test/tools/lldb-mi/TestMiInterrupt.py Tue Nov 25 04:41:57 2014
@@ -0,0 +1,115 @@
+"""
+Test that the lldb-mi driver can interrupt and resume a looping app.
+"""
+
+import os
+import unittest2
+import lldb
+from lldbtest import *
+
+class MiInterruptTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+    myexe = "a.out"
+
+    @classmethod
+    def classCleanup(cls):
+        """Cleanup the test byproducts."""
+        try:
+            os.remove("child_send.txt")
+            os.remove("child_read.txt")
+            os.remove(cls.myexe)
+        except:
+            pass
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    @lldbmi_test
+    def test_lldbmi_interrupt(self):
+        """Test that 'lldb-mi --interpreter' interrupt and resume a looping app."""
+        import pexpect
+        self.buildDefault()
+
+        # The default lldb-mi prompt (seriously?!).
+        prompt = "(gdb)"
+
+        # So that the child gets torn down after the test.
+        self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
+        child = self.child
+        child.setecho(True)
+        # Turn on logging for input/output to/from the child.
+        with open('child_send.txt', 'w') as f_send:
+            with open('child_read.txt', 'w') as f_read:
+                child.logfile_send = f_send
+                child.logfile_read = f_read
+
+                child.send("-file-exec-and-symbols " + self.myexe)
+                child.sendline('')
+                child.expect("\^done")
+
+                #run to main
+                child.send("-break-insert -f main")
+                child.sendline('')
+                child.expect("\^done,bkpt={number=\"1\"")
+                child.send("-exec-run")
+                child.sendline('') #FIXME: hangs here; extra return below is needed
+                child.send("")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+                #set doloop=1 and run (to loop forever)
+                child.send("-data-evaluate-expression \"doloop=1\"")
+                child.sendline('')
+                child.expect("value=\"1\"")
+                child.send("-exec-continue")
+                child.sendline('')
+                child.expect("\^running")
+
+                #issue interrupt, set a bp, and resume
+                child.send("-exec-interrupt")
+                child.sendline('')
+                child.expect("\*stopped,reason=\"signal-received\"")
+                child.send("-break-insert loop.c:11")
+                child.sendline('')
+                child.expect("\^done,bkpt={number=\"2\"")
+                #child.send("-exec-resume")
+                #child.sendline('') #FIXME: command not recognized
+                child.send("-exec-continue")
+                child.sendline('')
+                child.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+                #we should be sitting at loop.c:12
+                #set loop=-1 so we'll exit the loop
+                child.send("-data-evaluate-expression \"loop=-1\"")
+                child.sendline('')
+                child.expect("value=\"-1\"")
+                child.send("-exec-continue")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"exited-normally\"")
+                child.expect_exact(prompt)
+
+                child.send("quit")
+                child.sendline('')
+
+        # Now that the necessary logging is done, restore logfile to None to
+        # stop further logging.
+        child.logfile_send = None
+        child.logfile_read = None
+        
+        with open('child_send.txt', 'r') as fs:
+            if self.TraceOn():
+                print "\n\nContents of child_send.txt:"
+                print fs.read()
+        with open('child_read.txt', 'r') as fr:
+            from_child = fr.read()
+            if self.TraceOn():
+                print "\n\nContents of child_read.txt:"
+                print from_child
+
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/tools/lldb-mi/TestMiLaunch.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/TestMiLaunch.py?rev=222750&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/TestMiLaunch.py (added)
+++ lldb/trunk/test/tools/lldb-mi/TestMiLaunch.py Tue Nov 25 04:41:57 2014
@@ -0,0 +1,229 @@
+"""
+Test various ways the lldb-mi driver can launch a program.
+"""
+
+import os
+import unittest2
+import lldb
+from lldbtest import *
+
+class MiLaunchTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+    myexe = "a.out"
+
+    @classmethod
+    def classCleanup(cls):
+        """Cleanup the test byproducts."""
+        try:
+            os.remove("child_send.txt")
+            os.remove("child_read.txt")
+            os.remove(cls.myexe)
+        except:
+            pass
+
+    @lldbmi_test
+    def test_lldbmi_exe(self):
+        """Test that 'lldb-mi --interpreter' works for -file-exec-and-symbols exe."""
+        import pexpect
+        self.buildDefault()
+
+        # The default lldb-mi prompt (seriously?!).
+        prompt = "(gdb)"
+
+        # So that the child gets torn down after the test.
+        self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
+        child = self.child
+        child.setecho(True)
+        # Turn on logging for input/output to/from the child.
+        with open('child_send.txt', 'w') as f_send:
+            with open('child_read.txt', 'w') as f_read:
+                child.logfile_send = f_send
+                child.logfile_read = f_read
+
+                #use no path
+                child.send("-file-exec-and-symbols " + self.myexe)
+                child.sendline('')
+                child.expect("\^done")
+
+                child.send("-exec-run")
+                child.sendline('') # FIXME: lldb-mi hangs here, so the extra return below is needed
+                child.send("")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"exited-normally\"")
+                child.expect_exact(prompt)
+
+                child.send("quit")
+                child.sendline('')
+
+        # Now that the necessary logging is done, restore logfile to None to
+        # stop further logging.
+        child.logfile_send = None
+        child.logfile_read = None
+        
+        with open('child_send.txt', 'r') as fs:
+            if self.TraceOn():
+                print "\n\nContents of child_send.txt:"
+                print fs.read()
+        with open('child_read.txt', 'r') as fr:
+            from_child = fr.read()
+            if self.TraceOn():
+                print "\n\nContents of child_read.txt:"
+                print from_child
+
+    @lldbmi_test
+    def test_lldbmi_abspathexe(self):
+        """Test that 'lldb-mi --interpreter' works for -file-exec-and-symbols fullpath/exe."""
+        import pexpect
+        self.buildDefault()
+
+        # The default lldb-mi prompt (seriously?!).
+        prompt = "(gdb)"
+
+        # So that the child gets torn down after the test.
+        self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
+        child = self.child
+        child.setecho(True)
+        # Turn on logging for input/output to/from the child.
+        with open('child_send.txt', 'w') as f_send:
+            with open('child_read.txt', 'w') as f_read:
+                child.logfile_send = f_send
+                child.logfile_read = f_read
+
+                #use full path
+                exe = os.path.join(os.getcwd(), "a.out")
+                child.send("-file-exec-and-symbols " + exe)
+                child.sendline('')
+                child.expect("\^done")
+
+                child.send("-exec-run")
+                child.sendline('') # FIXME: lldb-mi hangs here, so the extra return below is needed
+                child.send("")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"exited-normally\"")
+                child.expect_exact(prompt)
+
+                child.send("quit")
+                child.sendline('')
+
+        # Now that the necessary logging is done, restore logfile to None to
+        # stop further logging.
+        child.logfile_send = None
+        child.logfile_read = None
+        
+        with open('child_send.txt', 'r') as fs:
+            if self.TraceOn():
+                print "\n\nContents of child_send.txt:"
+                print fs.read()
+        with open('child_read.txt', 'r') as fr:
+            from_child = fr.read()
+            if self.TraceOn():
+                print "\n\nContents of child_read.txt:"
+                print from_child
+
+    @lldbmi_test
+    def test_lldbmi_relpathexe(self):
+        """Test that 'lldb-mi --interpreter' works for -file-exec-and-symbols relpath/exe."""
+        import pexpect
+        self.buildDefault()
+
+        # The default lldb-mi prompt (seriously?!).
+        prompt = "(gdb)"
+
+        # So that the child gets torn down after the test.
+        self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
+        child = self.child
+        child.setecho(True)
+        # Turn on logging for input/output to/from the child.
+        with open('child_send.txt', 'w') as f_send:
+            with open('child_read.txt', 'w') as f_read:
+                child.logfile_send = f_send
+                child.logfile_read = f_read
+
+                #use relative path
+                exe = "../../" + self.mydir + "/" + self.myexe
+                child.send("-file-exec-and-symbols " + exe)
+                child.sendline('')
+                child.expect("\^done")
+
+                child.send("-exec-run")
+                child.sendline('') # FIXME: lldb-mi hangs here, so the extra return below is needed
+                child.send("")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"exited-normally\"")
+                child.expect_exact(prompt)
+
+                child.send("quit")
+                child.sendline('')
+
+        # Now that the necessary logging is done, restore logfile to None to
+        # stop further logging.
+        child.logfile_send = None
+        child.logfile_read = None
+        
+        with open('child_send.txt', 'r') as fs:
+            if self.TraceOn():
+                print "\n\nContents of child_send.txt:"
+                print fs.read()
+        with open('child_read.txt', 'r') as fr:
+            from_child = fr.read()
+            if self.TraceOn():
+                print "\n\nContents of child_read.txt:"
+                print from_child
+
+    @unittest2.skip("lldb-mi badpath hang")
+    @lldbmi_test
+    def test_lldbmi_badpathexe(self):
+        """Test that 'lldb-mi --interpreter' works for -file-exec-and-symbols badpath/exe."""
+        import pexpect
+        self.buildDefault()
+
+        # The default lldb-mi prompt (seriously?!).
+        prompt = "(gdb)"
+
+        # So that the child gets torn down after the test.
+        self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
+        child = self.child
+        child.setecho(True)
+        # Turn on logging for input/output to/from the child.
+        with open('child_send.txt', 'w') as f_send:
+            with open('child_read.txt', 'w') as f_read:
+                child.logfile_send = f_send
+                child.logfile_read = f_read
+
+                #use relative path
+                exe = "badpath/" + self.myexe
+                #print ("-file-exec-and-symbols " + exe)
+                child.send("-file-exec-and-symbols " + exe)
+                child.sendline('') #FIXME: non-existant directory caused hang
+                child.expect("\^error")
+
+                child.expect_exact(prompt)
+
+                child.send("quit")
+                child.sendline('')
+
+        # Now that the necessary logging is done, restore logfile to None to
+        # stop further logging.
+        child.logfile_send = None
+        child.logfile_read = None
+        
+        with open('child_send.txt', 'r') as fs:
+            if self.TraceOn():
+                print "\n\nContents of child_send.txt:"
+                print fs.read()
+        with open('child_read.txt', 'r') as fr:
+            from_child = fr.read()
+            if self.TraceOn():
+                print "\n\nContents of child_read.txt:"
+                print from_child
+
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/tools/lldb-mi/TestMiProgramArgs.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/TestMiProgramArgs.py?rev=222750&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/TestMiProgramArgs.py (added)
+++ lldb/trunk/test/tools/lldb-mi/TestMiProgramArgs.py Tue Nov 25 04:41:57 2014
@@ -0,0 +1,101 @@
+"""
+Test that the lldb-mi driver can pass arguments to the app.
+"""
+
+import os
+import unittest2
+import lldb
+from lldbtest import *
+
+class MiProgramArgsTestCase(TestBase):
+
+    mydir = TestBase.compute_mydir(__file__)
+    myexe = "a.out"
+
+    @classmethod
+    def classCleanup(cls):
+        """Cleanup the test byproducts."""
+        try:
+            os.remove("child_send.txt")
+            os.remove("child_read.txt")
+            os.remove(cls.myexe)
+        except:
+            pass
+
+    @unittest2.skip("lldb-mi can't pass params to app.")
+    @lldbmi_test
+    def test_lldbmi_paramargs(self):
+        """Test that 'lldb-mi --interpreter' can pass arguments to the app."""
+        import pexpect
+        self.buildDefault()
+
+        # The default lldb-mi prompt (seriously?!).
+        prompt = "(gdb)"
+
+        # So that the child gets torn down after the test.
+        self.child = pexpect.spawn('%s --interpreter' % (self.lldbMiExec))
+        child = self.child
+        child.setecho(True)
+        # Turn on logging for input/output to/from the child.
+        with open('child_send.txt', 'w') as f_send:
+            with open('child_read.txt', 'w') as f_read:
+                child.logfile_send = f_send
+                child.logfile_read = f_read
+
+                child.send("-file-exec-and-symbols " + self.myexe)
+                child.sendline('')
+                child.expect("\^done")
+
+                #child.send("-exec-arguments l")
+                #child.sendline('') #FIXME: not recognized and hung lldb-mi
+                child.send("settings set target.run-args l")
+                child.sendline('') #FIXME: args not passed
+
+                #run to main
+                child.send("-break-insert -f main")
+                child.sendline('')
+                child.expect("\^done,bkpt={number=\"1\"")
+                child.send("-exec-run")
+                child.sendline('') #FIXME: hangs here; extra return below is needed
+                child.send("")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+                #check argc to see if arg passed
+                child.send("-data-evaluate-expression argc")
+                child.sendline('')
+                child.expect("value=\"2\"")
+
+                #set BP on code which is only executed if "l" was passed correctly
+                child.send("-break-insert main.c:27") #BP_argtest
+                child.sendline('')
+                child.expect("\^done,bkpt={number=\"2\"")
+                child.send("-exec-continue")
+                child.sendline('')
+                child.expect("\^running")
+                child.expect("\*stopped,reason=\"breakpoint-hit\"")
+
+                child.send("quit")
+                child.sendline('')
+
+        # Now that the necessary logging is done, restore logfile to None to
+        # stop further logging.
+        child.logfile_send = None
+        child.logfile_read = None
+        
+        with open('child_send.txt', 'r') as fs:
+            if self.TraceOn():
+                print "\n\nContents of child_send.txt:"
+                print fs.read()
+        with open('child_read.txt', 'r') as fr:
+            from_child = fr.read()
+            if self.TraceOn():
+                print "\n\nContents of child_read.txt:"
+                print from_child
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/tools/lldb-mi/a.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/a.c?rev=222750&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/a.c (added)
+++ lldb/trunk/test/tools/lldb-mi/a.c Tue Nov 25 04:41:57 2014
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int
+a_MyFunction ()
+{
+  // Set a breakpoint here.
+  printf ("a is about to return 10.\n");
+  return 10;
+}

Added: lldb/trunk/test/tools/lldb-mi/b.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/b.c?rev=222750&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/b.c (added)
+++ lldb/trunk/test/tools/lldb-mi/b.c Tue Nov 25 04:41:57 2014
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+int
+b_MyFunction ()
+{
+  // Set a breakpoint here.
+  printf ("b is about to return 20.\n");
+  return 20;
+}

Added: lldb/trunk/test/tools/lldb-mi/loop.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/loop.c?rev=222750&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/loop.c (added)
+++ lldb/trunk/test/tools/lldb-mi/loop.c Tue Nov 25 04:41:57 2014
@@ -0,0 +1,14 @@
+#include <unistd.h>
+int
+infloop ()
+{
+    int loop = 1;
+    while (loop > 0) {
+        if (loop > 10) {
+            sleep(1);
+            loop = 1;
+        }
+        loop++; // Set break point at this line.
+    }
+    return loop;
+}

Added: lldb/trunk/test/tools/lldb-mi/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/tools/lldb-mi/main.c?rev=222750&view=auto
==============================================================================
--- lldb/trunk/test/tools/lldb-mi/main.c (added)
+++ lldb/trunk/test/tools/lldb-mi/main.c Tue Nov 25 04:41:57 2014
@@ -0,0 +1,31 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdio.h>
+extern int a_MyFunction();
+extern int b_MyFunction();
+extern int infloop();
+int doloop;
+int g_MyVar = 3;
+static int s_MyVar = 4;
+int main (int argc, char const *argv[])
+{
+    int a, b;
+    printf("argc=%d\n", argc);
+    a = a_MyFunction();
+    b = b_MyFunction();
+    if (doloop)
+        infloop();
+    if (argc > 1 && *argv[1] == 'l') {
+        a++;
+        printf("a=%d, argv[1]=%s\n", a, argv[1]); //BP_argtest
+    }
+    s_MyVar = a + b;
+    return a + b - s_MyVar; //BP_source
+}





More information about the lldb-commits mailing list