use crate::ingress::{Protocol, SenderBuilder};
use std::io;
use std::net::UdpSocket;
use std::time::Duration;
pub struct QwpUdpMock {
socket: UdpSocket,
host: &'static str,
port: u16,
}
impl QwpUdpMock {
pub fn new() -> io::Result<Self> {
let socket = UdpSocket::bind("127.0.0.1:0")?;
socket.set_read_timeout(Some(Duration::from_millis(500)))?;
let port = socket.local_addr()?.port();
Ok(Self {
socket,
host: "127.0.0.1",
port,
})
}
pub fn sender_builder(&self) -> SenderBuilder {
SenderBuilder::new(Protocol::Udp, self.host, self.port)
}
pub fn recv_datagram(&self) -> io::Result<Vec<u8>> {
let mut buf = vec![0u8; 65_536];
let (len, _) = self.socket.recv_from(&mut buf)?;
buf.truncate(len);
Ok(buf)
}
pub fn recv_datagrams(&self, count: usize) -> io::Result<Vec<Vec<u8>>> {
let mut datagrams = Vec::with_capacity(count);
for _ in 0..count {
datagrams.push(self.recv_datagram()?);
}
Ok(datagrams)
}
pub fn assert_no_datagram(&self) -> io::Result<()> {
let previous_timeout = self.socket.read_timeout()?;
self.socket
.set_read_timeout(Some(Duration::from_millis(50)))?;
let result = self.recv_datagram();
self.socket.set_read_timeout(previous_timeout)?;
match result {
Ok(datagram) => Err(io::Error::other(format!(
"unexpected datagram of {} bytes",
datagram.len()
))),
Err(err)
if err.kind() == io::ErrorKind::WouldBlock
|| err.kind() == io::ErrorKind::TimedOut =>
{
Ok(())
}
Err(err) => Err(err),
}
}
}