Finish writing FramedTransport tests

pull/146/head
Chip Senkbeil 2 years ago
parent 5c0a04962e
commit 1749ada5c8
No known key found for this signature in database
GPG Key ID: 35EF1F8EC72A4131

@ -205,6 +205,20 @@ mod tests {
}
}
/// Codec that always fails
#[derive(Clone)]
struct ErrorCodec;
impl Codec for ErrorCodec {
fn encode(&mut self, _item: &[u8], _dst: &mut BytesMut) -> io::Result<()> {
Err(io::Error::from(io::ErrorKind::Other))
}
fn decode(&mut self, _src: &mut BytesMut) -> io::Result<Option<Vec<u8>>> {
Err(io::Error::from(io::ErrorKind::Other))
}
}
#[test]
fn try_read_frame_should_return_would_block_if_fails_to_read_frame_before_blocking() {
// Should fail if immediately blocks
@ -250,41 +264,239 @@ mod tests {
#[test]
fn try_read_frame_should_return_error_if_encountered_error_with_reading_bytes() {
todo!();
let mut transport = FramedTransport::new(
TestTransport {
f_try_read: Box::new(|_| Err(io::Error::from(io::ErrorKind::NotConnected))),
f_ready: Box::new(|_| Ok(Ready::READABLE)),
..Default::default()
},
TestCodec,
);
assert_eq!(
transport.try_read_frame().unwrap_err().kind(),
io::ErrorKind::NotConnected
);
}
#[test]
fn try_read_frame_should_return_none_if_encountered_error_during_decode() {
todo!();
fn try_read_frame_should_return_error_if_encountered_error_during_decode() {
let mut transport = FramedTransport::new(
TestTransport {
f_try_read: Box::new(|buf| {
buf[0] = b'a';
Ok(1)
}),
f_ready: Box::new(|_| Ok(Ready::READABLE)),
..Default::default()
},
ErrorCodec,
);
assert_eq!(
transport.try_read_frame().unwrap_err().kind(),
io::ErrorKind::Other
);
}
#[test]
fn try_read_frame_should_return_next_available_frame() {
todo!();
let data = {
let mut data = BytesMut::new();
TestCodec.encode(b"hello world", &mut data).unwrap();
data.freeze()
};
let mut transport = FramedTransport::new(
TestTransport {
f_try_read: Box::new(move |buf| {
buf[..data.len()].copy_from_slice(data.as_ref());
Ok(data.len())
}),
f_ready: Box::new(|_| Ok(Ready::READABLE)),
..Default::default()
},
TestCodec,
);
assert_eq!(transport.try_read_frame().unwrap().unwrap(), b"hello world");
}
#[test]
fn try_read_frame_should_keep_reading_until_a_frame_is_found() {
const STEP_SIZE: usize = 7;
let data_1 = {
let mut data = BytesMut::new();
TestCodec.encode(b"hello world", &mut data).unwrap();
data.freeze()
};
let data_2 = {
let mut data = BytesMut::new();
TestCodec.encode(b"test hello", &mut data).unwrap();
data.freeze()
};
let data = [data_1, data_2].concat();
let mut transport = FramedTransport::new(
TestTransport {
f_try_read: Box::new(move |buf| {
static mut IDX: usize = 0;
unsafe {
let len: usize = IDX + STEP_SIZE;
let len = if len > data.len() { data.len() } else { len };
buf[..STEP_SIZE].copy_from_slice(&data[IDX..len]);
IDX += STEP_SIZE;
Ok(STEP_SIZE)
}
}),
f_ready: Box::new(|_| Ok(Ready::READABLE)),
..Default::default()
},
TestCodec,
);
assert_eq!(transport.try_read_frame().unwrap().unwrap(), b"hello world");
// Should have leftover bytes from next frame; for our test encoder
// we have a single byte length (10 for "test hello") and the first character
assert_eq!(transport.incoming.to_vec(), [10, b't']);
}
#[test]
fn try_write_frame_should_return_would_block_if_fails_to_write_frame_before_blocking() {
todo!();
let mut transport = FramedTransport::new(
TestTransport {
f_try_write: Box::new(|_| Err(io::Error::from(io::ErrorKind::WouldBlock))),
f_ready: Box::new(|_| Ok(Ready::WRITABLE)),
..Default::default()
},
TestCodec,
);
// First call will only write part of the frame and then return WouldBlock
assert_eq!(
transport
.try_write_frame(b"hello world")
.unwrap_err()
.kind(),
io::ErrorKind::WouldBlock
);
}
#[test]
fn try_write_frame_should_return_error_if_encountered_error_with_writing_bytes() {
todo!();
let mut transport = FramedTransport::new(
TestTransport {
f_try_write: Box::new(|_| Err(io::Error::from(io::ErrorKind::NotConnected))),
f_ready: Box::new(|_| Ok(Ready::WRITABLE)),
..Default::default()
},
TestCodec,
);
assert_eq!(
transport
.try_write_frame(b"hello world")
.unwrap_err()
.kind(),
io::ErrorKind::NotConnected
);
}
#[test]
fn try_write_frame_should_return_error_if_encountered_error_during_encode() {
todo!();
let mut transport = FramedTransport::new(
TestTransport {
f_try_write: Box::new(|buf| Ok(buf.len())),
f_ready: Box::new(|_| Ok(Ready::WRITABLE)),
..Default::default()
},
ErrorCodec,
);
assert_eq!(
transport
.try_write_frame(b"hello world")
.unwrap_err()
.kind(),
io::ErrorKind::Other
);
}
#[test]
fn try_write_frame_should_write_entire_frame_if_possible() {
todo!();
let (tx, rx) = std::sync::mpsc::sync_channel(1);
let mut transport = FramedTransport::new(
TestTransport {
f_try_write: Box::new(move |buf| {
let len = buf.len();
tx.send(buf.to_vec()).unwrap();
Ok(len)
}),
f_ready: Box::new(|_| Ok(Ready::WRITABLE)),
..Default::default()
},
TestCodec,
);
transport.try_write_frame(b"hello world").unwrap();
// Transmitted data should be encoded using the framed transport's codec
assert_eq!(
rx.try_recv().unwrap(),
[&[11], b"hello world".as_slice()].concat()
);
}
#[test]
fn try_write_frame_should_write_any_prior_queued_bytes_before_writing_next_frame() {
todo!();
const STEP_SIZE: usize = 5;
let (tx, rx) = std::sync::mpsc::sync_channel(10);
let mut transport = FramedTransport::new(
TestTransport {
f_try_write: Box::new(move |buf| {
static mut CNT: usize = 0;
unsafe {
CNT += 1;
if CNT == 2 {
Err(io::Error::from(io::ErrorKind::WouldBlock))
} else {
let len = std::cmp::min(STEP_SIZE, buf.len());
tx.send(buf[..len].to_vec()).unwrap();
Ok(len)
}
}
}),
f_ready: Box::new(|_| Ok(Ready::WRITABLE)),
..Default::default()
},
TestCodec,
);
// First call will only write part of the frame and then return WouldBlock
assert_eq!(
transport
.try_write_frame(b"hello world")
.unwrap_err()
.kind(),
io::ErrorKind::WouldBlock
);
// Transmitted data should be encoded using the framed transport's codec
assert_eq!(rx.try_recv().unwrap(), [&[11], b"hell".as_slice()].concat());
assert_eq!(
rx.try_recv().unwrap_err(),
std::sync::mpsc::TryRecvError::Empty
);
// Next call will keep writing successfully until done
transport.try_write_frame(b"test").unwrap();
assert_eq!(rx.try_recv().unwrap(), b"o wor");
assert_eq!(
rx.try_recv().unwrap(),
[b"ld".as_slice(), &[4], b"te".as_slice()].concat()
);
assert_eq!(rx.try_recv().unwrap(), b"st");
assert_eq!(
rx.try_recv().unwrap_err(),
std::sync::mpsc::TryRecvError::Empty
);
}
}

Loading…
Cancel
Save