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