101263c6cSJonas Devlieghere""" 201263c6cSJonas DevlieghereTest lldb-dap setBreakpoints request 301263c6cSJonas Devlieghere""" 401263c6cSJonas Devlieghere 501263c6cSJonas Devlieghere 601263c6cSJonas Devlieghereimport dap_server 701263c6cSJonas Devliegherefrom lldbsuite.test.decorators import * 801263c6cSJonas Devliegherefrom lldbsuite.test.lldbtest import * 901263c6cSJonas Devliegherefrom lldbsuite.test import lldbutil 1001263c6cSJonas Devlieghereimport lldbdap_testcase 1101263c6cSJonas Devlieghere 1201263c6cSJonas Devlieghere 1301263c6cSJonas Devlieghereclass TestDAP_setFunctionBreakpoints(lldbdap_testcase.DAPTestCaseBase): 1401263c6cSJonas Devlieghere @skipIfWindows 1501263c6cSJonas Devlieghere def test_set_and_clear(self): 1601263c6cSJonas Devlieghere """Tests setting and clearing function breakpoints. 1701263c6cSJonas Devlieghere This packet is a bit tricky on the debug adaptor side since there 1801263c6cSJonas Devlieghere is no "clearFunction Breakpoints" packet. Function breakpoints 1901263c6cSJonas Devlieghere are set by sending a "setFunctionBreakpoints" packet with zero or 2001263c6cSJonas Devlieghere more function names. If function breakpoints have been set before, 2101263c6cSJonas Devlieghere any existing breakpoints must remain set, and any new breakpoints 2201263c6cSJonas Devlieghere must be created, and any breakpoints that were in previous requests 2301263c6cSJonas Devlieghere and are not in the current request must be removed. This function 2401263c6cSJonas Devlieghere tests this setting and clearing and makes sure things happen 2501263c6cSJonas Devlieghere correctly. It doesn't test hitting breakpoints and the functionality 2601263c6cSJonas Devlieghere of each breakpoint, like 'conditions' and 'hitCondition' settings. 2701263c6cSJonas Devlieghere """ 2801263c6cSJonas Devlieghere # Visual Studio Code Debug Adaptors have no way to specify the file 2901263c6cSJonas Devlieghere # without launching or attaching to a process, so we must start a 3001263c6cSJonas Devlieghere # process in order to be able to set breakpoints. 3101263c6cSJonas Devlieghere program = self.getBuildArtifact("a.out") 3201263c6cSJonas Devlieghere self.build_and_launch(program) 3301263c6cSJonas Devlieghere bp_id_12 = None 3401263c6cSJonas Devlieghere functions = ["twelve"] 3501263c6cSJonas Devlieghere # Set a function breakpoint at 'twelve' 3601263c6cSJonas Devlieghere response = self.dap_server.request_setFunctionBreakpoints(functions) 3701263c6cSJonas Devlieghere if response: 3801263c6cSJonas Devlieghere breakpoints = response["body"]["breakpoints"] 39*80fcecb1SJonas Devlieghere self.assertEqual( 4001263c6cSJonas Devlieghere len(breakpoints), 4101263c6cSJonas Devlieghere len(functions), 4201263c6cSJonas Devlieghere "expect %u source breakpoints" % (len(functions)), 4301263c6cSJonas Devlieghere ) 4401263c6cSJonas Devlieghere for breakpoint in breakpoints: 4501263c6cSJonas Devlieghere bp_id_12 = breakpoint["id"] 4601263c6cSJonas Devlieghere self.assertTrue(breakpoint["verified"], "expect breakpoint verified") 4701263c6cSJonas Devlieghere 4801263c6cSJonas Devlieghere # Add an extra name and make sure we have two breakpoints after this 4901263c6cSJonas Devlieghere functions.append("thirteen") 5001263c6cSJonas Devlieghere response = self.dap_server.request_setFunctionBreakpoints(functions) 5101263c6cSJonas Devlieghere if response: 5201263c6cSJonas Devlieghere breakpoints = response["body"]["breakpoints"] 53*80fcecb1SJonas Devlieghere self.assertEqual( 5401263c6cSJonas Devlieghere len(breakpoints), 5501263c6cSJonas Devlieghere len(functions), 5601263c6cSJonas Devlieghere "expect %u source breakpoints" % (len(functions)), 5701263c6cSJonas Devlieghere ) 5801263c6cSJonas Devlieghere for breakpoint in breakpoints: 5901263c6cSJonas Devlieghere self.assertTrue(breakpoint["verified"], "expect breakpoint verified") 6001263c6cSJonas Devlieghere 6101263c6cSJonas Devlieghere # There is no breakpoint delete packet, clients just send another 6201263c6cSJonas Devlieghere # setFunctionBreakpoints packet with the different function names. 6301263c6cSJonas Devlieghere functions.remove("thirteen") 6401263c6cSJonas Devlieghere response = self.dap_server.request_setFunctionBreakpoints(functions) 6501263c6cSJonas Devlieghere if response: 6601263c6cSJonas Devlieghere breakpoints = response["body"]["breakpoints"] 67*80fcecb1SJonas Devlieghere self.assertEqual( 6801263c6cSJonas Devlieghere len(breakpoints), 6901263c6cSJonas Devlieghere len(functions), 7001263c6cSJonas Devlieghere "expect %u source breakpoints" % (len(functions)), 7101263c6cSJonas Devlieghere ) 7201263c6cSJonas Devlieghere for breakpoint in breakpoints: 7301263c6cSJonas Devlieghere bp_id = breakpoint["id"] 74*80fcecb1SJonas Devlieghere self.assertEqual( 7501263c6cSJonas Devlieghere bp_id, bp_id_12, 'verify "twelve" breakpoint ID is same' 7601263c6cSJonas Devlieghere ) 7701263c6cSJonas Devlieghere self.assertTrue( 7801263c6cSJonas Devlieghere breakpoint["verified"], "expect breakpoint still verified" 7901263c6cSJonas Devlieghere ) 8001263c6cSJonas Devlieghere 8101263c6cSJonas Devlieghere # Now get the full list of breakpoints set in the target and verify 8201263c6cSJonas Devlieghere # we have only 1 breakpoints set. The response above could have told 8301263c6cSJonas Devlieghere # us about 1 breakpoints, but we want to make sure we don't have the 8401263c6cSJonas Devlieghere # second one still set in the target 8501263c6cSJonas Devlieghere response = self.dap_server.request_testGetTargetBreakpoints() 8601263c6cSJonas Devlieghere if response: 8701263c6cSJonas Devlieghere breakpoints = response["body"]["breakpoints"] 88*80fcecb1SJonas Devlieghere self.assertEqual( 8901263c6cSJonas Devlieghere len(breakpoints), 9001263c6cSJonas Devlieghere len(functions), 9101263c6cSJonas Devlieghere "expect %u source breakpoints" % (len(functions)), 9201263c6cSJonas Devlieghere ) 9301263c6cSJonas Devlieghere for breakpoint in breakpoints: 9401263c6cSJonas Devlieghere bp_id = breakpoint["id"] 95*80fcecb1SJonas Devlieghere self.assertEqual( 9601263c6cSJonas Devlieghere bp_id, bp_id_12, 'verify "twelve" breakpoint ID is same' 9701263c6cSJonas Devlieghere ) 9801263c6cSJonas Devlieghere self.assertTrue( 9901263c6cSJonas Devlieghere breakpoint["verified"], "expect breakpoint still verified" 10001263c6cSJonas Devlieghere ) 10101263c6cSJonas Devlieghere 10201263c6cSJonas Devlieghere # Now clear all breakpoints for the source file by passing down an 10301263c6cSJonas Devlieghere # empty lines array 10401263c6cSJonas Devlieghere functions = [] 10501263c6cSJonas Devlieghere response = self.dap_server.request_setFunctionBreakpoints(functions) 10601263c6cSJonas Devlieghere if response: 10701263c6cSJonas Devlieghere breakpoints = response["body"]["breakpoints"] 108*80fcecb1SJonas Devlieghere self.assertEqual( 10901263c6cSJonas Devlieghere len(breakpoints), 11001263c6cSJonas Devlieghere len(functions), 11101263c6cSJonas Devlieghere "expect %u source breakpoints" % (len(functions)), 11201263c6cSJonas Devlieghere ) 11301263c6cSJonas Devlieghere 11401263c6cSJonas Devlieghere # Verify with the target that all breakpoints have been cleared 11501263c6cSJonas Devlieghere response = self.dap_server.request_testGetTargetBreakpoints() 11601263c6cSJonas Devlieghere if response: 11701263c6cSJonas Devlieghere breakpoints = response["body"]["breakpoints"] 118*80fcecb1SJonas Devlieghere self.assertEqual( 11901263c6cSJonas Devlieghere len(breakpoints), 12001263c6cSJonas Devlieghere len(functions), 12101263c6cSJonas Devlieghere "expect %u source breakpoints" % (len(functions)), 12201263c6cSJonas Devlieghere ) 12301263c6cSJonas Devlieghere 12401263c6cSJonas Devlieghere @skipIfWindows 12501263c6cSJonas Devlieghere def test_functionality(self): 12601263c6cSJonas Devlieghere """Tests hitting breakpoints and the functionality of a single 12701263c6cSJonas Devlieghere breakpoint, like 'conditions' and 'hitCondition' settings.""" 12801263c6cSJonas Devlieghere 12901263c6cSJonas Devlieghere program = self.getBuildArtifact("a.out") 13001263c6cSJonas Devlieghere self.build_and_launch(program) 13101263c6cSJonas Devlieghere # Set a breakpoint on "twelve" with no condition and no hitCondition 13201263c6cSJonas Devlieghere functions = ["twelve"] 13301263c6cSJonas Devlieghere breakpoint_ids = self.set_function_breakpoints(functions) 13401263c6cSJonas Devlieghere 135*80fcecb1SJonas Devlieghere self.assertEqual(len(breakpoint_ids), len(functions), "expect one breakpoint") 13601263c6cSJonas Devlieghere 13701263c6cSJonas Devlieghere # Verify we hit the breakpoint we just set 13801263c6cSJonas Devlieghere self.continue_to_breakpoints(breakpoint_ids) 13901263c6cSJonas Devlieghere 14001263c6cSJonas Devlieghere # Make sure i is zero at first breakpoint 14101263c6cSJonas Devlieghere i = int(self.dap_server.get_local_variable_value("i")) 142*80fcecb1SJonas Devlieghere self.assertEqual(i, 0, "i != 0 after hitting breakpoint") 14301263c6cSJonas Devlieghere 14401263c6cSJonas Devlieghere # Update the condition on our breakpoint 14501263c6cSJonas Devlieghere new_breakpoint_ids = self.set_function_breakpoints(functions, condition="i==4") 146*80fcecb1SJonas Devlieghere self.assertEqual( 14701263c6cSJonas Devlieghere breakpoint_ids, 14801263c6cSJonas Devlieghere new_breakpoint_ids, 14901263c6cSJonas Devlieghere "existing breakpoint should have its condition " "updated", 15001263c6cSJonas Devlieghere ) 15101263c6cSJonas Devlieghere 15201263c6cSJonas Devlieghere self.continue_to_breakpoints(breakpoint_ids) 15301263c6cSJonas Devlieghere i = int(self.dap_server.get_local_variable_value("i")) 154*80fcecb1SJonas Devlieghere self.assertEqual(i, 4, "i != 4 showing conditional works") 15501263c6cSJonas Devlieghere new_breakpoint_ids = self.set_function_breakpoints(functions, hitCondition="2") 15601263c6cSJonas Devlieghere 157*80fcecb1SJonas Devlieghere self.assertEqual( 15801263c6cSJonas Devlieghere breakpoint_ids, 15901263c6cSJonas Devlieghere new_breakpoint_ids, 16001263c6cSJonas Devlieghere "existing breakpoint should have its condition " "updated", 16101263c6cSJonas Devlieghere ) 16201263c6cSJonas Devlieghere 16301263c6cSJonas Devlieghere # Continue with a hitCondition of 2 and expect it to skip 1 value 16401263c6cSJonas Devlieghere self.continue_to_breakpoints(breakpoint_ids) 16501263c6cSJonas Devlieghere i = int(self.dap_server.get_local_variable_value("i")) 166*80fcecb1SJonas Devlieghere self.assertEqual(i, 6, "i != 6 showing hitCondition works") 16701263c6cSJonas Devlieghere 16801263c6cSJonas Devlieghere # continue after hitting our hitCondition and make sure it only goes 16901263c6cSJonas Devlieghere # up by 1 17001263c6cSJonas Devlieghere self.continue_to_breakpoints(breakpoint_ids) 17101263c6cSJonas Devlieghere i = int(self.dap_server.get_local_variable_value("i")) 172*80fcecb1SJonas Devlieghere self.assertEqual(i, 7, "i != 7 showing post hitCondition hits every time") 173