From 27374ca2899c856b8a34e76ba76b01bca496121c Mon Sep 17 00:00:00 2001 From: bherbruck Date: Wed, 14 Oct 2026 07:38:53 -0400 Subject: [PATCH] test: hold the enclosure lid's press/pull to CPU and memory, not wall time (#1027) press_pull_on_the_enclosure_lid_is_prompt took 61-87 s of wall time on loaded runners against a 60 s bound, for about 9 s of CPU. It now checks the operation's CPU time (under 300 s) and how far it grows the peak memory (under 1 GB; the runaway it guards against passed 24 GB), from /proc/self where the system has it. Co-Authored-By: Claude Opus 5.5 --- crates/engine/src/boolean_regression_tests.rs | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/crates/engine/src/boolean_regression_tests.rs b/crates/engine/src/boolean_regression_tests.rs index e11595ae..02014d11 100644 --- a/crates/engine/src/boolean_regression_tests.rs +++ b/crates/engine/src/boolean_regression_tests.rs @@ -216,9 +216,23 @@ fn ls_extruded_up_and_down_from_one_grid_join() { assert!((v - 6000.0).abs() < 1e-6, "{v}"); } +/// This process's CPU time (all threads) and peak resident memory, where the system says +/// (Linux: /proc/self); `None` elsewhere. +fn cpu_and_peak_memory() -> Option<(std::time::Duration, u64)> { + let stat = std::fs::read_to_string("/proc/self/stat").ok()?; + // utime and stime, in clock ticks (100 a second on Linux), after the command's name. + let fields: Vec<&str> = stat.rsplit_once(')')?.1.split_whitespace().collect(); + let ticks: u64 = fields.get(11)?.parse::().ok()? + fields.get(12)?.parse::().ok()?; + let status = std::fs::read_to_string("/proc/self/status").ok()?; + let kb: u64 = status.lines().find_map(|l| l.strip_prefix("VmHWM:"))?.trim().trim_end_matches("kB").trim().parse().ok()?; + Some((std::time::Duration::from_millis(ticks * 10), kb * 1024)) +} + /// Press/pull on the sensor enclosure's lid top: joining the pulled face's prism imprints the /// contact (#825), and boxing the lid's faces by dividing their curved edges down to the -/// contact tolerance ran away (over 24 GB and many minutes). It finishes in seconds. +/// contact tolerance ran away (over 24 GB and many minutes). It takes about 9 s of CPU here and +/// no memory beyond the design's. The budgets are work, not wall time, which a loaded runner +/// stretches (61-87 s for the same work on CI). #[test] fn press_pull_on_the_enclosure_lid_is_prompt() { let mut s = Session::default(); @@ -226,9 +240,13 @@ fn press_pull_on_the_enclosure_lid_is_prompt() { s.run_script(&script).unwrap(); let total = |s: &Session| -> f64 { s.model.state().bodies.iter().map(|b| solidcraft_kernel::measure(&b.body).unwrap().volume).sum() }; let before = total(&s); - let t = std::time::Instant::now(); + let start = cpu_and_peak_memory(); s.execute("solid.press_pull", &json!({"face": [-12.0, 27.4, 23.0], "distance": 5.0})).unwrap(); - // A few seconds here; the bound leaves room for a loaded CI runner. - assert!(t.elapsed().as_secs() < 60, "took {:?}", t.elapsed()); + if let (Some((cpu0, peak0)), Some((cpu1, peak1))) = (start, cpu_and_peak_memory()) { + let grew = peak1.saturating_sub(peak0); + assert!(grew < 1 << 30, "the press/pull grew the peak memory by {} MB", grew >> 20); + // Other tests in this process (cargo test) count too, so the bound is generous. + assert!(cpu1 - cpu0 < std::time::Duration::from_secs(300), "the press/pull took {:?} of CPU", cpu1 - cpu0); + } assert!(total(&s) > before, "{before} -> {}", total(&s)); }