ci: limit concurrent GPU tests in nextest

This commit is contained in:
skylartaylor
2026-11-08 19:54:11 +01:00
parent a41ff5015c
commit a4e200731a
3 changed files with 24 additions and 0 deletions
+11
View File
@@ -1,3 +1,14 @@
# Minimum cargo-nextest for this repository: GHSA-vc25-qg58-w57c is fixed in 0.9.150 and CI
# installs exactly that version, so an older nextest refuses to run (exit 92 REQUIRED_VERSION_NOT_MET).
nextest-version = "0.9.150"
[test-groups]
gpu = { max-threads = 1 }
# Coverage runs each test in a separate process, so the GPU suite's in-process lock
# cannot protect software adapters from competing devices and readback timeouts.
# UI harnesses can create a device lazily when rendering a screenshot, so include
# the whole UI package instead of an incomplete list of GPU-named tests.
[[profile.default.overrides]]
filter = 'package(effectcraft-gpu) | package(effectcraft-ui-egui) | package(effectcraft-sam2) | (package(effectcraft-cli) & test(/^cli::gpu_adapter_name_/))'
test-group = 'gpu'
@@ -184,11 +184,15 @@ fn restored_original_and_active_proxy_render_new_pixels_through_media_and_disk_c
let cached = s.render(comp, Tick::ZERO, RenderOpts::default());
assert_eq!(cached.data, before.data);
assert!(cache.stats().hits > 0, "the same media was read back through the disk cache");
let changed_time = std::fs::metadata(&active).unwrap().modified().unwrap() + std::time::Duration::from_secs(7);
std::fs::remove_file(&active).unwrap();
assert_eq!(s.execute("footage.reloadChanged", json!({})).unwrap()["reloaded"], 0, "availability alone drives recovery in this fixture");
let offline = s.render(comp, Tick::ZERO, RenderOpts::default());
assert_eq!(offline.data[8 * 16 + 8], [0.0, 0.0, 0.0, 0.0]);
image::RgbaImage::from_pixel(16, 16, image::Rgba([0, 0, 255, 255])).save(&active).unwrap();
// Changed media needs a distinct stamp, even when both writes land in one filesystem
// clock tick. Same-size, same-stamp replacements require explicit Reload Footage.
std::fs::File::options().append(true).open(&active).unwrap().set_modified(changed_time).unwrap();
assert_eq!(s.execute("footage.reloadChanged", json!({})).unwrap()["reloaded"], 0, "availability alone drives recovery in this fixture");
let restored = s.render(comp, Tick::ZERO, RenderOpts::default());
assert_eq!(restored.data[8 * 16 + 8], [0.0, 0.0, 1.0, 1.0], "restored pixels replace decoded and composited cached frames");
+9
View File
@@ -28,6 +28,15 @@ profile: `cargo run --profile dev-full -p effectcraft -- --demo` (see `CONTRIBUT
runs `missing_translations_report` with `--nocapture`, which prints the interface strings each
language has no translation for. Those strings show in English; the report always passes.
Direct nextest runs, including archived coverage shards, serialise `effectcraft-gpu`,
`effectcraft-ui-egui`, `effectcraft-sam2` and the CLI adapter tests through the `gpu` test group
in `.config/nextest.toml`. Their process-local mutexes cannot coordinate nextest's separate
processes; competing software devices can time out during readback. UI harnesses can also
create a device lazily when rendering a screenshot. This also reduces UI and SAM2 test
parallelism in the normal gate. `cargo xtask ci` still runs the GPU library suite in one
process to reuse its device. Group limits apply within one nextest invocation, not across
separate invocations, and cannot prevent timeouts from other host workloads.
Each crate with several integration-test files has one test binary, `tests/it/main.rs`, whose
modules are the files in `tests/it/`. Run one file with `cargo test -p <crate> --test it <module>::`
or `cargo nextest run -p <crate> -E 'binary(it) and test(/^<module>::/)'`.