Files
foxhunt/testing/integration/smoke_tests/mod.rs
jgrusewski d25c82f8f3 refactor: rename api_gateway → api across workspace, tests, and load crate
- 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>
2026-03-04 23:38:21 +01:00

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),
}
};
}
}