use std::net::UdpSocket;
use super::{runtime, within};
use crate::io::Handle;
const SIZES: [usize; 3] = [513, 1400, 9000];
fn pattern(len: usize, seed: u8) -> Vec<u8> {
(0..len)
.map(|i| (i as u8).wrapping_mul(13) ^ (i >> 8) as u8 ^ seed)
.collect()
}
#[test]
fn a_datagram_comes_whole_after_a_look_at_its_sender_or_a_short_peek() {
let rt = runtime();
rt.block_on(async {
let a = Handle::<UdpSocket>::bind("127.0.0.1:0").await.unwrap();
let b = Handle::<UdpSocket>::bind("127.0.0.1:0").await.unwrap();
let (from, to) = (a.local_addr().unwrap(), b.local_addr().unwrap());
let mut got = vec![0u8; 64 * 1024];
for (seed, &len) in SIZES.iter().enumerate() {
let sent = pattern(len, seed as u8);
let (sender, wrote) = within(super::join(b.peek_sender(), async {
crate::time::sleep(std::time::Duration::from_millis(5)).await;
a.send_to(&sent, to).await
}))
.await;
assert_eq!((sender.unwrap(), wrote.unwrap()), (from, len));
let mut short = [0u8; 16];
let peeked = within(b.peek_from(&mut short)).await;
#[cfg(unix)]
assert_eq!(peeked.unwrap(), (16, from));
#[cfg(windows)]
assert_eq!(peeked.unwrap_err().raw_os_error(), Some(10040));
assert_eq!(short, sent[..16]);
let (n, sender) = within(b.recv_from(&mut got)).await.unwrap();
assert_eq!((n, sender), (len, from), "a datagram of {len} bytes");
assert!(got[..n] == sent[..], "the datagram of {len} bytes differs");
}
});
}