10583cff8SDavid Pedersen use super::*;
2a585a722SMarcus Griep use tonic::codec::CompressionEncoding;
30583cff8SDavid Pedersen 
4e8cb48fcSQuentin Perez util::parametrized_tests! {
5e8cb48fcSQuentin Perez     client_enabled_server_enabled,
6e8cb48fcSQuentin Perez     zstd: CompressionEncoding::Zstd,
7e8cb48fcSQuentin Perez     gzip: CompressionEncoding::Gzip,
8*79a06cc8SIlya Averyanov     deflate: CompressionEncoding::Deflate,
9e8cb48fcSQuentin Perez }
10e8cb48fcSQuentin Perez 
11e8cb48fcSQuentin Perez #[allow(dead_code)]
client_enabled_server_enabled(encoding: CompressionEncoding)12e8cb48fcSQuentin Perez async fn client_enabled_server_enabled(encoding: CompressionEncoding) {
130583cff8SDavid Pedersen     let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10);
140583cff8SDavid Pedersen 
150583cff8SDavid Pedersen     #[derive(Clone, Copy)]
16e8cb48fcSQuentin Perez     struct AssertCorrectAcceptEncoding<S> {
17e8cb48fcSQuentin Perez         service: S,
18e8cb48fcSQuentin Perez         encoding: CompressionEncoding,
19e8cb48fcSQuentin Perez     }
200583cff8SDavid Pedersen 
210583cff8SDavid Pedersen     impl<S, B> Service<http::Request<B>> for AssertCorrectAcceptEncoding<S>
220583cff8SDavid Pedersen     where
230583cff8SDavid Pedersen         S: Service<http::Request<B>>,
240583cff8SDavid Pedersen     {
250583cff8SDavid Pedersen         type Response = S::Response;
260583cff8SDavid Pedersen         type Error = S::Error;
270583cff8SDavid Pedersen         type Future = S::Future;
280583cff8SDavid Pedersen 
290583cff8SDavid Pedersen         fn poll_ready(
300583cff8SDavid Pedersen             &mut self,
310583cff8SDavid Pedersen             cx: &mut std::task::Context<'_>,
320583cff8SDavid Pedersen         ) -> std::task::Poll<Result<(), Self::Error>> {
33e8cb48fcSQuentin Perez             self.service.poll_ready(cx)
340583cff8SDavid Pedersen         }
350583cff8SDavid Pedersen 
360583cff8SDavid Pedersen         fn call(&mut self, req: http::Request<B>) -> Self::Future {
37e8cb48fcSQuentin Perez             let expected = match self.encoding {
38e8cb48fcSQuentin Perez                 CompressionEncoding::Gzip => "gzip",
39e8cb48fcSQuentin Perez                 CompressionEncoding::Zstd => "zstd",
40*79a06cc8SIlya Averyanov                 CompressionEncoding::Deflate => "deflate",
41e8cb48fcSQuentin Perez                 _ => panic!("unexpected encoding {:?}", self.encoding),
42e8cb48fcSQuentin Perez             };
430583cff8SDavid Pedersen             assert_eq!(
44e8cb48fcSQuentin Perez                 req.headers()
45e8cb48fcSQuentin Perez                     .get("grpc-accept-encoding")
46e8cb48fcSQuentin Perez                     .unwrap()
47e8cb48fcSQuentin Perez                     .to_str()
48e8cb48fcSQuentin Perez                     .unwrap(),
49e8cb48fcSQuentin Perez                 format!("{},identity", expected)
500583cff8SDavid Pedersen             );
51e8cb48fcSQuentin Perez             self.service.call(req)
520583cff8SDavid Pedersen         }
530583cff8SDavid Pedersen     }
540583cff8SDavid Pedersen 
55e8cb48fcSQuentin Perez     let svc = test_server::TestServer::new(Svc::default()).send_compressed(encoding);
560583cff8SDavid Pedersen 
570583cff8SDavid Pedersen     let response_bytes_counter = Arc::new(AtomicUsize::new(0));
580583cff8SDavid Pedersen 
590583cff8SDavid Pedersen     tokio::spawn({
600583cff8SDavid Pedersen         let response_bytes_counter = response_bytes_counter.clone();
610583cff8SDavid Pedersen         async move {
620583cff8SDavid Pedersen             Server::builder()
630583cff8SDavid Pedersen                 .layer(
640583cff8SDavid Pedersen                     ServiceBuilder::new()
65e8cb48fcSQuentin Perez                         .layer(layer_fn(|service| AssertCorrectAcceptEncoding {
66e8cb48fcSQuentin Perez                             service,
67e8cb48fcSQuentin Perez                             encoding,
68e8cb48fcSQuentin Perez                         }))
690583cff8SDavid Pedersen                         .layer(MapResponseBodyLayer::new(move |body| {
700583cff8SDavid Pedersen                             util::CountBytesBody {
710583cff8SDavid Pedersen                                 inner: body,
720583cff8SDavid Pedersen                                 counter: response_bytes_counter.clone(),
730583cff8SDavid Pedersen                             }
740583cff8SDavid Pedersen                         }))
750583cff8SDavid Pedersen                         .into_inner(),
760583cff8SDavid Pedersen                 )
770583cff8SDavid Pedersen                 .add_service(svc)
78f089e7a0Stottoto                 .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server)))
790583cff8SDavid Pedersen                 .await
800583cff8SDavid Pedersen                 .unwrap();
810583cff8SDavid Pedersen         }
820583cff8SDavid Pedersen     });
830583cff8SDavid Pedersen 
84e8cb48fcSQuentin Perez     let mut client =
85e8cb48fcSQuentin Perez         test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding);
86e8cb48fcSQuentin Perez 
87e8cb48fcSQuentin Perez     let expected = match encoding {
88e8cb48fcSQuentin Perez         CompressionEncoding::Gzip => "gzip",
89e8cb48fcSQuentin Perez         CompressionEncoding::Zstd => "zstd",
90*79a06cc8SIlya Averyanov         CompressionEncoding::Deflate => "deflate",
91e8cb48fcSQuentin Perez         _ => panic!("unexpected encoding {:?}", encoding),
92e8cb48fcSQuentin Perez     };
930583cff8SDavid Pedersen 
940583cff8SDavid Pedersen     for _ in 0..3 {
950583cff8SDavid Pedersen         let res = client.compress_output_unary(()).await.unwrap();
96e8cb48fcSQuentin Perez         assert_eq!(res.metadata().get("grpc-encoding").unwrap(), expected);
970583cff8SDavid Pedersen         let bytes_sent = response_bytes_counter.load(SeqCst);
980583cff8SDavid Pedersen         assert!(bytes_sent < UNCOMPRESSED_MIN_BODY_SIZE);
990583cff8SDavid Pedersen     }
1000583cff8SDavid Pedersen }
1010583cff8SDavid Pedersen 
102e8cb48fcSQuentin Perez util::parametrized_tests! {
103e8cb48fcSQuentin Perez     client_enabled_server_disabled,
104e8cb48fcSQuentin Perez     zstd: CompressionEncoding::Zstd,
105e8cb48fcSQuentin Perez     gzip: CompressionEncoding::Gzip,
106*79a06cc8SIlya Averyanov     deflate: CompressionEncoding::Deflate,
107e8cb48fcSQuentin Perez }
108e8cb48fcSQuentin Perez 
109e8cb48fcSQuentin Perez #[allow(dead_code)]
client_enabled_server_disabled(encoding: CompressionEncoding)110e8cb48fcSQuentin Perez async fn client_enabled_server_disabled(encoding: CompressionEncoding) {
111e8cb48fcSQuentin Perez     let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10);
112e8cb48fcSQuentin Perez 
113e8cb48fcSQuentin Perez     let svc = test_server::TestServer::new(Svc::default());
114e8cb48fcSQuentin Perez 
115e8cb48fcSQuentin Perez     let response_bytes_counter = Arc::new(AtomicUsize::new(0));
116e8cb48fcSQuentin Perez 
117e8cb48fcSQuentin Perez     tokio::spawn({
118e8cb48fcSQuentin Perez         let response_bytes_counter = response_bytes_counter.clone();
119e8cb48fcSQuentin Perez         async move {
120e8cb48fcSQuentin Perez             Server::builder()
121e8cb48fcSQuentin Perez                 // no compression enable on the server so responses should not be compressed
122e8cb48fcSQuentin Perez                 .layer(
123e8cb48fcSQuentin Perez                     ServiceBuilder::new()
124e8cb48fcSQuentin Perez                         .layer(MapResponseBodyLayer::new(move |body| {
125e8cb48fcSQuentin Perez                             util::CountBytesBody {
126e8cb48fcSQuentin Perez                                 inner: body,
127e8cb48fcSQuentin Perez                                 counter: response_bytes_counter.clone(),
128e8cb48fcSQuentin Perez                             }
129e8cb48fcSQuentin Perez                         }))
130e8cb48fcSQuentin Perez                         .into_inner(),
131e8cb48fcSQuentin Perez                 )
132e8cb48fcSQuentin Perez                 .add_service(svc)
133e8cb48fcSQuentin Perez                 .serve_with_incoming(tokio_stream::iter(vec![Ok::<_, std::io::Error>(server)]))
134e8cb48fcSQuentin Perez                 .await
135e8cb48fcSQuentin Perez                 .unwrap();
136e8cb48fcSQuentin Perez         }
137e8cb48fcSQuentin Perez     });
138e8cb48fcSQuentin Perez 
139e8cb48fcSQuentin Perez     let mut client =
140e8cb48fcSQuentin Perez         test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding);
141e8cb48fcSQuentin Perez 
142e8cb48fcSQuentin Perez     let res = client.compress_output_unary(()).await.unwrap();
143e8cb48fcSQuentin Perez 
144e8cb48fcSQuentin Perez     assert!(res.metadata().get("grpc-encoding").is_none());
145e8cb48fcSQuentin Perez 
146e8cb48fcSQuentin Perez     let bytes_sent = response_bytes_counter.load(SeqCst);
147e8cb48fcSQuentin Perez     assert!(bytes_sent > UNCOMPRESSED_MIN_BODY_SIZE);
148e8cb48fcSQuentin Perez }
149e8cb48fcSQuentin Perez 
1500583cff8SDavid Pedersen #[tokio::test(flavor = "multi_thread")]
client_enabled_server_disabled_multi_encoding()151e8cb48fcSQuentin Perez async fn client_enabled_server_disabled_multi_encoding() {
1520583cff8SDavid Pedersen     let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10);
1530583cff8SDavid Pedersen 
1540583cff8SDavid Pedersen     let svc = test_server::TestServer::new(Svc::default());
1550583cff8SDavid Pedersen 
1560583cff8SDavid Pedersen     let response_bytes_counter = Arc::new(AtomicUsize::new(0));
1570583cff8SDavid Pedersen 
1580583cff8SDavid Pedersen     tokio::spawn({
1590583cff8SDavid Pedersen         let response_bytes_counter = response_bytes_counter.clone();
1600583cff8SDavid Pedersen         async move {
1610583cff8SDavid Pedersen             Server::builder()
1620583cff8SDavid Pedersen                 // no compression enable on the server so responses should not be compressed
1630583cff8SDavid Pedersen                 .layer(
1640583cff8SDavid Pedersen                     ServiceBuilder::new()
1650583cff8SDavid Pedersen                         .layer(MapResponseBodyLayer::new(move |body| {
1660583cff8SDavid Pedersen                             util::CountBytesBody {
1670583cff8SDavid Pedersen                                 inner: body,
1680583cff8SDavid Pedersen                                 counter: response_bytes_counter.clone(),
1690583cff8SDavid Pedersen                             }
1700583cff8SDavid Pedersen                         }))
1710583cff8SDavid Pedersen                         .into_inner(),
1720583cff8SDavid Pedersen                 )
1730583cff8SDavid Pedersen                 .add_service(svc)
174f089e7a0Stottoto                 .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server)))
1750583cff8SDavid Pedersen                 .await
1760583cff8SDavid Pedersen                 .unwrap();
1770583cff8SDavid Pedersen         }
1780583cff8SDavid Pedersen     });
1790583cff8SDavid Pedersen 
180a585a722SMarcus Griep     let mut client = test_client::TestClient::new(mock_io_channel(client).await)
181e8cb48fcSQuentin Perez         .accept_compressed(CompressionEncoding::Gzip)
182*79a06cc8SIlya Averyanov         .accept_compressed(CompressionEncoding::Zstd)
183*79a06cc8SIlya Averyanov         .accept_compressed(CompressionEncoding::Deflate);
1840583cff8SDavid Pedersen 
1850583cff8SDavid Pedersen     let res = client.compress_output_unary(()).await.unwrap();
1860583cff8SDavid Pedersen 
1870583cff8SDavid Pedersen     assert!(res.metadata().get("grpc-encoding").is_none());
1880583cff8SDavid Pedersen 
1890583cff8SDavid Pedersen     let bytes_sent = response_bytes_counter.load(SeqCst);
1900583cff8SDavid Pedersen     assert!(bytes_sent > UNCOMPRESSED_MIN_BODY_SIZE);
1910583cff8SDavid Pedersen }
1920583cff8SDavid Pedersen 
193e8cb48fcSQuentin Perez util::parametrized_tests! {
194e8cb48fcSQuentin Perez     client_disabled,
195e8cb48fcSQuentin Perez     zstd: CompressionEncoding::Zstd,
196e8cb48fcSQuentin Perez     gzip: CompressionEncoding::Gzip,
197*79a06cc8SIlya Averyanov     deflate: CompressionEncoding::Deflate,
198e8cb48fcSQuentin Perez }
199e8cb48fcSQuentin Perez 
200e8cb48fcSQuentin Perez #[allow(dead_code)]
client_disabled(encoding: CompressionEncoding)201e8cb48fcSQuentin Perez async fn client_disabled(encoding: CompressionEncoding) {
2020583cff8SDavid Pedersen     let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10);
2030583cff8SDavid Pedersen 
2040583cff8SDavid Pedersen     #[derive(Clone, Copy)]
2050583cff8SDavid Pedersen     struct AssertCorrectAcceptEncoding<S>(S);
2060583cff8SDavid Pedersen 
2070583cff8SDavid Pedersen     impl<S, B> Service<http::Request<B>> for AssertCorrectAcceptEncoding<S>
2080583cff8SDavid Pedersen     where
2090583cff8SDavid Pedersen         S: Service<http::Request<B>>,
2100583cff8SDavid Pedersen     {
2110583cff8SDavid Pedersen         type Response = S::Response;
2120583cff8SDavid Pedersen         type Error = S::Error;
2130583cff8SDavid Pedersen         type Future = S::Future;
2140583cff8SDavid Pedersen 
2150583cff8SDavid Pedersen         fn poll_ready(
2160583cff8SDavid Pedersen             &mut self,
2170583cff8SDavid Pedersen             cx: &mut std::task::Context<'_>,
2180583cff8SDavid Pedersen         ) -> std::task::Poll<Result<(), Self::Error>> {
2190583cff8SDavid Pedersen             self.0.poll_ready(cx)
2200583cff8SDavid Pedersen         }
2210583cff8SDavid Pedersen 
2220583cff8SDavid Pedersen         fn call(&mut self, req: http::Request<B>) -> Self::Future {
2230583cff8SDavid Pedersen             assert!(req.headers().get("grpc-accept-encoding").is_none());
2240583cff8SDavid Pedersen             self.0.call(req)
2250583cff8SDavid Pedersen         }
2260583cff8SDavid Pedersen     }
2270583cff8SDavid Pedersen 
228e8cb48fcSQuentin Perez     let svc = test_server::TestServer::new(Svc::default()).send_compressed(encoding);
2290583cff8SDavid Pedersen 
2300583cff8SDavid Pedersen     let response_bytes_counter = Arc::new(AtomicUsize::new(0));
2310583cff8SDavid Pedersen 
2320583cff8SDavid Pedersen     tokio::spawn({
2330583cff8SDavid Pedersen         let response_bytes_counter = response_bytes_counter.clone();
2340583cff8SDavid Pedersen         async move {
2350583cff8SDavid Pedersen             Server::builder()
2360583cff8SDavid Pedersen                 .layer(
2370583cff8SDavid Pedersen                     ServiceBuilder::new()
2380583cff8SDavid Pedersen                         .layer(layer_fn(AssertCorrectAcceptEncoding))
2390583cff8SDavid Pedersen                         .layer(MapResponseBodyLayer::new(move |body| {
2400583cff8SDavid Pedersen                             util::CountBytesBody {
2410583cff8SDavid Pedersen                                 inner: body,
2420583cff8SDavid Pedersen                                 counter: response_bytes_counter.clone(),
2430583cff8SDavid Pedersen                             }
2440583cff8SDavid Pedersen                         }))
2450583cff8SDavid Pedersen                         .into_inner(),
2460583cff8SDavid Pedersen                 )
2470583cff8SDavid Pedersen                 .add_service(svc)
248f089e7a0Stottoto                 .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server)))
2490583cff8SDavid Pedersen                 .await
2500583cff8SDavid Pedersen                 .unwrap();
2510583cff8SDavid Pedersen         }
2520583cff8SDavid Pedersen     });
2530583cff8SDavid Pedersen 
2540583cff8SDavid Pedersen     let mut client = test_client::TestClient::new(mock_io_channel(client).await);
2550583cff8SDavid Pedersen 
2560583cff8SDavid Pedersen     let res = client.compress_output_unary(()).await.unwrap();
2570583cff8SDavid Pedersen 
2580583cff8SDavid Pedersen     assert!(res.metadata().get("grpc-encoding").is_none());
2590583cff8SDavid Pedersen 
2600583cff8SDavid Pedersen     let bytes_sent = response_bytes_counter.load(SeqCst);
2610583cff8SDavid Pedersen     assert!(bytes_sent > UNCOMPRESSED_MIN_BODY_SIZE);
2620583cff8SDavid Pedersen }
2630583cff8SDavid Pedersen 
264e8cb48fcSQuentin Perez util::parametrized_tests! {
265e8cb48fcSQuentin Perez     server_replying_with_unsupported_encoding,
266e8cb48fcSQuentin Perez     zstd: CompressionEncoding::Zstd,
267e8cb48fcSQuentin Perez     gzip: CompressionEncoding::Gzip,
268*79a06cc8SIlya Averyanov     deflate: CompressionEncoding::Deflate,
269e8cb48fcSQuentin Perez }
270e8cb48fcSQuentin Perez 
271e8cb48fcSQuentin Perez #[allow(dead_code)]
server_replying_with_unsupported_encoding(encoding: CompressionEncoding)272e8cb48fcSQuentin Perez async fn server_replying_with_unsupported_encoding(encoding: CompressionEncoding) {
2730583cff8SDavid Pedersen     let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10);
2740583cff8SDavid Pedersen 
275e8cb48fcSQuentin Perez     let svc = test_server::TestServer::new(Svc::default()).send_compressed(encoding);
2760583cff8SDavid Pedersen 
2770583cff8SDavid Pedersen     fn add_weird_content_encoding<B>(mut response: http::Response<B>) -> http::Response<B> {
2780583cff8SDavid Pedersen         response
2790583cff8SDavid Pedersen             .headers_mut()
2800583cff8SDavid Pedersen             .insert("grpc-encoding", "br".parse().unwrap());
2810583cff8SDavid Pedersen         response
2820583cff8SDavid Pedersen     }
2830583cff8SDavid Pedersen 
2840583cff8SDavid Pedersen     tokio::spawn(async move {
2850583cff8SDavid Pedersen         Server::builder()
2860583cff8SDavid Pedersen             .layer(
2870583cff8SDavid Pedersen                 ServiceBuilder::new()
2880583cff8SDavid Pedersen                     .map_response(add_weird_content_encoding)
2890583cff8SDavid Pedersen                     .into_inner(),
2900583cff8SDavid Pedersen             )
2910583cff8SDavid Pedersen             .add_service(svc)
292f089e7a0Stottoto             .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server)))
2930583cff8SDavid Pedersen             .await
2940583cff8SDavid Pedersen             .unwrap();
2950583cff8SDavid Pedersen     });
2960583cff8SDavid Pedersen 
297e8cb48fcSQuentin Perez     let mut client =
298e8cb48fcSQuentin Perez         test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding);
2990583cff8SDavid Pedersen     let status: Status = client.compress_output_unary(()).await.unwrap_err();
3000583cff8SDavid Pedersen 
3010583cff8SDavid Pedersen     assert_eq!(status.code(), tonic::Code::Unimplemented);
3020583cff8SDavid Pedersen     assert_eq!(
3030583cff8SDavid Pedersen         status.message(),
3040583cff8SDavid Pedersen         "Content is compressed with `br` which isn't supported"
3050583cff8SDavid Pedersen     );
3060583cff8SDavid Pedersen }
3070583cff8SDavid Pedersen 
308e8cb48fcSQuentin Perez util::parametrized_tests! {
309e8cb48fcSQuentin Perez     disabling_compression_on_single_response,
310e8cb48fcSQuentin Perez     zstd: CompressionEncoding::Zstd,
311e8cb48fcSQuentin Perez     gzip: CompressionEncoding::Gzip,
312*79a06cc8SIlya Averyanov     deflate: CompressionEncoding::Deflate,
313e8cb48fcSQuentin Perez }
314e8cb48fcSQuentin Perez 
315e8cb48fcSQuentin Perez #[allow(dead_code)]
disabling_compression_on_single_response(encoding: CompressionEncoding)316e8cb48fcSQuentin Perez async fn disabling_compression_on_single_response(encoding: CompressionEncoding) {
3170583cff8SDavid Pedersen     let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10);
3180583cff8SDavid Pedersen 
3190583cff8SDavid Pedersen     let svc = test_server::TestServer::new(Svc {
3200583cff8SDavid Pedersen         disable_compressing_on_response: true,
3210583cff8SDavid Pedersen     })
322e8cb48fcSQuentin Perez     .send_compressed(encoding);
3230583cff8SDavid Pedersen 
3240583cff8SDavid Pedersen     let response_bytes_counter = Arc::new(AtomicUsize::new(0));
3250583cff8SDavid Pedersen 
3260583cff8SDavid Pedersen     tokio::spawn({
3270583cff8SDavid Pedersen         let response_bytes_counter = response_bytes_counter.clone();
3280583cff8SDavid Pedersen         async move {
3290583cff8SDavid Pedersen             Server::builder()
3300583cff8SDavid Pedersen                 .layer(
3310583cff8SDavid Pedersen                     ServiceBuilder::new()
3320583cff8SDavid Pedersen                         .layer(MapResponseBodyLayer::new(move |body| {
3330583cff8SDavid Pedersen                             util::CountBytesBody {
3340583cff8SDavid Pedersen                                 inner: body,
3350583cff8SDavid Pedersen                                 counter: response_bytes_counter.clone(),
3360583cff8SDavid Pedersen                             }
3370583cff8SDavid Pedersen                         }))
3380583cff8SDavid Pedersen                         .into_inner(),
3390583cff8SDavid Pedersen                 )
3400583cff8SDavid Pedersen                 .add_service(svc)
341f089e7a0Stottoto                 .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server)))
3420583cff8SDavid Pedersen                 .await
3430583cff8SDavid Pedersen                 .unwrap();
3440583cff8SDavid Pedersen         }
3450583cff8SDavid Pedersen     });
3460583cff8SDavid Pedersen 
347e8cb48fcSQuentin Perez     let mut client =
348e8cb48fcSQuentin Perez         test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding);
3490583cff8SDavid Pedersen 
3500583cff8SDavid Pedersen     let res = client.compress_output_unary(()).await.unwrap();
351e8cb48fcSQuentin Perez 
352e8cb48fcSQuentin Perez     let expected = match encoding {
353e8cb48fcSQuentin Perez         CompressionEncoding::Gzip => "gzip",
354e8cb48fcSQuentin Perez         CompressionEncoding::Zstd => "zstd",
355*79a06cc8SIlya Averyanov         CompressionEncoding::Deflate => "deflate",
356e8cb48fcSQuentin Perez         _ => panic!("unexpected encoding {:?}", encoding),
357e8cb48fcSQuentin Perez     };
358e8cb48fcSQuentin Perez     assert_eq!(res.metadata().get("grpc-encoding").unwrap(), expected);
359e8cb48fcSQuentin Perez 
3600583cff8SDavid Pedersen     let bytes_sent = response_bytes_counter.load(SeqCst);
3610583cff8SDavid Pedersen     assert!(bytes_sent > UNCOMPRESSED_MIN_BODY_SIZE);
3620583cff8SDavid Pedersen }
3630583cff8SDavid Pedersen 
364e8cb48fcSQuentin Perez util::parametrized_tests! {
365e8cb48fcSQuentin Perez     disabling_compression_on_response_but_keeping_compression_on_stream,
366e8cb48fcSQuentin Perez     zstd: CompressionEncoding::Zstd,
367e8cb48fcSQuentin Perez     gzip: CompressionEncoding::Gzip,
368*79a06cc8SIlya Averyanov     deflate: CompressionEncoding::Deflate,
369e8cb48fcSQuentin Perez }
370e8cb48fcSQuentin Perez 
371e8cb48fcSQuentin Perez #[allow(dead_code)]
disabling_compression_on_response_but_keeping_compression_on_stream( encoding: CompressionEncoding, )372e8cb48fcSQuentin Perez async fn disabling_compression_on_response_but_keeping_compression_on_stream(
373e8cb48fcSQuentin Perez     encoding: CompressionEncoding,
374e8cb48fcSQuentin Perez ) {
3750583cff8SDavid Pedersen     let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10);
3760583cff8SDavid Pedersen 
3770583cff8SDavid Pedersen     let svc = test_server::TestServer::new(Svc {
3780583cff8SDavid Pedersen         disable_compressing_on_response: true,
3790583cff8SDavid Pedersen     })
380e8cb48fcSQuentin Perez     .send_compressed(encoding);
3810583cff8SDavid Pedersen 
3820583cff8SDavid Pedersen     let response_bytes_counter = Arc::new(AtomicUsize::new(0));
3830583cff8SDavid Pedersen 
3840583cff8SDavid Pedersen     tokio::spawn({
3850583cff8SDavid Pedersen         let response_bytes_counter = response_bytes_counter.clone();
3860583cff8SDavid Pedersen         async move {
3870583cff8SDavid Pedersen             Server::builder()
3880583cff8SDavid Pedersen                 .layer(
3890583cff8SDavid Pedersen                     ServiceBuilder::new()
3900583cff8SDavid Pedersen                         .layer(MapResponseBodyLayer::new(move |body| {
3910583cff8SDavid Pedersen                             util::CountBytesBody {
3920583cff8SDavid Pedersen                                 inner: body,
3930583cff8SDavid Pedersen                                 counter: response_bytes_counter.clone(),
3940583cff8SDavid Pedersen                             }
3950583cff8SDavid Pedersen                         }))
3960583cff8SDavid Pedersen                         .into_inner(),
3970583cff8SDavid Pedersen                 )
3980583cff8SDavid Pedersen                 .add_service(svc)
399f089e7a0Stottoto                 .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server)))
4000583cff8SDavid Pedersen                 .await
4010583cff8SDavid Pedersen                 .unwrap();
4020583cff8SDavid Pedersen         }
4030583cff8SDavid Pedersen     });
4040583cff8SDavid Pedersen 
405e8cb48fcSQuentin Perez     let mut client =
406e8cb48fcSQuentin Perez         test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding);
4070583cff8SDavid Pedersen 
4080583cff8SDavid Pedersen     let res = client.compress_output_server_stream(()).await.unwrap();
4090583cff8SDavid Pedersen 
410e8cb48fcSQuentin Perez     let expected = match encoding {
411e8cb48fcSQuentin Perez         CompressionEncoding::Gzip => "gzip",
412e8cb48fcSQuentin Perez         CompressionEncoding::Zstd => "zstd",
413*79a06cc8SIlya Averyanov         CompressionEncoding::Deflate => "deflate",
414e8cb48fcSQuentin Perez         _ => panic!("unexpected encoding {:?}", encoding),
415e8cb48fcSQuentin Perez     };
416e8cb48fcSQuentin Perez     assert_eq!(res.metadata().get("grpc-encoding").unwrap(), expected);
4170583cff8SDavid Pedersen 
4180583cff8SDavid Pedersen     let mut stream: Streaming<SomeData> = res.into_inner();
4190583cff8SDavid Pedersen 
4200583cff8SDavid Pedersen     stream
4210583cff8SDavid Pedersen         .next()
4220583cff8SDavid Pedersen         .await
4230583cff8SDavid Pedersen         .expect("stream empty")
4240583cff8SDavid Pedersen         .expect("item was error");
4250583cff8SDavid Pedersen     assert!(response_bytes_counter.load(SeqCst) < UNCOMPRESSED_MIN_BODY_SIZE);
4260583cff8SDavid Pedersen 
4270583cff8SDavid Pedersen     stream
4280583cff8SDavid Pedersen         .next()
4290583cff8SDavid Pedersen         .await
4300583cff8SDavid Pedersen         .expect("stream empty")
4310583cff8SDavid Pedersen         .expect("item was error");
4320583cff8SDavid Pedersen     assert!(response_bytes_counter.load(SeqCst) < UNCOMPRESSED_MIN_BODY_SIZE);
4330583cff8SDavid Pedersen }
4340583cff8SDavid Pedersen 
435e8cb48fcSQuentin Perez util::parametrized_tests! {
436e8cb48fcSQuentin Perez     disabling_compression_on_response_from_client_stream,
437e8cb48fcSQuentin Perez     zstd: CompressionEncoding::Zstd,
438e8cb48fcSQuentin Perez     gzip: CompressionEncoding::Gzip,
439*79a06cc8SIlya Averyanov     deflate: CompressionEncoding::Deflate,
440e8cb48fcSQuentin Perez }
441e8cb48fcSQuentin Perez 
442e8cb48fcSQuentin Perez #[allow(dead_code)]
disabling_compression_on_response_from_client_stream(encoding: CompressionEncoding)443e8cb48fcSQuentin Perez async fn disabling_compression_on_response_from_client_stream(encoding: CompressionEncoding) {
4440583cff8SDavid Pedersen     let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10);
4450583cff8SDavid Pedersen 
4460583cff8SDavid Pedersen     let svc = test_server::TestServer::new(Svc {
4470583cff8SDavid Pedersen         disable_compressing_on_response: true,
4480583cff8SDavid Pedersen     })
449e8cb48fcSQuentin Perez     .send_compressed(encoding);
4500583cff8SDavid Pedersen 
4510583cff8SDavid Pedersen     let response_bytes_counter = Arc::new(AtomicUsize::new(0));
4520583cff8SDavid Pedersen 
4530583cff8SDavid Pedersen     tokio::spawn({
4540583cff8SDavid Pedersen         let response_bytes_counter = response_bytes_counter.clone();
4550583cff8SDavid Pedersen         async move {
4560583cff8SDavid Pedersen             Server::builder()
4570583cff8SDavid Pedersen                 .layer(
4580583cff8SDavid Pedersen                     ServiceBuilder::new()
4590583cff8SDavid Pedersen                         .layer(MapResponseBodyLayer::new(move |body| {
4600583cff8SDavid Pedersen                             util::CountBytesBody {
4610583cff8SDavid Pedersen                                 inner: body,
4620583cff8SDavid Pedersen                                 counter: response_bytes_counter.clone(),
4630583cff8SDavid Pedersen                             }
4640583cff8SDavid Pedersen                         }))
4650583cff8SDavid Pedersen                         .into_inner(),
4660583cff8SDavid Pedersen                 )
4670583cff8SDavid Pedersen                 .add_service(svc)
468f089e7a0Stottoto                 .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server)))
4690583cff8SDavid Pedersen                 .await
4700583cff8SDavid Pedersen                 .unwrap();
4710583cff8SDavid Pedersen         }
4720583cff8SDavid Pedersen     });
4730583cff8SDavid Pedersen 
474e8cb48fcSQuentin Perez     let mut client =
475e8cb48fcSQuentin Perez         test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding);
4760583cff8SDavid Pedersen 
477f089e7a0Stottoto     let req = Request::new(Box::pin(tokio_stream::empty()));
4780583cff8SDavid Pedersen 
4790583cff8SDavid Pedersen     let res = client.compress_output_client_stream(req).await.unwrap();
480e8cb48fcSQuentin Perez 
481e8cb48fcSQuentin Perez     let expected = match encoding {
482e8cb48fcSQuentin Perez         CompressionEncoding::Gzip => "gzip",
483e8cb48fcSQuentin Perez         CompressionEncoding::Zstd => "zstd",
484*79a06cc8SIlya Averyanov         CompressionEncoding::Deflate => "deflate",
485e8cb48fcSQuentin Perez         _ => panic!("unexpected encoding {:?}", encoding),
486e8cb48fcSQuentin Perez     };
487e8cb48fcSQuentin Perez     assert_eq!(res.metadata().get("grpc-encoding").unwrap(), expected);
4880583cff8SDavid Pedersen     let bytes_sent = response_bytes_counter.load(SeqCst);
4890583cff8SDavid Pedersen     assert!(bytes_sent > UNCOMPRESSED_MIN_BODY_SIZE);
4900583cff8SDavid Pedersen }
491