1"""
2Test watchpoint condition API.
3"""
4
5import os, time
6import unittest2
7import lldb
8import lldbutil
9from lldbtest import *
10
11class WatchpointConditionAPITestCase(TestBase):
12
13    mydir = os.path.join("python_api", "watchpoint", "condition")
14
15    def setUp(self):
16        # Call super's setUp().
17        TestBase.setUp(self)
18        # Our simple source filename.
19        self.source = 'main.cpp'
20        # Find the line number to break inside main().
21        self.line = line_number(self.source, '// Set break point at this line.')
22        # And the watchpoint variable declaration line number.
23        self.decl = line_number(self.source, '// Watchpoint variable declaration.')
24        # Build dictionary to have unique executable names for each test method.
25        self.exe_name = self.testMethodName
26        self.d = {'CXX_SOURCES': self.source, 'EXE': self.exe_name}
27
28    @unittest2.skipUnless(sys.platform.startswith("darwin"), "requires Darwin")
29    @dsym_test
30    def test_watchpoint_cond_api_with_dsym(self):
31        """Test watchpoint condition API."""
32        self.buildDsym(dictionary=self.d)
33        self.setTearDownCleanup(dictionary=self.d)
34        self.watchpoint_condition_api()
35
36    @expectedFailureFreeBSD('llvm.org/pr16706') # Watchpoints fail on FreeBSD
37    @dwarf_test
38    def test_watchpoint_cond_api_with_dwarf(self):
39        """Test watchpoint condition API."""
40        self.buildDwarf(dictionary=self.d)
41        self.setTearDownCleanup(dictionary=self.d)
42        self.watchpoint_condition_api()
43
44    def watchpoint_condition_api(self):
45        """Do watchpoint condition API to set condition as 'global==5'."""
46        exe = os.path.join(os.getcwd(), self.exe_name)
47
48        # Create a target by the debugger.
49        target = self.dbg.CreateTarget(exe)
50        self.assertTrue(target, VALID_TARGET)
51
52        # Now create a breakpoint on main.c.
53        breakpoint = target.BreakpointCreateByLocation(self.source, self.line)
54        self.assertTrue(breakpoint and
55                        breakpoint.GetNumLocations() == 1,
56                        VALID_BREAKPOINT)
57
58        # Now launch the process, and do not stop at the entry point.
59        process = target.LaunchSimple(None, None, os.getcwd())
60
61        # We should be stopped due to the breakpoint.  Get frame #0.
62        process = target.GetProcess()
63        self.assertTrue(process.GetState() == lldb.eStateStopped,
64                        PROCESS_STOPPED)
65        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonBreakpoint)
66        frame0 = thread.GetFrameAtIndex(0)
67
68        # Watch 'global' for write.
69        value = frame0.FindValue('global', lldb.eValueTypeVariableGlobal)
70        error = lldb.SBError();
71        watchpoint = value.Watch(True, False, True, error)
72        self.assertTrue(value and watchpoint,
73                        "Successfully found the variable and set a watchpoint")
74        self.DebugSBValue(value)
75
76        # Now set the condition as "global==5".
77        watchpoint.SetCondition('global==5')
78        self.expect(watchpoint.GetCondition(), exe=False,
79            startstr = 'global==5')
80
81        # Hide stdout if not running with '-t' option.
82        if not self.TraceOn():
83            self.HideStdout()
84
85        print watchpoint
86
87        # Continue.  Expect the program to stop due to the variable being written to.
88        process.Continue()
89
90        if (self.TraceOn()):
91            lldbutil.print_stacktraces(process)
92
93        thread = lldbutil.get_stopped_thread(process, lldb.eStopReasonWatchpoint)
94        self.assertTrue(thread, "The thread stopped due to watchpoint")
95        self.DebugSBValue(value)
96
97        # Verify that the condition is met.
98        self.assertTrue(value.GetValueAsUnsigned() == 5)
99
100
101if __name__ == '__main__':
102    import atexit
103    lldb.SBDebugger.Initialize()
104    atexit.register(lambda: lldb.SBDebugger.Terminate())
105    unittest2.main()
106