use super::*;
#[test]
fn direct_ifds_memory_budget_rejects_graph_before_resident_prepare() {
let mut batch = super::DirectResidentIfdsBatch::<u64>::with_memory_budget(2, 23);
let dispatch = FreeOnlyDispatch {
freed: RefCell::new(Vec::new()),
};
let graph_key = DirectResidentIfdsGraphKey::from_edges(1, 1, 1, &[], &[], &[], &[]);
let seed = [(0u32, 0u32, 0u32)];
let mut results = Vec::new();
let error = batch
.solve_many_with_graph_key_into(
&dispatch,
graph_key,
1,
1,
1,
&[],
&[],
&[],
&[],
&[&seed[..]],
1,
&mut results,
)
.expect_err("direct IFDS memory budget must reject oversized resident CSR");
assert!(
error.contains("requires 24 retained bytes") && error.contains("allows 23"),
"direct IFDS memory-budget error must report required and allowed retained bytes"
);
assert!(
dispatch.freed.borrow().is_empty(),
"direct IFDS budget rejection must happen before resident allocation or eviction"
);
assert_eq!(batch.stats().retained_bytes, 0);
assert_eq!(batch.stats().direct_prepare_bytes, 0);
}
#[test]
fn direct_ifds_cached_key_requires_warm_resident_graph() {
let mut batch = super::DirectResidentIfdsBatch::<u64>::with_max_entries(2);
let dispatch = FreeOnlyDispatch {
freed: RefCell::new(Vec::new()),
};
let graph_key = DirectResidentIfdsGraphKey::from_edges(1, 1, 1, &[], &[], &[], &[]);
let seed = [(0u32, 0u32, 0u32)];
let mut results = Vec::new();
let error = batch
.solve_cached_with_graph_key_into(&dispatch, graph_key, &[&seed[..]], 1, &mut results)
.expect_err("cached-key IFDS hot path must reject a cold graph key");
assert!(
error.contains("call solve_many_with_graph_key_into once"),
"cached-key IFDS error must explain the required warm-up path"
);
assert!(results.is_empty());
}