use rusty_alloc_api::{Heap, RustyAlloc};
use std::alloc::{GlobalAlloc, Layout};
#[test]
fn global_alloc_roundtrip_all_bins() {
let a = RustyAlloc;
for (size, align) in [(1, 1), (8, 8), (57, 1), (1024, 16), (70_000, 8), (256, 64)] {
let layout = Layout::from_size_align(size, align).unwrap();
unsafe {
let p = a.alloc(layout);
assert!(!p.is_null());
assert_eq!(p.addr() % align, 0, "misaligned block");
core::ptr::write_bytes(p, 0xAB, size);
assert_eq!(*p, 0xAB);
assert_eq!(*p.add(size - 1), 0xAB);
a.dealloc(p, layout);
}
}
}
#[test]
fn global_alloc_zeroed_is_zero() {
let a = RustyAlloc;
let layout = Layout::from_size_align(300, 8).unwrap();
unsafe {
let p = a.alloc_zeroed(layout);
assert!(!p.is_null());
for i in 0..300 {
assert_eq!(*p.add(i), 0, "alloc_zeroed handed back a dirty byte");
}
a.dealloc(p, layout);
}
}
#[test]
fn global_alloc_realloc_preserves_prefix() {
let a = RustyAlloc;
let layout = Layout::from_size_align(64, 8).unwrap();
unsafe {
let p = a.alloc(layout);
assert!(!p.is_null());
core::ptr::write_bytes(p, 0x5C, 64);
let np = a.realloc(p, layout, 4096);
assert!(!np.is_null());
for i in 0..64 {
assert_eq!(*np.add(i), 0x5C, "realloc lost the prefix");
}
a.dealloc(np, Layout::from_size_align(4096, 8).unwrap());
}
}
#[test]
fn first_class_heap_alloc_and_drop_migrates() {
let h = Heap::new();
let layout = Layout::from_size_align(128, 8).unwrap();
let p = h.alloc(layout).expect("heap alloc failed");
unsafe {
core::ptr::write_bytes(p.as_ptr(), 0x77, 128);
}
drop(h); unsafe {
assert_eq!(*p.as_ptr(), 0x77);
assert_eq!(*p.as_ptr().add(127), 0x77);
RustyAlloc.dealloc(p.as_ptr(), layout);
}
}
#[test]
fn destroyable_heap_releases_wholesale() {
let h = Heap::new_destroyable();
let layout = Layout::from_size_align(64, 8).unwrap();
for _ in 0..32 {
let p = h.alloc(layout).expect("heap alloc failed");
unsafe { core::ptr::write_bytes(p.as_ptr(), 1, 64) };
}
drop(h); }