Move unit tests inside conditionally compiled mod tests { } blocks

Idiomatic rust organizes unit tests into `mod tests { }` blocks
using conditional compilation `[cfg(test)]` to decide whether to
compile the code in that block.

This commit moves "bare" test functions into such blocks, and puts
the block at the bottom of respective file.
This commit is contained in:
Martin Algesten
2021-03-14 11:44:01 +01:00
parent 239ba342a2
commit 91cb0ce5fc
7 changed files with 295 additions and 271 deletions

View File

@@ -150,6 +150,25 @@ fn copy_chunked<R: Read, W: Write>(reader: &mut R, writer: &mut W) -> io::Result
}
}
/// Helper to send a body, either as chunked or not.
pub(crate) fn send_body(
mut body: SizedReader,
do_chunk: bool,
stream: &mut Stream,
) -> io::Result<()> {
if do_chunk {
copy_chunked(&mut body.reader, stream)?;
} else {
copy(&mut body.reader, stream)?;
};
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_copy_chunked() {
let mut source = Vec::<u8>::new();
@@ -169,18 +188,4 @@ fn test_copy_chunked() {
assert_eq!(dest, dest_expected);
}
/// Helper to send a body, either as chunked or not.
pub(crate) fn send_body(
mut body: SizedReader,
do_chunk: bool,
stream: &mut Stream,
) -> io::Result<()> {
if do_chunk {
copy_chunked(&mut body.reader, stream)?;
} else {
copy(&mut body.reader, stream)?;
};
Ok(())
}

View File

@@ -342,6 +342,10 @@ impl fmt::Display for ErrorKind {
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn status_code_error() {
let mut response = Response::new(404, "NotFound", "").unwrap();
@@ -412,3 +416,4 @@ fn error_is_send_and_sync() {
takes_send(crate::error::ErrorKind::InvalidUrl.new());
takes_sync(crate::error::ErrorKind::InvalidUrl.new());
}
}

View File

@@ -145,6 +145,10 @@ impl FromStr for Header {
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_valid_name() {
assert!(valid_name("example"));
@@ -214,3 +218,4 @@ fn name_and_value() {
assert!(header.is_name("x-forwarded-for"));
assert!(header.is_name("X-FORWARDED-FOR"));
}
}

View File

@@ -219,6 +219,70 @@ impl PoolKey {
}
}
/// Read wrapper that returns the stream to the pool once the
/// read is exhausted (reached a 0).
///
/// *Internal API*
pub(crate) struct PoolReturnRead<R: Read + Sized + Into<Stream>> {
// unit that contains the agent where we want to return the reader.
unit: Option<Unit>,
// wrapped reader around the same stream
reader: Option<R>,
}
impl<R: Read + Sized + Into<Stream>> PoolReturnRead<R> {
pub fn new(unit: Option<Unit>, reader: R) -> Self {
PoolReturnRead {
unit,
reader: Some(reader),
}
}
fn return_connection(&mut self) -> io::Result<()> {
// guard we only do this once.
if let (Some(unit), Some(reader)) = (self.unit.take(), self.reader.take()) {
// bring back stream here to either go into pool or dealloc
let mut stream = reader.into();
if !stream.is_poolable() {
// just let it deallocate
return Ok(());
}
// ensure stream can be reused
stream.reset()?;
// insert back into pool
let key = PoolKey::new(&unit.url, unit.agent.config.proxy.clone());
unit.agent.state.pool.add(key, stream);
}
Ok(())
}
fn do_read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match self.reader.as_mut() {
None => Ok(0),
Some(reader) => reader.read(buf),
}
}
}
impl<R: Read + Sized + Into<Stream>> Read for PoolReturnRead<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let amount = self.do_read(buf)?;
// only if the underlying reader is exhausted can we send a new
// request to the same socket. hence, we only return it now.
if amount == 0 {
self.return_connection()?;
}
Ok(amount)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn poolkey_new() {
// Test that PoolKey::new() does not panic on unrecognized schemes.
@@ -300,63 +364,4 @@ fn pool_checks_proxy() {
);
assert_eq!(pool.len(), 3);
}
/// Read wrapper that returns the stream to the pool once the
/// read is exhausted (reached a 0).
///
/// *Internal API*
pub(crate) struct PoolReturnRead<R: Read + Sized + Into<Stream>> {
// unit that contains the agent where we want to return the reader.
unit: Option<Unit>,
// wrapped reader around the same stream
reader: Option<R>,
}
impl<R: Read + Sized + Into<Stream>> PoolReturnRead<R> {
pub fn new(unit: Option<Unit>, reader: R) -> Self {
PoolReturnRead {
unit,
reader: Some(reader),
}
}
fn return_connection(&mut self) -> io::Result<()> {
// guard we only do this once.
if let (Some(unit), Some(reader)) = (self.unit.take(), self.reader.take()) {
// bring back stream here to either go into pool or dealloc
let mut stream = reader.into();
if !stream.is_poolable() {
// just let it deallocate
return Ok(());
}
// ensure stream can be reused
stream.reset()?;
// insert back into pool
let key = PoolKey::new(&unit.url, unit.agent.config.proxy.clone());
unit.agent.state.pool.add(key, stream);
}
Ok(())
}
fn do_read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
match self.reader.as_mut() {
None => Ok(0),
Some(reader) => reader.read(buf),
}
}
}
impl<R: Read + Sized + Into<Stream>> Read for PoolReturnRead<R> {
fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
let amount = self.do_read(buf)?;
// only if the underlying reader is exhausted can we send a new
// request to the same socket. hence, we only return it now.
if amount == 0 {
self.return_connection()?;
}
Ok(amount)
}
}

