//! Unit tests for client builder and factory //! //! Tests TliClientBuilder, ClientFactory, and TliClientSuite. use tli::client::{ TliClientBuilder, ClientFactory, ServiceEndpoints, connection_manager::ConnectionConfig, trading_client::TradingClientConfig, backtesting_client::BacktestingClientConfig, ml_training_client::MLTrainingClientConfig, }; /// Test ServiceEndpoints localhost defaults #[test] fn test_service_endpoints_localhost() { let endpoints = ServiceEndpoints::localhost(); assert_eq!(endpoints.trading_engine, "https://localhost:50050"); assert_eq!(endpoints.market_data, "https://localhost:50050"); assert_eq!(endpoints.backtesting_service, "https://localhost:50050"); assert_eq!(endpoints.ml_training_service, "https://localhost:50050"); } /// Test ServiceEndpoints default #[test] fn test_service_endpoints_default() { let endpoints = ServiceEndpoints::default(); // All fields should be empty strings assert_eq!(endpoints.trading_engine, ""); assert_eq!(endpoints.market_data, ""); assert_eq!(endpoints.backtesting_service, ""); assert_eq!(endpoints.ml_training_service, ""); } /// Test ServiceEndpoints clone #[test] fn test_service_endpoints_clone() { let endpoints = ServiceEndpoints::localhost(); let cloned = endpoints.clone(); assert_eq!(cloned.trading_engine, endpoints.trading_engine); assert_eq!(cloned.market_data, endpoints.market_data); } /// Test ServiceEndpoints serialization #[test] fn test_service_endpoints_serialization() { let endpoints = ServiceEndpoints::localhost(); let json = serde_json::to_string(&endpoints).unwrap(); let deserialized: ServiceEndpoints = serde_json::from_str(&json).unwrap(); assert_eq!(deserialized.trading_engine, endpoints.trading_engine); } /// Test ClientFactory creation #[test] fn test_client_factory_creation() { let config = ConnectionConfig::default(); let factory = ClientFactory::new(config); assert!(format!("{:?}", factory).contains("ClientFactory")); } /// Test ClientFactory create_trading_client #[test] fn test_client_factory_create_trading_client() { let config = ConnectionConfig::default(); let factory = ClientFactory::new(config); let trading_config = TradingClientConfig::default(); let _client = factory.create_trading_client(trading_config); // Client should be created successfully } /// Test ClientFactory create_backtesting_client #[test] fn test_client_factory_create_backtesting_client() { let config = ConnectionConfig::default(); let factory = ClientFactory::new(config); let backtesting_config = BacktestingClientConfig::default(); let _client = factory.create_backtesting_client(backtesting_config); // Client should be created successfully } /// Test ClientFactory create_ml_training_client #[test] fn test_client_factory_create_ml_training_client() { let config = ConnectionConfig::default(); let factory = ClientFactory::new(config); let ml_config = MLTrainingClientConfig::default(); let _client = factory.create_ml_training_client(ml_config); // Client should be created successfully } /// Test TliClientBuilder creation #[test] fn test_tli_client_builder_new() { let builder = TliClientBuilder::new(); // Builder should have default state assert!(format!("{:?}", builder).contains("TliClientBuilder")); } /// Test TliClientBuilder default #[test] fn test_tli_client_builder_default() { let builder = TliClientBuilder::default(); assert!(format!("{:?}", builder).contains("TliClientBuilder")); } /// Test TliClientBuilder with_connection_config #[test] fn test_tli_client_builder_with_connection_config() { let config = ConnectionConfig { server_url: "https://custom:8080".to_string(), auth_token: Some("token".to_string()), timeout_ms: 5000, max_retries: 5, }; let builder = TliClientBuilder::new().with_connection_config(config); assert!(format!("{:?}", builder).contains("TliClientBuilder")); } /// Test TliClientBuilder with_service_endpoint #[test] fn test_tli_client_builder_with_service_endpoint() { let builder = TliClientBuilder::new() .with_service_endpoint("trading".to_string(), "https://trading:50051".to_string()); assert!(format!("{:?}", builder).contains("TliClientBuilder")); } /// Test TliClientBuilder with multiple service endpoints #[test] fn test_tli_client_builder_multiple_endpoints() { let builder = TliClientBuilder::new() .with_service_endpoint("trading".to_string(), "https://trading:50051".to_string()) .with_service_endpoint("backtesting".to_string(), "https://backtesting:50052".to_string()) .with_service_endpoint("ml".to_string(), "https://ml:50053".to_string()); assert!(format!("{:?}", builder).contains("TliClientBuilder")); } /// Test TliClientBuilder with_trading_config #[test] fn test_tli_client_builder_with_trading_config() { let trading_config = TradingClientConfig::default(); let builder = TliClientBuilder::new().with_trading_config(trading_config); assert!(format!("{:?}", builder).contains("TliClientBuilder")); } /// Test TliClientBuilder with_backtesting_config #[test] fn test_tli_client_builder_with_backtesting_config() { let backtesting_config = BacktestingClientConfig::default(); let builder = TliClientBuilder::new().with_backtesting_config(backtesting_config); assert!(format!("{:?}", builder).contains("TliClientBuilder")); } /// Test TliClientBuilder with_ml_training_config #[test] fn test_tli_client_builder_with_ml_training_config() { let ml_config = MLTrainingClientConfig::default(); let builder = TliClientBuilder::new().with_ml_training_config(ml_config); assert!(format!("{:?}", builder).contains("TliClientBuilder")); } /// Test TliClientBuilder chaining multiple configs #[test] fn test_tli_client_builder_chaining() { let builder = TliClientBuilder::new() .with_connection_config(ConnectionConfig::default()) .with_service_endpoint("trading".to_string(), "https://trading:50051".to_string()) .with_trading_config(TradingClientConfig::default()) .with_backtesting_config(BacktestingClientConfig::default()) .with_ml_training_config(MLTrainingClientConfig::default()); assert!(format!("{:?}", builder).contains("TliClientBuilder")); } /// Test ServiceEndpoints with custom values #[test] fn test_service_endpoints_custom() { let endpoints = ServiceEndpoints { trading_engine: "https://trading.example.com:50051".to_string(), market_data: "https://market-data.example.com:50052".to_string(), backtesting_service: "https://backtesting.example.com:50053".to_string(), ml_training_service: "https://ml.example.com:50054".to_string(), }; assert_eq!(endpoints.trading_engine, "https://trading.example.com:50051"); assert_eq!(endpoints.market_data, "https://market-data.example.com:50052"); } /// Test ServiceEndpoints debug formatting #[test] fn test_service_endpoints_debug() { let endpoints = ServiceEndpoints::localhost(); let debug_str = format!("{:?}", endpoints); assert!(debug_str.contains("ServiceEndpoints")); } /// Test ClientFactory add_service #[tokio::test] async fn test_client_factory_add_service() { let config = ConnectionConfig::default(); let factory = ClientFactory::new(config.clone()); let result = factory.add_service("test_service".to_string(), config).await; assert!(result.is_ok()); } /// Test ClientFactory get_connection_stats #[tokio::test] async fn test_client_factory_get_connection_stats() { let config = ConnectionConfig::default(); let factory = ClientFactory::new(config); let stats = factory.get_connection_stats().await; assert!(stats.is_empty()); // Default implementation returns empty } /// Test ClientFactory shutdown #[tokio::test] async fn test_client_factory_shutdown() { let config = ConnectionConfig::default(); let factory = ClientFactory::new(config); // Should complete without error factory.shutdown().await; } /// Test ClientFactory debug formatting #[test] fn test_client_factory_debug() { let config = ConnectionConfig::default(); let factory = ClientFactory::new(config); let debug_str = format!("{:?}", factory); assert!(debug_str.contains("ClientFactory")); } /// Test ServiceEndpoints with empty strings #[test] fn test_service_endpoints_empty() { let endpoints = ServiceEndpoints { trading_engine: "".to_string(), market_data: "".to_string(), backtesting_service: "".to_string(), ml_training_service: "".to_string(), }; assert!(endpoints.trading_engine.is_empty()); assert!(endpoints.market_data.is_empty()); } /// Test ServiceEndpoints round-trip serialization #[test] fn test_service_endpoints_roundtrip() { let original = ServiceEndpoints::localhost(); let json = serde_json::to_string(&original).unwrap(); let deserialized: ServiceEndpoints = serde_json::from_str(&json).unwrap(); assert_eq!(deserialized.trading_engine, original.trading_engine); assert_eq!(deserialized.market_data, original.market_data); assert_eq!(deserialized.backtesting_service, original.backtesting_service); assert_eq!(deserialized.ml_training_service, original.ml_training_service); } /// Test TliClientBuilder with only trading config #[test] fn test_tli_client_builder_trading_only() { let builder = TliClientBuilder::new() .with_service_endpoint("trading".to_string(), "https://trading:50051".to_string()) .with_trading_config(TradingClientConfig::default()); assert!(format!("{:?}", builder).contains("TliClientBuilder")); } /// Test TliClientBuilder with only backtesting config #[test] fn test_tli_client_builder_backtesting_only() { let builder = TliClientBuilder::new() .with_service_endpoint("backtesting".to_string(), "https://backtesting:50052".to_string()) .with_backtesting_config(BacktestingClientConfig::default()); assert!(format!("{:?}", builder).contains("TliClientBuilder")); } /// Test TliClientBuilder with only ml config #[test] fn test_tli_client_builder_ml_only() { let builder = TliClientBuilder::new() .with_service_endpoint("ml".to_string(), "https://ml:50053".to_string()) .with_ml_training_config(MLTrainingClientConfig::default()); assert!(format!("{:?}", builder).contains("TliClientBuilder")); } /// Test ClientFactory with multiple service additions #[tokio::test] async fn test_client_factory_multiple_services() { let config = ConnectionConfig::default(); let factory = ClientFactory::new(config.clone()); // Add multiple services for i in 0..5 { let service_name = format!("service_{}", i); let result = factory.add_service(service_name, config.clone()).await; assert!(result.is_ok()); } } /// Test ClientFactory concurrent service additions #[tokio::test] async fn test_client_factory_concurrent_additions() { use std::sync::Arc; let config = ConnectionConfig::default(); let factory = Arc::new(ClientFactory::new(config.clone())); let mut handles = vec![]; for i in 0..10 { let factory_clone = factory.clone(); let config_clone = config.clone(); let handle = tokio::spawn(async move { let service_name = format!("service_{}", i); factory_clone.add_service(service_name, config_clone).await }); handles.push(handle); } for handle in handles { let result = handle.await.unwrap(); assert!(result.is_ok()); } } /// Test ServiceEndpoints with IPv6 addresses #[test] fn test_service_endpoints_ipv6() { let endpoints = ServiceEndpoints { trading_engine: "https://[::1]:50051".to_string(), market_data: "https://[2001:db8::1]:50052".to_string(), backtesting_service: "https://[::1]:50053".to_string(), ml_training_service: "https://[::1]:50054".to_string(), }; assert!(endpoints.trading_engine.contains("[::1]")); assert!(endpoints.market_data.contains("[2001:db8::1]")); }