Port the transport failure harness into test/harness
The freeze-proxy and MCP-stdio driver that measured the two worker-transport blockers lived outside any repo and would have died with the session that built them. They are the only instrument in reach that can construct a blackholed socket -- a route that stops carrying bytes without ever sending a FIN or an RST -- which is the condition both blockers are about.
The SYN-drop mode is the subtle part. It stops new connections by filling the accept queue and never accepting, so the kernel drops further SYNs and a connect hangs for its full retransmit budget (~135s). If the queue does not actually fill, the listening socket REFUSES instead and the connect fails in ~5s. Those are different failures, not a strong and a weak version of one, and an experiment that believes it is measuring the first while measuring the second still produces numbers that still look like results.
So the control that was previously run by hand before first use is now built in and runs every time:
assert_accepting() negative control -- the probe can see a HEALTHY
port, so its verdict on an unhealthy one means
something
assert_blackholing() positive control -- new connections HANG; raises
loudly and specifically if they are refusedproxy_control_test.py breaks the mode three ways (listener closed -> refused, blackhole_new() a no-op, backlog too large so the kernel completes the handshake itself) and asserts the control goes red for each. A control only ever seen passing is indistinguishable from one that always passes.
Two changes to the original while porting:
- Frozen connections are keyed by a monotonic counter rather than by Python id(). id()s are reused after GC, which was raised as a candidate explanation for a real measurement and had to be ruled out by hand; a counter cannot collide, so that hypothesis cannot arise again.
- Both controls score their OWN probe rather than probing separately and comparing. Two connects can land on different port states -- that is a race, not a check, and it produced one flaky result before it was fixed.
README records the teardown hazard: stop these servers by the exact PID in state.env, never by pattern. Concurrent harnesses on one host are a normal condition, and a pattern kill takes somebody else's server along with the killing session itself.
.gitignore | 1 +
test/harness/env-down.sh | 17 +++++++++
test/harness/env-up.sh | 78 +++++++++++++++++++++++++++++++++++++++++
test/harness/mcpdrv.py | 268 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
test/harness/proxy.py | 299 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
test/harness/proxy_control_test.py | 88 ++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 751 insertions(+).gitignoremodified
.sigil/deps/*.sgb*.core__pycache__/test/harness/env-down.shadded
#!/usr/bin/env bash## Tear down the throwaway enclave-server started by env-up.sh.## Kills ONLY the PID recorded in state.env. Never a pattern match:# another harness may be running the same binary on this host, and an# agent session's own command line typically contains the task name it# would match on. See README.md.set -uRUN=${HARNESS_RUN:-/tmp/apiary-harness}[ -f "$RUN/state.env" ] || { echo "no $RUN/state.env -- nothing to stop"; exit 0; }. "$RUN/state.env"if kill -0 "$SERVER_PID" 2>/dev/null; then kill "$SERVER_PID" && echo "killed enclave server pid=$SERVER_PID"else echo "server pid=$SERVER_PID already gone"fitest/harness/env-up.shadded
#!/usr/bin/env bash## Stand up a throwaway enclave-server + seeded DB for the apiary# transport harness. Writes state to $HARNESS_RUN/state.env so the# python drivers can read it.## ./env-up.sh -> seeds, starts server, prints the run dir# ./env-down.sh -> kills the server by RECORDED PID, never pkill## NEVER stop this server with a pattern match. See README.md --# concurrent enclave harnesses on one host are normal, and a pattern# kill takes somebody else's server AND the killing session with it.set -uRUN=${HARNESS_RUN:-/tmp/apiary-harness}PORT=${HARNESS_PORT:-49771}ENCLAVE_BIN=${ENCLAVE_BIN:-}DB="$RUN/harness.db"OWNER=${HARNESS_OWNER:-owner-1}OWNER_PASS=${HARNESS_OWNER_PASS:-harness-admin}LEADER=${HARNESS_LEADER:-leader-1}CHANNEL=${HARNESS_CHANNEL:-#coord}GROUP=${HARNESS_GROUP:-test-workers}if [ -z "$ENCLAVE_BIN" ]; then echo "FATAL: set ENCLAVE_BIN to an enclave-server binary." >&2 echo " e.g. ENCLAVE_BIN=/path/to/enclave ./env-up.sh" >&2 exit 1fiif [ ! -x "$ENCLAVE_BIN" ]; then echo "FATAL: enclave binary not found/executable at $ENCLAVE_BIN" >&2 exit 1fimkdir -p "$RUN"rm -f "$DB" "$DB-shm" "$DB-wal"ENCLAVE_DB_PATH="$DB" "$ENCLAVE_BIN" user add "$OWNER" \ --password "$OWNER_PASS" --role admin >/dev/null \ || { echo "FATAL: user add failed" >&2; exit 1; }ENCLAVE_DB_PATH="$DB" "$ENCLAVE_BIN" group create "$GROUP" >/dev/null 2>&1 || trueLEADER_OUT=$(ENCLAVE_DB_PATH="$DB" "$ENCLAVE_BIN" \ bot register "$LEADER" --owner "$OWNER" --allow-services yes \ --auto-join "$CHANNEL")LEADER_TOKEN=$(echo "$LEADER_OUT" | grep -oE '[a-f0-9]{64}' | head -1)if [ -z "$LEADER_TOKEN" ]; then echo "FATAL: no leader token in bot-register output" >&2 echo "$LEADER_OUT" >&2 exit 1fiENCLAVE_LOG_LEVEL=${ENCLAVE_LOG_LEVEL:-info} ENCLAVE_PORT="$PORT" \ ENCLAVE_DB_PATH="$DB" "$ENCLAVE_BIN" serve > "$RUN/server.log" 2>&1 &SERVER=$!sleep 2if ! kill -0 "$SERVER" 2>/dev/null; then echo "FATAL: server died on startup" >&2 cat "$RUN/server.log" >&2 exit 1ficat > "$RUN/state.env" <<EOFRUN=$RUNPORT=$PORTDB=$DBSERVER_PID=$SERVERENCLAVE_BIN=$ENCLAVE_BINLEADER_TOKEN=$LEADER_TOKENLEADER_NICK=$LEADEROWNER=$OWNERCHANNEL=$CHANNELEOFecho "RUN=$RUN PORT=$PORT SERVER_PID=$SERVER"echo "leader token: ${LEADER_TOKEN:0:8}...(${#LEADER_TOKEN} chars)"echo "stop with: HARNESS_RUN=$RUN $(dirname "$0")/env-down.sh"test/harness/mcpdrv.pyadded
#!/usr/bin/env python3"""Drive apiary (an MCP-stdio server) as a scriptable client.Apiary has no CLI; running the binary speaks MCP JSON-RPC onstdin/stdout. This module spawns one apiary process per bot, performsthe MCP handshake, and lets a test script call tools and observeinbound `notifications/claude/channel` events -- which is exactly thesignal that says "this bot's trusted-set filter delivered thatmessage".Everything is line-delimited JSON on stdout; stderr carries apiary'sown structured log.Configuration comes from the environment so a single experiment scriptcan be pointed at two different binaries for a matched pair: APIARY_BIN path to the apiary release bundle to drive (required) HARNESS_RUN state/log directory (default /tmp/apiary-harness)"""import jsonimport osimport queueimport subprocessimport sysimport threadingimport timeRUN_DIR = os.environ.get("HARNESS_RUN", "/tmp/apiary-harness")# Identifiers used by env-up.sh's seeded database. Generic on purpose:# this is a public repo and these must not encode any particular# deployment's nicks, hosts or channels.OWNER = os.environ.get("HARNESS_OWNER", "owner-1")LEADER_NICK = os.environ.get("HARNESS_LEADER", "leader-1")CHANNEL = os.environ.get("HARNESS_CHANNEL", "#coord")WORKER_GROUP = os.environ.get("HARNESS_GROUP", "test-workers")def apiary_bin(): b = os.environ.get("APIARY_BIN") if not b: raise SystemExit( "APIARY_BIN is not set. Point it at the apiary release " "bundle to drive, e.g.\n" " APIARY_BIN=$PWD/build/release/bin/apiary python3 " "test/harness/exp_silent_loss.py\n" "Refusing to guess: a matched pair is worthless if both " "arms silently run the same binary.") if not os.access(b, os.X_OK): raise SystemExit(f"APIARY_BIN is not executable: {b}") return bdef load_state(run_dir=None): """Read env-up.sh's state.env.""" run_dir = run_dir or RUN_DIR path = os.path.join(run_dir, "state.env") if not os.path.exists(path): raise SystemExit( f"no {path} -- run test/harness/env-up.sh first") state = {} with open(path) as f: for line in f: k, _, v = line.strip().partition("=") if k: state[k] = v return stateclass Bot: def __init__(self, label, env, bin=None, log_dir=None): self.label = label self.env = dict(os.environ) # Scrub any inherited APIARY_* so a stray value from the shell # cannot silently change what we think we are testing. for k in list(self.env): if k.startswith("APIARY_"): del self.env[k] self.env.update({k: str(v) for k, v in env.items()}) log_dir = log_dir or RUN_DIR os.makedirs(log_dir, exist_ok=True) self.stderr_path = os.path.join(log_dir, f"{label}.stderr") self._stderr_f = open(self.stderr_path, "w") self.bin = bin or apiary_bin() self.proc = subprocess.Popen( [self.bin], stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=self._stderr_f, env=self.env, text=True, bufsize=1, ) self._id = 0 self._responses = {} self._resp_lock = threading.Condition() self.notifications = [] self._notif_lock = threading.Condition() self.raw = [] self._reader = threading.Thread(target=self._read_loop, daemon=True) self._reader.start() # ---- plumbing ------------------------------------------------- def _read_loop(self): for line in self.proc.stdout: line = line.strip() if not line: continue self.raw.append(line) try: msg = json.loads(line) except json.JSONDecodeError: continue if "id" in msg and ("result" in msg or "error" in msg): with self._resp_lock: self._responses[msg["id"]] = msg self._resp_lock.notify_all() elif msg.get("method") == "notifications/claude/channel": with self._notif_lock: self.notifications.append(msg["params"]) self._notif_lock.notify_all() def _send(self, obj): self.proc.stdin.write(json.dumps(obj) + "\n") self.proc.stdin.flush() def _request(self, method, params=None, timeout=60): self._id += 1 rid = self._id self._send({"jsonrpc": "2.0", "id": rid, "method": method, "params": params or {}}) deadline = time.time() + timeout with self._resp_lock: while rid not in self._responses: remaining = deadline - time.time() if remaining <= 0: raise TimeoutError(f"{self.label}: {method} timed out") self._resp_lock.wait(remaining) return self._responses.pop(rid) # ---- MCP ------------------------------------------------------ def initialize(self, timeout=60): r = self._request("initialize", { "protocolVersion": "2024-11-05", "capabilities": {}, "clientInfo": {"name": "apiary-harness", "version": "0.0"}, }, timeout=timeout) self._send({"jsonrpc": "2.0", "method": "notifications/initialized", "params": {}}) return r def tools(self): r = self._request("tools/list") return sorted(t["name"] for t in r["result"]["tools"]) def call(self, tool, timeout=60, **args): r = self._request("tools/call", {"name": tool, "arguments": args}, timeout=timeout) if "error" in r: return f"<JSONRPC-ERROR {json.dumps(r['error'])}>" parts = [c.get("text", "") for c in r["result"].get("content", [])] return "\n".join(parts) def wait_connected(self, timeout=25.0): """Block until the bridge logs a successful connect.""" deadline = time.time() + timeout while time.time() < deadline: if self.grep_stderr("Apiary bridge connected"): return True time.sleep(0.1) return False # ---- observation --------------------------------------------- def wait_notification(self, match, timeout=20): """Wait for an inbound channel notification whose content contains `match`. Returns the params dict, or None on timeout.""" deadline = time.time() + timeout seen = 0 with self._notif_lock: while True: while seen < len(self.notifications): n = self.notifications[seen] seen += 1 if match in n.get("content", ""): return n remaining = deadline - time.time() if remaining <= 0: return None self._notif_lock.wait(remaining) def contents(self): return [n.get("content", "") for n in self.notifications] def alive(self): return self.proc.poll() is None def stderr_text(self): self._stderr_f.flush() with open(self.stderr_path) as f: return f.read() def grep_stderr(self, pat): return [l for l in self.stderr_text().splitlines() if pat in l] def close(self): try: self.proc.terminate() self.proc.wait(timeout=10) except Exception: try: self.proc.kill() except Exception: pass try: self._stderr_f.close() except Exception: passdef leader_env(port, token, nick=None, host="127.0.0.1", channel=None, owner=None, **extra): e = { "APIARY_ENCLAVE_HOST": host, "APIARY_ENCLAVE_PORT": port, "APIARY_ENCLAVE_TLS": "no", "APIARY_USER": nick or LEADER_NICK, "APIARY_TOKEN": token, "APIARY_CHANNEL": channel or CHANNEL, "APIARY_MODE": "leader", "APIARY_OWNER_NICK": owner or OWNER, "APIARY_REPORTS_TO": owner or OWNER, "APIARY_SERVICES_TIMEOUT": "8.0", "APIARY_WORKER_GROUP": WORKER_GROUP, } e.update(extra) return edef worker_env(port, token, nick, reports_to=None, host="127.0.0.1", channel=None, owner=None, **extra): e = { "APIARY_ENCLAVE_HOST": host, "APIARY_ENCLAVE_PORT": port, "APIARY_ENCLAVE_TLS": "no", "APIARY_USER": nick, "APIARY_TOKEN": token, "APIARY_CHANNEL": channel or CHANNEL, "APIARY_MODE": "worker", "APIARY_OWNER_NICK": owner or OWNER, "APIARY_REPORTS_TO": reports_to or LEADER_NICK, "APIARY_SERVICES_TIMEOUT": "8.0", } e.update(extra) return edef say(*a): print(*a, flush=True)def check(label, ok, detail=""): say(f" [{'PASS' if ok else 'FAIL'}] {label}" + (f" -- {detail}" if detail else "")) return bool(ok)test/harness/proxy.pyadded
"""Freeze-proxy: construct network failures that a plain socket closecannot imitate.Two modes, and they are DIFFERENT failures: freeze_existing() -- hold established connections open and silently swallow bytes in both directions. No FIN, no RST. This is what a route change looks like to the far end: the peer's kernel keeps the socket ESTABLISHED forever and writes succeed into the local send buffer. blackhole_new() -- make NEW connections HANG instead of being refused, by filling the accept queue and never accepting again so the kernel drops further SYNs.`blackhole_new()` is the subtle one and it carries a POSITIVE CONTROLyou must not remove -- see `assert_blackholing()` below."""import selectimport socketimport threadingimport timeclass ProxyControlFailed(AssertionError): """The proxy is not producing the failure it claims to produce. `observed` carries the probe classification that failed the control, so a caller scores the SAME probe the control scored. Probing twice and comparing the two answers is a race, not a check -- the port's state can differ between them. """ def __init__(self, message, observed=None): super().__init__(message) self.observed = observedclass Proxy: """TCP relay with a switchable mode.""" def __init__(self, listen_port, target_port, host="127.0.0.1"): self.mode = "pass" self.host = host self.listen_port = listen_port self.target_port = target_port self.conns = [] # list of [key, client_sock, upstream_sock] self.fillers = [] self._next_key = 0 self.srv = socket.socket() self.srv.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) self.srv.bind((host, listen_port)) # Tiny backlog on purpose: `blackhole_new()` fills the accept # queue and stops accepting, so further SYNs are DROPPED by the # kernel rather than refused. Refused fails fast (~5s) and would # test the wrong failure entirely; a route that has gone away # drops, and the caller waits out the kernel's SYN-retransmit # budget (~135s). self.srv.listen(1) # Frozen connections, keyed by our own monotonic counter. # # The spike version keyed this on `id(pair)`. CPython reuses # id()s after GC, so a connection created after a reconnect # could in principle inherit a stale frozen mark -- which was # raised as a candidate explanation (H1) for a real measurement # and had to be ruled out by hand. A counter cannot collide, so # the hypothesis cannot arise again. self.frozen_at = {} threading.Thread(target=self._accept_loop, daemon=True).start() # ---- failure modes ------------------------------------------- def freeze_existing(self): """Blackhole every currently-established connection.""" now = time.time() for entry in list(self.conns): self.frozen_at[entry[0]] = now return now def sever_existing(self): """Close every established connection cleanly (FIN both ways). This is the SERVER-RESTART shape, not the route-change shape: the peer sees EOF immediately and reconnects in seconds. Use it when you want to exercise the reconnect path itself rather than the detection that precedes it -- e.g. to inspect what state a reconnected connection comes back with. """ n = 0 for entry in list(self.conns): for s in entry[1:]: try: s.close() except OSError: pass n += 1 self.conns = [] return n def blackhole_new(self): """Make NEW connections hang instead of being refused. Call `assert_blackholing()` afterwards. Do not assume this worked. """ self.mode = "blackhole" time.sleep(0.3) # let the accept loop park for _ in range(4): c = socket.socket() c.settimeout(1.5) try: c.connect((self.host, self.listen_port)) self.fillers.append(c) except OSError: pass # queue already full: good # ---- controls ------------------------------------------------ def probe_connect(self, timeout=2.0): """Classify what a fresh connection to the proxy port does. Returns one of "connected" / "hung" / "refused" / "error:...". This is the instrument the two controls below score. """ s = socket.socket() s.settimeout(timeout) try: s.connect((self.host, self.listen_port)) return "connected" except socket.timeout: return "hung" except ConnectionRefusedError: return "refused" except OSError as e: return f"error:{e.__class__.__name__}" finally: try: s.close() except OSError: pass def assert_accepting(self, timeout=2.0): """NEGATIVE CONTROL -- prove the probe can see a HEALTHY port. Without this, `assert_blackholing()` is unfalsifiable: a probe that reports "hung" unconditionally (wrong host, wrong port, a bug in the timeout handling) would pass it for free. Run this BEFORE blackholing, against the same port, with the same probe. """ got = self.probe_connect(timeout=timeout) if got != "connected": raise ProxyControlFailed( "negative control FAILED: a fresh connection to the " f"proxy port before blackholing reported {got!r}, not " "'connected'. The probe cannot see a healthy port, so " "its verdict on an unhealthy one means nothing.", got) return got def assert_blackholing(self, timeout=2.0): """POSITIVE CONTROL for `blackhole_new()` -- DO NOT REMOVE. The mode claims new connections are DROPPED (SYNs go unanswered, the caller hangs for the kernel's full retransmit budget, ~135s). If the accept queue did not actually fill -- a larger backlog, a kernel that answers anyway, a filler connect that raced -- the listening socket instead REFUSES, which fails in ~5s. Refused and dropped are DIFFERENT FAILURES, not a strong and a weak version of one. An experiment that believes it is measuring a blackholed route while measuring a refused one is wrong in a way nothing downstream can detect: it still produces numbers, and the numbers still look like results. This was verified by hand before the mode was first used. That verification is now here so it runs every time. """ got = self.probe_connect(timeout=timeout) if got == "hung": return got if got == "refused": raise ProxyControlFailed( "SYN-drop positive control FAILED: a fresh connection " "was REFUSED, not dropped. The accept queue did not " "fill, so this proxy is producing a ~5s " "connection-refused, NOT a ~135s blackhole. Any " "measurement taken now is of a different failure.", got) raise ProxyControlFailed( "SYN-drop positive control FAILED: a fresh connection " f"reported {got!r}; expected 'hung'. New connections are " "not being dropped.", got) # ---- plumbing ------------------------------------------------ def _accept_loop(self): while True: if self.mode == "blackhole": time.sleep(0.2) # never accept: SYNs get dropped continue if self.mode == "closed": return r, _, _ = select.select([self.srv], [], [], 0.2) if not r: continue try: c, _ = self.srv.accept() except OSError: return try: u = socket.create_connection((self.host, self.target_port)) except OSError: c.close() continue self._next_key += 1 key = self._next_key self.conns.append([key, c, u]) threading.Thread(target=self._pump, args=(c, u, key), daemon=True).start() threading.Thread(target=self._pump, args=(u, c, key), daemon=True).start() def _pump(self, a, b, key): a.settimeout(0.5) while True: try: data = a.recv(65536) except socket.timeout: continue except OSError: return if not data: try: b.shutdown(socket.SHUT_WR) except OSError: pass return if self.frozen_at.get(key): continue # swallow: no FIN, no RST, bytes vanish try: b.sendall(data) except OSError: return def close(self): self.mode = "closed" for c in self.fillers: try: c.close() except OSError: pass try: self.srv.close() except OSError: passdef _self_test(): """Demonstrate BOTH controls firing, in both directions. Run: python3 proxy.py Prints the classification of a fresh connect before and after `blackhole_new()`. A run in which both lines say the same thing is a broken harness whatever the words are. """ # Target port is deliberately something nothing listens on: the # controls score the LISTENING side, and never need an upstream. p = Proxy(0, 9, host="127.0.0.1") # Port 0 asked the kernel for an ephemeral port; read back what it # actually bound so the probe aims at the right place. p.listen_port = p.srv.getsockname()[1] try: # Each control probes ONCE and we score that same probe. An # earlier version probed separately and compared, which is a # race rather than a check: the port's state can change between # two connects, and it did. before = p.assert_accepting() print(f" before blackhole_new(): fresh connect -> {before!r}") print(" [PASS] negative control: probe sees a HEALTHY port") p.blackhole_new() after = p.assert_blackholing() print(f" after blackhole_new(): fresh connect -> {after!r}") print(" [PASS] positive control: new connections are DROPPED, " "not refused") if before == after: raise ProxyControlFailed( f"both probes reported {before!r} -- the probe is not " "discriminating, it is just returning a constant", before) print(f"\n controls discriminate: {before!r} -> {after!r}") finally: p.close()if __name__ == "__main__": _self_test()test/harness/proxy_control_test.pyadded
#!/usr/bin/env python3"""Prove the SYN-drop positive control can go RED.`proxy.py --self-test` shows the control passing. A control that hasonly ever been seen passing is indistinguishable from a control thatalways passes, so this script breaks the SYN-drop mode three differentways and asserts the control catches each one.Run: python3 test/harness/proxy_control_test.pyThe sabotages are applied by monkeypatching a live Proxy instance --`proxy.py` itself is never edited, so there is no restore step thatcould silently discard work.Needs no enclave-server and no apiary binary: it scores the proxy'slistening socket only."""import osimport timeimport syssys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))from proxy import Proxy, ProxyControlFailed # noqa: E402def run(name, sabotage, expect_probe): p = Proxy(0, 9) # Port 0 asked the kernel for an ephemeral port; read back what it # actually bound so the probe aims at the right place. p.listen_port = p.srv.getsockname()[1] try: # Fixture validity: the instrument still sees a healthy port # BEFORE the sabotage. Without this a RED below could just mean # the probe was broken from the start. p.assert_accepting() sabotage(p) time.sleep(0.3) # let the accept loop park/exit before probing try: # Score the control's OWN probe (carried on the exception). # Probing separately and comparing would be a race: the two # connects can land on different port states. got = p.assert_blackholing() except ProxyControlFailed as e: ok = (e.observed == expect_probe) print(f" [{'RED' if ok else 'RED (unexpected shape)'}] {name}: " f"probe={e.observed!r} (expected {expect_probe!r})") print(f" -> {str(e).splitlines()[0][:96]}...") return ok print(f" [FALSE GREEN] {name}: probe={got!r} but the control PASSED") return False finally: p.close()def sab_close_listener(p): """Degradation: the listener is CLOSED rather than parked, so the kernel REFUSES. Refused fails in ~5s where a blackhole takes ~135s -- a different failure, and the one this control exists to catch.""" p.mode = "closed" p.srv.close()def sab_noop(p): """Degradation: blackhole_new() silently did nothing at all."""def sab_big_backlog(p): """Degradation: the backlog is large enough that the filler connects do not fill it, so the kernel completes the handshake by itself and connect() SUCCEEDS even though userspace never accepts.""" p.srv.listen(128) p.blackhole_new()def main(): print("== sabotaging the SYN-drop positive control ==") results = [ run("listener closed -> refused", sab_close_listener, "refused"), run("blackhole_new() no-op", sab_noop, "connected"), run("backlog too large", sab_big_backlog, "connected"), ] print(f"\n {sum(results)}/{len(results)} sabotages produced the " "expected RED") return 0 if all(results) else 1if __name__ == "__main__": sys.exit(main())