1"""
2Use lldb Python API to make sure the dynamic checkers are doing their jobs.
3"""
4
5import os, time
6import re
7import unittest2
8import lldb, lldbutil
9from lldbtest import *
10
11class 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
88if __name__ == '__main__':
89    import atexit
90    lldb.SBDebugger.Initialize()
91    atexit.register(lambda: lldb.SBDebugger.Terminate())
92    unittest2.main()
93