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:
33
src/body.rs
33
src/body.rs
@@ -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(())
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"));
|
||||
}
|
||||
}
|
||||
|
||||
123
src/pool.rs
123
src/pool.rs
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()))
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user