#!/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 [--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() { # 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() { # : 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" ]