diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index dfa28c9f0..f9d0099b1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ You need [Rust](https://rustup.rs/) 1.95 or newer. ```sh cargo run -p effectcraft -- --demo # the desktop app, with the demo project cargo test --workspace -cargo xtask ci # what every commit must pass +cargo xtask ci # what every commit must pass (tests use --profile ci) ``` ## Ground rules diff --git a/Cargo.toml b/Cargo.toml index 38ba10a0e..919b55d03 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -204,3 +204,10 @@ opt-level = 3 [profile.release] lto = "thin" codegen-units = 1 + +# `cargo xtask ci` builds clippy and tests with this profile. Tests don't need shipping-grade LTO: +# thin LTO + one codegen unit across ~69 test binaries made the gate ~1.5 h while the tests run in ~75 s. +[profile.ci] +inherits = "release" +lto = false +codegen-units = 16 diff --git a/crates/engine/src/tests_settings.rs b/crates/engine/src/tests_settings.rs index 1a445205b..4e1a8e391 100644 --- a/crates/engine/src/tests_settings.rs +++ b/crates/engine/src/tests_settings.rs @@ -545,11 +545,13 @@ fn open_recent_increment_and_revert() { fn memory_tick_never_waits_for_the_system() { let mut s = Session::default(); let t0 = std::time::Instant::now(); - s.memory_tick(); - s.memory_tick(); + for _ in 0..8 { + s.memory_tick(); + } // Reading the system's memory starts PowerShell on Windows (about a second): the UI thread - // only takes the last reading. - assert!(t0.elapsed() < std::time::Duration::from_millis(200), "{:?}", t0.elapsed()); + // only takes the last reading. Eight blocking ticks would take ~8 s; the bound is loose so a + // loaded machine doesn't flake it. + assert!(t0.elapsed() < std::time::Duration::from_secs(4), "{:?}", t0.elapsed()); if crate::sysinfo::memory().is_some() { let mut got = None; for _ in 0..200 { diff --git a/crates/gpu/src/tests_init.rs b/crates/gpu/src/tests_init.rs index 9c579ae69..30a9ba6da 100644 --- a/crates/gpu/src/tests_init.rs +++ b/crates/gpu/src/tests_init.rs @@ -146,7 +146,8 @@ fn opengl_adapters_get_cpu_compositing_at_once() { let t = std::time::Instant::now(); let error = crate::Gpu::new(&adapter, device, queue).err().expect("no GPU compositor on OpenGL"); assert!(error.contains("(Gl)"), "{error}"); - assert!(t.elapsed() < std::time::Duration::from_secs(1), "{:?}", t.elapsed()); + // Generous bound (the failure mode took tens of seconds) so a loaded machine doesn't flake it. + assert!(t.elapsed() < std::time::Duration::from_secs(10), "{:?}", t.elapsed()); } #[test] diff --git a/crates/script/src/tests_ui_more.rs b/crates/script/src/tests_ui_more.rs index 228a58016..87ff00e34 100644 --- a/crates/script/src/tests_ui_more.rs +++ b/crates/script/src/tests_ui_more.rs @@ -441,5 +441,6 @@ fn socket_edge_cases() { "net.jsx", ); assert_eq!(o.result, json!(0), "{:?}", o.error); - assert!(t.elapsed().as_secs_f64() < 5.0); + // Doesn't hang; generous so a loaded machine doesn't flake it. + assert!(t.elapsed().as_secs_f64() < 30.0, "{:?}", t.elapsed()); } diff --git a/docs/testing.md b/docs/testing.md index b053a3e8e..3c81c5524 100644 --- a/docs/testing.md +++ b/docs/testing.md @@ -51,6 +51,9 @@ Limits: a crate that reads a repo file at run time through a path that is not a sources is not detected, and building a subset of packages can unify features differently from the whole workspace. Run the full `cargo xtask ci` before a release. +`xtask ci` builds clippy and tests with `--profile ci` (release optimisation without LTO, 16 codegen +units, output in `target/ci/`): fast to build, still optimised enough for the pixel and perf tests. + ## What the tests cover - **Engine commands** (`crates/engine/src/tests*.rs`): every command family, including undo and diff --git a/xtask/src/main.rs b/xtask/src/main.rs index ac1283408..0f422a493 100644 --- a/xtask/src/main.rs +++ b/xtask/src/main.rs @@ -9,7 +9,7 @@ //! - `assets`: every asset file (image, icon, font, LUT, audio, video…) has a complete //! `.attribution` sidecar and an entry in `ATTRIBUTION.md` (AGENTS.md §1). //! - `ico …`: pack PNGs into a Windows `.ico` (used by `packaging/icons.sh`). -//! - `ci`: fmt check, clippy -D warnings, tests, layers, assets, wasm. +//! - `ci`: fmt check, clippy -D warnings, tests (`--profile ci`), layers, assets, wasm. //! - `ci --affected [--base REV] [--dry-run]`: the same gates for only the crates the change since //! REV (default: the merge-base with `main`) can affect; see `affected.rs` and docs/testing.md. @@ -408,8 +408,8 @@ fn serve_dir(dir: &std::path::Path, port: u16) -> Result<(), String> { fn ci() -> Result<(), String> { let cargo = env!("CARGO"); run(Command::new(cargo).args(["fmt", "--check"]))?; - run(Command::new(cargo).args(["clippy", "--workspace", "--all-targets", "--release", "--", "-D", "warnings"]))?; - run(Command::new(cargo).args(["test", "--workspace", "--release"]))?; + run(Command::new(cargo).args(["clippy", "--workspace", "--all-targets", "--profile", "ci", "--", "-D", "warnings"]))?; + run(Command::new(cargo).args(["test", "--workspace", "--profile", "ci"]))?; layers()?; assets()?; wasm()