[Lldb-commits] [lldb] [lldb-dap] Migrate the runInTerminal tests (PR #231964)
John Harrison via lldb-commits
lldb-commits at lists.llvm.org
Wed Oct 14 13:50:15 PDT 2026
================
@@ -0,0 +1,216 @@
+"""
+Test the lldb-dap runInTerminal launcher flow.
+"""
+
+import json
+import os
+import subprocess
+import sys
+
+from lldbsuite.test.decorators import *
+from lldbsuite.test.tools.lldb_dap import DAPTestCaseBase
+
+if sys.platform == "win32":
+ import ctypes
+ import ctypes.wintypes
+ import uuid
+
+
+class CommChannel:
+ """The channel the runInTerminal launcher uses to talk to the debug adapter.
+
+ fifo on Unix and named pipe on Windows.
+ """
+
+ if sys.platform == "win32":
+ PIPE_ACCESS_DUPLEX = 0x00000003
+ PIPE_TYPE_MESSAGE = 0x00000004
+ PIPE_READMODE_MESSAGE = 0x00000002
+ PIPE_WAIT = 0x00000000
+ PIPE_UNLIMITED_INSTANCES = 255
+ ERROR_MORE_DATA = 234
+ BUFFER_SIZE = 4096
+
+ def __init__(self, _directory: str):
+ self.path = rf"\\.\pipe\lldb-dap-run-in-terminal-comm-{uuid.uuid4().hex}"
+ self._kernel32 = ctypes.windll.kernel32
+ self._pipe = self._kernel32.CreateNamedPipeW(
+ self.path,
+ self.PIPE_ACCESS_DUPLEX,
+ self.PIPE_TYPE_MESSAGE | self.PIPE_READMODE_MESSAGE | self.PIPE_WAIT,
+ self.PIPE_UNLIMITED_INSTANCES,
+ self.BUFFER_SIZE,
+ self.BUFFER_SIZE,
+ 0,
+ None,
+ )
+
+ def read_message(self) -> str:
+ self._kernel32.ConnectNamedPipe(self._pipe, None)
+ buffer = b""
+ while True:
+ chunk = ctypes.create_string_buffer(self.BUFFER_SIZE)
+ bytes_read = ctypes.wintypes.DWORD()
+ success = self._kernel32.ReadFile(
+ self._pipe, chunk, self.BUFFER_SIZE, ctypes.byref(bytes_read), None
+ )
+ buffer += chunk.raw[: bytes_read.value]
+ if success:
+ break
+ if ctypes.GetLastError() != self.ERROR_MORE_DATA:
+ break
+ return buffer.decode()
+
+ def write_message(self, message: str) -> None:
+ bytes_written = ctypes.wintypes.DWORD()
+ self._kernel32.ConnectNamedPipe(self._pipe, None)
+ self._kernel32.WriteFile(
+ self._pipe,
+ message.encode(),
+ len(message),
+ ctypes.byref(bytes_written),
+ None,
+ )
+
+ def close(self) -> None:
+ self._kernel32.DisconnectNamedPipe(self._pipe)
+ self._kernel32.CloseHandle(self._pipe)
+
+ else:
+
+ def __init__(self, directory: str):
+ self.path = os.path.join(directory, "comm-file")
+ os.mkfifo(self.path)
+
+ def read_message(self) -> str:
+ with open(self.path, "r") as file:
+ return file.readline()
+
+ def write_message(self, message: str) -> None:
+ with open(self.path, "w") as file:
+ file.write(message)
+
+ def close(self) -> None:
+ pass
+
+ def __enter__(self) -> "CommChannel":
+ return self
+
+ def __exit__(self, *exc_info):
+ self.close()
+
+ def send_did_attach(self):
+ self.write_message(json.dumps({"kind": "didAttach"}) + "\n")
+
+
+ at skipIfWasm # runInTerminal has the client run the program, and a Wasm module is not executable
+class TestDAP_runInTerminal_launcher(DAPTestCaseBase):
+ SHARED_BUILD_TESTCASE = False
+ USE_DEFAULT_DEBUG_ADAPTER = False
+
+ def test_launch_target_requires_comm_file(self):
+ proc = subprocess.run(
+ [
+ self.lldb_dap_exe,
+ "--launch-target",
+ self.getBuildArtifact("INVALIDPROGRAM"),
+ ],
+ capture_output=True,
+ universal_newlines=True,
+ )
+ self.assertNotEqual(proc.returncode, 0)
+ self.assertIn(
+ '"--launch-target" requires "--comm-file" to be specified', proc.stderr
+ )
+
+ def test_invalid_program_reports_error(self):
+ with CommChannel(self.getBuildDir()) as channel:
+ proc = subprocess.Popen(
+ [
+ self.lldb_dap_exe,
+ "--comm-file",
+ channel.path,
+ "--launch-target",
+ self.getBuildArtifact("INVALIDPROGRAM"),
+ ],
+ universal_newlines=True,
+ stderr=subprocess.PIPE,
+ )
+ if sys.platform == "win32":
+ _, stderr = proc.communicate()
+ self.assertIn("Failed to launch target process", stderr)
+ else:
+ self.assertIn("pid", channel.read_message())
+ channel.send_did_attach()
+ self.assertIn("No such file or directory", channel.read_message())
+
+ _, stderr = proc.communicate()
+ self.assertIn("No such file or directory", stderr)
+
+ def test_launches_program_after_attach(self):
+ build_dir = self.getBuildDir()
+ with CommChannel(build_dir) as channel:
+ proc = subprocess.Popen(
+ [
+ self.lldb_dap_exe,
+ "--comm-file",
+ channel.path,
+ "--launch-target",
+ "echo",
----------------
ashgti wrote:
Is this looking up `echo` in `$PATH`? Should we have a specific program helper program in case `echo` isn't in `$PATH`?
https://github.com/llvm/llvm-project/pull/231964
More information about the lldb-commits
mailing list