Files
foxhunt/ml/tests/log_size_test.rs
jgrusewski f5947c2b22 Wave 16S-V11: Bug #8 fix + P2-A/B implementation
Bug #8 (CRITICAL): Fixed action selection frequency catastrophe
- Root cause: execute_action called during training (522,713 orders/epoch)
- Fix: Removed execute_action from experience collection loop (line 928-936)
- Impact: 522,713 → 0 orders/epoch (100% reduction)
- Transaction costs: $338K → $0 (eliminated)
- Test suite: ml/tests/action_selection_frequency_test.rs (3/3 passing)

P2-A: Configurable Initial Capital
- CLI argument: --initial-capital (default: $100K, min: $1K)
- Files modified: trainers/dqn.rs, train_dqn.rs, hyperopt adapter
- Test suite: ml/tests/configurable_capital_test.rs (8/8 passing)
- Supports: Small accounts ($10K), Standard ($100K), Institutional ($500K+)

P2-B: Cash Reserve Requirement
- CLI argument: --cash-reserve-percent (default: 0%, range: 0-100%)
- Reserve enforcement: BUY trades only (SELL always allowed)
- Dynamic reserve adjusts with portfolio value
- Files modified: portfolio_tracker.rs (70 lines), trainers/dqn.rs, train_dqn.rs
- Test suite: ml/tests/cash_reserve_requirement_test.rs (10/10 passing)

Test Status: 21/21 core tests passing (P2-C deferred due to API mismatch)

Wave 16S-V11 Agents:
- Agent #1: Bug #8 investigation (transaction cost analysis)
- Agent #2: P2-A implementation (configurable capital)
- Agent #3: P2-B implementation + test fix (cash reserve)
- Agent #4: Integration validation (certification report)
2025-11-12 23:05:51 +01:00

127 lines
3.9 KiB
Rust

/// Wave 16M: Test log size reduction from 2.8MB → <1MB
///
/// Validates that 1-epoch training produces <100KB of INFO-level logs
/// (scaling to <1MB for 10 epochs).
///
/// **Test Strategy**:
/// 1. Run 1-epoch training with RUST_LOG=info
/// 2. Capture log output to file
/// 3. Verify file size <100KB (10x scaling → <1MB for 10 epochs)
/// 4. Verify essential metrics still visible (epoch summary, trading stats)
use std::fs::File;
use std::io::Write;
use std::process::Command;
#[test]
fn test_log_size_under_1mb() {
// Create temp log file
let log_file = "/tmp/test_log_size.log";
// Run 1-epoch training with INFO-level logging
let output = Command::new("cargo")
.args(&[
"run",
"-p",
"ml",
"--example",
"train_dqn",
"--release",
"--features",
"cuda",
"--",
"--epochs",
"1",
])
.env("RUST_LOG", "info")
.output()
.expect("Failed to run training");
// Write output to file
let mut file = File::create(log_file).expect("Failed to create log file");
file.write_all(&output.stdout).expect("Failed to write stdout");
file.write_all(&output.stderr).expect("Failed to write stderr");
// Check log size
let metadata = std::fs::metadata(log_file).expect("Failed to read log file");
let size_bytes = metadata.len();
let size_kb = size_bytes as f64 / 1_024.0;
let size_mb = size_bytes as f64 / 1_048_576.0;
println!("Log size: {:.2} KB ({:.3} MB)", size_kb, size_mb);
// 1 epoch should produce <100KB (10 epochs → <1MB)
assert!(
size_kb < 100.0,
"1-epoch log should be <100KB, got {:.2}KB ({:.3}MB). 10-epoch projection: {:.2}MB",
size_kb,
size_mb,
size_mb * 10.0
);
// Verify essential metrics are still present (INFO level)
let log_content = std::fs::read_to_string(log_file).expect("Failed to read log file");
// Essential metrics that MUST be visible at INFO level
assert!(
log_content.contains("Epoch 1/1"),
"Missing epoch summary in INFO logs"
);
assert!(
log_content.contains("train_loss=") || log_content.contains("Training Stats"),
"Missing training loss in INFO logs"
);
assert!(
log_content.contains("Trading Stats") || log_content.contains("P&L"),
"Missing trading stats in INFO logs"
);
assert!(
log_content.contains("Action diversity") || log_content.contains("diversity="),
"Missing action diversity in INFO logs"
);
println!("✅ Test passed: Log size {:.2}KB < 100KB target", size_kb);
println!("✅ Projected 10-epoch log size: {:.2}MB < 1MB target", size_mb * 10.0);
}
#[test]
fn test_debug_logs_available() {
// Create temp log file
let log_file = "/tmp/test_log_debug.log";
// Run 1-epoch training with DEBUG-level logging
let output = Command::new("cargo")
.args(&[
"run",
"-p",
"ml",
"--example",
"train_dqn",
"--release",
"--features",
"cuda",
"--",
"--epochs",
"1",
])
.env("RUST_LOG", "debug")
.output()
.expect("Failed to run training");
// Write output to file
let mut file = File::create(log_file).expect("Failed to create log file");
file.write_all(&output.stdout).expect("Failed to write stdout");
file.write_all(&output.stderr).expect("Failed to write stderr");
// Verify DEBUG logs contain step-level details
let log_content = std::fs::read_to_string(log_file).expect("Failed to read log file");
// DEBUG-level details should be present
assert!(
log_content.contains("Q-values:") || log_content.contains("Diagnostics:"),
"Missing step-level diagnostics in DEBUG logs"
);
println!("✅ DEBUG logs contain step-level details");
}