forked from 1b-agent/fieldcraft-upstream
Fast PR CI: small hostile-test caps, heavy tests in a separate job (#43)
* test: hostile-params test runs under small session work caps Session gains Limits, the defaults of mesh.tet.generate's max_steiner and max_tets (production values unchanged; a parameter still overrides them; file.open keeps them). The registry-wide hostile-params test runs on sessions with small caps, so the needle-triangle tessellation it meshes is refused at once instead of meshing to the 50k Steiner cap: the engine test binary drops from ~350 s to ~20 s locally. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * ci: move heavy tests to a heavy job on main, nightly and on demand Four slow tests are #[ignore = "heavy: ..."] (every corpus recipe, the cantilever convergence study, the explicit-vs-modal cantilever period, the generic-predicate rational cross-check); fast representative tests of each area stay in the PR gate. cargo xtask test --heavy runs every ignored test (benchmarks included) and the doc tests; cargo xtask test and ci run the rest without the doc tests. The new heavy CI job runs it on pushes to main, nightly and on workflow_dispatch. Branch jobs restore main's rust cache and no longer save their own. AGENTS.md documents the rule. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm * test: the three slow LBM verification cases run in the heavy job The Stokes-drag sphere array, the staircase-pipe convergence study and the developing-channel case are heavy (21 s, 11 s, 6 s alone); plane Poiseuille, Couette, Taylor-Green, reproducibility and the stability limits stay in the PR gate. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm --------- Co-authored-by: jyviko <2501648+jyviko@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
13 files changed
+113
-18
No files matched your search
@@ -154,9 +154,11 @@ impl Session {
|
||||
(session, warnings)
|
||||
}
|
||||
|
||||
/// Replace this session with `opened`, keeping its undo memory limit; the history starts empty.
|
||||
/// Replace this session with `opened`, keeping its undo memory limit and its work caps; the
|
||||
/// history starts empty.
|
||||
fn replace_with(&mut self, mut opened: Session) {
|
||||
opened.history = std::mem::take(&mut self.history);
|
||||
opened.limits = self.limits;
|
||||
opened.clear_history();
|
||||
*self = opened;
|
||||
}
|
||||
|
||||
@@ -126,10 +126,9 @@ fn surface_options(p: &Value, mesh: &SurfaceMesh) -> Result<SurfaceOptions> {
|
||||
}
|
||||
|
||||
fn tet_generate(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
let defaults = CdtOptions::default();
|
||||
let cdt_options = CdtOptions {
|
||||
max_steiner: optional_count(p, "max_steiner", defaults.max_steiner as u64, 0..=TET_MAX_STEINER)?,
|
||||
max_tets: optional_count(p, "max_tets", defaults.max_tets as u64, 1..=TET_MAX_TETS)?,
|
||||
max_steiner: optional_count(p, "max_steiner", s.limits.max_steiner as u64, 0..=TET_MAX_STEINER)?,
|
||||
max_tets: optional_count(p, "max_tets", s.limits.max_tets as u64, 1..=TET_MAX_TETS)?,
|
||||
};
|
||||
let (surface, body, face_names) = {
|
||||
let Input { mesh, body, faces } = surface_input(s, p)?;
|
||||
@@ -648,6 +647,26 @@ mod tests {
|
||||
assert_eq!((s.journal.len(), &s.model), (journal, &model), "failures change nothing");
|
||||
}
|
||||
|
||||
/// The session's caps are the defaults of `max_steiner` and `max_tets`; a parameter overrides them.
|
||||
#[test]
|
||||
fn tet_generate_honours_the_session_caps() {
|
||||
use std::sync::Arc;
|
||||
|
||||
use modelcraft_geometry::open_design;
|
||||
use modelcraft_geometry::sample::{Plate, plate_design};
|
||||
|
||||
use crate::{EngineError, Limits};
|
||||
|
||||
let design = Arc::new(open_design(&plate_design(&Plate::default()).unwrap()).unwrap());
|
||||
let mut s = Session { design: Some(design), limits: Limits { max_tets: 10, ..Limits::default() }, ..Session::default() };
|
||||
let plate = json!({"body": "Body1", "tolerance": 0.5});
|
||||
let refused = s.execute("mesh.tet.generate", &plate).unwrap_err();
|
||||
assert!(matches!(refused, EngineError::Mesh(modelcraft_mesh::Error::Limit(_))), "{refused}");
|
||||
assert!(s.model.elements().is_empty());
|
||||
let r = s.execute("mesh.tet.generate", &json!({"body": "Body1", "tolerance": 0.5, "max_tets": 1_000_000})).unwrap();
|
||||
assert!(r["elements"].as_u64().unwrap() > 0, "{r}");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn tet_generate_on_an_imported_surface_and_an_open_one() {
|
||||
use std::sync::Arc;
|
||||
|
||||
@@ -792,6 +792,7 @@ pub(crate) mod tests {
|
||||
/// bending energy, so without hourglass stiffness (viscous control) the period is longer by
|
||||
/// (1 − 1/n²)^{−½} (3.3% for n = 4); the stiffness form restores part of it.
|
||||
#[test]
|
||||
#[ignore = "heavy: cargo xtask test --heavy (CI heavy job)"]
|
||||
fn explicit_cantilever_period_matches_the_modal_frequency() {
|
||||
let (length, n) = (10.0, [40usize, 4usize]);
|
||||
let mut s = Session::default();
|
||||
|
||||
Reference in new issue
Block a user