Something went wrong. Try again.
Backend environment for match hosting for lance.blue
Something went wrong. Try again.
Shell
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151#!/usr/bin/env bash# upload() has one path: ask headquarters to sign a PUT and send the bytes# straight to S3. There is no fallback through headquarters' own API any more,# so what these cases pin down is that the direct route stays unused - including# when a manifest still offers one, and when signing fails. Buffering whole# artifacts in a 512MB instance was the thing being removed, and it would come# back invisibly.## tests/upload-stub.py plays both ends, so this needs no AWS and no network.set -uo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"TMP="$(mktemp -d)"STUB_PID=""cleanup() { [ -n "$STUB_PID" ] && kill "$STUB_PID" 2>/dev/null rm -rf "$TMP"}trap cleanup EXIT
fail=0check() { # <description> <test-command...> if "${@:2}"; then echo "ok $1"; else echo "FAIL $1"; fail=1; fi}
echo ok > "$TMP/mint-mode": > "$TMP/requests"python3 "$ROOT/tests/upload-stub.py" "$TMP" &STUB_PID=$!for _ in $(seq 50); do [ -s "$TMP/port" ] && break; sleep 0.1; done[ -s "$TMP/port" ] || { echo "FAIL the stub never bound a port"; exit 1; }BASE="http://127.0.0.1:$(cat "$TMP/port")"
echo 'a line of client log' > "$TMP/megamek.log"
# Only .upload matters here; mq reads the rest of the manifest for other callers.manifest() { # <json object for .upload> printf '{"matchId":"m1","upload":%s}\n' "$1" > "$TMP/manifest.json"}
# Source common.sh in a child shell so each case starts from a clean state.run_upload() { # <key> MANIFEST="$TMP/manifest.json" ARENA_LOG_TAG=test \ bash -c 'set -uo pipefail; . "$0"; upload "$1" "$2"' \ "$ROOT/container/lib/common.sh" "$TMP/megamek.log" "$1" 2>&1}
both_targets="{\"diagnostics\":{\"method\":\"PUT\",\\"urlTemplate\":\"$BASE/api/{name}\",\"signTemplate\":\"$BASE/sign/{name}\"}}"
# --- a manifest still offering a direct target: it is ignored ---------------# This is the deploy order arena has to survive: it ships before headquarters# drops urlTemplate, so both fields arrive and only the signing one is read.manifest "$both_targets"signed_out="$(run_upload diagnostics)"; status=$?
check "a signed upload succeeds" test "$status" -eq 0check "the signing endpoint was asked for this artifact by name" \ grep -qx 'POST /sign/megamek.log' "$TMP/requests"check "the bytes went to the signed destination" \ grep -qx 'PUT /s3/megamek.log' "$TMP/requests"# The whole point of the change: nothing reaches the API's own route, even# though this manifest hands it one.check "and not through the API" \ bash -c "! grep -q '^PUT /api/' '$TMP/requests'"# A minted URL is a bearer credential for that key. common.sh's own rules say# log field names, not values - and curl quotes URLs in its error text, which is# why mint_upload_url drops curl's stderr.check "the signed URL never reaches the log" \ bash -c "! grep -q '/s3/' <<<\"\$1\"" _ "$signed_out"
# --- minting fails: the upload fails with it --------------------------------# It used to fall back to the API. Losing the artifact is the deliberate cost of# not having a slow route that can come back unnoticed - and the failure is in# the log, where reverting to the API was not.echo fail > "$TMP/mint-mode": > "$TMP/requests"out="$(run_upload diagnostics)"; status=$?
check "a minting failure fails the upload" test "$status" -ne 0check "and says which key it was for" grep -q "could not mint an upload URL for 'diagnostics'" <<<"$out"check "and nothing is sent through the API" \ bash -c "! grep -q '^PUT ' '$TMP/requests'"check "with nothing claiming the file was uploaded" \ bash -c "! grep -q 'uploaded megamek.log' <<<\"\$1\"" _ "$out"
# --- a manifest with a direct target and nothing to sign with ---------------# What an older headquarters sends. There is no route for it now, so the file is# kept rather than pushed through the API. 10-manifest.sh refuses such a# manifest at container start; this is upload() holding the line anyway.echo ok > "$TMP/mint-mode": > "$TMP/requests"manifest "{\"diagnostics\":{\"method\":\"PUT\",\"urlTemplate\":\"$BASE/api/{name}\"}}"out="$(run_upload diagnostics)"; status=$?
check "a manifest with no signing target uploads nothing" test "$status" -ne 0check "and does not try to mint" bash -c "! grep -q '^POST ' '$TMP/requests'"check "and does not fall back to the direct target it was given" \ test ! -s "$TMP/requests"
# --- no target at all -------------------------------------------------------# The state every diagnostics artifact was in before headquarters carried the# key: the file is kept, and upload() reports that it did not send it.: > "$TMP/requests"manifest '{}'out="$(run_upload diagnostics)"; status=$?
check "no target at all fails rather than looking sent" test "$status" -ne 0check "and names the key that had none" \ grep -q "no upload target for 'diagnostics'" <<<"$out"check "having sent nothing anywhere" test ! -s "$TMP/requests"
# --- the layout keys, and the ones they replaced ------------------------------# headquarters names the layout, so an image that knows `raw/` has to work# against a control plane that has not deployed it yet, and vice versa. Each# caller names the key it wants and the key that layout replaced.run_class() { # <key> <name> <legacy-key> <legacy-name> MANIFEST="$TMP/manifest.json" ARENA_LOG_TAG=test \ bash -c 'set -uo pipefail; . "$0"; upload_class "$1" "$2" "$3" "$4" "$5"' \ "$ROOT/container/lib/common.sh" "$TMP/megamek.log" "$1" "$2" "$3" "$4" 2>&1}
: > "$TMP/requests"manifest "{\"socials\":{\"signTemplate\":\"$BASE/sign/derived/socials/{name}\"},\\"screenshots\":{\"signTemplate\":\"$BASE/sign/shots/{name}\"}}"out="$(run_class socials share-card.png screenshots share-card.png)"
check "a manifest that knows the layout uses it" \ grep -qx 'POST /sign/derived/socials/share-card.png' "$TMP/requests"check "and does not also write the old name" bash -c \ "! grep -qx 'POST /sign/shots/share-card.png' \"\$1/requests\"" _ "$TMP"
: > "$TMP/requests"manifest "{\"screenshots\":{\"signTemplate\":\"$BASE/sign/shots/{name}\"}}"out="$(run_class socials share-card.png screenshots share-card.png)"
check "a manifest without it falls back" \ grep -qx 'POST /sign/shots/share-card.png' "$TMP/requests"
# An artifact with no older home is skipped rather than misfiled: there is no# right place for MegaMek's action log in a layout that predates `raw/`.: > "$TMP/requests"out="$(MANIFEST="$TMP/manifest.json" ARENA_LOG_TAG=test \ bash -c 'set -uo pipefail; . "$0"; upload_class "$1" raw game_actions_0.tsv' \ "$ROOT/container/lib/common.sh" "$TMP/megamek.log" 2>&1)"check "an artifact with no older home is not misfiled" bash -c \ "! grep -q 'POST /sign' \"\$1/requests\"" _ "$TMP"check "and says which key had no target" grep -q "no upload target for 'raw'" <<<"$out"
exit "$fail"