test(client): use real server for compliant peers
This commit is contained in:
9 files changed
+172
-50
No files matched your search
@@ -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)]
|
||||
|
||||
mod in_tree_server;
|
||||
mod real_irtt;
|
||||
|
||||
use std::{
|
||||
@@ -17,7 +18,9 @@ use irtt_proto::{
|
||||
PacketLayout, Params, ProtoError, ReceivedStats, ServerFill, StampAt, TimestampFields,
|
||||
HMAC_SIZE, MAGIC, PROTOCOL_VERSION,
|
||||
};
|
||||
use irtt_server::ServerConfig;
|
||||
|
||||
pub use in_tree_server::InTreeServer;
|
||||
pub use real_irtt::RealIrtServer;
|
||||
|
||||
const HMAC_OFFSET: usize = 4;
|
||||
@@ -27,7 +30,7 @@ pub const RECV_WINDOW: u64 = 0x07;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub enum TestBackendKind {
|
||||
Fake,
|
||||
InTree,
|
||||
Real,
|
||||
}
|
||||
|
||||
@@ -43,9 +46,9 @@ pub fn selected_backend() -> TestBackendKind {
|
||||
_ => panic!("IRTT_TEST_BACKEND=real but irtt binary not found at '{irtt_bin}'"),
|
||||
}
|
||||
}
|
||||
Ok("fake") | Err(_) => {
|
||||
debug_backend("[backend] selected backend=fake");
|
||||
TestBackendKind::Fake
|
||||
Ok("in-tree") | Err(_) => {
|
||||
debug_backend("[backend] selected backend=in-tree");
|
||||
TestBackendKind::InTree
|
||||
}
|
||||
Ok(other) => panic!("unknown IRTT_TEST_BACKEND value: {other}"),
|
||||
}
|
||||
@@ -58,24 +61,25 @@ fn debug_backend(message: &str) {
|
||||
}
|
||||
|
||||
pub enum BackendPeer {
|
||||
Fake(FakeServer),
|
||||
InTree(InTreeServer),
|
||||
Real(RealIrtServer),
|
||||
}
|
||||
|
||||
impl BackendPeer {
|
||||
pub fn addr(&self) -> SocketAddr {
|
||||
match self {
|
||||
BackendPeer::Fake(s) => s.addr,
|
||||
BackendPeer::InTree(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() {
|
||||
TestBackendKind::Fake => {
|
||||
let timestamps = standard_timestamps();
|
||||
BackendPeer::Fake(start_one_probe_server(params, timestamps, hmac_key))
|
||||
}
|
||||
TestBackendKind::InTree => BackendPeer::InTree(InTreeServer::start(
|
||||
hmac_key.map_or_else(ServerConfig::default, |key| {
|
||||
ServerConfig::default().with_hmac_key(key)
|
||||
}),
|
||||
)),
|
||||
TestBackendKind::Real => {
|
||||
BackendPeer::Real(RealIrtServer::start(hmac_key.as_deref()).unwrap())
|
||||
}
|
||||
@@ -84,9 +88,8 @@ impl BackendPeer {
|
||||
|
||||
pub fn start_hmac_required(key: Vec<u8>) -> Self {
|
||||
match selected_backend() {
|
||||
TestBackendKind::Fake => BackendPeer::Fake(start_hmac_required_open_drop_server(
|
||||
key,
|
||||
Duration::from_millis(250),
|
||||
TestBackendKind::InTree => BackendPeer::InTree(InTreeServer::start(
|
||||
ServerConfig::default().with_hmac_key(key),
|
||||
)),
|
||||
TestBackendKind::Real => BackendPeer::Real(RealIrtServer::start(Some(&key)).unwrap()),
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user