use super::*;
#[test]
fn resident_csr_upload_rolls_back_allocated_buffers_on_failure() {
let dispatch = FakeResidentDispatch::failing_on_upload_call(1, 3);
let prepared = PreparedIfdsCsr {
shape: IfdsShape {
num_procs: 1,
blocks_per_proc: 1,
facts_per_proc: 1,
edge_count: 0,
},
node_count: 1,
words: 1,
pg_nodes_b: vec![0; 4],
row_ptr_b: vec![0; 8],
col_idx_b: Vec::new(),
pg_edge_kind_mask_b: Vec::new(),
pg_node_tags_b: vec![0; 4],
};
let err = upload_prepared_ifds_csr_resident(&dispatch, &prepared)
.expect_err("injected upload failure must fail prepare");
assert!(
err.contains("batch CSR upload failed") && err.contains("injected upload failure"),
"unexpected diagnostic: {err}"
);
assert_eq!(
*dispatch.freed.borrow(),
vec![5, 6, 7, 8, 9],
"resident CSR batch upload failure must free every allocated ProgramGraph buffer"
);
}
#[test]
fn resident_csr_upload_pads_zero_length_edge_buffers() {
let dispatch = FakeResidentDispatch::new_with_program_graph_buffers(1);
let prepared = PreparedIfdsCsr {
shape: IfdsShape {
num_procs: 1,
blocks_per_proc: 1,
facts_per_proc: 1,
edge_count: 0,
},
node_count: 1,
words: 1,
pg_nodes_b: vec![0; 4],
row_ptr_b: vec![0; 8],
col_idx_b: Vec::new(),
pg_edge_kind_mask_b: Vec::new(),
pg_node_tags_b: vec![0; 4],
};
let resident = upload_prepared_ifds_csr_resident(&dispatch, &prepared)
.expect("zero-edge resident CSR upload should allocate padded edge buffers");
assert_eq!(
dispatch.upload_many_calls.get(),
1,
"resident CSR upload should batch all invariant ProgramGraph uploads"
);
assert_eq!(dispatch.buffers.borrow()[resident.col_idx].len(), 4);
assert_eq!(
dispatch.buffers.borrow()[resident.pg_edge_kind_mask].len(),
4
);
}