oracle: quantities of a generated mesh can be gated by their tolerance alone ("fixture": false)

The bracket's tet mesh is not bit-identical across platforms (#115): its fillet peak is 213.31 MPa
on macOS and 212.42 on Linux CI, which turned the oracle job red after #110. Those two quantities
are no longer frozen; the page names them mesh-dependent instead of printing one platform's value.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NmAttHhUZTokgPeEJia8sm
This commit is contained in:
jyvikoandClaude Opus 5.5 authored and Irakli Kourtis committed 2026-10-14 08:42:31 -04:00
1 parent fe7d536719
commit 90729e4532
7 files changed
+57 -18

No files matched your search

+44 -3
View File
@@ -94,6 +94,10 @@ pub struct Quantity {
/// The fixture band's relative part, when the quantity is more sensitive to rounding than
/// [`FIXTURE_RELATIVE`] allows (an ill-conditioned problem); `fixture_reason` says why.
pub fixture_relative: f64,
/// Whether the result is frozen in `fixture.json`. A quantity that depends on a mesh the
/// mesher generates from geometry (`"fixture": false`, with a `fixture_reason`) is not: the
/// mesh is not bit-identical across platforms, so only its reference tolerance gates it.
pub frozen: bool,
}
/// One case's `expected.json`.
@@ -153,6 +157,17 @@ impl Expected {
if quantities.iter().any(|x: &Quantity| x.id == id) {
return Err(format!("quantity `{id}` is listed twice"));
}
let frozen = match q.get("fixture") {
None => true,
Some(Value::Bool(f)) => *f,
Some(_) => return Err(context("`fixture` must be true or false".into())),
};
if !frozen {
text(q, "fixture_reason").map_err(|_| context("`\"fixture\": false` needs a `fixture_reason`".into()))?;
if q.get("fixture_relative").is_some() {
return Err(context("`fixture_relative` has no meaning with `\"fixture\": false`".into()));
}
}
let fixture_relative = match q.get("fixture_relative") {
None => FIXTURE_RELATIVE,
Some(r) => {
@@ -163,6 +178,7 @@ impl Expected {
};
quantities.push(Quantity {
fixture_relative,
frozen,
description: text(q, "quantity").map_err(context)?,
known_failure: q.get("known_failure").and_then(Value::as_str).map(str::to_string),
id,
@@ -319,6 +335,7 @@ pub fn judge(q: &Quantity, ours: &Result<f64, String>, frozen: Option<&Frozen>)
(false, Some(_)) => Verdict::Known,
};
let fixture = match frozen {
_ if !q.frozen => FixtureCheck::NotKept,
Some(f) if (ours - f.value).abs() <= f.band => FixtureCheck::Matches,
Some(f) => FixtureCheck::Moved { frozen: f.value },
None if verdict == Verdict::Pass => FixtureCheck::Missing,
@@ -392,7 +409,7 @@ pub fn run(root: &Path, options: &Options) -> Result<(), String> {
problems.push(format!("{case}: not blessed, it does not pass against expected.json"));
} else {
let mut values = serde_json::Map::new();
for r in case_rows.iter_mut().filter(|r| r.verdict == Verdict::Pass) {
for r in case_rows.iter_mut().filter(|r| r.verdict == Verdict::Pass && r.quantity.frozen) {
if let (Some(ours), Some(reference)) = (r.ours, r.quantity.reference) {
values.insert(
r.quantity.id.clone(),
@@ -513,6 +530,18 @@ fn ours_text(r: &Row) -> String {
}
}
/// docs/oracle.md's result column. A quantity that is not frozen depends on a generated mesh
/// that differs by platform, so the page names that instead of one platform's number (the run's
/// console prints the value).
fn page_ours(r: &Row) -> String {
if r.quantity.frozen { ours_text(r) } else { "mesh-dependent".into() }
}
/// docs/oracle.md's error column; see [`page_ours`].
fn page_error(r: &Row) -> String {
if r.quantity.frozen { error_of(r) } else { format!("within {}", r.quantity.tolerance.describe()) }
}
/// The error against the reference: relative where the reference is not zero. Errors inside the
/// fixture band are rounding and are shown as a bound.
fn error_of(r: &Row) -> String {
@@ -615,8 +644,8 @@ benchmark, {} experiment; {} pending cases wait for capabilities still being bui
"| [{case}](../tests/oracle/{case}/) | {} | {} | {} | {} | {} | {} | {} |",
cell(&r.quantity.description),
show(r.quantity.reference),
ours_text(r),
error_of(r),
page_ours(r),
page_error(r),
r.quantity.tolerance.describe(),
cell(&result),
page_fixture_text(&r.fixture),
@@ -668,9 +697,21 @@ mod tests {
reason: "r".into(),
known_failure: known.map(str::to_string),
fixture_relative: FIXTURE_RELATIVE,
frozen: true,
}
}
/// A quantity of a generated mesh is gated by its tolerance only: a stored fixture is ignored
/// and blessing skips it.
#[test]
fn unfrozen_quantities_skip_the_fixture() {
let t = Tolerance { relative: 0.03, absolute: 0.0 };
let q = Quantity { frozen: false, ..quantity(213.0, t, None) };
let old = Frozen { value: 213.3, band: 2e-7 };
assert_eq!(judge(&q, &Ok(212.4), Some(&old)), (Verdict::Pass, FixtureCheck::NotKept));
assert_eq!(judge(&q, &Ok(200.0), Some(&old)).0, Verdict::Fail, "the tolerance still gates it");
}
#[test]
fn verdicts_and_fixtures() {
let t = Tolerance { relative: 0.01, absolute: 0.0 };