open-standards/wai/wai-rs/tests/fixtures/dev-stack/fake-stack.py
Transaction Science 576511d62b
Some checks failed
joule-moq-remote host agent / joule-moq-remote · does this change touch it (pull_request) Successful in 7s
joule-moq-room room service / joule-moq-room · does this change touch it (pull_request) Successful in 5s
joule-moq-web browser client / joule-moq-web · does this change touch it (pull_request) Successful in 6s
wai-app and Create / wai-app · does this change touch it (pull_request) Successful in 5s
standards workspaces build + test / which workspaces this change touches (pull_request) Successful in 7s
wai-audit collector and player integration / does this change touch it (pull_request) Successful in 7s
WAI breaking changes and the conformance runner / WAI breaking · does this change touch WAI (pull_request) Successful in 6s
WAI operation catalogue / does this change touch it (pull_request) Successful in 5s
WAI conformance / does this change touch it (pull_request) Successful in 7s
WAI energy receipts / does this change touch it (pull_request) Successful in 7s
WAI examples / WAI examples · does this change touch them (pull_request) Successful in 10s
wai-fleet service / does this change touch it (pull_request) Successful in 7s
wai-ledger service / does this change touch it (pull_request) Successful in 7s
wai-pack / wai-pack · does this change touch it (pull_request) Successful in 5s
wai-quantum studio and desktop / does this change touch it (pull_request) Successful in 5s
wai-sink-android native sink library / does this change touch it (pull_request) Successful in 7s
wai-sink-swift native sink package / does this change touch it (pull_request) Successful in 5s
WAI Studio / does this change touch it (pull_request) Successful in 7s
wai-web wasm32 / does this change touch it (pull_request) Successful in 6s
wai-web reach builds / wai-web reach · does this change touch it (pull_request) Successful in 7s
wai-quantum for JavaScript / does this change touch it (pull_request) Successful in 1m21s
WAI conformance / fast integer kernels, every x86_64 kernel set (AVX-512 silicon) (pull_request) Successful in 4m1s
repository checks / lockfiles, advisories, tests in CI, workflow hygiene, spec and section references, public text (pull_request) Failing after 1m30s
joule-moq-remote host agent / joule-moq-remote, every target (macos) (pull_request) Successful in 58s
wai-app and Create / wai-app · Create, browser end-to-end (macos) (pull_request) Failing after 6s
standards workspaces build + test / macOS energy backends (pull_request) Failing after 7s
wai-audit collector and player integration / collector, player integration and the browser end to end · macos (pull_request) Successful in 1m49s
WAI conformance / cross-arch byte-equality · macos (pull_request) Failing after 11s
WAI conformance / codec wrappers · fuzz smoke, text decode limits, C entry points, provenance, the semantic path (pull_request) Failing after 16s
WAI energy receipts / energy receipts · macos (pull_request) Failing after 11s
joule-moq-web browser client / joule-moq-web · browser end-to-end (macos) (pull_request) Successful in 15m56s
wai-fleet service / service · macos (pull_request) Successful in 39s
wai-ledger service / service · macos (pull_request) Successful in 59s
wai-pack / wai-pack · macos (pull_request) Successful in 3m3s
WAI conformance / cargo-class corpora · macos (pull_request) Successful in 10m56s
wai-sink-android native sink library / every ABI, the AAR, and the instrumented tests in a headless emulator · macos (pull_request) Failing after 6s
wai-sink-swift native sink package / libwai slices, desktop tests, simulator tests · macos (pull_request) Failing after 8s
wai-quantum studio and desktop / desktop app · macos (pull_request) Successful in 3m24s
wai-quantum studio and desktop / desktop app · windows (pull_request) Successful in 9m59s
joule-moq-remote host agent / joule-moq-remote, every target (linux-arm64) (pull_request) Successful in 1m10s
WAI examples / WAI examples · the archive, the readiness check, the browser and Apple · macos (pull_request) Successful in 20m11s
WAI Studio / Studio in Chromium and Firefox · macos (pull_request) Successful in 12m21s
joule-moq-room room service / joule-moq-room, every target (pull_request) Successful in 3m49s
wai-app and Create / wai-app · tests, clippy, the line language's verifier (linux) (pull_request) Successful in 57s
WAI breaking changes and the conformance runner / WAI breaking · wire, record and API against main · linux (pull_request) Successful in 1m34s
wai-audit collector and player integration / collector · linux (pull_request) Successful in 3m44s
WAI breaking changes and the conformance runner / WAI breaking and conform · their tests, and the independent verifiers through wai conform · linux (pull_request) Successful in 5m40s
WAI operation catalogue / the catalogue and every door · linux (pull_request) Successful in 5m22s
WAI conformance / cross-arch byte-equality · linux (pull_request) Successful in 39s
WAI conformance / faces from keypoints under wasm32-wasip2 (wasmtime) (pull_request) Successful in 1m48s
WAI conformance / quantum core and corpus under wasm32-wasip2 (wasmtime) (pull_request) Successful in 3m36s
wai-fleet service / service · linux (pull_request) Successful in 2m27s
standards workspaces build + test / joule-code-rs (joule-code/joule-code-rs, joule-code-rs, linux-arm64, true) (pull_request) Successful in 6m0s
wai-pack / wai-pack · linux (pull_request) Successful in 1m57s
wai-ledger service / service · linux (pull_request) Successful in 2m32s
WAI conformance / v2 vocabulary · manifests validate as stated (pull_request) Successful in 17s
WAI conformance / delivery telemetry · CMCD and CMSD against an independent library (pull_request) Successful in 13s
WAI conformance / cross-arch byte-equality · linux-arm64 (pull_request) Successful in 28s
WAI conformance / C2PA manifest emission · signed, read back, validated (pull_request) Successful in 1m42s
WAI conformance / cargo-class corpora · linux (pull_request) Successful in 17m43s
WAI examples / WAI examples · portable · linux (pull_request) Successful in 10m44s
WAI Studio / the catalogue's actions, the unit tests and the core · linux (pull_request) Successful in 58s
WAI energy receipts / energy receipts · linux (pull_request) Successful in 15m37s
wai-quantum studio and desktop / studio · browser (pull_request) Successful in 6m10s
wai-web reach builds / wai-web reach builds · the package of record, every output as recorded (pull_request) Successful in 2m39s
wai-quantum studio and desktop / desktop app · linux (pull_request) Successful in 8m47s
wai-web reach builds / wai-web reach builds · this tree's wai-web, every rung on its engine line (pull_request) Successful in 4m48s
WAI energy receipts / energy receipts · linux-arm64 (pull_request) Successful in 11m58s
wai-pack / wai-pack · linux-arm64 (pull_request) Successful in 1m55s
WAI examples / WAI examples · android-app · linux-arm64 (pull_request) Successful in 8m6s
wai-pack / wai-pack · the floor through a media prober (pull_request) Successful in 21s
wai-pack / wai-pack · dependency licences (pull_request) Successful in 17s
WAI Studio / Studio in WebKit · linux (pull_request) Successful in 12m4s
wai-sink-android native sink library / the JNI layer and the platform-free half on the host JVM · linux-arm64 (pull_request) Successful in 2m20s
wai-quantum for JavaScript / javascript · linux (pull_request) Successful in 2m51s
WAI conformance / each feature of the independent verifiers' steps compiles alone (pull_request) Successful in 19m29s
wai-pack / wai-pack · independent verifier (Python) (pull_request) Successful in 6m46s
WAI conformance / cargo-class corpora · linux-arm64 (pull_request) Successful in 23m36s
wai-web wasm32 / wai-web wasm32 build · corpus, menu and writers (pull_request) Successful in 18m56s
WAI conformance / independent verifiers · claims, JWP, key discovery and integer payloads (Python) (pull_request) Successful in 1h40m40s
wai dev's test: the stand-in room service listens without a reverse lookup
tests/cli_studio.rs failed on every run on one macOS runner and passed on
every other runner, 3 of 3 against 19 of 19 on 5 November, with "the room
service's clock on the relay: not within 30 s".

