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:
19 files changed
+107
-5
No files matched your search
Generated
+10
-1
@@ -719,6 +719,16 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "irtt-integration-tests"
|
||||||
|
version = "0.0.0"
|
||||||
|
dependencies = [
|
||||||
|
"irtt-client",
|
||||||
|
"irtt-proto",
|
||||||
|
"irtt-server",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "irtt-proto"
|
name = "irtt-proto"
|
||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
@@ -734,7 +744,6 @@ name = "irtt-server"
|
|||||||
version = "0.5.0"
|
version = "0.5.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom 0.4.3",
|
"getrandom 0.4.3",
|
||||||
"irtt-client",
|
|
||||||
"irtt-proto",
|
"irtt-proto",
|
||||||
"nix 0.31.3",
|
"nix 0.31.3",
|
||||||
"socket2",
|
"socket2",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ members = [
|
|||||||
"crates/irtt-server",
|
"crates/irtt-server",
|
||||||
"crates/irtt-stats",
|
"crates/irtt-stats",
|
||||||
"crates/irtt-cli",
|
"crates/irtt-cli",
|
||||||
|
"crates/irtt-integration-tests",
|
||||||
]
|
]
|
||||||
resolver = "2"
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ use irtt_proto::{
|
|||||||
};
|
};
|
||||||
use tokio::runtime::{Builder, Runtime};
|
use tokio::runtime::{Builder, Runtime};
|
||||||
|
|
||||||
#[path = "../../tests/support/in_tree_server.rs"]
|
#[path = "in_tree_server_support.rs"]
|
||||||
mod in_tree_server;
|
mod in_tree_server;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -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.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
@@ -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.
|
# source-selection path here; elsewhere a wildcard bind is refused.
|
||||||
[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))'.dependencies]
|
[target.'cfg(any(target_os = "linux", target_os = "macos", target_os = "freebsd"))'.dependencies]
|
||||||
nix = { version = "0.31.3", default-features = false, features = ["net", "uio"] }
|
nix = { version = "0.31.3", default-features = false, features = ["net", "uio"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
irtt-client = { workspace = true, features = ["ancillary", "tokio"] }
|
|
||||||
Reference in new issue
Block a user