Merge pull request #115 from Lochnair/fix/break-client-server-dev-dep-cycle

fix(tests): break the irtt-client/irtt-server dev-dependency cycle
This commit is contained in:
Nils Andreas Svee authored and GitHub committed 2026-08-17 09:53:49 +07:00
commit 1461dab73b
19 files changed
+107 -5

No files matched your search

Generated
+10 -1
View File
@@ -719,6 +719,16 @@ dependencies = [
"tokio",
]
[[package]]
name = "irtt-integration-tests"
version = "0.0.0"
dependencies = [
"irtt-client",
"irtt-proto",
"irtt-server",
"tokio",
]
[[package]]
name = "irtt-proto"
version = "0.5.0"
@@ -734,7 +744,6 @@ name = "irtt-server"
version = "0.5.0"
dependencies = [
"getrandom 0.4.3",
"irtt-client",
"irtt-proto",
"nix 0.31.3",
"socket2",
+1
View File
@@ -5,6 +5,7 @@ members = [
"crates/irtt-server",
"crates/irtt-stats",
"crates/irtt-cli",
"crates/irtt-integration-tests",
]
resolver = "2"
@@ -0,0 +1,82 @@
//! A real `irtt-server` running in-process, for tests that need to prove
//! `AsyncClient` and the blocking `Client` are equivalent against a real peer.
//!
//! This duplicates `crates/irtt-integration-tests/tests/support/in_tree_server.rs`
//! rather than depending on it: this module backs private (`super::*`) unit
//! tests here, while the integration crate covers black-box client/server
//! behavior, and neither can depend on the other's test-only code.
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<(), irtt_server::ServerRuntimeError>>>,
}
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()
.expect("failed to build in-tree test server runtime");
runtime.block_on(async move {
let bind_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::LOCALHOST), 0);
let mut server = Server::bind(bind_addr, config).await?;
startup_tx
.send(server.local_addr()?)
.expect("test stopped waiting for in-tree server startup");
server
.run(async {
let _ = shutdown_rx.await;
})
.await
})
});
let addr = match startup_rx.recv_timeout(STARTUP_TIMEOUT) {
Ok(addr) => addr,
Err(error) => {
let _ = shutdown_tx.send(());
let result = done.join().expect("in-tree test server thread panicked");
panic!("in-tree test server failed before startup ({error}): {result:?}");
}
};
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 -1
View File
@@ -14,7 +14,7 @@ use irtt_proto::{
};
use tokio::runtime::{Builder, Runtime};
#[path = "../../tests/support/in_tree_server.rs"]
#[path = "in_tree_server_support.rs"]
mod in_tree_server;
use super::*;
+13
View File
@@ -0,0 +1,13 @@
[package]
name = "irtt-integration-tests"
version = "0.0.0"
edition.workspace = true
license.workspace = true
rust-version.workspace = true
publish = false
[dependencies]
irtt-client = { workspace = true, features = ["ancillary", "tokio"] }
irtt-server.workspace = true
irtt-proto.workspace = true
tokio = { version = "1.53.1", default-features = false, features = ["rt", "net", "time", "sync", "macros"] }
File renamed without changes.
-3
View File
@@ -23,6 +23,3 @@ tokio = { version = "1.53.1", default-features = false, features = ["rt", "net",
# source-selection path here; elsewhere a wildcard bind is refused.
[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))'.dependencies]
nix = { version = "0.31.3", default-features = false, features = ["net", "uio"] }
[dev-dependencies]
irtt-client = { workspace = true, features = ["ancillary", "tokio"] }