use super::*;
use crate::transport_parameters::AddressDiscoveryConfig;
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
use std::time::{Duration, Instant};
#[test]
fn test_address_discovery_state_initialization() {
let config = AddressDiscoveryConfig::SendAndReceive;
let now = Instant::now();
let state = AddressDiscoveryState::new(&config, now);
assert!(state.enabled);
assert_eq!(state.max_observation_rate, 10); assert!(!state.observe_all_paths); assert!(state.received_history.is_empty());
assert!(!state.bootstrap_mode);
}
#[test]
fn test_handle_observed_address() {
let config = AddressDiscoveryConfig::default();
let now = Instant::now();
let mut state = AddressDiscoveryState::new(&config, now);
let observed_addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(93, 184, 215, 123)), 443);
state.handle_observed_address(observed_addr, 0, now);
assert_eq!(state.received_history.len(), 1);
assert_eq!(state.received_history[0].address, observed_addr);
assert_eq!(state.received_history[0].path_id, 0);
}
#[test]
fn test_multiple_observations() {
let config = AddressDiscoveryConfig::default();
let now = Instant::now();
let mut state = AddressDiscoveryState::new(&config, now);
let addresses = [SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 8080),
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 2)), 8081),
SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 3)), 8082)];
for (i, addr) in addresses.iter().enumerate() {
state.handle_observed_address(*addr, i as u64, now);
}
assert_eq!(state.received_history.len(), 3);
for (i, addr) in addresses.iter().enumerate() {
assert_eq!(state.received_history[i].address, *addr);
}
}
#[test]
fn test_rate_limiting() {
let config = AddressDiscoveryConfig::SendAndReceive;
let mut now = Instant::now();
let mut state = AddressDiscoveryState::new(&config, now);
let path_id = 0;
assert!(state.should_send_observation(path_id, now));
for _ in 0..10 {
state.rate_limiter.try_consume(1.0, now);
}
assert!(!state.should_send_observation(path_id, now));
now += Duration::from_millis(200);
state.rate_limiter.update_tokens(now);
assert!(state.should_send_observation(path_id, now));
}
#[test]
fn test_bootstrap_mode() {
let config = AddressDiscoveryConfig::default();
let now = Instant::now();
let mut state = AddressDiscoveryState::new(&config, now);
state.set_bootstrap_mode(true);
assert!(state.bootstrap_mode);
assert!(state.should_observe_path(0));
}
#[test]
fn test_disabled_state() {
let config = AddressDiscoveryConfig::SendAndReceive;
let now = Instant::now();
let mut state = AddressDiscoveryState::new(&config, now);
state.enabled = false;
assert!(!state.should_send_observation(0, now));
let addr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(10, 0, 0, 1)), 80);
state.handle_observed_address(addr, 0, now);
assert_eq!(state.received_history.len(), 0);
}
#[test]
fn test_observe_all_paths_configuration() {
let config = AddressDiscoveryConfig::SendAndReceive;
let now = Instant::now();
let state = AddressDiscoveryState::new(&config, now);
assert!(state.should_observe_path(0));
assert!(!state.should_observe_path(1));
assert!(!state.should_observe_path(2));
}
#[test]
fn test_ipv6_address_handling() {
let config = AddressDiscoveryConfig::default();
let now = Instant::now();
let mut state = AddressDiscoveryState::new(&config, now);
let ipv6_addresses = [SocketAddr::new(IpAddr::V6("2001:db8::1".parse().unwrap()), 443),
SocketAddr::new(IpAddr::V6("::1".parse().unwrap()), 8080),
SocketAddr::new(IpAddr::V6("fe80::1".parse().unwrap()), 22)];
for (i, addr) in ipv6_addresses.iter().enumerate() {
state.handle_observed_address(*addr, i as u64, now);
}
assert_eq!(state.received_history.len(), 3);
for (i, addr) in ipv6_addresses.iter().enumerate() {
assert_eq!(state.received_history[i].address, *addr);
}
}
#[test]
fn test_rate_limiter_token_bucket() {
let rate = 10; let now = Instant::now();
let mut limiter = AddressObservationRateLimiter::new(rate, now);
assert!(limiter.try_consume(1.0, now));
assert!(limiter.try_consume(1.0, now));
for _ in 0..8 {
limiter.try_consume(1.0, now);
}
assert!(!limiter.try_consume(1.0, now));
let later = now + Duration::from_millis(100); assert!(limiter.try_consume(1.0, later));
}