use std::env;
use crate::defaults::DefaultExecutor;
use crate::settings::SettingsBuilder;
use crate::settings::keys::*;
fn builder() -> SettingsBuilder<DefaultExecutor> {
SettingsBuilder::new()
}
#[test]
fn test_default_settings_pass_assertions() {
assert!(builder().build().is_ok());
}
#[test]
fn test_settings_timeout_min_exceeds_max() {
let result = builder().set(&TIMEOUT_MIN, 50000).set(&TIMEOUT_MAX, 1000).build();
assert!(result.is_err());
}
#[test]
fn test_settings_rtt_min_exceeds_max() {
let result = builder().set(&RTT_MIN, 10000).set(&RTT_MAX, 100).build();
assert!(result.is_err());
}
#[test]
fn test_settings_rtt_alpha_exceeds_one() {
let result = builder().set(&RTT_ALPHA, 1.5).build();
assert!(result.is_err());
}
#[test]
fn test_settings_rtt_alpha_zero() {
let result = builder().set(&RTT_ALPHA, 0.0).build();
assert!(result.is_err());
}
#[test]
fn test_settings_rtt_beta_negative() {
let result = builder().set(&RTT_BETA, -0.1).build();
assert!(result.is_err());
}
#[test]
fn test_settings_fake_header_probability_exceeds_one() {
let result = builder().set(&FAKE_HEADER_PROBABILITY, 1.5).build();
assert!(result.is_err());
}
#[test]
fn test_settings_fake_header_probability_zero_ok() {
let result = builder().set(&FAKE_HEADER_PROBABILITY, 0.0).build();
assert!(result.is_ok());
}
#[test]
fn test_settings_send_bytes_jitter_exceeds_one() {
let result = builder().set(&SEND_BYTES_JITTER, 1.5).build();
assert!(result.is_err());
}
#[test]
fn test_settings_send_bytes_jitter_negative() {
let result = builder().set(&SEND_BYTES_JITTER, -0.1).build();
assert!(result.is_err());
}
#[test]
fn test_settings_send_bytes_jitter_unit_bounds_ok() {
assert!(builder().set(&SEND_BYTES_JITTER, 0.0).build().is_ok());
assert!(builder().set(&SEND_BYTES_JITTER, 1.0).build().is_ok());
}
#[test]
fn test_settings_send_bytes_chunk_bounds() {
assert!(builder().set(&SEND_BYTES_CHUNK, 0).build().is_ok());
assert!(builder().set(&SEND_BYTES_CHUNK, 512).build().is_ok());
assert!(builder().set(&SEND_BYTES_CHUNK, 1500).build().is_ok());
assert!(builder().set(&SEND_BYTES_CHUNK, 9000).build().is_err());
}
#[test]
fn test_settings_next_in_not_greater_than_timeout() {
let result = builder().set(&HEALTH_CHECK_NEXT_IN_MIN, 30000).set(&TIMEOUT_MAX, 32000).build();
assert!(result.is_err());
}
#[test]
fn test_settings_rtt_default_out_of_range() {
let result = builder().set(&RTT_DEFAULT, 100_000).build();
assert!(result.is_err());
}
#[test]
fn test_settings_decoy_current_alpha_exceeds_one() {
let result = builder().set(&DECOY_CURRENT_ALPHA, 2.0).build();
assert!(result.is_err());
}
#[test]
fn test_settings_decoy_length_min_exceeds_max() {
let result = builder().set(&DECOY_LENGTH_MIN, 2000).set(&DECOY_LENGTH_MAX, 100).build();
assert!(result.is_err());
}
#[test]
fn test_settings_decoy_fallthrough_min_exceeds_max() {
let result = builder().set(&DECOY_FALLTHROUGH_PACKETS_MIN, 0.5).set(&DECOY_FALLTHROUGH_PACKETS_MAX, 0.1).build();
assert!(result.is_err());
}
#[test]
fn test_settings_decoy_fallthrough_min_out_of_unit_range() {
assert!(builder().set(&DECOY_FALLTHROUGH_PACKETS_MIN, -0.1).build().is_err());
assert!(builder().set(&DECOY_FALLTHROUGH_PACKETS_MIN, 1.5).build().is_err());
}
#[test]
fn test_settings_decoy_fallthrough_max_out_of_unit_range() {
assert!(builder().set(&DECOY_FALLTHROUGH_PACKETS_MAX, -0.1).build().is_err());
assert!(builder().set(&DECOY_FALLTHROUGH_PACKETS_MAX, 1.5).build().is_err());
}
#[test]
fn test_settings_decoy_fallthrough_unit_bounds_ok() {
assert!(builder().set(&DECOY_FALLTHROUGH_PACKETS_MIN, 0.0).set(&DECOY_FALLTHROUGH_PACKETS_MAX, 1.0).build().is_ok());
assert!(builder().set(&DECOY_FALLTHROUGH_PACKETS_MIN, 0.5).set(&DECOY_FALLTHROUGH_PACKETS_MAX, 0.5).build().is_ok());
}
#[test]
fn test_settings_valid_custom_pass() {
let result = builder().set(&RTT_ALPHA, 0.5).set(&RTT_BETA, 0.5).set(&FAKE_HEADER_PROBABILITY, 0.5).build();
assert!(result.is_ok());
}
#[test]
fn test_env_var_override_applied() {
let env_name = HANDSHAKE_NEXT_IN_FACTOR.name;
let original = env::var(env_name).ok();
unsafe { env::set_var(env_name, "0.5") };
let settings = builder().build().expect("settings should build with env override");
let val: f64 = settings.get(&HANDSHAKE_NEXT_IN_FACTOR);
assert_eq!(val, 0.5, "env var override should take effect");
unsafe {
match original {
Some(v) => env::set_var(env_name, v),
None => env::remove_var(env_name),
}
}
}
#[test]
fn test_settings_fake_header_volatile_change_prob_min_exceeds_max() {
let result = builder().set(&FAKE_HEADER_VOLATILE_CHANGE_PROB_MIN, 0.5).set(&FAKE_HEADER_VOLATILE_CHANGE_PROB_MAX, 0.1).build();
assert!(result.is_err());
}
#[test]
fn test_settings_fake_header_volatile_change_prob_exceeds_one() {
let result = builder().set(&FAKE_HEADER_VOLATILE_CHANGE_PROB_MAX, 1.5).build();
assert!(result.is_err());
}
#[test]
fn test_settings_fake_header_switching_timeout_min_exceeds_max() {
let result = builder().set(&FAKE_HEADER_SWITCHING_TIMEOUT_MIN_MS, 50_000).set(&FAKE_HEADER_SWITCHING_TIMEOUT_MAX_MS, 1_000).build();
assert!(result.is_err());
}
#[test]
fn test_settings_fake_header_switching_timeout_min_zero() {
let result = builder().set(&FAKE_HEADER_SWITCHING_TIMEOUT_MIN_MS, 0).build();
assert!(result.is_err());
}
#[test]
fn test_settings_noisy_length_min_exceeds_max() {
let result = builder().set(&DECOY_NOISY_DECOY_LENGTH_MIN, 1000).set(&DECOY_NOISY_LENGTH_MAX, 500).build();
assert!(result.is_err());
}
#[test]
fn test_settings_heavy_length_min_exceeds_decoy_max() {
let result = builder().set(&DECOY_HEAVY_LENGTH_MIN, 2000).set(&DECOY_LENGTH_MAX, 1400).build();
assert!(result.is_err());
}
#[test]
fn test_explicit_override_beats_env_var() {
let env_name = TIMEOUT_RTT_FACTOR.name;
let original = env::var(env_name).ok();
unsafe { env::set_var(env_name, "7.5") };
let settings = builder().set(&TIMEOUT_RTT_FACTOR, 3.0).build().expect("settings should build");
let val: f64 = settings.get(&TIMEOUT_RTT_FACTOR);
assert_eq!(val, 3.0, "explicit override should take precedence over env var");
unsafe {
match original {
Some(v) => env::set_var(env_name, v),
None => env::remove_var(env_name),
}
}
}