Enable Discovery debug logging for production troubleshooting

- Add DISCOVERY_LOG_LEVEL=debug
- Add DISCOVERY_SHOW_PROGRESS=true
- Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
2025-08-11 20:13:26 +02:00
parent 59fd3dd3b1
commit 55a330b223
3683 changed files with 2956207 additions and 16948 deletions

View File

@@ -0,0 +1,218 @@
<?php
declare(strict_types=1);
use App\Framework\Core\ValueObjects\Duration;
use App\Framework\DateTime\SystemClock;
use App\Framework\DDoS\DDoSConfig;
use App\Framework\DDoS\ValueObjects\ThreatLevel;
require_once __DIR__ . '/Helpers/TestHelpers.php';
beforeEach(function () {
$this->clock = new SystemClock();
// Create DDoS config for testing
$this->config = new DDoSConfig(
enabled: true,
volumetricThreshold: 100.0, // Lower threshold for faster testing
distributedThreshold: 0.8,
analysisWindow: Duration::fromMinutes(5),
trustedIps: ['127.0.0.1', '::1'],
exemptPaths: ['/health', '/ping']
);
// Mock the engine (we'll need to set up proper DI for real tests)
$this->engine = $this->createMockEngine();
});
describe('DDoS Protection Engine', function () {
it('allows normal requests through', function () {
$request = createTestRequest('192.168.1.100', 'GET', '/api/users');
$assessment = $this->engine->assessRequest($request);
expect($assessment->threatLevel)->toBe(ThreatLevel::LOW);
expect($assessment->shouldBlock)->toBeFalse();
expect($assessment->threatScore)->toBeLessThan(0.3);
});
it('detects high volume attacks from single IP', function () {
$attackerIp = '10.0.0.1';
$assessment = null;
// Simulate rapid requests from same IP
for ($i = 1; $i <= 20; $i++) {
$request = createTestRequest($attackerIp, 'GET', "/page{$i}");
$assessment = $this->engine->assessRequest($request);
if ($assessment->shouldBlock) {
break;
}
}
expect($assessment->threatLevel)->toBeIn([ThreatLevel::HIGH, ThreatLevel::CRITICAL]);
expect($assessment->shouldBlock)->toBeTrue();
expect($assessment->threatScore)->toBeGreaterThan(0.7);
});
it('detects distributed attacks', function () {
$attackIps = ['1.2.3.4', '5.6.7.8', '9.10.11.12', '13.14.15.16'];
$assessments = [];
foreach ($attackIps as $ip) {
for ($i = 1; $i <= 15; $i++) {
$request = createTestRequest($ip, 'POST', '/api/login');
$assessments[] = $this->engine->assessRequest($request);
}
}
// Should detect distributed pattern
$lastAssessment = end($assessments);
expect($lastAssessment->threatLevel)->toBeIn([ThreatLevel::MEDIUM, ThreatLevel::HIGH]);
expect($lastAssessment->threatScore)->toBeGreaterThan(0.4);
});
it('blocks suspicious bot traffic', function () {
$request = createTestRequest('192.168.1.200', 'GET', '/sensitive-data', [
'User-Agent' => 'BadBot/1.0 (automated scraper)',
]);
$assessment = $this->engine->assessRequest($request);
expect($assessment->threatLevel)->toBeIn([ThreatLevel::MEDIUM, ThreatLevel::HIGH]);
expect($assessment->threatScore)->toBeGreaterThan(0.5);
});
it('allows trusted IPs through', function () {
$request = createTestRequest('127.0.0.1', 'GET', '/admin/sensitive');
$assessment = $this->engine->assessRequest($request);
expect($assessment->threatLevel)->toBe(ThreatLevel::LOW);
expect($assessment->shouldBlock)->toBeFalse();
});
it('bypasses exempt paths', function () {
$request = createTestRequest('10.0.0.1', 'GET', '/health');
$assessment = $this->engine->assessRequest($request);
expect($assessment->threatLevel)->toBe(ThreatLevel::LOW);
expect($assessment->shouldBlock)->toBeFalse();
});
it('escalates threat level with repeated attacks', function () {
$attackerIp = '192.168.1.50';
$assessments = [];
// First wave - should be low threat
for ($i = 1; $i <= 5; $i++) {
$request = createTestRequest($attackerIp, 'GET', "/api/data{$i}");
$assessments[] = $this->engine->assessRequest($request);
}
expect($assessments[0]->threatLevel)->toBe(ThreatLevel::LOW);
// Second wave - should escalate
for ($i = 6; $i <= 25; $i++) {
$request = createTestRequest($attackerIp, 'GET', "/api/data{$i}");
$assessments[] = $this->engine->assessRequest($request);
}
$lastAssessment = end($assessments);
expect($lastAssessment->threatLevel)->toBeIn([ThreatLevel::MEDIUM, ThreatLevel::HIGH, ThreatLevel::CRITICAL]);
expect($lastAssessment->threatScore)->toBeGreaterThan($assessments[0]->threatScore);
});
it('handles malformed requests gracefully', function () {
$request = createTestRequest('invalid-ip', 'INVALID_METHOD', '');
$assessment = $this->engine->assessRequest($request);
// Should not crash and should treat as suspicious
expect($assessment)->not()->toBeNull();
expect($assessment->threatLevel)->toBeIn([ThreatLevel::MEDIUM, ThreatLevel::HIGH]);
});
it('provides detailed assessment information', function () {
$request = createTestRequest('192.168.1.100', 'GET', '/api/test');
$assessment = $this->engine->assessRequest($request);
expect($assessment)->toHaveProperties([
'threatLevel',
'threatScore',
'shouldBlock',
'detectedPatterns',
'responseRecommendation',
]);
expect($assessment->threatScore)->toBeBetween(0.0, 1.0);
});
});
describe('DDoS Configuration', function () {
it('respects custom thresholds', function () {
$strictConfig = new DDoSConfig(
volumetricThreshold: 10.0, // Very low threshold
highThreatThreshold: 0.3 // Lower threshold for high threat
);
$engine = createEngineWithConfig($strictConfig);
$request = createTestRequest('192.168.1.100', 'GET', '/api/test');
// With strict config, even normal requests might be flagged
$assessment = $engine->assessRequest($request);
expect($assessment)->not()->toBeNull();
});
it('can be disabled', function () {
$disabledConfig = new DDoSConfig(enabled: false);
$engine = createEngineWithConfig($disabledConfig);
$request = createTestRequest('10.0.0.1', 'GET', '/api/test');
$assessment = $engine->assessRequest($request);
expect($assessment->threatLevel)->toBe(ThreatLevel::LOW);
expect($assessment->shouldBlock)->toBeFalse();
});
});
describe('Performance', function () {
it('completes assessment within reasonable time', function () {
$start = microtime(true);
$request = createTestRequest('192.168.1.100', 'GET', '/api/test');
$assessment = $this->engine->assessRequest($request);
$duration = microtime(true) - $start;
expect($duration)->toBeLessThan(0.1); // Should complete within 100ms
expect($assessment)->not()->toBeNull();
});
it('handles high request volume efficiently', function () {
$start = microtime(true);
// Process 100 requests
for ($i = 1; $i <= 100; $i++) {
$ip = '192.168.1.' . ($i % 254 + 1);
$request = createTestRequest($ip, 'GET', "/api/test{$i}");
$this->engine->assessRequest($request);
}
$duration = microtime(true) - $start;
$avgPerRequest = $duration / 100;
expect($avgPerRequest)->toBeLessThan(0.01); // Average <10ms per request
});
});
// Helper functions are now in Helpers/TestHelpers.php