199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest lldb-vscode setBreakpoints request
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprecht
699451b44SJordan Rupprechtimport unittest2
799451b44SJordan Rupprechtimport vscode
899451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
999451b44SJordan Rupprechtfrom lldbsuite.test.lldbtest import *
1099451b44SJordan Rupprechtfrom lldbsuite.test import lldbutil
1199451b44SJordan Rupprechtimport lldbvscode_testcase
1299451b44SJordan Rupprecht
1399451b44SJordan Rupprecht
1499451b44SJordan Rupprechtclass TestVSCode_setFunctionBreakpoints(
1599451b44SJordan Rupprecht        lldbvscode_testcase.VSCodeTestCaseBase):
1699451b44SJordan Rupprecht
1799451b44SJordan Rupprecht    @skipIfWindows
1814fb3179SJonas Devlieghere    @skipIfRemote
1999451b44SJordan Rupprecht    def test_set_and_clear(self):
2099451b44SJordan Rupprecht        '''Tests setting and clearing function breakpoints.
2199451b44SJordan Rupprecht           This packet is a bit tricky on the debug adaptor side since there
2299451b44SJordan Rupprecht           is no "clearFunction Breakpoints" packet. Function breakpoints
2399451b44SJordan Rupprecht           are set by sending a "setFunctionBreakpoints" packet with zero or
2499451b44SJordan Rupprecht           more function names. If function breakpoints have been set before,
25*e9264b74SKazuaki Ishizaki           any existing breakpoints must remain set, and any new breakpoints
2699451b44SJordan Rupprecht           must be created, and any breakpoints that were in previous requests
2799451b44SJordan Rupprecht           and are not in the current request must be removed. This function
2899451b44SJordan Rupprecht           tests this setting and clearing and makes sure things happen
2999451b44SJordan Rupprecht           correctly. It doesn't test hitting breakpoints and the functionality
3099451b44SJordan Rupprecht           of each breakpoint, like 'conditions' and 'hitCondition' settings.
3199451b44SJordan Rupprecht        '''
3299451b44SJordan Rupprecht        # Visual Studio Code Debug Adaptors have no way to specify the file
3399451b44SJordan Rupprecht        # without launching or attaching to a process, so we must start a
3499451b44SJordan Rupprecht        # process in order to be able to set breakpoints.
3599451b44SJordan Rupprecht        program = self.getBuildArtifact("a.out")
3699451b44SJordan Rupprecht        self.build_and_launch(program)
3799451b44SJordan Rupprecht        bp_id_12 = None
3899451b44SJordan Rupprecht        functions = ['twelve']
3999451b44SJordan Rupprecht        # Set a function breakpoint at 'twelve'
4099451b44SJordan Rupprecht        response = self.vscode.request_setFunctionBreakpoints(functions)
4199451b44SJordan Rupprecht        if response:
4299451b44SJordan Rupprecht            breakpoints = response['body']['breakpoints']
43b3a0c4d7SRaphael Isemann            self.assertEquals(len(breakpoints), len(functions),
4499451b44SJordan Rupprecht                            "expect %u source breakpoints" % (len(functions)))
4599451b44SJordan Rupprecht            for breakpoint in breakpoints:
4699451b44SJordan Rupprecht                bp_id_12 = breakpoint['id']
4799451b44SJordan Rupprecht                self.assertTrue(breakpoint['verified'],
4899451b44SJordan Rupprecht                                "expect breakpoint verified")
4999451b44SJordan Rupprecht
5099451b44SJordan Rupprecht        # Add an extra name and make sure we have two breakpoints after this
5199451b44SJordan Rupprecht        functions.append('thirteen')
5299451b44SJordan Rupprecht        response = self.vscode.request_setFunctionBreakpoints(functions)
5399451b44SJordan Rupprecht        if response:
5499451b44SJordan Rupprecht            breakpoints = response['body']['breakpoints']
55b3a0c4d7SRaphael Isemann            self.assertEquals(len(breakpoints), len(functions),
5699451b44SJordan Rupprecht                            "expect %u source breakpoints" % (len(functions)))
5799451b44SJordan Rupprecht            for breakpoint in breakpoints:
5899451b44SJordan Rupprecht                self.assertTrue(breakpoint['verified'],
5999451b44SJordan Rupprecht                                "expect breakpoint verified")
6099451b44SJordan Rupprecht
6199451b44SJordan Rupprecht        # There is no breakpoint delete packet, clients just send another
6299451b44SJordan Rupprecht        # setFunctionBreakpoints packet with the different function names.
6399451b44SJordan Rupprecht        functions.remove('thirteen')
6499451b44SJordan Rupprecht        response = self.vscode.request_setFunctionBreakpoints(functions)
6599451b44SJordan Rupprecht        if response:
6699451b44SJordan Rupprecht            breakpoints = response['body']['breakpoints']
67b3a0c4d7SRaphael Isemann            self.assertEquals(len(breakpoints), len(functions),
6899451b44SJordan Rupprecht                            "expect %u source breakpoints" % (len(functions)))
6999451b44SJordan Rupprecht            for breakpoint in breakpoints:
7099451b44SJordan Rupprecht                bp_id = breakpoint['id']
71b3a0c4d7SRaphael Isemann                self.assertEquals(bp_id, bp_id_12,
7299451b44SJordan Rupprecht                                'verify "twelve" breakpoint ID is same')
7399451b44SJordan Rupprecht                self.assertTrue(breakpoint['verified'],
7499451b44SJordan Rupprecht                                "expect breakpoint still verified")
7599451b44SJordan Rupprecht
7699451b44SJordan Rupprecht        # Now get the full list of breakpoints set in the target and verify
7799451b44SJordan Rupprecht        # we have only 1 breakpoints set. The response above could have told
7899451b44SJordan Rupprecht        # us about 1 breakpoints, but we want to make sure we don't have the
7999451b44SJordan Rupprecht        # second one still set in the target
8099451b44SJordan Rupprecht        response = self.vscode.request_testGetTargetBreakpoints()
8199451b44SJordan Rupprecht        if response:
8299451b44SJordan Rupprecht            breakpoints = response['body']['breakpoints']
83b3a0c4d7SRaphael Isemann            self.assertEquals(len(breakpoints), len(functions),
8499451b44SJordan Rupprecht                            "expect %u source breakpoints" % (len(functions)))
8599451b44SJordan Rupprecht            for breakpoint in breakpoints:
8699451b44SJordan Rupprecht                bp_id = breakpoint['id']
87b3a0c4d7SRaphael Isemann                self.assertEquals(bp_id, bp_id_12,
8899451b44SJordan Rupprecht                                'verify "twelve" breakpoint ID is same')
8999451b44SJordan Rupprecht                self.assertTrue(breakpoint['verified'],
9099451b44SJordan Rupprecht                                "expect breakpoint still verified")
9199451b44SJordan Rupprecht
9299451b44SJordan Rupprecht        # Now clear all breakpoints for the source file by passing down an
9399451b44SJordan Rupprecht        # empty lines array
9499451b44SJordan Rupprecht        functions = []
9599451b44SJordan Rupprecht        response = self.vscode.request_setFunctionBreakpoints(functions)
9699451b44SJordan Rupprecht        if response:
9799451b44SJordan Rupprecht            breakpoints = response['body']['breakpoints']
98b3a0c4d7SRaphael Isemann            self.assertEquals(len(breakpoints), len(functions),
9999451b44SJordan Rupprecht                            "expect %u source breakpoints" % (len(functions)))
10099451b44SJordan Rupprecht
10199451b44SJordan Rupprecht        # Verify with the target that all breakpoints have been cleared
10299451b44SJordan Rupprecht        response = self.vscode.request_testGetTargetBreakpoints()
10399451b44SJordan Rupprecht        if response:
10499451b44SJordan Rupprecht            breakpoints = response['body']['breakpoints']
105b3a0c4d7SRaphael Isemann            self.assertEquals(len(breakpoints), len(functions),
10699451b44SJordan Rupprecht                            "expect %u source breakpoints" % (len(functions)))
10799451b44SJordan Rupprecht
10899451b44SJordan Rupprecht    @skipIfWindows
10914fb3179SJonas Devlieghere    @skipIfRemote
11099451b44SJordan Rupprecht    def test_functionality(self):
11199451b44SJordan Rupprecht        '''Tests hitting breakpoints and the functionality of a single
11299451b44SJordan Rupprecht           breakpoint, like 'conditions' and 'hitCondition' settings.'''
11399451b44SJordan Rupprecht
11499451b44SJordan Rupprecht        program = self.getBuildArtifact("a.out")
11599451b44SJordan Rupprecht        self.build_and_launch(program)
11699451b44SJordan Rupprecht        # Set a breakpoint on "twelve" with no condition and no hitCondition
11799451b44SJordan Rupprecht        functions = ['twelve']
11899451b44SJordan Rupprecht        breakpoint_ids = self.set_function_breakpoints(functions)
11999451b44SJordan Rupprecht
120b3a0c4d7SRaphael Isemann        self.assertEquals(len(breakpoint_ids), len(functions),
12199451b44SJordan Rupprecht                        "expect one breakpoint")
12299451b44SJordan Rupprecht
12399451b44SJordan Rupprecht        # Verify we hit the breakpoint we just set
12499451b44SJordan Rupprecht        self.continue_to_breakpoints(breakpoint_ids)
12599451b44SJordan Rupprecht
12699451b44SJordan Rupprecht        # Make sure i is zero at first breakpoint
12799451b44SJordan Rupprecht        i = int(self.vscode.get_local_variable_value('i'))
128b3a0c4d7SRaphael Isemann        self.assertEquals(i, 0, 'i != 0 after hitting breakpoint')
12999451b44SJordan Rupprecht
13099451b44SJordan Rupprecht        # Update the condition on our breakpoint
13199451b44SJordan Rupprecht        new_breakpoint_ids = self.set_function_breakpoints(functions,
13299451b44SJordan Rupprecht                                                           condition="i==4")
133b3a0c4d7SRaphael Isemann        self.assertEquals(breakpoint_ids, new_breakpoint_ids,
13499451b44SJordan Rupprecht                        "existing breakpoint should have its condition "
13599451b44SJordan Rupprecht                        "updated")
13699451b44SJordan Rupprecht
13799451b44SJordan Rupprecht        self.continue_to_breakpoints(breakpoint_ids)
13899451b44SJordan Rupprecht        i = int(self.vscode.get_local_variable_value('i'))
139b3a0c4d7SRaphael Isemann        self.assertEquals(i, 4,
14099451b44SJordan Rupprecht                        'i != 4 showing conditional works')
14199451b44SJordan Rupprecht        new_breakpoint_ids = self.set_function_breakpoints(functions,
14299451b44SJordan Rupprecht                                                           hitCondition="2")
14399451b44SJordan Rupprecht
144b3a0c4d7SRaphael Isemann        self.assertEquals(breakpoint_ids, new_breakpoint_ids,
14599451b44SJordan Rupprecht                        "existing breakpoint should have its condition "
14699451b44SJordan Rupprecht                        "updated")
14799451b44SJordan Rupprecht
148*e9264b74SKazuaki Ishizaki        # Continue with a hitCondition of 2 and expect it to skip 1 value
14999451b44SJordan Rupprecht        self.continue_to_breakpoints(breakpoint_ids)
15099451b44SJordan Rupprecht        i = int(self.vscode.get_local_variable_value('i'))
151b3a0c4d7SRaphael Isemann        self.assertEquals(i, 6,
15299451b44SJordan Rupprecht                        'i != 6 showing hitCondition works')
15399451b44SJordan Rupprecht
15499451b44SJordan Rupprecht        # continue after hitting our hitCondition and make sure it only goes
15599451b44SJordan Rupprecht        # up by 1
15699451b44SJordan Rupprecht        self.continue_to_breakpoints(breakpoint_ids)
15799451b44SJordan Rupprecht        i = int(self.vscode.get_local_variable_value('i'))
158b3a0c4d7SRaphael Isemann        self.assertEquals(i, 7,
15999451b44SJordan Rupprecht                        'i != 7 showing post hitCondition hits every time')
160