- Add comprehensive health check system with multiple endpoints - Add Prometheus metrics endpoint - Add production logging configurations (5 strategies) - Add complete deployment documentation suite: * QUICKSTART.md - 30-minute deployment guide * DEPLOYMENT_CHECKLIST.md - Printable verification checklist * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference * production-logging.md - Logging configuration guide * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation * README.md - Navigation hub * DEPLOYMENT_SUMMARY.md - Executive summary - Add deployment scripts and automation - Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment - Update README with production-ready features All production infrastructure is now complete and ready for deployment.
129 lines
4.1 KiB
PHP
129 lines
4.1 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
use App\Framework\Cache\Cache;
|
|
use App\Framework\Cache\Warming\Strategies\PredictiveWarmingStrategy;
|
|
use App\Framework\Cache\Warming\ValueObjects\WarmupPriority;
|
|
|
|
describe('PredictiveWarmingStrategy', function () {
|
|
beforeEach(function () {
|
|
$this->cache = Mockery::mock(Cache::class);
|
|
});
|
|
|
|
afterEach(function () {
|
|
Mockery::close();
|
|
});
|
|
|
|
it('has correct name', function () {
|
|
$strategy = new PredictiveWarmingStrategy($this->cache);
|
|
|
|
expect($strategy->getName())->toBe('predictive');
|
|
});
|
|
|
|
it('has background priority', function () {
|
|
$strategy = new PredictiveWarmingStrategy($this->cache);
|
|
|
|
expect($strategy->getPriority())->toBe(WarmupPriority::BACKGROUND->value);
|
|
});
|
|
|
|
it('should not run without sufficient access patterns', function () {
|
|
$this->cache->shouldReceive('get')
|
|
->andReturn(null); // No access patterns available
|
|
|
|
$strategy = new PredictiveWarmingStrategy($this->cache);
|
|
|
|
expect($strategy->shouldRun())->toBeFalse();
|
|
});
|
|
|
|
it('should run with sufficient access patterns', function () {
|
|
// Mock access patterns (10+ patterns)
|
|
$accessPatterns = [];
|
|
for ($i = 0; $i < 15; $i++) {
|
|
$accessPatterns["pattern_{$i}"] = [
|
|
'access_count' => 10 + $i,
|
|
'hourly_distribution' => array_fill(0, 24, 0.04),
|
|
'daily_distribution' => array_fill(0, 7, 0.14),
|
|
];
|
|
}
|
|
|
|
$this->cache->shouldReceive('get')
|
|
->andReturn($accessPatterns);
|
|
|
|
$strategy = new PredictiveWarmingStrategy($this->cache);
|
|
|
|
expect($strategy->shouldRun())->toBeTrue();
|
|
});
|
|
|
|
it('estimates reasonable duration', function () {
|
|
$strategy = new PredictiveWarmingStrategy($this->cache);
|
|
|
|
$duration = $strategy->getEstimatedDuration();
|
|
|
|
expect($duration)->toBeGreaterThan(0);
|
|
expect($duration)->toBeLessThan(300); // Should be < 5 minutes
|
|
});
|
|
|
|
it('warms predicted cache keys', function () {
|
|
// Mock access patterns with high probability
|
|
$currentHour = (int) date('G');
|
|
$currentDay = (int) date('N') - 1;
|
|
|
|
$accessPatterns = [
|
|
'key1' => [
|
|
'access_count' => 50,
|
|
'hourly_distribution' => array_fill(0, 24, 0.04),
|
|
'daily_distribution' => array_fill(0, 7, 0.14),
|
|
],
|
|
'key2' => [
|
|
'access_count' => 30,
|
|
'hourly_distribution' => array_fill(0, 24, 0.04),
|
|
'daily_distribution' => array_fill(0, 7, 0.14),
|
|
],
|
|
];
|
|
|
|
// Boost current hour/day to ensure high probability
|
|
$accessPatterns['key1']['hourly_distribution'][$currentHour] = 0.5;
|
|
$accessPatterns['key1']['daily_distribution'][$currentDay] = 0.5;
|
|
|
|
$this->cache->shouldReceive('get')
|
|
->with(Mockery::pattern('/access_patterns/'))
|
|
->andReturn($accessPatterns);
|
|
|
|
$this->cache->shouldReceive('get')
|
|
->with(Mockery::pattern('/^key[12]$/'))
|
|
->andReturn(null); // Cache miss
|
|
|
|
$this->cache->shouldReceive('set')
|
|
->atLeast(1)
|
|
->andReturn(true);
|
|
|
|
$strategy = new PredictiveWarmingStrategy($this->cache);
|
|
$result = $strategy->warmup();
|
|
|
|
expect($result->isSuccess())->toBeTrue();
|
|
});
|
|
|
|
it('skips low probability keys', function () {
|
|
$accessPatterns = [
|
|
'low_prob_key' => [
|
|
'access_count' => 2, // Below MIN_ACCESS_COUNT
|
|
'hourly_distribution' => array_fill(0, 24, 0.01),
|
|
'daily_distribution' => array_fill(0, 7, 0.01),
|
|
],
|
|
];
|
|
|
|
$this->cache->shouldReceive('get')
|
|
->with(Mockery::pattern('/access_patterns/'))
|
|
->andReturn($accessPatterns);
|
|
|
|
$this->cache->shouldNotReceive('set'); // Should not warm low probability
|
|
|
|
$strategy = new PredictiveWarmingStrategy($this->cache);
|
|
$result = $strategy->warmup();
|
|
|
|
// No items warmed due to low probability
|
|
expect($result->itemsWarmed)->toBe(0);
|
|
});
|
|
});
|