test: prefer real server for compliant peers #89
No files matched your search
Generated
+1
@@ -712,6 +712,7 @@ name = "irtt-client"
|
|||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"irtt-proto",
|
"irtt-proto",
|
||||||
|
"irtt-server",
|
||||||
"nix 0.31.3",
|
"nix 0.31.3",
|
||||||
"socket2",
|
"socket2",
|
||||||
"thiserror 2.0.20",
|
"thiserror 2.0.20",
|
||||||
|
|||||||
@@ -27,3 +27,7 @@ tokio = ["dep:tokio"]
|
|||||||
|
|
||||||
[package.metadata.docs.rs]
|
[package.metadata.docs.rs]
|
||||||
all-features = true
|
all-features = true
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
irtt-server.workspace = true
|
||||||
|
tokio = { version = "1.53.1", default-features = false, features = ["rt", "sync"] }
|
||||||
@@ -14,11 +14,16 @@ use irtt_proto::{
|
|||||||
};
|
};
|
||||||
use tokio::runtime::{Builder, Runtime};
|
use tokio::runtime::{Builder, Runtime};
|
||||||
|
|
||||||
|
#[path = "../../tests/support/in_tree_server.rs"]
|
||||||
|
mod in_tree_server;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::{
|
use crate::{
|
||||||
probe::PendingProbe, socket_options::tokio_socket_traffic_class, Client, ClientTimestamp,
|
probe::PendingProbe, socket_options::tokio_socket_traffic_class, Client, ClientTimestamp,
|
||||||
RunMode, SocketConfig,
|
RunMode, SocketConfig,
|
||||||
};
|
};
|
||||||
|
use in_tree_server::InTreeServer;
|
||||||
|
use irtt_server::ServerConfig;
|
||||||
|
|
||||||
const TOKEN: u64 = 0x1234_5678_90ab_cdef;
|
const TOKEN: u64 = 0x1234_5678_90ab_cdef;
|
||||||
|
|
||||||
@@ -248,24 +253,6 @@ fn start_peer_close_server() -> TestServer {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn start_echo_close_server(key: Option<Vec<u8>>) -> TestServer {
|
|
||||||
start_server(move |socket, tx| {
|
|
||||||
let (params, peer) = open_session(&socket, &tx, key.as_deref());
|
|
||||||
|
|
||||||
let (probe_packet, _) = recv_packet(&socket, &tx);
|
|
||||||
let sequence = echo_request_sequence(&probe_packet, key.as_deref());
|
|
||||||
socket
|
|
||||||
.send_to(
|
|
||||||
&echo_reply(¶ms, sequence, TOKEN, flags::FLAG_REPLY, key.as_deref()),
|
|
||||||
peer,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
let (close_packet, _) = recv_packet(&socket, &tx);
|
|
||||||
assert_eq!(close_request_token(&close_packet, key.as_deref()), TOKEN);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn poll_once<F: Future>(future: Pin<&mut F>) -> Poll<F::Output> {
|
fn poll_once<F: Future>(future: Pin<&mut F>) -> Poll<F::Output> {
|
||||||
let mut context = Context::from_waker(Waker::noop());
|
let mut context = Context::from_waker(Waker::noop());
|
||||||
Future::poll(future, &mut context)
|
Future::poll(future, &mut context)
|
||||||
@@ -1084,16 +1071,16 @@ fn successful_close_uses_post_acceptance_timestamp() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn blocking_and_async_hmac_dscp_lifecycle_are_semantically_equivalent() {
|
fn blocking_and_async_hmac_dscp_lifecycle_are_semantically_equivalent() {
|
||||||
let key = b"async-equivalence-key".to_vec();
|
let key = b"async-equivalence-key".to_vec();
|
||||||
let blocking_server = start_echo_close_server(Some(key.clone()));
|
let blocking_server = InTreeServer::start(ServerConfig::default().with_hmac_key(key.clone()));
|
||||||
let mut blocking =
|
let mut blocking =
|
||||||
Client::connect(config(blocking_server.addr, Some(key.clone()), 46)).unwrap();
|
Client::connect(config(blocking_server.addr, Some(key.clone()), 46)).unwrap();
|
||||||
let blocking_open = blocking.open().unwrap();
|
let blocking_open = blocking.open().unwrap();
|
||||||
let blocking_sent = blocking.send_probe().unwrap();
|
let blocking_sent = blocking.send_probe().unwrap();
|
||||||
let blocking_reply = blocking.recv_once().unwrap();
|
let blocking_reply = blocking.recv_once().unwrap();
|
||||||
let blocking_close = blocking.close().unwrap();
|
let blocking_close = blocking.close().unwrap();
|
||||||
assert_eq!(blocking_server.finish().len(), 3);
|
drop(blocking_server);
|
||||||
|
|
||||||
let async_server = start_echo_close_server(Some(key.clone()));
|
let async_server = InTreeServer::start(ServerConfig::default().with_hmac_key(key.clone()));
|
||||||
let (async_open, async_sent, async_reply, async_close) = runtime().block_on(async {
|
let (async_open, async_sent, async_reply, async_close) = runtime().block_on(async {
|
||||||
let mut client = AsyncClient::connect(config(async_server.addr, Some(key), 46))
|
let mut client = AsyncClient::connect(config(async_server.addr, Some(key), 46))
|
||||||
.await
|
.await
|
||||||
@@ -1105,7 +1092,7 @@ fn blocking_and_async_hmac_dscp_lifecycle_are_semantically_equivalent() {
|
|||||||
let closed = client.close().await.unwrap();
|
let closed = client.close().await.unwrap();
|
||||||
(opened, sent, reply, closed)
|
(opened, sent, reply, closed)
|
||||||
});
|
});
|
||||||
assert_eq!(async_server.finish().len(), 3);
|
drop(async_server);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
open_negotiated(&blocking_open),
|
open_negotiated(&blocking_open),
|
||||||
@@ -1118,20 +1105,28 @@ fn blocking_and_async_hmac_dscp_lifecycle_are_semantically_equivalent() {
|
|||||||
);
|
);
|
||||||
assert_matching_event_shape(&blocking_sent[0], &async_sent[0]);
|
assert_matching_event_shape(&blocking_sent[0], &async_sent[0]);
|
||||||
assert_matching_event_shape(&blocking_reply[0], &async_reply[0]);
|
assert_matching_event_shape(&blocking_reply[0], &async_reply[0]);
|
||||||
|
assert!(matches!(
|
||||||
|
blocking_close.as_slice(),
|
||||||
|
[ClientEvent::SessionClosed { token, .. }] if *token == open_token(&blocking_open)
|
||||||
|
));
|
||||||
|
assert!(matches!(
|
||||||
|
async_close.as_slice(),
|
||||||
|
[ClientEvent::SessionClosed { token, .. }] if *token == open_token(&async_open)
|
||||||
|
));
|
||||||
assert_matching_event_shape(&blocking_close[0], &async_close[0]);
|
assert_matching_event_shape(&blocking_close[0], &async_close[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn blocking_and_async_no_test_are_semantically_equivalent() {
|
fn blocking_and_async_no_test_are_semantically_equivalent() {
|
||||||
let blocking_no_test_server = start_no_test_server();
|
let blocking_no_test_server = InTreeServer::start(ServerConfig::default());
|
||||||
let mut blocking_no_test_config = config(blocking_no_test_server.addr, None, 0);
|
let mut blocking_no_test_config = config(blocking_no_test_server.addr, None, 0);
|
||||||
blocking_no_test_config.run_mode = RunMode::NoTest;
|
blocking_no_test_config.run_mode = RunMode::NoTest;
|
||||||
let mut blocking_no_test = Client::connect(blocking_no_test_config).unwrap();
|
let mut blocking_no_test = Client::connect(blocking_no_test_config).unwrap();
|
||||||
let blocking_no_test_open = blocking_no_test.open().unwrap();
|
let blocking_no_test_open = blocking_no_test.open().unwrap();
|
||||||
assert!(blocking_no_test.is_run_complete());
|
assert!(blocking_no_test.is_run_complete());
|
||||||
assert_eq!(blocking_no_test_server.finish().len(), 1);
|
drop(blocking_no_test_server);
|
||||||
|
|
||||||
let async_no_test_server = start_no_test_server();
|
let async_no_test_server = InTreeServer::start(ServerConfig::default());
|
||||||
let mut async_no_test_config = config(async_no_test_server.addr, None, 0);
|
let mut async_no_test_config = config(async_no_test_server.addr, None, 0);
|
||||||
async_no_test_config.run_mode = RunMode::NoTest;
|
async_no_test_config.run_mode = RunMode::NoTest;
|
||||||
let async_no_test_open = runtime().block_on(async {
|
let async_no_test_open = runtime().block_on(async {
|
||||||
@@ -1140,7 +1135,7 @@ fn blocking_and_async_no_test_are_semantically_equivalent() {
|
|||||||
assert!(client.is_run_complete());
|
assert!(client.is_run_complete());
|
||||||
opened
|
opened
|
||||||
});
|
});
|
||||||
assert_eq!(async_no_test_server.finish().len(), 1);
|
drop(async_no_test_server);
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
blocking_no_test_open,
|
blocking_no_test_open,
|
||||||
OpenOutcome::NoTestCompleted { .. }
|
OpenOutcome::NoTestCompleted { .. }
|
||||||
@@ -1197,6 +1192,13 @@ fn open_negotiated(outcome: &OpenOutcome) -> &crate::NegotiatedParams {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn open_token(outcome: &OpenOutcome) -> u64 {
|
||||||
|
match outcome {
|
||||||
|
OpenOutcome::Started { token, .. } => *token,
|
||||||
|
OpenOutcome::NoTestCompleted { .. } => panic!("no-test open has no session token"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fn assert_matching_event_shape(blocking: &ClientEvent, asynchronous: &ClientEvent) {
|
fn assert_matching_event_shape(blocking: &ClientEvent, asynchronous: &ClientEvent) {
|
||||||
assert_eq!(event_shape(blocking), event_shape(asynchronous));
|
assert_eq!(event_shape(blocking), event_shape(asynchronous));
|
||||||
}
|
}
|
||||||
@@ -1205,7 +1207,7 @@ fn event_shape(event: &ClientEvent) -> (&'static str, u64, usize) {
|
|||||||
match event {
|
match event {
|
||||||
ClientEvent::EchoSent { seq, bytes, .. } => ("sent", u64::from(*seq), *bytes),
|
ClientEvent::EchoSent { seq, bytes, .. } => ("sent", u64::from(*seq), *bytes),
|
||||||
ClientEvent::EchoReply { seq, bytes, .. } => ("reply", u64::from(*seq), *bytes),
|
ClientEvent::EchoReply { seq, bytes, .. } => ("reply", u64::from(*seq), *bytes),
|
||||||
ClientEvent::SessionClosed { token, .. } => ("closed", *token, 0),
|
ClientEvent::SessionClosed { .. } => ("closed", 0, 0),
|
||||||
other => panic!("unexpected equivalence event: {other:?}"),
|
other => panic!("unexpected equivalence event: {other:?}"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -276,7 +276,7 @@ fn assert_no_duplicate_late_or_warning(events: &[ClientEvent]) {
|
|||||||
fn backend_hmac_correct_key_succeeds() {
|
fn backend_hmac_correct_key_succeeds() {
|
||||||
let key = b"compat-secret".to_vec();
|
let key = b"compat-secret".to_vec();
|
||||||
let params = default_params();
|
let params = default_params();
|
||||||
let peer = BackendPeer::start_open_echo(params.clone(), Some(key.clone()));
|
let peer = BackendPeer::start_open_echo(Some(key.clone()));
|
||||||
let mut config = config_for_params(peer.addr(), ¶ms);
|
let mut config = config_for_params(peer.addr(), ¶ms);
|
||||||
config.hmac_key = Some(key);
|
config.hmac_key = Some(key);
|
||||||
|
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ fn echo_reply_bytes_consistent_with_echo_packet_len_for_various_lengths() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn backend_large_packet_smoke() {
|
fn backend_large_packet_smoke() {
|
||||||
let params = params_with_length(1472);
|
let params = params_with_length(1472);
|
||||||
let peer = BackendPeer::start_open_echo(params.clone(), None);
|
let peer = BackendPeer::start_open_echo(None);
|
||||||
let mut client = Client::connect(ClientConfig {
|
let mut client = Client::connect(ClientConfig {
|
||||||
negotiation_policy: NegotiationPolicy::Loose,
|
negotiation_policy: NegotiationPolicy::Loose,
|
||||||
length: 1472,
|
length: 1472,
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use crate::support::{config_for_params, default_params, params_for_modes, Backen
|
|||||||
#[test]
|
#[test]
|
||||||
fn backend_basic_open_echo_close() {
|
fn backend_basic_open_echo_close() {
|
||||||
let params = default_params();
|
let params = default_params();
|
||||||
let peer = BackendPeer::start_open_echo(params.clone(), None);
|
let peer = BackendPeer::start_open_echo(None);
|
||||||
let mut client = Client::connect(config_for_params(peer.addr(), ¶ms)).unwrap();
|
let mut client = Client::connect(config_for_params(peer.addr(), ¶ms)).unwrap();
|
||||||
|
|
||||||
let outcome = client.open().unwrap();
|
let outcome = client.open().unwrap();
|
||||||
@@ -31,7 +31,7 @@ fn backend_received_stats_smoke() {
|
|||||||
ReceivedStats::Both,
|
ReceivedStats::Both,
|
||||||
] {
|
] {
|
||||||
let params = params_for_modes(mode, StampAt::None, Clock::Both);
|
let params = params_for_modes(mode, StampAt::None, Clock::Both);
|
||||||
let peer = BackendPeer::start_open_echo(params.clone(), None);
|
let peer = BackendPeer::start_open_echo(None);
|
||||||
let mut client = Client::connect(config_for_params(peer.addr(), ¶ms)).unwrap();
|
let mut client = Client::connect(config_for_params(peer.addr(), ¶ms)).unwrap();
|
||||||
|
|
||||||
client.open().unwrap();
|
client.open().unwrap();
|
||||||
@@ -54,7 +54,7 @@ fn backend_timestamp_smoke() {
|
|||||||
StampAt::Midpoint,
|
StampAt::Midpoint,
|
||||||
] {
|
] {
|
||||||
let params = params_for_modes(ReceivedStats::None, mode, Clock::Both);
|
let params = params_for_modes(ReceivedStats::None, mode, Clock::Both);
|
||||||
let peer = BackendPeer::start_open_echo(params.clone(), None);
|
let peer = BackendPeer::start_open_echo(None);
|
||||||
let mut client = Client::connect(config_for_params(peer.addr(), ¶ms)).unwrap();
|
let mut client = Client::connect(config_for_params(peer.addr(), ¶ms)).unwrap();
|
||||||
|
|
||||||
client.open().unwrap();
|
client.open().unwrap();
|
||||||
@@ -101,7 +101,7 @@ fn backend_timestamp_smoke() {
|
|||||||
fn backend_clock_smoke() {
|
fn backend_clock_smoke() {
|
||||||
for clock in [Clock::Wall, Clock::Monotonic, Clock::Both] {
|
for clock in [Clock::Wall, Clock::Monotonic, Clock::Both] {
|
||||||
let params = params_for_modes(ReceivedStats::None, StampAt::Both, clock);
|
let params = params_for_modes(ReceivedStats::None, StampAt::Both, clock);
|
||||||
let peer = BackendPeer::start_open_echo(params.clone(), None);
|
let peer = BackendPeer::start_open_echo(None);
|
||||||
let mut client = Client::connect(config_for_params(peer.addr(), ¶ms)).unwrap();
|
let mut client = Client::connect(config_for_params(peer.addr(), ¶ms)).unwrap();
|
||||||
|
|
||||||
client.open().unwrap();
|
client.open().unwrap();
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ use irtt_proto::{Params, TimestampFields};
|
|||||||
|
|
||||||
use support::{
|
use support::{
|
||||||
config_for_params, default_params, run_one_probe, run_one_probe_with_config, server_fill,
|
config_for_params, default_params, run_one_probe, run_one_probe_with_config, server_fill,
|
||||||
start_open_server, OneProbeRun, ServerObservation,
|
start_open_server, InTreeServer, OneProbeRun, ServerObservation,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::support::test_echo_packet_len;
|
use crate::support::test_echo_packet_len;
|
||||||
@@ -68,8 +68,21 @@ fn server_fill_empty_and_oversized_values_are_rejected_at_config_boundary() {
|
|||||||
fn server_fill_negotiated_params_reflect_accepted_value() {
|
fn server_fill_negotiated_params_reflect_accepted_value() {
|
||||||
let mut params = default_params();
|
let mut params = default_params();
|
||||||
params.server_fill = server_fill("rand");
|
params.server_fill = server_fill("rand");
|
||||||
let run = run_one_probe(params.clone(), TimestampFields::default());
|
let server = InTreeServer::start(irtt_server::ServerConfig::default());
|
||||||
assert_eq!(run.negotiated.params.server_fill, params.server_fill);
|
let mut client = Client::connect(config_for_params(server.addr, ¶ms)).unwrap();
|
||||||
|
let outcome = client.open().unwrap();
|
||||||
|
let negotiated = match outcome {
|
||||||
|
irtt_client::OpenOutcome::Started { negotiated, .. } => negotiated,
|
||||||
|
other => panic!("expected started outcome, got {other:?}"),
|
||||||
|
};
|
||||||
|
assert_eq!(negotiated.params.server_fill, params.server_fill);
|
||||||
|
|
||||||
|
client.send_probe().unwrap();
|
||||||
|
assert!(matches!(
|
||||||
|
client.recv_once().unwrap().as_slice(),
|
||||||
|
[irtt_client::ClientEvent::EchoReply { .. }]
|
||||||
|
));
|
||||||
|
client.close().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -0,0 +1,99 @@
|
|||||||
|
use std::{
|
||||||
|
net::{IpAddr, Ipv4Addr, SocketAddr},
|
||||||
|
sync::mpsc,
|
||||||
|
thread::{self, JoinHandle},
|
||||||
|
time::Duration,
|
||||||
|
};
|
||||||
|
|
||||||
|
use irtt_server::{Server, ServerConfig};
|
||||||
|
use tokio::sync::oneshot;
|
||||||
|
|
||||||
|
const STARTUP_TIMEOUT: Duration = Duration::from_secs(2);
|
||||||
|
|
||||||
|
pub struct InTreeServer {
|
||||||
|
pub addr: SocketAddr,
|
||||||
|
shutdown: Option<oneshot::Sender<()>>,
|
||||||
|
done: Option<JoinHandle<Result<(), String>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl InTreeServer {
|
||||||
|
pub fn start(config: ServerConfig) -> Self {
|
||||||
|
let (startup_tx, startup_rx) = mpsc::sync_channel(1);
|
||||||
|
let (shutdown_tx, shutdown_rx) = oneshot::channel();
|
||||||
|
let done = thread::spawn(move || {
|
||||||
|
let runtime = tokio::runtime::Builder::new_current_thread()
|
||||||
|
.enable_all()
|
||||||
|
.build()
|
||||||
|
.map_err(|error| format!("failed to build test server runtime: {error}"))?;
|
||||||
|
runtime.block_on(async move {
|
||||||
|
let bind_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0);
|
||||||
|
let mut server = match Server::bind(bind_addr, config).await {
|
||||||
|
Ok(server) => server,
|
||||||
|
Err(error) => {
|
||||||
|
let message = format!("failed to bind in-tree test server: {error}");
|
||||||
|
let _ = startup_tx.send(Err(message.clone()));
|
||||||
|
return Err(message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
let addr = match server.local_addr() {
|
||||||
|
Ok(addr) => addr,
|
||||||
|
Err(error) => {
|
||||||
|
let message =
|
||||||
|
format!("failed to read in-tree test server address: {error}");
|
||||||
|
let _ = startup_tx.send(Err(message.clone()));
|
||||||
|
return Err(message);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
startup_tx
|
||||||
|
.send(Ok(addr))
|
||||||
|
.map_err(|_| "test stopped waiting for in-tree server startup".to_owned())?;
|
||||||
|
server
|
||||||
|
.run(async {
|
||||||
|
let _ = shutdown_rx.await;
|
||||||
|
})
|
||||||
|
.await
|
||||||
|
.map_err(|error| format!("in-tree test server failed: {error}"))
|
||||||
|
})
|
||||||
|
});
|
||||||
|
|
||||||
|
let addr = match startup_rx.recv_timeout(STARTUP_TIMEOUT) {
|
||||||
|
Ok(Ok(addr)) => addr,
|
||||||
|
Ok(Err(error)) => {
|
||||||
|
done.join()
|
||||||
|
.expect("in-tree test server thread panicked")
|
||||||
|
.ok();
|
||||||
|
panic!("{error}");
|
||||||
|
}
|
||||||
|
Err(error) => {
|
||||||
|
let _ = shutdown_tx.send(());
|
||||||
|
done.join()
|
||||||
|
.expect("in-tree test server thread panicked")
|
||||||
|
.ok();
|
||||||
|
panic!("timed out waiting for in-tree test server startup: {error}");
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
Self {
|
||||||
|
addr,
|
||||||
|
shutdown: Some(shutdown_tx),
|
||||||
|
done: Some(done),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn stop_inner(&mut self) {
|
||||||
|
if let Some(shutdown) = self.shutdown.take() {
|
||||||
|
let _ = shutdown.send(());
|
||||||
|
}
|
||||||
|
if let Some(done) = self.done.take() {
|
||||||
|
done.join()
|
||||||
|
.expect("in-tree test server thread panicked")
|
||||||
|
.expect("in-tree test server stopped with an error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Drop for InTreeServer {
|
||||||
|
fn drop(&mut self) {
|
||||||
|
self.stop_inner();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,6 @@
|
|||||||
#![allow(dead_code)]
|
#![allow(dead_code)]
|
||||||
|
|
||||||
|
mod in_tree_server;
|
||||||
mod real_irtt;
|
mod real_irtt;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
@@ -17,7 +18,9 @@ use irtt_proto::{
|
|||||||
PacketLayout, Params, ProtoError, ReceivedStats, ServerFill, StampAt, TimestampFields,
|
PacketLayout, Params, ProtoError, ReceivedStats, ServerFill, StampAt, TimestampFields,
|
||||||
HMAC_SIZE, MAGIC, PROTOCOL_VERSION,
|
HMAC_SIZE, MAGIC, PROTOCOL_VERSION,
|
||||||
};
|
};
|
||||||
|
use irtt_server::ServerConfig;
|
||||||
|
|
||||||
|
pub use in_tree_server::InTreeServer;
|
||||||
pub use real_irtt::RealIrtServer;
|
pub use real_irtt::RealIrtServer;
|
||||||
|
|
||||||
const HMAC_OFFSET: usize = 4;
|
const HMAC_OFFSET: usize = 4;
|
||||||
@@ -27,7 +30,7 @@ pub const RECV_WINDOW: u64 = 0x07;
|
|||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
pub enum TestBackendKind {
|
pub enum TestBackendKind {
|
||||||
Fake,
|
InTree,
|
||||||
Real,
|
Real,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -43,9 +46,9 @@ pub fn selected_backend() -> TestBackendKind {
|
|||||||
_ => panic!("IRTT_TEST_BACKEND=real but irtt binary not found at '{irtt_bin}'"),
|
_ => panic!("IRTT_TEST_BACKEND=real but irtt binary not found at '{irtt_bin}'"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok("fake") | Err(_) => {
|
Ok("in-tree") | Err(_) => {
|
||||||
debug_backend("[backend] selected backend=fake");
|
debug_backend("[backend] selected backend=in-tree");
|
||||||
TestBackendKind::Fake
|
TestBackendKind::InTree
|
||||||
}
|
}
|
||||||
Ok(other) => panic!("unknown IRTT_TEST_BACKEND value: {other}"),
|
Ok(other) => panic!("unknown IRTT_TEST_BACKEND value: {other}"),
|
||||||
}
|
}
|
||||||
@@ -58,24 +61,25 @@ fn debug_backend(message: &str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub enum BackendPeer {
|
pub enum BackendPeer {
|
||||||
Fake(FakeServer),
|
InTree(InTreeServer),
|
||||||
Real(RealIrtServer),
|
Real(RealIrtServer),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl BackendPeer {
|
impl BackendPeer {
|
||||||
pub fn addr(&self) -> SocketAddr {
|
pub fn addr(&self) -> SocketAddr {
|
||||||
match self {
|
match self {
|
||||||
BackendPeer::Fake(s) => s.addr,
|
BackendPeer::InTree(s) => s.addr,
|
||||||
BackendPeer::Real(s) => s.addr(),
|
BackendPeer::Real(s) => s.addr(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn start_open_echo(params: Params, hmac_key: Option<Vec<u8>>) -> Self {
|
pub fn start_open_echo(hmac_key: Option<Vec<u8>>) -> Self {
|
||||||
match selected_backend() {
|
match selected_backend() {
|
||||||
TestBackendKind::Fake => {
|
TestBackendKind::InTree => BackendPeer::InTree(InTreeServer::start(
|
||||||
let timestamps = standard_timestamps();
|
hmac_key.map_or_else(ServerConfig::default, |key| {
|
||||||
BackendPeer::Fake(start_one_probe_server(params, timestamps, hmac_key))
|
ServerConfig::default().with_hmac_key(key)
|
||||||
}
|
}),
|
||||||
|
)),
|
||||||
TestBackendKind::Real => {
|
TestBackendKind::Real => {
|
||||||
BackendPeer::Real(RealIrtServer::start(hmac_key.as_deref()).unwrap())
|
BackendPeer::Real(RealIrtServer::start(hmac_key.as_deref()).unwrap())
|
||||||
}
|
}
|
||||||
@@ -84,9 +88,8 @@ impl BackendPeer {
|
|||||||
|
|
||||||
pub fn start_hmac_required(key: Vec<u8>) -> Self {
|
pub fn start_hmac_required(key: Vec<u8>) -> Self {
|
||||||
match selected_backend() {
|
match selected_backend() {
|
||||||
TestBackendKind::Fake => BackendPeer::Fake(start_hmac_required_open_drop_server(
|
TestBackendKind::InTree => BackendPeer::InTree(InTreeServer::start(
|
||||||
key,
|
ServerConfig::default().with_hmac_key(key),
|
||||||
Duration::from_millis(250),
|
|
||||||
)),
|
)),
|
||||||
TestBackendKind::Real => BackendPeer::Real(RealIrtServer::start(Some(&key)).unwrap()),
|
TestBackendKind::Real => BackendPeer::Real(RealIrtServer::start(Some(&key)).unwrap()),
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in new issue
Block a user