View File

@@ -171,8 +171,7 @@ Proxy-Connection: Keep-Alive\r\n\
#[cfg(test)]
mod tests {
use super::Proto;
use super::Proxy;
use super::*;
#[test]
fn parse_proxy_fakeproto() {

View File

@@ -397,6 +397,10 @@ impl Request {
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn request_implements_send_and_sync() {
let _request: Box<dyn Send> = Box::new(Request::new(
@@ -419,3 +423,4 @@ fn send_byte_slice() {
.send(&bytes[1..2])
.ok();
}
}

View File

@@ -632,15 +632,6 @@ impl<R: Read> Read for LimitedRead<R> {
}
}
#[test]
fn short_read() {
use std::io::Cursor;
let mut lr = LimitedRead::new(Cursor::new(vec![b'a'; 3]), 10);
let mut buf = vec![0; 1000];
let result = lr.read_to_end(&mut buf);
assert!(result.err().unwrap().kind() == io::ErrorKind::UnexpectedEof);
}
impl<R: Read> From<LimitedRead<R>> for Stream
where
Stream: From<R>,
@@ -667,10 +658,30 @@ pub(crate) fn charset_from_content_type(header: Option<&str>) -> &str {
.unwrap_or(DEFAULT_CHARACTER_SET)
}
// ErrorReader returns an error for every read.
// The error is as close to a clone of the underlying
// io::Error as we can get.
struct ErrorReader(io::Error);
impl Read for ErrorReader {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
Err(io::Error::new(self.0.kind(), self.0.to_string()))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn short_read() {
use std::io::Cursor;
let mut lr = LimitedRead::new(Cursor::new(vec![b'a'; 3]), 10);
let mut buf = vec![0; 1000];
let result = lr.read_to_end(&mut buf);
assert!(result.err().unwrap().kind() == io::ErrorKind::UnexpectedEof);
}
#[test]
fn content_type_without_charset() {
let s = "HTTP/1.1 200 OK\r\n\
@@ -823,14 +834,3 @@ mod tests {
assert_eq!(hist, ["http://1.example.com/", "http://2.example.com/"])
}
}
// ErrorReader returns an error for every read.
// The error is as close to a clone of the underlying
// io::Error as we can get.
struct ErrorReader(io::Error);
impl Read for ErrorReader {
fn read(&mut self, _buf: &mut [u8]) -> io::Result<usize> {
Err(io::Error::new(self.0.kind(), self.0.to_string()))
}
}