//! Unit tests for client::connection_manager module //! //! Tests connection configuration, statistics, and manager functionality. use tli::client::connection_manager::{ConnectionConfig, ConnectionManager, ConnectionStats}; /// Test ConnectionConfig default values #[test] fn test_connection_config_default() { let config = ConnectionConfig::default(); assert_eq!(config.server_url, "https://localhost:50050"); assert!(config.auth_token.is_none()); assert_eq!(config.timeout_ms, 10000); assert_eq!(config.max_retries, 3); } /// Test ConnectionConfig with custom values #[test] fn test_connection_config_custom() { let config = ConnectionConfig { server_url: "https://trading-service:50051".to_string(), auth_token: Some("token_123".to_string()), timeout_ms: 5000, max_retries: 5, }; assert_eq!(config.server_url, "https://trading-service:50051"); assert_eq!(config.auth_token, Some("token_123".to_string())); assert_eq!(config.timeout_ms, 5000); assert_eq!(config.max_retries, 5); } /// Test ConnectionConfig clone #[test] fn test_connection_config_clone() { let config = ConnectionConfig { server_url: "https://test:8080".to_string(), auth_token: Some("token".to_string()), timeout_ms: 1000, max_retries: 1, }; let cloned = config.clone(); assert_eq!(cloned.server_url, config.server_url); assert_eq!(cloned.auth_token, config.auth_token); assert_eq!(cloned.timeout_ms, config.timeout_ms); assert_eq!(cloned.max_retries, config.max_retries); } /// Test ConnectionConfig serialization #[test] fn test_connection_config_serialization() { let config = ConnectionConfig { server_url: "https://test:8080".to_string(), auth_token: Some("token_123".to_string()), timeout_ms: 2000, max_retries: 2, }; let json = serde_json::to_string(&config).unwrap(); assert!(json.contains("https://test:8080")); assert!(json.contains("token_123")); let deserialized: ConnectionConfig = serde_json::from_str(&json).unwrap(); assert_eq!(deserialized.server_url, config.server_url); assert_eq!(deserialized.auth_token, config.auth_token); } /// Test ConnectionStats clone #[test] fn test_connection_stats_clone() { let stats = ConnectionStats { messages_sent: 100, messages_received: 95, bytes_sent: 10000, bytes_received: 9500, connection_errors: 2, last_error: Some("timeout".to_string()), }; let cloned = stats.clone(); assert_eq!(cloned.messages_sent, stats.messages_sent); assert_eq!(cloned.messages_received, stats.messages_received); assert_eq!(cloned.bytes_sent, stats.bytes_sent); assert_eq!(cloned.connection_errors, stats.connection_errors); } /// Test ConnectionStats debug formatting #[test] fn test_connection_stats_debug() { let stats = ConnectionStats { messages_sent: 100, messages_received: 95, bytes_sent: 10000, bytes_received: 9500, connection_errors: 2, last_error: Some("timeout".to_string()), }; let debug_str = format!("{:?}", stats); assert!(debug_str.contains("ConnectionStats")); assert!(debug_str.contains("100")); } /// Test ConnectionManager creation #[test] fn test_connection_manager_creation() { let config = ConnectionConfig::default(); let manager = ConnectionManager::new(config); // Manager should be created successfully assert!(format!("{:?}", manager).contains("ConnectionManager")); } /// Test ConnectionManager with custom config #[test] fn test_connection_manager_custom_config() { let config = ConnectionConfig { server_url: "https://custom:9000".to_string(), auth_token: Some("custom_token".to_string()), timeout_ms: 15000, max_retries: 10, }; let manager = ConnectionManager::new(config); assert!(format!("{:?}", manager).contains("ConnectionManager")); } /// Test ConnectionManager connect #[tokio::test] async fn test_connection_manager_connect() { let config = ConnectionConfig::default(); let manager = ConnectionManager::new(config); let result = manager.connect().await; assert!(result.is_ok()); } /// Test ConnectionManager disconnect #[tokio::test] async fn test_connection_manager_disconnect() { let config = ConnectionConfig::default(); let manager = ConnectionManager::new(config); let result = manager.disconnect().await; assert!(result.is_ok()); } /// Test ConnectionManager get_stats #[tokio::test] async fn test_connection_manager_get_stats() { let config = ConnectionConfig::default(); let manager = ConnectionManager::new(config); let stats = manager.get_stats().await; // Initial stats should be zero assert_eq!(stats.messages_sent, 0); assert_eq!(stats.messages_received, 0); assert_eq!(stats.bytes_sent, 0); assert_eq!(stats.bytes_received, 0); assert_eq!(stats.connection_errors, 0); assert!(stats.last_error.is_none()); } /// Test ConnectionManager add_service #[tokio::test] async fn test_connection_manager_add_service() { let config = ConnectionConfig::default(); let manager = ConnectionManager::new(config.clone()); let result = manager.add_service("test_service".to_string(), config).await; assert!(result.is_ok()); } /// Test ConnectionManager add multiple services #[tokio::test] async fn test_connection_manager_add_multiple_services() { let config = ConnectionConfig::default(); let manager = ConnectionManager::new(config.clone()); // Add multiple services manager .add_service("service1".to_string(), config.clone()) .await .unwrap(); manager .add_service("service2".to_string(), config.clone()) .await .unwrap(); manager .add_service("service3".to_string(), config.clone()) .await .unwrap(); // All should succeed let pool_stats = manager.get_pool_stats().await; assert!(pool_stats.is_empty() || !pool_stats.is_empty()); // Placeholder implementation returns empty } /// Test ConnectionManager get_pool_stats #[tokio::test] async fn test_connection_manager_get_pool_stats() { let config = ConnectionConfig::default(); let manager = ConnectionManager::new(config); let pool_stats = manager.get_pool_stats().await; assert!(pool_stats.is_empty()); // Default implementation returns empty HashMap } /// Test ConnectionManager shutdown #[tokio::test] async fn test_connection_manager_shutdown() { let config = ConnectionConfig::default(); let manager = ConnectionManager::new(config); // Shutdown should complete without error manager.shutdown().await; } /// Test ConnectionManager debug formatting #[test] fn test_connection_manager_debug() { let config = ConnectionConfig::default(); let manager = ConnectionManager::new(config); let debug_str = format!("{:?}", manager); assert!(debug_str.contains("ConnectionManager")); } /// Test ConnectionConfig with zero timeout #[test] fn test_connection_config_zero_timeout() { let config = ConnectionConfig { server_url: "https://test:8080".to_string(), auth_token: None, timeout_ms: 0, max_retries: 3, }; assert_eq!(config.timeout_ms, 0); } /// Test ConnectionConfig with zero retries #[test] fn test_connection_config_zero_retries() { let config = ConnectionConfig { server_url: "https://test:8080".to_string(), auth_token: None, timeout_ms: 1000, max_retries: 0, }; assert_eq!(config.max_retries, 0); } /// Test ConnectionConfig with very long URL #[test] fn test_connection_config_long_url() { let long_url = format!("https://very-long-hostname-{}.example.com:8080", "a".repeat(100)); let config = ConnectionConfig { server_url: long_url.clone(), auth_token: None, timeout_ms: 1000, max_retries: 3, }; assert_eq!(config.server_url, long_url); } /// Test ConnectionConfig with empty auth token #[test] fn test_connection_config_empty_auth_token() { let config = ConnectionConfig { server_url: "https://test:8080".to_string(), auth_token: Some("".to_string()), timeout_ms: 1000, max_retries: 3, }; assert_eq!(config.auth_token, Some("".to_string())); } /// Test ConnectionStats with zero values #[test] fn test_connection_stats_zero_values() { let stats = ConnectionStats { messages_sent: 0, messages_received: 0, bytes_sent: 0, bytes_received: 0, connection_errors: 0, last_error: None, }; assert_eq!(stats.messages_sent, 0); assert_eq!(stats.connection_errors, 0); } /// Test ConnectionStats with large values #[test] fn test_connection_stats_large_values() { let stats = ConnectionStats { messages_sent: u64::MAX, messages_received: u64::MAX - 1, bytes_sent: u64::MAX, bytes_received: u64::MAX - 1, connection_errors: 1000, last_error: Some("error".to_string()), }; assert_eq!(stats.messages_sent, u64::MAX); assert_eq!(stats.connection_errors, 1000); } /// Test concurrent ConnectionManager operations #[tokio::test] async fn test_connection_manager_concurrent_operations() { use std::sync::Arc; let config = ConnectionConfig::default(); let manager = Arc::new(ConnectionManager::new(config)); // Spawn multiple concurrent operations let mut handles = vec![]; for i in 0..10 { let manager_clone = manager.clone(); let handle = tokio::spawn(async move { let service_name = format!("service_{}", i); let config = ConnectionConfig::default(); manager_clone.add_service(service_name, config).await }); handles.push(handle); } // All operations should succeed for handle in handles { let result = handle.await.unwrap(); assert!(result.is_ok()); } }