Validate the actual hmod in the pinned host sandbox (#102)
build / mod (push) Failing after 19s
build / mod (push) Failing after 19s
Keep runtime compilation in an opt-in CI tier; run asset consistency on regular builds. Sandbox checks do not substitute for GPU, capture or maximum-scenario budgets. Co-Authored-By: Codex <noreply@openai.com>
This commit is contained in:
@@ -32,6 +32,8 @@ jobs:
|
|||||||
run: nice -n 19 python3 tools/airdef.py fork
|
run: nice -n 19 python3 tools/airdef.py fork
|
||||||
- name: Проверка закреплённого checkout
|
- name: Проверка закреплённого checkout
|
||||||
run: python3 -m unittest discover -s tools -p test_engine_checkout.py
|
run: python3 -m unittest discover -s tools -p test_engine_checkout.py
|
||||||
|
- name: Проверка generated assets
|
||||||
|
run: python3 tools/gen_models.py --check
|
||||||
- name: Тесты ядра без SDK
|
- name: Тесты ядра без SDK
|
||||||
working-directory: airdef-core
|
working-directory: airdef-core
|
||||||
run: |
|
run: |
|
||||||
|
|||||||
@@ -0,0 +1,20 @@
|
|||||||
|
# Heavy sandbox runtime is opt-in on the shared 2-core runner.
|
||||||
|
name: wasm-contract
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
env:
|
||||||
|
CARGO_BUILD_JOBS: "1"
|
||||||
|
CARGO_INCREMENTAL: "0"
|
||||||
|
jobs:
|
||||||
|
contract:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
with:
|
||||||
|
submodules: recursive
|
||||||
|
- name: Rust
|
||||||
|
run: |
|
||||||
|
curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --target wasm32-unknown-unknown
|
||||||
|
echo "$HOME/.cargo/bin" >> "$GITHUB_PATH"
|
||||||
|
- name: Actual WASM contract
|
||||||
|
run: nice -n 19 python3 tools/airdef.py test-wasm
|
||||||
@@ -0,0 +1,46 @@
|
|||||||
|
# Actual .hmod in the engine sandbox, with default fuel/memory limits.
|
||||||
|
# Missing render replies exercise fallback paths, not GPU correctness.
|
||||||
|
[[step]]
|
||||||
|
ticks = 2
|
||||||
|
frames = 2
|
||||||
|
expect.commands = ["airdef"]
|
||||||
|
|
||||||
|
[[step]]
|
||||||
|
command = "airdef deploy patriot"
|
||||||
|
|
||||||
|
[[step]]
|
||||||
|
command = "airdef deploy s400"
|
||||||
|
|
||||||
|
[[step]]
|
||||||
|
command = "airdef wave mix 40 1500"
|
||||||
|
|
||||||
|
[[step]]
|
||||||
|
ticks = 240
|
||||||
|
frames = 120
|
||||||
|
|
||||||
|
[[step]]
|
||||||
|
command = "airdef clear"
|
||||||
|
|
||||||
|
[[step]]
|
||||||
|
ticks = 140
|
||||||
|
frames = 10
|
||||||
|
|
||||||
|
[[step]]
|
||||||
|
command = "airdef replay stop"
|
||||||
|
|
||||||
|
[[step]]
|
||||||
|
title-screen = true
|
||||||
|
ticks = 2
|
||||||
|
frames = 2
|
||||||
|
|
||||||
|
[[step]]
|
||||||
|
player = { x = 100.5, y = 64.0, z = 100.5 }
|
||||||
|
clock = { game-time = 500, day-time = 6000 }
|
||||||
|
ticks = 3
|
||||||
|
frames = 3
|
||||||
|
|
||||||
|
[[step]]
|
||||||
|
reload = true
|
||||||
|
ticks = 2
|
||||||
|
frames = 2
|
||||||
|
expect.commands = ["airdef"]
|
||||||
@@ -38,3 +38,16 @@ python tools/airdef.py play
|
|||||||
Рядом с airdef.hmod записывается build-identity.json: SHA AirDef, pin/identity движка,
|
Рядом с airdef.hmod записывается build-identity.json: SHA AirDef, pin/identity движка,
|
||||||
SHA256 WIT и артефакта. API-диагностика остаётся в `python tools/airdef.py check`.
|
SHA256 WIT и артефакта. API-диагностика остаётся в `python tools/airdef.py check`.
|
||||||
Нативные тесты не заменяют отдельную игровую проверку графики, звука и экспорта.
|
Нативные тесты не заменяют отдельную игровую проверку графики, звука и экспорта.
|
||||||
|
|
||||||
|
## Проверка настоящего WASM
|
||||||
|
|
||||||
|
`python tools/airdef.py test-wasm` собирает `.hmod` и запускает `tests/*.toml` в настоящем
|
||||||
|
runtime закреплённого движка. Используется временное storage; игровые миры не нужны.
|
||||||
|
Сценарий проверяет загрузку/регистрацию команды, два комплекса, налёт, tick/frame,
|
||||||
|
выход из мира и перезагрузку мода. Действуют лимиты runtime: 64 MiB linear memory,
|
||||||
|
300 млн fuel на tick, 10 млн на frame, 1 млрд на event, 2 млрд на init.
|
||||||
|
Это проверка ABI и fallback при отсутствии render replies; она не измеряет GPU,
|
||||||
|
не подтверждает акустику/MP4 и не заменяет максимальный боевой полигон.
|
||||||
|
|
||||||
|
В CI проверка assets входит в лёгкий build. Wasmtime tier вынесен в ручной workflow
|
||||||
|
`wasm-contract`, чтобы не компилировать тяжёлый runtime на каждом push слабого общего runner.
|
||||||
|
|||||||
+13
-1
@@ -8,6 +8,7 @@
|
|||||||
python3 tools/airdef.py play [аргументы игры] # запустить форк на папке игры
|
python3 tools/airdef.py play [аргументы игры] # запустить форк на папке игры
|
||||||
python3 tools/airdef.py all # всё по порядку: fork, game, mod, install
|
python3 tools/airdef.py all # всё по порядку: fork, game, mod, install
|
||||||
python3 tools/airdef.py check # совпадают ли форк, упаковщик, уровень API мода и ресурсы
|
python3 tools/airdef.py check # совпадают ли форк, упаковщик, уровень API мода и ресурсы
|
||||||
|
python3 tools/airdef.py test-wasm # собрать и прогнать настоящий .hmod в песочнице без GPU
|
||||||
|
|
||||||
Переменные окружения: HORIZON_HOME (папка игры), HORIZON_RESOURCES (подготовленные ресурсы
|
Переменные окружения: HORIZON_HOME (папка игры), HORIZON_RESOURCES (подготовленные ресурсы
|
||||||
Minecraft 26.3), AIRDEF_GAME (готовый horizon-client вместо собранного).
|
Minecraft 26.3), AIRDEF_GAME (готовый horizon-client вместо собранного).
|
||||||
@@ -138,6 +139,17 @@ def hmod() -> Path:
|
|||||||
sys.exit("Нет airdef.hmod: python3 tools/airdef.py mod")
|
sys.exit("Нет airdef.hmod: python3 tools/airdef.py mod")
|
||||||
|
|
||||||
|
|
||||||
|
def test_wasm():
|
||||||
|
"""The real component and host ABI, with the engine's normal fuel/memory limits."""
|
||||||
|
mod()
|
||||||
|
build_env = dict(os.environ)
|
||||||
|
build_env["PATH"] = str(Path(cargo()).parent) + os.pathsep + build_env.get("PATH", "")
|
||||||
|
# `full` is the packer's default feature; the lightweight release packer has no runtime.
|
||||||
|
run([cargo(), "run", "--locked", "--manifest-path", FORK / "Cargo.toml",
|
||||||
|
"-p", "cargo-horizon-mod", "--", "horizon-mod", "test", "--hmod", hmod()],
|
||||||
|
cwd=ROOT / "airdef-mod", env=build_env)
|
||||||
|
|
||||||
|
|
||||||
def install():
|
def install():
|
||||||
home = game_home()
|
home = game_home()
|
||||||
mods = home / "horizon-mods"
|
mods = home / "horizon-mods"
|
||||||
@@ -281,7 +293,7 @@ def main():
|
|||||||
if len(sys.argv) < 2:
|
if len(sys.argv) < 2:
|
||||||
sys.exit(__doc__)
|
sys.exit(__doc__)
|
||||||
cmd, rest = sys.argv[1], sys.argv[2:]
|
cmd, rest = sys.argv[1], sys.argv[2:]
|
||||||
steps = {"fork": fork, "game": game, "mod": mod, "install": install, "check": check}
|
steps = {"fork": fork, "game": game, "mod": mod, "install": install, "check": check, "test-wasm": test_wasm}
|
||||||
if cmd == "play":
|
if cmd == "play":
|
||||||
play(rest)
|
play(rest)
|
||||||
elif cmd == "all":
|
elif cmd == "all":
|
||||||
|
|||||||
Reference in New Issue
Block a user