use super::*;
#[test]
fn test_alloc_oversize_100gb() {
let ctx = CudaContext::new(0).expect("Context");
let oversize = 25_000_000_000usize;
let result = GpuBuffer::<f32>::new(&ctx, oversize);
match result {
Err(GpuError::OutOfMemory { .. }) => {
}
Err(GpuError::MemoryAllocation(_)) => {
}
Err(e) => {
println!("Oversize alloc returned: {:?}", e);
}
Ok(_) => {
panic!("CRITICAL: 100GB allocation succeeded - this should be impossible on RTX 4090!");
}
}
}
#[test]
fn test_copy_from_host_too_small() {
let ctx = CudaContext::new(0).expect("Context");
let mut buf = GpuBuffer::<f32>::new(&ctx, 1000).expect("Alloc");
let small_data = vec![1.0f32; 500];
let result = buf.copy_from_host(&small_data);
assert!(result.is_err(), "copy_from_host should fail when host buffer is smaller");
if let Err(e) = result {
assert!(
format!("{:?}", e).contains("mismatch") || format!("{:?}", e).contains("Transfer"),
"Error should mention size mismatch: {:?}",
e
);
}
}
#[test]
fn test_copy_to_host_too_large() {
let ctx = CudaContext::new(0).expect("Context");
let buf = GpuBuffer::<f32>::new(&ctx, 100).expect("Alloc");
let mut large_data = vec![0.0f32; 500];
let result = buf.copy_to_host(&mut large_data);
assert!(result.is_err(), "copy_to_host should fail when host buffer size doesn't match");
}
#[test]
fn test_copy_from_host_at_out_of_bounds() {
let ctx = CudaContext::new(0).expect("Context");
let mut buf = GpuBuffer::<f32>::new(&ctx, 100).expect("Alloc");
let data = vec![1.0f32; 50];
let result = buf.copy_from_host_at(&data, 60);
assert!(result.is_err(), "copy_from_host_at should fail when offset+len > buffer size");
}
#[test]
fn test_copy_to_host_at_out_of_bounds() {
let ctx = CudaContext::new(0).expect("Context");
let data = vec![1.0f32; 100];
let buf = GpuBuffer::from_host(&ctx, &data).expect("Alloc");
let mut result = vec![0.0f32; 50];
let copy_result = buf.copy_to_host_at(&mut result, 60);
assert!(copy_result.is_err(), "copy_to_host_at should fail when offset+len > buffer size");
}
#[test]
fn test_d2d_copy_size_mismatch() {
let ctx = CudaContext::new(0).expect("Context");
let src = GpuBuffer::<f32>::new(&ctx, 100).expect("Alloc src");
let mut dst = GpuBuffer::<f32>::new(&ctx, 200).expect("Alloc dst");
let result = dst.copy_from_buffer(&src);
assert!(result.is_err(), "D2D copy should fail when buffer sizes don't match");
}
#[test]
fn test_d2d_copy_at_dst_out_of_bounds() {
let ctx = CudaContext::new(0).expect("Context");
let src = GpuBuffer::<f32>::new(&ctx, 50).expect("Alloc src");
let mut dst = GpuBuffer::<f32>::new(&ctx, 100).expect("Alloc dst");
let result = dst.copy_from_buffer_at(&src, 60, 0, 50);
assert!(result.is_err(), "D2D copy_at should fail when dst_offset+count > dst.len");
}
#[test]
fn test_d2d_copy_at_src_out_of_bounds() {
let ctx = CudaContext::new(0).expect("Context");
let src = GpuBuffer::<f32>::new(&ctx, 50).expect("Alloc src");
let mut dst = GpuBuffer::<f32>::new(&ctx, 100).expect("Alloc dst");
let result = dst.copy_from_buffer_at(&src, 0, 30, 50);
assert!(result.is_err(), "D2D copy_at should fail when src_offset+count > src.len");
}
#[test]
fn test_raii_cleanup_single_buffer() {
let ctx = CudaContext::new(0).expect("Context");
let (free_before, _) = ctx.memory_info().expect("Memory info");
let size = 25_000_000; {
let _buf = GpuBuffer::<f32>::new(&ctx, size).expect("Alloc");
let (free_during, _) = ctx.memory_info().expect("Memory info");
assert!(
free_during < free_before,
"Memory should decrease after allocation: before={}, during={}",
free_before,
free_during
);
}
let (free_after, _) = ctx.memory_info().expect("Memory info");
let tolerance = 10 * 1024 * 1024;
assert!(
free_after >= free_before - tolerance,
"Memory leak detected! before={}, after={}, diff={}",
free_before,
free_after,
free_before.saturating_sub(free_after)
);
}