use rhttpd::{config::ServerConfig, server::ProxyServer}; use std::collections::HashMap; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use tokio::net::TcpListener; #[tokio::test] async fn test_static_file_serving() { // Create test configuration let mut sites = HashMap::new(); sites.insert( "test.com".to_string(), rhttpd::config::SiteConfig { hostname: "test.com".to_string(), routes: vec![rhttpd::config::RouteRule::Static { path_pattern: "/*".to_string(), root: std::path::PathBuf::from("./public"), index: Some(vec!["index.html".to_string()]), directory_listing: Some(false), }], tls: None, }, ); let config = ServerConfig { port: 8081, sites, js_config: None, connection_pool: None, health_check: None, }; let server = ProxyServer::new(config); // Test that server can be created assert_eq!(server.config.port, 8081); } #[tokio::test] async fn test_config_loading() { // Test loading a valid TOML config let config_result = ServerConfig::from_file("config.toml"); assert!(config_result.is_ok()); let config = config_result.unwrap(); assert_eq!(config.port, 8080); assert!(config.sites.contains_key("example.com")); } #[tokio::test] async fn test_connection_pool() { use rhttpd::proxy::connection_pool::ConnectionPool; let pool = ConnectionPool::new(10, std::time::Duration::from_secs(90)); let result = pool.get_connection("test.example.com").await; assert!(result.is_ok()); let stats = pool.get_pool_stats().await; assert_eq!(stats.total_connections, 1); } #[tokio::test] async fn test_load_balancer() { use rhttpd::proxy::load_balancer::{LoadBalancer, LoadBalancerStrategy}; let upstreams = vec![ "http://backend1:3000".to_string(), "http://backend2:3000".to_string(), ]; let lb = LoadBalancer::new(LoadBalancerStrategy::RoundRobin, upstreams); let upstream = lb.select_upstream().await; assert!(upstream.is_some()); let stats = lb.get_stats().await; assert_eq!(stats.total_upstreams, 2); } #[tokio::test] async fn test_tcp_proxy() { use rhttpd::proxy::tcp_proxy::TcpProxyManager; let _manager = TcpProxyManager::new(); let listener = TcpListener::bind("127.0.0.1:0").await.unwrap(); let local_addr = listener.local_addr().unwrap(); let target_addr = format!("{}:{}", local_addr.ip(), local_addr.port()); tokio::spawn(async move { if let Ok((mut stream, _)) = listener.accept().await { let mut buf = [0u8; 1024]; if let Ok(_n) = stream.read(&mut buf).await { let _ = stream.write_all(b"Hello from server").await; } } }); tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; let mut test_stream = tokio::net::TcpStream::connect(&target_addr).await.unwrap(); let _ = test_stream.write_all(b"Hello from client").await; tokio::time::sleep(tokio::time::Duration::from_millis(100)).await; } #[tokio::test] async fn test_tcp_proxy_manager_stats() { use rhttpd::proxy::tcp_proxy::TcpProxyManager; let _manager = TcpProxyManager::new(); let _manager_clone = TcpProxyManager::new(); let stats = _manager_clone.get_stats().await; assert_eq!(stats.len(), 0); _manager .cleanup_expired(std::time::Duration::from_secs(0)) .await; }