The stand-in room service starts an HTTPServer, whose server_bind calls
socket.getfqdn before the server listens. On that host, under the runner's
Python 3.15.2, getfqdn("127.0.0.1") takes 35 s, past the 30 s wai dev waits, and
a stack dump of the stalled stand-in shows it there. The stand-in relay opens a
plain socket and answers in 0.1 s. Nothing here reads the name, so the fixture
no longer asks for it.

On that host and Python the room stand-in took 35.5 s and now takes 0.12 s. A
socket.getfqdn planted to stall for 40 s fails the test without this change,
with the same message, and passes with it.

Changelog: none

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-11-05 18:24:54 -05:00

90 lines
2.9 KiB
Python
Executable file

#!/usr/bin/env python3
"""A stand-in for the relay and the room service, for tests/cli_studio.rs: what `wai dev`
asks of each, and nothing more.
fake-stack.py keygen|relay-lines <keys.toml> prints relay lines (comments here)
fake-stack.py --config <relay.toml|room.toml> listens where the configuration says
A relay's configuration names `websocket_listen`; it accepts connections and closes them. A
room service's names `listen`; it answers GET /health as a service whose clock is on the
relay, and GET /room with an empty room. Either exits when the process that started it is
gone. Standard library only.
"""
import http.server
import json
import os
import re
import socket
import socketserver
import sys
import threading
import time
def watch_parent():
parent = os.getppid()
while True:
time.sleep(0.5)
if os.getppid() != parent:
os._exit(0)
def listen_addr(config, key):
text = open(config, encoding="utf-8").read()
m = re.search(r'^%s\s*=\s*"([^"]+)"' % key, text, re.M)
host, port = m.group(1).rsplit(":", 1)
return host, int(port)
class Room(http.server.BaseHTTPRequestHandler):
def do_GET(self):
if self.path.startswith("/health"):
body = {"ok": True, "relay": True, "room": "00" * 32}
elif self.path.startswith("/room"):
body = {"room": "00" * 32, "t0_us": 0, "descriptor": "", "grants": []}
else:
self.send_error(404)
return
b = json.dumps(body).encode()
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(b)))
self.end_headers()
self.wfile.write(b)
def log_message(self, *args):
pass
class Server(http.server.ThreadingHTTPServer):
"""HTTPServer looks up a name for its address before it listens, and nothing here reads the
name. On some hosts that lookup takes 35 s, past what `wai dev` waits for a service."""
def server_bind(self):
socketserver.TCPServer.server_bind(self)
def main(argv):
if argv[:1] in (["keygen"], ["relay-lines"]):
open(argv[1], "a").close()
print("# authority %s\n# clock %s" % ("11" * 32, "22" * 32))
return 0
if argv[:1] != ["--config"]:
print("fake-stack.py: keygen|relay-lines <keys> or --config <file>", file=sys.stderr)
return 2
threading.Thread(target=watch_parent, daemon=True).start()
config = argv[1]
if "websocket_listen" in open(config, encoding="utf-8").read():
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(listen_addr(config, "websocket_listen"))
s.listen(16)
while True:
c, _ = s.accept()
c.close()
Server(listen_addr(config, "listen"), Room).serve_forever()
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))