llvm-project/lldb/test/API/commands/platform/launchgdbserver/TestPlatformLaunchGDBServer.py
Dave Lee b9225e8607
[lldb] Allow tests to share a single build (#181720)
This changes Python API tests to use a single build shared across all
test functions, instead of the previous default behavior of a separate
build dir for each test function.

This build behavior opt-out, tests can use the previous behavior of one
individual (unshared) build directory per test function, by setting
`SHARED_BUILD_TESTCASE` to False (in the test class).

The motivation is to make the test suite more efficient, by not
repeatedly building the same test source. When running tests on my macOS
machine, this reduces the time of `ninja check-lldb-api` by almost 60%
(sample numbers: from ~492s down to ~207s = 58%). Almost 5min time
saved.

Each test function still calls `self.build()`, but only the first call
will do a build, in the subsequent tests `make` will be a no-op because
the sources won't have changed.
2026-02-18 10:38:45 -08:00

86 lines
3.0 KiB
Python

import os
import socket
import shutil
import lldbgdbserverutils
from lldbsuite.test.decorators import *
from lldbsuite.test.lldbtest import *
from lldbsuite.test import lldbutil
class TestPlatformProcessLaunchGDBServer(TestBase):
NO_DEBUG_INFO_TESTCASE = True
SHARED_BUILD_TESTCASE = False
def _launch_and_connect(self, exe):
hostname = socket.getaddrinfo("localhost", 0, proto=socket.IPPROTO_TCP)[0][4][0]
listen_url = "[%s]:0" % hostname
port_file = self.getBuildArtifact("port")
commandline_args = [
"platform",
"--listen",
listen_url,
"--socket-file",
port_file,
]
self.spawnSubprocess(exe, commandline_args)
socket_id = lldbutil.wait_for_file_on_target(self, port_file)
new_platform = lldb.SBPlatform("remote-" + self.getPlatform())
self.dbg.SetSelectedPlatform(new_platform)
connect_url = "connect://[%s]:%s" % (hostname, socket_id)
self.runCmd("platform connect %s" % connect_url)
wd = self.getBuildArtifact("wd")
os.mkdir(wd)
new_platform.SetWorkingDirectory(wd)
@skipIfRemote
# Windows cannot delete the executable while it is running.
# On Darwin we may be using debugserver.
@skipUnlessPlatform(["linux"])
@add_test_categories(["lldb-server"])
def test_launch_error(self):
"""
Check that errors while handling qLaunchGDBServer are reported to the
user. Though this isn't a platform command in itself, the best way to
test it is from Python because we can juggle multiple processes more
easily.
"""
self.build()
# Run lldb-server from a new location.
new_lldb_server = self.getBuildArtifact("lldb-server")
shutil.copy(lldbgdbserverutils.get_lldb_server_exe(), new_lldb_server)
self._launch_and_connect(new_lldb_server)
# Now, remove our new lldb-server so that when it tries to invoke itself as a
# gdbserver, it fails.
os.remove(new_lldb_server)
self.runCmd("target create {}".format(self.getBuildArtifact("a.out")))
self.expect("run", substrs=["unable to launch a GDB server on"], error=True)
@skipIfRemote
@skipIfDarwin # Uses debugserver for debugging
@skipIfWindows
@add_test_categories(["lldb-server"])
def test_launch_with_unusual_process_name(self):
"""
Test that lldb-server can launch a debug session when running under an
unusual name (or under a symlink which resolves to an unusal name).
"""
self.build()
# Run lldb-server from a new location.
new_lldb_server = self.getBuildArtifact("obfuscated-server")
shutil.copy(lldbgdbserverutils.get_lldb_server_exe(), new_lldb_server)
self._launch_and_connect(new_lldb_server)
self.runCmd("target create {}".format(self.getBuildArtifact("a.out")))
self.expect("run", substrs=["exited with status = 0"])