#[cfg(test)]
mod tests {
use crate::net::quic_native::{
ConnectionRouter, ManagedEndpointConfig, ManagedQuicEndpoint, NativeQuicConnectionConfig,
QuicTimerScheduler,
};
use crate::test_utils::run_test_with_cx;
use std::net::SocketAddr;
use std::time::Duration;
use std::time::Instant;
#[test]
fn test_managed_endpoint_basic_lifecycle() {
run_test_with_cx(|cx| async move {
let server_config = ManagedEndpointConfig {
is_server: true,
max_connections: 10,
..ManagedEndpointConfig::default()
};
let mut server =
ManagedQuicEndpoint::bind(&cx, "127.0.0.1:0".parse().unwrap(), server_config)
.await
.expect("server bind should succeed");
let _server_addr = server.local_addr();
let client_config = ManagedEndpointConfig {
is_server: false,
max_connections: 5,
..ManagedEndpointConfig::default()
};
let mut client =
ManagedQuicEndpoint::bind(&cx, "127.0.0.1:0".parse().unwrap(), client_config)
.await
.expect("client bind should succeed");
let server_stats = server.connection_stats();
assert_eq!(server_stats.active_connections, 0);
assert_eq!(server_stats.established_connections, 0);
let client_stats = client.connection_stats();
assert_eq!(client_stats.active_connections, 0);
server
.shutdown(&cx)
.await
.expect("server shutdown should succeed");
client
.shutdown(&cx)
.await
.expect("client shutdown should succeed");
});
}
#[test]
fn test_connection_router_with_timer_integration() {
run_test_with_cx(|cx| async move {
let connection_config = NativeQuicConnectionConfig::default();
let mut router = ConnectionRouter::new(connection_config);
assert_eq!(router.connection_stats().active_connections, 0);
assert_eq!(router.next_timer_deadline(), None);
let connection_id = router.allocate_connection_id();
let peer_addr: SocketAddr = "192.168.1.100:5000".parse().unwrap();
router
.create_connection(&cx, connection_id, peer_addr, true)
.await
.expect("connection creation should succeed");
let stats = router.connection_stats();
assert_eq!(stats.active_connections, 1);
assert_eq!(stats.pending_connections, 1);
let now = Instant::now();
let packets = router
.process_timer_events(&cx, now)
.await
.expect("timer processing should succeed");
assert!(packets.is_empty());
router
.remove_connection(&cx, connection_id)
.expect("connection removal should succeed");
assert_eq!(router.connection_stats().active_connections, 0);
});
}
#[test]
fn test_timer_scheduler_deadline_management() {
run_test_with_cx(|cx| async move {
let mut scheduler = QuicTimerScheduler::new();
assert!(!scheduler.has_pending_timer());
assert_eq!(scheduler.current_deadline(), None);
let deadline1 = Instant::now() + Duration::from_millis(100);
scheduler
.schedule_timer(&cx, deadline1)
.await
.expect("timer scheduling should succeed");
assert!(scheduler.has_pending_timer());
assert_eq!(scheduler.current_deadline(), Some(deadline1));
let deadline2 = Instant::now() + Duration::from_millis(50);
scheduler
.schedule_timer(&cx, deadline2)
.await
.expect("timer rescheduling should succeed");
assert!(scheduler.has_pending_timer());
assert_eq!(scheduler.current_deadline(), Some(deadline2));
let deadline3 = Instant::now() + Duration::from_millis(200);
scheduler
.schedule_timer(&cx, deadline3)
.await
.expect("timer scheduling should succeed");
assert_eq!(scheduler.current_deadline(), Some(deadline2));
});
}
#[test]
fn test_endpoint_configuration_validation() {
run_test_with_cx(|cx| async move {
let test_cases = vec![
ManagedEndpointConfig {
max_connections: 0,
..ManagedEndpointConfig::default()
},
ManagedEndpointConfig {
packet_batch_size: 0,
..ManagedEndpointConfig::default()
},
];
for config in test_cases {
let result =
ManagedQuicEndpoint::bind(&cx, "127.0.0.1:0".parse().unwrap(), config).await;
assert!(result.is_err(), "Expected configuration validation to fail");
}
let valid_config = ManagedEndpointConfig::default();
let endpoint =
ManagedQuicEndpoint::bind(&cx, "127.0.0.1:0".parse().unwrap(), valid_config)
.await
.expect("valid configuration should succeed");
assert_ne!(endpoint.local_addr().port(), 0);
});
}
#[test]
fn test_endpoint_stats_and_metrics() {
run_test_with_cx(|cx| async move {
let config = ManagedEndpointConfig {
max_connections: 100,
packet_batch_size: 16,
is_server: true,
..ManagedEndpointConfig::default()
};
let endpoint = ManagedQuicEndpoint::bind(&cx, "127.0.0.1:0".parse().unwrap(), config)
.await
.expect("endpoint creation should succeed");
let stats = endpoint.connection_stats();
assert_eq!(stats.active_connections, 0);
assert_eq!(stats.established_connections, 0);
assert_eq!(stats.pending_connections, 0);
assert!(endpoint.endpoint_id() > 0);
let addr = endpoint.local_addr();
assert_eq!(addr.ip().to_string(), "127.0.0.1");
assert!(addr.port() > 0);
});
}
#[test]
fn test_connection_id_routing_behavior() {
run_test_with_cx(|cx| async move {
let config = NativeQuicConnectionConfig::default();
let mut router = ConnectionRouter::new(config);
let mut allocated_ids = std::collections::HashSet::new();
for _ in 0..10 {
let id = router.allocate_connection_id();
assert!(allocated_ids.insert(id), "Connection IDs should be unique");
}
for id in &allocated_ids {
let peer_addr: SocketAddr = "10.0.0.1:8080".parse().unwrap();
router
.create_connection(&cx, *id, peer_addr, false)
.await
.expect("connection creation should succeed");
}
let stats = router.connection_stats();
assert_eq!(stats.active_connections, allocated_ids.len());
for id in allocated_ids {
router
.remove_connection(&cx, id)
.expect("connection removal should succeed");
}
assert_eq!(router.connection_stats().active_connections, 0);
});
}
#[test]
fn test_integration_with_real_socket_addresses() {
run_test_with_cx(|cx| async move {
let ipv4_config = ManagedEndpointConfig::default();
let ipv4_endpoint =
ManagedQuicEndpoint::bind(&cx, "127.0.0.1:0".parse().unwrap(), ipv4_config)
.await
.expect("IPv4 endpoint should bind successfully");
assert!(ipv4_endpoint.local_addr().is_ipv4());
let ipv6_config = ManagedEndpointConfig::default();
if let Ok(ipv6_endpoint) =
ManagedQuicEndpoint::bind(&cx, "[::1]:0".parse().unwrap(), ipv6_config).await
{
assert!(ipv6_endpoint.local_addr().is_ipv6());
}
let specific_port = 19841; let port_config = ManagedEndpointConfig::default();
if let Ok(port_endpoint) = ManagedQuicEndpoint::bind(
&cx,
format!("127.0.0.1:{specific_port}").parse().unwrap(),
port_config,
)
.await
{
assert_eq!(port_endpoint.local_addr().port(), specific_port);
}
});
}
}