"""Start the built EXE in isolation, verify setup/login, then stop its own tree.""" import os from pathlib import Path import socket import subprocess import tempfile import time import urllib.request def probe(executable): with tempfile.TemporaryDirectory(prefix='po-win7-exe-') as temporary: directory = Path(temporary) with socket.socket() as sock: sock.bind(('127.0.0.1', 0)) port = sock.getsockname()[1] env = {k: v for k, v in os.environ.items() if not k.upper().startswith(('PO_', 'PYTHON', 'VIRTUAL_ENV'))} env.update(PO_DATA_DIR=str(directory), PO_HOST='127.0.0.1', PO_OPEN_BROWSER='0') http = urllib.request.build_opener(urllib.request.ProxyHandler({})) with (directory/'server.log').open('wb') as log: process = subprocess.Popen([str(Path(executable).resolve()), str(port)], env=env, cwd=directory, stdout=log, stderr=subprocess.STDOUT, creationflags=subprocess.CREATE_NO_WINDOW) try: deadline = time.monotonic() + 90 while time.monotonic() < deadline: if process.poll() is not None: raise RuntimeError('EXE exited: ' + (directory/'server.log').read_text(errors='replace')) try: with http.open('http://127.0.0.1:%s/login' % port, timeout=1) as response: if response.status == 200: assert (directory/'instance/setup.token').is_file() print('EXE STARTUP PASSED:', executable) return except (OSError, TimeoutError): time.sleep(0.25) raise RuntimeError('EXE did not start within 90 seconds') finally: if process.poll() is None: subprocess.run(['taskkill', '/PID', str(process.pid), '/T', '/F'], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE, creationflags=subprocess.CREATE_NO_WINDOW) process.wait(timeout=20) if __name__ == '__main__': import sys probe(sys.argv[1])