//! Infrastructure Health Smoke Tests //! //! Tests to validate that core infrastructure services are available and functional. //! These tests run first to ensure the foundation is solid before testing application services. use super::common::*; #[tokio::test] async fn test_postgres_connection() { let result = with_timeout(async { let pool = sqlx::PgPool::connect(&database_url()) .await .map_err(|e| Box::new(e) as Box)?; // Verify database is responsive let row: (i32,) = sqlx::query_as("SELECT 1") .fetch_one(&pool) .await .map_err(|e| Box::new(e) as Box)?; assert_eq!(row.0, 1, "Database query returned unexpected value"); // Check TimescaleDB extension let has_timescale: (bool,) = sqlx::query_as( "SELECT COUNT(*) > 0 FROM pg_extension WHERE extname = 'timescaledb'" ) .fetch_one(&pool) .await .map_err(|e| Box::new(e) as Box)?; pool.close().await; println!("✅ PostgreSQL connection successful (TimescaleDB: {})", has_timescale.0); Ok(()) }).await; skip_if_unavailable!("PostgreSQL", { result }); } #[tokio::test] async fn test_postgres_schema_exists() { let result = with_timeout(async { let pool = sqlx::PgPool::connect(&database_url()) .await .map_err(|e| Box::new(e) as Box)?; // Check for key tables let tables = vec!["orders", "positions", "market_data", "audit_log"]; for table in tables { let exists: (bool,) = sqlx::query_as( "SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = $1)" ) .bind(table) .fetch_one(&pool) .await .map_err(|e| Box::new(e) as Box)?; assert!(exists.0, "Table '{}' does not exist", table); println!(" ✓ Table '{}' exists", table); } pool.close().await; println!("✅ PostgreSQL schema validation successful"); Ok(()) }).await; skip_if_unavailable!("PostgreSQL", { result }); } #[tokio::test] async fn test_redis_connection() { let result = with_timeout(async { use redis::AsyncCommands; let client = redis::Client::open(redis_url().as_str()) .map_err(|e| Box::new(e) as Box)?; let mut con = client.get_multiplexed_async_connection() .await .map_err(|e| Box::new(e) as Box)?; // Test PING let pong: String = redis::cmd("PING") .query_async(&mut con) .await .map_err(|e| Box::new(e) as Box)?; assert_eq!(pong, "PONG", "Redis PING returned unexpected value"); // Test SET/GET let test_key = "smoke_test:redis_health"; let test_value = "healthy"; con.set::<_, _, ()>(test_key, test_value) .await .map_err(|e| Box::new(e) as Box)?; let retrieved: String = con.get(test_key) .await .map_err(|e| Box::new(e) as Box)?; assert_eq!(retrieved, test_value, "Redis GET returned unexpected value"); // Cleanup con.del::<_, ()>(test_key) .await .map_err(|e| Box::new(e) as Box)?; println!("✅ Redis connection and operations successful"); Ok(()) }).await; skip_if_unavailable!("Redis", { result }); } #[tokio::test] async fn test_vault_connectivity() { let result = with_timeout(async { let client = reqwest::Client::new(); let vault_url = vault_url(); // Test Vault health endpoint let response = client .get(format!("{}/v1/sys/health", vault_url)) .send() .await .map_err(|e| Box::new(e) as Box)?; // Vault health returns 200 (initialized and unsealed), 429 (unsealed and standby), // 472 (data recovery mode), 473 (performance standby), or 501 (not initialized) let status = response.status(); assert!( status == 200 || status == 429 || status == 473, "Vault health check returned unexpected status: {}", status ); println!("✅ Vault connectivity successful (status: {})", status); Ok(()) }).await; skip_if_unavailable!("Vault", { result }); } #[tokio::test] async fn test_influxdb_connectivity() { let result = with_timeout(async { let client = reqwest::Client::new(); let influxdb_url = influxdb_url(); // Test InfluxDB ping endpoint let response = client .get(format!("{}/ping", influxdb_url)) .send() .await .map_err(|e| Box::new(e) as Box)?; assert!( response.status().is_success(), "InfluxDB ping failed with status: {}", response.status() ); println!("✅ InfluxDB connectivity successful"); Ok(()) }).await; skip_if_unavailable!("InfluxDB", { result }); } #[tokio::test] async fn test_prometheus_connectivity() { let result = with_timeout(async { let client = reqwest::Client::new(); let prometheus_url = prometheus_url(); // Test Prometheus health endpoint let response = client .get(format!("{}/-/healthy", prometheus_url)) .send() .await .map_err(|e| Box::new(e) as Box)?; assert!( response.status().is_success(), "Prometheus health check failed with status: {}", response.status() ); println!("✅ Prometheus connectivity successful"); Ok(()) }).await; skip_if_unavailable!("Prometheus", { result }); } #[tokio::test] async fn test_grafana_connectivity() { let result = with_timeout(async { let client = reqwest::Client::new(); let grafana_url = grafana_url(); // Test Grafana API health endpoint let response = client .get(format!("{}/api/health", grafana_url)) .send() .await .map_err(|e| Box::new(e) as Box)?; assert!( response.status().is_success(), "Grafana health check failed with status: {}", response.status() ); println!("✅ Grafana connectivity successful"); Ok(()) }).await; skip_if_unavailable!("Grafana", { result }); } #[tokio::test] async fn test_infrastructure_all_healthy() { println!("🏥 Running comprehensive infrastructure health check..."); let mut checks_passed = 0; let mut checks_failed = 0; // PostgreSQL match sqlx::PgPool::connect(&database_url()).await { Ok(pool) => { pool.close().await; println!(" ✓ PostgreSQL"); checks_passed += 1; } Err(e) => { eprintln!(" ✗ PostgreSQL: {}", e); checks_failed += 1; } } // Redis match redis::Client::open(redis_url().as_str()) { Ok(client) => { match client.get_multiplexed_async_connection().await { Ok(_) => { println!(" ✓ Redis"); checks_passed += 1; } Err(e) => { eprintln!(" ✗ Redis: {}", e); checks_failed += 1; } } } Err(e) => { eprintln!(" ✗ Redis: {}", e); checks_failed += 1; } } // Vault (optional - don't fail if unavailable) let client = reqwest::Client::new(); match client.get(format!("{}/v1/sys/health", vault_url())).send().await { Ok(response) if response.status() == 200 || response.status() == 429 => { println!(" ✓ Vault"); checks_passed += 1; } _ => { println!(" ⚠ Vault (not critical)"); } } // InfluxDB (optional - don't fail if unavailable) match client.get(format!("{}/ping", influxdb_url())).send().await { Ok(response) if response.status().is_success() => { println!(" ✓ InfluxDB"); checks_passed += 1; } _ => { println!(" ⚠ InfluxDB (not critical)"); } } println!("\n📊 Infrastructure Health Summary:"); println!(" Passed: {}", checks_passed); println!(" Failed: {}", checks_failed); // Require at least PostgreSQL and Redis assert!(checks_passed >= 2, "Critical infrastructure services are down"); println!("✅ Infrastructure health check complete"); }