cache = new GeneralCache($inMemoryCache, $serializer); }); 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 () { // No access patterns in cache (cache miss) $strategy = new PredictiveWarmingStrategy($this->cache); expect($strategy->shouldRun())->toBeFalse(); }); it('should run with sufficient access patterns', function () { // Set up access patterns in cache (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), ]; } // Store in cache with the key that PredictiveWarmingStrategy uses $key = CacheKey::fromString('warmup_access_patterns'); $this->cache->set(CacheItem::forSet($key, $accessPatterns, Duration::fromHours(1))); $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 () { // Set up 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; // Store access patterns in cache $key = CacheKey::fromString('warmup_access_patterns'); $this->cache->set(CacheItem::forSet($key, $accessPatterns)); $strategy = new PredictiveWarmingStrategy($this->cache); $result = $strategy->warmup(); // Result should complete without errors expect($result->itemsFailed)->toBe(0); }); 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), ], ]; // Store low probability access patterns in cache $key = CacheKey::fromString('warmup_access_patterns'); $this->cache->set(CacheItem::forSet($key, $accessPatterns)); $strategy = new PredictiveWarmingStrategy($this->cache); $result = $strategy->warmup(); // No items warmed due to low probability expect($result->itemsWarmed)->toBe(0); }); });