diff --git a/.travis.yml b/.travis.yml
index 4897e99485..065caafe41 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -38,6 +38,7 @@ cache:
- php-$MIN_PHP
services:
+ - memcached
- mongodb
- redis-server
@@ -60,7 +61,7 @@ before_install:
- if [[ ! $skip && $PHP = 5.* ]]; then (echo yes | pecl install -f apcu-4.0.11 && echo apc.enable_cli = 1 >> $INI_FILE); fi
- if [[ ! $skip && $PHP = 7.* ]]; then (echo yes | pecl install -f apcu-5.1.6 && echo apc.enable_cli = 1 >> $INI_FILE); fi
- if [[ ! $deps && $PHP = 5.* ]]; then (cd src/Symfony/Component/Debug/Resources/ext && phpize && ./configure && make && echo extension = $(pwd)/modules/symfony_debug.so >> $INI_FILE); fi
- - if [[ ! $skip && $PHP = 5.* ]]; then pecl install -f memcached-2.1.0; fi
+ - if [[ ! $skip && ! $PHP = hhvm* ]]; then echo extension = memcached.so >> $INI_FILE; fi
- if [[ ! $skip && ! $PHP = hhvm* ]]; then echo extension = ldap.so >> $INI_FILE; fi
- if [[ ! $skip && ! $PHP = hhvm* ]]; then echo extension = redis.so >> $INI_FILE; fi;
- if [[ ! $skip && ! $PHP = hhvm* ]]; then phpenv config-rm xdebug.ini || echo "xdebug not available"; fi
diff --git a/phpunit.xml.dist b/phpunit.xml.dist
index 7652c58475..336c320de9 100644
--- a/phpunit.xml.dist
+++ b/phpunit.xml.dist
@@ -16,6 +16,7 @@
+
diff --git a/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php
index 55b4dc19b1..7a766e073f 100644
--- a/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php
+++ b/src/Symfony/Component/Cache/Tests/Adapter/MemcachedAdapterTest.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Cache\Tests\Adapter;
+use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Adapter\MemcachedAdapter;
class MemcachedAdapterTest extends AdapterTestCase
@@ -28,14 +29,13 @@ class MemcachedAdapterTest extends AdapterTestCase
if (!MemcachedAdapter::isSupported()) {
self::markTestSkipped('Extension memcached >=2.2.0 required.');
}
+ self::$client = AbstractAdapter::createConnection('memcached://'.getenv('MEMCACHED_HOST'));
+ self::$client->get('foo');
+ $code = self::$client->getResultCode();
- self::$client = new \Memcached();
- self::$client->addServers(array(array(
- getenv('MEMCACHED_HOST') ?: '127.0.0.1',
- getenv('MEMCACHED_PORT') ?: 11211,
- )));
-
- parent::setupBeforeClass();
+ if (\Memcached::RES_SUCCESS !== $code && \Memcached::RES_NOTFOUND !== $code) {
+ self::markTestSkipped('Memcached error: '.strtolower(self::$client->getResultMessage()));
+ }
}
public function createCachePool($defaultLifetime = 0)
@@ -43,8 +43,130 @@ class MemcachedAdapterTest extends AdapterTestCase
return new MemcachedAdapter(self::$client, str_replace('\\', '.', __CLASS__), $defaultLifetime);
}
- public function testIsSupported()
+ public function testOptions()
+ {
+ $client = MemcachedAdapter::createConnection(array(), array(
+ 'libketama_compatible' => false,
+ 'distribution' => 'modula',
+ 'compression' => true,
+ 'serializer' => 'php',
+ 'hash' => 'md5',
+ ));
+
+ $this->assertSame(\Memcached::SERIALIZER_PHP, $client->getOption(\Memcached::OPT_SERIALIZER));
+ $this->assertSame(\Memcached::HASH_MD5, $client->getOption(\Memcached::OPT_HASH));
+ $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION));
+ $this->assertSame(0, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE));
+ $this->assertSame(\Memcached::DISTRIBUTION_MODULA, $client->getOption(\Memcached::OPT_DISTRIBUTION));
+ }
+
+ /**
+ * @dataProvider provideBadOptions
+ * @expectedException \ErrorException
+ * @expectedExceptionMessage constant(): Couldn't find constant Memcached::
+ */
+ public function testBadOptions($name, $value)
+ {
+ MemcachedAdapter::createConnection(array(), array($name => $value));
+ }
+
+ public function provideBadOptions()
+ {
+ return array(
+ array('foo', 'bar'),
+ array('hash', 'zyx'),
+ array('serializer', 'zyx'),
+ array('distribution', 'zyx'),
+ );
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Cache\Exception\CacheException
+ * @expectedExceptionMessage MemcachedAdapter: "binary_protocol" option must be enabled.
+ */
+ public function testBinaryProtocol()
+ {
+ new MemcachedAdapter(MemcachedAdapter::createConnection(array(), array('binary_protocol' => false)));
+ }
+
+ public function testDefaultOptions()
{
$this->assertTrue(MemcachedAdapter::isSupported());
+
+ $client = MemcachedAdapter::createConnection(array());
+
+ $this->assertTrue($client->getOption(\Memcached::OPT_COMPRESSION));
+ $this->assertSame(1, $client->getOption(\Memcached::OPT_BINARY_PROTOCOL));
+ $this->assertSame(1, $client->getOption(\Memcached::OPT_LIBKETAMA_COMPATIBLE));
+ }
+
+ /**
+ * @expectedException \Symfony\Component\Cache\Exception\CacheException
+ * @expectedExceptionMessage MemcachedAdapter: "serializer" option must be "php" or "igbinary".
+ */
+ public function testOptionSerializer()
+ {
+ if (!\Memcached::HAVE_JSON) {
+ $this->markTestSkipped('Memcached::HAVE_JSON required');
+ }
+
+ new MemcachedAdapter(MemcachedAdapter::createConnection(array(), array('serializer' => 'json')));
+ }
+
+ /**
+ * @dataProvider provideServersSetting
+ */
+ public function testServersSetting($dsn, $host, $port)
+ {
+ $client1 = MemcachedAdapter::createConnection($dsn);
+ $client2 = MemcachedAdapter::createConnection(array($dsn));
+ $client3 = MemcachedAdapter::createConnection(array(array($host, $port)));
+ $expect = array(
+ 'host' => $host,
+ 'port' => $port,
+ );
+
+ $f = function ($s) { return array('host' => $s['host'], 'port' => $s['port']); };
+ $this->assertSame(array($expect), array_map($f, $client1->getServerList()));
+ $this->assertSame(array($expect), array_map($f, $client2->getServerList()));
+ $this->assertSame(array($expect), array_map($f, $client3->getServerList()));
+ }
+
+ public function provideServersSetting()
+ {
+ yield array(
+ 'memcached://127.0.0.1/50',
+ '127.0.0.1',
+ 11211,
+ );
+ yield array(
+ 'memcached://localhost:11222?weight=25',
+ 'localhost',
+ 11222,
+ );
+ if (ini_get('memcached.use_sasl')) {
+ yield array(
+ 'memcached://user:password@127.0.0.1?weight=50',
+ '127.0.0.1',
+ 11211,
+ );
+ }
+ yield array(
+ 'memcached:///var/run/memcached.sock?weight=25',
+ '/var/run/memcached.sock',
+ 0,
+ );
+ yield array(
+ 'memcached:///var/local/run/memcached.socket?weight=25',
+ '/var/local/run/memcached.socket',
+ 0,
+ );
+ if (ini_get('memcached.use_sasl')) {
+ yield array(
+ 'memcached://user:password@/var/local/run/memcached.socket?weight=25',
+ '/var/local/run/memcached.socket',
+ 0,
+ );
+ }
}
}
diff --git a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterTest.php b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterTest.php
index 301d531ac3..a8f7a673f8 100644
--- a/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterTest.php
+++ b/src/Symfony/Component/Cache/Tests/Adapter/RedisAdapterTest.php
@@ -11,6 +11,7 @@
namespace Symfony\Component\Cache\Tests\Adapter;
+use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\Cache\Adapter\RedisAdapter;
class RedisAdapterTest extends AbstractRedisAdapterTest
@@ -18,8 +19,7 @@ class RedisAdapterTest extends AbstractRedisAdapterTest
public static function setupBeforeClass()
{
parent::setupBeforeClass();
- self::$redis = new \Redis();
- self::$redis->connect(getenv('REDIS_HOST'));
+ self::$redis = AbstractAdapter::createConnection('redis://'.getenv('REDIS_HOST'));
}
public function testCreateConnection()
diff --git a/src/Symfony/Component/Cache/phpunit.xml.dist b/src/Symfony/Component/Cache/phpunit.xml.dist
index 3e164e64b5..19b5496277 100644
--- a/src/Symfony/Component/Cache/phpunit.xml.dist
+++ b/src/Symfony/Component/Cache/phpunit.xml.dist
@@ -9,6 +9,7 @@
+