#!/usr/bin/env python3 """Measure native upload backlog against a delayed loopback server with fixture data.""" import base64 import http.server import json import os from pathlib import Path import subprocess import sys import threading import time root = Path(__file__).resolve().parents[2] fixture = (root / "internal/docs/seeddata/letter.update.bin").read_bytes() updates = [] lock = threading.Lock() fail_once = "--fail-once" in sys.argv class Handler(http.server.BaseHTTPRequestHandler): def do_GET(self): if self.path.endswith("/stream"): self.send_response(200) self.send_header("Content-Type", "text/event-stream") self.end_headers() self.wfile.write(b"data: 0\n\n") self.wfile.flush() time.sleep(30) return if self.path == "/stats": with lock: data = json.dumps(dict(updates=updates)).encode() elif "/updates" in self.path: data = fixture else: data = json.dumps(dict(sqid="fixture", title="Sync fixture", guid="sync-fixture", can_write=True, can_share=False)).encode() self.send_response(200) self.send_header("Docs-Seq", "0") self.send_header("Content-Length", str(len(data))) self.end_headers() self.wfile.write(data) def do_POST(self): body = self.rfile.read(int(self.headers.get("Content-Length", "0"))) # Deterministic request latency, not an artificial client debounce. time.sleep(0.25) with lock: updates.append(base64.b64encode(body).decode()) self.send_response(503 if fail_once and len(updates) == 1 else 204) self.end_headers() def log_message(self, *_): pass with http.server.ThreadingHTTPServer(("127.0.0.1", 0), Handler) as server: threading.Thread(target=server.serve_forever, daemon=True).start() env = dict(os.environ, DOCS_SYNC_TEST_ORIGIN=f"http://127.0.0.1:{server.server_port}") result = subprocess.run(["swift", "test", "--package-path", str(root / "native/apple"), "--filter", "DocumentSyncIntegrationTests"], env=env, timeout=240) server.shutdown() raise SystemExit(result.returncode)