use super::*;
#[test]
fn resident_ifds_batch_rejects_parallel_scratch_over_budget_before_csr_upload() {
let prepared = prepared_fixture();
let dispatch = FakeResidentDispatch::new();
let mut batch = ResidentIfdsBatch::with_memory_budget(usize::MAX, 47);
let seed_a = [(0, 0, 0)];
let seed_b = [(0, 1, 0)];
let mut results = Vec::new();
let error = batch
.solve_prepared_many_into(
&dispatch,
&prepared,
&[&seed_a[..], &seed_b[..]],
4,
&mut results,
)
.expect_err("parallel scratch budget must reject oversized query batch");
assert!(
error.contains("requires 48 bytes") && error.contains("allows 47"),
"parallel scratch budget error must report required and allowed bytes"
);
assert_eq!(
dispatch.allocate_calls.get(),
0,
"parallel scratch budget rejection must happen before CSR or scratch resident allocation"
);
assert_eq!(dispatch.upload_many_calls.get(), 0);
assert!(results.is_empty());
assert_eq!(
batch.stats(),
ResidentIfdsBatchStats {
csr_cache: ResidentIfdsCsrCacheStats::default(),
scratch_allocations: 0,
scratch_reuses: 0,
scratch_frees: 0,
resident_dispatches: 0,
seed_upload_bytes: 0,
result_readback_bytes: 0,
resident_graph_cold_uploads: 0,
resident_graph_warm_reuses: 0,
resident_graph_upload_bytes: 0,
resident_graph_avoided_upload_bytes: 0,
scratch_resident: false,
scratch_bytes: 0,
}
);
}