#![cfg(feature = "stats")]
use multitude::{Arena, ArenaBuilder};
#[test]
fn is_oversized_shared_routes_at_threshold_via_normal() {
const MNA: usize = 4 * 1024;
let arena = ArenaBuilder::new().max_normal_alloc(MNA).build();
let before_normal = arena.stats().normal_shared_chunks_allocated;
let before_oversized = arena.stats().oversized_shared_chunks_allocated;
let _arc = arena.alloc_arc([0_u8; MNA - 1]);
let after_normal = arena.stats().normal_shared_chunks_allocated;
let after_oversized = arena.stats().oversized_shared_chunks_allocated;
assert!(after_normal > before_normal);
assert_eq!(
after_oversized, before_oversized,
"threshold must NOT route oversized (kills `>=` mutant)"
);
}
#[test]
fn is_oversized_shared_routes_above_threshold_via_oversized() {
const MNA: usize = 4 * 1024;
let arena = ArenaBuilder::new().max_normal_alloc(MNA).build();
let before_oversized = arena.stats().oversized_shared_chunks_allocated;
let _arc = arena.alloc_arc([0_u8; MNA]); let after_oversized = arena.stats().oversized_shared_chunks_allocated;
assert!(
after_oversized > before_oversized,
"above-threshold must route oversized (kills `==` mutant)"
);
}
#[test]
fn is_oversized_local_routes_at_threshold_via_normal() {
const MNA: usize = 4 * 1024;
let arena = ArenaBuilder::new().max_normal_alloc(MNA).build();
let before_normal = arena.stats().normal_local_chunks_allocated;
let before_oversized = arena.stats().oversized_local_chunks_allocated;
let s = "x".repeat(MNA);
let _r: &mut str = arena.alloc_str(&s);
let after_normal = arena.stats().normal_local_chunks_allocated;
let after_oversized = arena.stats().oversized_local_chunks_allocated;
assert!(after_normal > before_normal);
assert_eq!(after_oversized, before_oversized, "threshold must NOT route oversized");
}
#[test]
fn is_oversized_local_routes_above_threshold_via_oversized() {
const MNA: usize = 4 * 1024;
let arena = ArenaBuilder::new().max_normal_alloc(MNA).build();
let before_oversized = arena.stats().oversized_local_chunks_allocated;
let s = "x".repeat(MNA + 1);
let _r: &mut str = arena.alloc_str(&s);
let after_oversized = arena.stats().oversized_local_chunks_allocated;
assert!(after_oversized > before_oversized);
}
#[test]
fn slice_fill_with_records_size_times_len() {
let arena = Arena::new();
let before = arena.stats().total_bytes_allocated;
let _s: &mut [u32] = arena.alloc_slice_fill_with(10, |i| u32::try_from(i).unwrap());
let after = arena.stats().total_bytes_allocated;
assert_eq!(after - before, (10 * core::mem::size_of::<u32>()) as u64);
}
#[test]
fn slice_fill_iter_records_size_times_len() {
let arena = Arena::new();
let before = arena.stats().total_bytes_allocated;
let _s: &mut [u32] = arena.alloc_slice_fill_iter(0_u32..10);
let after = arena.stats().total_bytes_allocated;
assert_eq!(after - before, (10 * core::mem::size_of::<u32>()) as u64);
}
#[test]
fn slice_fill_with_oversized_records_size_times_len() {
let mna = 4096;
let arena = ArenaBuilder::new().max_normal_alloc(mna).build();
let len = mna * 2; let before = arena.stats().total_bytes_allocated;
let _s: &mut [u8] = arena.alloc_slice_fill_with(len, |_| 0);
let after = arena.stats().total_bytes_allocated;
assert_eq!(after - before, len as u64);
}
#[test]
fn slice_fill_iter_oversized_records_size_times_len() {
let mna = 4096;
let arena = ArenaBuilder::new().max_normal_alloc(mna).build();
let len = mna * 2;
let before = arena.stats().total_bytes_allocated;
let _s: &mut [u8] = arena.alloc_slice_fill_iter((0..len).map(|_| 0_u8));
let after = arena.stats().total_bytes_allocated;
assert_eq!(after - before, len as u64);
}
#[test]
fn shrink_to_fit_reclaims_strictly_below_max_normal_alloc() {
let mna = 4 * 1024;
let arena: Arena = ArenaBuilder::new().max_normal_alloc(mna).build();
let cap = mna - 1;
let mut v: multitude::vec::Vec<'_, u8> = multitude::vec::Vec::with_capacity_in(cap, &arena);
v.extend_from_slice([7_u8; 16]);
assert_eq!(v.capacity(), cap);
v.shrink_to_fit();
assert_eq!(v.capacity(), v.len(), "Vec strictly below max_normal_alloc must reclaim tail");
}
#[test]
fn local_cache_floor_advances_so_post_reset_alloc_reuses_chunk() {
let mut arena = Arena::new();
let stride = 1024_usize;
for _ in 0..8 {
let s = "y".repeat(stride);
let _r = arena.alloc_str(&s);
}
let before_reset = arena.stats().normal_local_chunks_allocated;
arena.reset();
let _ = arena.alloc(0_u8);
let after_reset = arena.stats().normal_local_chunks_allocated;
assert!(
after_reset - before_reset <= 1,
"post-reset alloc must reuse cached saturated-class chunk; got {} fresh allocs (kills floor-bump mutants)",
after_reset - before_reset,
);
}