video_monitor/tests/windows_tray.py
2026-09-04 18:16:14 +08:00

44 lines
2.2 KiB
Python

"""Desktop supervisor smoke test; opens the normal local setup browser."""
import json,os,secrets,socket,subprocess,sys,time
from pathlib import Path
import psutil,requests
exe=Path(sys.argv[1]).resolve()
data=Path(sys.argv[2]).resolve()
data.mkdir(parents=True,exist_ok=False)
with socket.socket() as sock:
sock.bind(('127.0.0.1',0));port=sock.getsockname()[1]
(data/'config.json').write_text(json.dumps({'host':'127.0.0.1','adminPort':port}),encoding='utf-8')
env=os.environ.copy();env['MONITOR_DATA_DIR']=str(data)
env.pop('PYTHONPATH',None);env.pop('PYTHONHOME',None)
root=env['SYSTEMROOT'];env['PATH']=root+'/System32;'+root+';'+root+'/System32/WindowsPowerShell/v1.0'
client=requests.Session();client.trust_env=False
base='http://127.0.0.1:'+str(port)
child=subprocess.Popen([str(exe)],env=env,cwd=data,creationflags=subprocess.CREATE_NO_WINDOW)
try:
duplicate=subprocess.Popen([str(exe)],env=env,cwd=data,creationflags=subprocess.CREATE_NO_WINDOW)
assert duplicate.wait(timeout=35)==0
deadline=time.monotonic()+120
while time.monotonic()<deadline:
assert child.poll() is None,'Supervisor exited early'
try:
if client.get(base+'/setup',timeout=2).status_code==200:break
except requests.RequestException:pass
time.sleep(.5)
else:raise RuntimeError('Setup page not ready')
descendants=psutil.Process(child.pid).children(recursive=True)
workers=[p for p in descendants if p.name().lower()=='monitor.exe']
assert len(workers)==1,[(p.pid,p.name()) for p in descendants]
stop=subprocess.Popen([str(exe),'--stop'],env=env,cwd=data,creationflags=subprocess.CREATE_NO_WINDOW)
assert stop.wait(timeout=50)==0
assert child.wait(timeout=10)==0
_,alive=psutil.wait_procs(workers,timeout=10)
assert not alive
result={'status':'passed','single_instance':'passed (simultaneous double launch)',
'setup_http':'passed','tray_supervisor':'passed','stop_command':'passed',
'owned_workers_stopped':'passed','external_python_path':'removed'}
(data/'tray-validation.json').write_text(json.dumps(result,indent=2),encoding='utf-8')
print(json.dumps(result,indent=2))
finally:
if child.poll() is None:
child.kill();child.wait(timeout=15)