1 use integration_tests::pb::{test_client::TestClient, test_server, Input, Output};
2 use std::time::Duration;
3 use tokio::{net::TcpListener, sync::oneshot};
4 use tonic::{
5     transport::{server::TcpIncoming, Endpoint, Server},
6     GrpcMethod, Request, Response, Status,
7 };
8 
9 #[tokio::test]
interceptor_retrieves_grpc_method()10 async fn interceptor_retrieves_grpc_method() {
11     use test_server::Test;
12 
13     struct Svc;
14 
15     #[tonic::async_trait]
16     impl Test for Svc {
17         async fn unary_call(&self, _: Request<Input>) -> Result<Response<Output>, Status> {
18             Ok(Response::new(Output {}))
19         }
20     }
21 
22     let svc = test_server::TestServer::new(Svc);
23 
24     let (tx, rx) = oneshot::channel();
25 
26     let listener = TcpListener::bind("127.0.0.1:0").await.unwrap();
27     let addr = listener.local_addr().unwrap();
28     let incoming = TcpIncoming::from(listener).with_nodelay(Some(true));
29 
30     // Start the server now, second call should succeed
31     let jh = tokio::spawn(async move {
32         Server::builder()
33             .add_service(svc)
34             .serve_with_incoming_shutdown(incoming, async { drop(rx.await) })
35             .await
36             .unwrap();
37     });
38 
39     let channel = Endpoint::from_shared(format!("http://{addr}"))
40         .unwrap()
41         .connect_lazy();
42 
43     fn client_intercept(req: Request<()>) -> Result<Request<()>, Status> {
44         println!("Intercepting client request: {:?}", req);
45 
46         let gm = req.extensions().get::<GrpcMethod>().unwrap();
47         assert_eq!(gm.service(), "test.Test");
48         assert_eq!(gm.method(), "UnaryCall");
49 
50         Ok(req)
51     }
52     let mut client = TestClient::with_interceptor(channel, client_intercept);
53 
54     tokio::time::sleep(Duration::from_millis(100)).await;
55     client.unary_call(Request::new(Input {})).await.unwrap();
56 
57     tx.send(()).unwrap();
58     jh.await.unwrap();
59 }
60