The aarch64 leg ran npm with only cargo added to launchd's PATH, which omits node. Both clean-machine scripts said every binary runs and only looked for wai-pack and wai-remote-host: each now runs alone and says its usage. check-wai-release-quickstart.py read a step's lines for the script's path, so an echo of the path or a `|| true` after it passed; it now requires the script as the line's command, the step's exit status to be the script's, and the Windows throw after it. Co-Authored-By: Claude Opus 5.5 <[email protected]>
90 lines
4.8 KiB
Shell
Executable file
90 lines
4.8 KiB
Shell
Executable file
#!/usr/bin/env bash
|
|
# The quickstart as a new user runs it, from the archive alone, timed step by step:
|
|
#
|
|
# bash wai/quickstart/test/clean-machine.sh <archive.tar.gz> [--browser]
|
|
#
|
|
# A machine with nothing of WAI on it: a fresh HOME and working directory, a PATH of the system's
|
|
# own directories, no cargo and no repository. The steps are the quickstart's:
|
|
# 1. check the archive against its .sha256 beside it, and unpack it;
|
|
# 2. the archive holds what `wai dev` and the quickstart name: bin/ with wai, wai-relay,
|
|
# wai-room, wai-ingest, wai-remote-host, wai-pack and wai-quantum, each of which runs (the
|
|
# last four here, the first three in the steps below), and share/wai/web/ and
|
|
# share/wai/studio/ (Studio's page and its core);
|
|
# 3. wai hello; 4. wai verify; 5. wai create my-room --template video-room;
|
|
# 6. wai dev --check in the project: the relay, the room service, the page and WAI Studio at
|
|
# /_wai/ on one origin, each checked through it;
|
|
# 7. with --browser (BROWSER_BIN and PLAYWRIGHT_HOST set): the project's page joined in two
|
|
# browser pages, each decoding the other (the video-room example's test).
|
|
# It prints each step's time, the total, and a JSON line; it exits non-zero when a step fails,
|
|
# naming it. Downloading the archive is not timed: the archive is given. Its PowerShell twin,
|
|
# clean-machine.ps1, runs the same steps from the Windows archive.
|
|
set -uo pipefail
|
|
[ $# -ge 1 ] || { sed -n '2,20p' "$0"; exit 2; }
|
|
ARCHIVE=$(cd "$(dirname "$1")" && pwd)/$(basename "$1")
|
|
BROWSER=0; [ "${2:-}" = --browser ] && BROWSER=1
|
|
HERE=$(cd "$(dirname "$0")" && pwd)
|
|
ROOT=$(mktemp -d)
|
|
export HOME="$ROOT/home" TMPDIR="$ROOT/tmp"
|
|
mkdir -p "$HOME" "$TMPDIR" "$ROOT/work"
|
|
export PATH=/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
|
|
[ "$(uname -s)" = Darwin ] && [ "$BROWSER" = 1 ] && export PATH="/opt/homebrew/bin:$PATH" # node, for the browser step alone
|
|
cd "$ROOT/work"
|
|
now() { python3 -c 'import time; print(time.monotonic())'; }
|
|
T0=$(now)
|
|
steps=() failed=""
|
|
step() { # <name> <command...>
|
|
local name="$1"; shift
|
|
local s; s=$(now)
|
|
if "$@" > "$ROOT/$name.log" 2>&1; then
|
|
steps+=("$name $(python3 -c "print(round($(now) - $s, 2))")")
|
|
else
|
|
steps+=("$name FAILED")
|
|
failed="$name"
|
|
echo "FAIL $name:"; tail -15 "$ROOT/$name.log"
|
|
fi
|
|
}
|
|
unpack() {
|
|
local want; want=$(cut -d' ' -f1 "$ARCHIVE.sha256")
|
|
local got; got=$( (command -v sha256sum > /dev/null && sha256sum "$ARCHIVE" || shasum -a 256 "$ARCHIVE") | cut -d' ' -f1)
|
|
[ "$got" = "$want" ] || { echo "SHA-256 $got, not $want"; return 1; }
|
|
tar -xzf "$ARCHIVE"
|
|
}
|
|
step unpack unpack
|
|
BIN=$(ls -d "$ROOT"/work/wai-*/bin 2>/dev/null | head -1)
|
|
export PATH="$BIN:$PATH"
|
|
says_usage() { # <program> <its exit status>: run alone, it says how it is run
|
|
local s=0; "$1" > /dev/null 2> "$ROOT/$1.err" || s=$?
|
|
[ "$s" = "$2" ] && grep -q usage "$ROOT/$1.err" && grep -q "$1 " "$ROOT/$1.err"
|
|
}
|
|
contents() {
|
|
local b missing=""
|
|
for b in wai wai-relay wai-room wai-ingest wai-remote-host wai-pack wai-quantum; do
|
|
[ -x "$BIN/$b" ] || missing="$missing bin/$b"
|
|
done
|
|
for f in share/wai/web/room/index.html share/wai/studio/index.html share/wai/studio/pkg/wai_studio_core_bg.wasm; do
|
|
[ -f "$BIN/../$f" ] || missing="$missing $f"
|
|
done
|
|
[ -z "$missing" ] || { echo "the archive lacks:$missing"; return 1; }
|
|
wai-quantum --version || return 1
|
|
# wai-ingest and wai-pack alone say how they are run and exit 2; wai-remote-host, 1.
|
|
says_usage wai-ingest 2 || return 1
|
|
says_usage wai-pack 2 || return 1
|
|
says_usage wai-remote-host 1
|
|
}
|
|
[ -z "$failed" ] && step contents contents
|
|
[ -z "$failed" ] && step hello wai hello
|
|
[ -z "$failed" ] && step verify wai verify wai-hello
|
|
[ -z "$failed" ] && step create wai create my-room --template video-room
|
|
# Every piece held, Studio among them: the archive's share/wai/studio, found beside wai.
|
|
[ -z "$failed" ] && step dev-check bash -c 'cd my-room && { wai dev --check --port 0 > ../dev-check.out; s=$?; cat ../dev-check.out; [ "$s" = 0 ] && grep -q "ok WAI Studio at /_wai/" ../dev-check.out; }'
|
|
if [ -z "$failed" ] && [ "$BROWSER" = 1 ]; then
|
|
step two-tabs env WAI_BIN="$BIN/wai" node "$HERE/../../examples/video-room/test/video-room.test.mjs"
|
|
fi
|
|
TOTAL=$(python3 -c "print(round($(now) - $T0, 2))")
|
|
echo "the quickstart from $(basename "$ARCHIVE") on $(uname -sm), a fresh HOME and directory:"
|
|
for s in "${steps[@]}"; do set -- $s; if [ "$2" = FAILED ]; then printf ' %-10s FAILED\n' "$1"; else printf ' %-10s %s s\n' "$1" "$2"; fi; done
|
|
grep -h 'checks held' "$ROOT/dev-check.log" 2>/dev/null | sed 's/^/ /'
|
|
echo " total $TOTAL s${failed:+ (stopped at $failed)}"
|
|
python3 -c 'import json,sys; s=sys.argv[3:]; print(json.dumps({"archive": sys.argv[1], "total_s": float(sys.argv[2]), "steps": dict((x.split()[0], x.split()[1]) for x in s), "ok": all("FAILED" not in x for x in s)}))' "$(basename "$ARCHIVE")" "$TOTAL" "${steps[@]}"
|
|
rm -rf "$ROOT"
|
|
[ -z "$failed" ]
|