[Lldb-commits] [lldb] r114480 - in /lldb/trunk/test: breakpoint_command/ breakpoint_command/Makefile breakpoint_command/TestBreakpointCommand.py breakpoint_command/main.c lldbtest.py

Johnny Chen johnny.chen at apple.com
Tue Sep 21 14:08:54 PDT 2010


Author: johnny
Date: Tue Sep 21 16:08:53 2010
New Revision: 114480

URL: http://llvm.org/viewvc/llvm-project?rev=114480&view=rev
Log:
Added a more complex test case of breakpoint commands, which executes a sequence
of 'breakpoint command add/list/remove' commands to set breakpoint callbacks,
list them, and then remove one.

Modified the lldbtest.TestBase.expect() method to add two additional keyword
arguments:

o matching (default to True), which, if set to False, reverses the semantics of
  'expect' to 'expect not'

o patterns (default to None), which specifies a list of regexp patterns to match
  against the output from running the command

TestBreakpointCommand.py uses the matching=False and the patterns=[...] expect()
API.

Added:
    lldb/trunk/test/breakpoint_command/
    lldb/trunk/test/breakpoint_command/Makefile
    lldb/trunk/test/breakpoint_command/TestBreakpointCommand.py
    lldb/trunk/test/breakpoint_command/main.c
Modified:
    lldb/trunk/test/lldbtest.py

Added: lldb/trunk/test/breakpoint_command/Makefile
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/breakpoint_command/Makefile?rev=114480&view=auto
==============================================================================
--- lldb/trunk/test/breakpoint_command/Makefile (added)
+++ lldb/trunk/test/breakpoint_command/Makefile Tue Sep 21 16:08:53 2010
@@ -0,0 +1,5 @@
+LEVEL = ../make
+
+C_SOURCES := main.c
+
+include $(LEVEL)/Makefile.rules

Added: lldb/trunk/test/breakpoint_command/TestBreakpointCommand.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/breakpoint_command/TestBreakpointCommand.py?rev=114480&view=auto
==============================================================================
--- lldb/trunk/test/breakpoint_command/TestBreakpointCommand.py (added)
+++ lldb/trunk/test/breakpoint_command/TestBreakpointCommand.py Tue Sep 21 16:08:53 2010
@@ -0,0 +1,115 @@
+"""
+Test lldb breakpoint command add/list/remove.
+"""
+
+import os, time
+import unittest2
+import lldb
+from lldbtest import *
+
+class BreakpointCommandTestCase(TestBase):
+
+    mydir = "breakpoint_command"
+
+    @classmethod
+    def classCleanup(cls):
+        system(["/bin/sh", "-c", "rm output.txt"])
+
+    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
+    def test_with_dsym(self):
+        """Test a sequence of breakpoint command add, list, and remove."""
+        self.buildDsym()
+        self.breakpoint_command_sequence()
+
+    def test_with_dwarf(self):
+        """Test a sequence of breakpoint command add, list, and remove."""
+        self.buildDwarf()
+        self.breakpoint_command_sequence()
+
+    def breakpoint_command_sequence(self):
+        """Test a sequence of breakpoint command add, list, and remove."""
+        exe = os.path.join(os.getcwd(), "a.out")
+        self.runCmd("file " + exe, CURRENT_EXECUTABLE_SET)
+
+        # Add two breakpoints on the same line.
+        self.expect("breakpoint set -f main.c -l 12", BREAKPOINT_CREATED,
+            startstr = "Breakpoint created: 1: file ='main.c', line = 12, locations = 1")
+        self.expect("breakpoint set -f main.c -l 12", BREAKPOINT_CREATED,
+            startstr = "Breakpoint created: 2: file ='main.c', line = 12, locations = 1")
+
+        # Now add callbacks for the breakpoints just created.
+        self.runCmd("breakpoint command add -c -o 'frame variable -s' 1")
+        self.runCmd("breakpoint command add -p -o 'here = open(\"output.txt\", \"w\"); print >> here, \"lldb\"; here.close()' 2")
+
+        # Check that the breakpoint commands are correctly set.
+
+        # The breakpoint list now only contains breakpoint 1.
+        self.expect("breakpoint list", "Breakpoints 1 & 2 created",
+            substrs = ["1: file ='main.c', line = 12, locations = 1",
+                       "2: file ='main.c', line = 12, locations = 1"],
+            patterns = ["1.1: .+at main.c:12, .+unresolved, hit count = 0",
+                        "2.1: .+at main.c:12, .+unresolved, hit count = 0"])
+
+        self.expect("breakpoint command list 1", "Breakpoint 1 command ok",
+            substrs = ["Breakpoint commands:",
+                          "frame variable -s"])
+        self.expect("breakpoint command list 2", "Breakpoint 2 command ok",
+            substrs = ["Breakpoint commands:",
+                          "here = open",
+                          "print >> here",
+                          "here.close()"])
+
+        # Run the program.
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # Check that the file 'output.txt' exists and contains the string "lldb".
+
+        # Read the output file produced by running the program.
+        output = open('output.txt', 'r').read()
+
+        self.assertTrue(output.startswith("lldb"),
+                        "File 'output.txt' and the content matches")
+
+        # Finish the program.
+        self.runCmd("process continue")
+
+        # Remove the breakpoint command associated with breakpoint 1.
+        self.runCmd("breakpoint command remove 1")
+
+        # Remove breakpoint 2.
+        self.runCmd("breakpoint delete 2")
+
+        self.expect("breakpoint command list 1",
+            startstr = "Breakpoint 1 does not have an associated command.")
+        self.expect("breakpoint command list 2", error=True,
+            startstr = "error: '2' is not a currently valid breakpoint id.")
+
+        # The breakpoint list now only contains breakpoint 1.
+        self.expect("breakpoint list", "Breakpoint 1 exists",
+            substrs = ["1: file ='main.c', line = 12, locations = 1, resolved = 1",
+                       "hit count = 1"])
+
+        # Not breakpoint 2.
+        self.expect("breakpoint list", "No more breakpoint 2", matching=False,
+            substrs = ["2: file ='main.c', line = 12, locations = 1, resolved = 1"])
+
+        # Run the program again, with breakpoint 1 remaining.
+        self.runCmd("run", RUN_SUCCEEDED)
+
+        # We should be stopped again due to breakpoint 1.
+
+        # The stop reason of the thread should be breakpoint.
+        self.expect("thread list", STOPPED_DUE_TO_BREAKPOINT,
+            substrs = ['state is Stopped',
+                       'stop reason = breakpoint'])
+
+        # The breakpoint should have a hit count of 2.
+        self.expect("breakpoint list", BREAKPOINT_HIT_ONCE,
+            substrs = ['resolved, hit count = 2'])
+
+
+if __name__ == '__main__':
+    import atexit
+    lldb.SBDebugger.Initialize()
+    atexit.register(lambda: lldb.SBDebugger.Terminate())
+    unittest2.main()

