#[cfg(target_os = "linux")]
#[tokio::test]
async fn test_buffer_ownership_after_completion(
) -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
use safer_ring::{OwnedBuffer, Ring};
use std::io::Write;
use std::os::unix::io::FromRawFd;
use std::time::Duration;
use tokio::time::timeout;
let mut pipe_fds = [-1; 2];
assert_eq!(unsafe { libc::pipe(pipe_fds.as_mut_ptr()) }, 0);
let (read_fd, write_fd) = (pipe_fds[0], pipe_fds[1]);
let _read_pipe = unsafe { std::fs::File::from_raw_fd(read_fd) };
let mut write_pipe = unsafe { std::fs::File::from_raw_fd(write_fd) };
let ring = Ring::new(32)?;
let buffer = OwnedBuffer::new(1024);
tokio::spawn(async move {
tokio::time::sleep(Duration::from_millis(10)).await;
write_pipe.write_all(b"hello").unwrap();
write_pipe.flush().unwrap();
});
let read_future = ring.read_owned(read_fd, buffer);
let (bytes_read, returned_buffer) = timeout(Duration::from_secs(2), read_future)
.await
.expect("Test timed out")
.expect("Read operation failed");
assert_eq!(bytes_read, 5, "Should have read 5 bytes");
if let Some(guard) = returned_buffer.try_access() {
assert_eq!(guard.len(), 1024);
assert_eq!(&guard[..5], b"hello");
println!("✓ Buffer is returned to the user after completion with read data");
} else {
panic!("Buffer should be user-owned after completion");
}
assert!(
returned_buffer.is_user_owned(),
"Buffer should be user-owned after completion"
);
println!("✓ Buffer ownership is correctly transferred back to user");
Ok(())
}
#[cfg(not(target_os = "linux"))]
#[test]
fn test_polling_api_buffer_ownership_non_linux() {
use safer_ring::Ring;
match Ring::new(32) {
Ok(_) => panic!("Ring creation should fail on non-Linux platforms"),
Err(e) => {
println!("Expected error on non-Linux platform: {}", e);
}
}
}
#[test]
fn test_completion_result_behavior() {
use safer_ring::operation::OperationType;
assert!(OperationType::Read.requires_buffer());
assert!(OperationType::Read.is_read_like());
assert!(!OperationType::Read.is_write_like());
assert!(!OperationType::Read.is_vectored());
assert!(!OperationType::Accept.requires_buffer());
assert!(!OperationType::Accept.is_read_like());
assert!(!OperationType::Accept.is_write_like());
println!("Operation types work correctly");
}