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