Added: lldb/trunk/test/breakpoint_command/main.c
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/breakpoint_command/main.c?rev=114480&view=auto
==============================================================================
--- lldb/trunk/test/breakpoint_command/main.c (added)
+++ lldb/trunk/test/breakpoint_command/main.c Tue Sep 21 16:08:53 2010
@@ -0,0 +1,13 @@
+//===-- main.c --------------------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+int main (int argc, char const *argv[])
+{
+    return 0;
+}

Modified: lldb/trunk/test/lldbtest.py
URL: http://llvm.org/viewvc/llvm-project/lldb/trunk/test/lldbtest.py?rev=114480&r1=114479&r2=114480&view=diff
==============================================================================
--- lldb/trunk/test/lldbtest.py (original)
+++ lldb/trunk/test/lldbtest.py Tue Sep 21 16:08:53 2010
@@ -97,6 +97,7 @@
 """
 
 import os, sys
+import re
 from subprocess import *
 import time
 import types
@@ -399,19 +400,24 @@
             self.assertTrue(self.res.Succeeded(),
                             msg if msg else CMD_MSG(cmd))
 
-    def expect(self, cmd, msg=None, startstr=None, substrs=None, trace=False, error=False):
+    def expect(self, cmd, msg=None, patterns=None, startstr=None, substrs=None, trace=False, error=False, matching=True):
         """
         Similar to runCmd; with additional expect style output matching ability.
 
         Ask the command interpreter to handle the command and then check its
         return status.  The 'msg' parameter specifies an informational assert
         message.  We expect the output from running the command to start with
-        'startstr' and matches the substrings contained in 'substrs'.
+        'startstr', matches the substrings contained in 'substrs', and regexp
+        matches the patterns contained in 'patterns'.
 
         If the keyword argument error is set to True, it signifies that the API
         client is expecting the command to fail.  In this case, the error stream
         from running the command is retrieved and compared against the golden
         input, instead.
+
+        If the keyword argument matching is set to False, it signifies that the API
+        client is expecting the output of the command not to match the golden
+        input.
         """
         trace = (True if traceAlways else trace)
 
@@ -426,25 +432,50 @@
             self.assertFalse(self.res.Succeeded(),
                              "Command '" + cmd + "' is expected to fail!")
 
-        matched = output.startswith(startstr) if startstr else True
+        # The heading says either "Expecting" or "Not expecting".
+        if trace:
+            heading = "Expecting" if matching else "Not expecting"
+
+        # Start from the startstr, if specified.
+        # If there's no startstr, set the initial state appropriately.
+        matched = output.startswith(startstr) if startstr else (True if matching else False)
 
         if startstr and trace:
-            print >> sys.stderr, "Expecting start string:", startstr
+            print >> sys.stderr, "%s start string: %s" % (heading, startstr)
             print >> sys.stderr, "Matched" if matched else "Not matched"
             print >> sys.stderr
 
-        if substrs and matched:
+        # Look for sub strings, if specified.
+        keepgoing = matched if matching else not matched
+        if substrs and keepgoing:
             for str in substrs:
                 matched = output.find(str) > 0
                 if trace:
-                    print >> sys.stderr, "Expecting sub string:", str
+                    print >> sys.stderr, "%s sub string: %s" % (heading, str)
+                    print >> sys.stderr, "Matched" if matched else "Not matched"
+                keepgoing = matched if matching else not matched
+                if not keepgoing:
+                    break
+            if trace:
+                print >> sys.stderr
+
+        # Search for regular expression patterns, if specified.
+        keepgoing = matched if matching else not matched
+        if patterns and keepgoing:
+            for pattern in patterns:
+                # Match Objects always have a boolean value of True.
+                matched = bool(re.search(pattern, output))
+                if trace:
+                    print >> sys.stderr, "%s pattern: %s" % (heading, pattern)
                     print >> sys.stderr, "Matched" if matched else "Not matched"
-                if not matched:
+                keepgoing = matched if matching else not matched
+                if not keepgoing:
                     break
             if trace:
                 print >> sys.stderr
 
-        self.assertTrue(matched, msg if msg else CMD_MSG(cmd))
+        self.assertTrue(matched if matching else not matched,
+                        msg if msg else CMD_MSG(cmd))
 
     def invoke(self, obj, name, trace=False):
         """Use reflection to call a method dynamically with no argument."""





More information about the lldb-commits mailing list