Home | History | Annotate | Download | only in objc-checker
      1 """
      2 Use lldb Python API to make sure the dynamic checkers are doing their jobs.
      3 """
      4 
      5 import os, time
      6 import re
      7 import unittest2
      8 import lldb, lldbutil
      9 from lldbtest import *
     10 
     11 class ObjCCheckerTestCase(TestBase):
     12 
     13     mydir = os.path.join("lang", "objc", "objc-checker")
     14 
     15     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     16     @python_api_test
     17     @dsym_test
     18     def test_objc_checker_with_dsym(self):
     19         """Test that checkers catch unrecognized selectors"""
     20         if self.getArchitecture() == 'i386':
     21             self.skipTest("requires Objective-C 2.0 runtime")
     22         self.buildDsym()
     23         self.do_test_checkers()
     24 
     25     @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
     26     @python_api_test
     27     @dwarf_test
     28     def test_objc_checker_with_dwarf(self):
     29         """Test that checkers catch unrecognized selectors"""
     30         if self.getArchitecture() == 'i386':
     31             self.skipTest("requires Objective-C 2.0 runtime")
     32         self.buildDwarf()
     33         self.do_test_checkers()
     34 
     35     def setUp(self):
     36         # Call super's setUp().                                                                                                           
     37         TestBase.setUp(self)
     38 
     39         # Find the line number to break for main.c.                                                                                       
     40 
     41         self.source_name = 'main.m'
     42 
     43     def do_test_checkers (self):
     44         """Make sure the dynamic checkers catch messages to unrecognized selectors"""
     45         exe = os.path.join(os.getcwd(), "a.out")
     46 
     47         # Create a target from the debugger.
     48 
     49         target = self.dbg.CreateTarget (exe)
     50         self.assertTrue(target, VALID_TARGET)
     51 
     52         # Set up our breakpoints:
     53 
     54         
     55         main_bkpt = target.BreakpointCreateBySourceRegex ("Set a breakpoint here.", lldb.SBFileSpec (self.source_name))
     56         self.assertTrue(main_bkpt and
     57                         main_bkpt.GetNumLocations() == 1,
     58                         VALID_BREAKPOINT)
     59 
     60         # Now launch the process, and do not stop at the entry point.
     61         process = target.LaunchSimple (None, None, os.getcwd())
     62 
     63         self.assertTrue(process.GetState() == lldb.eStateStopped,
     64                         PROCESS_STOPPED)
     65 
     66         threads = lldbutil.get_threads_stopped_at_breakpoint (process, main_bkpt)
     67         self.assertTrue (len(threads) == 1)
     68         thread = threads[0]
     69 
     70         #
     71         #  The class Simple doesn't have a count method.  Make sure that we don't 
     72         #  actually try to send count but catch it as an unrecognized selector.
     73 
     74         frame = thread.GetFrameAtIndex(0)
     75         expr_value = frame.EvaluateExpression("(int) [my_simple count]", False)
     76         expr_error = expr_value.GetError()
     77 
     78         self.assertTrue (expr_error.Fail())
     79         
     80         # Make sure the call produced no NSLog stdout.
     81         stdout = process.GetSTDOUT(100)
     82         self.assertTrue (len(stdout) == 0)
     83         
     84         # Make sure the error is helpful:
     85         err_string = expr_error.GetCString()
     86         self.assertTrue ("selector" in err_string)
     87 
     88 if __name__ == '__main__':
     89     import atexit
     90     lldb.SBDebugger.Initialize()
     91     atexit.register(lambda: lldb.SBDebugger.Terminate())
     92     unittest2.main()
     93