mql5/Experts/Advisors/DualEA/Include/CArchitectureTests.mqh

478 lines
15 KiB
MQL5
Raw Permalink Normal View History

2026-02-24 12:47:37 -05:00
//+------------------------------------------------------------------+
//| CArchitectureTests.mqh - Comprehensive Test Suite for P0-P5 |
//| Tests all new architectural systems: Config, Error, Resources |
//+------------------------------------------------------------------+
#ifndef CARCHITECTURE_TESTS_MQH
#define CARCHITECTURE_TESTS_MQH
#include "CArchitectureConfig.mqh"
#include "CErrorHandling.mqh"
#include "CResourceManager.mqh"
//+------------------------------------------------------------------+
//| Test Result Structure |
//+------------------------------------------------------------------+
struct STestResult
{
string test_name;
bool passed;
string message;
double execution_time_ms;
void Set(const string name, bool p, const string msg, double exec_time)
{
test_name = name;
passed = p;
message = msg;
execution_time_ms = exec_time;
}
string ToString()
{
return StringFormat("[%s] %s: %s (%.2f ms)",
passed ? "PASS" : "FAIL",
test_name,
message,
execution_time_ms);
}
};
//+------------------------------------------------------------------+
//| Architecture Test Suite Class |
//+------------------------------------------------------------------+
class CArchitectureTestSuite
{
private:
STestResult m_results[];
int m_result_count;
int m_passed_count;
int m_failed_count;
datetime m_start_time;
public:
CArchitectureTestSuite()
{
m_result_count = 0;
m_passed_count = 0;
m_failed_count = 0;
ArrayResize(m_results, 100);
m_start_time = TimeCurrent();
}
//+------------------------------------------------------------------+
//| Run All Tests |
//+------------------------------------------------------------------+
bool RunAllTests()
{
Print("\n========================================");
Print(" P0-P5 ARCHITECTURE TEST SUITE");
Print("========================================\n");
ulong suite_start = GetMicrosecondCount();
// Phase 1: Configuration Tests
Test_Config_Validation();
Test_Config_GateSystemDefaults();
Test_Config_RiskEngineDefaults();
Test_Config_InvalidRanges();
// Phase 2: Error Handling Tests
Test_Error_Logging();
Test_Error_Categories();
Test_Error_CircuitBreaker();
Test_Error_History();
// Phase 3: Resource Manager Tests
Test_Resource_IndicatorTracking();
Test_Resource_FileTracking();
Test_Resource_Ownership();
Test_Resource_LeakDetection();
// Phase 4: Integration Tests
Test_Integration_AllSystems();
ulong suite_end = GetMicrosecondCount();
double suite_time_ms = (suite_end - suite_start) / 1000.0;
// Print Results
PrintResults(suite_time_ms);
return m_failed_count == 0;
}
private:
//+------------------------------------------------------------------+
//| Configuration Tests |
//+------------------------------------------------------------------+
void Test_Config_Validation()
{
ulong start = GetMicrosecondCount();
CArchitectureConfig config;
config.SetAllDefaults();
bool valid = config.ValidateAll();
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
if(valid)
AddResult("Config_Validation", true, "All configurations valid", time_ms);
else
AddResult("Config_Validation", false, "Validation failed:\n" + config.GetValidationReport(), time_ms);
}
void Test_Config_GateSystemDefaults()
{
ulong start = GetMicrosecondCount();
CArchitectureConfig config;
config.SetAllDefaults();
bool budget_ok = true;
for(int i = 0; i < 8; i++)
{
if(config.GateSystem.gate_budgets_us[i] != 2000)
budget_ok = false;
}
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
AddResult("Config_GateDefaults", budget_ok,
StringFormat("Gate budgets: %d us per gate", config.GateSystem.total_budget_us),
time_ms);
}
void Test_Config_RiskEngineDefaults()
{
ulong start = GetMicrosecondCount();
CArchitectureConfig config;
config.SetAllDefaults();
bool defaults_ok = (
config.RiskEngine.max_drawdown_pct == 10.0 &&
config.RiskEngine.kelly_fraction == 0.25 &&
config.RiskEngine.var_confidence == 0.95
);
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
AddResult("Config_RiskDefaults", defaults_ok,
StringFormat("MaxDD=%.1f%%, Kelly=%.2f, VaR=%.2f",
config.RiskEngine.max_drawdown_pct,
config.RiskEngine.kelly_fraction,
config.RiskEngine.var_confidence),
time_ms);
}
void Test_Config_InvalidRanges()
{
ulong start = GetMicrosecondCount();
CArchitectureConfig config;
config.SetAllDefaults();
// Set invalid values
config.RiskEngine.max_drawdown_pct = -5.0; // Invalid
config.RiskEngine.kelly_fraction = 2.0; // Invalid (> 1.0)
bool validation_caught = !config.ValidateAll();
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
AddResult("Config_InvalidRanges", validation_caught,
"Validation correctly caught invalid ranges",
time_ms);
}
//+------------------------------------------------------------------+
//| Error Handling Tests |
//+------------------------------------------------------------------+
void Test_Error_Logging()
{
ulong start = GetMicrosecondCount();
CErrorHandler handler;
handler.Info(ERR_CAT_SYSTEM, "Test", "TestFunc", "Test info message");
handler.Warning(ERR_CAT_FILE, "Test", "TestFunc", 123, "Test warning");
handler.Error(ERR_CAT_NETWORK, "Test", "TestFunc", 456, "Test error");
int total = handler.GetErrorCount(ERR_SEVERITY_INFO) +
handler.GetErrorCount(ERR_SEVERITY_WARNING) +
handler.GetErrorCount(ERR_SEVERITY_ERROR);
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
AddResult("Error_Logging", total == 3,
StringFormat("Logged %d errors correctly", total),
time_ms);
}
void Test_Error_Categories()
{
ulong start = GetMicrosecondCount();
CErrorHandler handler;
// Log one error per category
for(int cat = ERR_CAT_INIT; cat <= ERR_CAT_SYSTEM; cat++)
{
handler.Error((ENUM_ERROR_CATEGORY)cat, "Test", "TestFunc", cat, "Category test");
}
int total_categories = 0;
for(int cat = ERR_CAT_INIT; cat <= ERR_CAT_SYSTEM; cat++)
{
if(handler.GetCategoryCount((ENUM_ERROR_CATEGORY)cat) > 0)
total_categories++;
}
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
AddResult("Error_Categories", total_categories == 9,
StringFormat("Logged errors in %d/9 categories", total_categories),
time_ms);
}
void Test_Error_CircuitBreaker()
{
ulong start = GetMicrosecondCount();
CErrorHandler handler;
// Trip circuit breaker
for(int i = 0; i < 15; i++)
{
handler.Error(ERR_CAT_SYSTEM, "Test", "TestFunc", i, "Circuit breaker test");
}
bool tripped = handler.IsCircuitBreakerTripped();
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
AddResult("Error_CircuitBreaker", tripped,
"Circuit breaker tripped after 10 errors",
time_ms);
}
void Test_Error_History()
{
ulong start = GetMicrosecondCount();
CErrorHandler handler;
// Log some errors
for(int i = 0; i < 5; i++)
{
handler.Error(ERR_CAT_SYSTEM, "Test", "TestFunc", i, "History test");
}
string recent = handler.GetRecentErrors(3);
bool has_history = StringFind(recent, "History test") >= 0;
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
AddResult("Error_History", has_history,
"Error history correctly maintained",
time_ms);
}
//+------------------------------------------------------------------+
//| Resource Manager Tests |
//+------------------------------------------------------------------+
void Test_Resource_IndicatorTracking()
{
ulong start = GetMicrosecondCount();
CResourceManager manager;
// Simulate indicator handle (use a dummy value)
int dummy_handle = 12345;
manager.TrackIndicator(dummy_handle, "Test", "Test MA indicator", __FILE__, __LINE__);
// Release it
bool released = manager.ReleaseIndicator(dummy_handle, "Test");
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
AddResult("Resource_Indicator", released,
"Indicator handle tracked and released",
time_ms);
}
void Test_Resource_FileTracking()
{
ulong start = GetMicrosecondCount();
CResourceManager manager;
// Simulate file handle
int dummy_handle = 67890;
manager.TrackFile(dummy_handle, "Test", "Test log file", __FILE__, __LINE__);
// Release it
bool released = manager.ReleaseFile(dummy_handle, "Test");
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
AddResult("Resource_File", released,
"File handle tracked and released",
time_ms);
}
void Test_Resource_Ownership()
{
ulong start = GetMicrosecondCount();
CResourceManager manager;
// Track multiple resources for different owners
manager.TrackIndicator(1001, "OwnerA", "MA20", __FILE__, __LINE__);
manager.TrackIndicator(1002, "OwnerA", "RSI14", __FILE__, __LINE__);
manager.TrackIndicator(1003, "OwnerB", "MACD", __FILE__, __LINE__);
// Release all for OwnerA
int released = manager.ReleaseAllForOwner("OwnerA");
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
AddResult("Resource_Ownership", released == 2,
StringFormat("Released %d resources for OwnerA", released),
time_ms);
}
void Test_Resource_LeakDetection()
{
ulong start = GetMicrosecondCount();
CResourceManager manager;
// Track resources but don't release some
manager.TrackIndicator(2001, "Test", "Released", __FILE__, __LINE__);
manager.TrackIndicator(2002, "Test", "Leaked", __FILE__, __LINE__);
// Only release one
manager.ReleaseIndicator(2001, "Test");
// Check stats
string stats = manager.GetStatistics();
bool has_leak_info = StringFind(stats, "Leaked") >= 0 || StringFind(stats, "Alloc") >= 0;
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
AddResult("Resource_LeakDetection", has_leak_info,
"Leak detection statistics available",
time_ms);
}
//+------------------------------------------------------------------+
//| Integration Tests |
//+------------------------------------------------------------------+
void Test_Integration_AllSystems()
{
ulong start = GetMicrosecondCount();
// Test all systems working together
CArchitectureConfig config;
config.SetAllDefaults();
CErrorHandler errors;
CResourceManager resources;
// Simulate a scenario: Config validation fails
config.GateSystem.total_budget_us = 100; // Too small
if(!config.ValidateAll())
{
errors.Error(ERR_CAT_CONFIG, "Integration", "Test", 1, "Config validation failed");
}
// Simulate resource allocation
resources.TrackIndicator(3001, "Integration", "Test Indicator", __FILE__, __LINE__);
bool all_working = (
errors.GetErrorCount(ERR_SEVERITY_ERROR) > 0 &&
StringFind(resources.GetStatistics(), "Alloc") >= 0
);
ulong end = GetMicrosecondCount();
double time_ms = (end - start) / 1000.0;
AddResult("Integration_AllSystems", all_working,
"All architectural systems integrated and functional",
time_ms);
}
//+------------------------------------------------------------------+
//| Result Management |
//+------------------------------------------------------------------+
void AddResult(const string name, bool passed, const string msg, double time_ms)
{
int idx = m_result_count;
if(idx >= ArraySize(m_results))
{
ArrayResize(m_results, ArraySize(m_results) + 50);
}
m_results[idx].Set(name, passed, msg, time_ms);
m_result_count++;
if(passed)
m_passed_count++;
else
m_failed_count++;
}
void PrintResults(double total_time_ms)
{
Print("\n----------------------------------------");
Print(" TEST RESULTS SUMMARY");
Print("----------------------------------------\n");
for(int i = 0; i < m_result_count; i++)
{
Print(m_results[i].ToString());
}
Print("\n----------------------------------------");
Print(StringFormat(" TOTAL: %d tests | %d passed | %d failed",
m_result_count, m_passed_count, m_failed_count));
Print(StringFormat(" Execution Time: %.2f ms", total_time_ms));
Print(StringFormat(" Success Rate: %.1f%%",
(double)m_passed_count / m_result_count * 100.0));
Print("----------------------------------------\n");
if(m_failed_count == 0)
{
Print(" ✅ ALL TESTS PASSED - Architecture ready for production");
}
else
{
Print(StringFormat(" ⚠️ %d TESTS FAILED - Review failures above", m_failed_count));
}
Print("========================================\n");
}
};
//+------------------------------------------------------------------+
//| Global Test Function |
//+------------------------------------------------------------------+
bool RunArchitectureTests()
{
CArchitectureTestSuite test_suite;
return test_suite.RunAllTests();
}
#endif // CARCHITECTURE_TESTS_MQH