use ixgbe_driver::{alloc_pkt, IxgbeError, IxgbeHal, MemPool, PACKET_HEADROOM};
struct MockHal;
unsafe impl IxgbeHal for MockHal {
fn dma_alloc(size: usize) -> (usize, core::ptr::NonNull<u8>) {
let layout = std::alloc::Layout::from_size_align(size, 4096).unwrap();
let ptr = unsafe { std::alloc::alloc(layout) };
if ptr.is_null() {
panic!("Memory allocation failed");
}
let phys_addr = ptr as usize; (phys_addr, core::ptr::NonNull::new(ptr).unwrap())
}
unsafe fn dma_dealloc(paddr: usize, vaddr: core::ptr::NonNull<u8>, size: usize) -> i32 {
let layout = std::alloc::Layout::from_size_align(size, 4096).unwrap();
std::alloc::dealloc(vaddr.as_ptr(), layout);
0
}
unsafe fn mmio_phys_to_virt(paddr: usize, size: usize) -> core::ptr::NonNull<u8> {
core::ptr::NonNull::new(paddr as *mut u8).unwrap()
}
unsafe fn mmio_virt_to_phys(vaddr: core::ptr::NonNull<u8>, size: usize) -> usize {
vaddr.as_ptr() as usize
}
fn wait_until(duration: core::time::Duration) -> Result<(), &'static str> {
Ok(())
}
}
#[test]
fn test_memory_pool_allocation() {
let pool = MemPool::allocate::<MockHal>(4096, 2048).expect("Failed to allocate memory pool");
assert_eq!(pool.entry_size(), 2048);
}
#[test]
fn test_memory_pool_invalid_size() {
let result = MemPool::allocate::<MockHal>(4096, 100);
assert!(matches!(result, Err(IxgbeError::PageNotAligned)));
}
#[test]
fn test_packet_allocation_and_deallocation() {
let pool = MemPool::allocate::<MockHal>(4096, 2048).unwrap();
let packet = alloc_pkt(&pool, 1500).expect("Failed to allocate packet");
assert_eq!(packet.len(), 1500);
let data = packet.as_bytes();
assert_eq!(data.len(), 1500);
drop(packet);
let packet2 = alloc_pkt(&pool, 1500).expect("Failed to allocate second packet");
assert_eq!(packet2.len(), 1500);
}
#[test]
fn test_packet_allocation_too_large() {
let pool = MemPool::allocate::<MockHal>(4096, 2048).unwrap();
let result = alloc_pkt(&pool, 2048 - PACKET_HEADROOM + 1);
assert!(result.is_none());
}
#[test]
fn test_packet_data_access() {
let pool = MemPool::allocate::<MockHal>(4096, 2048).unwrap();
let mut packet = alloc_pkt(&pool, 1500).unwrap();
{
let data = packet.as_mut_bytes();
data[0] = 0xFF;
data[1] = 0x00;
data[1499] = 0xAA;
}
{
let data = packet.as_bytes();
assert_eq!(data[0], 0xFF);
assert_eq!(data[1], 0x00);
assert_eq!(data[1499], 0xAA);
}
}
#[test]
fn test_packet_clone() {
let pool = MemPool::allocate::<MockHal>(4096, 2048).unwrap();
let mut original = alloc_pkt(&pool, 100).unwrap();
original.as_mut_bytes()[0] = 0x42;
let cloned = original.clone();
assert_eq!(cloned.len(), original.len());
assert_eq!(cloned.as_bytes()[0], 0x42);
original.as_mut_bytes()[0] = 0x24;
assert_eq!(original.as_bytes()[0], 0x24);
assert_eq!(cloned.as_bytes()[0], 0x42); }
#[test]
fn test_memory_pool_exhaustion() {
let pool = MemPool::allocate::<MockHal>(2, 2048).unwrap();
let packet1 = alloc_pkt(&pool, 1500).unwrap();
let packet2 = alloc_pkt(&pool, 1500).unwrap();
let packet3 = alloc_pkt(&pool, 1500);
assert!(packet3.is_none());
drop(packet1);
let packet4 = alloc_pkt(&pool, 1500).unwrap();
assert_eq!(packet4.len(), 1500);
}
#[test]
fn test_packet_headroom_access() {
let pool = MemPool::allocate::<MockHal>(4096, 2048).unwrap();
let mut packet = alloc_pkt(&pool, 1500).unwrap();
{
let headroom = packet.headroom_mut(10);
assert_eq!(headroom.len(), 10);
headroom[0] = 0xDE;
headroom[9] = 0xAD;
}
assert_eq!(packet.as_bytes()[0], 0); }
#[test]
#[should_panic]
fn test_packet_headroom_too_large() {
let pool = MemPool::allocate::<MockHal>(4096, 2048).unwrap();
let mut packet = alloc_pkt(&pool, 1500).unwrap();
let _ = packet.headroom_mut(PACKET_HEADROOM + 1);
}