blob: 4a360a0bcad0122ed10da1eb1c9d96b0372b88c5 [file] [log] [blame]
"""
Test lldb-dap runInTerminal reverse request
"""
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import line_number
import lldbdap_testcase
import os
import subprocess
import json
@skipIfBuildType(["debug"])
class TestDAP_runInTerminal(lldbdap_testcase.DAPTestCaseBase):
def read_pid_message(self, fifo_file):
with open(fifo_file, "r") as file:
self.assertIn("pid", file.readline())
@staticmethod
def send_did_attach_message(fifo_file):
with open(fifo_file, "w") as file:
file.write(json.dumps({"kind": "didAttach"}) + "\n")
@staticmethod
def read_error_message(fifo_file):
with open(fifo_file, "r") as file:
return file.readline()
@skipIfAsan
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_runInTerminal(self):
"""
Tests the "runInTerminal" reverse request. It makes sure that the IDE can
launch the inferior with the correct environment variables and arguments.
"""
program = self.getBuildArtifact("a.out")
source = "main.c"
self.build_and_launch(
program, console="integratedTerminal", args=["foobar"], env=["FOO=bar"]
)
self.assertEqual(
len(self.dap_server.reverse_requests),
1,
"make sure we got a reverse request",
)
request = self.dap_server.reverse_requests[0]
self.assertIn(self.lldbDAPExec, request["arguments"]["args"])
self.assertIn(program, request["arguments"]["args"])
self.assertIn("foobar", request["arguments"]["args"])
self.assertIn("FOO", request["arguments"]["env"])
breakpoint_line = line_number(source, "// breakpoint")
self.set_source_breakpoints(source, [breakpoint_line])
self.continue_to_next_stop()
# We verify we actually stopped inside the loop
counter = int(self.dap_server.get_local_variable_value("counter"))
self.assertEqual(counter, 1)
# We verify we were able to set the launch arguments
argc = int(self.dap_server.get_local_variable_value("argc"))
self.assertEqual(argc, 2)
argv1 = self.dap_server.request_evaluate("argv[1]")["body"]["result"]
self.assertIn("foobar", argv1)
# We verify we were able to set the environment
env = self.dap_server.request_evaluate("foo")["body"]["result"]
self.assertIn("bar", env)
self.continue_to_exit()
@skipIfAsan
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_runInTerminalWithObjectEnv(self):
"""
Tests the "runInTerminal" reverse request. It makes sure that the IDE can
launch the inferior with the correct environment variables using an object.
"""
program = self.getBuildArtifact("a.out")
self.build_and_launch(program, console="integratedTerminal", env={"FOO": "BAR"})
self.assertEqual(
len(self.dap_server.reverse_requests),
1,
"make sure we got a reverse request",
)
request = self.dap_server.reverse_requests[0]
request_envs = request["arguments"]["env"]
self.assertIn("FOO", request_envs)
self.assertEqual("BAR", request_envs["FOO"])
self.continue_to_exit()
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_runInTerminalInvalidTarget(self):
self.build_and_create_debug_adapter()
response = self.launch(
"INVALIDPROGRAM",
console="integratedTerminal",
args=["foobar"],
env=["FOO=bar"],
expectFailure=True,
)
self.assertFalse(response["success"])
self.assertIn(
"'INVALIDPROGRAM' does not exist",
response["body"]["error"]["format"],
)
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_missingArgInRunInTerminalLauncher(self):
proc = subprocess.run(
[self.lldbDAPExec, "--launch-target", "INVALIDPROGRAM"],
capture_output=True,
universal_newlines=True,
)
self.assertNotEqual(proc.returncode, 0)
self.assertIn(
'"--launch-target" requires "--comm-file" to be specified', proc.stderr
)
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_FakeAttachedRunInTerminalLauncherWithInvalidProgram(self):
comm_file = os.path.join(self.getBuildDir(), "comm-file")
os.mkfifo(comm_file)
proc = subprocess.Popen(
[
self.lldbDAPExec,
"--comm-file",
comm_file,
"--launch-target",
"INVALIDPROGRAM",
],
universal_newlines=True,
stderr=subprocess.PIPE,
)
self.read_pid_message(comm_file)
self.send_did_attach_message(comm_file)
self.assertIn("No such file or directory", self.read_error_message(comm_file))
_, stderr = proc.communicate()
self.assertIn("No such file or directory", stderr)
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_FakeAttachedRunInTerminalLauncherWithValidProgram(self):
comm_file = os.path.join(self.getBuildDir(), "comm-file")
os.mkfifo(comm_file)
proc = subprocess.Popen(
[
self.lldbDAPExec,
"--comm-file",
comm_file,
"--launch-target",
"echo",
"foo",
],
universal_newlines=True,
stdout=subprocess.PIPE,
)
self.read_pid_message(comm_file)
self.send_did_attach_message(comm_file)
stdout, _ = proc.communicate()
self.assertIn("foo", stdout)
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_FakeAttachedRunInTerminalLauncherAndCheckEnvironment(self):
comm_file = os.path.join(self.getBuildDir(), "comm-file")
os.mkfifo(comm_file)
proc = subprocess.Popen(
[self.lldbDAPExec, "--comm-file", comm_file, "--launch-target", "env"],
universal_newlines=True,
stdout=subprocess.PIPE,
env={**os.environ, "FOO": "BAR"},
)
self.read_pid_message(comm_file)
self.send_did_attach_message(comm_file)
stdout, _ = proc.communicate()
self.assertIn("FOO=BAR", stdout)
@skipIfWindows
@skipIf(oslist=["linux"], archs=no_match(["x86_64"]))
def test_NonAttachedRunInTerminalLauncher(self):
comm_file = os.path.join(self.getBuildDir(), "comm-file")
os.mkfifo(comm_file)
proc = subprocess.Popen(
[
self.lldbDAPExec,
"--comm-file",
comm_file,
"--launch-target",
"echo",
"foo",
],
universal_newlines=True,
stderr=subprocess.PIPE,
env={**os.environ, "LLDB_DAP_RIT_TIMEOUT_IN_MS": "1000"},
)
self.read_pid_message(comm_file)
_, stderr = proc.communicate()
self.assertIn("Timed out trying to get messages from the debug adapter", stderr)