**Progress: 1,178 → 57 test errors (95% reduction)** ## Status Summary - ✅ Production code: Compiles cleanly (0 errors) - ⚠️ Test code: 57 errors remain (massive improvement) - ⚙️ All services build successfully - 📊 Warning count: 253 (target: <20) - AGENTS WILL FIX ## Remaining Test Errors (57 total) ### Primary Issues: 1. 23× E0308 mismatched types 2. 17× E0433 undeclared Decimal 3. 15× E0433 compliance module not found 4. 6× E0624 private method access 5. Various import and type issues ## Next Phase: Wave 33-2 Launch 10+ parallel agents to: - Fix remaining 57 test compilation errors - Reduce 253 warnings to <20 - Achieve 95% test coverage - Ensure all tests pass 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
173 lines
5.0 KiB
Rust
173 lines
5.0 KiB
Rust
//! Test Utilities Module
|
|
//!
|
|
//! Comprehensive test utilities for safe, reliable testing patterns
|
|
//! across the Foxhunt HFT trading system.
|
|
|
|
pub mod hft_utils;
|
|
pub mod test_safety;
|
|
|
|
// Re-export commonly used items for convenience (macros are exported at crate root)
|
|
// DO NOT RE-EXPORT - Use explicit imports at usage sites
|
|
|
|
// Note: test_assert and test_assert_eq macros are exported at crate root automatically
|
|
|
|
// DO NOT RE-EXPORT - Use explicit imports at usage sites
|
|
|
|
/// Macro to create a test with automatic error handling and context
|
|
#[macro_export]
|
|
macro_rules! safe_test {
|
|
($test_name:ident, $test_fn:expr) => {
|
|
#[tokio::test]
|
|
async fn $test_name() {
|
|
match $test_fn().await {
|
|
Ok(()) => {},
|
|
Err(e) => {
|
|
panic!("Test {} failed: {}", stringify!($test_name), e);
|
|
},
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
/// Macro to create a property based test
|
|
#[macro_export]
|
|
macro_rules! property_test {
|
|
($test_name:ident, $iterations:expr, $test_fn:expr) => {
|
|
#[tokio::test]
|
|
async fn $test_name() {
|
|
use crate::utils::test_safety::property;
|
|
|
|
match property::run_property_test(stringify!($test_name), $iterations, $test_fn) {
|
|
Ok(()) => {},
|
|
Err(e) => {
|
|
panic!("Property test {} failed: {}", stringify!($test_name), e);
|
|
},
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
/// Macro to create a performance benchmark test
|
|
#[macro_export]
|
|
macro_rules! benchmark_test {
|
|
($test_name:ident, $operation:expr, $max_latency:expr) => {
|
|
#[tokio::test]
|
|
async fn $test_name() {
|
|
use crate::utils::hft_utils::performance;
|
|
use std::time::Duration;
|
|
|
|
let measurements = performance::benchmark_operation(
|
|
$operation,
|
|
10, // warmup iterations
|
|
100, // measurement iterations
|
|
stringify!($test_name),
|
|
)
|
|
.await
|
|
.expect("Benchmark should complete");
|
|
|
|
let avg_latency = measurements.average().expect("Should have measurements");
|
|
let p99_latency = measurements.percentile(0.99).expect("Should have p99");
|
|
|
|
println!(
|
|
"Benchmark {}: avg={:?}, p99={:?}, max={:?}",
|
|
stringify!($test_name),
|
|
avg_latency,
|
|
p99_latency,
|
|
measurements.max().unwrap_or_default()
|
|
);
|
|
|
|
if avg_latency > $max_latency {
|
|
panic!(
|
|
"Benchmark {} failed: average latency {:?} exceeds maximum {:?}",
|
|
stringify!($test_name),
|
|
avg_latency,
|
|
$max_latency
|
|
);
|
|
}
|
|
}
|
|
};
|
|
}
|
|
|
|
/// Test configuration for different environments
|
|
#[derive(Debug, Clone)]
|
|
pub struct TestConfig {
|
|
pub enable_chaos: bool,
|
|
pub chaos_failure_rate: f64,
|
|
pub default_timeout: std::time::Duration,
|
|
pub hft_latency_requirement: std::time::Duration,
|
|
pub enable_performance_validation: bool,
|
|
}
|
|
|
|
impl Default for TestConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
enable_chaos: false,
|
|
chaos_failure_rate: 0.1,
|
|
default_timeout: std::time::Duration::from_secs(30),
|
|
hft_latency_requirement: std::time::Duration::from_micros(50),
|
|
enable_performance_validation: true,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TestConfig {
|
|
pub fn for_unit_tests() -> Self {
|
|
Self {
|
|
enable_chaos: false,
|
|
default_timeout: std::time::Duration::from_secs(5),
|
|
..Default::default()
|
|
}
|
|
}
|
|
|
|
pub fn for_integration_tests() -> Self {
|
|
Self {
|
|
enable_chaos: false,
|
|
default_timeout: std::time::Duration::from_secs(30),
|
|
..Default::default()
|
|
}
|
|
}
|
|
|
|
pub fn for_chaos_tests() -> Self {
|
|
Self {
|
|
enable_chaos: true,
|
|
chaos_failure_rate: 0.2,
|
|
default_timeout: std::time::Duration::from_secs(60),
|
|
..Default::default()
|
|
}
|
|
}
|
|
}
|
|
|
|
/// Global test configuration accessor
|
|
static TEST_CONFIG: std::sync::OnceLock<TestConfig> = std::sync::OnceLock::new();
|
|
|
|
pub fn get_test_config() -> &'static TestConfig {
|
|
TEST_CONFIG.get_or_init(|| {
|
|
std::env::var("TEST_MODE")
|
|
.map(|mode| match mode.as_str() {
|
|
"unit" => TestConfig::for_unit_tests(),
|
|
"integration" => TestConfig::for_integration_tests(),
|
|
"chaos" => TestConfig::for_chaos_tests(),
|
|
_ => TestConfig::default(),
|
|
})
|
|
.unwrap_or_default()
|
|
})
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[tokio::test]
|
|
async fn test_config_default() {
|
|
let config = TestConfig::default();
|
|
assert!(!config.enable_chaos);
|
|
assert_eq!(config.chaos_failure_rate, 0.1);
|
|
}
|
|
|
|
#[tokio::test]
|
|
async fn test_config_access() {
|
|
let config = get_test_config();
|
|
assert!(config.default_timeout.as_secs() > 0);
|
|
}
|
|
}
|