10583cff8SDavid Pedersen use super::*;
2*e8cb48fcSQuentin Perez use http_body::Body;
3a585a722SMarcus Griep use tonic::codec::CompressionEncoding;
40583cff8SDavid Pedersen 
5*e8cb48fcSQuentin Perez util::parametrized_tests! {
6*e8cb48fcSQuentin Perez     client_enabled_server_enabled,
7*e8cb48fcSQuentin Perez     zstd: CompressionEncoding::Zstd,
8*e8cb48fcSQuentin Perez     gzip: CompressionEncoding::Gzip,
9*e8cb48fcSQuentin Perez }
10*e8cb48fcSQuentin Perez 
11*e8cb48fcSQuentin Perez #[allow(dead_code)]
12*e8cb48fcSQuentin Perez async fn client_enabled_server_enabled(encoding: CompressionEncoding) {
130583cff8SDavid Pedersen     let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10);
140583cff8SDavid Pedersen 
15*e8cb48fcSQuentin Perez     let svc = test_server::TestServer::new(Svc::default()).accept_compressed(encoding);
160583cff8SDavid Pedersen 
170583cff8SDavid Pedersen     let request_bytes_counter = Arc::new(AtomicUsize::new(0));
180583cff8SDavid Pedersen 
19*e8cb48fcSQuentin Perez     #[derive(Clone)]
20*e8cb48fcSQuentin Perez     pub struct AssertRightEncoding {
21*e8cb48fcSQuentin Perez         encoding: CompressionEncoding,
22*e8cb48fcSQuentin Perez     }
23*e8cb48fcSQuentin Perez 
24*e8cb48fcSQuentin Perez     #[allow(dead_code)]
25*e8cb48fcSQuentin Perez     impl AssertRightEncoding {
26*e8cb48fcSQuentin Perez         pub fn new(encoding: CompressionEncoding) -> Self {
27*e8cb48fcSQuentin Perez             Self { encoding }
28*e8cb48fcSQuentin Perez         }
29*e8cb48fcSQuentin Perez 
30*e8cb48fcSQuentin Perez         pub fn call<B: Body>(self, req: http::Request<B>) -> http::Request<B> {
31*e8cb48fcSQuentin Perez             let expected = match self.encoding {
32*e8cb48fcSQuentin Perez                 CompressionEncoding::Gzip => "gzip",
33*e8cb48fcSQuentin Perez                 CompressionEncoding::Zstd => "zstd",
34*e8cb48fcSQuentin Perez                 _ => panic!("unexpected encoding {:?}", self.encoding),
35*e8cb48fcSQuentin Perez             };
36*e8cb48fcSQuentin Perez             assert_eq!(req.headers().get("grpc-encoding").unwrap(), expected);
37*e8cb48fcSQuentin Perez 
380583cff8SDavid Pedersen             req
390583cff8SDavid Pedersen         }
40*e8cb48fcSQuentin Perez     }
410583cff8SDavid Pedersen 
420583cff8SDavid Pedersen     tokio::spawn({
430583cff8SDavid Pedersen         let request_bytes_counter = request_bytes_counter.clone();
440583cff8SDavid Pedersen         async move {
450583cff8SDavid Pedersen             Server::builder()
460583cff8SDavid Pedersen                 .layer(
470583cff8SDavid Pedersen                     ServiceBuilder::new()
48*e8cb48fcSQuentin Perez                         .map_request(move |req| {
49*e8cb48fcSQuentin Perez                             AssertRightEncoding::new(encoding).clone().call(req)
50*e8cb48fcSQuentin Perez                         })
510583cff8SDavid Pedersen                         .layer(measure_request_body_size_layer(
520583cff8SDavid Pedersen                             request_bytes_counter.clone(),
530583cff8SDavid Pedersen                         ))
540583cff8SDavid Pedersen                         .into_inner(),
550583cff8SDavid Pedersen                 )
560583cff8SDavid Pedersen                 .add_service(svc)
57f089e7a0Stottoto                 .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server)))
580583cff8SDavid Pedersen                 .await
590583cff8SDavid Pedersen                 .unwrap();
600583cff8SDavid Pedersen         }
610583cff8SDavid Pedersen     });
620583cff8SDavid Pedersen 
63*e8cb48fcSQuentin Perez     let mut client =
64*e8cb48fcSQuentin Perez         test_client::TestClient::new(mock_io_channel(client).await).send_compressed(encoding);
650583cff8SDavid Pedersen 
660583cff8SDavid Pedersen     let data = [0_u8; UNCOMPRESSED_MIN_BODY_SIZE].to_vec();
6723602b47Stottoto     let stream = tokio_stream::iter(vec![SomeData { data: data.clone() }, SomeData { data }]);
680583cff8SDavid Pedersen     let req = Request::new(Box::pin(stream));
690583cff8SDavid Pedersen 
700583cff8SDavid Pedersen     client.compress_input_client_stream(req).await.unwrap();
710583cff8SDavid Pedersen 
720583cff8SDavid Pedersen     let bytes_sent = request_bytes_counter.load(SeqCst);
730583cff8SDavid Pedersen     assert!(bytes_sent < UNCOMPRESSED_MIN_BODY_SIZE);
740583cff8SDavid Pedersen }
750583cff8SDavid Pedersen 
76*e8cb48fcSQuentin Perez util::parametrized_tests! {
77*e8cb48fcSQuentin Perez     client_disabled_server_enabled,
78*e8cb48fcSQuentin Perez     zstd: CompressionEncoding::Zstd,
79*e8cb48fcSQuentin Perez     gzip: CompressionEncoding::Gzip,
80*e8cb48fcSQuentin Perez }
81*e8cb48fcSQuentin Perez 
82*e8cb48fcSQuentin Perez #[allow(dead_code)]
83*e8cb48fcSQuentin Perez async fn client_disabled_server_enabled(encoding: CompressionEncoding) {
840583cff8SDavid Pedersen     let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10);
850583cff8SDavid Pedersen 
86*e8cb48fcSQuentin Perez     let svc = test_server::TestServer::new(Svc::default()).accept_compressed(encoding);
870583cff8SDavid Pedersen 
880583cff8SDavid Pedersen     let request_bytes_counter = Arc::new(AtomicUsize::new(0));
890583cff8SDavid Pedersen 
900583cff8SDavid Pedersen     fn assert_right_encoding<B>(req: http::Request<B>) -> http::Request<B> {
910583cff8SDavid Pedersen         assert!(req.headers().get("grpc-encoding").is_none());
920583cff8SDavid Pedersen         req
930583cff8SDavid Pedersen     }
940583cff8SDavid Pedersen 
950583cff8SDavid Pedersen     tokio::spawn({
960583cff8SDavid Pedersen         let request_bytes_counter = request_bytes_counter.clone();
970583cff8SDavid Pedersen         async move {
980583cff8SDavid Pedersen             Server::builder()
990583cff8SDavid Pedersen                 .layer(
1000583cff8SDavid Pedersen                     ServiceBuilder::new()
1010583cff8SDavid Pedersen                         .map_request(assert_right_encoding)
1020583cff8SDavid Pedersen                         .layer(measure_request_body_size_layer(
1030583cff8SDavid Pedersen                             request_bytes_counter.clone(),
1040583cff8SDavid Pedersen                         ))
1050583cff8SDavid Pedersen                         .into_inner(),
1060583cff8SDavid Pedersen                 )
1070583cff8SDavid Pedersen                 .add_service(svc)
108f089e7a0Stottoto                 .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server)))
1090583cff8SDavid Pedersen                 .await
1100583cff8SDavid Pedersen                 .unwrap();
1110583cff8SDavid Pedersen         }
1120583cff8SDavid Pedersen     });
1130583cff8SDavid Pedersen 
1140583cff8SDavid Pedersen     let mut client = test_client::TestClient::new(mock_io_channel(client).await);
1150583cff8SDavid Pedersen 
1160583cff8SDavid Pedersen     let data = [0_u8; UNCOMPRESSED_MIN_BODY_SIZE].to_vec();
11723602b47Stottoto     let stream = tokio_stream::iter(vec![SomeData { data: data.clone() }, SomeData { data }]);
1180583cff8SDavid Pedersen     let req = Request::new(Box::pin(stream));
1190583cff8SDavid Pedersen 
1200583cff8SDavid Pedersen     client.compress_input_client_stream(req).await.unwrap();
1210583cff8SDavid Pedersen 
1220583cff8SDavid Pedersen     let bytes_sent = request_bytes_counter.load(SeqCst);
1230583cff8SDavid Pedersen     assert!(bytes_sent > UNCOMPRESSED_MIN_BODY_SIZE);
1240583cff8SDavid Pedersen }
1250583cff8SDavid Pedersen 
126*e8cb48fcSQuentin Perez util::parametrized_tests! {
127*e8cb48fcSQuentin Perez     client_enabled_server_disabled,
128*e8cb48fcSQuentin Perez     zstd: CompressionEncoding::Zstd,
129*e8cb48fcSQuentin Perez     gzip: CompressionEncoding::Gzip,
130*e8cb48fcSQuentin Perez }
131*e8cb48fcSQuentin Perez 
132*e8cb48fcSQuentin Perez #[allow(dead_code)]
133*e8cb48fcSQuentin Perez async fn client_enabled_server_disabled(encoding: CompressionEncoding) {
1340583cff8SDavid Pedersen     let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10);
1350583cff8SDavid Pedersen 
1360583cff8SDavid Pedersen     let svc = test_server::TestServer::new(Svc::default());
1370583cff8SDavid Pedersen 
1380583cff8SDavid Pedersen     tokio::spawn(async move {
1390583cff8SDavid Pedersen         Server::builder()
1400583cff8SDavid Pedersen             .add_service(svc)
141f089e7a0Stottoto             .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server)))
1420583cff8SDavid Pedersen             .await
1430583cff8SDavid Pedersen             .unwrap();
1440583cff8SDavid Pedersen     });
1450583cff8SDavid Pedersen 
146*e8cb48fcSQuentin Perez     let mut client =
147*e8cb48fcSQuentin Perez         test_client::TestClient::new(mock_io_channel(client).await).send_compressed(encoding);
1480583cff8SDavid Pedersen 
1490583cff8SDavid Pedersen     let data = [0_u8; UNCOMPRESSED_MIN_BODY_SIZE].to_vec();
15023602b47Stottoto     let stream = tokio_stream::iter(vec![SomeData { data: data.clone() }, SomeData { data }]);
1510583cff8SDavid Pedersen     let req = Request::new(Box::pin(stream));
1520583cff8SDavid Pedersen 
1530583cff8SDavid Pedersen     let status = client.compress_input_client_stream(req).await.unwrap_err();
1540583cff8SDavid Pedersen 
1550583cff8SDavid Pedersen     assert_eq!(status.code(), tonic::Code::Unimplemented);
156*e8cb48fcSQuentin Perez     let expected = match encoding {
157*e8cb48fcSQuentin Perez         CompressionEncoding::Gzip => "gzip",
158*e8cb48fcSQuentin Perez         CompressionEncoding::Zstd => "zstd",
159*e8cb48fcSQuentin Perez         _ => panic!("unexpected encoding {:?}", encoding),
160*e8cb48fcSQuentin Perez     };
1610583cff8SDavid Pedersen     assert_eq!(
1620583cff8SDavid Pedersen         status.message(),
163*e8cb48fcSQuentin Perez         format!(
164*e8cb48fcSQuentin Perez             "Content is compressed with `{}` which isn't supported",
165*e8cb48fcSQuentin Perez             expected
166*e8cb48fcSQuentin Perez         )
1670583cff8SDavid Pedersen     );
1680583cff8SDavid Pedersen }
1690583cff8SDavid Pedersen 
170*e8cb48fcSQuentin Perez util::parametrized_tests! {
171*e8cb48fcSQuentin Perez     compressing_response_from_client_stream,
172*e8cb48fcSQuentin Perez     zstd: CompressionEncoding::Zstd,
173*e8cb48fcSQuentin Perez     gzip: CompressionEncoding::Gzip,
174*e8cb48fcSQuentin Perez }
175*e8cb48fcSQuentin Perez 
176*e8cb48fcSQuentin Perez #[allow(dead_code)]
177*e8cb48fcSQuentin Perez async fn compressing_response_from_client_stream(encoding: CompressionEncoding) {
1780583cff8SDavid Pedersen     let (client, server) = tokio::io::duplex(UNCOMPRESSED_MIN_BODY_SIZE * 10);
1790583cff8SDavid Pedersen 
180*e8cb48fcSQuentin Perez     let svc = test_server::TestServer::new(Svc::default()).send_compressed(encoding);
1810583cff8SDavid Pedersen 
1820583cff8SDavid Pedersen     let response_bytes_counter = Arc::new(AtomicUsize::new(0));
1830583cff8SDavid Pedersen 
1840583cff8SDavid Pedersen     tokio::spawn({
1850583cff8SDavid Pedersen         let response_bytes_counter = response_bytes_counter.clone();
1860583cff8SDavid Pedersen         async move {
1870583cff8SDavid Pedersen             Server::builder()
1880583cff8SDavid Pedersen                 .layer(
1890583cff8SDavid Pedersen                     ServiceBuilder::new()
1900583cff8SDavid Pedersen                         .layer(MapResponseBodyLayer::new(move |body| {
1910583cff8SDavid Pedersen                             util::CountBytesBody {
1920583cff8SDavid Pedersen                                 inner: body,
1930583cff8SDavid Pedersen                                 counter: response_bytes_counter.clone(),
1940583cff8SDavid Pedersen                             }
1950583cff8SDavid Pedersen                         }))
1960583cff8SDavid Pedersen                         .into_inner(),
1970583cff8SDavid Pedersen                 )
1980583cff8SDavid Pedersen                 .add_service(svc)
199f089e7a0Stottoto                 .serve_with_incoming(tokio_stream::once(Ok::<_, std::io::Error>(server)))
2000583cff8SDavid Pedersen                 .await
2010583cff8SDavid Pedersen                 .unwrap();
2020583cff8SDavid Pedersen         }
2030583cff8SDavid Pedersen     });
2040583cff8SDavid Pedersen 
205*e8cb48fcSQuentin Perez     let mut client =
206*e8cb48fcSQuentin Perez         test_client::TestClient::new(mock_io_channel(client).await).accept_compressed(encoding);
2070583cff8SDavid Pedersen 
208f089e7a0Stottoto     let req = Request::new(Box::pin(tokio_stream::empty()));
2090583cff8SDavid Pedersen 
2100583cff8SDavid Pedersen     let res = client.compress_output_client_stream(req).await.unwrap();
211*e8cb48fcSQuentin Perez     let expected = match encoding {
212*e8cb48fcSQuentin Perez         CompressionEncoding::Gzip => "gzip",
213*e8cb48fcSQuentin Perez         CompressionEncoding::Zstd => "zstd",
214*e8cb48fcSQuentin Perez         _ => panic!("unexpected encoding {:?}", encoding),
215*e8cb48fcSQuentin Perez     };
216*e8cb48fcSQuentin Perez     assert_eq!(res.metadata().get("grpc-encoding").unwrap(), expected);
2170583cff8SDavid Pedersen     let bytes_sent = response_bytes_counter.load(SeqCst);
2180583cff8SDavid Pedersen     assert!(bytes_sent < UNCOMPRESSED_MIN_BODY_SIZE);
2190583cff8SDavid Pedersen }
220