Files
benchmarks/egress/run.sh
zeekayandHanzo Dev 0078a3efcd Refuse without a stray cd
`cd "$(cloud_src)" || exit 1` runs cd on the empty string when the resolver
refuses, so a lane that had just printed how to get the source followed it with
`cd: null directory`. The path is captured first and checked before anything
is entered.

Co-authored-by: Hanzo Dev <[email protected]>
2026-09-16 09:54:04 -07:00

159 lines
7.2 KiB
Bash
Executable File

#!/usr/bin/env bash
# What leaves the machine.
#
# `self/` measures whether you can have the software. This measures whether
# having it means anyone else hears about it.
#
# Two observers, because one of them can miss.
#
# A LISTENER STANDING IN FOR THE INTERNET. Go's net/http honours HTTP_PROXY and
# HTTPS_PROXY, so a process pointed at `catcher.py` reaches that socket instead
# of anywhere real, and every attempt is recorded with what it asked for. It
# cannot be missed by timing: the connection is either accepted or it never
# happened.
#
# ITS SOCKETS, SAMPLED. The proxy only sees a client that honours the variables,
# so the process is also watched directly with lsof. That one CAN miss — a
# connection that opens and closes between two samples is invisible, and this
# run proves it does miss by reporting how many it caught of traffic it knows
# was there. Read it as corroboration, never as the proof.
#
# Both end with a control: the same observer, pointed at something that does
# reach out. A zero from an observer that cannot see is not evidence.
set -euo pipefail
# The lane runs from the cloud source, which is a different repository now.
# `cloud_src` finds it or says how to get it (../host.sh).
HERE="$(cd "$(dirname "$0")" && pwd)"
. "$HERE/../host.sh"
SRC="$(cloud_src)" || exit 1
cd "$SRC"
host
sockets() {
lsof -nP -i -a -p "$1" -F n 2>/dev/null | sed -n 's/^n//p' || true
}
watch_sockets() {
local pid=$1 until_ts=$2 seen=$3
while [ "$(python3 -c 'import time;print(int(time.time()))')" -lt "$until_ts" ]; do
sockets "$pid" >>"$seen"
sleep 0.1
done
}
# A peer on loopback is this machine talking to itself — the curls below, the
# health probe, the catcher. Anything else is egress. The catcher's own port is
# loopback, so an attempt to phone home shows up in ITS log, not here.
remote_only() {
grep -F -- '->' "$1" 2>/dev/null | sed 's/.*->//' | sort -u |
grep -vE '^(127\.0\.0\.1|\[?::1\]?|localhost)[:.]' || true
}
P=${P:-18090}; ZP=${ZP:-19663}; HP=${HP:-19091}; AP=${AP:-18091}
DATA=$(mktemp -d); BIN=$(mktemp -u); PID=""; WATCH=""; CATCH=""
cleanup() {
for p in "$WATCH" "$CATCH" "$PID"; do
[ -n "$p" ] || continue
# `|| true` OR THE HANDLER DIES HERE. set -e is in force inside a trap, and
# kill returns non-zero for a pid that has already exited — which $WATCH
# always has, because watch_sockets runs to a deadline and returns on its
# own. So the first kill failed, cleanup aborted before it reached the
# server, and every run left one behind holding :18090. The next run then
# could not bind and died with no message at all.
kill "$p" 2>/dev/null || true
# Reaped here, or the shell reports the signal over the last row of output.
wait "$p" 2>/dev/null || true
done
rm -rf "$DATA" "$BIN"
}
trap cleanup EXIT
export GOWORK=off
go build -o "$BIN" ./cmd/cloud
: >"$DATA/caught"
# AN OBSERVER THAT NEVER STARTED IS NOT AN OBSERVER THAT SAW NOTHING, and this
# loop could not tell them apart. It waited five seconds for `ready`, then went on
# whatever happened; the run reached its control, found an empty log, and reported
# that the caller had not used the catcher — blaming the subject for the
# instrument. On 2026-09-16 the port was simply taken by an unrelated process that
# had held it for seven hours, and the lane said the caller did not phone home.
#
# So the failure is named where it happens, and the port is not a constant. A
# fixed CP is a standing appointment with whatever else on the machine likes that
# number; asking the kernel for a free one removes the whole class.
if [ -z "${CP:-}" ]; then
CP=$(python3 -c 'import socket;s=socket.socket();s.bind(("127.0.0.1",0));print(s.getsockname()[1]);s.close()')
fi
python3 "$HERE/catcher.py" "$CP" "$DATA/caught" >"$DATA/catcher.out" 2>&1 & CATCH=$!
# ANCHORED, because the unanchored probe matched the failure. `grep -q ready`
# is true of "OSError: [Errno 48] Address already in use" — the word is inside
# "already" — so a catcher that could not bind reported itself started, the run
# went on with nothing watching, and the control blamed the caller for an empty
# log. The readiness token is a whole line or it is not a token.
for _ in $(seq 1 100); do grep -qx ready "$DATA/catcher.out" 2>/dev/null && break; sleep 0.05; done
if ! grep -qx ready "$DATA/catcher.out" 2>/dev/null; then
echo "the catcher never started on port $CP, so nothing was watching:" >&2
sed 's/^/ /' "$DATA/catcher.out" >&2
exit 1
fi
export CLOUD_DEV_UNENCRYPTED=1
export CLOUD_LISTEN=":$P" CLOUD_ZAP_LISTEN="127.0.0.1:$ZP"
export CLOUD_HEALTH_LISTEN="127.0.0.1:$HP" CLOUD_ADMIN_LISTEN="127.0.0.1:$AP"
export CLOUD_DATA_DIR="$DATA"
# Everything except the ports this run is driving. NO_PROXY has to name them or
# the binary's own health probe would be recorded as an attempt to leave.
export HTTP_PROXY="http://127.0.0.1:$CP" HTTPS_PROXY="http://127.0.0.1:$CP"
export http_proxy="$HTTP_PROXY" https_proxy="$HTTPS_PROXY" ALL_PROXY="$HTTP_PROXY"
export NO_PROXY="127.0.0.1:$P,127.0.0.1:$ZP,127.0.0.1:$HP,127.0.0.1:$AP"
export no_proxy="$NO_PROXY"
"$BIN" serve >"$DATA/log" 2>&1 & PID=$!
for _ in $(seq 1 300); do
curl -s -m 2 --noproxy '*' "http://127.0.0.1:$HP/healthz" 2>/dev/null | grep -q . && break
sleep 0.1
done
UNTIL=$(python3 -c 'import time;print(int(time.time())+12)')
watch_sockets "$PID" "$UNTIL" "$DATA/seen" & WATCH=$!
for _ in $(seq 1 20); do
curl -s -o /dev/null -m 8 --noproxy '*' "http://127.0.0.1:$P/v1/tasks"
curl -s -o /dev/null -m 8 --noproxy '*' -X POST "http://127.0.0.1:$P/mcp" \
-H 'Content-Type: application/json' \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'
curl -s -o /dev/null -m 8 --noproxy '*' -X POST "http://127.0.0.1:$P/.well-known/zip/op/tasks_list"
done
wait "$WATCH" 2>/dev/null || true; WATCH=""
say "attempts to leave" "$(sort -u "$DATA/caught" | wc -l | tr -d ' ')"
sort -u "$DATA/caught" | sed 's/^/ /'
LISTENERS=$(sort -u "$DATA/seen" | grep -vF -- '->' | wc -l | tr -d ' ')
OUT=$(remote_only "$DATA/seen")
say "listeners seen" "$LISTENERS"
say "connections caught by sampling" "$(grep -cF -- '->' "$DATA/seen" || true)"
say "peers off this machine" "$([ -z "$OUT" ] && echo 0 || echo "$OUT" | wc -l | tr -d ' ')"
[ -n "$OUT" ] && echo "$OUT" | sed 's/^/ /'
[ "$LISTENERS" -eq 0 ] && { echo "no socket of any kind was seen on the server; it was not being watched" >&2; exit 1; }
# The controls, in the same run, so a broken observer fails the lane instead of
# reporting a clean one.
curl -s -m 6 -o /dev/null -x "http://127.0.0.1:$CP" https://pkg.hanzo.ai/ 2>/dev/null || true
sleep 0.5
CAUGHT_NOW=$(sort -u "$DATA/caught" | wc -l | tr -d ' ')
say "control: the catcher saw" "$CAUGHT_NOW attempt(s) after one caller"
[ "$CAUGHT_NOW" -eq 0 ] && { echo "the catcher recorded nothing for a caller that used it; the zero above is not evidence" >&2; exit 1; }
curl -s -m 10 -o /dev/null --noproxy '*' https://pkg.hanzo.ai/ & CPID=$!
UNTIL=$(python3 -c 'import time;print(int(time.time())+3)')
watch_sockets "$CPID" "$UNTIL" "$DATA/control" 2>/dev/null || true
wait "$CPID" 2>/dev/null || true
CN=$(remote_only "$DATA/control" | wc -l | tr -d ' ')
say "control: sampling saw" "$CN peer(s)"
[ "$CN" -eq 0 ] && { echo "sampling saw nothing it should have seen" >&2; exit 1; }
exit 0