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