Skip to content

Commit 900e075

Browse files
committed
chore(socket): basic TCP + (mutual) TLS integration test on reqrep
1 parent 3d04d6e commit 900e075

File tree

3 files changed

+128
-5
lines changed

3 files changed

+128
-5
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

msg-socket/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ parking_lot.workspace = true
2929
[dev-dependencies]
3030
rand.workspace = true
3131
msg-transport = { workspace = true, features = ["quic"] }
32+
openssl.workspace = true
3233

3334
msg-sim.workspace = true
3435

msg-socket/tests/it/reqrep.rs

Lines changed: 126 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,64 @@
11
use bytes::Bytes;
22
use msg_socket::{RepSocket, ReqSocket};
3-
use msg_transport::tcp::Tcp;
3+
use msg_transport::{
4+
tcp::Tcp,
5+
tcp_tls::{self, TcpTls},
6+
};
47
use tokio_stream::StreamExt;
58

6-
#[tokio::test(flavor = "multi_thread", worker_threads = 4)]
7-
async fn test_reqrep() {
9+
/// Helper functions.
10+
mod helpers {
11+
use std::{path::PathBuf, str::FromStr as _};
12+
13+
use openssl::ssl::{
14+
SslAcceptor, SslAcceptorBuilder, SslConnector, SslConnectorBuilder, SslFiletype, SslMethod,
15+
};
16+
17+
/// Creates a default SSL acceptor builder for testing, with a trusted CA.
18+
pub fn default_acceptor_builder() -> SslAcceptorBuilder {
19+
let certificate_path =
20+
PathBuf::from_str("../testdata/certificates/server-cert.pem").unwrap();
21+
let private_key_path =
22+
PathBuf::from_str("../testdata/certificates/server-key.pem").unwrap();
23+
let ca_certificate_path =
24+
PathBuf::from_str("../testdata/certificates/ca-cert.pem").unwrap();
25+
26+
assert!(certificate_path.exists(), "Certificate file does not exist");
27+
assert!(private_key_path.exists(), "Private key file does not exist");
28+
assert!(ca_certificate_path.exists(), "CA Certificate file does not exist");
29+
30+
let mut acceptor_builder = SslAcceptor::mozilla_intermediate(SslMethod::tls()).unwrap();
31+
acceptor_builder.set_certificate_file(certificate_path, SslFiletype::PEM).unwrap();
32+
acceptor_builder.set_private_key_file(private_key_path, SslFiletype::PEM).unwrap();
33+
acceptor_builder.set_ca_file(ca_certificate_path).unwrap();
34+
acceptor_builder
35+
}
36+
37+
/// Creates a default SSL connector builder for testing, with a trusted CA.
38+
/// It also has client certificate and private key set for mTLS testing.
39+
pub fn default_connector_builder() -> SslConnectorBuilder {
40+
let certificate_path =
41+
PathBuf::from_str("../testdata/certificates/client-cert.pem").unwrap();
42+
let private_key_path =
43+
PathBuf::from_str("../testdata/certificates/client-key.pem").unwrap();
44+
let ca_certificate_path =
45+
PathBuf::from_str("../testdata/certificates/ca-cert.pem").unwrap();
46+
47+
assert!(certificate_path.exists(), "Certificate file does not exist");
48+
assert!(private_key_path.exists(), "Private key file does not exist");
49+
assert!(ca_certificate_path.exists(), "CA Certificate file does not exist");
50+
51+
let mut connector_builder = SslConnector::builder(SslMethod::tls()).unwrap();
52+
connector_builder.set_certificate_file(certificate_path, SslFiletype::PEM).unwrap();
53+
connector_builder.set_private_key_file(private_key_path, SslFiletype::PEM).unwrap();
54+
connector_builder.set_ca_file(ca_certificate_path).unwrap();
55+
56+
connector_builder
57+
}
58+
}
59+
60+
#[tokio::test]
61+
async fn reqrep_works() {
862
let _ = tracing_subscriber::fmt::try_init();
963

1064
let mut rep = RepSocket::new(Tcp::default());
@@ -21,6 +75,73 @@ async fn test_reqrep() {
2175
}
2276
});
2377

24-
let response = req.request(Bytes::from_static(b"hello")).await.unwrap();
25-
tracing::info!("Response: {:?}", response);
78+
let hello = Bytes::from_static(b"hello");
79+
let response = req.request(hello.clone()).await.unwrap();
80+
assert_eq!(hello, response, "expected {:?}, got {:?}", hello, response);
81+
}
82+
83+
#[tokio::test]
84+
async fn reqrep_tls_works() {
85+
let _ = tracing_subscriber::fmt::try_init();
86+
87+
let server_config =
88+
tcp_tls::config::Server { ssl_acceptor: helpers::default_acceptor_builder().build() };
89+
let tcp_tls_server = TcpTls::new_server(server_config);
90+
let mut rep = RepSocket::new(tcp_tls_server);
91+
92+
rep.bind("0.0.0.0:0").await.unwrap();
93+
94+
let domain = "localhost".to_string();
95+
let ssl_connector = helpers::default_connector_builder().build();
96+
let tcp_tls_client =
97+
TcpTls::new_client(tcp_tls::config::Client::new(domain).with_ssl_connector(ssl_connector));
98+
let mut req = ReqSocket::new(tcp_tls_client);
99+
100+
req.connect(rep.local_addr().unwrap()).await.unwrap();
101+
102+
tokio::spawn(async move {
103+
while let Some(request) = rep.next().await {
104+
let msg = request.msg().clone();
105+
request.respond(msg).unwrap();
106+
}
107+
});
108+
109+
let hello = Bytes::from_static(b"hello");
110+
let response = req.request(hello.clone()).await.unwrap();
111+
assert_eq!(hello, response, "expected {:?}, got {:?}", hello, response);
112+
}
113+
114+
#[tokio::test]
115+
async fn reqrep_mutual_tls_works() {
116+
let _ = tracing_subscriber::fmt::try_init();
117+
118+
let mut acceptor_builder = helpers::default_acceptor_builder();
119+
// By specifying peer verification mode, we essentially toggle mTLS.
120+
acceptor_builder.set_verify(
121+
openssl::ssl::SslVerifyMode::PEER | openssl::ssl::SslVerifyMode::FAIL_IF_NO_PEER_CERT,
122+
);
123+
let server_config = tcp_tls::config::Server { ssl_acceptor: acceptor_builder.build() };
124+
let tcp_tls_server = TcpTls::new_server(server_config);
125+
let mut rep = RepSocket::new(tcp_tls_server);
126+
127+
rep.bind("0.0.0.0:0").await.unwrap();
128+
129+
let domain = "localhost".to_string();
130+
let ssl_connector = helpers::default_connector_builder().build();
131+
let tcp_tls_client =
132+
TcpTls::new_client(tcp_tls::config::Client::new(domain).with_ssl_connector(ssl_connector));
133+
let mut req = ReqSocket::new(tcp_tls_client);
134+
135+
req.connect(rep.local_addr().unwrap()).await.unwrap();
136+
137+
tokio::spawn(async move {
138+
while let Some(request) = rep.next().await {
139+
let msg = request.msg().clone();
140+
request.respond(msg).unwrap();
141+
}
142+
});
143+
144+
let hello = Bytes::from_static(b"hello");
145+
let response = req.request(hello.clone()).await.unwrap();
146+
assert_eq!(hello, response, "expected {:?}, got {:?}", hello, response);
26147
}

0 commit comments

Comments
 (0)