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,272 @@
<?php
declare(strict_types=1);
use App\Framework\Core\ValueObjects\Duration;
use App\Framework\DateTime\SystemClock;
use App\Framework\DDoS\Response\ValueObjects\DDoSResponse;
require_once __DIR__ . '/../../Helpers/TestHelpers.php';
beforeEach(function () {
$this->clock = new SystemClock();
});
describe('DDoSResponse', function () {
it('creates allow response correctly', function () {
$response = DDoSResponse::allow();
expect($response->action)->toBe('allow');
expect($response->shouldBlock)->toBeFalse();
expect($response->httpStatusCode)->toBe(200);
expect($response->blockDuration)->toBeNull();
});
it('creates rate limit response with headers', function () {
$response = DDoSResponse::rateLimit(
limit: 60,
remaining: 45,
resetTime: $this->clock->time()->add(Duration::fromMinutes(1))
);
expect($response->action)->toBe('rate_limit');
expect($response->shouldBlock)->toBeFalse();
expect($response->httpStatusCode)->toBe(429);
expect($response->rateLimitHeaders)->toHaveKeys([
'X-RateLimit-Limit',
'X-RateLimit-Remaining',
'X-RateLimit-Reset',
]);
expect($response->rateLimitHeaders['X-RateLimit-Limit'])->toBe('60');
expect($response->rateLimitHeaders['X-RateLimit-Remaining'])->toBe('45');
});
it('creates block response with duration', function () {
$blockDuration = Duration::fromMinutes(30);
$response = DDoSResponse::block(
duration: $blockDuration,
reason: 'Malicious activity detected'
);
expect($response->action)->toBe('block');
expect($response->shouldBlock)->toBeTrue();
expect($response->httpStatusCode)->toBe(403);
expect($response->blockDuration)->toBe($blockDuration);
expect($response->blockReason)->toBe('Malicious activity detected');
});
it('creates captcha challenge response', function () {
$challengeData = [
'captcha_token' => 'abc123',
'challenge_url' => '/captcha/verify',
'expires_at' => time() + 300,
];
$response = DDoSResponse::captchaChallenge($challengeData);
expect($response->action)->toBe('captcha_challenge');
expect($response->shouldBlock)->toBeFalse();
expect($response->httpStatusCode)->toBe(202);
expect($response->challengeData)->toBe($challengeData);
expect($response->challengeData['captcha_token'])->toBe('abc123');
});
it('creates proof of work challenge response', function () {
$challengeData = [
'difficulty' => 4,
'challenge' => 'find_hash_with_4_leading_zeros',
'algorithm' => 'sha256',
'expires_at' => time() + 600,
];
$response = DDoSResponse::proofOfWork($challengeData);
expect($response->action)->toBe('proof_of_work');
expect($response->shouldBlock)->toBeFalse();
expect($response->httpStatusCode)->toBe(202);
expect($response->challengeData)->toBe($challengeData);
expect($response->challengeData['difficulty'])->toBe(4);
});
it('adds custom response headers', function () {
$response = DDoSResponse::allow()
->withHeader('X-DDoS-Protection', 'Active')
->withHeader('X-Request-ID', 'req-123');
expect($response->responseHeaders)->toHaveKeys([
'X-DDoS-Protection',
'X-Request-ID',
]);
expect($response->responseHeaders['X-DDoS-Protection'])->toBe('Active');
expect($response->responseHeaders['X-Request-ID'])->toBe('req-123');
});
it('sets security event logging', function () {
$logContext = [
'client_ip' => '192.168.1.100',
'threat_level' => 'HIGH',
'attack_patterns' => ['VOLUMETRIC_ATTACK'],
];
$response = DDoSResponse::block(Duration::fromMinutes(15), 'High threat detected')
->withSecurityEvent($logContext);
expect($response->securityEventLogged)->toBeTrue();
expect($response->logContext)->toBe($logContext);
});
it('adds response metrics', function () {
$metrics = [
'processing_time_ms' => 25,
'decision_confidence' => 0.8,
'escalation_level' => 2,
'historical_offenses' => 3,
];
$response = DDoSResponse::rateLimit(60, 30, $this->clock->time())
->withMetrics($metrics);
expect($response->metrics)->toBe($metrics);
expect($response->metrics['processing_time_ms'])->toBe(25);
expect($response->metrics['decision_confidence'])->toBe(0.8);
});
it('adds additional protective measures', function () {
$measures = ['enhanced_logging', 'alert_security_team', 'increase_monitoring'];
$response = DDoSResponse::block(Duration::fromHours(1), 'Critical threat')
->withAdditionalMeasures($measures);
expect($response->additionalMeasures)->toBe($measures);
expect($response->additionalMeasures)->toContain('enhanced_logging');
expect($response->additionalMeasures)->toContain('alert_security_team');
});
it('converts to HTTP response array', function () {
$response = DDoSResponse::rateLimit(60, 45, $this->clock->time())
->withHeader('X-Protection', 'Active')
->withMetrics(['processing_time_ms' => 30]);
$httpResponse = $response->toHttpResponse();
expect($httpResponse)->toHaveKeys([
'status_code',
'headers',
'body',
]);
expect($httpResponse['status_code'])->toBe(429);
expect($httpResponse['headers'])->toHaveKey('X-RateLimit-Limit');
expect($httpResponse['headers'])->toHaveKey('X-Protection');
expect($httpResponse['body'])->toContain('Rate limit exceeded');
});
it('exports to array for serialization', function () {
$response = DDoSResponse::block(Duration::fromMinutes(30), 'Threat detected')
->withMetrics(['confidence' => 0.9])
->withSecurityEvent(['ip' => '192.168.1.100']);
$array = $response->toArray();
expect($array)->toHaveKeys([
'action',
'should_block',
'http_status_code',
'block_duration_seconds',
'block_reason',
'response_headers',
'metrics',
'security_event_logged',
'log_context',
]);
expect($array['action'])->toBe('block');
expect($array['should_block'])->toBeTrue();
expect($array['block_duration_seconds'])->toBe(1800); // 30 minutes
});
it('creates response from array data', function () {
$data = [
'action' => 'rate_limit',
'should_block' => false,
'http_status_code' => 429,
'rate_limit_headers' => [
'X-RateLimit-Limit' => '60',
'X-RateLimit-Remaining' => '30',
],
'response_headers' => ['X-Protection' => 'Active'],
'metrics' => ['processing_time_ms' => 40],
];
$response = DDoSResponse::fromArray($data);
expect($response->action)->toBe('rate_limit');
expect($response->shouldBlock)->toBeFalse();
expect($response->httpStatusCode)->toBe(429);
expect($response->rateLimitHeaders['X-RateLimit-Limit'])->toBe('60');
expect($response->responseHeaders['X-Protection'])->toBe('Active');
expect($response->metrics['processing_time_ms'])->toBe(40);
});
it('validates response consistency', function () {
$blockResponse = DDoSResponse::block(Duration::fromMinutes(15), 'Threat');
$allowResponse = DDoSResponse::allow();
expect($blockResponse->shouldBlock)->toBeTrue();
expect($blockResponse->action)->toBe('block');
expect($blockResponse->httpStatusCode)->toBe(403);
expect($allowResponse->shouldBlock)->toBeFalse();
expect($allowResponse->action)->toBe('allow');
expect($allowResponse->httpStatusCode)->toBe(200);
});
it('handles challenge expiration', function () {
$challengeData = [
'captcha_token' => 'abc123',
'expires_at' => time() - 300, // Expired 5 minutes ago
];
$response = DDoSResponse::captchaChallenge($challengeData);
expect($response->isChallengeExpired())->toBeTrue();
$challengeData['expires_at'] = time() + 300; // Expires in 5 minutes
$response = DDoSResponse::captchaChallenge($challengeData);
expect($response->isChallengeExpired())->toBeFalse();
});
it('calculates response severity', function () {
$allowResponse = DDoSResponse::allow();
$rateLimitResponse = DDoSResponse::rateLimit(60, 30, $this->clock->time());
$blockResponse = DDoSResponse::block(Duration::fromHours(1), 'Critical');
expect($allowResponse->getSeverity())->toBe('low');
expect($rateLimitResponse->getSeverity())->toBe('medium');
expect($blockResponse->getSeverity())->toBe('high');
});
it('provides response recommendations', function () {
$response = DDoSResponse::block(Duration::fromMinutes(30), 'Volumetric attack')
->withAdditionalMeasures(['monitor_traffic', 'alert_ops']);
$recommendations = $response->getRecommendations();
expect($recommendations)->toBeArray();
expect($recommendations)->toContain('Review traffic patterns');
expect($recommendations)->toContain('Consider IP reputation check');
});
it('tracks response effectiveness', function () {
$response = DDoSResponse::rateLimit(60, 30, $this->clock->time());
// Simulate tracking effectiveness
$response->recordEffectiveness(0.8, 'Successfully reduced request rate');
expect($response->getEffectivenessScore())->toBe(0.8);
expect($response->getEffectivenessNote())->toBe('Successfully reduced request rate');
});
});