test: keep pytest basetemp within the AF_UNIX path limit

Moving TMPDIR into the private runtime root left pytest's default
<TMPDIR>/pytest-of-<user>/pytest-<n> beneath it. With xdist's popen-gw<n>
the real-tmux witness bound a 110-byte socket path, over Linux's 107-byte
sun_path limit, so it failed under every worker count while passing
serially.

The controller now roots basetemp at the private root's pytest directory;
xdist hands workers popen-gw<n> beneath it. An explicit --basetemp wins.
A tmux-independent witness binds a socket at the same path budget.
This commit is contained in:
Alexandre Teixeira
2026-10-03 03:46:52 +01:00
parent e1bc13b634
commit 256beebb3d
3 changed files with 18 additions and 2 deletions
+2 -1
View File
@@ -351,7 +351,8 @@ def context_probe_ledger(_no_context_window_network_probe):
return _no_context_window_network_probe return _no_context_window_network_probe
@pytest.hookimpl(specname="pytest_configure") # Before pytest's tmpdir plugin reads the basetemp this sets.
@pytest.hookimpl(specname="pytest_configure", tryfirst=True)
def pytest_configure_worker_runtime(config): def pytest_configure_worker_runtime(config):
configure_runtime(config, _runtime_environment) configure_runtime(config, _runtime_environment)
+7 -1
View File
@@ -14,7 +14,7 @@ def bootstrap_runtime():
if os.environ.get("APP_PORT") and not worker: if os.environ.get("APP_PORT") and not worker:
return None return None
runtime = isolated_runtime(worker or "main") runtime = isolated_runtime(worker or "main")
runtime.__enter__() runtime.root = runtime.__enter__()
return runtime return runtime
@@ -22,6 +22,12 @@ def configure_runtime(config, runtime):
"""Register ownership even when configuration or collection fails.""" """Register ownership even when configuration or collection fails."""
if runtime is not None: if runtime is not None:
config.add_cleanup(lambda: runtime.__exit__(None, None, None)) config.add_cleanup(lambda: runtime.__exit__(None, None, None))
# pytest's default <TMPDIR>/pytest-of-<user>/pytest-<n> beneath the
# private TMPDIR, plus xdist's popen-gw<n>, overflows the 107-byte
# AF_UNIX limit for sockets in tmp_path. Workers inherit a basetemp
# under the controller's; an explicit --basetemp still wins.
if config.option.basetemp is None and not hasattr(config, "workerinput"):
config.option.basetemp = str(runtime.root / "pytest")
parallel = bool(getattr(config.option, "numprocesses", None)) or hasattr(config, "workerinput") parallel = bool(getattr(config.option, "numprocesses", None)) or hasattr(config, "workerinput")
# This consumes the existing test option; its public read and documented # This consumes the existing test option; its public read and documented
# source location remain in the static-server fixture. # source location remain in the static-server fixture.
+9
View File
@@ -1,6 +1,7 @@
"""The default namespace must protect callers and simultaneous pytest runs.""" """The default namespace must protect callers and simultaneous pytest runs."""
import os import os
import socket
import subprocess import subprocess
import sys import sys
import tempfile import tempfile
@@ -70,3 +71,11 @@ def test_subprocess_inherits_private_temp_and_data_directories():
assert (root / "data" / "child").read_text() == "data" assert (root / "data" / "child").read_text() == "data"
assert (root / "tmp" / "child").read_text() == "temp" assert (root / "tmp" / "child").read_text() == "temp"
assert not root.exists() assert not root.exists()
@pytest.mark.skipif(not hasattr(socket, "AF_UNIX"), reason="requires AF_UNIX")
def test_tmp_path_under_private_runtime_fits_unix_socket(tmp_path):
# pytest truncates this name to 30 characters, as for the real-tmux
# witness. A nested pytest-of-<user> basetemp made it 110 bytes under xdist.
with socket.socket(socket.AF_UNIX) as sock:
sock.bind(str(tmp_path / "tmux.sock"))