blob: 1ff08d32c4ec5607a567186893bf1db36cf93445 [file] [log] [blame]
#![cfg(feature = "steer")]
#[path = "../support.rs"]
mod support;
use futures_util::future::{ready, Ready};
use std::task::{Context, Poll};
use tower::steer::Steer;
use tower_service::Service;
type StdError = Box<dyn std::error::Error + Send + Sync + 'static>;
struct MyService(u8, bool);
impl Service<String> for MyService {
type Response = u8;
type Error = StdError;
type Future = Ready<Result<u8, Self::Error>>;
fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
if !self.1 {
Poll::Pending
} else {
Poll::Ready(Ok(()))
}
}
fn call(&mut self, _req: String) -> Self::Future {
ready(Ok(self.0))
}
}
#[tokio::test(flavor = "current_thread")]
async fn pick_correctly() {
let _t = support::trace_init();
let srvs = vec![MyService(42, true), MyService(57, true)];
let mut st = Steer::new(srvs, |_: &_, _: &[_]| 1);
futures_util::future::poll_fn(|cx| st.poll_ready(cx))
.await
.unwrap();
let r = st.call(String::from("foo")).await.unwrap();
assert_eq!(r, 57);
}
#[tokio::test(flavor = "current_thread")]
async fn pending_all_ready() {
let _t = support::trace_init();
let srvs = vec![MyService(42, true), MyService(57, false)];
let mut st = Steer::new(srvs, |_: &_, _: &[_]| 0);
let p = futures_util::poll!(futures_util::future::poll_fn(|cx| st.poll_ready(cx)));
match p {
Poll::Pending => (),
_ => panic!(
"Steer should not return poll_ready if at least one component service is not ready"
),
}
}