225 lines · python
1"""2Test lldb-dap runInTerminal reverse request3"""4 5from lldbsuite.test.decorators import *6from lldbsuite.test.lldbtest import line_number7import lldbdap_testcase8import os9import subprocess10import json11 12 13@skipIfBuildType(["debug"])14class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):15 def read_pid_message(self, fifo_file):16 with open(fifo_file, "r") as file:17 self.assertIn("pid", file.readline())18 19 @staticmethod20 def send_did_attach_message(fifo_file):21 with open(fifo_file, "w") as file:22 file.write(json.dumps({"kind": "didAttach"}) + "\n")23 24 @staticmethod25 def read_error_message(fifo_file):26 with open(fifo_file, "r") as file:27 return file.readline()28 29 @skipIfAsan30 @skipIfWindows31 @skipIf(oslist=["linux"], archs=no_match(["x86_64"]))32 def test_runInTerminal(self):33 """34 Tests the "runInTerminal" reverse request. It makes sure that the IDE can35 launch the inferior with the correct environment variables and arguments.36 """37 program = self.getBuildArtifact("a.out")38 source = "main.c"39 self.build_and_launch(40 program, console="integratedTerminal", args=["foobar"], env=["FOO=bar"]41 )42 43 self.assertEqual(44 len(self.dap_server.reverse_requests),45 1,46 "make sure we got a reverse request",47 )48 49 request = self.dap_server.reverse_requests[0]50 self.assertIn(self.lldbDAPExec, request["arguments"]["args"])51 self.assertIn(program, request["arguments"]["args"])52 self.assertIn("foobar", request["arguments"]["args"])53 self.assertIn("FOO", request["arguments"]["env"])54 55 breakpoint_line = line_number(source, "// breakpoint")56 57 self.set_source_breakpoints(source, [breakpoint_line])58 self.continue_to_next_stop()59 60 # We verify we actually stopped inside the loop61 counter = int(self.dap_server.get_local_variable_value("counter"))62 self.assertEqual(counter, 1)63 64 # We verify we were able to set the launch arguments65 argc = int(self.dap_server.get_local_variable_value("argc"))66 self.assertEqual(argc, 2)67 68 argv1 = self.dap_server.request_evaluate("argv[1]")["body"]["result"]69 self.assertIn("foobar", argv1)70 71 # We verify we were able to set the environment72 env = self.dap_server.request_evaluate("foo")["body"]["result"]73 self.assertIn("bar", env)74 75 self.continue_to_exit()76 77 @skipIfAsan78 @skipIfWindows79 @skipIf(oslist=["linux"], archs=no_match(["x86_64"]))80 def test_runInTerminalWithObjectEnv(self):81 """82 Tests the "runInTerminal" reverse request. It makes sure that the IDE can83 launch the inferior with the correct environment variables using an object.84 """85 program = self.getBuildArtifact("a.out")86 self.build_and_launch(program, console="integratedTerminal", env={"FOO": "BAR"})87 88 self.assertEqual(89 len(self.dap_server.reverse_requests),90 1,91 "make sure we got a reverse request",92 )93 94 request = self.dap_server.reverse_requests[0]95 request_envs = request["arguments"]["env"]96 97 self.assertIn("FOO", request_envs)98 self.assertEqual("BAR", request_envs["FOO"])99 100 self.continue_to_exit()101 102 @skipIfWindows103 @skipIf(oslist=["linux"], archs=no_match(["x86_64"]))104 def test_runInTerminalInvalidTarget(self):105 self.build_and_create_debug_adapter()106 response = self.launch(107 "INVALIDPROGRAM",108 console="integratedTerminal",109 args=["foobar"],110 env=["FOO=bar"],111 expectFailure=True,112 )113 self.assertFalse(response["success"])114 self.assertIn(115 "'INVALIDPROGRAM' does not exist",116 response["body"]["error"]["format"],117 )118 119 @skipIfWindows120 @skipIf(oslist=["linux"], archs=no_match(["x86_64"]))121 def test_missingArgInRunInTerminalLauncher(self):122 proc = subprocess.run(123 [self.lldbDAPExec, "--launch-target", "INVALIDPROGRAM"],124 capture_output=True,125 universal_newlines=True,126 )127 self.assertNotEqual(proc.returncode, 0)128 self.assertIn(129 '"--launch-target" requires "--comm-file" to be specified', proc.stderr130 )131 132 @skipIfWindows133 @skipIf(oslist=["linux"], archs=no_match(["x86_64"]))134 def test_FakeAttachedRunInTerminalLauncherWithInvalidProgram(self):135 comm_file = os.path.join(self.getBuildDir(), "comm-file")136 os.mkfifo(comm_file)137 138 proc = subprocess.Popen(139 [140 self.lldbDAPExec,141 "--comm-file",142 comm_file,143 "--launch-target",144 "INVALIDPROGRAM",145 ],146 universal_newlines=True,147 stderr=subprocess.PIPE,148 )149 150 self.read_pid_message(comm_file)151 self.send_did_attach_message(comm_file)152 self.assertIn("No such file or directory", self.read_error_message(comm_file))153 154 _, stderr = proc.communicate()155 self.assertIn("No such file or directory", stderr)156 157 @skipIfWindows158 @skipIf(oslist=["linux"], archs=no_match(["x86_64"]))159 def test_FakeAttachedRunInTerminalLauncherWithValidProgram(self):160 comm_file = os.path.join(self.getBuildDir(), "comm-file")161 os.mkfifo(comm_file)162 163 proc = subprocess.Popen(164 [165 self.lldbDAPExec,166 "--comm-file",167 comm_file,168 "--launch-target",169 "echo",170 "foo",171 ],172 universal_newlines=True,173 stdout=subprocess.PIPE,174 )175 176 self.read_pid_message(comm_file)177 self.send_did_attach_message(comm_file)178 179 stdout, _ = proc.communicate()180 self.assertIn("foo", stdout)181 182 @skipIfWindows183 @skipIf(oslist=["linux"], archs=no_match(["x86_64"]))184 def test_FakeAttachedRunInTerminalLauncherAndCheckEnvironment(self):185 comm_file = os.path.join(self.getBuildDir(), "comm-file")186 os.mkfifo(comm_file)187 188 proc = subprocess.Popen(189 [self.lldbDAPExec, "--comm-file", comm_file, "--launch-target", "env"],190 universal_newlines=True,191 stdout=subprocess.PIPE,192 env={**os.environ, "FOO": "BAR"},193 )194 195 self.read_pid_message(comm_file)196 self.send_did_attach_message(comm_file)197 198 stdout, _ = proc.communicate()199 self.assertIn("FOO=BAR", stdout)200 201 @skipIfWindows202 @skipIf(oslist=["linux"], archs=no_match(["x86_64"]))203 def test_NonAttachedRunInTerminalLauncher(self):204 comm_file = os.path.join(self.getBuildDir(), "comm-file")205 os.mkfifo(comm_file)206 207 proc = subprocess.Popen(208 [209 self.lldbDAPExec,210 "--comm-file",211 comm_file,212 "--launch-target",213 "echo",214 "foo",215 ],216 universal_newlines=True,217 stderr=subprocess.PIPE,218 env={**os.environ, "LLDB_DAP_RIT_TIMEOUT_IN_MS": "1000"},219 )220 221 self.read_pid_message(comm_file)222 223 _, stderr = proc.communicate()224 self.assertIn("Timed out trying to get messages from the debug adapter", stderr)225