Files
manual_slop/tests/conftest.py

87 lines
3.2 KiB
Python

import pytest
import subprocess
import time
import requests
import os
import signal
def kill_process_tree(pid):
"""Robustly kills a process and all its children."""
if pid is None:
return
try:
print(f"[Fixture] Attempting to kill process tree for PID {pid}...")
if os.name == 'nt':
# /F is force, /T is tree (includes children)
subprocess.run(["taskkill", "/F", "/T", "/PID", str(pid)],
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
check=False)
else:
# On Unix, kill the process group
os.killpg(os.getpgid(pid), signal.SIGKILL)
print(f"[Fixture] Process tree {pid} killed.")
except Exception as e:
print(f"[Fixture] Error killing process tree {pid}: {e}")
@pytest.fixture(scope="session", params=["gui_legacy.py", "gui_2.py"])
def live_gui(request):
"""
Session-scoped fixture that starts a GUI script with --enable-test-hooks.
Parameterized to run either gui.py or gui_2.py.
"""
gui_script = request.param
print(f"\n[Fixture] Starting {gui_script} --enable-test-hooks...")
os.makedirs("logs", exist_ok=True)
log_file = open(f"logs/{gui_script.replace('.', '_')}_test.log", "w", encoding="utf-8")
process = subprocess.Popen(
["uv", "run", "python", gui_script, "--enable-test-hooks"],
stdout=log_file,
stderr=log_file,
text=True,
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP if os.name == 'nt' else 0
)
max_retries = 10 # Increased for potentially slower startup of gui_2
ready = False
print(f"[Fixture] Waiting up to {max_retries}s for Hook Server on port 8999...")
start_time = time.time()
while time.time() - start_time < max_retries:
try:
response = requests.get("http://127.0.0.1:8999/status", timeout=0.5)
if response.status_code == 200:
ready = True
print(f"[Fixture] GUI Hook Server for {gui_script} is ready after {round(time.time() - start_time, 2)}s.")
break
except (requests.exceptions.ConnectionError, requests.exceptions.Timeout):
if process.poll() is not None:
print(f"[Fixture] {gui_script} process died unexpectedly during startup.")
break
time.sleep(0.5)
if not ready:
print(f"[Fixture] TIMEOUT/FAILURE: Hook server for {gui_script} failed to respond.")
kill_process_tree(process.pid)
pytest.fail(f"Failed to start {gui_script} with test hooks.")
try:
yield process, gui_script
finally:
print(f"\n[Fixture] Finally block triggered: Shutting down {gui_script}...")
kill_process_tree(process.pid)
log_file.close()
@pytest.fixture(scope="session")
def live_gui_2(live_gui):
"""
A specific instance of the live_gui fixture that only runs for gui_2.py.
This simplifies tests that are specific to gui_2.py.
"""
process, gui_script = live_gui
if gui_script != "gui_2.py":
pytest.skip("This test is only for gui_2.py")
return process