use dope::transport::link::egress::Queue;
use o3::buffer::Shared;
fn iov_bytes(q: &mut Queue<8>) -> Vec<u8> {
let v = q.prepare_send(u32::MAX as usize);
let mut out = Vec::new();
for iov in v.iovs {
let slice =
unsafe { std::slice::from_raw_parts(iov.as_ptr(), iov.len()) };
out.extend_from_slice(slice);
}
out
}
#[test]
fn back_to_back_push_preserves_all_chunks() {
let mut q: Queue<8> = Queue::new();
q.push(Shared::copy_from_slice(b"AAAA"));
q.push(Shared::copy_from_slice(b"BBBB"));
assert_eq!(q.total_bytes(), 8);
assert_eq!(iov_bytes(&mut q), b"AAAABBBB");
}
#[test]
fn ack_partial_then_remaining_preserved() {
let mut q: Queue<8> = Queue::new();
q.push(Shared::copy_from_slice(b"AAAA"));
q.push(Shared::copy_from_slice(b"BBBB"));
q.ack(6);
assert_eq!(q.total_bytes(), 2);
assert_eq!(iov_bytes(&mut q), b"BB");
q.ack(2);
assert_eq!(q.total_bytes(), 0);
assert!(iov_bytes(&mut q).is_empty());
}
#[test]
fn many_chunks_drain_in_order() {
let mut q: Queue<8> = Queue::new();
for i in 0..6u8 {
q.push(Shared::copy_from_slice(&[b'0' + i; 3]));
}
assert_eq!(q.total_bytes(), 18);
let mut acc = Vec::new();
while q.total_bytes() > 0 {
let chunk = iov_bytes(&mut q);
assert!(!chunk.is_empty());
let take = chunk.len().min(4);
acc.extend_from_slice(&chunk[..take]);
q.ack(take);
}
assert_eq!(acc, b"000111222333444555");
}