AtlatestRepositoryapiary
1
#!/usr/bin/env bash2
#3
# End-to-end smoke for apiary. Boots a throwaway enclave-server,4
# provisions a daviwil/admin user + leader-davos bot, then runs:5
#6
# 1. test/smoke-driver.sgl — exercises the live bridge path:7
# tool registration (both modes), connect, presence broadcast,8
# trusted-set filter, listen-peer mechanics, self-echo check.9
#10
# 2. The release `apiary` binary — boots it pointed at the11
# throwaway server, confirms it connects, lets it idle a few12
# seconds, then SIGTERMs it. Verifies clean exit.13
#14
# Prerequisites:15
# - enclave-server built at $ENCLAVE_BIN (default:16
# ~/Projects/Code/sigil/enclave/build/dev/bin/enclave)17
# - apiary release bundle built at build/release/bin/apiary18
# (the script will build it if missing)20
set -u21
PORT=${PORT:-49669}22
ENCLAVE_REPO=${ENCLAVE_REPO:-$HOME/Projects/Code/sigil/enclave}23
ENCLAVE_BIN=${ENCLAVE_BIN:-$ENCLAVE_REPO/build/dev/bin/enclave}24
APIARY_REPO=${APIARY_REPO:-$(pwd)}25
APIARY_BIN=${APIARY_BIN:-$APIARY_REPO/build/release/bin/apiary}26
DB=${DB:-/tmp/apiary-smoke.db}28
if [ ! -x "$ENCLAVE_BIN" ]; then29
echo "FATAL: enclave binary not found at $ENCLAVE_BIN" >&230
exit 131
fi33
if [ ! -x "$APIARY_BIN" ]; then34
echo "==> apiary release bundle missing; building it"35
(cd "$APIARY_REPO" && \36
sigil build apiary -c release --backend bytecode --force) \37
|| { echo "FATAL: apiary build failed"; exit 1; }38
fi40
SERVER_LOG=$(mktemp)41
SMOKE_LOG=$(mktemp)42
APIARY_LOG=$(mktemp)43
SERVER=44
APIARY_PID=46
cleanup() {47
[ -n "${APIARY_PID:-}" ] && kill "$APIARY_PID" 2>/dev/null48
[ -n "${SERVER:-}" ] && kill "$SERVER" 2>/dev/null49
wait 2>/dev/null50
rm -f "$SERVER_LOG" "$SMOKE_LOG" "$APIARY_LOG"51
rm -f "$DB" "$DB-shm" "$DB-wal"52
}53
trap cleanup EXIT55
echo "==> seeding DB at $DB"56
rm -f "$DB" "$DB-shm" "$DB-wal"58
DAVIWIL_PASS=admin59
ENCLAVE_DB_PATH="$DB" "$ENCLAVE_BIN" \60
user add daviwil --password "$DAVIWIL_PASS" --role admin > /dev/null62
# Pre-create the ops-workers group so the Bug-A smoke check (which63
# spawns a worker without an explicit `groups` arg and verifies it64
# lands in APIARY_WORKER_GROUP) has a real group to land in.65
ENCLAVE_DB_PATH="$DB" "$ENCLAVE_BIN" \66
group create ops-workers > /dev/null 2>&1 || true68
LEADER_OUT=$(ENCLAVE_DB_PATH="$DB" "$ENCLAVE_BIN" \69
bot register leader-davos --owner daviwil --allow-services yes --auto-join "#hive")70
LEADER_TOKEN=$(echo "$LEADER_OUT" | grep -oE '[a-f0-9]{64}' | head -1)71
[ -z "$LEADER_TOKEN" ] && { echo "FATAL: no leader-davos token" >&2; exit 1; }72
echo " leader-davos token: ${LEADER_TOKEN:0:8}…(${#LEADER_TOKEN})"74
echo "==> starting enclave-server on :$PORT"75
ENCLAVE_LOG_LEVEL=warn ENCLAVE_PORT="$PORT" ENCLAVE_DB_PATH="$DB" \76
"$ENCLAVE_BIN" serve > "$SERVER_LOG" 2>&1 &77
SERVER=$!78
sleep 279
kill -0 "$SERVER" 2>/dev/null || \80
{ echo "FATAL: server died"; cat "$SERVER_LOG" >&2; exit 1; }82
# ============================================================83
# Phase 1: sigil-test driver against the live server84
# ============================================================85
echo "==> running test/smoke-driver.sgl"86
cd "$APIARY_REPO"87
APIARY_ENCLAVE_HOST=127.0.0.1 \88
APIARY_ENCLAVE_PORT="$PORT" \89
APIARY_ENCLAVE_TLS=no \90
APIARY_USER=leader-davos \91
APIARY_TOKEN="$LEADER_TOKEN" \92
APIARY_CHANNEL=#hive \93
APIARY_OWNER_NICK=daviwil \94
APIARY_REPORTS_TO=daviwil \95
APIARY_WORKER_GROUP=ops-workers \96
APIARY_SERVICES_TIMEOUT=8.0 \97
APIARY_DAVIWIL_PASS="$DAVIWIL_PASS" \98
sigil test test/smoke-driver.sgl > "$SMOKE_LOG" 2>&199
SMOKE_EXIT=$?101
echo102
echo "==> driver output:"103
sed 's/^/ /' "$SMOKE_LOG"105
if [ "$SMOKE_EXIT" != "0" ] || ! grep -q "All tests passed" "$SMOKE_LOG"; then106
echo107
echo "DRIVER FAILED (exit=$SMOKE_EXIT)"108
exit 1109
fi111
# ============================================================112
# Phase 2: rotate a fresh leader token (smoke driver consumed113
# auth state on the previous token), then run the release114
# `apiary` binary briefly. SIGTERM after a short idle.115
# ============================================================116
echo117
echo "==> rotating leader-davos token for the binary smoke"118
LEADER_OUT2=$(ENCLAVE_DB_PATH="$DB" "$ENCLAVE_BIN" \119
bot rotate-token leader-davos)120
LEADER_TOKEN2=$(echo "$LEADER_OUT2" | grep -oE '[a-f0-9]{64}' | head -1)121
[ -z "$LEADER_TOKEN2" ] && { echo "FATAL: no rotated token" >&2; exit 1; }123
echo "==> launching apiary binary against the throwaway server"124
export APIARY_ENCLAVE_HOST=127.0.0.1125
export APIARY_ENCLAVE_PORT="$PORT"126
export APIARY_ENCLAVE_TLS=no127
export APIARY_USER=leader-davos128
export APIARY_TOKEN="$LEADER_TOKEN2"129
export APIARY_CHANNEL=#hive130
export APIARY_OWNER_NICK=daviwil131
export APIARY_REPORTS_TO=daviwil132
export APIARY_SERVICES_TIMEOUT=8.0133
export APIARY_MODE=leader134
# Drive the MCP loop with a fake initialize handshake so the bridge135
# kicks in (channel-wait-initialized! gates on the MCP `initialize`136
# request). Then keep stdin open via `tail -f` so the loop doesn't137
# return.138
INIT_JSON='{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"smoke","version":"0.0"}}}'139
INITED_JSON='{"jsonrpc":"2.0","method":"notifications/initialized","params":{}}'140
(printf '%s\n%s\n' "$INIT_JSON" "$INITED_JSON"; tail -f /dev/null) \141
| "$APIARY_BIN" > "$APIARY_LOG" 2>&1 &142
APIARY_PID=$!144
# Wait up to 6s for "Apiary bridge connected" to appear.145
for _ in $(seq 1 60); do146
if grep -q "Apiary bridge connected" "$APIARY_LOG"; then147
break148
fi149
sleep 0.1150
done152
if ! grep -q "Apiary bridge connected" "$APIARY_LOG"; then153
echo154
echo "BINARY FAILED to connect"155
echo "==> apiary log:"156
sed 's/^/ /' "$APIARY_LOG"157
exit 1158
fi159
echo " apiary bridge connected"161
# Idle briefly so any deferred goroutine crash surfaces.162
sleep 1164
# Send SIGTERM and verify the binary exits cleanly.165
kill -TERM "$APIARY_PID" 2>/dev/null166
wait "$APIARY_PID" 2>/dev/null167
APIARY_EXIT=$?168
APIARY_PID=170
echo171
echo "==> apiary log (tail):"172
tail -20 "$APIARY_LOG" | sed 's/^/ /'174
# Standard SIGTERM exit code on POSIX is 143 (128+15). Treat 0175
# and 143 as clean.176
if [ "$APIARY_EXIT" = "0" ] || [ "$APIARY_EXIT" = "143" ]; then177
echo178
echo "ALL CHECKS PASSED (apiary exit=$APIARY_EXIT)"179
exit 0180
else181
echo182
echo "BINARY EXIT UNCLEAN (exit=$APIARY_EXIT)"183
exit 1184
fi