Files
michaelschiemer/tests/debug/test-dependency-analysis.php
Michael Schiemer 36ef2a1e2c
Some checks failed
🚀 Build & Deploy Image / Determine Build Necessity (push) Failing after 10m14s
🚀 Build & Deploy Image / Build Runtime Base Image (push) Has been skipped
🚀 Build & Deploy Image / Build Docker Image (push) Has been skipped
🚀 Build & Deploy Image / Run Tests & Quality Checks (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Staging (push) Has been skipped
🚀 Build & Deploy Image / Auto-deploy to Production (push) Has been skipped
Security Vulnerability Scan / Check for Dependency Changes (push) Failing after 11m25s
Security Vulnerability Scan / Composer Security Audit (push) Has been cancelled
fix: Gitea Traefik routing and connection pool optimization
- Remove middleware reference from Gitea Traefik labels (caused routing issues)
- Optimize Gitea connection pool settings (MAX_IDLE_CONNS=30, authentication_timeout=180s)
- Add explicit service reference in Traefik labels
- Fix intermittent 504 timeouts by improving PostgreSQL connection handling

Fixes Gitea unreachability via git.michaelschiemer.de
2025-11-09 14:46:15 +01:00

257 lines
9.4 KiB
PHP
Raw Blame History

This file contains invisible Unicode characters
This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
require_once __DIR__ . '/../../vendor/autoload.php';
use App\Framework\Core\ValueObjects\ClassName;
use App\Framework\Discovery\Analysis\DependencyAnalyzer;
use App\Framework\ReflectionLegacy\CachedReflectionProvider;
echo "=== Testing Dependency Graph Analysis System ===\n\n";
$reflectionProvider = new CachedReflectionProvider();
echo "1. Testing DependencyAnalyzer with sample framework classes:\n";
try {
$analyzer = new DependencyAnalyzer($reflectionProvider);
// Test with simpler, existing classes first
$classesToAnalyze = [
'App\\Framework\\Core\\ValueObjects\\ClassName',
'App\\Framework\\Http\\Method',
'App\\Framework\\Router\\ValueObjects\\RoutePath',
'App\\Framework\\Router\\ValueObjects\\Placeholder',
];
echo " 🔍 Analyzing classes: " . implode(', ', array_map(fn ($c) => basename(str_replace('\\', '/', $c)), $classesToAnalyze)) . "\n";
$analysisResult = $analyzer->analyzeWithCircularDetection($classesToAnalyze);
$graph = $analysisResult->getGraph();
$statistics = $analysisResult->getStatistics();
echo " ✅ Analysis completed successfully\n";
echo " 📊 Statistics:\n";
echo " • Total nodes: {$statistics['node_count']}\n";
echo " • Total edges: {$statistics['edge_count']}\n";
echo " • Circular dependencies: {$statistics['circular_dependencies']}\n";
echo " • Leaf nodes: {$statistics['leaf_nodes']}\n";
echo " • Root nodes: {$statistics['root_nodes']}\n";
echo " • Average complexity: {$statistics['average_complexity']}\n";
echo " • Max dependencies: {$statistics['max_dependency_count']}\n\n";
echo " 📈 Type distribution:\n";
foreach ($statistics['type_distribution'] as $type => $count) {
echo "{$type}: {$count}\n";
}
echo "\n";
if ($analysisResult->hasCircularDependencies()) {
echo " ⚠️ Circular dependencies found:\n";
foreach ($analysisResult->getCircularDependencies() as $cycle) {
echo "" . implode(' -> ', $cycle) . "\n";
}
echo "\n";
} else {
echo " ✅ No circular dependencies found\n\n";
}
} catch (\Throwable $e) {
echo " ❌ Error: {$e->getMessage()}\n\n";
}
echo "2. Testing specific class analysis (DefaultContainer):\n";
try {
$containerClass = 'App\\Framework\\DI\\DefaultContainer';
$analyzer = new DependencyAnalyzer($reflectionProvider);
$analysisResult = $analyzer->analyzeWithCircularDetection([$containerClass]);
$graph = $analysisResult->getGraph();
$node = $graph->getNode(ClassName::create($containerClass));
if ($node !== null) {
echo " ✅ DefaultContainer analysis:\n";
echo " • Type: {$node->getType()->value}\n";
echo " • Dependencies: {$node->getDependencyCount()}\n";
echo " • Dependents: {$node->getDependentCount()}\n";
echo " • Complexity score: " . round($node->getComplexityScore(), 2) . "\n";
echo " • Is leaf: " . ($node->isLeaf() ? 'Yes' : 'No') . "\n";
echo " • Is root: " . ($node->isRoot() ? 'Yes' : 'No') . "\n\n";
if (! empty($node->getDependencies())) {
echo " 📋 Dependencies:\n";
foreach ($node->getDependencies() as $edge) {
echo "{$edge->getTarget()->getShortName()} ({$edge->getRelation()->value}, weight: {$edge->getWeight()})\n";
}
echo "\n";
}
// Test dependency depth
$depth = $graph->getDependencyDepth($node->getClassName());
echo " 📏 Dependency depth: {$depth}\n\n";
}
} catch (\Throwable $e) {
echo " ❌ Error: {$e->getMessage()}\n\n";
}
echo "3. Testing dependency recommendations:\n";
try {
$analyzer = new DependencyAnalyzer($reflectionProvider);
// Analyze a larger set of framework classes
$frameworkClasses = [
'App\\Framework\\DI\\DefaultContainer',
'App\\Framework\\Router\\ValueObjects\\RoutePath',
'App\\Framework\\Router\\ValueObjects\\RouteGroup',
'App\\Framework\\TypeCaster\\TypeCasterRegistry',
'App\\Framework\\Discovery\\UnifiedDiscoveryService',
'App\\Framework\\Core\\Application',
'App\\Framework\\Http\\Request',
'App\\Framework\\Database\\EntityManager',
];
$analysisResult = $analyzer->analyzeWithCircularDetection($frameworkClasses);
$recommendations = $analyzer->getRecommendations($analysisResult->getGraph());
echo " 📝 Recommendations:\n";
if (isset($recommendations['high_complexity'])) {
echo " 🔺 High Complexity Classes:\n";
foreach ($recommendations['high_complexity'] as $item) {
echo "{$item['class']}: {$item['current']} (expected max: {$item['expected_max']})\n";
echo " {$item['suggestion']}\n";
}
echo "\n";
}
if (isset($recommendations['high_dependencies'])) {
echo " 🔗 High Dependency Classes:\n";
foreach ($recommendations['high_dependencies'] as $item) {
echo "{$item['class']}: {$item['dependency_count']} dependencies\n";
echo " {$item['suggestion']}\n";
}
echo "\n";
}
if (isset($recommendations['circular_dependencies'])) {
echo " 🔄 Circular Dependencies:\n";
echo " • Count: {$recommendations['circular_dependencies']['count']}\n";
echo "{$recommendations['circular_dependencies']['suggestion']}\n";
foreach ($recommendations['circular_dependencies']['cycles'] as $cycle) {
echo " Cycle: " . implode(' -> ', $cycle) . "\n";
}
echo "\n";
}
if (isset($recommendations['potentially_unused'])) {
echo " 🗑️ Potentially Unused Classes:\n";
foreach ($recommendations['potentially_unused'] as $item) {
echo "{$item['class']}: {$item['suggestion']}\n";
}
echo "\n";
}
if (empty($recommendations)) {
echo " ✅ No major issues found!\n\n";
}
} catch (\Throwable $e) {
echo " ❌ Error: {$e->getMessage()}\n\n";
}
echo "4. Testing dependency path finding:\n";
try {
$analyzer = new DependencyAnalyzer($reflectionProvider);
$analysisResult = $analyzer->analyzeWithCircularDetection([
'App\\Framework\\DI\\DefaultContainer',
'App\\Framework\\Reflection\\ReflectionProvider',
'App\\Framework\\Reflection\\CachedReflectionProvider',
]);
$graph = $analysisResult->getGraph();
$fromClass = ClassName::create('App\\Framework\\DI\\DefaultContainer');
$toClass = ClassName::create('App\\Framework\\Reflection\\ReflectionProvider');
$path = $graph->getDependencyPath($fromClass, $toClass);
if ($path !== null) {
echo " ✅ Dependency path found:\n";
echo " 📍 From: {$fromClass->getShortName()}\n";
echo " 📍 To: {$toClass->getShortName()}\n";
echo " 🛤️ Path: " . implode(' -> ', array_map(fn ($class) => basename(str_replace('\\', '/', $class)), $path)) . "\n";
echo " 📏 Length: " . count($path) . "\n\n";
} else {
echo " No dependency path found between DefaultContainer and ReflectionProvider\n\n";
}
} catch (\Throwable $e) {
echo " ❌ Error: {$e->getMessage()}\n\n";
}
echo "5. Testing graph statistics and analysis:\n";
try {
$analyzer = new DependencyAnalyzer($reflectionProvider);
// Test with more comprehensive class set
$allClasses = [
'App\\Framework\\DI\\DefaultContainer',
'App\\Framework\\Router\\ValueObjects\\RoutePath',
'App\\Framework\\Router\\ValueObjects\\RouteGroup',
'App\\Framework\\Router\\ValueObjects\\GroupRoute',
'App\\Framework\\TypeCaster\\TypeCasterRegistry',
'App\\Framework\\Core\\ValueObjects\\ClassName',
'App\\Framework\\Http\\Method',
];
$analysisResult = $analyzer->analyzeWithCircularDetection($allClasses);
$graph = $analysisResult->getGraph();
echo " 📊 Detailed Graph Analysis:\n";
// Top complex nodes
$topComplex = $graph->getHighestDependencyNodes(3);
echo " 🔺 Most Complex Classes:\n";
foreach ($topComplex as $node) {
echo "{$node->getClassName()->getShortName()}: complexity {$node->getComplexityScore()}\n";
}
echo "\n";
// Most used nodes
$mostUsed = $graph->getMostUsedNodes(3);
echo " 🌟 Most Used Classes:\n";
foreach ($mostUsed as $node) {
echo "{$node->getClassName()->getShortName()}: {$node->getDependentCount()} dependents\n";
}
echo "\n";
// Leaf nodes
$leafNodes = $graph->getLeafNodes();
echo " 🍃 Leaf Nodes (no dependencies):\n";
foreach (array_slice($leafNodes, 0, 5) as $node) {
echo "{$node->getClassName()->getShortName()} ({$node->getType()->value})\n";
}
echo "\n";
// Root nodes
$rootNodes = $graph->getRootNodes();
echo " 🌳 Root Nodes (no dependents):\n";
foreach (array_slice($rootNodes, 0, 5) as $node) {
echo "{$node->getClassName()->getShortName()} ({$node->getType()->value})\n";
}
echo "\n";
} catch (\Throwable $e) {
echo " ❌ Error: {$e->getMessage()}\n\n";
}
echo "=== Dependency Graph Analysis Test Completed ===\n";