#!/usr/bin/env python3 """Start an isolated native process and verify HTTP readiness and PWA resources.""" import argparse import json import os from pathlib import Path import socket import subprocess import tempfile import time import urllib.error import urllib.parse import urllib.request parser = argparse.ArgumentParser(description=__doc__) parser.add_argument('binary', type=Path) parser.add_argument('--timeout', type=int, default=90) args = parser.parse_args() binary = args.binary.resolve(strict=True) with socket.socket() as sock: sock.bind(('127.0.0.1', 0)) port = sock.getsockname()[1] base = f'http://127.0.0.1:{port}' # Never inherit application secrets, OIDC settings or a developer's JAVA_HOME. env = {'PATH': '/usr/bin:/bin', 'LANG': 'C.UTF-8'} with tempfile.TemporaryDirectory(prefix='werkjournal-smoke-') as directory: env['HOME'] = directory logfile = Path(directory) / 'server.log' with logfile.open('wb') as log: process = subprocess.Popen( [str(binary), f'--server.port={port}', '--server.address=127.0.0.1'], cwd=directory, env=env, stdout=log, stderr=subprocess.STDOUT, ) try: deadline = time.monotonic() + args.timeout while True: if process.poll() is not None: raise RuntimeError(f'Native process exited with {process.returncode}') try: with urllib.request.urlopen(base + '/api/v1/info', timeout=2) as response: info = json.load(response) if info.get('application') != 'werkjournal' or not info.get('version'): raise RuntimeError(f'Unexpected readiness response: {info}') break except (urllib.error.URLError, TimeoutError): if time.monotonic() >= deadline: raise RuntimeError('Native readiness timed out') time.sleep(0.25) for resource, expected in [('/', b'