test: run the full content-root tests only where they matter

The five mod_content tests that load the whole content root took minutes of
every `cargo test -p horizon-client --lib` on prepared data. They are now
#[ignore]d; pr_ready runs them when the diff touches what they load, and CI's
verify job runs them filtered with --ignored on its existing build.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
Ludovic MarieandClaude Opus 5.5 committed 2026-10-27 08:37:40 +01:00
1 parent 6af60956ec
commit 80751276f3
5 files changed
+33

No files matched your search

+3
View File
@@ -72,6 +72,9 @@ jobs:
if: steps.rust.outputs.required != 'false'
run: |
cargo +stable test --workspace --lib --bins --tests --features horizon-client/mods,horizon-mods/pack
# The full content-root tests (#[ignore]d: minutes each on a laptop). The same build as above; they need the
# prepared vanilla data, so without it they pass at once.
cargo +stable test --workspace --lib --features horizon-client/mods,horizon-mods/pack mod_content::tests:: -- --ignored
cargo +stable test --workspace --doc --features horizon-client/mods,horizon-mods/pack
# The launcher is its own workspace (launcher/Cargo.toml), so verify's cargo runs never build it. A pull request that
# changes it or a crate it builds is checked here, and so is every push to main: two pull requests can each pass
+1
View File
@@ -66,6 +66,7 @@ reads `README.md`, `launcher/links.json`, `docs/api/`, `roadmap/roadmap.json` an
python3 tools/pr_ready.py # the self-check: fmt, clippy -D warnings, touched crates' tests, harnesses; paste its block in the PR
python3 tools/pr_ready.py --quick # same without harnesses
cargo test -p horizon-client --lib --bins --tests # skips the 104 examples (pr_ready does this); `--doc` separately
cargo test -p horizon-client --features horizon-client/mods --lib mod_content::tests:: -- --ignored # the 5 slow content-root tests, #[ignore]d; pr_ready runs them when mod content, assets, blocks or items change
cargo build --profile fast -p horizon-client # optimized, quick to link: use it to play or run lan_e2e
python3 tools/parity.py --changed origin/main # the harnesses your branch can affect (CI's parity job)
python3 tools/parity.py --changed-files paths.txt --list # which harnesses cover these files, without running them
@@ -114,6 +114,7 @@ fn ruby_mod(dir: &Path) -> ContentMod {
/// new blocks behave like their templates with the overrides, and vanilla's
/// states are where they were.
#[test]
#[ignore = "full content root: CI and pr_ready run it"]
fn content_root_loads_with_every_table() {
let Some(base) = prepared() else {
return;
@@ -352,6 +353,7 @@ fn no_content_keeps_the_base_root() {
use horizon_world::registry::BlockStateId;
#[test]
#[ignore = "full content root: CI and pr_ready run it"]
fn shared_behaviour_document_matches_independent_loaders() {
let Some(root) = prepared() else { return };
let assets = Assets::load(&root).expect("assets");
@@ -414,6 +416,7 @@ fn shared_behaviour_document_matches_independent_loaders() {
#[cfg(unix)]
#[test]
#[ignore = "full content root: CI and pr_ready run it"]
fn independent_reloads_read_changed_behaviour_json_and_report_invalid_files() {
let Some(base) = prepared() else { return };
let scratch = std::env::temp_dir().join(format!("horizon-json-reloads-{}", std::process::id()));
@@ -535,6 +538,7 @@ fn independent_reloads_read_changed_behaviour_json_and_report_invalid_files() {
/// A built root is kept for later starts, and built again when a mod's
/// files change.
#[test]
#[ignore = "full content root: CI and pr_ready run it"]
fn content_root_is_reused_until_a_mod_changes() {
let Some(base) = prepared() else {
return;
@@ -571,6 +575,7 @@ fn content_root_is_reused_until_a_mod_changes() {
/// set, pool and templates join the bundles, and its biome tag keeps only
/// what the loader knows.
#[test]
#[ignore = "full content root: CI and pr_ready run it"]
fn content_root_carries_a_structure_mod() {
let Some(base) = prepared() else {
return;
+13
View File
@@ -56,6 +56,19 @@ class PrReadyTests(unittest.TestCase):
self.assertEqual(by_name["doc tests"].command, "cargo test --locked -p horizon-client --doc")
self.assertIsNone(by_name["doc tests"].status)
def test_content_root_tests_run_only_when_what_they_load_changes(self):
def content_step(path):
with mock.patch.object(pr_ready, "affected_here", return_value=[]):
steps = pr_ready.plan(args(quick=True), "origin/main", {path}, PACKAGES, LIBRARIES, DEPENDENCIES)
return {step.name: step for step in steps}["content root tests"]
self.assertEqual(content_step("crates/horizon-client/src/game.rs").skip, "content root untouched")
for path in ["crates/horizon-client/src/mod_content.rs", "crates/horizon-client/src/mod_content_tests.rs",
"crates/horizon-mods/src/content.rs", "crates/horizon-assets/src/lib.rs", "Cargo.lock"]:
with self.subTest(path=path):
step = content_step(path)
self.assertIsNone(step.skip)
self.assertEqual(step.command, pr_ready.CONTENT_ROOT_TESTS)
def test_shared_rust_configuration_keeps_workspace_coverage(self):
for path in sorted(pr_ready.ROOT_RUST | {".cargo/config.toml", "crates/unknown/src/lib.rs"}):
with self.subTest(path=path), mock.patch.object(pr_ready, "affected_here", return_value=[]):
+11
View File
@@ -290,6 +290,14 @@ def mod_features(crates):
return f" --features {','.join(features)}" if features else ""
# What horizon-client's full content-root tests load (mod_content_tests.rs). They take minutes on prepared data, so
# they are #[ignore]d and run here only when one of these changes.
CONTENT_ROOT = ("crates/horizon-client/src/mod_content", "crates/horizon-client/src/assets.rs",
"crates/horizon-client/src/blocks.rs", "crates/horizon-client/src/items.rs", "crates/horizon-items/",
"crates/horizon-mods/", "crates/horizon-assets/")
CONTENT_ROOT_TESTS = "cargo test --locked -p horizon-client --features horizon-client/mods --lib mod_content::tests:: -- --ignored"
def plan(args, base, changed, crates_of, libraries, dependencies):
"""The checks for these changed files, in the order they run."""
rust = any(workspace_rust(path) for path in changed)
@@ -323,6 +331,9 @@ def plan(args, base, changed, crates_of, libraries, dependencies):
skip=test_skip, summary=tests_passed),
Step("doc tests", f"cargo test --locked {doc_selection} --doc",
skip=test_skip or (None if doc_crates else "no library touched"), summary=tests_passed),
Step("content root tests", CONTENT_ROOT_TESTS, summary=tests_passed,
skip=None if crates is None or any(p.startswith(CONTENT_ROOT) for p in changed)
else "content root untouched"),
Step("tokens.css up to date", "cargo test --locked -p horizon-theme --lib tokens_css_is_up_to_date",
skip=None if any(p.startswith(("crates/horizon-theme/", "xtask/")) for p in changed)
else "theme untouched"),