telemt/src/proxy/tests/client_beobachten_ttl_bound...

127 lines
3.7 KiB
Rust

use super::*;
const BEOBACHTEN_TTL_MAX_MINUTES: u64 = 24 * 60;
#[test]
fn beobachten_ttl_exact_upper_bound_is_preserved() {
let mut config = ProxyConfig::default();
config.general.beobachten = true;
config.general.beobachten_minutes = BEOBACHTEN_TTL_MAX_MINUTES;
let ttl = beobachten_ttl(&config);
assert_eq!(
ttl,
Duration::from_secs(BEOBACHTEN_TTL_MAX_MINUTES * 60),
"upper-bound TTL should remain unchanged"
);
}
#[test]
fn beobachten_ttl_above_upper_bound_is_clamped() {
let mut config = ProxyConfig::default();
config.general.beobachten = true;
config.general.beobachten_minutes = BEOBACHTEN_TTL_MAX_MINUTES + 1;
let ttl = beobachten_ttl(&config);
assert_eq!(
ttl,
Duration::from_secs(BEOBACHTEN_TTL_MAX_MINUTES * 60),
"TTL above security cap must be clamped"
);
}
#[test]
fn beobachten_ttl_u64_max_is_clamped_fail_safe() {
let mut config = ProxyConfig::default();
config.general.beobachten = true;
config.general.beobachten_minutes = u64::MAX;
let ttl = beobachten_ttl(&config);
assert_eq!(
ttl,
Duration::from_secs(BEOBACHTEN_TTL_MAX_MINUTES * 60),
"extreme configured TTL must not become multi-century retention"
);
}
#[test]
fn positive_one_minute_maps_to_exact_60_seconds() {
let mut config = ProxyConfig::default();
config.general.beobachten = true;
config.general.beobachten_minutes = 1;
assert_eq!(beobachten_ttl(&config), Duration::from_secs(60));
}
#[test]
fn adversarial_boundary_triplet_behaves_deterministically() {
let mut config = ProxyConfig::default();
config.general.beobachten = true;
config.general.beobachten_minutes = BEOBACHTEN_TTL_MAX_MINUTES - 1;
assert_eq!(
beobachten_ttl(&config),
Duration::from_secs((BEOBACHTEN_TTL_MAX_MINUTES - 1) * 60)
);
config.general.beobachten_minutes = BEOBACHTEN_TTL_MAX_MINUTES;
assert_eq!(
beobachten_ttl(&config),
Duration::from_secs(BEOBACHTEN_TTL_MAX_MINUTES * 60)
);
config.general.beobachten_minutes = BEOBACHTEN_TTL_MAX_MINUTES + 1;
assert_eq!(
beobachten_ttl(&config),
Duration::from_secs(BEOBACHTEN_TTL_MAX_MINUTES * 60)
);
}
#[test]
fn light_fuzz_random_minutes_match_fail_safe_model() {
let mut config = ProxyConfig::default();
config.general.beobachten = true;
let mut seed = 0xD15E_A5E5_F00D_BAADu64;
for _ in 0..8192 {
seed ^= seed << 7;
seed ^= seed >> 9;
seed ^= seed << 8;
config.general.beobachten_minutes = seed;
let ttl = beobachten_ttl(&config);
let expected = if seed == 0 {
Duration::from_secs(60)
} else {
Duration::from_secs(seed.min(BEOBACHTEN_TTL_MAX_MINUTES) * 60)
};
assert_eq!(ttl, expected, "ttl mismatch for minutes={seed}");
assert!(ttl <= Duration::from_secs(BEOBACHTEN_TTL_MAX_MINUTES * 60));
}
}
#[test]
fn stress_monotonic_minutes_remain_monotonic_until_cap_then_flat() {
let mut config = ProxyConfig::default();
config.general.beobachten = true;
let mut prev = Duration::from_secs(0);
for minutes in 0..=(BEOBACHTEN_TTL_MAX_MINUTES + 4096) {
config.general.beobachten_minutes = minutes;
let ttl = beobachten_ttl(&config);
assert!(ttl >= prev, "ttl must be non-decreasing as minutes grow");
assert!(ttl <= Duration::from_secs(BEOBACHTEN_TTL_MAX_MINUTES * 60));
if minutes > BEOBACHTEN_TTL_MAX_MINUTES {
assert_eq!(
ttl,
Duration::from_secs(BEOBACHTEN_TTL_MAX_MINUTES * 60),
"ttl must stay clamped once cap is exceeded"
);
}
prev = ttl;
}
}