fix(tests): live_gui fixture kills stale process on port 8999 before spawn
The fixture detected stale processes on port 8999 but only issued a soft btn_reset POST (which doesn't reset the provider). When a previous batch left a sloppy.py subprocess running, the new subprocess failed to bind port 8999 and the wait loop connected to the stale process instead, leading to cross-batch state pollution (e.g., test_change_provider_via_hook seeing current_provider='gemini' after setting 'anthropic').
Fix: when port 8999 is found LISTENING, parse netstat -ano for the PID, taskkill /F /PID it, sleep 1s, then proceed with the fresh subprocess.Popen.
Verified: tests/test_conftest_watchdog.py 3/3 still pass (the watchdog from e1c8730f is independent of this fix).
This commit is contained in:
+21
-6
@@ -356,15 +356,30 @@ def live_gui() -> Generator[tuple[subprocess.Popen, str], None, None]:
|
|||||||
else:
|
else:
|
||||||
os.symlink(src_assets, temp_workspace / "assets")
|
os.symlink(src_assets, temp_workspace / "assets")
|
||||||
|
|
||||||
# Check if already running (shouldn't be)
|
# Check if already running (shouldn't be). If stale, kill the old process
|
||||||
|
# before spawning a new one — otherwise the new subprocess fails to bind
|
||||||
|
# port 8999 and the wait loop connects to the stale process instead,
|
||||||
|
# leading to state pollution across batches.
|
||||||
try:
|
try:
|
||||||
resp = requests.get("http://127.0.0.1:8999/status", timeout=0.5)
|
resp = requests.get("http://127.0.0.1:8999/status", timeout=0.5)
|
||||||
if resp.status_code == 200:
|
if resp.status_code == 200:
|
||||||
print("[Fixture] WARNING: Hook Server already up on port 8999. Test state might be polluted.")
|
print("[Fixture] WARNING: Hook Server already up on port 8999. Killing stale process...")
|
||||||
# Optionally try to reset it
|
netstat = subprocess.run(["netstat", "-ano"], capture_output=True, text=True, timeout=5)
|
||||||
try: requests.post("http://127.0.0.1:8999/api/gui", json={"action": "click", "item": "btn_reset"}, timeout=1)
|
stale_pids: set[int] = set()
|
||||||
except: pass
|
for line in netstat.stdout.splitlines():
|
||||||
except: pass
|
if ":8999" in line and "LISTENING" in line:
|
||||||
|
parts = line.split()
|
||||||
|
if parts:
|
||||||
|
try: stale_pids.add(int(parts[-1]))
|
||||||
|
except ValueError: pass
|
||||||
|
for pid in stale_pids:
|
||||||
|
try:
|
||||||
|
subprocess.run(["taskkill", "/F", "/PID", str(pid)], capture_output=True, timeout=5)
|
||||||
|
print(f"[Fixture] Killed stale PID {pid}")
|
||||||
|
except Exception: pass
|
||||||
|
time.sleep(1.0)
|
||||||
|
print("[Fixture] Proceeding with fresh sloppy.py spawn")
|
||||||
|
except Exception: pass
|
||||||
|
|
||||||
print(f"\n[Fixture] Starting {gui_script} --enable-test-hooks in {temp_workspace}...")
|
print(f"\n[Fixture] Starting {gui_script} --enable-test-hooks in {temp_workspace}...")
|
||||||
os.makedirs("logs", exist_ok=True)
|
os.makedirs("logs", exist_ok=True)
|
||||||
|
|||||||
Reference in New Issue
Block a user