1 #![allow(missing_docs)]
2
3 use std::net::SocketAddr;
4
5 use tokio::sync::oneshot;
6 use tokio_stream::{wrappers::TcpListenerStream, StreamExt};
7 use tonic::{transport::Server, Request};
8
9 use tonic_reflection::pb::{v1, v1alpha};
10 use tonic_reflection::server::Builder;
11
12 #[tokio::test]
test_v1()13 async fn test_v1() {
14 let response = make_v1_request(v1::ServerReflectionRequest {
15 host: "".to_string(),
16 message_request: Some(v1::server_reflection_request::MessageRequest::ListServices(
17 String::new(),
18 )),
19 })
20 .await;
21
22 if let v1::server_reflection_response::MessageResponse::ListServicesResponse(services) =
23 response
24 {
25 assert_eq!(
26 services.service,
27 vec![v1::ServiceResponse {
28 name: String::from("grpc.reflection.v1.ServerReflection")
29 }]
30 );
31 } else {
32 panic!("Expected a ListServicesResponse variant");
33 }
34 }
35
36 #[tokio::test]
test_v1alpha()37 async fn test_v1alpha() {
38 let response = make_v1alpha_request(v1alpha::ServerReflectionRequest {
39 host: "".to_string(),
40 message_request: Some(
41 v1alpha::server_reflection_request::MessageRequest::ListServices(String::new()),
42 ),
43 })
44 .await;
45
46 if let v1alpha::server_reflection_response::MessageResponse::ListServicesResponse(services) =
47 response
48 {
49 assert_eq!(
50 services.service,
51 vec![v1alpha::ServiceResponse {
52 name: String::from("grpc.reflection.v1alpha.ServerReflection")
53 }]
54 );
55 } else {
56 panic!("Expected a ListServicesResponse variant");
57 }
58 }
59
make_v1_request( request: v1::ServerReflectionRequest, ) -> v1::server_reflection_response::MessageResponse60 async fn make_v1_request(
61 request: v1::ServerReflectionRequest,
62 ) -> v1::server_reflection_response::MessageResponse {
63 // Run a test server
64 let (shutdown_tx, shutdown_rx) = oneshot::channel();
65
66 let addr: SocketAddr = "127.0.0.1:0".parse().expect("SocketAddr parse");
67 let listener = tokio::net::TcpListener::bind(addr).await.expect("bind");
68 let local_addr = format!("http://{}", listener.local_addr().expect("local address"));
69 let jh = tokio::spawn(async move {
70 let service = Builder::configure().build_v1().unwrap();
71
72 Server::builder()
73 .add_service(service)
74 .serve_with_incoming_shutdown(TcpListenerStream::new(listener), async {
75 drop(shutdown_rx.await)
76 })
77 .await
78 .unwrap();
79 });
80
81 // Give the test server a few ms to become available
82 tokio::time::sleep(std::time::Duration::from_millis(100)).await;
83
84 // Construct client and send request, extract response
85 let conn = tonic::transport::Endpoint::new(local_addr)
86 .unwrap()
87 .connect()
88 .await
89 .unwrap();
90 let mut client = v1::server_reflection_client::ServerReflectionClient::new(conn);
91
92 let request = Request::new(tokio_stream::once(request));
93 let mut inbound = client
94 .server_reflection_info(request)
95 .await
96 .expect("request")
97 .into_inner();
98
99 let response = inbound
100 .next()
101 .await
102 .expect("steamed response")
103 .expect("successful response")
104 .message_response
105 .expect("some MessageResponse");
106
107 // We only expect one response per request
108 assert!(inbound.next().await.is_none());
109
110 // Shut down test server
111 shutdown_tx.send(()).expect("send shutdown");
112 jh.await.expect("server shutdown");
113
114 response
115 }
116
make_v1alpha_request( request: v1alpha::ServerReflectionRequest, ) -> v1alpha::server_reflection_response::MessageResponse117 async fn make_v1alpha_request(
118 request: v1alpha::ServerReflectionRequest,
119 ) -> v1alpha::server_reflection_response::MessageResponse {
120 // Run a test server
121 let (shutdown_tx, shutdown_rx) = oneshot::channel();
122
123 let addr: SocketAddr = "127.0.0.1:0".parse().expect("SocketAddr parse");
124 let listener = tokio::net::TcpListener::bind(addr).await.expect("bind");
125 let local_addr = format!("http://{}", listener.local_addr().expect("local address"));
126 let jh = tokio::spawn(async move {
127 let service = Builder::configure().build_v1alpha().unwrap();
128
129 Server::builder()
130 .add_service(service)
131 .serve_with_incoming_shutdown(TcpListenerStream::new(listener), async {
132 drop(shutdown_rx.await)
133 })
134 .await
135 .unwrap();
136 });
137
138 // Give the test server a few ms to become available
139 tokio::time::sleep(std::time::Duration::from_millis(100)).await;
140
141 // Construct client and send request, extract response
142 let conn = tonic::transport::Endpoint::new(local_addr)
143 .unwrap()
144 .connect()
145 .await
146 .unwrap();
147 let mut client = v1alpha::server_reflection_client::ServerReflectionClient::new(conn);
148
149 let request = Request::new(tokio_stream::once(request));
150 let mut inbound = client
151 .server_reflection_info(request)
152 .await
153 .expect("request")
154 .into_inner();
155
156 let response = inbound
157 .next()
158 .await
159 .expect("steamed response")
160 .expect("successful response")
161 .message_response
162 .expect("some MessageResponse");
163
164 // We only expect one response per request
165 assert!(inbound.next().await.is_none());
166
167 // Shut down test server
168 shutdown_tx.send(()).expect("send shutdown");
169 jh.await.expect("server shutdown");
170
171 response
172 }
173