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.
86 lines
3.0 KiB
Python
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"])
|