Skip to content

Commit

Permalink
[Cache] Use correct expiry in ChainAdapter
Browse files Browse the repository at this point in the history
  • Loading branch information
Nyholm authored and nicolas-grekas committed Oct 21, 2020
1 parent e693b3c commit 17e0167
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 1 deletion.
4 changes: 3 additions & 1 deletion src/Symfony/Component/Cache/Adapter/ChainAdapter.php
Expand Up @@ -73,7 +73,9 @@ static function ($sourceItem, $item, $sourceMetadata = null) use ($defaultLifeti
$item->isHit = $sourceItem->isHit;
$item->metadata = $item->newMetadata = $sourceItem->metadata = $sourceMetadata;

if (0 < $defaultLifetime) {
if (isset($item->metadata[CacheItem::METADATA_EXPIRY])) {
$item->expiresAt(\DateTime::createFromFormat('U.u', $item->metadata[CacheItem::METADATA_EXPIRY]));
} elseif (0 < $defaultLifetime) {
$item->expiresAfter($defaultLifetime);
}

Expand Down
49 changes: 49 additions & 0 deletions src/Symfony/Component/Cache/Tests/Adapter/ChainAdapterTest.php
Expand Up @@ -16,8 +16,10 @@
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\ChainAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter;
use Symfony\Component\Cache\Tests\Fixtures\PrunableAdapter;
use Symfony\Contracts\Cache\ItemInterface;

/**
* @author Kévin Dunglas <dunglas@gmail.com>
Expand All @@ -34,6 +36,11 @@ public function createCachePool(int $defaultLifetime = 0, string $testMethod = n
return new ChainAdapter([new ArrayAdapter($defaultLifetime), new ExternalAdapter($defaultLifetime), new FilesystemAdapter('', $defaultLifetime)], $defaultLifetime);
}

public static function tearDownAfterClass(): void
{
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
}

public function testEmptyAdaptersException()
{
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
Expand Down Expand Up @@ -187,6 +194,48 @@ public function testMultipleCachesExpirationWhenCommonTtlIsSet()
$this->assertFalse($item->isHit());
}

public function testExpirationOnAllAdapters()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}

$itemValidator = function (CacheItem $item) {
$refl = new \ReflectionObject($item);
$propExpiry = $refl->getProperty('expiry');
$propExpiry->setAccessible(true);
$expiry = $propExpiry->getValue($item);
$this->assertGreaterThan(10, $expiry - time(), 'Item should be saved with the given ttl, not the default for the adapter.');

return true;
};

$adapter1 = $this->getMockBuilder(FilesystemAdapter::class)
->setConstructorArgs(['', 2])
->setMethods(['save'])
->getMock();
$adapter1->expects($this->once())
->method('save')
->with($this->callback($itemValidator))
->willReturn(true);

$adapter2 = $this->getMockBuilder(FilesystemAdapter::class)
->setConstructorArgs(['', 4])
->setMethods(['save'])
->getMock();
$adapter2->expects($this->once())
->method('save')
->with($this->callback($itemValidator))
->willReturn(true);

$cache = new ChainAdapter([$adapter1, $adapter2], 6);
$cache->get('test_key', function (ItemInterface $item) {
$item->expiresAfter(15);

return 'chain';
});
}

private function getPruneableMock(): AdapterInterface
{
$pruneable = $this->createMock(PrunableAdapter::class);
Expand Down

0 comments on commit 17e0167

Please sign in to comment.