1""" 2Test lldb-dap RestartRequest. 3""" 4 5from lldbsuite.test.decorators import * 6from lldbsuite.test.lldbtest import line_number 7import lldbdap_testcase 8 9 10class TestDAP_restart(lldbdap_testcase.DAPTestCaseBase): 11 @skipIfWindows 12 def test_basic_functionality(self): 13 """ 14 Tests the basic restarting functionality: set two breakpoints in 15 sequence, restart at the second, check that we hit the first one. 16 """ 17 line_A = line_number("main.c", "// breakpoint A") 18 line_B = line_number("main.c", "// breakpoint B") 19 20 program = self.getBuildArtifact("a.out") 21 self.build_and_launch(program) 22 [bp_A, bp_B] = self.set_source_breakpoints("main.c", [line_A, line_B]) 23 24 # Verify we hit A, then B. 25 self.dap_server.request_configurationDone() 26 self.verify_breakpoint_hit([bp_A]) 27 self.dap_server.request_continue() 28 self.verify_breakpoint_hit([bp_B]) 29 30 # Make sure i has been modified from its initial value of 0. 31 self.assertEqual( 32 int(self.dap_server.get_local_variable_value("i")), 33 1234, 34 "i != 1234 after hitting breakpoint B", 35 ) 36 37 # Restart then check we stop back at A and program state has been reset. 38 self.dap_server.request_restart() 39 self.verify_breakpoint_hit([bp_A]) 40 self.assertEqual( 41 int(self.dap_server.get_local_variable_value("i")), 42 0, 43 "i != 0 after hitting breakpoint A on restart", 44 ) 45 46 @skipIfWindows 47 def test_stopOnEntry(self): 48 """ 49 Check that the stopOnEntry setting is still honored after a restart. 50 """ 51 program = self.getBuildArtifact("a.out") 52 self.build_and_launch(program, stopOnEntry=True) 53 [bp_main] = self.set_function_breakpoints(["main"]) 54 self.dap_server.request_configurationDone() 55 56 # Once the "configuration done" event is sent, we should get a stopped 57 # event immediately because of stopOnEntry. 58 stopped_events = self.dap_server.wait_for_stopped() 59 for stopped_event in stopped_events: 60 if "body" in stopped_event: 61 body = stopped_event["body"] 62 if "reason" in body: 63 reason = body["reason"] 64 self.assertNotEqual( 65 reason, "breakpoint", 'verify stop isn\'t "main" breakpoint' 66 ) 67 68 # Then, if we continue, we should hit the breakpoint at main. 69 self.dap_server.request_continue() 70 self.verify_breakpoint_hit([bp_main]) 71 72 # Restart and check that we still get a stopped event before reaching 73 # main. 74 self.dap_server.request_restart() 75 stopped_events = self.dap_server.wait_for_stopped() 76 for stopped_event in stopped_events: 77 if "body" in stopped_event: 78 body = stopped_event["body"] 79 if "reason" in body: 80 reason = body["reason"] 81 self.assertNotEqual( 82 reason, 83 "breakpoint", 84 'verify stop after restart isn\'t "main" breakpoint', 85 ) 86 87 @skipIfWindows 88 def test_arguments(self): 89 """ 90 Tests that lldb-dap will use updated launch arguments included 91 with a restart request. 92 """ 93 line_A = line_number("main.c", "// breakpoint A") 94 95 program = self.getBuildArtifact("a.out") 96 self.build_and_launch(program) 97 [bp_A] = self.set_source_breakpoints("main.c", [line_A]) 98 99 # Verify we hit A, then B. 100 self.dap_server.request_configurationDone() 101 self.verify_breakpoint_hit([bp_A]) 102 103 # We don't set any arguments in the initial launch request, so argc 104 # should be 1. 105 self.assertEqual( 106 int(self.dap_server.get_local_variable_value("argc")), 107 1, 108 "argc != 1 before restart", 109 ) 110 111 # Restart with some extra 'args' and check that the new argc reflects 112 # the updated launch config. 113 self.dap_server.request_restart( 114 restartArguments={ 115 "arguments": { 116 "program": program, 117 "args": ["a", "b", "c", "d"], 118 } 119 } 120 ) 121 self.verify_breakpoint_hit([bp_A]) 122 self.assertEqual( 123 int(self.dap_server.get_local_variable_value("argc")), 124 5, 125 "argc != 5 after restart", 126 ) 127