Upgrade 1-11.38

This commit is contained in:
xesmyd
2026-03-30 14:10:30 +02:00
parent f2a7e6d1fc
commit ac648ef29d
24665 changed files with 69682 additions and 2205004 deletions
@@ -28,18 +28,19 @@ abstract class AbstractRedisAdapterTest extends AdapterTestCase
return new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
}
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
if (!\extension_loaded('redis')) {
self::markTestSkipped('Extension redis required.');
}
if (!@((new \Redis())->connect(getenv('REDIS_HOST')))) {
$e = error_get_last();
self::markTestSkipped($e['message']);
try {
(new \Redis())->connect(getenv('REDIS_HOST'));
} catch (\Exception $e) {
self::markTestSkipped($e->getMessage());
}
}
public static function tearDownAfterClass(): void
public static function tearDownAfterClass()
{
self::$redis = null;
}
+12 -100
View File
@@ -12,117 +12,24 @@
namespace Symfony\Component\Cache\Tests\Adapter;
use Cache\IntegrationTests\CachePoolTest;
use PHPUnit\Framework\Assert;
use Psr\Cache\CacheItemInterface;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\CacheItem;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Contracts\Cache\CallbackInterface;
abstract class AdapterTestCase extends CachePoolTest
{
protected function setUp(): void
protected function setUp()
{
parent::setUp();
if (!\array_key_exists('testDeferredSaveWithoutCommit', $this->skippedTests) && \defined('HHVM_VERSION')) {
$this->skippedTests['testDeferredSaveWithoutCommit'] = 'Destructors are called late on HHVM.';
}
if (!\array_key_exists('testPrune', $this->skippedTests) && !$this->createCachePool() instanceof PruneableInterface) {
$this->skippedTests['testPrune'] = 'Not a pruneable cache pool.';
}
}
public function testGet()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
$cache = $this->createCachePool();
$cache->clear();
$value = mt_rand();
$this->assertSame($value, $cache->get('foo', function (CacheItem $item) use ($value) {
$this->assertSame('foo', $item->getKey());
return $value;
}));
$item = $cache->getItem('foo');
$this->assertSame($value, $item->get());
$isHit = true;
$this->assertSame($value, $cache->get('foo', function (CacheItem $item) use (&$isHit) { $isHit = false; }, 0));
$this->assertTrue($isHit);
$this->assertNull($cache->get('foo', function (CacheItem $item) use (&$isHit, $value) {
$isHit = false;
$this->assertTrue($item->isHit());
$this->assertSame($value, $item->get());
}, INF));
$this->assertFalse($isHit);
$this->assertSame($value, $cache->get('bar', new class($value) implements CallbackInterface {
private $value;
public function __construct(int $value)
{
$this->value = $value;
}
public function __invoke(CacheItemInterface $item, bool &$save)
{
Assert::assertSame('bar', $item->getKey());
return $this->value;
}
}));
}
public function testRecursiveGet()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
$cache = $this->createCachePool(0, __FUNCTION__);
$v = $cache->get('k1', function () use (&$counter, $cache) {
$cache->get('k2', function () use (&$counter) { return ++$counter; });
$v = $cache->get('k2', function () use (&$counter) { return ++$counter; }); // ensure the callback is called once
return $v;
});
$this->assertSame(1, $counter);
$this->assertSame(1, $v);
$this->assertSame(1, $cache->get('k2', function () { return 2; }));
}
public function testGetMetadata()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
$cache = $this->createCachePool(0, __FUNCTION__);
$cache->deleteItem('foo');
$cache->get('foo', function ($item) {
$item->expiresAfter(10);
usleep(999000);
return 'bar';
});
$item = $cache->getItem('foo');
$expected = [
CacheItem::METADATA_EXPIRY => 9.5 + time(),
CacheItem::METADATA_CTIME => 1000,
];
$this->assertEqualsWithDelta($expected, $item->getMetadata(), .6, 'Item metadata should embed expiry and ctime.');
}
public function testDefaultLifeTime()
{
if (isset($this->skippedTests[__FUNCTION__])) {
@@ -254,9 +161,14 @@ abstract class AdapterTestCase extends CachePoolTest
}
}
class NotUnserializable
class NotUnserializable implements \Serializable
{
public function __wakeup()
public function serialize()
{
return serialize(123);
}
public function unserialize($ser)
{
throw new \Exception(__CLASS__);
}
+4 -4
View File
@@ -24,10 +24,10 @@ class ApcuAdapterTest extends AdapterTestCase
public function createCachePool($defaultLifetime = 0)
{
if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN)) {
if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN)) {
$this->markTestSkipped('APCu extension is required.');
}
if ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN)) {
if ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN)) {
if ('testWithCliSapi' !== $this->getName()) {
$this->markTestSkipped('apc.enable_cli=1 is required.');
}
@@ -54,7 +54,7 @@ class ApcuAdapterTest extends AdapterTestCase
public function testVersion()
{
$namespace = str_replace('\\', '.', \get_class($this));
$namespace = str_replace('\\', '.', static::class);
$pool1 = new ApcuAdapter($namespace, 0, 'p1');
@@ -79,7 +79,7 @@ class ApcuAdapterTest extends AdapterTestCase
public function testNamespace()
{
$namespace = str_replace('\\', '.', \get_class($this));
$namespace = str_replace('\\', '.', static::class);
$pool1 = new ApcuAdapter($namespace.'_1', 0, 'p1');
+3 -4
View File
@@ -19,7 +19,6 @@ use Symfony\Component\Cache\Adapter\ArrayAdapter;
class ArrayAdapterTest extends AdapterTestCase
{
protected $skippedTests = [
'testGetMetadata' => 'ArrayAdapter does not keep metadata.',
'testDeferredSaveWithoutCommit' => 'Assumes a shared cache which ArrayAdapter is not.',
'testSaveWithoutExpire' => 'Assumes a shared cache which ArrayAdapter is not.',
];
@@ -36,12 +35,12 @@ class ArrayAdapterTest extends AdapterTestCase
// Hit
$item = $cache->getItem('foo');
$item->set('::4711');
$item->set('4711');
$cache->save($item);
$fooItem = $cache->getItem('foo');
$this->assertTrue($fooItem->isHit());
$this->assertEquals('::4711', $fooItem->get());
$this->assertEquals('4711', $fooItem->get());
// Miss (should be present as NULL in $values)
$cache->getItem('bar');
@@ -50,7 +49,7 @@ class ArrayAdapterTest extends AdapterTestCase
$this->assertCount(2, $values);
$this->assertArrayHasKey('foo', $values);
$this->assertSame(serialize('::4711'), $values['foo']);
$this->assertSame(serialize('4711'), $values['foo']);
$this->assertArrayHasKey('bar', $values);
$this->assertNull($values['bar']);
}
+120 -6
View File
@@ -25,13 +25,9 @@ use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter;
*/
class ChainAdapterTest extends AdapterTestCase
{
public function createCachePool($defaultLifetime = 0, $testMethod = null)
public function createCachePool($defaultLifetime = 0)
{
if ('testGetMetadata' === $testMethod) {
return new ChainAdapter([new FilesystemAdapter('a', $defaultLifetime), new FilesystemAdapter('b', $defaultLifetime)], $defaultLifetime);
}
return new ChainAdapter([new ArrayAdapter($defaultLifetime), new ExternalAdapter(), new FilesystemAdapter('', $defaultLifetime)], $defaultLifetime);
return new ChainAdapter([new ArrayAdapter($defaultLifetime), new ExternalAdapter($defaultLifetime), new FilesystemAdapter('', $defaultLifetime)], $defaultLifetime);
}
public function testEmptyAdaptersException()
@@ -69,6 +65,124 @@ class ChainAdapterTest extends AdapterTestCase
$this->assertFalse($cache->prune());
}
public function testMultipleCachesExpirationWhenCommonTtlIsNotSet()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
$adapter1 = new ArrayAdapter(4);
$adapter2 = new ArrayAdapter(2);
$cache = new ChainAdapter([$adapter1, $adapter2]);
$cache->save($cache->getItem('key')->set('value'));
$item = $adapter1->getItem('key');
$this->assertTrue($item->isHit());
$this->assertEquals('value', $item->get());
$item = $adapter2->getItem('key');
$this->assertTrue($item->isHit());
$this->assertEquals('value', $item->get());
sleep(2);
$item = $adapter1->getItem('key');
$this->assertTrue($item->isHit());
$this->assertEquals('value', $item->get());
$item = $adapter2->getItem('key');
$this->assertFalse($item->isHit());
sleep(2);
$item = $adapter1->getItem('key');
$this->assertFalse($item->isHit());
$adapter2->save($adapter2->getItem('key1')->set('value1'));
$item = $cache->getItem('key1');
$this->assertTrue($item->isHit());
$this->assertEquals('value1', $item->get());
sleep(2);
$item = $adapter1->getItem('key1');
$this->assertTrue($item->isHit());
$this->assertEquals('value1', $item->get());
$item = $adapter2->getItem('key1');
$this->assertFalse($item->isHit());
sleep(2);
$item = $adapter1->getItem('key1');
$this->assertFalse($item->isHit());
}
public function testMultipleCachesExpirationWhenCommonTtlIsSet()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
$adapter1 = new ArrayAdapter(4);
$adapter2 = new ArrayAdapter(2);
$cache = new ChainAdapter([$adapter1, $adapter2], 6);
$cache->save($cache->getItem('key')->set('value'));
$item = $adapter1->getItem('key');
$this->assertTrue($item->isHit());
$this->assertEquals('value', $item->get());
$item = $adapter2->getItem('key');
$this->assertTrue($item->isHit());
$this->assertEquals('value', $item->get());
sleep(2);
$item = $adapter1->getItem('key');
$this->assertTrue($item->isHit());
$this->assertEquals('value', $item->get());
$item = $adapter2->getItem('key');
$this->assertFalse($item->isHit());
sleep(2);
$item = $adapter1->getItem('key');
$this->assertFalse($item->isHit());
$adapter2->save($adapter2->getItem('key1')->set('value1'));
$item = $cache->getItem('key1');
$this->assertTrue($item->isHit());
$this->assertEquals('value1', $item->get());
sleep(2);
$item = $adapter1->getItem('key1');
$this->assertTrue($item->isHit());
$this->assertEquals('value1', $item->get());
$item = $adapter2->getItem('key1');
$this->assertFalse($item->isHit());
sleep(2);
$item = $adapter1->getItem('key1');
$this->assertTrue($item->isHit());
$this->assertEquals('value1', $item->get());
sleep(2);
$item = $adapter1->getItem('key1');
$this->assertFalse($item->isHit());
}
/**
* @return MockObject|PruneableCacheInterface
*/
@@ -24,7 +24,7 @@ class FilesystemAdapterTest extends AdapterTestCase
return new FilesystemAdapter('', $defaultLifetime);
}
public static function tearDownAfterClass(): void
public static function tearDownAfterClass()
{
self::rmdir(sys_get_temp_dir().'/symfony-cache');
}
@@ -1,28 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\FilesystemTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
/**
* @group time-sensitive
*/
class FilesystemTagAwareAdapterTest extends FilesystemAdapterTest
{
use TagAwareTestTrait;
public function createCachePool($defaultLifetime = 0)
{
return new FilesystemTagAwareAdapter('', $defaultLifetime);
}
}
@@ -26,7 +26,7 @@ class MaxIdLengthAdapterTest extends TestCase
$cache->expects($this->exactly(2))
->method('doHave')
->withConsecutive(
[$this->equalTo('----------:nWfzGiCgLczv3SSUzXL3kg:')],
[$this->equalTo('----------:0GTYWa9n4ed8vqNlOT2iEr:')],
[$this->equalTo('----------:---------------------------------------')]
);
+11 -47
View File
@@ -23,7 +23,7 @@ class MemcachedAdapterTest extends AdapterTestCase
protected static $client;
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
if (!MemcachedAdapter::isSupported()) {
self::markTestSkipped('Extension memcached >=2.2.0 required.');
@@ -66,8 +66,14 @@ class MemcachedAdapterTest extends AdapterTestCase
*/
public function testBadOptions($name, $value)
{
$this->expectException('ErrorException');
$this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::');
if (\PHP_VERSION_ID < 80000) {
$this->expectException('ErrorException');
$this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::');
} else {
$this->expectException('Error');
$this->expectExceptionMessage('Undefined constant Memcached::');
}
MemcachedAdapter::createConnection([], [$name => $value]);
}
@@ -135,7 +141,7 @@ class MemcachedAdapterTest extends AdapterTestCase
'localhost',
11222,
];
if (filter_var(ini_get('memcached.use_sasl'), FILTER_VALIDATE_BOOLEAN)) {
if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) {
yield [
'memcached://user:password@127.0.0.1?weight=50',
'127.0.0.1',
@@ -152,7 +158,7 @@ class MemcachedAdapterTest extends AdapterTestCase
'/var/local/run/memcached.socket',
0,
];
if (filter_var(ini_get('memcached.use_sasl'), FILTER_VALIDATE_BOOLEAN)) {
if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) {
yield [
'memcached://user:password@/var/local/run/memcached.socket?weight=25',
'/var/local/run/memcached.socket',
@@ -195,46 +201,4 @@ class MemcachedAdapterTest extends AdapterTestCase
{
$this->assertTrue($this->createCachePool()->clear());
}
public function testMultiServerDsn()
{
$dsn = 'memcached:?host[localhost]&host[localhost:12345]&host[/some/memcached.sock:]=3';
$client = MemcachedAdapter::createConnection($dsn);
$expected = [
0 => [
'host' => 'localhost',
'port' => 11211,
'type' => 'TCP',
],
1 => [
'host' => 'localhost',
'port' => 12345,
'type' => 'TCP',
],
2 => [
'host' => '/some/memcached.sock',
'port' => 0,
'type' => 'SOCKET',
],
];
$this->assertSame($expected, $client->getServerList());
$dsn = 'memcached://localhost?host[foo.bar]=3';
$client = MemcachedAdapter::createConnection($dsn);
$expected = [
0 => [
'host' => 'localhost',
'port' => 11211,
'type' => 'TCP',
],
1 => [
'host' => 'foo.bar',
'port' => 11211,
'type' => 'TCP',
],
];
$this->assertSame($expected, $client->getServerList());
}
}
@@ -12,7 +12,6 @@
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\ProxyAdapter;
/**
@@ -20,12 +19,8 @@ use Symfony\Component\Cache\Adapter\ProxyAdapter;
*/
class NamespacedProxyAdapterTest extends ProxyAdapterTest
{
public function createCachePool($defaultLifetime = 0, $testMethod = null)
public function createCachePool($defaultLifetime = 0)
{
if ('testGetMetadata' === $testMethod) {
return new ProxyAdapter(new FilesystemAdapter(), 'foo', $defaultLifetime);
}
return new ProxyAdapter(new ArrayAdapter($defaultLifetime), 'foo', $defaultLifetime);
}
}
-13
View File
@@ -34,19 +34,6 @@ class NullAdapterTest extends TestCase
$this->assertNull($item->get(), "Item's value must be null when isHit is false.");
}
public function testGet()
{
$adapter = $this->createCachePool();
$fetched = [];
$adapter->get('myKey', function ($item) use (&$fetched) { $fetched[] = $item; });
$this->assertCount(1, $fetched);
$item = $fetched[0];
$this->assertFalse($item->isHit());
$this->assertNull($item->get(), "Item's value must be null when isHit is false.");
$this->assertSame('myKey', $item->getKey());
}
public function testHasItem()
{
$this->assertFalse($this->createCachePool()->hasItem('key'));
+2 -2
View File
@@ -23,7 +23,7 @@ class PdoAdapterTest extends AdapterTestCase
protected static $dbFile;
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
if (!\extension_loaded('pdo_sqlite')) {
self::markTestSkipped('Extension pdo_sqlite required.');
@@ -35,7 +35,7 @@ class PdoAdapterTest extends AdapterTestCase
$pool->createTable();
}
public static function tearDownAfterClass(): void
public static function tearDownAfterClass()
{
@unlink(self::$dbFile);
}
+5 -2
View File
@@ -24,16 +24,19 @@ class PdoDbalAdapterTest extends AdapterTestCase
protected static $dbFile;
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
if (!\extension_loaded('pdo_sqlite')) {
self::markTestSkipped('Extension pdo_sqlite required.');
}
self::$dbFile = tempnam(sys_get_temp_dir(), 'sf_sqlite_cache');
$pool = new PdoAdapter(DriverManager::getConnection(['driver' => 'pdo_sqlite', 'path' => self::$dbFile]));
$pool->createTable();
}
public static function tearDownAfterClass(): void
public static function tearDownAfterClass()
{
@unlink(self::$dbFile);
}
+10 -37
View File
@@ -12,7 +12,6 @@
namespace Symfony\Component\Cache\Tests\Adapter;
use Psr\Cache\CacheItemInterface;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\NullAdapter;
use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
@@ -22,8 +21,6 @@ use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
class PhpArrayAdapterTest extends AdapterTestCase
{
protected $skippedTests = [
'testGet' => 'PhpArrayAdapter is read-only.',
'testRecursiveGet' => 'PhpArrayAdapter is read-only.',
'testBasicUsage' => 'PhpArrayAdapter is read-only.',
'testBasicUsageWithLongKey' => 'PhpArrayAdapter is read-only.',
'testClear' => 'PhpArrayAdapter is read-only.',
@@ -58,12 +55,12 @@ class PhpArrayAdapterTest extends AdapterTestCase
protected static $file;
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php';
}
protected function tearDown(): void
protected function tearDown()
{
$this->createCachePool()->clear();
@@ -72,12 +69,8 @@ class PhpArrayAdapterTest extends AdapterTestCase
}
}
public function createCachePool($defaultLifetime = 0, $testMethod = null)
public function createCachePool()
{
if ('testGetMetadata' === $testMethod) {
return new PhpArrayAdapter(self::$file, new FilesystemAdapter());
}
return new PhpArrayAdapterWrapper(self::$file, new NullAdapter());
}
@@ -110,32 +103,16 @@ class PhpArrayAdapterTest extends AdapterTestCase
public function testStoredFile()
{
$data = [
$expected = [
'integer' => 42,
'float' => 42.42,
'boolean' => true,
'array_simple' => ['foo', 'bar'],
'array_associative' => ['foo' => 'bar', 'foo2' => 'bar2'],
];
$expected = [
[
'integer' => 0,
'float' => 1,
'boolean' => 2,
'array_simple' => 3,
'array_associative' => 4,
],
[
0 => 42,
1 => 42.42,
2 => true,
3 => ['foo', 'bar'],
4 => ['foo' => 'bar', 'foo2' => 'bar2'],
],
];
$adapter = $this->createCachePool();
$adapter->warmUp($data);
$adapter->warmUp($expected);
$values = eval(substr(file_get_contents(self::$file), 6));
@@ -145,17 +122,13 @@ class PhpArrayAdapterTest extends AdapterTestCase
class PhpArrayAdapterWrapper extends PhpArrayAdapter
{
protected $data = [];
public function save(CacheItemInterface $item)
{
(\Closure::bind(function () use ($item) {
$key = $item->getKey();
$this->keys[$key] = $id = \count($this->values);
$this->data[$key] = $this->values[$id] = $item->get();
$this->warmUp($this->data);
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
}, $this, PhpArrayAdapter::class))();
\call_user_func(\Closure::bind(function () use ($item) {
$this->values[$item->getKey()] = $item->get();
$this->warmUp($this->values);
$this->values = eval(substr(file_get_contents($this->file), 6));
}, $this, PhpArrayAdapter::class));
return true;
}
@@ -30,12 +30,12 @@ class PhpArrayAdapterWithFallbackTest extends AdapterTestCase
protected static $file;
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php';
}
protected function tearDown(): void
protected function tearDown()
{
$this->createCachePool()->clear();
@@ -1,31 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Adapter;
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
/**
* @group time-sensitive
*/
class PhpFilesAdapterAppendOnlyTest extends PhpFilesAdapterTest
{
protected $skippedTests = [
'testDefaultLifeTime' => 'PhpFilesAdapter does not allow configuring a default lifetime.',
'testExpiration' => 'PhpFilesAdapter in append-only mode does not expiration.',
];
public function createCachePool(): CacheItemPoolInterface
{
return new PhpFilesAdapter('sf-cache', 0, null, true);
}
}
+5 -1
View File
@@ -25,10 +25,14 @@ class PhpFilesAdapterTest extends AdapterTestCase
public function createCachePool()
{
if (!PhpFilesAdapter::isSupported()) {
$this->markTestSkipped('OPcache extension is not enabled.');
}
return new PhpFilesAdapter('sf-cache');
}
public static function tearDownAfterClass(): void
public static function tearDownAfterClass()
{
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
}
+10 -4
View File
@@ -16,7 +16,7 @@ use Symfony\Component\Cache\Adapter\RedisAdapter;
class PredisAdapterTest extends AbstractRedisAdapterTest
{
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
self::$redis = new \Predis\Client(['host' => getenv('REDIS_HOST')]);
@@ -35,12 +35,18 @@ class PredisAdapterTest extends AbstractRedisAdapterTest
$params = [
'scheme' => 'tcp',
'host' => $redisHost,
'path' => '',
'dbindex' => '1',
'port' => 6379,
'persistent' => 0,
'class' => 'Predis\Client',
'timeout' => 3,
'read_write_timeout' => 0,
'tcp_nodelay' => true,
'persistent' => 0,
'persistent_id' => null,
'read_timeout' => 0,
'retry_interval' => 0,
'lazy' => false,
'database' => '1',
'password' => null,
];
$this->assertSame($params, $connection->getParameters()->toArray());
}
@@ -13,13 +13,13 @@ namespace Symfony\Component\Cache\Tests\Adapter;
class PredisClusterAdapterTest extends AbstractRedisAdapterTest
{
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
self::$redis = new \Predis\Client([['host' => getenv('REDIS_HOST')]]);
}
public static function tearDownAfterClass(): void
public static function tearDownAfterClass()
{
self::$redis = null;
}
@@ -11,20 +11,17 @@
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
class PredisRedisClusterAdapterTest extends AbstractRedisAdapterTest
{
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
if (!$hosts = getenv('REDIS_CLUSTER_HOSTS')) {
self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.');
}
self::$redis = RedisAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['class' => \Predis\Client::class, 'redis_cluster' => true]);
self::$redis = new \Predis\Client(explode(' ', $hosts), ['cluster' => 'redis']);
}
public static function tearDownAfterClass(): void
public static function tearDownAfterClass()
{
self::$redis = null;
}
@@ -1,34 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
class PredisTagAwareAdapterTest extends PredisAdapterTest
{
use TagAwareTestTrait;
protected function setUp(): void
{
parent::setUp();
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
}
public function createCachePool($defaultLifetime = 0)
{
$this->assertInstanceOf(\Predis\Client::class, self::$redis);
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
return $adapter;
}
}
@@ -1,34 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
class PredisTagAwareClusterAdapterTest extends PredisClusterAdapterTest
{
use TagAwareTestTrait;
protected function setUp(): void
{
parent::setUp();
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
}
public function createCachePool($defaultLifetime = 0)
{
$this->assertInstanceOf(\Predis\Client::class, self::$redis);
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
return $adapter;
}
}
@@ -1,34 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
class PredisTagAwareRedisClusterAdapterTest extends PredisRedisClusterAdapterTest
{
use TagAwareTestTrait;
protected function setUp(): void
{
parent::setUp();
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
}
public function createCachePool($defaultLifetime = 0)
{
$this->assertInstanceOf(\Predis\Client::class, self::$redis);
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
return $adapter;
}
}
+1 -6
View File
@@ -13,7 +13,6 @@ namespace Symfony\Component\Cache\Tests\Adapter;
use Psr\Cache\CacheItemInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\ProxyAdapter;
use Symfony\Component\Cache\CacheItem;
@@ -28,12 +27,8 @@ class ProxyAdapterTest extends AdapterTestCase
'testPrune' => 'ProxyAdapter just proxies',
];
public function createCachePool($defaultLifetime = 0, $testMethod = null)
public function createCachePool($defaultLifetime = 0)
{
if ('testGetMetadata' === $testMethod) {
return new ProxyAdapter(new FilesystemAdapter(), '', $defaultLifetime);
}
return new ProxyAdapter(new ArrayAdapter(), '', $defaultLifetime);
}
-42
View File
@@ -1,42 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\Psr16Adapter;
use Symfony\Component\Cache\Psr16Cache;
/**
* @group time-sensitive
*/
class Psr16AdapterTest extends AdapterTestCase
{
protected $skippedTests = [
'testPrune' => 'Psr16adapter just proxies',
];
public function createCachePool($defaultLifetime = 0)
{
return new Psr16Adapter(new Psr16Cache(new FilesystemAdapter()), '', $defaultLifetime);
}
public function testValidCacheKeyWithNamespace()
{
$cache = new Psr16Adapter(new Psr16Cache(new ArrayAdapter()), 'some_namespace', 0);
$item = $cache->getItem('my_key');
$item->set('someValue');
$cache->save($item);
$this->assertTrue($cache->getItem('my_key')->isHit(), 'Stored item is successfully retrieved.');
}
}
+8 -24
View File
@@ -17,7 +17,7 @@ use Symfony\Component\Cache\Traits\RedisProxy;
class RedisAdapterTest extends AbstractRedisAdapterTest
{
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'), ['lazy' => true]);
@@ -31,33 +31,25 @@ class RedisAdapterTest extends AbstractRedisAdapterTest
return $adapter;
}
/**
* @dataProvider provideValidSchemes
*/
public function testCreateConnection($dsnScheme)
public function testCreateConnection()
{
$redis = RedisAdapter::createConnection($dsnScheme.':?host[h1]&host[h2]&host[/foo:]');
$this->assertInstanceOf(\RedisArray::class, $redis);
$this->assertSame(['h1:6379', 'h2:6379', '/foo'], $redis->_hosts());
@$redis = null; // some versions of phpredis connect on destruct, let's silence the warning
$redisHost = getenv('REDIS_HOST');
$redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost);
$redis = RedisAdapter::createConnection('redis://'.$redisHost);
$this->assertInstanceOf(\Redis::class, $redis);
$this->assertTrue($redis->isConnected());
$this->assertSame(0, $redis->getDbNum());
$redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost.'/2');
$redis = RedisAdapter::createConnection('redis://'.$redisHost.'/2');
$this->assertSame(2, $redis->getDbNum());
$redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost, ['timeout' => 3]);
$redis = RedisAdapter::createConnection('redis://'.$redisHost, ['timeout' => 3]);
$this->assertEquals(3, $redis->getTimeout());
$redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost.'?timeout=4');
$redis = RedisAdapter::createConnection('redis://'.$redisHost.'?timeout=4');
$this->assertEquals(4, $redis->getTimeout());
$redis = RedisAdapter::createConnection($dsnScheme.'://'.$redisHost, ['read_timeout' => 5]);
$redis = RedisAdapter::createConnection('redis://'.$redisHost, ['read_timeout' => 5]);
$this->assertEquals(5, $redis->getReadTimeout());
}
@@ -67,7 +59,7 @@ class RedisAdapterTest extends AbstractRedisAdapterTest
public function testFailedCreateConnection($dsn)
{
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
$this->expectExceptionMessage('Redis connection failed');
$this->expectExceptionMessage('Redis connection ');
RedisAdapter::createConnection($dsn);
}
@@ -90,14 +82,6 @@ class RedisAdapterTest extends AbstractRedisAdapterTest
RedisAdapter::createConnection($dsn);
}
public function provideValidSchemes()
{
return [
['redis'],
['rediss'],
];
}
public function provideInvalidCreateConnection()
{
return [
@@ -13,7 +13,7 @@ namespace Symfony\Component\Cache\Tests\Adapter;
class RedisArrayAdapterTest extends AbstractRedisAdapterTest
{
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
parent::setupBeforeClass();
if (!class_exists('RedisArray')) {
@@ -11,13 +11,9 @@
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\Traits\RedisClusterProxy;
class RedisClusterAdapterTest extends AbstractRedisAdapterTest
{
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
if (!class_exists('RedisCluster')) {
self::markTestSkipped('The RedisCluster class is required.');
@@ -26,33 +22,6 @@ class RedisClusterAdapterTest extends AbstractRedisAdapterTest
self::markTestSkipped('REDIS_CLUSTER_HOSTS env var is not defined.');
}
self::$redis = AbstractAdapter::createConnection('redis:?host['.str_replace(' ', ']&host[', $hosts).']', ['lazy' => true, 'redis_cluster' => true]);
}
public function createCachePool($defaultLifetime = 0)
{
$this->assertInstanceOf(RedisClusterProxy::class, self::$redis);
$adapter = new RedisAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
return $adapter;
}
/**
* @dataProvider provideFailedCreateConnection
*/
public function testFailedCreateConnection($dsn)
{
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
$this->expectExceptionMessage('Redis connection failed');
RedisAdapter::createConnection($dsn);
}
public function provideFailedCreateConnection()
{
return [
['redis://localhost:1234?redis_cluster=1'],
['redis://foo@localhost?redis_cluster=1'],
['redis://localhost/123?redis_cluster=1'],
];
self::$redis = new \RedisCluster(null, explode(' ', $hosts));
}
}
@@ -1,35 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
use Symfony\Component\Cache\Traits\RedisProxy;
class RedisTagAwareAdapterTest extends RedisAdapterTest
{
use TagAwareTestTrait;
protected function setUp(): void
{
parent::setUp();
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
}
public function createCachePool($defaultLifetime = 0)
{
$this->assertInstanceOf(RedisProxy::class, self::$redis);
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
return $adapter;
}
}
@@ -1,34 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
class RedisTagAwareArrayAdapterTest extends RedisArrayAdapterTest
{
use TagAwareTestTrait;
protected function setUp(): void
{
parent::setUp();
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
}
public function createCachePool($defaultLifetime = 0)
{
$this->assertInstanceOf(\RedisArray::class, self::$redis);
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
return $adapter;
}
}
@@ -1,35 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Adapter;
use Symfony\Component\Cache\Adapter\RedisTagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
use Symfony\Component\Cache\Traits\RedisClusterProxy;
class RedisTagAwareClusterAdapterTest extends RedisClusterAdapterTest
{
use TagAwareTestTrait;
protected function setUp(): void
{
parent::setUp();
$this->skippedTests['testTagItemExpiry'] = 'Testing expiration slows down the test suite';
}
public function createCachePool($defaultLifetime = 0)
{
$this->assertInstanceOf(RedisClusterProxy::class, self::$redis);
$adapter = new RedisTagAwareAdapter(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
return $adapter;
}
}
@@ -17,7 +17,6 @@ use Symfony\Component\Cache\Simple\FilesystemCache;
/**
* @group time-sensitive
* @group legacy
*/
class SimpleCacheAdapterTest extends AdapterTestCase
{
+123 -8
View File
@@ -14,31 +14,71 @@ namespace Symfony\Component\Cache\Tests\Adapter;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Cache\CacheItemInterface;
use Symfony\Component\Cache\Adapter\AdapterInterface;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
use Symfony\Component\Cache\Tests\Traits\TagAwareTestTrait;
/**
* @group time-sensitive
*/
class TagAwareAdapterTest extends AdapterTestCase
{
use TagAwareTestTrait;
public function createCachePool($defaultLifetime = 0)
{
return new TagAwareAdapter(new FilesystemAdapter('', $defaultLifetime));
}
public static function tearDownAfterClass(): void
public static function tearDownAfterClass()
{
FilesystemAdapterTest::rmdir(sys_get_temp_dir().'/symfony-cache');
}
/**
* Test feature specific to TagAwareAdapter as it implicit needs to save deferred when also saving expiry info.
*/
public function testInvalidateCommitsSeperatePools()
public function testInvalidTag()
{
$this->expectException('Psr\Cache\InvalidArgumentException');
$pool = $this->createCachePool();
$item = $pool->getItem('foo');
$item->tag(':');
}
public function testInvalidateTags()
{
$pool = $this->createCachePool();
$i0 = $pool->getItem('i0');
$i1 = $pool->getItem('i1');
$i2 = $pool->getItem('i2');
$i3 = $pool->getItem('i3');
$foo = $pool->getItem('foo');
$pool->save($i0->tag('bar'));
$pool->save($i1->tag('foo'));
$pool->save($i2->tag('foo')->tag('bar'));
$pool->save($i3->tag('foo')->tag('baz'));
$pool->save($foo);
$pool->invalidateTags(['bar']);
$this->assertFalse($pool->getItem('i0')->isHit());
$this->assertTrue($pool->getItem('i1')->isHit());
$this->assertFalse($pool->getItem('i2')->isHit());
$this->assertTrue($pool->getItem('i3')->isHit());
$this->assertTrue($pool->getItem('foo')->isHit());
$pool->invalidateTags(['foo']);
$this->assertFalse($pool->getItem('i1')->isHit());
$this->assertFalse($pool->getItem('i3')->isHit());
$this->assertTrue($pool->getItem('foo')->isHit());
$anotherPoolInstance = $this->createCachePool();
$this->assertFalse($anotherPoolInstance->getItem('i1')->isHit());
$this->assertFalse($anotherPoolInstance->getItem('i3')->isHit());
$this->assertTrue($anotherPoolInstance->getItem('foo')->isHit());
}
public function testInvalidateCommits()
{
$pool1 = $this->createCachePool();
@@ -54,6 +94,62 @@ class TagAwareAdapterTest extends AdapterTestCase
$this->assertTrue($foo->isHit());
}
public function testTagsAreCleanedOnSave()
{
$pool = $this->createCachePool();
$i = $pool->getItem('k');
$pool->save($i->tag('foo'));
$i = $pool->getItem('k');
$pool->save($i->tag('bar'));
$pool->invalidateTags(['foo']);
$this->assertTrue($pool->getItem('k')->isHit());
}
public function testTagsAreCleanedOnDelete()
{
$pool = $this->createCachePool();
$i = $pool->getItem('k');
$pool->save($i->tag('foo'));
$pool->deleteItem('k');
$pool->save($pool->getItem('k'));
$pool->invalidateTags(['foo']);
$this->assertTrue($pool->getItem('k')->isHit());
}
public function testTagItemExpiry()
{
$pool = $this->createCachePool(10);
$item = $pool->getItem('foo');
$item->tag(['baz']);
$item->expiresAfter(100);
$pool->save($item);
$pool->invalidateTags(['baz']);
$this->assertFalse($pool->getItem('foo')->isHit());
sleep(20);
$this->assertFalse($pool->getItem('foo')->isHit());
}
public function testGetPreviousTags()
{
$pool = $this->createCachePool();
$i = $pool->getItem('k');
$pool->save($i->tag('foo'));
$i = $pool->getItem('k');
$this->assertSame(['foo' => 'foo'], $i->getPreviousTags());
}
public function testPrune()
{
$cache = new TagAwareAdapter($this->getPruneableMock());
@@ -160,6 +256,25 @@ class TagAwareAdapterTest extends AdapterTestCase
$this->assertFalse($anotherPool->hasItem($itemKey));
}
public function testInvalidateTagsWithArrayAdapter()
{
$adapter = new TagAwareAdapter(new ArrayAdapter());
$item = $adapter->getItem('foo');
$this->assertFalse($item->isHit());
$item->tag('bar');
$item->expiresAfter(100);
$adapter->save($item);
$this->assertTrue($adapter->getItem('foo')->isHit());
$adapter->invalidateTags(['bar']);
$this->assertFalse($adapter->getItem('foo')->isHit());
}
public function testGetItemReturnsCacheMissWhenPoolDoesNotHaveItemAndOnlyHasTags()
{
$pool = $this->createCachePool();
+3 -22
View File
@@ -55,16 +55,13 @@ class CacheItemTest extends TestCase
public function testTag()
{
$item = new CacheItem();
$r = new \ReflectionProperty($item, 'isTaggable');
$r->setAccessible(true);
$r->setValue($item, true);
$this->assertSame($item, $item->tag('foo'));
$this->assertSame($item, $item->tag(['bar', 'baz']));
(\Closure::bind(function () use ($item) {
$this->assertSame(['foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz'], $item->newMetadata[CacheItem::METADATA_TAGS]);
}, $this, CacheItem::class))();
\call_user_func(\Closure::bind(function () use ($item) {
$this->assertSame(['foo' => 'foo', 'bar' => 'bar', 'baz' => 'baz'], $item->tags);
}, $this, CacheItem::class));
}
/**
@@ -75,22 +72,6 @@ class CacheItemTest extends TestCase
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
$this->expectExceptionMessage('Cache tag');
$item = new CacheItem();
$r = new \ReflectionProperty($item, 'isTaggable');
$r->setAccessible(true);
$r->setValue($item, true);
$item->tag($tag);
}
public function testNonTaggableItem()
{
$this->expectException('Symfony\Component\Cache\Exception\LogicException');
$this->expectExceptionMessage('Cache item "foo" comes from a non tag-aware pool: you cannot tag it.');
$item = new CacheItem();
$r = new \ReflectionProperty($item, 'key');
$r->setAccessible(true);
$r->setValue($item, 'foo');
$item->tag([]);
}
}
@@ -1,49 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\DependencyInjection;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\TagAwareAdapter;
use Symfony\Component\Cache\Adapter\TraceableAdapter;
use Symfony\Component\Cache\Adapter\TraceableTagAwareAdapter;
use Symfony\Component\Cache\DataCollector\CacheDataCollector;
use Symfony\Component\Cache\DependencyInjection\CacheCollectorPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class CacheCollectorPassTest extends TestCase
{
public function testProcess()
{
$container = new ContainerBuilder();
$container
->register('fs', FilesystemAdapter::class)
->addTag('cache.pool');
$container
->register('tagged_fs', TagAwareAdapter::class)
->addArgument(new Reference('fs'))
->addTag('cache.pool');
$collector = $container->register('data_collector.cache', CacheDataCollector::class);
(new CacheCollectorPass())->process($container);
$this->assertEquals([
['addInstance', ['fs', new Reference('fs')]],
['addInstance', ['tagged_fs', new Reference('tagged_fs')]],
], $collector->getMethodCalls());
$this->assertSame(TraceableAdapter::class, $container->findDefinition('fs')->getClass());
$this->assertSame(TraceableTagAwareAdapter::class, $container->getDefinition('tagged_fs')->getClass());
$this->assertFalse($collector->isPublic(), 'The "data_collector.cache" should be private after processing');
}
}
@@ -1,73 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\DependencyInjection;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\DependencyInjection\CachePoolClearerPass;
use Symfony\Component\Cache\DependencyInjection\CachePoolPass;
use Symfony\Component\DependencyInjection\Compiler\RemoveUnusedDefinitionsPass;
use Symfony\Component\DependencyInjection\Compiler\RepeatedPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\HttpKernel\CacheClearer\Psr6CacheClearer;
class CachePoolClearerPassTest extends TestCase
{
public function testPoolRefsAreWeak()
{
$container = new ContainerBuilder();
$container->setParameter('kernel.container_class', 'app');
$container->setParameter('kernel.project_dir', 'foo');
$globalClearer = new Definition(Psr6CacheClearer::class);
$container->setDefinition('cache.global_clearer', $globalClearer);
$publicPool = new Definition();
$publicPool->addArgument('namespace');
$publicPool->addTag('cache.pool', ['clearer' => 'clearer_alias']);
$container->setDefinition('public.pool', $publicPool);
$publicPool = new Definition();
$publicPool->addArgument('namespace');
$publicPool->addTag('cache.pool', ['clearer' => 'clearer_alias', 'name' => 'pool2']);
$container->setDefinition('public.pool2', $publicPool);
$privatePool = new Definition();
$privatePool->setPublic(false);
$privatePool->addArgument('namespace');
$privatePool->addTag('cache.pool', ['clearer' => 'clearer_alias']);
$container->setDefinition('private.pool', $privatePool);
$clearer = new Definition();
$container->setDefinition('clearer', $clearer);
$container->setAlias('clearer_alias', 'clearer');
$pass = new RemoveUnusedDefinitionsPass();
foreach ($container->getCompiler()->getPassConfig()->getRemovingPasses() as $removingPass) {
if ($removingPass instanceof RepeatedPass) {
$pass->setRepeatedPass(new RepeatedPass([$pass]));
break;
}
}
foreach ([new CachePoolPass(), $pass, new CachePoolClearerPass()] as $pass) {
$pass->process($container);
}
$expected = [[
'public.pool' => new Reference('public.pool'),
'pool2' => new Reference('public.pool2'),
]];
$this->assertEquals($expected, $clearer->getArguments());
$this->assertEquals($expected, $globalClearer->getArguments());
}
}
@@ -1,177 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\DependencyInjection;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
use Symfony\Component\Cache\DependencyInjection\CachePoolPass;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Reference;
class CachePoolPassTest extends TestCase
{
private $cachePoolPass;
protected function setUp(): void
{
$this->cachePoolPass = new CachePoolPass();
}
public function testNamespaceArgumentIsReplaced()
{
$container = new ContainerBuilder();
$container->setParameter('kernel.container_class', 'app');
$container->setParameter('kernel.project_dir', 'foo');
$adapter = new Definition();
$adapter->setAbstract(true);
$adapter->addTag('cache.pool');
$container->setDefinition('app.cache_adapter', $adapter);
$container->setAlias('app.cache_adapter_alias', 'app.cache_adapter');
$cachePool = new ChildDefinition('app.cache_adapter_alias');
$cachePool->addArgument(null);
$cachePool->addTag('cache.pool');
$container->setDefinition('app.cache_pool', $cachePool);
$this->cachePoolPass->process($container);
$this->assertSame('z3X945Jbf5', $cachePool->getArgument(0));
}
public function testNamespaceArgumentIsSeededWithAdapterClassName()
{
$container = new ContainerBuilder();
$container->setParameter('kernel.container_class', 'app');
$container->setParameter('kernel.project_dir', 'foo');
$adapter = new Definition();
$adapter->setAbstract(true);
$adapter->addTag('cache.pool');
$adapter->setClass(RedisAdapter::class);
$container->setDefinition('app.cache_adapter', $adapter);
$container->setAlias('app.cache_adapter_alias', 'app.cache_adapter');
$cachePool = new ChildDefinition('app.cache_adapter_alias');
$cachePool->addArgument(null);
$cachePool->addTag('cache.pool');
$container->setDefinition('app.cache_pool', $cachePool);
$this->cachePoolPass->process($container);
$this->assertSame('xmOJ8gqF-Y', $cachePool->getArgument(0));
}
public function testNamespaceArgumentIsSeededWithAdapterClassNameWithoutAffectingOtherCachePools()
{
$container = new ContainerBuilder();
$container->setParameter('kernel.container_class', 'app');
$container->setParameter('kernel.project_dir', 'foo');
$adapter = new Definition();
$adapter->setAbstract(true);
$adapter->addTag('cache.pool');
$adapter->setClass(RedisAdapter::class);
$container->setDefinition('app.cache_adapter', $adapter);
$container->setAlias('app.cache_adapter_alias', 'app.cache_adapter');
$otherCachePool = new ChildDefinition('app.cache_adapter_alias');
$otherCachePool->addArgument(null);
$otherCachePool->addTag('cache.pool');
$container->setDefinition('app.other_cache_pool', $otherCachePool);
$cachePool = new ChildDefinition('app.cache_adapter_alias');
$cachePool->addArgument(null);
$cachePool->addTag('cache.pool');
$container->setDefinition('app.cache_pool', $cachePool);
$this->cachePoolPass->process($container);
$this->assertSame('xmOJ8gqF-Y', $cachePool->getArgument(0));
}
public function testNamespaceArgumentIsNotReplacedIfArrayAdapterIsUsed()
{
$container = new ContainerBuilder();
$container->setParameter('kernel.container_class', 'app');
$container->setParameter('kernel.project_dir', 'foo');
$container->register('cache.adapter.array', ArrayAdapter::class)->addArgument(0);
$cachePool = new ChildDefinition('cache.adapter.array');
$cachePool->addTag('cache.pool');
$container->setDefinition('app.cache_pool', $cachePool);
$this->cachePoolPass->process($container);
$this->assertCount(0, $container->getDefinition('app.cache_pool')->getArguments());
}
public function testArgsAreReplaced()
{
$container = new ContainerBuilder();
$container->setParameter('kernel.container_class', 'app');
$container->setParameter('cache.prefix.seed', 'foo');
$cachePool = new Definition();
$cachePool->addTag('cache.pool', [
'provider' => 'foobar',
'default_lifetime' => 3,
]);
$cachePool->addArgument(null);
$cachePool->addArgument(null);
$cachePool->addArgument(null);
$container->setDefinition('app.cache_pool', $cachePool);
$this->cachePoolPass->process($container);
$this->assertInstanceOf(Reference::class, $cachePool->getArgument(0));
$this->assertSame('foobar', (string) $cachePool->getArgument(0));
$this->assertSame('tQNhcV-8xa', $cachePool->getArgument(1));
$this->assertSame(3, $cachePool->getArgument(2));
}
public function testWithNameAttribute()
{
$container = new ContainerBuilder();
$container->setParameter('kernel.container_class', 'app');
$container->setParameter('cache.prefix.seed', 'foo');
$cachePool = new Definition();
$cachePool->addTag('cache.pool', [
'name' => 'foobar',
'provider' => 'foobar',
]);
$cachePool->addArgument(null);
$cachePool->addArgument(null);
$cachePool->addArgument(null);
$container->setDefinition('app.cache_pool', $cachePool);
$this->cachePoolPass->process($container);
$this->assertSame('+naTpPa4Sm', $cachePool->getArgument(1));
}
public function testThrowsExceptionWhenCachePoolTagHasUnknownAttributes()
{
$this->expectException('InvalidArgumentException');
$this->expectExceptionMessage('Invalid "cache.pool" tag for service "app.cache_pool": accepted attributes are');
$container = new ContainerBuilder();
$container->setParameter('kernel.container_class', 'app');
$container->setParameter('kernel.project_dir', 'foo');
$adapter = new Definition();
$adapter->setAbstract(true);
$adapter->addTag('cache.pool');
$container->setDefinition('app.cache_adapter', $adapter);
$cachePool = new ChildDefinition('app.cache_adapter');
$cachePool->addTag('cache.pool', ['foobar' => 123]);
$container->setDefinition('app.cache_pool', $cachePool);
$this->cachePoolPass->process($container);
}
}
@@ -1,70 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\DependencyInjection;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Adapter\PhpFilesAdapter;
use Symfony\Component\Cache\DependencyInjection\CachePoolPrunerPass;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class CachePoolPrunerPassTest extends TestCase
{
public function testCompilerPassReplacesCommandArgument()
{
$container = new ContainerBuilder();
$container->register('console.command.cache_pool_prune')->addArgument([]);
$container->register('pool.foo', FilesystemAdapter::class)->addTag('cache.pool');
$container->register('pool.bar', PhpFilesAdapter::class)->addTag('cache.pool');
$pass = new CachePoolPrunerPass();
$pass->process($container);
$expected = [
'pool.foo' => new Reference('pool.foo'),
'pool.bar' => new Reference('pool.bar'),
];
$argument = $container->getDefinition('console.command.cache_pool_prune')->getArgument(0);
$this->assertInstanceOf(IteratorArgument::class, $argument);
$this->assertEquals($expected, $argument->getValues());
}
public function testCompilePassIsIgnoredIfCommandDoesNotExist()
{
$container = new ContainerBuilder();
$definitionsBefore = \count($container->getDefinitions());
$aliasesBefore = \count($container->getAliases());
$pass = new CachePoolPrunerPass();
$pass->process($container);
// the container is untouched (i.e. no new definitions or aliases)
$this->assertCount($definitionsBefore, $container->getDefinitions());
$this->assertCount($aliasesBefore, $container->getAliases());
}
public function testCompilerPassThrowsOnInvalidDefinitionClass()
{
$this->expectException('Symfony\Component\DependencyInjection\Exception\InvalidArgumentException');
$this->expectExceptionMessage('Class "Symfony\Component\Cache\Tests\DependencyInjection\NotFound" used for service "pool.not-found" cannot be found.');
$container = new ContainerBuilder();
$container->register('console.command.cache_pool_prune')->addArgument([]);
$container->register('pool.not-found', NotFound::class)->addTag('cache.pool');
$pass = new CachePoolPrunerPass();
$pass->process($container);
}
}
+2 -2
View File
@@ -21,12 +21,12 @@ class ArrayCache extends CacheProvider
$expiry = $this->data[$id][1];
return !$expiry || microtime(true) < $expiry || !$this->doDelete($id);
return !$expiry || time() < $expiry || !$this->doDelete($id);
}
protected function doSave($id, $data, $lifeTime = 0)
{
$this->data[$id] = [$data, $lifeTime ? microtime(true) + $lifeTime : false];
$this->data[$id] = [$data, $lifeTime ? time() + $lifeTime : false];
return true;
}
+1 -1
View File
@@ -24,7 +24,7 @@ class ExternalAdapter implements CacheItemPoolInterface
{
private $cache;
public function __construct(int $defaultLifetime = 0)
public function __construct($defaultLifetime = 0)
{
$this->cache = new ArrayAdapter($defaultLifetime);
}
-26
View File
@@ -1,26 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\LockRegistry;
class LockRegistryTest extends TestCase
{
public function testFiles()
{
$lockFiles = LockRegistry::setFiles([]);
LockRegistry::setFiles($lockFiles);
$expected = array_map('realpath', glob(__DIR__.'/../Adapter/*'));
$this->assertSame($expected, $lockFiles);
}
}
@@ -1,112 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Marshaller;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Cache\Marshaller\DefaultMarshaller;
class DefaultMarshallerTest extends TestCase
{
public function testSerialize()
{
$marshaller = new DefaultMarshaller();
$values = [
'a' => 123,
'b' => function () {},
];
$expected = ['a' => \extension_loaded('igbinary') && (\PHP_VERSION_ID < 70400 || version_compare('3.1.0', phpversion('igbinary'), '<=')) ? igbinary_serialize(123) : serialize(123)];
$this->assertSame($expected, $marshaller->marshall($values, $failed));
$this->assertSame(['b'], $failed);
}
public function testNativeUnserialize()
{
$marshaller = new DefaultMarshaller();
$this->assertNull($marshaller->unmarshall(serialize(null)));
$this->assertFalse($marshaller->unmarshall(serialize(false)));
$this->assertSame('', $marshaller->unmarshall(serialize('')));
$this->assertSame(0, $marshaller->unmarshall(serialize(0)));
}
/**
* @requires extension igbinary
*/
public function testIgbinaryUnserialize()
{
if (\PHP_VERSION_ID >= 70400 && version_compare('3.1.0', phpversion('igbinary'), '>')) {
$this->markTestSkipped('igbinary is not compatible with PHP 7.4.');
}
$marshaller = new DefaultMarshaller();
$this->assertNull($marshaller->unmarshall(igbinary_serialize(null)));
$this->assertFalse($marshaller->unmarshall(igbinary_serialize(false)));
$this->assertSame('', $marshaller->unmarshall(igbinary_serialize('')));
$this->assertSame(0, $marshaller->unmarshall(igbinary_serialize(0)));
}
public function testNativeUnserializeNotFoundClass()
{
$this->expectException('DomainException');
$this->expectExceptionMessage('Class not found: NotExistingClass');
$marshaller = new DefaultMarshaller();
$marshaller->unmarshall('O:16:"NotExistingClass":0:{}');
}
/**
* @requires extension igbinary
*/
public function testIgbinaryUnserializeNotFoundClass()
{
if (\PHP_VERSION_ID >= 70400 && version_compare('3.1.0', phpversion('igbinary'), '>')) {
$this->markTestSkipped('igbinary is not compatible with PHP 7.4.');
}
$this->expectException('DomainException');
$this->expectExceptionMessage('Class not found: NotExistingClass');
$marshaller = new DefaultMarshaller();
$marshaller->unmarshall(rawurldecode('%00%00%00%02%17%10NotExistingClass%14%00'));
}
public function testNativeUnserializeInvalid()
{
$this->expectException('DomainException');
$this->expectExceptionMessage('unserialize(): Error at offset 0 of 3 bytes');
$marshaller = new DefaultMarshaller();
set_error_handler(function () { return false; });
try {
@$marshaller->unmarshall(':::');
} finally {
restore_error_handler();
}
}
/**
* @requires extension igbinary
*/
public function testIgbinaryUnserializeInvalid()
{
if (\PHP_VERSION_ID >= 70400 && version_compare('3.1.0', phpversion('igbinary'), '>')) {
$this->markTestSkipped('igbinary is not compatible with PHP 7.4.');
}
$this->expectException('DomainException');
$this->expectExceptionMessage('igbinary_unserialize_zval: unknown type \'61\', position 5');
$marshaller = new DefaultMarshaller();
set_error_handler(function () { return false; });
try {
@$marshaller->unmarshall(rawurldecode('%00%00%00%02abc'));
} finally {
restore_error_handler();
}
}
}
-168
View File
@@ -1,168 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests;
use Cache\IntegrationTests\SimpleCacheTest;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\PruneableInterface;
use Symfony\Component\Cache\Psr16Cache;
/**
* @group time-sensitive
*/
class Psr16CacheTest extends SimpleCacheTest
{
protected function setUp(): void
{
parent::setUp();
if (\array_key_exists('testPrune', $this->skippedTests)) {
return;
}
$pool = $this->createSimpleCache();
if ($pool instanceof Psr16Cache) {
$pool = ((array) $pool)[sprintf("\0%s\0pool", Psr16Cache::class)];
}
if (!$pool instanceof PruneableInterface) {
$this->skippedTests['testPrune'] = 'Not a pruneable cache pool.';
}
}
public function createSimpleCache($defaultLifetime = 0)
{
return new Psr16Cache(new FilesystemAdapter('', $defaultLifetime));
}
public static function validKeys()
{
return array_merge(parent::validKeys(), [["a\0b"]]);
}
public function testDefaultLifeTime()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
$cache = $this->createSimpleCache(2);
$cache->clear();
$cache->set('key.dlt', 'value');
sleep(1);
$this->assertSame('value', $cache->get('key.dlt'));
sleep(2);
$this->assertNull($cache->get('key.dlt'));
$cache->clear();
}
public function testNotUnserializable()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
$cache = $this->createSimpleCache();
$cache->clear();
$cache->set('foo', new NotUnserializable());
$this->assertNull($cache->get('foo'));
$cache->setMultiple(['foo' => new NotUnserializable()]);
foreach ($cache->getMultiple(['foo']) as $value) {
}
$this->assertNull($value);
$cache->clear();
}
public function testPrune()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
/** @var PruneableInterface|CacheInterface $cache */
$cache = $this->createSimpleCache();
$cache->clear();
$cache->set('foo', 'foo-val', new \DateInterval('PT05S'));
$cache->set('bar', 'bar-val', new \DateInterval('PT10S'));
$cache->set('baz', 'baz-val', new \DateInterval('PT15S'));
$cache->set('qux', 'qux-val', new \DateInterval('PT20S'));
sleep(30);
$cache->prune();
$this->assertTrue($this->isPruned($cache, 'foo'));
$this->assertTrue($this->isPruned($cache, 'bar'));
$this->assertTrue($this->isPruned($cache, 'baz'));
$this->assertTrue($this->isPruned($cache, 'qux'));
$cache->set('foo', 'foo-val');
$cache->set('bar', 'bar-val', new \DateInterval('PT20S'));
$cache->set('baz', 'baz-val', new \DateInterval('PT40S'));
$cache->set('qux', 'qux-val', new \DateInterval('PT80S'));
$cache->prune();
$this->assertFalse($this->isPruned($cache, 'foo'));
$this->assertFalse($this->isPruned($cache, 'bar'));
$this->assertFalse($this->isPruned($cache, 'baz'));
$this->assertFalse($this->isPruned($cache, 'qux'));
sleep(30);
$cache->prune();
$this->assertFalse($this->isPruned($cache, 'foo'));
$this->assertTrue($this->isPruned($cache, 'bar'));
$this->assertFalse($this->isPruned($cache, 'baz'));
$this->assertFalse($this->isPruned($cache, 'qux'));
sleep(30);
$cache->prune();
$this->assertFalse($this->isPruned($cache, 'foo'));
$this->assertTrue($this->isPruned($cache, 'baz'));
$this->assertFalse($this->isPruned($cache, 'qux'));
sleep(30);
$cache->prune();
$this->assertFalse($this->isPruned($cache, 'foo'));
$this->assertTrue($this->isPruned($cache, 'qux'));
$cache->clear();
}
protected function isPruned($cache, $name)
{
if (Psr16Cache::class !== \get_class($cache)) {
$this->fail('Test classes for pruneable caches must implement `isPruned($cache, $name)` method.');
}
$pool = ((array) $cache)[sprintf("\0%s\0pool", Psr16Cache::class)];
$getFileMethod = (new \ReflectionObject($pool))->getMethod('getFile');
$getFileMethod->setAccessible(true);
return !file_exists($getFileMethod->invoke($pool, $name));
}
}
class NotUnserializable
{
public function __wakeup()
{
throw new \Exception(__CLASS__);
}
}
@@ -13,9 +13,6 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\RedisCache;
/**
* @group legacy
*/
abstract class AbstractRedisCacheTest extends CacheTestCase
{
protected $skippedTests = [
@@ -31,18 +28,19 @@ abstract class AbstractRedisCacheTest extends CacheTestCase
return new RedisCache(self::$redis, str_replace('\\', '.', __CLASS__), $defaultLifetime);
}
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
if (!\extension_loaded('redis')) {
self::markTestSkipped('Extension redis required.');
}
if (!@((new \Redis())->connect(getenv('REDIS_HOST')))) {
$e = error_get_last();
self::markTestSkipped($e['message']);
try {
(new \Redis())->connect(getenv('REDIS_HOST'));
} catch (\Exception $e) {
self::markTestSkipped($e->getMessage());
}
}
public static function tearDownAfterClass(): void
public static function tearDownAfterClass()
{
self::$redis = null;
}
+1 -4
View File
@@ -13,9 +13,6 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\ApcuCache;
/**
* @group legacy
*/
class ApcuCacheTest extends CacheTestCase
{
protected $skippedTests = [
@@ -26,7 +23,7 @@ class ApcuCacheTest extends CacheTestCase
public function createSimpleCache($defaultLifetime = 0)
{
if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) || ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), FILTER_VALIDATE_BOOLEAN))) {
if (!\function_exists('apcu_fetch') || !filter_var(ini_get('apc.enabled'), \FILTER_VALIDATE_BOOLEAN) || ('cli' === \PHP_SAPI && !filter_var(ini_get('apc.enable_cli'), \FILTER_VALIDATE_BOOLEAN))) {
$this->markTestSkipped('APCu extension is required.');
}
if ('\\' === \DIRECTORY_SEPARATOR) {
-1
View File
@@ -15,7 +15,6 @@ use Symfony\Component\Cache\Simple\ArrayCache;
/**
* @group time-sensitive
* @group legacy
*/
class ArrayCacheTest extends CacheTestCase
{
+12 -3
View File
@@ -17,7 +17,7 @@ use Symfony\Component\Cache\PruneableInterface;
abstract class CacheTestCase extends SimpleCacheTest
{
protected function setUp(): void
protected function setUp()
{
parent::setUp();
@@ -28,6 +28,10 @@ abstract class CacheTestCase extends SimpleCacheTest
public static function validKeys()
{
if (\defined('HHVM_VERSION')) {
return parent::validKeys();
}
return array_merge(parent::validKeys(), [["a\0b"]]);
}
@@ -132,9 +136,14 @@ abstract class CacheTestCase extends SimpleCacheTest
}
}
class NotUnserializable
class NotUnserializable implements \Serializable
{
public function __wakeup()
public function serialize()
{
return serialize(123);
}
public function unserialize($ser)
{
throw new \Exception(__CLASS__);
}
-1
View File
@@ -20,7 +20,6 @@ use Symfony\Component\Cache\Simple\FilesystemCache;
/**
* @group time-sensitive
* @group legacy
*/
class ChainCacheTest extends CacheTestCase
{
@@ -16,7 +16,6 @@ use Symfony\Component\Cache\Tests\Fixtures\ArrayCache;
/**
* @group time-sensitive
* @group legacy
*/
class DoctrineCacheTest extends CacheTestCase
{
@@ -16,7 +16,6 @@ use Symfony\Component\Cache\Simple\FilesystemCache;
/**
* @group time-sensitive
* @group legacy
*/
class FilesystemCacheTest extends CacheTestCase
{
+11 -8
View File
@@ -14,9 +14,6 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Simple\MemcachedCache;
/**
* @group legacy
*/
class MemcachedCacheTest extends CacheTestCase
{
protected $skippedTests = [
@@ -27,7 +24,7 @@ class MemcachedCacheTest extends CacheTestCase
protected static $client;
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
if (!MemcachedCache::isSupported()) {
self::markTestSkipped('Extension memcached >=2.2.0 required.');
@@ -79,8 +76,14 @@ class MemcachedCacheTest extends CacheTestCase
*/
public function testBadOptions($name, $value)
{
$this->expectException('ErrorException');
$this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::');
if (\PHP_VERSION_ID < 80000) {
$this->expectException('ErrorException');
$this->expectExceptionMessage('constant(): Couldn\'t find constant Memcached::');
} else {
$this->expectException('Error');
$this->expectExceptionMessage('Undefined constant Memcached::');
}
MemcachedCache::createConnection([], [$name => $value]);
}
@@ -147,7 +150,7 @@ class MemcachedCacheTest extends CacheTestCase
'localhost',
11222,
];
if (filter_var(ini_get('memcached.use_sasl'), FILTER_VALIDATE_BOOLEAN)) {
if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) {
yield [
'memcached://user:password@127.0.0.1?weight=50',
'127.0.0.1',
@@ -164,7 +167,7 @@ class MemcachedCacheTest extends CacheTestCase
'/var/local/run/memcached.socket',
0,
];
if (filter_var(ini_get('memcached.use_sasl'), FILTER_VALIDATE_BOOLEAN)) {
if (filter_var(ini_get('memcached.use_sasl'), \FILTER_VALIDATE_BOOLEAN)) {
yield [
'memcached://user:password@/var/local/run/memcached.socket?weight=25',
'/var/local/run/memcached.socket',
@@ -14,9 +14,6 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Simple\MemcachedCache;
/**
* @group legacy
*/
class MemcachedCacheTextModeTest extends MemcachedCacheTest
{
public function createSimpleCache($defaultLifetime = 0)
-1
View File
@@ -16,7 +16,6 @@ use Symfony\Component\Cache\Simple\NullCache;
/**
* @group time-sensitive
* @group legacy
*/
class NullCacheTest extends TestCase
{
+2 -3
View File
@@ -16,7 +16,6 @@ use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
/**
* @group time-sensitive
* @group legacy
*/
class PdoCacheTest extends CacheTestCase
{
@@ -24,7 +23,7 @@ class PdoCacheTest extends CacheTestCase
protected static $dbFile;
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
if (!\extension_loaded('pdo_sqlite')) {
self::markTestSkipped('Extension pdo_sqlite required.');
@@ -36,7 +35,7 @@ class PdoCacheTest extends CacheTestCase
$pool->createTable();
}
public static function tearDownAfterClass(): void
public static function tearDownAfterClass()
{
@unlink(self::$dbFile);
}
+2 -3
View File
@@ -17,7 +17,6 @@ use Symfony\Component\Cache\Tests\Traits\PdoPruneableTrait;
/**
* @group time-sensitive
* @group legacy
*/
class PdoDbalCacheTest extends CacheTestCase
{
@@ -25,7 +24,7 @@ class PdoDbalCacheTest extends CacheTestCase
protected static $dbFile;
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
if (!\extension_loaded('pdo_sqlite')) {
self::markTestSkipped('Extension pdo_sqlite required.');
@@ -37,7 +36,7 @@ class PdoDbalCacheTest extends CacheTestCase
$pool->createTable();
}
public static function tearDownAfterClass(): void
public static function tearDownAfterClass()
{
@unlink(self::$dbFile);
}
+34 -21
View File
@@ -17,7 +17,6 @@ use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest;
/**
* @group time-sensitive
* @group legacy
*/
class PhpArrayCacheTest extends CacheTestCase
{
@@ -50,12 +49,12 @@ class PhpArrayCacheTest extends CacheTestCase
protected static $file;
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php';
}
protected function tearDown(): void
protected function tearDown()
{
$this->createSimpleCache()->clear();
@@ -98,35 +97,49 @@ class PhpArrayCacheTest extends CacheTestCase
public function testStoredFile()
{
$data = [
$expected = [
'integer' => 42,
'float' => 42.42,
'boolean' => true,
'array_simple' => ['foo', 'bar'],
'array_associative' => ['foo' => 'bar', 'foo2' => 'bar2'],
];
$expected = [
[
'integer' => 0,
'float' => 1,
'boolean' => 2,
'array_simple' => 3,
'array_associative' => 4,
],
[
0 => 42,
1 => 42.42,
2 => true,
3 => ['foo', 'bar'],
4 => ['foo' => 'bar', 'foo2' => 'bar2'],
],
];
$cache = new PhpArrayCache(self::$file, new NullCache());
$cache->warmUp($data);
$cache->warmUp($expected);
$values = eval(substr(file_get_contents(self::$file), 6));
$this->assertSame($expected, $values, 'Warm up should create a PHP file that OPCache can load in memory');
}
}
class PhpArrayCacheWrapper extends PhpArrayCache
{
public function set($key, $value, $ttl = null)
{
\call_user_func(\Closure::bind(function () use ($key, $value) {
$this->values[$key] = $value;
$this->warmUp($this->values);
$this->values = eval(substr(file_get_contents($this->file), 6));
}, $this, PhpArrayCache::class));
return true;
}
public function setMultiple($values, $ttl = null)
{
if (!\is_array($values) && !$values instanceof \Traversable) {
return parent::setMultiple($values, $ttl);
}
\call_user_func(\Closure::bind(function () use ($values) {
foreach ($values as $key => $value) {
$this->values[$key] = $value;
}
$this->warmUp($this->values);
$this->values = eval(substr(file_get_contents($this->file), 6));
}, $this, PhpArrayCache::class));
return true;
}
}
@@ -17,7 +17,6 @@ use Symfony\Component\Cache\Tests\Adapter\FilesystemAdapterTest;
/**
* @group time-sensitive
* @group legacy
*/
class PhpArrayCacheWithFallbackTest extends CacheTestCase
{
@@ -37,12 +36,12 @@ class PhpArrayCacheWithFallbackTest extends CacheTestCase
protected static $file;
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
self::$file = sys_get_temp_dir().'/symfony-cache/php-array-adapter-test.php';
}
protected function tearDown(): void
protected function tearDown()
{
$this->createSimpleCache()->clear();
@@ -1,46 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\PhpArrayCache;
class PhpArrayCacheWrapper extends PhpArrayCache
{
protected $data = [];
public function set($key, $value, $ttl = null)
{
(\Closure::bind(function () use ($key, $value) {
$this->data[$key] = $value;
$this->warmUp($this->data);
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
}, $this, PhpArrayCache::class))();
return true;
}
public function setMultiple($values, $ttl = null)
{
if (!\is_array($values) && !$values instanceof \Traversable) {
return parent::setMultiple($values, $ttl);
}
(\Closure::bind(function () use ($values) {
foreach ($values as $key => $value) {
$this->data[$key] = $value;
}
$this->warmUp($this->data);
list($this->keys, $this->values) = eval(substr(file_get_contents($this->file), 6));
}, $this, PhpArrayCache::class))();
return true;
}
}
+4 -1
View File
@@ -16,7 +16,6 @@ use Symfony\Component\Cache\Simple\PhpFilesCache;
/**
* @group time-sensitive
* @group legacy
*/
class PhpFilesCacheTest extends CacheTestCase
{
@@ -26,6 +25,10 @@ class PhpFilesCacheTest extends CacheTestCase
public function createSimpleCache()
{
if (!PhpFilesCache::isSupported()) {
$this->markTestSkipped('OPcache extension is not enabled.');
}
return new PhpFilesCache('sf-cache');
}
+4 -5
View File
@@ -11,12 +11,13 @@
namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
use Symfony\Component\Cache\Simple\Psr6Cache;
/**
* @group legacy
* @group time-sensitive
*/
abstract class Psr6CacheTest extends CacheTestCase
class Psr6CacheTest extends CacheTestCase
{
protected $skippedTests = [
'testPrune' => 'Psr6Cache just proxies',
@@ -24,8 +25,6 @@ abstract class Psr6CacheTest extends CacheTestCase
public function createSimpleCache($defaultLifetime = 0)
{
return new Psr6Cache($this->createCacheItemPool($defaultLifetime));
return new Psr6Cache(new FilesystemAdapter('', $defaultLifetime));
}
abstract protected function createCacheItemPool($defaultLifetime = 0);
}
@@ -1,26 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Adapter\FilesystemAdapter;
/**
* @group time-sensitive
* @group legacy
*/
class Psr6CacheWithAdapterTest extends Psr6CacheTest
{
protected function createCacheItemPool($defaultLifetime = 0)
{
return new FilesystemAdapter('', $defaultLifetime);
}
}
@@ -1,26 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Tests\Fixtures\ExternalAdapter;
/**
* @group time-sensitive
* @group legacy
*/
class Psr6CacheWithoutAdapterTest extends Psr6CacheTest
{
protected function createCacheItemPool($defaultLifetime = 0)
{
return new ExternalAdapter($defaultLifetime);
}
}
+1 -4
View File
@@ -11,12 +11,9 @@
namespace Symfony\Component\Cache\Tests\Simple;
/**
* @group legacy
*/
class RedisArrayCacheTest extends AbstractRedisCacheTest
{
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
parent::setupBeforeClass();
if (!class_exists('RedisArray')) {
+2 -5
View File
@@ -13,12 +13,9 @@ namespace Symfony\Component\Cache\Tests\Simple;
use Symfony\Component\Cache\Simple\RedisCache;
/**
* @group legacy
*/
class RedisCacheTest extends AbstractRedisCacheTest
{
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
parent::setupBeforeClass();
self::$redis = RedisCache::createConnection('redis://'.getenv('REDIS_HOST'));
@@ -52,7 +49,7 @@ class RedisCacheTest extends AbstractRedisCacheTest
public function testFailedCreateConnection($dsn)
{
$this->expectException('Symfony\Component\Cache\Exception\InvalidArgumentException');
$this->expectExceptionMessage('Redis connection failed');
$this->expectExceptionMessage('Redis connection ');
RedisCache::createConnection($dsn);
}
@@ -11,12 +11,9 @@
namespace Symfony\Component\Cache\Tests\Simple;
/**
* @group legacy
*/
class RedisClusterCacheTest extends AbstractRedisCacheTest
{
public static function setUpBeforeClass(): void
public static function setUpBeforeClass()
{
if (!class_exists('RedisCluster')) {
self::markTestSkipped('The RedisCluster class is required.');
@@ -16,7 +16,6 @@ use Symfony\Component\Cache\Simple\TraceableCache;
/**
* @group time-sensitive
* @group legacy
*/
class TraceableCacheTest extends CacheTestCase
{
+3 -3
View File
@@ -24,11 +24,11 @@ trait PdoPruneableTrait
$getPdoConn = $o->getMethod('getConnection');
$getPdoConn->setAccessible(true);
/** @var \Doctrine\DBAL\Statement $select */
/** @var \Doctrine\DBAL\Statement|\PDOStatement $select */
$select = $getPdoConn->invoke($cache)->prepare('SELECT 1 FROM cache_items WHERE item_id LIKE :id');
$select->bindValue(':id', sprintf('%%%s', $name));
$select->execute();
$result = $select->execute();
return 0 === \count($select->fetchAll(\PDO::FETCH_COLUMN));
return 1 !== (int) (\is_object($result) ? $result->fetchOne() : $select->fetch(\PDO::FETCH_COLUMN));
}
}
-158
View File
@@ -1,158 +0,0 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Cache\Tests\Traits;
use Symfony\Component\Cache\CacheItem;
/**
* Common assertions for TagAware adapters.
*
* @method \Symfony\Component\Cache\Adapter\TagAwareAdapterInterface createCachePool() Must be implemented by TestCase
*/
trait TagAwareTestTrait
{
public function testInvalidTag()
{
$this->expectException('Psr\Cache\InvalidArgumentException');
$pool = $this->createCachePool();
$item = $pool->getItem('foo');
$item->tag(':');
}
public function testInvalidateTags()
{
$pool = $this->createCachePool();
$i0 = $pool->getItem('i0');
$i1 = $pool->getItem('i1');
$i2 = $pool->getItem('i2');
$i3 = $pool->getItem('i3');
$foo = $pool->getItem('foo');
$pool->save($i0->tag('bar'));
$pool->save($i1->tag('foo'));
$pool->save($i2->tag('foo')->tag('bar'));
$pool->save($i3->tag('foo')->tag('baz'));
$pool->save($foo);
$pool->invalidateTags(['bar']);
$this->assertFalse($pool->getItem('i0')->isHit());
$this->assertTrue($pool->getItem('i1')->isHit());
$this->assertFalse($pool->getItem('i2')->isHit());
$this->assertTrue($pool->getItem('i3')->isHit());
$this->assertTrue($pool->getItem('foo')->isHit());
$pool->invalidateTags(['foo']);
$this->assertFalse($pool->getItem('i1')->isHit());
$this->assertFalse($pool->getItem('i3')->isHit());
$this->assertTrue($pool->getItem('foo')->isHit());
$anotherPoolInstance = $this->createCachePool();
$this->assertFalse($anotherPoolInstance->getItem('i1')->isHit());
$this->assertFalse($anotherPoolInstance->getItem('i3')->isHit());
$this->assertTrue($anotherPoolInstance->getItem('foo')->isHit());
}
public function testInvalidateCommits()
{
$pool = $this->createCachePool();
$foo = $pool->getItem('foo');
$foo->tag('tag');
$pool->saveDeferred($foo->set('foo'));
$pool->invalidateTags(['tag']);
// ??: This seems to contradict a bit logic in deleteItems, where it does unset($this->deferred[$key]); on key matches
$foo = $pool->getItem('foo');
$this->assertTrue($foo->isHit());
}
public function testTagsAreCleanedOnSave()
{
$pool = $this->createCachePool();
$i = $pool->getItem('k');
$pool->save($i->tag('foo'));
$i = $pool->getItem('k');
$pool->save($i->tag('bar'));
$pool->invalidateTags(['foo']);
$this->assertTrue($pool->getItem('k')->isHit());
}
public function testTagsAreCleanedOnDelete()
{
$pool = $this->createCachePool();
$i = $pool->getItem('k');
$pool->save($i->tag('foo'));
$pool->deleteItem('k');
$pool->save($pool->getItem('k'));
$pool->invalidateTags(['foo']);
$this->assertTrue($pool->getItem('k')->isHit());
}
public function testTagItemExpiry()
{
if (isset($this->skippedTests[__FUNCTION__])) {
$this->markTestSkipped($this->skippedTests[__FUNCTION__]);
}
$pool = $this->createCachePool(10);
$item = $pool->getItem('foo');
$item->tag(['baz']);
$item->expiresAfter(100);
$pool->save($item);
$pool->invalidateTags(['baz']);
$this->assertFalse($pool->getItem('foo')->isHit());
sleep(20);
$this->assertFalse($pool->getItem('foo')->isHit());
}
/**
* @group legacy
*/
public function testGetPreviousTags()
{
$pool = $this->createCachePool();
$i = $pool->getItem('k');
$pool->save($i->tag('foo'));
$i = $pool->getItem('k');
$this->assertSame(['foo' => 'foo'], $i->getPreviousTags());
}
public function testGetMetadata()
{
$pool = $this->createCachePool();
$i = $pool->getItem('k');
$pool->save($i->tag('foo'));
$i = $pool->getItem('k');
$this->assertSame(['foo' => 'foo'], $i->getMetadata()[CacheItem::METADATA_TAGS]);
}
}