Files
cobblemon-survival-pack/tools/selftest.py
T
claudeandClaude Opus 5.5 398301f0be Cobblemon Survival Pack: phases 0-2 and Phase 3 zones and hazards
Free NeoForge 1.21.1 modpack on Cobblemon 1.8.4 built with packwiz, plus
the Kotlin companion mod (cobblesurvival) and its built-in data pack.

- Phase 0: packwiz pack with Modrinth/CurseForge cross-links, build and
  export tooling, Prism instance sync, test server with smoke checks.
- Phase 1: Poke Ball shaped island (WorldGen Editor preset, seed isle-26),
  Adrian's biome list, no natural ore, structures without ore or vanilla
  mobs, no Nether portals, world template builder and world report.
- Phase 2: permadeath (CobbleHardcoreMon plus the companion mod's gap
  fixes), Revival Charm, expensive Healing Machine, Lootr refreshing
  loot, in-game self-tests on Minecraft's GameTest framework.
- Phase 3 so far: 14 zones with their own spawn pools and level bands
  (tools/zone_layout.py, tools/zone_spawns.py, "zone" spawn condition),
  Cold Sweat heat and cold as gates with boss-drop insulation recipes,
  spawn survey and hazard self-tests in tools/quick_check.py.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-10-29 19:01:21 +01:00

60 lines
2.5 KiB
Python
Executable File

#!/usr/bin/env python3
"""Run the companion mod's in-game tests on their own: one server boot on a fresh flat
world, `/cobblesurvival selftest run`, wait for the results, stop, scan the log.
The tests (mod/src/main/kotlin/dev/cobblesurvival/selftest/) play real situations on the
live server with every mod and config of the pack, e.g. the permadeath matrix: Pokémon
fainting from a fall, lava, poison, in wild and trainer battles, with and without a
Revival Charm. tools/quick_check.py runs them too; this is the faster loop while
working on them.
Usage: tools/selftest.py [--accept-eula] (run tools/build.py first)
"""
import argparse
import shutil
import sys
import time
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent))
from mcserver import SELFTEST_JVM_ARGS, SERVER, Server, eula_accepted, prepare, scan_log # noqa: E402
LEVEL = "selftest"
def main():
parser = argparse.ArgumentParser(description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
parser.add_argument("--accept-eula", action="store_true", help="write eula=true for the test server")
args = parser.parse_args()
if args.accept_eula:
(SERVER / "eula.txt").parent.mkdir(parents=True, exist_ok=True)
(SERVER / "eula.txt").write_text("eula=true\n")
elif not eula_accepted():
sys.exit("build/server/eula.txt does not accept the Minecraft EULA yet; pass --accept-eula if you accept it.")
started = time.time()
args_file = prepare()
shutil.rmtree(SERVER / LEVEL, ignore_errors=True)
flat = '{"layers":[{"block":"minecraft:bedrock","height":1},{"block":"minecraft:stone","height":3},' \
'{"block":"minecraft:grass_block","height":1}],"biome":"minecraft:plains"}'
props = {"level-name": LEVEL, "level-type": "minecraft:flat", "generator-settings": flat}
failures = []
with Server(args_file, props, stdout_name="selftest-stdout.log", jvm_args=SELFTEST_JVM_ARGS) as server:
try:
print(f"server started in {server.wait_ready():.0f}s")
failures += server.run_selftest()
server.stop()
except Exception as e: # report; the context manager still kills the process
failures.append(f"{type(e).__name__}: {e}")
failures += [f"log: {line}" for line in scan_log(server.log)]
print(f"\nselftest took {time.time() - started:.0f}s")
if failures:
print("SELFTEST FAILED")
print("\n".join(f" - {f}" for f in failures))
sys.exit(1)
print("SELFTEST PASSED")
if __name__ == "__main__":
main()