From d1549cba57936427fcf54f7be779b87545172367 Mon Sep 17 00:00:00 2001 From: Swung0x48 Date: Wed, 23 Sep 2026 10:53:25 -0400 Subject: [PATCH] [scripts] (P7): the TCP lane supervisor starts headless like every other server the harness reaches --- scripts/ci/tcp_lane_tools_test.py | 50 +++++++++++++++++++++++++++++++ scripts/ci/tcp_server_fixture.py | 9 ++++++ 2 files changed, 59 insertions(+) diff --git a/scripts/ci/tcp_lane_tools_test.py b/scripts/ci/tcp_lane_tools_test.py index 8c13fe42..2f1a5adb 100644 --- a/scripts/ci/tcp_lane_tools_test.py +++ b/scripts/ci/tcp_lane_tools_test.py @@ -202,6 +202,56 @@ class Supervisor(unittest.TestCase): with self.assertRaises(OSError): socket.create_connection(('127.0.0.1', port), timeout=.2) + def started_server_environment(self, **outer): + """Start the fixture under `outer` (None unsets a key) and return the environment its + server process actually saw.""" + fixture = module('tcp_server_fixture') + with tempfile.TemporaryDirectory() as directory: + root = Path(directory) + seen = root / 'seen.json' + server = root / 'server' + server.write_text('#!' + sys.executable + '\n' + 'import json,os,socket,sys\n' + f'open({str(seen)!r},"w").write(json.dumps(dict(os.environ)))\n' + 'port=int(sys.argv[1].rsplit(":",1)[1])\n' + 's=socket.socket();s.bind(("127.0.0.1",port));s.listen()\n' + 'while True: s.accept()[0].close()\n') + server.chmod(0o755) + with socket.socket() as reservation: + reservation.bind(('127.0.0.1', 0)) + port = reservation.getsockname()[1] + state = root / 'state.json' + env = dict(os.environ) + for key, value in outer.items(): + if value is None: + env.pop(key, None) + else: + env[key] = value + subprocess.run([sys.executable, str(Path(fixture.__file__)), 'start', + '--server', str(server), '--endpoint', f'tcp://127.0.0.1:{port}', + '--state', str(state)], check=True, env=env) + try: + return json.loads(seen.read_text()) + finally: + fixture.stop(state) + + def test_the_supervisor_is_headless_like_every_other_server_the_harness_reaches(self): + """CI red since P6.5: every DirectGLES.Tcp. case failed "remote TCP bring-up failed". + + Under inproc and spawn the server inherits the CLIENT's environment after + HeadlessGL.cpp's EnsureHeadlessPlatform pinned EGL_PLATFORM=surfaceless and cleared + DISPLAY/WAYLAND_DISPLAY. This supervisor is started by ctest from the job environment + instead, so on a WSLg workstation it bound Mesa's build-time default x11 platform and went + green, and on a runner with no window system eglInitialize failed with "xcb_connect + failed" for every session.""" + seen = self.started_server_environment(DISPLAY=':0', WAYLAND_DISPLAY='wayland-0', EGL_PLATFORM=None) + self.assertEqual(seen.get('EGL_PLATFORM'), 'surfaceless') + self.assertNotIn('DISPLAY', seen) + self.assertNotIn('WAYLAND_DISPLAY', seen) + # An operator's explicit platform still wins, as it does in the harness. + seen = self.started_server_environment(EGL_PLATFORM='x11') + self.assertEqual(seen.get('EGL_PLATFORM'), 'x11') + if __name__ == '__main__': unittest.main() diff --git a/scripts/ci/tcp_server_fixture.py b/scripts/ci/tcp_server_fixture.py index 9e0d41bc..146c4fed 100644 --- a/scripts/ci/tcp_server_fixture.py +++ b/scripts/ci/tcp_server_fixture.py @@ -63,6 +63,15 @@ def start(args): for key in ('MOBILEGL_TRANSPORT', 'MOBILEGL_IPC_SERVER_PATH', 'MOBILEGL_IPC_RING_MB', 'MOBILEGL_IPC_STAGE_MB', 'MOBILEGL_IPC_CONTROL', 'MOBILEGL_IPC_ENDPOINT', 'MOBILEGL_BACKEND_TYPE'): env.pop(key, None) + # The harness's headless pin (HeadlessGL.cpp, EnsureHeadlessPlatform), for the one server it + # does not start. Under inproc and spawn the server inherits the client's environment AFTER the + # pin; this supervisor inherits ctest's. Without it Mesa takes its build-time x11 platform: on a + # WSLg workstation that binds the window system and goes green, on a runner with no DISPLAY + # eglInitialize fails ("xcb_connect failed") and every Tcp. case reds with "remote TCP bring-up + # failed". An operator's explicit EGL_PLATFORM still wins, as it does in the harness. + env.setdefault('EGL_PLATFORM', 'surfaceless') + env.pop('DISPLAY', None) + env.pop('WAYLAND_DISPLAY', None) log_path = args.state.with_suffix('.log') with log_path.open('wb') as log: child = subprocess.Popen([args.server, args.endpoint, '--serve'], env=env,