test: consolidate and prune implementation-coupled tests
This commit is contained in:
1 parent
a7288cc612
commit
ddd420cc21
4 files changed
+30
-219
No files matched your search
@@ -1217,17 +1217,6 @@ mod tests {
|
|||||||
assert_machine_packet_meta(&line, "0", "0", "0", "none");
|
assert_machine_packet_meta(&line, "0", "0", "0", "none");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn machine_echo_reply_metadata_dscp_46_ecn_0_prints_values() {
|
|
||||||
let line = format_event(
|
|
||||||
&reply_event_with_meta(packet_meta(184, 46, 0)),
|
|
||||||
OutputMode::Machine,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert_machine_packet_meta(&line, "184", "46", "0", "none");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn machine_echo_reply_metadata_dscp_46_ecn_2_prints_values() {
|
fn machine_echo_reply_metadata_dscp_46_ecn_2_prints_values() {
|
||||||
let line = format_event(
|
let line = format_event(
|
||||||
@@ -1252,18 +1241,6 @@ mod tests {
|
|||||||
assert_machine_packet_meta(&line, "none", "none", "none", "1000000234");
|
assert_machine_packet_meta(&line, "none", "none", "none", "1000000234");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn machine_late_reply_metadata_unavailable_prints_none() {
|
|
||||||
let line = format_event(
|
|
||||||
&late_event_with_meta(PacketMeta::default()),
|
|
||||||
OutputMode::Machine,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert!(line.starts_with("event=late "));
|
|
||||||
assert_machine_packet_meta(&line, "none", "none", "none", "none");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn machine_late_reply_metadata_observed_values_prints_values() {
|
fn machine_late_reply_metadata_observed_values_prints_values() {
|
||||||
let line = format_event(
|
let line = format_event(
|
||||||
@@ -1276,20 +1253,6 @@ mod tests {
|
|||||||
assert_machine_packet_meta(&line, "186", "46", "2", "none");
|
assert_machine_packet_meta(&line, "186", "46", "2", "none");
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn machine_late_reply_metadata_kernel_rx_timestamp_prints_ns() {
|
|
||||||
let line = format_event(
|
|
||||||
&late_event_with_meta(packet_meta_with_timestamp(Some(
|
|
||||||
UNIX_EPOCH + Duration::new(2, 345),
|
|
||||||
))),
|
|
||||||
OutputMode::Machine,
|
|
||||||
)
|
|
||||||
.unwrap();
|
|
||||||
|
|
||||||
assert!(line.starts_with("event=late "));
|
|
||||||
assert_machine_packet_meta(&line, "none", "none", "none", "2000000345");
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn simple_prints_readable_reply_line() {
|
fn simple_prints_readable_reply_line() {
|
||||||
let line = format_event(&reply_event(), OutputMode::Simple).unwrap();
|
let line = format_event(&reply_event(), OutputMode::Simple).unwrap();
|
||||||
|
|||||||
@@ -122,34 +122,13 @@ fn hmac_close_success_sends_authenticated_close_and_closes_session() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn missing_client_key_against_hmac_required_server_times_out() {
|
fn hmac_required_server_rejects_missing_or_wrong_client_key() {
|
||||||
let key = b"compat-secret".to_vec();
|
for (hmac_key, expected_hmac_flag) in [(None, false), (Some(b"wrong-secret".to_vec()), true)] {
|
||||||
let server = start_hmac_required_open_drop_server(key, Duration::from_millis(250));
|
|
||||||
let mut config = config_for_params(server.addr, &default_params());
|
|
||||||
config.open_timeouts = vec![Duration::from_millis(200)];
|
|
||||||
config.hmac_key = None;
|
|
||||||
|
|
||||||
let mut client = Client::connect(config).unwrap();
|
|
||||||
assert!(matches!(client.open(), Err(ClientError::OpenTimeout)));
|
|
||||||
|
|
||||||
let observations = server.observations(1);
|
|
||||||
assert!(matches!(
|
|
||||||
observations.as_slice(),
|
|
||||||
[ServerObservation::RejectedHmac {
|
|
||||||
hmac: false,
|
|
||||||
bad_hmac: true
|
|
||||||
}]
|
|
||||||
));
|
|
||||||
server.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn wrong_client_key_against_hmac_required_server_times_out() {
|
|
||||||
let server_key = b"compat-secret".to_vec();
|
let server_key = b"compat-secret".to_vec();
|
||||||
let server = start_hmac_required_open_drop_server(server_key, Duration::from_millis(250));
|
let server = start_hmac_required_open_drop_server(server_key, Duration::from_millis(250));
|
||||||
let mut config = config_for_params(server.addr, &default_params());
|
let mut config = config_for_params(server.addr, &default_params());
|
||||||
config.open_timeouts = vec![Duration::from_millis(200)];
|
config.open_timeouts = vec![Duration::from_millis(200)];
|
||||||
config.hmac_key = Some(b"wrong-secret".to_vec());
|
config.hmac_key = hmac_key;
|
||||||
|
|
||||||
let mut client = Client::connect(config).unwrap();
|
let mut client = Client::connect(config).unwrap();
|
||||||
assert!(matches!(client.open(), Err(ClientError::OpenTimeout)));
|
assert!(matches!(client.open(), Err(ClientError::OpenTimeout)));
|
||||||
@@ -158,11 +137,12 @@ fn wrong_client_key_against_hmac_required_server_times_out() {
|
|||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
observations.as_slice(),
|
observations.as_slice(),
|
||||||
[ServerObservation::RejectedHmac {
|
[ServerObservation::RejectedHmac {
|
||||||
hmac: true,
|
hmac,
|
||||||
bad_hmac: true
|
bad_hmac: true
|
||||||
}]
|
}] if *hmac == expected_hmac_flag
|
||||||
));
|
));
|
||||||
server.join();
|
server.join();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -311,25 +291,15 @@ fn backend_hmac_correct_key_succeeds() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn backend_hmac_wrong_key_fails() {
|
fn backend_hmac_required_rejects_missing_or_wrong_client_key() {
|
||||||
|
for hmac_key in [None, Some(b"wrong-secret".to_vec())] {
|
||||||
let server_key = b"compat-secret".to_vec();
|
let server_key = b"compat-secret".to_vec();
|
||||||
let peer = BackendPeer::start_hmac_required(server_key);
|
let peer = BackendPeer::start_hmac_required(server_key);
|
||||||
let mut config = config_for_params(peer.addr(), &default_params());
|
let mut config = config_for_params(peer.addr(), &default_params());
|
||||||
config.open_timeouts = vec![Duration::from_millis(200)];
|
config.open_timeouts = vec![Duration::from_millis(200)];
|
||||||
config.hmac_key = Some(b"wrong-secret".to_vec());
|
config.hmac_key = hmac_key;
|
||||||
|
|
||||||
let mut client = Client::connect(config).unwrap();
|
|
||||||
assert!(matches!(client.open(), Err(ClientError::OpenTimeout)));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn backend_hmac_missing_key_fails() {
|
|
||||||
let server_key = b"compat-secret".to_vec();
|
|
||||||
let peer = BackendPeer::start_hmac_required(server_key);
|
|
||||||
let mut config = config_for_params(peer.addr(), &default_params());
|
|
||||||
config.open_timeouts = vec![Duration::from_millis(200)];
|
|
||||||
config.hmac_key = None;
|
|
||||||
|
|
||||||
let mut client = Client::connect(config).unwrap();
|
let mut client = Client::connect(config).unwrap();
|
||||||
assert!(matches!(client.open(), Err(ClientError::OpenTimeout)));
|
assert!(matches!(client.open(), Err(ClientError::OpenTimeout)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
mod support;
|
mod support;
|
||||||
|
|
||||||
use irtt_client::{Client, ClientConfig, ClientError, ClientEvent, NegotiationPolicy};
|
use irtt_client::{Client, ClientConfig, ClientError, NegotiationPolicy};
|
||||||
use irtt_proto::{Params, TimestampFields};
|
use irtt_proto::{Params, TimestampFields};
|
||||||
|
|
||||||
use support::{
|
use support::{
|
||||||
@@ -32,63 +32,34 @@ fn echo_observation(run: &OneProbeRun) -> (usize, bool, u64, u32) {
|
|||||||
// ─── Config mapping ───
|
// ─── Config mapping ───
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn server_fill_none_produces_no_fill_in_open_params() {
|
fn server_fill_none_short_and_max_map_into_open_params() {
|
||||||
let params = default_params();
|
for fill in [None, Some("abc"), Some("0123456789abcdef0123456789abcdef")] {
|
||||||
let run = run_one_probe(params, TimestampFields::default());
|
|
||||||
assert!(open_observation_params(&run).server_fill.is_none());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn server_fill_short_value_maps_into_open_params() {
|
|
||||||
let mut params = default_params();
|
let mut params = default_params();
|
||||||
params.server_fill = server_fill("abc");
|
params.server_fill = fill.and_then(server_fill);
|
||||||
|
|
||||||
let run = run_one_probe(params, TimestampFields::default());
|
let run = run_one_probe(params, TimestampFields::default());
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
open_observation_params(&run)
|
open_observation_params(&run)
|
||||||
.server_fill
|
.server_fill
|
||||||
.as_ref()
|
.as_ref()
|
||||||
.map(|f| f.value.as_str()),
|
.map(|f| f.value.as_str()),
|
||||||
Some("abc")
|
fill
|
||||||
);
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn server_fill_32_byte_value_maps_into_open_params() {
|
fn server_fill_empty_and_oversized_values_are_rejected_at_config_boundary() {
|
||||||
let mut params = default_params();
|
for fill in ["", "0123456789abcdef0123456789abcdefx"] {
|
||||||
let fill = "0123456789abcdef0123456789abcdef";
|
|
||||||
params.server_fill = server_fill(fill);
|
|
||||||
let run = run_one_probe(params, TimestampFields::default());
|
|
||||||
assert_eq!(
|
|
||||||
open_observation_params(&run)
|
|
||||||
.server_fill
|
|
||||||
.as_ref()
|
|
||||||
.map(|f| f.value.as_str()),
|
|
||||||
Some(fill)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn server_fill_over_32_bytes_rejected_at_config_boundary() {
|
|
||||||
let config = ClientConfig {
|
let config = ClientConfig {
|
||||||
server_fill: Some("0123456789abcdef0123456789abcdefx".to_owned()),
|
server_fill: Some(fill.to_owned()),
|
||||||
..ClientConfig::default()
|
|
||||||
};
|
|
||||||
assert!(matches!(
|
|
||||||
Client::connect(config),
|
|
||||||
Err(ClientError::InvalidConfig { .. })
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn server_fill_empty_rejected_at_config_boundary() {
|
|
||||||
let config = ClientConfig {
|
|
||||||
server_fill: Some("".to_owned()),
|
|
||||||
..ClientConfig::default()
|
..ClientConfig::default()
|
||||||
};
|
};
|
||||||
assert!(matches!(
|
assert!(matches!(
|
||||||
Client::connect(config),
|
Client::connect(config),
|
||||||
Err(ClientError::InvalidConfig { .. })
|
Err(ClientError::InvalidConfig { .. })
|
||||||
));
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Open negotiation ───
|
// ─── Open negotiation ───
|
||||||
@@ -102,45 +73,17 @@ fn server_fill_negotiated_params_reflect_accepted_value() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn server_fill_strict_rejects_removed_fill() {
|
fn server_fill_strict_rejects_removed_changed_or_unexpected_fill() {
|
||||||
|
for (requested_fill, returned_fill) in [
|
||||||
|
(Some("rand"), None),
|
||||||
|
(Some("abc"), Some("xyz")),
|
||||||
|
(None, Some("unexpected")),
|
||||||
|
] {
|
||||||
let mut requested = default_params();
|
let mut requested = default_params();
|
||||||
requested.server_fill = server_fill("rand");
|
requested.server_fill = requested_fill.and_then(server_fill);
|
||||||
|
|
||||||
let mut returned = requested.clone();
|
let mut returned = requested.clone();
|
||||||
returned.server_fill = None;
|
returned.server_fill = returned_fill.and_then(server_fill);
|
||||||
|
|
||||||
let server = start_open_server(returned, None);
|
|
||||||
let mut client = Client::connect(config_for_params(server.addr, &requested)).unwrap();
|
|
||||||
assert!(matches!(
|
|
||||||
client.open(),
|
|
||||||
Err(ClientError::NegotiationRejected { .. })
|
|
||||||
));
|
|
||||||
server.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn server_fill_strict_rejects_different_fill_value() {
|
|
||||||
let mut requested = default_params();
|
|
||||||
requested.server_fill = server_fill("abc");
|
|
||||||
|
|
||||||
let mut returned = requested.clone();
|
|
||||||
returned.server_fill = server_fill("xyz");
|
|
||||||
|
|
||||||
let server = start_open_server(returned, None);
|
|
||||||
let mut client = Client::connect(config_for_params(server.addr, &requested)).unwrap();
|
|
||||||
assert!(matches!(
|
|
||||||
client.open(),
|
|
||||||
Err(ClientError::NegotiationRejected { .. })
|
|
||||||
));
|
|
||||||
server.join();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn server_fill_strict_rejects_unexpected_fill_from_server() {
|
|
||||||
let requested = default_params();
|
|
||||||
|
|
||||||
let mut returned = requested.clone();
|
|
||||||
returned.server_fill = server_fill("unexpected");
|
|
||||||
|
|
||||||
let server = start_open_server(returned, None);
|
let server = start_open_server(returned, None);
|
||||||
let mut client = Client::connect(config_for_params(server.addr, &requested)).unwrap();
|
let mut client = Client::connect(config_for_params(server.addr, &requested)).unwrap();
|
||||||
@@ -149,6 +92,7 @@ fn server_fill_strict_rejects_unexpected_fill_from_server() {
|
|||||||
Err(ClientError::NegotiationRejected { .. })
|
Err(ClientError::NegotiationRejected { .. })
|
||||||
));
|
));
|
||||||
server.join();
|
server.join();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -176,14 +120,6 @@ fn server_fill_loose_allows_server_to_remove_fill() {
|
|||||||
|
|
||||||
// ─── Echo behavior ───
|
// ─── Echo behavior ───
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn server_fill_echo_reply_decoded_with_fill_configured() {
|
|
||||||
let mut params = default_params();
|
|
||||||
params.server_fill = server_fill("rand");
|
|
||||||
let run = run_one_probe(params, TimestampFields::default());
|
|
||||||
assert!(matches!(run.reply, ClientEvent::EchoReply { .. }));
|
|
||||||
}
|
|
||||||
|
|
||||||
// server_fill is a negotiation/config parameter only; it does not affect
|
// server_fill is a negotiation/config parameter only; it does not affect
|
||||||
// client-observable reply payload layout. The client sends server_fill in
|
// client-observable reply payload layout. The client sends server_fill in
|
||||||
// the open request and expects the server to use it for reply payload
|
// the open request and expects the server to use it for reply payload
|
||||||
|
|||||||
@@ -275,61 +275,3 @@ macro_rules! debug_eprintln {
|
|||||||
}
|
}
|
||||||
|
|
||||||
use debug_eprintln;
|
use debug_eprintln;
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
use super::*;
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn startup_failure_details_include_bind_command_status_and_output() {
|
|
||||||
let status = Command::new("sh")
|
|
||||||
.arg("-c")
|
|
||||||
.arg("exit 7")
|
|
||||||
.status()
|
|
||||||
.expect("shell exits");
|
|
||||||
let failure = StartupFailure {
|
|
||||||
bind: "127.0.0.1:12345".to_owned(),
|
|
||||||
command: "\"irtt\" \"server\"".to_owned(),
|
|
||||||
output: "stderr: listen udp4 127.0.0.1:12345: bind: address already in use".to_owned(),
|
|
||||||
exit_status: Some(status),
|
|
||||||
error: Some("readiness timed out or server exited before ready".to_owned()),
|
|
||||||
};
|
|
||||||
|
|
||||||
let details = failure.details();
|
|
||||||
|
|
||||||
assert!(details.contains("bind: 127.0.0.1:12345"));
|
|
||||||
assert!(details.contains("command: \"irtt\" \"server\""));
|
|
||||||
assert!(details.contains("exit status:"));
|
|
||||||
assert!(details.contains("address already in use"));
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn startup_failure_summary_includes_attempt_count_and_each_bind() {
|
|
||||||
let failures = vec![
|
|
||||||
StartupFailure {
|
|
||||||
bind: "127.0.0.1:11111".to_owned(),
|
|
||||||
command: "\"irtt\" \"server\" -b 127.0.0.1:11111".to_owned(),
|
|
||||||
output: "stdout: first".to_owned(),
|
|
||||||
exit_status: None,
|
|
||||||
error: Some("readiness timed out or server exited before ready".to_owned()),
|
|
||||||
},
|
|
||||||
StartupFailure {
|
|
||||||
bind: "127.0.0.1:22222".to_owned(),
|
|
||||||
command: "\"irtt\" \"server\" -b 127.0.0.1:22222".to_owned(),
|
|
||||||
output: "stderr: second".to_owned(),
|
|
||||||
exit_status: None,
|
|
||||||
error: Some("readiness timed out or server exited before ready".to_owned()),
|
|
||||||
},
|
|
||||||
];
|
|
||||||
|
|
||||||
let message = format_startup_failures("irtt", &failures);
|
|
||||||
|
|
||||||
assert!(message.contains("after 2 attempt(s)"));
|
|
||||||
assert!(message.contains("attempt 1/2"));
|
|
||||||
assert!(message.contains("attempt 2/2"));
|
|
||||||
assert!(message.contains("127.0.0.1:11111"));
|
|
||||||
assert!(message.contains("127.0.0.1:22222"));
|
|
||||||
assert!(message.contains("stdout: first"));
|
|
||||||
assert!(message.contains("stderr: second"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Reference in new issue
Block a user