use crate::error::*;
use crate::http::client::*;
use crate::http::types::{HeaderMap, ResponseMetadata};
use reqwest::Client as InnerClient;
use reqwest::{Method, Request, RequestBuilder, Url};
use std::cell::RefCell;
use std::collections::VecDeque;
use std::time::Duration;
struct RetriesTestClient {
inner: InnerClient,
requests: RefCell<VecDeque<Request>>,
sleeps: RefCell<Vec<Duration>>,
}
impl RetriesTestClient {
pub(crate) fn new() -> Self {
RetriesTestClient {
inner: InnerClient::new(),
requests: RefCell::new(VecDeque::new()),
sleeps: RefCell::new(Vec::new()),
}
}
}
impl AbstractClient for RetriesTestClient {
fn execute(&self, request: Request) -> Result<(ResponseMetadata, Vec<u8>)> {
self.requests.borrow_mut().push_back(request);
Ok((
ResponseMetadata {
status: 503,
headers: HeaderMap::new(),
},
Vec::new(),
))
}
fn sleep(&self, _: fn(Duration), duration: Duration) {
self.sleeps.borrow_mut().push(duration);
}
fn get(&self, url: Url) -> RequestBuilder {
self.inner.get(url)
}
fn post(&self, url: Url) -> RequestBuilder {
self.inner.post(url)
}
fn put(&self, url: Url) -> RequestBuilder {
self.inner.put(url)
}
fn patch(&self, url: Url) -> RequestBuilder {
self.inner.patch(url)
}
fn delete(&self, url: Url) -> RequestBuilder {
self.inner.delete(url)
}
fn head(&self, url: Url) -> RequestBuilder {
self.inner.head(url)
}
}
#[test]
fn test_execute_with_retries_too_many() {
crate::init().unwrap();
let client = RetriesTestClient::new();
assert!(
client
.execute_with_retries(
59,
false,
Method::GET,
"http://www.google.com/".parse().unwrap(),
None,
None
)
.is_err()
);
assert!(client.requests.borrow().is_empty());
assert!(client.sleeps.borrow().is_empty());
}
#[test]
fn test_execute_with_retries_single() {
crate::init().unwrap();
let client = RetriesTestClient::new();
assert!(
client
.execute_with_retries(
0,
false,
Method::GET,
"http://www.google.com/".parse().unwrap(),
None,
None
)
.is_err()
);
assert_eq!(1, client.requests.borrow().len());
assert!(client.sleeps.borrow().is_empty());
}
#[test]
fn test_execute_with_retries_many() {
crate::init().unwrap();
let client = RetriesTestClient::new();
assert!(
client
.execute_with_retries(
5,
false,
Method::GET,
"http://www.google.com/".parse().unwrap(),
None,
None
)
.is_err()
);
assert_eq!(6, client.requests.borrow().len());
assert!(
vec![
Duration::from_millis(100),
Duration::from_millis(200),
Duration::from_millis(400),
Duration::from_millis(800),
Duration::from_millis(1600),
]
.iter()
.eq(client.sleeps.borrow().iter()),
);
}
#[test]
fn test_trait_object_works() {
crate::init().unwrap();
let client: Box<dyn AbstractClient> = Box::new(RetriesTestClient::new());
assert!(
client
.execute_with_retries(
0,
false,
Method::GET,
"http://www.google.com/".parse().unwrap(),
None,
None
)
.is_err()
);
}