Skip to content

Commit 24dc5d8

Browse files
authored
chore(app/inbound): address hyper deprecations in http/2 tests (#3445)
this addresses deprecations in inbound proxy tests that should migrate to hyper's new http/2 client connection builder. http/1 tests will be upgraded in a follow-on commit. the `connect_and_accept(..)` helper function is copied, and duplicated into an http/2 version. see <linkerd/linkerd2#8733> for more information on upgrading to hyper 1.0. Signed-off-by: katelyn martin <kate@buoyant.io>
1 parent 307dbc4 commit 24dc5d8

File tree

2 files changed

+74
-34
lines changed

2 files changed

+74
-34
lines changed

linkerd/app/inbound/src/http/tests.rs

+17-27
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ async fn http1_bad_gateway_meshed_response_error_header() {
199199
let cfg = default_config();
200200
let (rt, _shutdown) = runtime();
201201
let server = build_server(cfg, rt, profiles, connect).new_service(Target::meshed_http1());
202-
let (client, bg) = http_util::connect_and_accept(&mut client, server).await;
202+
let (mut client, bg) = http_util::connect_and_accept(&mut client, server).await;
203203

204204
// Send a request and assert that it is a BAD_GATEWAY with the expected
205205
// header message.
@@ -209,7 +209,7 @@ async fn http1_bad_gateway_meshed_response_error_header() {
209209
.body(Body::default())
210210
.unwrap();
211211
let rsp = client
212-
.oneshot(req)
212+
.send_request(req)
213213
.await
214214
.expect("HTTP client request failed");
215215
tracing::info!(?rsp);
@@ -380,17 +380,15 @@ async fn h2_response_meshed_error_header() {
380380
let connect = support::connect().endpoint_fn_boxed(Target::addr(), connect_error());
381381

382382
// Build a client using the connect that always errors.
383-
#[allow(deprecated)] // linkerd/linkerd2#8733
384-
let mut client = hyper::client::conn::Builder::new();
385-
client.http2_only(true);
383+
let mut client = hyper::client::conn::http2::Builder::new(TracingExecutor);
386384
let profiles = profile::resolver();
387385
let profile_tx =
388386
profiles.profile_tx(NameAddr::from_str_and_port("foo.svc.cluster.local", 5550).unwrap());
389387
profile_tx.send(profile::Profile::default()).unwrap();
390388
let cfg = default_config();
391389
let (rt, _shutdown) = runtime();
392390
let server = build_server(cfg, rt, profiles, connect).new_service(Target::meshed_h2());
393-
let (client, bg) = http_util::connect_and_accept(&mut client, server).await;
391+
let (mut client, bg) = http_util::connect_and_accept_http2(&mut client, server).await;
394392

395393
// Send a request and assert that it is SERVICE_UNAVAILABLE with the
396394
// expected header message.
@@ -400,7 +398,7 @@ async fn h2_response_meshed_error_header() {
400398
.body(Body::default())
401399
.unwrap();
402400
let rsp = client
403-
.oneshot(req)
401+
.send_request(req)
404402
.await
405403
.expect("HTTP client request failed");
406404
tracing::info!(?rsp);
@@ -422,17 +420,15 @@ async fn h2_response_unmeshed_error_header() {
422420
let connect = support::connect().endpoint_fn_boxed(Target::addr(), connect_error());
423421

424422
// Build a client using the connect that always errors.
425-
#[allow(deprecated)] // linkerd/linkerd2#8733
426-
let mut client = hyper::client::conn::Builder::new();
427-
client.http2_only(true);
423+
let mut client = hyper::client::conn::http2::Builder::new(TracingExecutor);
428424
let profiles = profile::resolver();
429425
let profile_tx =
430426
profiles.profile_tx(NameAddr::from_str_and_port("foo.svc.cluster.local", 5550).unwrap());
431427
profile_tx.send(profile::Profile::default()).unwrap();
432428
let cfg = default_config();
433429
let (rt, _shutdown) = runtime();
434430
let server = build_server(cfg, rt, profiles, connect).new_service(Target::UNMESHED_H2);
435-
let (client, bg) = http_util::connect_and_accept(&mut client, server).await;
431+
let (mut client, bg) = http_util::connect_and_accept_http2(&mut client, server).await;
436432

437433
// Send a request and assert that it is SERVICE_UNAVAILABLE with the
438434
// expected header message.
@@ -442,7 +438,7 @@ async fn h2_response_unmeshed_error_header() {
442438
.body(Body::default())
443439
.unwrap();
444440
let rsp = client
445-
.oneshot(req)
441+
.send_request(req)
446442
.await
447443
.expect("HTTP client request failed");
448444
tracing::info!(?rsp);
@@ -466,17 +462,15 @@ async fn grpc_meshed_response_error_header() {
466462
let connect = support::connect().endpoint_fn_boxed(Target::addr(), connect_error());
467463

468464
// Build a client using the connect that always errors.
469-
#[allow(deprecated)] // linkerd/linkerd2#8733
470-
let mut client = hyper::client::conn::Builder::new();
471-
client.http2_only(true);
465+
let mut client = hyper::client::conn::http2::Builder::new(TracingExecutor);
472466
let profiles = profile::resolver();
473467
let profile_tx =
474468
profiles.profile_tx(NameAddr::from_str_and_port("foo.svc.cluster.local", 5550).unwrap());
475469
profile_tx.send(profile::Profile::default()).unwrap();
476470
let cfg = default_config();
477471
let (rt, _shutdown) = runtime();
478472
let server = build_server(cfg, rt, profiles, connect).new_service(Target::meshed_h2());
479-
let (client, bg) = http_util::connect_and_accept(&mut client, server).await;
473+
let (mut client, bg) = http_util::connect_and_accept_http2(&mut client, server).await;
480474

481475
// Send a request and assert that it is OK with the expected header
482476
// message.
@@ -487,7 +481,7 @@ async fn grpc_meshed_response_error_header() {
487481
.body(Body::default())
488482
.unwrap();
489483
let rsp = client
490-
.oneshot(req)
484+
.send_request(req)
491485
.await
492486
.expect("HTTP client request failed");
493487
tracing::info!(?rsp);
@@ -509,17 +503,15 @@ async fn grpc_unmeshed_response_error_header() {
509503
let connect = support::connect().endpoint_fn_boxed(Target::addr(), connect_error());
510504

511505
// Build a client using the connect that always errors.
512-
#[allow(deprecated)] // linkerd/linkerd2#8733
513-
let mut client = hyper::client::conn::Builder::new();
514-
client.http2_only(true);
506+
let mut client = hyper::client::conn::http2::Builder::new(TracingExecutor);
515507
let profiles = profile::resolver();
516508
let profile_tx =
517509
profiles.profile_tx(NameAddr::from_str_and_port("foo.svc.cluster.local", 5550).unwrap());
518510
profile_tx.send(profile::Profile::default()).unwrap();
519511
let cfg = default_config();
520512
let (rt, _shutdown) = runtime();
521513
let server = build_server(cfg, rt, profiles, connect).new_service(Target::UNMESHED_H2);
522-
let (client, bg) = http_util::connect_and_accept(&mut client, server).await;
514+
let (mut client, bg) = http_util::connect_and_accept_http2(&mut client, server).await;
523515

524516
// Send a request and assert that it is OK with the expected header
525517
// message.
@@ -530,7 +522,7 @@ async fn grpc_unmeshed_response_error_header() {
530522
.body(Body::default())
531523
.unwrap();
532524
let rsp = client
533-
.oneshot(req)
525+
.send_request(req)
534526
.await
535527
.expect("HTTP client request failed");
536528
tracing::info!(?rsp);
@@ -560,9 +552,7 @@ async fn grpc_response_class() {
560552
};
561553

562554
// Build a client using the connect that always errors.
563-
#[allow(deprecated)] // linkerd/linkerd2#8733
564-
let mut client = hyper::client::conn::Builder::new();
565-
client.http2_only(true);
555+
let mut client = hyper::client::conn::http2::Builder::new(TracingExecutor);
566556
let profiles = profile::resolver();
567557
let profile_tx =
568558
profiles.profile_tx(NameAddr::from_str_and_port("foo.svc.cluster.local", 5550).unwrap());
@@ -575,7 +565,7 @@ async fn grpc_response_class() {
575565
.http_endpoint
576566
.into_report(time::Duration::from_secs(3600));
577567
let server = build_server(cfg, rt, profiles, connect).new_service(Target::meshed_h2());
578-
let (client, bg) = http_util::connect_and_accept(&mut client, server).await;
568+
let (mut client, bg) = http_util::connect_and_accept_http2(&mut client, server).await;
579569

580570
// Send a request and assert that it is OK with the expected header
581571
// message.
@@ -587,7 +577,7 @@ async fn grpc_response_class() {
587577
.unwrap();
588578

589579
let mut rsp = client
590-
.oneshot(req)
580+
.send_request(req)
591581
.await
592582
.expect("HTTP client request failed");
593583
tracing::info!(?rsp);

linkerd/app/test/src/http_util.rs

+57-7
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,11 @@ use crate::{
22
app_core::{svc, Error},
33
io, ContextError,
44
};
5-
use hyper::{body::HttpBody, Body};
5+
use http_body::Body;
66
use tokio::task::JoinSet;
77
use tower::ServiceExt;
88
use tracing::Instrument;
99

10-
#[allow(deprecated)] // linkerd/linkerd2#8733
11-
use hyper::client::conn::{Builder as ClientBuilder, SendRequest};
12-
1310
type BoxServer = svc::BoxTcp<io::DuplexStream>;
1411

1512
/// Connects a client and server, running a proxy between them.
@@ -18,9 +15,62 @@ type BoxServer = svc::BoxTcp<io::DuplexStream>;
1815
/// await a response, and (2) a [`JoinSet<T>`] running background tasks.
1916
#[allow(deprecated)] // linkerd/linkerd2#8733
2017
pub async fn connect_and_accept(
21-
client_settings: &mut ClientBuilder,
18+
client_settings: &mut hyper::client::conn::Builder,
2219
server: BoxServer,
23-
) -> (SendRequest<Body>, JoinSet<Result<(), Error>>) {
20+
) -> (
21+
hyper::client::conn::SendRequest<hyper::Body>,
22+
JoinSet<Result<(), Error>>,
23+
) {
24+
tracing::info!(settings = ?client_settings, "connecting client with");
25+
let (client_io, server_io) = io::duplex(4096);
26+
27+
let (client, conn) = client_settings
28+
.handshake(client_io)
29+
.await
30+
.expect("Client must connect");
31+
32+
let mut bg = tokio::task::JoinSet::new();
33+
bg.spawn(
34+
async move {
35+
server
36+
.oneshot(server_io)
37+
.await
38+
.map_err(ContextError::ctx("proxy background task failed"))?;
39+
tracing::info!("proxy serve task complete");
40+
Ok(())
41+
}
42+
.instrument(tracing::info_span!("proxy")),
43+
);
44+
bg.spawn(
45+
async move {
46+
conn.await
47+
.map_err(ContextError::ctx("client background task failed"))
48+
.map_err(Error::from)?;
49+
tracing::info!("client background complete");
50+
Ok(())
51+
}
52+
.instrument(tracing::info_span!("client_bg")),
53+
);
54+
55+
(client, bg)
56+
}
57+
58+
/// Connects a client and server, running a proxy between them.
59+
///
60+
/// Returns a tuple containing (1) a [`SendRequest`] that can be used to transmit a request and
61+
/// await a response, and (2) a [`JoinSet<T>`] running background tasks.
62+
pub async fn connect_and_accept_http2<B>(
63+
client_settings: &mut hyper::client::conn::http2::Builder,
64+
server: BoxServer,
65+
) -> (
66+
hyper::client::conn::http2::SendRequest<B>,
67+
JoinSet<Result<(), Error>>,
68+
)
69+
where
70+
B: Body + Send + 'static,
71+
B::Data: Send,
72+
B::Error: Into<Box<dyn std::error::Error + Send + Sync>>,
73+
{
2474
tracing::info!(settings = ?client_settings, "connecting client with");
2575
let (client_io, server_io) = io::duplex(4096);
2676

@@ -58,7 +108,7 @@ pub async fn connect_and_accept(
58108
/// Collects a request or response body, returning it as a [`String`].
59109
pub async fn body_to_string<T>(body: T) -> Result<String, Error>
60110
where
61-
T: HttpBody,
111+
T: Body,
62112
T::Error: Into<Error>,
63113
{
64114
let bytes = body

0 commit comments

Comments
 (0)