#!/usr/bin/env python3 """Check the CI app's unauthenticated API without changing saved preferences.""" import json import socket import subprocess import sys import tempfile import time import urllib.error import urllib.request from pathlib import Path app = Path(sys.argv[1]) / "Contents/MacOS/Meetingnotes" with socket.socket() as listener: listener.bind(("127.0.0.1", 0)) port = listener.getsockname()[1] with tempfile.TemporaryFile() as log: process = subprocess.Popen( [str(app), "-muteDeckAPIEnabled", "YES", "-muteDeckAPIPort", str(port), "-hasCompletedOnboarding", "YES", "-hasAcceptedTerms", "YES", "-SUEnableAutomaticChecks", "NO"], stdout=log, stderr=subprocess.STDOUT, ) try: for attempt in range(30): if process.poll() is not None: raise RuntimeError("CI app exited before the API became ready") try: with urllib.request.urlopen(f"http://127.0.0.1:{port}/api/info", timeout=2) as response: info = json.load(response) break except (urllib.error.URLError, TimeoutError): time.sleep(1) else: raise RuntimeError("CI API did not become ready") assert info["name"] == "MeetingDebrief", "Unexpected API identity" try: urllib.request.urlopen(f"http://127.0.0.1:{port}/api/recording/status", timeout=2) except urllib.error.HTTPError as error: assert error.code == 401, f"Unexpected status: {error.code}" else: raise RuntimeError("Recording status allowed an unauthenticated request") print("Local API readiness and authentication checks passed") except Exception: log.seek(0) print(log.read().decode(errors="replace")[-8000:], file=sys.stderr) raise finally: if process.poll() is None: process.terminate() try: process.wait(timeout=10) except subprocess.TimeoutExpired: process.kill() process.wait()