use jvmrs::memory::{
MemoryAllocator,
ArenaAllocator,
TlabAllocator,
MemoryType,
PrimitiveArrayType,
MemoryStats
};
#[test]
fn test_arena_allocator_basic() {
let mut allocator = ArenaAllocator::new(1024);
let obj1 = allocator.allocate_object("TestClass").unwrap();
let obj2 = allocator.allocate_object("TestClass").unwrap();
assert_ne!(obj1, obj2);
let stats = allocator.get_stats();
assert_eq!(stats.allocation_count, 2);
assert!(stats.total_allocated >= 32); assert_eq!(stats.deallocation_count, 0);
}
#[test]
fn test_arena_array_allocation() {
let mut allocator = ArenaAllocator::new(2048);
let int_array = allocator.allocate_array(
MemoryType::PrimitiveArray(PrimitiveArrayType::Int.clone()),
10
).unwrap();
let byte_array = allocator.allocate_array(
MemoryType::PrimitiveArray(PrimitiveArrayType::Byte.clone()),
20
).unwrap();
let long_array = allocator.allocate_array(
MemoryType::PrimitiveArray(PrimitiveArrayType::Long.clone()),
5
).unwrap();
assert_ne!(int_array, byte_array);
assert_ne!(int_array, long_array);
assert_ne!(byte_array, long_array);
let stats = allocator.get_stats();
assert_eq!(stats.allocation_count, 3); assert!(stats.total_allocated > 0);
}
#[test]
fn test_arena_cleanup() {
let mut allocator = ArenaAllocator::new(1024);
let _obj1 = allocator.allocate_object("Test1").unwrap();
let _obj2 = allocator.allocate_object("Test2").unwrap();
let before_cleanup = allocator.get_stats();
assert_eq!(before_cleanup.allocation_count, 2);
assert_eq!(before_cleanup.deallocation_count, 0);
allocator.cleanup().unwrap();
let after_cleanup = allocator.get_stats();
assert_eq!(after_cleanup.allocation_count, 2); assert_eq!(after_cleanup.deallocation_count, 1); }
#[test]
fn test_arena_resize() {
let mut allocator = ArenaAllocator::new(256);
let mut objects = Vec::new();
for i in 0..20 {
if i % 2 == 0 {
let obj = allocator.allocate_object(format!("Object{}", i).as_str()).unwrap();
objects.push(obj);
} else {
let arr = allocator.allocate_array(
MemoryType::PrimitiveArray(PrimitiveArrayType::Int.clone()),
5
).unwrap();
objects.push(arr);
}
}
assert_eq!(objects.len(), 20);
let stats = allocator.get_stats();
assert_eq!(stats.allocation_count, 20);
assert!(stats.total_allocated > 0);
}
#[test]
fn test_tlab_allocator_basic() {
let mut allocator = TlabAllocator::new(512);
let obj1 = allocator.allocate_object("TestObject").unwrap();
let obj2 = allocator.allocate_object("TestObject").unwrap();
assert_ne!(obj1, obj2);
let array = allocator.allocate_array(
MemoryType::PrimitiveArray(PrimitiveArrayType::Float),
8
).unwrap();
assert_ne!(array, 0);
let stats = allocator.get_stats();
assert_eq!(stats.allocation_count, 3); }
#[test]
fn test_tlab_cleanup() {
let mut allocator = TlabAllocator::new(1024);
let _obj1 = allocator.allocate_object("Test1").unwrap();
let _obj2 = allocator.allocate_object("Test2").unwrap();
let before_cleanup = allocator.get_stats();
assert_eq!(before_cleanup.allocation_count, 2);
allocator.cleanup().unwrap();
let after_cleanup = allocator.get_stats();
assert_eq!(after_cleanup.allocation_count, 2); assert_eq!(after_cleanup.deallocation_count, 1); }
#[test]
fn test_memory_type_enum() {
let types = [
PrimitiveArrayType::Int,
PrimitiveArrayType::Byte,
PrimitiveArrayType::Short,
PrimitiveArrayType::Char,
PrimitiveArrayType::Long,
PrimitiveArrayType::Float,
PrimitiveArrayType::Double,
PrimitiveArrayType::Boolean,
];
for array_type in types.iter() {
let memory_type = MemoryType::PrimitiveArray(array_type.clone());
assert!(matches!(memory_type, MemoryType::PrimitiveArray(_)));
}
let obj_array_type = MemoryType::ObjectArray("java/lang/String".to_string());
assert!(matches!(obj_array_type, MemoryType::ObjectArray(_)));
let multi_type = MemoryType::MultiArray("I".to_string(), vec![2, 3, 4]);
assert!(matches!(multi_type, MemoryType::MultiArray(_, _)));
}
#[test]
fn test_memory_stats_consistency() {
let mut allocator = ArenaAllocator::new(1024);
let initial_stats = allocator.get_stats();
assert_eq!(initial_stats.allocation_count, 0);
assert_eq!(initial_stats.deallocation_count, 0);
assert_eq!(initial_stats.current_usage, 0);
assert_eq!(initial_stats.total_allocated, 1024);
for i in 0..5 {
let _ = allocator.allocate_object(format!("Obj{}", i).as_str()).unwrap();
}
let after_allocation = allocator.get_stats();
assert_eq!(after_allocation.allocation_count, 5);
assert_eq!(after_allocation.deallocation_count, 0);
assert!(after_allocation.current_usage > 0);
assert!(after_allocation.total_allocated > 0);
allocator.cleanup().unwrap();
let after_cleanup = allocator.get_stats();
assert_eq!(after_cleanup.allocation_count, 5); assert_eq!(after_cleanup.deallocation_count, 1);
assert_eq!(after_cleanup.current_usage, 0); assert_eq!(after_cleanup.total_allocated, 1024); }
#[test]
fn test_allocator_capacity() {
let mut allocator = ArenaAllocator::new(1000);
assert!(allocator.can_allocate(100));
assert!(allocator.can_allocate(500));
assert!(!allocator.can_allocate(2000));
for i in 0..62 {
let _ = allocator.allocate_object("Obj").unwrap();
}
assert!(!allocator.can_allocate(500));
allocator.cleanup().unwrap();
assert!(allocator.can_allocate(500));
}
#[test]
fn test_array_size_validation() {
let mut allocator = ArenaAllocator::new(1024);
let result = allocator.allocate_array(
MemoryType::PrimitiveArray(PrimitiveArrayType::Int),
-1
);
assert!(result.is_err());
let zero_array = allocator.allocate_array(
MemoryType::PrimitiveArray(PrimitiveArrayType::Int),
0
);
assert!(zero_array.is_ok());
let large_array = allocator.allocate_array(
MemoryType::PrimitiveArray(PrimitiveArrayType::Int),
100000
);
assert!(large_array.is_ok() || large_array.is_err());
}
#[test]
fn test_allocator_memory_safety() {
let mut allocator = ArenaAllocator::new(512);
let obj1 = allocator.allocate_object("SafetyTest1").unwrap();
let obj2 = allocator.allocate_object("SafetyTest2").unwrap();
let stats1 = allocator.get_stats();
assert_eq!(stats1.allocation_count, 2);
allocator.cleanup().unwrap();
let stats2 = allocator.get_stats();
assert_eq!(stats2.allocation_count, 2); assert_eq!(stats2.deallocation_count, 1);
assert_eq!(stats2.current_usage, 0);
let obj3 = allocator.allocate_object("SafetyTest3").unwrap();
assert_ne!(obj3, 0);
let stats3 = allocator.get_stats();
assert_eq!(stats3.allocation_count, 3);
}
#[test]
fn test_primitive_array_element_sizes() {
let mut allocator = ArenaAllocator::new(1024);
let test_cases = vec![
(PrimitiveArrayType::Int, 4),
(PrimitiveArrayType::Byte, 1),
(PrimitiveArrayType::Short, 2),
(PrimitiveArrayType::Char, 2),
(PrimitiveArrayType::Long, 8),
(PrimitiveArrayType::Float, 4),
(PrimitiveArrayType::Double, 8),
(PrimitiveArrayType::Boolean, 1),
];
for (array_type, _expected_element_size) in &test_cases {
let array = allocator.allocate_array(
MemoryType::PrimitiveArray(array_type.clone()),
10
).unwrap();
assert_ne!(array, 0);
let stats = allocator.get_stats();
assert!(stats.total_allocated > 0);
}
let final_stats = allocator.get_stats();
assert_eq!(final_stats.allocation_count, test_cases.len() as u64);
}
#[test]
fn test_allocator_drop_safety() {
{
let mut _allocator = ArenaAllocator::new(256);
let _obj = _allocator.allocate_object("Test").unwrap();
}
let mut _another = ArenaAllocator::new(512);
let _result = _another.allocate_object("AnotherTest");
{
let mut _tlab = TlabAllocator::new(128);
let _obj = _tlab.allocate_object("TlabTest").unwrap();
}
let _final_tlab = TlabAllocator::new(256);
}
#[test]
fn test_memory_type_debug_format() {
let debug_cases = vec![
format!("{:?}", MemoryType::PrimitiveArray(PrimitiveArrayType::Int)),
format!("{:?}", MemoryType::ObjectArray("java/lang/String".to_string())),
format!("{:?}", MemoryType::MultiArray("I".to_string(), vec![2, 3])),
];
for debug_str in debug_cases {
assert!(!debug_str.is_empty());
assert!(debug_str.contains("PrimitiveArray") ||
debug_str.contains("ObjectArray") ||
debug_str.contains("MultiArray"));
}
}