✅ Agent 7: Moved ALL types to common crate - canonical source established ✅ Agent 8: Eliminated trading_engine type duplicates - 96% file reduction ✅ Agent 9: Fixed 301 import references across entire workspace ✅ Agent 10: Ensured 171+ public type exports with proper visibility ✅ Agent 11: Fixed E0603 private import violations ✅ Agent 12: Eliminated E0277 trait bound failures ✅ Agent 13: Added missing Order methods (limit, market, symbol_hash) ✅ Agent 14: Verified progress - 71→64 errors (10% reduction) 🔧 Key Architectural Improvements: - Single source of truth: common::types - Zero duplicate type definitions - Clean import architecture established - All types properly public and accessible 📊 Status: 64 compilation errors remain for next phase 🚀 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
189 lines
5.2 KiB
Rust
189 lines
5.2 KiB
Rust
//! Test framework utilities for Foxhunt HFT system
|
|
|
|
use std::sync::Arc;
|
|
use tokio::sync::RwLock;
|
|
use common::types::prelude::*;
|
|
|
|
/// Test framework for setting up common test infrastructure
|
|
pub struct TestFramework {
|
|
pub config: TestConfig,
|
|
}
|
|
|
|
/// Configuration for test setup
|
|
#[derive(Debug, Clone)]
|
|
pub struct TestConfig {
|
|
pub initial_capital: Decimal,
|
|
pub test_symbols: Vec<String>,
|
|
pub enable_logging: bool,
|
|
}
|
|
|
|
impl Default for TestConfig {
|
|
fn default() -> Self {
|
|
Self {
|
|
initial_capital: Decimal::from(100000),
|
|
test_symbols: vec!["BTCUSD".to_string(), "ETHUSD".to_string()],
|
|
enable_logging: false,
|
|
}
|
|
}
|
|
}
|
|
|
|
impl TestFramework {
|
|
pub fn new(config: TestConfig) -> Self {
|
|
Self { config }
|
|
}
|
|
|
|
pub fn with_default() -> Self {
|
|
Self::new(TestConfig::default())
|
|
}
|
|
|
|
pub async fn setup(&self) -> anyhow::Result<()> {
|
|
if self.config.enable_logging {
|
|
// TODO: Add tracing_subscriber dependency to enable logging
|
|
// tracing_subscriber::fmt::init();
|
|
println!("Logging enabled (tracing_subscriber not available)");
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
/// Test safety module for error-free testing
|
|
pub mod test_safety {
|
|
use std::fmt::Debug;
|
|
use std::time::Duration;
|
|
|
|
/// Safe test result type
|
|
pub type TestResult<T> = Result<T, TestSafetyError>;
|
|
|
|
/// Test safety error types
|
|
#[derive(Debug, Clone)]
|
|
pub enum TestSafetyError {
|
|
AssertionFailed {
|
|
field: String,
|
|
expected: String,
|
|
actual: String,
|
|
},
|
|
ThreadJoinFailed {
|
|
thread_type: String,
|
|
},
|
|
Timeout {
|
|
operation: String,
|
|
timeout_ms: u64,
|
|
},
|
|
CalculationFailed {
|
|
operation: String,
|
|
details: String,
|
|
},
|
|
}
|
|
|
|
impl std::fmt::Display for TestSafetyError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
match self {
|
|
TestSafetyError::AssertionFailed {
|
|
field,
|
|
expected,
|
|
actual,
|
|
} => {
|
|
write!(
|
|
f,
|
|
"Assertion failed for {}: expected {}, got {}",
|
|
field, expected, actual
|
|
)
|
|
}
|
|
TestSafetyError::ThreadJoinFailed { thread_type } => {
|
|
write!(f, "Thread join failed for: {}", thread_type)
|
|
}
|
|
TestSafetyError::Timeout {
|
|
operation,
|
|
timeout_ms,
|
|
} => {
|
|
write!(
|
|
f,
|
|
"Operation {} timed out after {}ms",
|
|
operation, timeout_ms
|
|
)
|
|
}
|
|
TestSafetyError::CalculationFailed { operation, details } => {
|
|
write!(f, "Calculation failed for {}: {}", operation, details)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
impl std::error::Error for TestSafetyError {}
|
|
|
|
/// Safe assertion function
|
|
pub fn safe_assert(
|
|
condition: bool,
|
|
field: &str,
|
|
expected: &str,
|
|
actual: impl std::fmt::Display,
|
|
) -> TestResult<()> {
|
|
if condition {
|
|
Ok(())
|
|
} else {
|
|
Err(TestSafetyError::AssertionFailed {
|
|
field: field.to_string(),
|
|
expected: expected.to_string(),
|
|
actual: actual.to_string(),
|
|
})
|
|
}
|
|
}
|
|
|
|
/// Safe equality assertion
|
|
pub fn safe_assert_eq<T: PartialEq + Debug>(
|
|
actual: &T,
|
|
expected: &T,
|
|
field: &str,
|
|
) -> TestResult<()> {
|
|
if actual == expected {
|
|
Ok(())
|
|
} else {
|
|
Err(TestSafetyError::AssertionFailed {
|
|
field: field.to_string(),
|
|
expected: format!("{:?}", expected),
|
|
actual: format!("{:?}", actual),
|
|
})
|
|
}
|
|
}
|
|
|
|
/// HFT Performance validator
|
|
pub struct HftPerformanceValidator {
|
|
pub max_latency_micros: u64,
|
|
pub min_throughput_ops_per_sec: u64,
|
|
}
|
|
|
|
impl HftPerformanceValidator {
|
|
pub fn new() -> Self {
|
|
Self {
|
|
max_latency_micros: 50, // 50μs max latency
|
|
min_throughput_ops_per_sec: 10_000, // 10k ops/sec min
|
|
}
|
|
}
|
|
|
|
pub fn validate_latency(&self, duration: Duration) -> TestResult<()> {
|
|
let micros = duration.as_micros() as u64;
|
|
safe_assert(
|
|
micros <= self.max_latency_micros,
|
|
"latency",
|
|
&format!("≤{}μs", self.max_latency_micros),
|
|
format!("{}μs", micros),
|
|
)
|
|
}
|
|
|
|
pub fn validate_throughput(&self, ops_per_sec: u64) -> TestResult<()> {
|
|
safe_assert(
|
|
ops_per_sec >= self.min_throughput_ops_per_sec,
|
|
"throughput",
|
|
&format!("≥{} ops/sec", self.min_throughput_ops_per_sec),
|
|
format!("{} ops/sec", ops_per_sec),
|
|
)
|
|
}
|
|
}
|
|
|
|
impl Default for HftPerformanceValidator {
|
|
fn default() -> Self {
|
|
Self::new()
|
|
}
|
|
}
|
|
}
|