test(client): add integration tests for packet length and server fill
Verify that the client correctly handles custom packet lengths and server fill negotiation to ensure protocol compliance and support for larger MTUs. Add validation to reject empty server fill strings during configuration.
This commit is contained in:
1 parent
a4e2f3aef4
commit
ab95489f20
6 files changed
+384
-2
No files matched your search
@@ -0,0 +1,140 @@
|
||||
mod support;
|
||||
|
||||
use irtt_client::{Client, ClientConfig, ClientEvent, ClientTimestamp, NegotiationPolicy};
|
||||
use irtt_proto::{echo_header_len, echo_packet_len, Params, TimestampFields};
|
||||
|
||||
use support::{config_for_params, default_params, run_one_probe, BackendPeer, ServerObservation};
|
||||
|
||||
fn params_with_length(length: i64) -> Params {
|
||||
Params {
|
||||
length,
|
||||
..default_params()
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_echo_size(run: &support::OneProbeRun, expected: usize) {
|
||||
match run.observations[1] {
|
||||
ServerObservation::Echo { len, .. } => assert_eq!(len, expected),
|
||||
ref other => panic!("expected Echo observation, got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_reply(event: &ClientEvent) {
|
||||
assert!(matches!(event, ClientEvent::EchoReply { .. }));
|
||||
}
|
||||
|
||||
fn assert_sent_bytes(event: &ClientEvent, expected: usize) {
|
||||
match event {
|
||||
ClientEvent::EchoSent { bytes, .. } => assert_eq!(*bytes, expected),
|
||||
other => panic!("expected EchoSent, got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn assert_reply_bytes(event: &ClientEvent, expected: usize) {
|
||||
match event {
|
||||
ClientEvent::EchoReply { bytes, .. } => assert_eq!(*bytes, expected),
|
||||
other => panic!("expected EchoReply, got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Config/client validation ───
|
||||
|
||||
#[test]
|
||||
fn length_zero_baseline() {
|
||||
let params = params_with_length(0);
|
||||
let expected = echo_packet_len(false, ¶ms);
|
||||
let header = echo_header_len(false, ¶ms);
|
||||
assert_eq!(expected, header);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn length_one_accepted() {
|
||||
let params = params_with_length(1);
|
||||
let expected = echo_packet_len(false, ¶ms);
|
||||
assert!(expected >= 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn length_1472_accepted() {
|
||||
let params = params_with_length(1472);
|
||||
let expected = echo_packet_len(false, ¶ms);
|
||||
assert_eq!(expected, 1472);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn length_4096_accepted() {
|
||||
let params = params_with_length(4096);
|
||||
let expected = echo_packet_len(false, ¶ms);
|
||||
assert_eq!(expected, 4096);
|
||||
}
|
||||
|
||||
// ─── Echo request size: FakeServer observes exact packet size ───
|
||||
|
||||
#[test]
|
||||
fn echo_request_size_matches_echo_packet_len_for_zero_length() {
|
||||
let params = params_with_length(0);
|
||||
let run = run_one_probe(params.clone(), TimestampFields::default());
|
||||
let expected = echo_packet_len(false, ¶ms);
|
||||
assert_echo_size(&run, expected);
|
||||
assert_sent_bytes(&run.sent, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn echo_request_size_matches_echo_packet_len_above_header() {
|
||||
for length in [16, 60, 128, 1472, 4096] {
|
||||
let params = params_with_length(length);
|
||||
let run = run_one_probe(params.clone(), TimestampFields::default());
|
||||
let expected = echo_packet_len(false, ¶ms);
|
||||
assert_eq!(
|
||||
expected,
|
||||
echo_header_len(false, ¶ms).max(length as usize)
|
||||
);
|
||||
assert_echo_size(&run, expected);
|
||||
assert_sent_bytes(&run.sent, expected);
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Echo reply handling ───
|
||||
|
||||
#[test]
|
||||
fn echo_reply_decoded_for_large_length() {
|
||||
let params = params_with_length(4096);
|
||||
let run = run_one_probe(params.clone(), TimestampFields::default());
|
||||
let expected = echo_packet_len(false, ¶ms);
|
||||
assert_reply(&run.reply);
|
||||
assert_reply_bytes(&run.reply, expected);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn echo_reply_bytes_consistent_with_echo_packet_len_for_various_lengths() {
|
||||
for length in [0, 1472, 4096] {
|
||||
let params = params_with_length(length);
|
||||
let run = run_one_probe(params.clone(), TimestampFields::default());
|
||||
let expected = echo_packet_len(false, ¶ms);
|
||||
assert_reply_bytes(&run.reply, expected);
|
||||
}
|
||||
}
|
||||
|
||||
// ─── Backend-neutral smoke ───
|
||||
|
||||
#[test]
|
||||
fn backend_large_packet_smoke() {
|
||||
let params = params_with_length(1472);
|
||||
let peer = BackendPeer::start_open_echo(params.clone(), None);
|
||||
let mut client = Client::connect(ClientConfig {
|
||||
negotiation_policy: NegotiationPolicy::Loose,
|
||||
length: 1472,
|
||||
..config_for_params(peer.addr(), ¶ms)
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
let outcome = client.open(ClientTimestamp::now()).unwrap();
|
||||
assert!(matches!(outcome, irtt_client::OpenOutcome::Started { .. }));
|
||||
|
||||
client.send_probe().unwrap();
|
||||
let events = client.recv_once().unwrap();
|
||||
assert_eq!(events.len(), 1);
|
||||
assert!(matches!(events[0], ClientEvent::EchoReply { .. }));
|
||||
|
||||
client.close(ClientTimestamp::now()).unwrap();
|
||||
}
|
||||
Reference in new issue
Block a user