#!/usr/bin/env bash set -euo pipefail root_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" godot_bin="${GODOT_BIN:-/Applications/Godot.app/Contents/MacOS/Godot}" godot_image="barichello/godot-ci@sha256:622e5ca81b54cd8038ecf7de5d157b47efc800d7cf635af2eec18a6aee4bab7e" run_godot_harness() { if [[ -x "$godot_bin" ]]; then set +e "$godot_bin" --headless --path "$root_dir/Game" res://tests/test_runner.tscn local native_status=$? set -e if [[ "$native_status" -eq 0 ]]; then return fi # A failing test exits 1 and must fail the gate. A signal exit (as seen # with the host Metal/Vulkan stack) is an engine-host failure, so rerun # the identical pinned Linux harness instead of losing all verification. if [[ "$native_status" -lt 128 ]]; then return "$native_status" fi echo "local multiplayer gate: native Godot crashed (status $native_status); using pinned headless fallback" >&2 fi if ! command -v docker >/dev/null 2>&1 || ! docker info >/dev/null 2>&1; then echo "local multiplayer gate: Godot executable not found ($godot_bin), and Docker is unavailable for the pinned headless fallback" >&2 return 2 fi echo "local multiplayer gate: using pinned headless Godot container fallback" docker run --rm --platform linux/amd64 \ --mount "type=bind,src=$root_dir,dst=/workspace" \ -w /workspace "$godot_image" \ godot --headless --path Game res://tests/test_runner.tscn } echo "local multiplayer gate: Go tests" (cd "$root_dir/server" && go test ./...) echo "local multiplayer gate: Go race and vet" (cd "$root_dir/server" && go test -race ./...) (cd "$root_dir/server" && go vet ./...) echo "local multiplayer gate: bounded fuzz targets" (cd "$root_dir/server" && go test ./domain -fuzz FuzzQueueCreateDoesNotPanic -fuzztime=2s) (cd "$root_dir/server" && go test ./domain -fuzz FuzzResultDigestIsDeterministic -fuzztime=2s) (cd "$root_dir/server" && go test ./domain -fuzz FuzzSyncEventApplicationDoesNotPanic -fuzztime=2s) echo "local multiplayer gate: Godot harness" run_godot_harness echo "local multiplayer gate: contracts and manifests" python3 -m json.tool "$root_dir/server/contracts/v1/openapi.json" >/dev/null # json.tool only proves the contract parses. test_contracts.py is what actually # checks the operation IDs, envelopes and state vocabulary generated clients # bind to; it was previously not run by any target, so a real mismatch between # openapi.json and the suite sat undetected. python3 "$root_dir/server/contracts/v1/test_contracts.py" python3 "$root_dir/server/migrations/test_migration.py" python3 "$root_dir/server/security/test_fleet_manifests.py" python3 "$root_dir/server/security/test_compose_manifests.py" python3 "$root_dir/server/security/test_kubernetes_policies.py" python3 "$root_dir/server/security/test_supply_chain.py" python3 "$root_dir/server/security/test_threat_model.py" python3 "$root_dir/scripts/verify_observability_manifests.py" # The checker above validates the checked-in manifests; this validates the # checker itself still rejects a widened scrape scope. python3 "$root_dir/server/security/test_observability_manifests.py" python3 -m unittest "$root_dir/scripts/test_verify_agones_allocation_response.py" echo "LOCAL MULTIPLAYER GATE PASS"