- Workspace Cargo.toml: remove web-gateway + api_gateway members, keep api - trading_service: dep api-gateway → api, update test imports - testing/api-gateway-load → testing/api-load (crate renamed) - All test crates: get_api_gateway_addr → get_api_addr + variable renames Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
136 lines
4.7 KiB
Rust
136 lines
4.7 KiB
Rust
//! Smoke Tests - End-to-End System Validation
|
|
//!
|
|
//! Automated smoke tests to validate complete system functionality after deployment.
|
|
//! Tests are organized by category and can run selectively based on service availability.
|
|
//!
|
|
//! ## Test Categories
|
|
//! - Infrastructure Health (PostgreSQL, Redis, Vault, InfluxDB)
|
|
//! - Service Health (API Gateway, Trading, Backtesting, ML Training)
|
|
//! - Authentication Flow (JWT, MFA, Session Management)
|
|
//! - Basic Order Flow (Submit, Query, Cancel, Positions)
|
|
//! - Market Data (Streaming, Historical Queries)
|
|
//! - ML Inference (Predictions, Feature Engineering)
|
|
//! - Compliance (Audit Logs, Best Execution, Risk Checks)
|
|
//! - Metrics and Monitoring (Prometheus, Grafana)
|
|
//!
|
|
//! ## Usage
|
|
//! ```bash
|
|
//! # Run all smoke tests
|
|
//! cargo test --test smoke_tests
|
|
//!
|
|
//! # Run specific category
|
|
//! cargo test --test smoke_tests infrastructure_health
|
|
//! cargo test --test smoke_tests service_health
|
|
//! cargo test --test smoke_tests basic_order_flow
|
|
//!
|
|
//! # Run with logging
|
|
//! RUST_LOG=debug cargo test --test smoke_tests -- --nocapture
|
|
//! ```
|
|
|
|
pub mod infrastructure_health;
|
|
pub mod service_health;
|
|
pub mod authentication_flow;
|
|
pub mod basic_order_flow;
|
|
|
|
/// Common test utilities and helpers
|
|
pub mod common {
|
|
use std::time::Duration;
|
|
use tokio::time::timeout;
|
|
|
|
/// Standard timeout for smoke tests (10 seconds)
|
|
pub const SMOKE_TEST_TIMEOUT: Duration = Duration::from_secs(10);
|
|
|
|
/// Standard timeout for infrastructure checks (5 seconds)
|
|
pub const INFRA_TEST_TIMEOUT: Duration = Duration::from_secs(5);
|
|
|
|
/// Load database URL from environment
|
|
pub fn database_url() -> String {
|
|
std::env::var("DATABASE_URL")
|
|
.unwrap_or_else(|_| "postgresql://foxhunt:foxhunt_dev_password@localhost:5432/foxhunt".to_string())
|
|
}
|
|
|
|
/// Load Redis URL from environment
|
|
pub fn redis_url() -> String {
|
|
std::env::var("REDIS_URL")
|
|
.unwrap_or_else(|_| "redis://localhost:6379".to_string())
|
|
}
|
|
|
|
/// Load Vault URL from environment
|
|
pub fn vault_url() -> String {
|
|
std::env::var("VAULT_ADDR")
|
|
.unwrap_or_else(|_| "http://localhost:8200".to_string())
|
|
}
|
|
|
|
/// Load InfluxDB URL from environment
|
|
pub fn influxdb_url() -> String {
|
|
std::env::var("INFLUXDB_URL")
|
|
.unwrap_or_else(|_| "http://localhost:8086".to_string())
|
|
}
|
|
|
|
/// Load API Gateway URL from environment
|
|
pub fn api_url() -> String {
|
|
std::env::var("API_GATEWAY_URL")
|
|
.unwrap_or_else(|_| "http://localhost:50051".to_string())
|
|
}
|
|
|
|
/// Load Trading Service URL from environment
|
|
pub fn trading_service_url() -> String {
|
|
std::env::var("TRADING_SERVICE_URL")
|
|
.unwrap_or_else(|_| "http://localhost:50052".to_string())
|
|
}
|
|
|
|
/// Load Backtesting Service URL from environment
|
|
pub fn backtesting_service_url() -> String {
|
|
std::env::var("BACKTESTING_SERVICE_URL")
|
|
.unwrap_or_else(|_| "http://localhost:50053".to_string())
|
|
}
|
|
|
|
/// Load ML Training Service URL from environment
|
|
pub fn ml_training_service_url() -> String {
|
|
std::env::var("ML_TRAINING_SERVICE_URL")
|
|
.unwrap_or_else(|_| "http://localhost:50054".to_string())
|
|
}
|
|
|
|
/// Load Prometheus URL from environment
|
|
pub fn prometheus_url() -> String {
|
|
std::env::var("PROMETHEUS_URL")
|
|
.unwrap_or_else(|_| "http://localhost:9090".to_string())
|
|
}
|
|
|
|
/// Load Grafana URL from environment
|
|
pub fn grafana_url() -> String {
|
|
std::env::var("GRAFANA_URL")
|
|
.unwrap_or_else(|_| "http://localhost:3000".to_string())
|
|
}
|
|
|
|
/// Run a test with timeout
|
|
pub async fn with_timeout<F, T>(future: F) -> Result<T, Box<dyn std::error::Error>>
|
|
where
|
|
F: std::future::Future<Output = Result<T, Box<dyn std::error::Error>>>,
|
|
{
|
|
match timeout(SMOKE_TEST_TIMEOUT, future).await {
|
|
Ok(result) => result,
|
|
Err(_) => Err("Test timed out after 10 seconds".into()),
|
|
}
|
|
}
|
|
|
|
/// Skip test if service is not available
|
|
///
|
|
/// This allows tests to be skipped gracefully when services are down
|
|
#[macro_export]
|
|
macro_rules! skip_if_unavailable {
|
|
($service:expr, $test:block) => {
|
|
match $test {
|
|
Ok(result) => result,
|
|
Err(e) if e.to_string().contains("connection refused") ||
|
|
e.to_string().contains("connection reset") ||
|
|
e.to_string().contains("timed out") => {
|
|
eprintln!("⏭️ Skipping test - {} not available: {}", $service, e);
|
|
return;
|
|
}
|
|
Err(e) => panic!("Test failed: {}", e),
|
|
}
|
|
};
|
|
}
|
|
}
|