docs: consolidate documentation into organized structure

- Move 12 markdown files from root to docs/ subdirectories
- Organize documentation by category:
  • docs/troubleshooting/ (1 file)  - Technical troubleshooting guides
  • docs/deployment/      (4 files) - Deployment and security documentation
  • docs/guides/          (3 files) - Feature-specific guides
  • docs/planning/        (4 files) - Planning and improvement proposals

Root directory cleanup:
- Reduced from 16 to 4 markdown files in root
- Only essential project files remain:
  • CLAUDE.md (AI instructions)
  • README.md (Main project readme)
  • CLEANUP_PLAN.md (Current cleanup plan)
  • SRC_STRUCTURE_IMPROVEMENTS.md (Structure improvements)

This improves:
 Documentation discoverability
 Logical organization by purpose
 Clean root directory
 Better maintainability
This commit is contained in:
2025-10-05 11:05:04 +02:00
parent 887847dde6
commit 5050c7d73a
36686 changed files with 196456 additions and 12398919 deletions

View File

@@ -0,0 +1,530 @@
<?php
declare(strict_types=1);
/**
* MCP System Test Suite
*
* Comprehensive testing of the MCP framework including:
* - Cache Manager Performance
* - Concurrent Execution
* - Result Optimization
* - Performance Monitoring
*/
require_once __DIR__ . '/../../vendor/autoload.php';
use App\Framework\Mcp\Core\Services\IntelligentMcpCacheManager;
use App\Framework\Mcp\Core\Services\ResultOptimizer;
use App\Framework\Mcp\Core\Services\McpPerformanceMonitor;
use App\Framework\Mcp\Core\Services\ConcurrentExecutionManager;
use App\Framework\Mcp\Core\ValueObjects\CacheStrategy;
use App\Framework\Mcp\Core\ValueObjects\OptimizationStrategy;
use App\Framework\Mcp\Core\ValueObjects\OutputFormat;
use App\Framework\Mcp\Core\ValueObjects\ExecutionTask;
use App\Framework\Mcp\Core\ValueObjects\ConcurrencyStrategy;
use App\Framework\Cache\SmartCache;
use App\Framework\Async\AsyncService;
class McpSystemTester
{
private array $testResults = [];
private float $startTime;
public function __construct()
{
$this->startTime = microtime(true);
echo "🧪 MCP System Test Suite Starting...\n\n";
}
public function runAllTests(): void
{
echo "📋 Running comprehensive MCP system tests...\n\n";
// Test Cache Manager
$this->testCacheManager();
// Test Result Optimizer
$this->testResultOptimizer();
// Test Performance Monitor
$this->testPerformanceMonitor();
// Test Concurrent Execution (simulated)
$this->testConcurrentExecution();
// Performance Integration Test
$this->testIntegratedPerformance();
// Generate final report
$this->generateReport();
}
private function testCacheManager(): void
{
echo "🗄️ Testing Cache Manager...\n";
try {
// Create mock cache for testing
$cache = new SmartCache();
$cacheManager = new IntelligentMcpCacheManager($cache);
// Test 1: Basic caching functionality
echo " ⚡ Test 1: Basic Caching\n";
$testData = ['test' => 'data', 'timestamp' => time()];
// Test set/get
$cacheManager->set('test_tool', 'test_method', [], $testData, CacheStrategy::MEDIUM);
$retrieved = $cacheManager->get('test_tool', 'test_method', [], CacheStrategy::MEDIUM);
$this->assert($retrieved === $testData, "Cache set/get should work");
echo " ✅ Basic caching works\n";
// Test 2: Cache strategy selection
echo " ⚡ Test 2: Cache Strategy Selection\n";
$healthStrategy = CacheStrategy::recommendFor('health_checker', 'status');
$routeStrategy = CacheStrategy::recommendFor('route_analyzer', 'analyze');
$this->assert($healthStrategy === CacheStrategy::SHORT, "Health tools should use SHORT strategy");
$this->assert($routeStrategy === CacheStrategy::LONG, "Route tools should use LONG strategy");
echo " ✅ Strategy selection works\n";
// Test 3: Remember pattern
echo " ⚡ Test 3: Remember Pattern\n";
$callCount = 0;
$result = $cacheManager->remember(
'test_tool',
'expensive_operation',
['param' => 'value'],
function() use (&$callCount) {
$callCount++;
return ['expensive' => 'result', 'call_count' => $callCount];
},
CacheStrategy::MEDIUM
);
// Should be called once
$this->assert($callCount === 1, "Callback should be called once");
// Second call should use cache
$result2 = $cacheManager->remember(
'test_tool',
'expensive_operation',
['param' => 'value'],
function() use (&$callCount) {
$callCount++;
return ['expensive' => 'result', 'call_count' => $callCount];
},
CacheStrategy::MEDIUM
);
$this->assert($callCount === 1, "Callback should not be called again (cache hit)");
$this->assert($result === $result2, "Results should be identical");
echo " ✅ Remember pattern works\n";
// Test 4: Cache metrics
echo " ⚡ Test 4: Cache Metrics\n";
$metrics = $cacheManager->getMetrics();
$this->assert(is_array($metrics->toArray()), "Metrics should be returned");
echo " ✅ Cache metrics available\n";
$this->testResults['cache_manager'] = [
'status' => 'passed',
'tests' => 4,
'details' => 'All cache manager tests passed'
];
} catch (\Throwable $e) {
$this->testResults['cache_manager'] = [
'status' => 'failed',
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
];
echo " ❌ Cache Manager test failed: " . $e->getMessage() . "\n";
}
echo "\n";
}
private function testResultOptimizer(): void
{
echo "🔧 Testing Result Optimizer...\n";
try {
$optimizer = new ResultOptimizer();
// Test 1: Basic optimization
echo " ⚡ Test 1: Basic Optimization\n";
$largeData = array_fill(0, 1000, 'test data item');
$result = $optimizer->optimize($largeData, OutputFormat::JSON, OptimizationStrategy::SIZE);
$this->assert($result->compressionRatio < 1.0, "Should achieve compression");
$this->assert($result->optimizedSize < $result->originalSize, "Optimized size should be smaller");
echo " ✅ Basic optimization works\n";
// Test 2: Strategy comparison
echo " ⚡ Test 2: Strategy Comparison\n";
$testData = ['large_array' => array_fill(0, 500, 'data'), 'metadata' => 'test'];
$sizeResult = $optimizer->optimize($testData, OutputFormat::JSON, OptimizationStrategy::SIZE);
$speedResult = $optimizer->optimize($testData, OutputFormat::JSON, OptimizationStrategy::SPEED);
$noneResult = $optimizer->optimize($testData, OutputFormat::JSON, OptimizationStrategy::NONE);
$this->assert($sizeResult->compressionRatio <= $speedResult->compressionRatio, "Size strategy should compress more");
$this->assert($noneResult->compressionRatio === 1.0, "None strategy should not compress");
echo " ✅ Strategy comparison works\n";
// Test 3: Format-specific optimization
echo " ⚡ Test 3: Format-Specific Optimization\n";
$complexData = [
'nodes' => ['A' => ['connections' => ['B', 'C']], 'B' => ['connections' => ['A']]],
'metadata' => ['type' => 'graph', 'version' => '1.0']
];
$jsonResult = $optimizer->optimize($complexData, OutputFormat::JSON, OptimizationStrategy::BALANCED);
$tableResult = $optimizer->optimize($complexData, OutputFormat::TABLE, OptimizationStrategy::BALANCED);
$this->assert(is_array($jsonResult->optimizedData), "JSON optimization should return array");
echo " ✅ Format-specific optimization works\n";
// Test 4: Compression and decompression
echo " ⚡ Test 4: Compression and Decompression\n";
$originalData = array_fill(0, 100, 'This is a test string that should compress well when repeated many times');
$compressed = $optimizer->compress($originalData, 6);
if (is_array($compressed) && isset($compressed['_compressed'])) {
$decompressed = $optimizer->decompress($compressed);
$this->assert($decompressed === $originalData, "Decompression should restore original data");
echo " ✅ Compression/decompression works\n";
} else {
echo " Data too small for compression\n";
}
$this->testResults['result_optimizer'] = [
'status' => 'passed',
'tests' => 4,
'details' => 'All result optimizer tests passed'
];
} catch (\Throwable $e) {
$this->testResults['result_optimizer'] = [
'status' => 'failed',
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
];
echo " ❌ Result Optimizer test failed: " . $e->getMessage() . "\n";
}
echo "\n";
}
private function testPerformanceMonitor(): void
{
echo "📊 Testing Performance Monitor...\n";
try {
$cache = new SmartCache();
$monitor = new McpPerformanceMonitor($cache);
// Test 1: Basic execution monitoring
echo " ⚡ Test 1: Basic Execution Monitoring\n";
$executionId = $monitor->startExecution('test_tool', 'test_method', ['param' => 'value']);
$this->assert(!empty($executionId), "Execution ID should be generated");
// Simulate some work
usleep(100000); // 0.1 seconds
$metrics = $monitor->endExecution($executionId, ['result' => 'data']);
$this->assert($metrics->success, "Execution should be successful");
$this->assert($metrics->executionTime > 0.09, "Execution time should be recorded");
echo " ✅ Basic monitoring works\n";
// Test 2: Error handling
echo " ⚡ Test 2: Error Handling\n";
$errorId = $monitor->startExecution('test_tool', 'failing_method');
$errorMetrics = $monitor->endExecution($errorId, null, 'Test error');
$this->assert(!$errorMetrics->success, "Failed execution should be marked as unsuccessful");
$this->assert($errorMetrics->error === 'Test error', "Error message should be preserved");
echo " ✅ Error handling works\n";
// Test 3: Monitor wrapper
echo " ⚡ Test 3: Monitor Wrapper\n";
$result = $monitor->monitor(
'test_tool',
'wrapper_test',
function() {
usleep(50000); // 0.05 seconds
return ['wrapped' => 'result'];
},
['wrapper' => 'param']
);
$this->assert($result === ['wrapped' => 'result'], "Monitor wrapper should return result");
echo " ✅ Monitor wrapper works\n";
// Test 4: Performance thresholds
echo " ⚡ Test 4: Performance Thresholds\n";
$threshold = $monitor->getThresholds('test_tool');
$this->assert($threshold->maxExecutionTime > 0, "Threshold should have execution time limit");
echo " ✅ Performance thresholds work\n";
$this->testResults['performance_monitor'] = [
'status' => 'passed',
'tests' => 4,
'details' => 'All performance monitor tests passed'
];
} catch (\Throwable $e) {
$this->testResults['performance_monitor'] = [
'status' => 'failed',
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
];
echo " ❌ Performance Monitor test failed: " . $e->getMessage() . "\n";
}
echo "\n";
}
private function testConcurrentExecution(): void
{
echo "🔄 Testing Concurrent Execution (Simulated)...\n";
try {
// Note: This is a simplified test since we can't easily test real concurrency in this context
// Test 1: Task creation
echo " ⚡ Test 1: Task Creation\n";
$task1 = ExecutionTask::create('test_tool', 'method1', ['param1' => 'value1']);
$task2 = ExecutionTask::highPriority('test_tool', 'method2', ['param2' => 'value2']);
$task3 = ExecutionTask::lowResource('test_tool', 'method3', ['param3' => 'value3']);
$this->assert(!empty($task1->getId()), "Task should have ID");
$this->assert($task2->getPriority() > $task1->getPriority(), "High priority task should have higher priority");
$this->assert($task3->getEstimatedMemory() < $task1->getEstimatedMemory(), "Low resource task should estimate less memory");
echo " ✅ Task creation works\n";
// Test 2: Concurrency strategy
echo " ⚡ Test 2: Concurrency Strategy\n";
$conservative = ConcurrencyStrategy::conservative();
$balanced = ConcurrencyStrategy::balanced();
$aggressive = ConcurrencyStrategy::aggressive();
$this->assert($conservative->getMaxConcurrency() < $balanced->getMaxConcurrency(), "Conservative should have lower concurrency");
$this->assert($balanced->getMaxConcurrency() < $aggressive->getMaxConcurrency(), "Aggressive should have higher concurrency");
echo " ✅ Concurrency strategy works\n";
// Test 3: Task array conversion
echo " ⚡ Test 3: Task Serialization\n";
$taskArray = $task1->toArray();
$this->assert(isset($taskArray['id']), "Task array should contain ID");
$this->assert(isset($taskArray['tool_name']), "Task array should contain tool name");
echo " ✅ Task serialization works\n";
$this->testResults['concurrent_execution'] = [
'status' => 'passed',
'tests' => 3,
'details' => 'Concurrent execution structure tests passed (simulated)'
];
} catch (\Throwable $e) {
$this->testResults['concurrent_execution'] = [
'status' => 'failed',
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
];
echo " ❌ Concurrent Execution test failed: " . $e->getMessage() . "\n";
}
echo "\n";
}
private function testIntegratedPerformance(): void
{
echo "🎯 Testing Integrated Performance...\n";
try {
$cache = new SmartCache();
$cacheManager = new IntelligentMcpCacheManager($cache);
$optimizer = new ResultOptimizer();
$monitor = new McpPerformanceMonitor($cache);
// Test 1: Full pipeline performance
echo " ⚡ Test 1: Full Pipeline Performance\n";
$startTime = microtime(true);
// Simulate complex operation
$complexData = $this->generateComplexTestData();
// Optimize the data
$optimized = $optimizer->optimize($complexData, OutputFormat::JSON, OptimizationStrategy::BALANCED);
// Cache the result
$cacheManager->set('integration_test', 'complex_operation', ['test' => 'param'], $optimized->optimizedData);
// Retrieve from cache
$cached = $cacheManager->get('integration_test', 'complex_operation', ['test' => 'param']);
$endTime = microtime(true);
$totalTime = $endTime - $startTime;
$this->assert($cached !== null, "Should retrieve from cache");
$this->assert($totalTime < 1.0, "Full pipeline should complete in under 1 second");
echo " ✅ Full pipeline performance acceptable ({$totalTime}s)\n";
// Test 2: Memory efficiency
echo " ⚡ Test 2: Memory Efficiency\n";
$memoryBefore = memory_get_usage(true);
// Process multiple datasets
for ($i = 0; $i < 10; $i++) {
$data = array_fill(0, 100, "test data item {$i}");
$optimized = $optimizer->optimize($data, OutputFormat::JSON, OptimizationStrategy::SIZE);
$cacheManager->set('memory_test', "operation_{$i}", [], $optimized->optimizedData);
}
$memoryAfter = memory_get_usage(true);
$memoryIncrease = $memoryAfter - $memoryBefore;
$this->assert($memoryIncrease < 50 * 1024 * 1024, "Memory increase should be under 50MB"); // 50MB
echo " ✅ Memory efficiency acceptable (" . $this->formatBytes($memoryIncrease) . " increase)\n";
// Test 3: Cache hit performance
echo " ⚡ Test 3: Cache Hit Performance\n";
$hitTimes = [];
// Prime the cache
$cacheManager->set('performance_test', 'hit_test', [], $complexData);
// Measure cache hit times
for ($i = 0; $i < 5; $i++) {
$hitStart = microtime(true);
$result = $cacheManager->get('performance_test', 'hit_test', []);
$hitEnd = microtime(true);
$hitTimes[] = $hitEnd - $hitStart;
}
$averageHitTime = array_sum($hitTimes) / count($hitTimes);
$this->assert($averageHitTime < 0.01, "Cache hits should be under 10ms"); // 10ms
echo " ✅ Cache hit performance excellent ({$averageHitTime}s average)\n";
$this->testResults['integrated_performance'] = [
'status' => 'passed',
'tests' => 3,
'details' => "Full pipeline: {$totalTime}s, Memory: " . $this->formatBytes($memoryIncrease) . ", Cache hits: {$averageHitTime}s"
];
} catch (\Throwable $e) {
$this->testResults['integrated_performance'] = [
'status' => 'failed',
'error' => $e->getMessage(),
'trace' => $e->getTraceAsString()
];
echo " ❌ Integrated Performance test failed: " . $e->getMessage() . "\n";
}
echo "\n";
}
private function generateComplexTestData(): array
{
return [
'routes' => array_fill(0, 50, [
'path' => '/api/test/' . uniqid(),
'method' => 'GET',
'controller' => 'TestController',
'middleware' => ['auth', 'throttle'],
'parameters' => ['id' => 'integer']
]),
'containers' => array_fill(0, 30, [
'service' => 'Service' . rand(1, 100),
'binding' => 'Interface' . rand(1, 50),
'singleton' => rand(0, 1) === 1,
'dependencies' => array_fill(0, rand(1, 5), 'Dependency' . rand(1, 20))
]),
'metadata' => [
'generated_at' => time(),
'version' => '1.0.0',
'environment' => 'test',
'memory_usage' => memory_get_usage(true),
'peak_memory' => memory_get_peak_usage(true)
]
];
}
private function generateReport(): void
{
$totalTime = microtime(true) - $this->startTime;
echo "📊 TEST REPORT\n";
echo "═══════════════════════════════════════════════════════\n\n";
$passed = 0;
$failed = 0;
foreach ($this->testResults as $testName => $result) {
$status = $result['status'] === 'passed' ? '✅' : '❌';
$statusText = strtoupper($result['status']);
echo "{$status} {$testName}: {$statusText}\n";
if ($result['status'] === 'passed') {
$passed++;
if (isset($result['tests'])) {
echo " 📋 {$result['tests']} sub-tests passed\n";
}
if (isset($result['details'])) {
echo " 📝 {$result['details']}\n";
}
} else {
$failed++;
echo " ❌ Error: {$result['error']}\n";
}
echo "\n";
}
echo "═══════════════════════════════════════════════════════\n";
echo "📈 SUMMARY:\n";
echo " ✅ Passed: {$passed}\n";
echo " ❌ Failed: {$failed}\n";
echo " ⏱️ Total time: " . round($totalTime, 3) . "s\n";
echo " 🧠 Memory usage: " . $this->formatBytes(memory_get_usage(true)) . "\n";
echo " 📊 Peak memory: " . $this->formatBytes(memory_get_peak_usage(true)) . "\n";
if ($failed === 0) {
echo "\n🎉 ALL TESTS PASSED! MCP System is working correctly.\n";
} else {
echo "\n⚠️ Some tests failed. Please check the errors above.\n";
}
echo "\n";
}
private function assert(bool $condition, string $message): void
{
if (!$condition) {
throw new \AssertionError("Assertion failed: {$message}");
}
}
private function formatBytes(int $bytes): string
{
if ($bytes === 0) return '0 B';
$units = ['B', 'KB', 'MB', 'GB'];
$unitIndex = 0;
$value = $bytes;
while ($value >= 1024 && $unitIndex < count($units) - 1) {
$value /= 1024;
$unitIndex++;
}
return round($value, 2) . ' ' . $units[$unitIndex];
}
}
// Run the tests
$tester = new McpSystemTester();
$tester->runAllTests();