fix(tests): break the irtt-client/irtt-server dev-dependency cycle
irtt-client and irtt-server mutually dev-depended on each other for cross-crate integration tests. That cycle blocks `cargo publish` for either crate whenever the other doesn't already exist on the registry at the required version, which is exactly the situation for a crate's first-ever release (irtt-server has never been published before). Introduce a new `irtt-integration-tests` crate (publish = false, no library target) to own tests whose actual subject is the interaction between two or more irtt-* production crates: crate-local behavior -> crate's own tests/ cross-crate/system behavior -> irtt-integration-tests Move every test that imports both irtt_client and irtt_server there: the client-side support harness (hmac, large_packets, protocol_options, fill_negotiation) and the server-side real-socket tests that drive a real AsyncClient against a real Server (async_client, negotiation_policy, fill_wire_bytes, traffic_class, wildcard_source). server_set.rs stays in irtt-server/tests since it only uses irtt_proto as test machinery to drive irtt-server directly, which is a normal one-directional test dependency, not a peer relationship. irtt-server's dev-dependency on irtt-client is dropped entirely now that nothing under crates/irtt-server/tests needs it, which fully breaks the cycle from that side. irtt-client keeps a one-directional dev-dependency on irtt-server: a handful of white-box unit tests in src/async_client/tests.rs assert on private AsyncClient internals (socket, remote, test_hooks) while also needing a real in-tree server for blocking/async equivalence checks, so they can't move to an external crate without losing that access. Their InTreeServer helper is duplicated locally rather than shared, matching the existing precedent of irtt-cli's own tests/support/in_tree_server.rs.
This commit is contained in:
19 files changed
+106
-5
No files matched your search
@@ -0,0 +1,140 @@
|
||||
use irtt_client::{Client, ClientEvent};
|
||||
use irtt_proto::{Clock, ReceivedStats, StampAt};
|
||||
|
||||
use crate::support::{config_for_params, default_params, params_for_modes, BackendPeer};
|
||||
|
||||
#[test]
|
||||
fn backend_basic_open_echo_close() {
|
||||
let params = default_params();
|
||||
let peer = BackendPeer::start_open_echo(None);
|
||||
let mut client = Client::connect(config_for_params(peer.addr(), ¶ms)).unwrap();
|
||||
|
||||
let outcome = client.open().unwrap();
|
||||
assert!(matches!(outcome, irtt_client::OpenOutcome::Started { .. }));
|
||||
|
||||
let sent = client.send_probe().unwrap();
|
||||
assert_eq!(sent.len(), 1);
|
||||
|
||||
let events = client.recv_once().unwrap();
|
||||
assert_eq!(events.len(), 1);
|
||||
assert!(matches!(events[0], ClientEvent::EchoReply { .. }));
|
||||
|
||||
client.close().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn backend_received_stats_smoke() {
|
||||
for mode in [
|
||||
ReceivedStats::None,
|
||||
ReceivedStats::Count,
|
||||
ReceivedStats::Window,
|
||||
ReceivedStats::Both,
|
||||
] {
|
||||
let params = params_for_modes(mode, StampAt::None, Clock::Both);
|
||||
let peer = BackendPeer::start_open_echo(None);
|
||||
let mut client = Client::connect(config_for_params(peer.addr(), ¶ms)).unwrap();
|
||||
|
||||
client.open().unwrap();
|
||||
client.send_probe().unwrap();
|
||||
let events = client.recv_once().unwrap();
|
||||
assert_eq!(events.len(), 1);
|
||||
assert!(matches!(events[0], ClientEvent::EchoReply { .. }));
|
||||
|
||||
client.close().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn backend_timestamp_smoke() {
|
||||
for mode in [
|
||||
StampAt::None,
|
||||
StampAt::Send,
|
||||
StampAt::Receive,
|
||||
StampAt::Both,
|
||||
StampAt::Midpoint,
|
||||
] {
|
||||
let params = params_for_modes(ReceivedStats::None, mode, Clock::Both);
|
||||
let peer = BackendPeer::start_open_echo(None);
|
||||
let mut client = Client::connect(config_for_params(peer.addr(), ¶ms)).unwrap();
|
||||
|
||||
client.open().unwrap();
|
||||
client.send_probe().unwrap();
|
||||
let events = client.recv_once().unwrap();
|
||||
assert_eq!(events.len(), 1);
|
||||
|
||||
match &events[0] {
|
||||
ClientEvent::EchoReply {
|
||||
server_timing,
|
||||
one_way,
|
||||
..
|
||||
} => match mode {
|
||||
StampAt::None => {
|
||||
assert!(server_timing.is_none());
|
||||
assert!(one_way.is_none());
|
||||
}
|
||||
StampAt::Send => {
|
||||
let st = server_timing.as_ref().unwrap();
|
||||
assert!(st.send_wall_ns.is_some() || st.send_mono_ns.is_some());
|
||||
}
|
||||
StampAt::Receive => {
|
||||
let st = server_timing.as_ref().unwrap();
|
||||
assert!(st.receive_wall_ns.is_some() || st.receive_mono_ns.is_some());
|
||||
}
|
||||
StampAt::Both => {
|
||||
let st = server_timing.as_ref().unwrap();
|
||||
assert!(st.receive_wall_ns.is_some() || st.receive_mono_ns.is_some());
|
||||
assert!(st.send_wall_ns.is_some() || st.send_mono_ns.is_some());
|
||||
}
|
||||
StampAt::Midpoint => {
|
||||
let st = server_timing.as_ref().unwrap();
|
||||
assert!(st.midpoint_wall_ns.is_some() || st.midpoint_mono_ns.is_some());
|
||||
}
|
||||
},
|
||||
other => panic!("expected EchoReply, got {other:?}"),
|
||||
}
|
||||
|
||||
client.close().unwrap();
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn backend_clock_smoke() {
|
||||
for clock in [Clock::Wall, Clock::Monotonic, Clock::Both] {
|
||||
let params = params_for_modes(ReceivedStats::None, StampAt::Both, clock);
|
||||
let peer = BackendPeer::start_open_echo(None);
|
||||
let mut client = Client::connect(config_for_params(peer.addr(), ¶ms)).unwrap();
|
||||
|
||||
client.open().unwrap();
|
||||
client.send_probe().unwrap();
|
||||
let events = client.recv_once().unwrap();
|
||||
assert_eq!(events.len(), 1);
|
||||
|
||||
match &events[0] {
|
||||
ClientEvent::EchoReply { server_timing, .. } => {
|
||||
let st = server_timing.as_ref().unwrap();
|
||||
match clock {
|
||||
Clock::Wall => {
|
||||
assert!(st.receive_wall_ns.is_some());
|
||||
assert!(st.send_wall_ns.is_some());
|
||||
}
|
||||
Clock::Monotonic => {
|
||||
assert!(st.receive_mono_ns.is_some());
|
||||
assert!(st.send_mono_ns.is_some());
|
||||
}
|
||||
Clock::Both => {
|
||||
assert!(st.receive_wall_ns.is_some());
|
||||
assert!(st.receive_mono_ns.is_some());
|
||||
assert!(st.send_wall_ns.is_some());
|
||||
assert!(st.send_mono_ns.is_some());
|
||||
}
|
||||
Clock::Unspecified => {
|
||||
unreachable!("clients never request an unspecified clock")
|
||||
}
|
||||
}
|
||||
}
|
||||
other => panic!("expected EchoReply, got {other:?}"),
|
||||
}
|
||||
|
||||
client.close().unwrap();
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user