initial commit
Some checks failed
ci / go (push) Has been cancelled
ci / admin-ui (push) Has been cancelled
ci / runtime-sdk (push) Has been cancelled
ci / helm (push) Has been cancelled
ci / openapi (push) Has been cancelled
ci / container (push) Has been cancelled
ci / release-config (push) Has been cancelled
ci / shared styling (push) Has been cancelled
ci / security (push) Has been cancelled
ci / all green (push) Has been cancelled
Some checks failed
ci / go (push) Has been cancelled
ci / admin-ui (push) Has been cancelled
ci / runtime-sdk (push) Has been cancelled
ci / helm (push) Has been cancelled
ci / openapi (push) Has been cancelled
ci / container (push) Has been cancelled
ci / release-config (push) Has been cancelled
ci / shared styling (push) Has been cancelled
ci / security (push) Has been cancelled
ci / all green (push) Has been cancelled
This commit is contained in:
commit
951dd8d26b
175 changed files with 50041 additions and 0 deletions
153
hack/check-pilot-go-loose.sh
Executable file
153
hack/check-pilot-go-loose.sh
Executable file
|
|
@ -0,0 +1,153 @@
|
|||
#!/usr/bin/env bash
|
||||
#
|
||||
# Pilot check: go-loose consuming the shared contract.
|
||||
#
|
||||
# This is the test that decides whether the consolidation is real. It loads go-loose's
|
||||
# *actual* index.html and its *actual* hand-written style.css, with only the theme
|
||||
# origin substituted exactly as go-loose's server does it, and then asks the question
|
||||
# that matters:
|
||||
#
|
||||
# Do the components shipped by go-bananas change the attributes that go-loose's own
|
||||
# CSS already keys on, so go-loose is themed without a single edit to its stylesheet?
|
||||
#
|
||||
# If that is true, adoption is one <link> and one <script> per page, which is what
|
||||
# ADR 0005 claims. If it is false, the contract is decoration.
|
||||
#
|
||||
# It does not boot go-loose: that needs a database and a first-run installer, and
|
||||
# neither is what is being tested. What is being tested is the page and the stylesheet.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
LOOSE="${GO_LOOSE_DIR:-/home/dnoulet/go/go-loose}"
|
||||
WORK="$(mktemp -d)"
|
||||
PORT="${PORT:-8398}"
|
||||
THEME_PORT="${THEME_PORT:-8397}"
|
||||
CHROME="${CHROME:-$(command -v chromium || command -v chromium-browser || command -v google-chrome || true)}"
|
||||
|
||||
cleanup() {
|
||||
for pid in "${SERVER_PID:-}" "${THEME_PID:-}"; do
|
||||
[[ -n "$pid" ]] && kill "$pid" 2>/dev/null || true
|
||||
done
|
||||
echo "WORK=$WORK" >/tmp/pilot-work-dir; rm -rf "$WORK"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
[[ -d "$LOOSE/web" ]] || { echo "go-loose not found at $LOOSE; set GO_LOOSE_DIR" >&2; exit 1; }
|
||||
[[ -n "$CHROME" ]] || { echo "no chromium found; set CHROME" >&2; exit 1; }
|
||||
|
||||
echo "==> building go-bananas and the SDK"
|
||||
# The SDK is built first, then the server that embeds it. The other order compiles a
|
||||
# binary containing whatever sdk/dist happened to contain when the pilot last ran,
|
||||
# which 404s /rt/v1/components.js — and the check used not to notice, because it loaded
|
||||
# the module from its own copy instead of from the service.
|
||||
(cd "$ROOT/sdk" && npm run build >/dev/null)
|
||||
(cd "$ROOT" && go build -o "$WORK/go-bananas" ./cmd/go-bananas)
|
||||
|
||||
mkdir -p "$WORK/site" "$WORK/site/assets"
|
||||
|
||||
# go-loose's own files with the theme origin substituted the way its server does it.
|
||||
# This is the only transformation: nothing in its stylesheet or markup is edited.
|
||||
echo "==> assembling go-loose's page"
|
||||
THEME_ORIGIN="http://localhost:$THEME_PORT"
|
||||
export LOOSE_WEB="$LOOSE/web" SITE="$WORK/site" THEME_ORIGIN
|
||||
python3 - <<'PY'
|
||||
import os, re
|
||||
|
||||
src = os.environ['LOOSE_WEB']
|
||||
out = os.environ['SITE']
|
||||
origin = os.environ['THEME_ORIGIN']
|
||||
|
||||
html = open(os.path.join(src, 'index.html')).read().replace('__GO_LOOSE_THEME_ORIGIN__', origin)
|
||||
|
||||
# Nothing is rewritten to a local copy any more. The module used to be pointed at a
|
||||
# copy under /assets/ so that the check would not depend on CORS being configured, and
|
||||
# that is exactly what hid the bug this now covers: the service sent no CORS headers,
|
||||
# so in a real deployment the ES module could not be fetched and the control rendered
|
||||
# empty, while the pilot passed against its own copy. A module <script> is always
|
||||
# fetched under CORS rules, so the only way to test the deployed path is to load it
|
||||
# from the service.
|
||||
|
||||
# The reporter is appended to the *copy*. go-loose's source is never edited.
|
||||
if 'id="pilot"' not in html:
|
||||
html = html.replace('</body>', ' <script type="module" src="/pilot.js"></script>\n</body>')
|
||||
|
||||
open(os.path.join(out, 'index.html'), 'w').write(html)
|
||||
|
||||
# go-loose serves its own files under /assets/, so they belong in site/assets/ rather
|
||||
# than at the site root. Getting this wrong 404s every one of them while leaving the
|
||||
# page looking merely unstyled.
|
||||
assets = os.path.join(out, 'assets')
|
||||
os.makedirs(assets, exist_ok=True)
|
||||
for name in ('style.css', 'app.js', 'account.js', 'roles.js', 'profile.js'):
|
||||
p = os.path.join(src, name)
|
||||
if os.path.exists(p):
|
||||
open(os.path.join(assets, name), 'w').write(open(p).read())
|
||||
PY
|
||||
sed "s#from '/rt/v1/components.js'#from '$THEME_ORIGIN/rt/v1/components.js'#" \
|
||||
"$ROOT/hack/pilot-go-loose.js" > "$WORK/site/pilot.js"
|
||||
|
||||
echo "==> starting the theme service on :$THEME_PORT"
|
||||
# The selector fetches contract.json, and this page is on a different origin from the
|
||||
# service. A cross-origin module fetch and a JSON fetch both need the consuming
|
||||
# origin in CORS_ALLOWED_ORIGINS; a same-origin deployment needs nothing here. That is
|
||||
# the one setting adopting the contract requires, and setting it here is what proves it
|
||||
# is sufficient.
|
||||
DATABASE_PATH="$WORK/pilot.db" \
|
||||
BANANAS_ENVIRONMENT=development \
|
||||
BANANAS_AUTH_MODE=dev \
|
||||
BANANAS_PUBLIC_BASE_URL="$THEME_ORIGIN" \
|
||||
BANANAS_HTTP_ADDR=":$THEME_PORT" \
|
||||
BANANAS_SDK_DIR="$WORK/site/assets" \
|
||||
BANANAS_CORS_ALLOWED_ORIGINS="http://localhost:$PORT" \
|
||||
"$WORK/go-bananas" >"$WORK/theme.log" 2>&1 &
|
||||
THEME_PID=$!
|
||||
|
||||
for _ in $(seq 1 40); do
|
||||
curl -fsS -m 2 "http://localhost:$THEME_PORT/healthz" >/dev/null 2>&1 && break
|
||||
sleep 0.25
|
||||
done
|
||||
|
||||
echo "==> serving go-loose's page on :$PORT"
|
||||
(cd "$WORK/site" && exec python3 -m http.server "$PORT") >"$WORK/site.log" 2>&1 &
|
||||
SERVER_PID=$!
|
||||
for _ in $(seq 1 40); do
|
||||
curl -fsS -m 2 "http://localhost:$PORT/index.html" >/dev/null 2>&1 && break
|
||||
sleep 0.25
|
||||
done
|
||||
|
||||
echo "==> driving the page"
|
||||
"$CHROME" \
|
||||
--headless --no-sandbox --disable-gpu \
|
||||
--virtual-time-budget=12000 \
|
||||
--dump-dom "http://localhost:$PORT/index.html" \
|
||||
>"$WORK/dom.html" 2>"$WORK/chrome.log"
|
||||
|
||||
result="$(python3 - "$WORK/dom.html" <<'PY'
|
||||
import re, sys
|
||||
dom = open(sys.argv[1]).read()
|
||||
m = re.search(r'id="pilot"[^>]*>(.*?)</pre>', dom, re.S)
|
||||
print(m.group(1).strip() if m else "")
|
||||
PY
|
||||
)"
|
||||
|
||||
if [[ -z "$result" ]]; then
|
||||
echo "PILOT FAIL: the page recorded nothing, so the check did not run." >&2
|
||||
echo "the reporter most likely threw; diagnostics follow." >&2
|
||||
echo "--- browser console ---" >&2
|
||||
grep -iE 'CONSOLE.*(error|Uncaught|violates|refused)' "$WORK/chrome.log" | head -5 >&2 || true
|
||||
echo "--- dom size / page head ---" >&2
|
||||
wc -c <"$WORK/dom.html" >&2 || true
|
||||
head -c 300 "$WORK/dom.html" >&2 || true
|
||||
echo >&2
|
||||
echo "--- static server 404s ---" >&2
|
||||
grep -oE 'GET /[^"]*" 404' "$WORK/site.log" | head -5 >&2 || true
|
||||
echo "--- pilot element ---" >&2
|
||||
grep -o 'id="pilot"[^<]*' "$WORK/dom.html" | head -2 >&2 || true
|
||||
echo "--- theme service log (last 5) ---" >&2
|
||||
tail -5 "$WORK/theme.log" >&2 || true
|
||||
fi
|
||||
|
||||
echo
|
||||
echo "$result"
|
||||
[[ "$result" == PILOT\ PASS* ]]
|
||||
Loading…
Add table
Add a link
Reference in a new issue