smoke: qa-wasp P3 + economy/headless runners
This commit is contained in:
parent
0b3d835963
commit
3046782474
5 changed files with 166 additions and 0 deletions
38
scripts/smoke/economy_smoke.py
Executable file
38
scripts/smoke/economy_smoke.py
Executable file
|
|
@ -0,0 +1,38 @@
|
|||
#!/usr/bin/env python3
|
||||
"""Short Pitch economy scenario — start 500, claim well, 10s seep, assert gain."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
if str(ROOT) not in sys.path:
|
||||
sys.path.insert(0, str(ROOT))
|
||||
|
||||
from game.sim.pitch_economy import Economy, SEEP_PER_SEC, START_PITCH
|
||||
|
||||
|
||||
def main() -> int:
|
||||
eco = Economy()
|
||||
assert eco.pitch == START_PITCH, f"start pitch want {START_PITCH} got {eco.pitch}"
|
||||
|
||||
well = eco.add_well()
|
||||
well.claim_via_refinery()
|
||||
assert well.claimed and well.has_refinery
|
||||
|
||||
before = eco.pitch
|
||||
eco.tick(10.0) # 10 simulated seconds of seep (GAMEPLAY.md +0.4/s)
|
||||
expected = before + SEEP_PER_SEC * 10.0
|
||||
if eco.pitch <= before:
|
||||
print(f"FAIL: pitch did not increase ({before} -> {eco.pitch})")
|
||||
return 1
|
||||
if abs(eco.pitch - expected) > 1e-9:
|
||||
print(f"FAIL: pitch {eco.pitch} != expected {expected}")
|
||||
return 1
|
||||
print(f"PASS: pitch {before} -> {eco.pitch} after 10s claimed seep")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
74
scripts/smoke/headless_smoke.sh
Executable file
74
scripts/smoke/headless_smoke.sh
Executable file
|
|
@ -0,0 +1,74 @@
|
|||
#!/usr/bin/env bash
|
||||
# Headless Pitchwell smoke — no Godot GUI. docs/GAMEPLAY.md: 20 Hz sim, seep +0.4/s.
|
||||
set -euo pipefail
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
N_TICKS="${1:-40}"
|
||||
HZ=20
|
||||
# GAMEPLAY.md Economy: Sump Wells slow seep (+0.4/s while claimed)
|
||||
SEEP_PER_S=0.4
|
||||
# GAMEPLAY.md Match open: HQ + 4 workers, 500 Pitch start
|
||||
START_PITCH=500
|
||||
DT="$(python3 -c "print(1.0/${HZ})")"
|
||||
|
||||
STUB="${ROOT}/assets/cinematics/first-contact/out/first-contact-stub.mp4"
|
||||
|
||||
fail() {
|
||||
echo "SMOKE FAIL $*" >&2
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Optional cinematic probe (GAMEPLAY.md: briefings ≥1280×720)
|
||||
if [[ -f "${STUB}" ]]; then
|
||||
if command -v ffprobe >/dev/null 2>&1; then
|
||||
wh="$(ffprobe -v error -select_streams v:0 -show_entries stream=width,height -of csv=p=0 "${STUB}" || true)"
|
||||
w="${wh%%,*}"; h="${wh##*,}"
|
||||
if [[ "${w}" != "1280" || "${h}" != "720" ]]; then
|
||||
fail "stub ${STUB} size ${w}x${h} want 1280x720"
|
||||
fi
|
||||
else
|
||||
echo "SMOKE WARN ffprobe missing; skip stub size check" >&2
|
||||
fi
|
||||
fi
|
||||
|
||||
# Pure-Python 20 Hz tick loop: match open — HQ exists, claimed well seeps Pitch
|
||||
OUT="$(
|
||||
N_TICKS="${N_TICKS}" HZ="${HZ}" SEEP_PER_S="${SEEP_PER_S}" START_PITCH="${START_PITCH}" DT="${DT}" python3 - <<'PY'
|
||||
import os, sys
|
||||
|
||||
n = int(os.environ["N_TICKS"])
|
||||
hz = int(os.environ["HZ"])
|
||||
seep = float(os.environ["SEEP_PER_S"])
|
||||
pitch = float(os.environ["START_PITCH"])
|
||||
dt = float(os.environ["DT"])
|
||||
|
||||
hq_alive = True
|
||||
well_claimed = True # conceptual: refinery radius holds seep (GAMEPLAY.md)
|
||||
|
||||
if n < 1:
|
||||
print("bad N_TICKS", n, file=sys.stderr)
|
||||
sys.exit(2)
|
||||
|
||||
for t in range(n):
|
||||
if not hq_alive:
|
||||
print("HQ dead mid-sim", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
if well_claimed:
|
||||
pitch += seep * dt # +0.4 Pitch/s → +0.02/tick at 20 Hz
|
||||
|
||||
# Expect: start 500 + N*(0.4/20)
|
||||
expect = float(os.environ["START_PITCH"]) + n * (seep / hz)
|
||||
# float tolerance
|
||||
if abs(pitch - expect) > 1e-6:
|
||||
print(f"pitch {pitch} != expect {expect}", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
if not hq_alive:
|
||||
print("HQ missing", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
print(f"ticks={n} hz={hz} pitch={pitch:.4f} hq=1 seep={seep}/s")
|
||||
PY
|
||||
)" || fail "sim ${OUT}"
|
||||
|
||||
echo "SMOKE PASS headless ${OUT}"
|
||||
exit 0
|
||||
22
scripts/smoke/run_all.sh
Executable file
22
scripts/smoke/run_all.sh
Executable file
|
|
@ -0,0 +1,22 @@
|
|||
#!/usr/bin/env bash
|
||||
# Aggregate Deltoid smokes — OpenKKnD / Pitchwell. No git push.
|
||||
set -euo pipefail
|
||||
ROOT="$(cd "$(dirname "$0")/../.." && pwd)"
|
||||
cd "$ROOT"
|
||||
fail=0
|
||||
|
||||
run() {
|
||||
echo "== $* =="
|
||||
"$@" || fail=1
|
||||
}
|
||||
|
||||
[[ -x scripts/smoke/headless_smoke.sh ]] && run scripts/smoke/headless_smoke.sh
|
||||
[[ -x scripts/smoke/ip_fence_check.sh ]] && run scripts/smoke/ip_fence_check.sh
|
||||
[[ -f scripts/smoke/economy_smoke.py ]] && run python3 scripts/smoke/economy_smoke.py
|
||||
|
||||
if [[ "$fail" -eq 0 ]]; then
|
||||
echo "RUN_ALL PASS"
|
||||
else
|
||||
echo "RUN_ALL FAIL" >&2
|
||||
fi
|
||||
exit "$fail"
|
||||
Loading…
Add table
Add a link
Reference in a new issue