1 #![cfg(feature = "steer")]
2 #[path = "../support.rs"]
3 mod support;
4
5 use futures_util::future::{ready, Ready};
6 use std::task::{Context, Poll};
7 use tower::steer::Steer;
8 use tower_service::Service;
9
10 type StdError = Box<dyn std::error::Error + Send + Sync + 'static>;
11
12 struct MyService(u8, bool);
13
14 impl Service<String> for MyService {
15 type Response = u8;
16 type Error = StdError;
17 type Future = Ready<Result<u8, Self::Error>>;
18
poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>>19 fn poll_ready(&mut self, _cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
20 if !self.1 {
21 Poll::Pending
22 } else {
23 Poll::Ready(Ok(()))
24 }
25 }
26
call(&mut self, _req: String) -> Self::Future27 fn call(&mut self, _req: String) -> Self::Future {
28 ready(Ok(self.0))
29 }
30 }
31
32 #[tokio::test(flavor = "current_thread")]
pick_correctly()33 async fn pick_correctly() {
34 let _t = support::trace_init();
35 let srvs = vec![MyService(42, true), MyService(57, true)];
36 let mut st = Steer::new(srvs, |_: &_, _: &[_]| 1);
37
38 futures_util::future::poll_fn(|cx| st.poll_ready(cx))
39 .await
40 .unwrap();
41 let r = st.call(String::from("foo")).await.unwrap();
42 assert_eq!(r, 57);
43 }
44
45 #[tokio::test(flavor = "current_thread")]
pending_all_ready()46 async fn pending_all_ready() {
47 let _t = support::trace_init();
48
49 let srvs = vec![MyService(42, true), MyService(57, false)];
50 let mut st = Steer::new(srvs, |_: &_, _: &[_]| 0);
51
52 let p = futures_util::poll!(futures_util::future::poll_fn(|cx| st.poll_ready(cx)));
53 match p {
54 Poll::Pending => (),
55 _ => panic!(
56 "Steer should not return poll_ready if at least one component service is not ready"
57 ),
58 }
59 }
60