test: consolidate duplicate CLI and client config cases
This commit is contained in:
1 parent
ddd420cc21
commit
00fd0ebb15
3 files changed
+111
-176
No files matched your search
+15
-40
@@ -971,15 +971,12 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn duration_zero_selects_continuous_config() {
|
fn cli_options_map_to_client_config() {
|
||||||
let args = parse(&["--duration", "0", "127.0.0.1:2112"]).unwrap();
|
let args = parse(&["--duration", "0", "127.0.0.1:2112"]).unwrap();
|
||||||
assert!(args.is_continuous());
|
assert!(args.is_continuous());
|
||||||
assert_eq!(args.duration, Duration::ZERO);
|
assert_eq!(args.duration, Duration::ZERO);
|
||||||
assert_eq!(args.to_client_config().duration, None);
|
assert_eq!(args.to_client_config().duration, None);
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn parses_output_clock_and_timestamp_modes() {
|
|
||||||
let args = parse(&[
|
let args = parse(&[
|
||||||
"--output",
|
"--output",
|
||||||
"machine",
|
"machine",
|
||||||
@@ -994,6 +991,7 @@ mod tests {
|
|||||||
assert_eq!(args.clock, ClockArg::Wall);
|
assert_eq!(args.clock, ClockArg::Wall);
|
||||||
assert_eq!(args.timestamp_mode(), TimestampArg::Send);
|
assert_eq!(args.timestamp_mode(), TimestampArg::Send);
|
||||||
assert_eq!(args.to_client_config().stamp_at, StampAt::Send);
|
assert_eq!(args.to_client_config().stamp_at, StampAt::Send);
|
||||||
|
assert_eq!(args.to_client_config().clock, Clock::Wall);
|
||||||
|
|
||||||
let args = parse(&[
|
let args = parse(&[
|
||||||
"--output",
|
"--output",
|
||||||
@@ -1009,13 +1007,11 @@ mod tests {
|
|||||||
assert_eq!(args.clock, ClockArg::Monotonic);
|
assert_eq!(args.clock, ClockArg::Monotonic);
|
||||||
assert_eq!(args.timestamp_mode(), TimestampArg::Receive);
|
assert_eq!(args.timestamp_mode(), TimestampArg::Receive);
|
||||||
assert_eq!(args.to_client_config().stamp_at, StampAt::Receive);
|
assert_eq!(args.to_client_config().stamp_at, StampAt::Receive);
|
||||||
|
assert_eq!(args.to_client_config().clock, Clock::Monotonic);
|
||||||
|
|
||||||
let args = parse(&["--output", "human", "127.0.0.1:2112"]).unwrap();
|
let args = parse(&["--output", "human", "127.0.0.1:2112"]).unwrap();
|
||||||
assert_eq!(args.output, OutputMode::Human);
|
assert_eq!(args.output, OutputMode::Human);
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn maps_tstamp_modes() {
|
|
||||||
for (value, expected) in [
|
for (value, expected) in [
|
||||||
("none", StampAt::None),
|
("none", StampAt::None),
|
||||||
("send", StampAt::Send),
|
("send", StampAt::Send),
|
||||||
@@ -1026,29 +1022,11 @@ mod tests {
|
|||||||
let args = parse(&["--tstamp", value, "127.0.0.1:2112"]).unwrap();
|
let args = parse(&["--tstamp", value, "127.0.0.1:2112"]).unwrap();
|
||||||
assert_eq!(args.to_client_config().stamp_at, expected);
|
assert_eq!(args.to_client_config().stamp_at, expected);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn timestamps_alias_accepts_midpoint() {
|
|
||||||
let args = parse(&["--timestamps", "midpoint", "127.0.0.1:2112"]).unwrap();
|
let args = parse(&["--timestamps", "midpoint", "127.0.0.1:2112"]).unwrap();
|
||||||
assert_eq!(args.timestamp_mode(), TimestampArg::Midpoint);
|
assert_eq!(args.timestamp_mode(), TimestampArg::Midpoint);
|
||||||
assert_eq!(args.to_client_config().stamp_at, StampAt::Midpoint);
|
assert_eq!(args.to_client_config().stamp_at, StampAt::Midpoint);
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn rejects_duplicate_timestamp_options() {
|
|
||||||
assert!(parse(&[
|
|
||||||
"--tstamp",
|
|
||||||
"send",
|
|
||||||
"--timestamps",
|
|
||||||
"receive",
|
|
||||||
"127.0.0.1:2112"
|
|
||||||
])
|
|
||||||
.is_err());
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn maps_received_stats_modes() {
|
|
||||||
for (value, expected) in [
|
for (value, expected) in [
|
||||||
("none", ReceivedStats::None),
|
("none", ReceivedStats::None),
|
||||||
("count", ReceivedStats::Count),
|
("count", ReceivedStats::Count),
|
||||||
@@ -1061,10 +1039,7 @@ mod tests {
|
|||||||
|
|
||||||
let args = parse(&["127.0.0.1:2112"]).unwrap();
|
let args = parse(&["127.0.0.1:2112"]).unwrap();
|
||||||
assert_eq!(args.to_client_config().received_stats, ReceivedStats::Both);
|
assert_eq!(args.to_client_config().received_stats, ReceivedStats::Both);
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn maps_sfill_server_fill_options() {
|
|
||||||
let args = parse(&["--sfill", "abc", "127.0.0.1:2112"]).unwrap();
|
let args = parse(&["--sfill", "abc", "127.0.0.1:2112"]).unwrap();
|
||||||
assert_eq!(args.to_client_config().server_fill.as_deref(), Some("abc"));
|
assert_eq!(args.to_client_config().server_fill.as_deref(), Some("abc"));
|
||||||
|
|
||||||
@@ -1074,18 +1049,12 @@ mod tests {
|
|||||||
let max = "0123456789abcdef0123456789abcdef";
|
let max = "0123456789abcdef0123456789abcdef";
|
||||||
let args = parse(&["--sfill", max, "127.0.0.1:2112"]).unwrap();
|
let args = parse(&["--sfill", max, "127.0.0.1:2112"]).unwrap();
|
||||||
assert_eq!(args.to_client_config().server_fill.as_deref(), Some(max));
|
assert_eq!(args.to_client_config().server_fill.as_deref(), Some(max));
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn maps_dscp_codepoints() {
|
|
||||||
for value in ["0", "46", "63"] {
|
for value in ["0", "46", "63"] {
|
||||||
let args = parse(&["--dscp", value, "127.0.0.1:2112"]).unwrap();
|
let args = parse(&["--dscp", value, "127.0.0.1:2112"]).unwrap();
|
||||||
assert_eq!(args.to_client_config().dscp, value.parse::<u8>().unwrap());
|
assert_eq!(args.to_client_config().dscp, value.parse::<u8>().unwrap());
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn maps_ttl_values() {
|
|
||||||
for value in ["1", "64", "255"] {
|
for value in ["1", "64", "255"] {
|
||||||
let args = parse(&["--ttl", value, "127.0.0.1:2112"]).unwrap();
|
let args = parse(&["--ttl", value, "127.0.0.1:2112"]).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -1093,10 +1062,7 @@ mod tests {
|
|||||||
Some(value.parse::<u32>().unwrap())
|
Some(value.parse::<u32>().unwrap())
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn maps_length_option() {
|
|
||||||
let args = parse(&["--length", "1472", "127.0.0.1:2112"]).unwrap();
|
let args = parse(&["--length", "1472", "127.0.0.1:2112"]).unwrap();
|
||||||
assert_eq!(args.length, 1472);
|
assert_eq!(args.length, 1472);
|
||||||
assert_eq!(args.to_client_config().length, 1472);
|
assert_eq!(args.to_client_config().length, 1472);
|
||||||
@@ -1104,10 +1070,7 @@ mod tests {
|
|||||||
let args = parse(&["127.0.0.1:2112"]).unwrap();
|
let args = parse(&["127.0.0.1:2112"]).unwrap();
|
||||||
assert_eq!(args.length, 0);
|
assert_eq!(args.length, 0);
|
||||||
assert_eq!(args.to_client_config().length, 0);
|
assert_eq!(args.to_client_config().length, 0);
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn maps_loose_negotiation() {
|
|
||||||
let args = parse(&["127.0.0.1:2112"]).unwrap();
|
let args = parse(&["127.0.0.1:2112"]).unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
args.to_client_config().negotiation_policy,
|
args.to_client_config().negotiation_policy,
|
||||||
@@ -1121,6 +1084,18 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn rejects_duplicate_timestamp_options() {
|
||||||
|
assert!(parse(&[
|
||||||
|
"--tstamp",
|
||||||
|
"send",
|
||||||
|
"--timestamps",
|
||||||
|
"receive",
|
||||||
|
"127.0.0.1:2112"
|
||||||
|
])
|
||||||
|
.is_err());
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn help_lists_advanced_protocol_options() {
|
fn help_lists_advanced_protocol_options() {
|
||||||
let help = CliArgs::command().render_help().to_string();
|
let help = CliArgs::command().render_help().to_string();
|
||||||
|
|||||||
+27
-49
@@ -599,46 +599,41 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn finite_stats_memory_warning_skips_continuous_mode() {
|
fn finite_stats_memory_warning_skips_non_warning_runs() {
|
||||||
let args = cli_args(&["--duration", "0", "--interval", "1ms", "127.0.0.1:2112"]);
|
for args in [
|
||||||
|
cli_args(&["--duration", "0", "--interval", "1ms", "127.0.0.1:2112"]),
|
||||||
assert_eq!(finite_stats_memory_warning(&args), None);
|
cli_args(&[
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn finite_stats_memory_warning_skips_small_finite_run() {
|
|
||||||
let args = cli_args(&[
|
|
||||||
"--duration",
|
"--duration",
|
||||||
"1000ms",
|
"1000ms",
|
||||||
"--interval",
|
"--interval",
|
||||||
"1ms",
|
"1ms",
|
||||||
"127.0.0.1:2112",
|
"127.0.0.1:2112",
|
||||||
]);
|
]),
|
||||||
|
] {
|
||||||
assert_eq!(finite_stats_memory_warning(&args), None);
|
assert_eq!(finite_stats_memory_warning(&args), None);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn finite_stats_memory_warning_reports_128_mib_tier() {
|
|
||||||
let expected_probes =
|
|
||||||
FINITE_STATS_MEMORY_WARNING_BYTES.div_ceil(FINITE_STATS_BYTES_PER_PROBE);
|
|
||||||
let args = cli_args(&[
|
|
||||||
"--duration",
|
|
||||||
&format!("{expected_probes}ms"),
|
|
||||||
"--interval",
|
|
||||||
"1ms",
|
|
||||||
"127.0.0.1:2112",
|
|
||||||
]);
|
|
||||||
|
|
||||||
let warning = finite_stats_memory_warning(&args).unwrap();
|
|
||||||
assert!(warning.contains("about 128 MiB"));
|
|
||||||
assert!(warning.contains("bounded-memory long-running tests"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn finite_stats_memory_warning_reports_512_mib_tier() {
|
fn finite_stats_memory_warning_reports_threshold_tiers() {
|
||||||
let expected_probes =
|
for (threshold, size, guidance) in [
|
||||||
FINITE_STATS_MEMORY_STRONG_WARNING_BYTES.div_ceil(FINITE_STATS_BYTES_PER_PROBE);
|
(
|
||||||
|
FINITE_STATS_MEMORY_WARNING_BYTES,
|
||||||
|
"about 128 MiB",
|
||||||
|
"bounded-memory long-running tests",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
FINITE_STATS_MEMORY_STRONG_WARNING_BYTES,
|
||||||
|
"about 512 MiB",
|
||||||
|
"shortening the run",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
FINITE_STATS_MEMORY_VERY_STRONG_WARNING_BYTES,
|
||||||
|
"about 1 GiB",
|
||||||
|
"memory-constrained systems",
|
||||||
|
),
|
||||||
|
] {
|
||||||
|
let expected_probes = threshold.div_ceil(FINITE_STATS_BYTES_PER_PROBE);
|
||||||
let args = cli_args(&[
|
let args = cli_args(&[
|
||||||
"--duration",
|
"--duration",
|
||||||
&format!("{expected_probes}ms"),
|
&format!("{expected_probes}ms"),
|
||||||
@@ -648,26 +643,9 @@ mod tests {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
let warning = finite_stats_memory_warning(&args).unwrap();
|
let warning = finite_stats_memory_warning(&args).unwrap();
|
||||||
assert!(warning.contains("about 512 MiB"));
|
assert!(warning.contains(size));
|
||||||
assert!(warning.contains("shortening the run"));
|
assert!(warning.contains(guidance));
|
||||||
assert!(warning.contains("increasing the interval"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn finite_stats_memory_warning_reports_1_gib_tier() {
|
|
||||||
let expected_probes =
|
|
||||||
FINITE_STATS_MEMORY_VERY_STRONG_WARNING_BYTES.div_ceil(FINITE_STATS_BYTES_PER_PROBE);
|
|
||||||
let args = cli_args(&[
|
|
||||||
"--duration",
|
|
||||||
&format!("{expected_probes}ms"),
|
|
||||||
"--interval",
|
|
||||||
"1ms",
|
|
||||||
"127.0.0.1:2112",
|
|
||||||
]);
|
|
||||||
|
|
||||||
let warning = finite_stats_memory_warning(&args).unwrap();
|
|
||||||
assert!(warning.contains("about 1 GiB"));
|
|
||||||
assert!(warning.contains("memory-constrained systems"));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ fn params_from_config_maps_compatibility_fields() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn params_from_config_accepts_udp_payload_length_boundary_values() {
|
fn params_from_config_accepts_boundary_values() {
|
||||||
for length in [0, 1, 1472, 4096, MAX_UDP_PAYLOAD_LENGTH] {
|
for length in [0, 1, 1472, 4096, MAX_UDP_PAYLOAD_LENGTH] {
|
||||||
let config = ClientConfig {
|
let config = ClientConfig {
|
||||||
length,
|
length,
|
||||||
@@ -62,18 +62,12 @@ fn params_from_config_accepts_udp_payload_length_boundary_values() {
|
|||||||
i64::from(length)
|
i64::from(length)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn params_from_config_rejects_oversized_udp_payload_length() {
|
|
||||||
let config = ClientConfig {
|
let config = ClientConfig {
|
||||||
length: MAX_UDP_PAYLOAD_LENGTH + 1,
|
dscp: 63,
|
||||||
..ClientConfig::default()
|
..ClientConfig::default()
|
||||||
};
|
};
|
||||||
assert!(matches!(
|
assert_eq!(params_from_config(&config).unwrap().dscp, 63);
|
||||||
params_from_config(&config),
|
|
||||||
Err(ClientError::InvalidConfig { reason }) if reason.contains("packet length")
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@@ -86,97 +80,85 @@ fn params_from_config_encodes_continuous_duration_as_zero() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn params_from_config_rejects_zero_finite_duration() {
|
fn params_from_config_rejects_invalid_values() {
|
||||||
let config = ClientConfig {
|
let i64_max_ns = u64::try_from(i64::MAX).unwrap();
|
||||||
|
let too_large = Duration::from_nanos(i64_max_ns) + Duration::from_nanos(1);
|
||||||
|
let cases = [
|
||||||
|
(
|
||||||
|
"oversized UDP payload",
|
||||||
|
ClientConfig {
|
||||||
|
length: MAX_UDP_PAYLOAD_LENGTH + 1,
|
||||||
|
..ClientConfig::default()
|
||||||
|
},
|
||||||
|
"packet length",
|
||||||
|
),
|
||||||
|
(
|
||||||
|
"zero finite duration",
|
||||||
|
ClientConfig {
|
||||||
duration: Some(Duration::ZERO),
|
duration: Some(Duration::ZERO),
|
||||||
..ClientConfig::default()
|
..ClientConfig::default()
|
||||||
};
|
},
|
||||||
assert!(matches!(
|
"duration must be greater than zero; use None for continuous mode",
|
||||||
params_from_config(&config),
|
),
|
||||||
Err(ClientError::InvalidConfig { reason })
|
(
|
||||||
if reason == "duration must be greater than zero; use None for continuous mode"
|
"zero interval",
|
||||||
));
|
ClientConfig {
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn params_from_config_rejects_zero_interval() {
|
|
||||||
let config = ClientConfig {
|
|
||||||
interval: Duration::ZERO,
|
interval: Duration::ZERO,
|
||||||
..ClientConfig::default()
|
..ClientConfig::default()
|
||||||
};
|
},
|
||||||
assert!(matches!(
|
"interval must be greater than zero",
|
||||||
params_from_config(&config),
|
),
|
||||||
Err(ClientError::InvalidConfig { reason }) if reason == "interval must be greater than zero"
|
(
|
||||||
));
|
"duration nanosecond overflow",
|
||||||
}
|
ClientConfig {
|
||||||
|
duration: Some(too_large),
|
||||||
#[test]
|
|
||||||
fn params_from_config_rejects_nanosecond_encoding_overflow_as_invalid_config() {
|
|
||||||
let i64_max_ns = u64::try_from(i64::MAX).unwrap();
|
|
||||||
let config = ClientConfig {
|
|
||||||
duration: Some(Duration::from_nanos(i64_max_ns) + Duration::from_nanos(1)),
|
|
||||||
..ClientConfig::default()
|
..ClientConfig::default()
|
||||||
};
|
},
|
||||||
assert!(matches!(
|
"duration is too large to encode as nanoseconds",
|
||||||
params_from_config(&config),
|
),
|
||||||
Err(ClientError::InvalidConfig { reason })
|
(
|
||||||
if reason == "duration is too large to encode as nanoseconds"
|
"interval nanosecond overflow",
|
||||||
));
|
ClientConfig {
|
||||||
|
interval: too_large,
|
||||||
let config = ClientConfig {
|
|
||||||
interval: Duration::from_nanos(i64_max_ns) + Duration::from_nanos(1),
|
|
||||||
..ClientConfig::default()
|
..ClientConfig::default()
|
||||||
};
|
},
|
||||||
assert!(matches!(
|
"interval is too large to encode as nanoseconds",
|
||||||
params_from_config(&config),
|
),
|
||||||
Err(ClientError::InvalidConfig { reason })
|
(
|
||||||
if reason == "interval is too large to encode as nanoseconds"
|
"invalid DSCP codepoint",
|
||||||
));
|
ClientConfig {
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn params_from_config_accepts_max_dscp_codepoint() {
|
|
||||||
let config = ClientConfig {
|
|
||||||
dscp: 63,
|
|
||||||
..ClientConfig::default()
|
|
||||||
};
|
|
||||||
assert_eq!(params_from_config(&config).unwrap().dscp, 63);
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn params_from_config_rejects_invalid_dscp_codepoint() {
|
|
||||||
let config = ClientConfig {
|
|
||||||
dscp: 64,
|
dscp: 64,
|
||||||
..ClientConfig::default()
|
..ClientConfig::default()
|
||||||
};
|
},
|
||||||
assert!(matches!(
|
"dscp",
|
||||||
params_from_config(&config),
|
),
|
||||||
Err(ClientError::InvalidConfig { .. })
|
(
|
||||||
));
|
"empty server fill",
|
||||||
}
|
ClientConfig {
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn params_from_config_rejects_empty_server_fill() {
|
|
||||||
let config = ClientConfig {
|
|
||||||
server_fill: Some("".to_owned()),
|
server_fill: Some("".to_owned()),
|
||||||
..ClientConfig::default()
|
..ClientConfig::default()
|
||||||
};
|
},
|
||||||
assert!(matches!(
|
"server_fill",
|
||||||
params_from_config(&config),
|
),
|
||||||
Err(ClientError::InvalidConfig { .. })
|
(
|
||||||
));
|
"oversized server fill",
|
||||||
}
|
ClientConfig {
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn params_from_config_rejects_oversized_server_fill() {
|
|
||||||
let config = ClientConfig {
|
|
||||||
server_fill: Some("0123456789abcdef0123456789abcdefx".to_owned()),
|
server_fill: Some("0123456789abcdef0123456789abcdefx".to_owned()),
|
||||||
..ClientConfig::default()
|
..ClientConfig::default()
|
||||||
};
|
},
|
||||||
assert!(matches!(
|
"server_fill",
|
||||||
|
),
|
||||||
|
];
|
||||||
|
|
||||||
|
for (name, config, expected_reason) in cases {
|
||||||
|
assert!(
|
||||||
|
matches!(
|
||||||
params_from_config(&config),
|
params_from_config(&config),
|
||||||
Err(ClientError::InvalidConfig { .. })
|
Err(ClientError::InvalidConfig { reason }) if reason.contains(expected_reason)
|
||||||
));
|
),
|
||||||
|
"{name} should fail with InvalidConfig containing {expected_reason:?}"
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in new issue
Block a user