Skip to main content

Crate foch_runner

Crate foch_runner 

Source
Expand description

Runs Foch test bundles against a real EU4 install, in isolation.

The install stays read-only: the runner builds a short-path runtime layer that copies the executable and loose files and links the large data directories, then launches the copied eu4.exe with a throwaway user directory holding only the source mod and the generated test layer. It never launches through Steam and never writes the player’s own profile.

The player’s real EU4 user directory is kept intact by backing up the few files the game rewrites and restoring them if their contents change (the game may still touch their modification time). A stronger in-process redirect was tried and dropped; see notes/research/eu4-headless-testing.md and the CreateFileW-redirect route noted there. The caller turns a SessionOutcome into a foch_test::RunArtifacts for judging; this crate performs the I/O that foch-test deliberately does not.

Modules§

layout
Pure helpers for assembling a runtime layer and reading its logs.

Structs§

DependencyMod
A mod the mod under test declares a dependency on, resolved to its installed directory. Loaded read-only before the source mod so the mod’s content that relies on it resolves.
Installation
The game installation to launch and where to stage the throwaway runtime.
RunOptions
Everything that varies per run.
SessionOutcome
What one launch produced, ready to turn into a foch_test::RunArtifacts.

Functions§

capabilities
What this built-in runner can provide, as verified against a real game. Cases needing anything else are refused before launch.
locate_game
Resolve the EU4 install from Foch configuration and Steam, honoring an explicit override first.
run_session
Build the runtime layer, launch the game, wait for every case to finish (or time out), collect the logs, and tear the layer down. session_dir is where the throwaway profile and logs live; source_mod is the mod under test.
sweep_runtime_base
Remove runtime layers left under runtime_base by earlier runs that exited without their [RuntimeLayer] drop (a crash or a hard kill). Only entries older than max_age are removed, so a concurrent run’s fresh layer is never touched. Junctions are unlinked rather than followed, so linked game data is never deleted. Best-effort: inaccessible entries are left alone.