Compare commits

..

30 Commits

Author SHA1 Message Date
Daniele Alessandri 7411cdb23e Backported changes from the mainline library to the PHP 5.2 branch (up to commit f97312d) 2011-04-01 20:36:41 +02:00
Daniele Alessandri ada8878295 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 17f83a5) 2011-04-01 20:27:57 +02:00
Daniele Alessandri 0546f74374 Backported changes from the mainline library to the PHP 5.2 branch (up to commit f76d616) 2011-02-12 21:56:38 +01:00
Daniele Alessandri 897c217fe3 Backported changes from the mainline library to the PHP 5.2 branch (up to commit ca422b0) 2011-02-12 14:03:58 +01:00
Daniele Alessandri c5d29a8ca4 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 118af28) 2011-01-26 15:24:19 +01:00
Daniele Alessandri 3f058cb5ea Backported changes from the mainline library to the PHP 5.2 branch (up to commit ec42796) 2011-01-01 18:53:59 +01:00
Daniele Alessandri f2ab80e7e9 Add missing example for CAS with MULTI/EXEC abstraction. 2011-01-01 17:40:35 +01:00
Daniele Alessandri ddb5109805 Backported changes from the mainline library to the PHP 5.2 branch (up to commit c75bdd9) 2011-01-01 17:18:33 +01:00
Daniele Alessandri ccb48a1857 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 7db5e65) 2010-11-28 20:25:36 +01:00
Daniele Alessandri 2fc80a5f0d Backported changes from the mainline library to the PHP 5.2 branch (up to commit 975bd98) 2010-11-28 19:25:40 +01:00
Daniele Alessandri 49e151a3d0 Backported changes from the mainline library to the PHP 5.2 branch (up to commit bd961a7) 2010-07-11 17:57:26 +02:00
Daniele Alessandri 7d181160a3 Backported changes from the mainline library to the PHP 5.2 branch (up to commit f073bc8) 2010-07-01 17:10:52 +02:00
Daniele Alessandri c546351e1d Backported changes from the mainline library to the PHP 5.2 branch (up to commit 3c33c74) 2010-05-24 19:37:00 +02:00
Daniele Alessandri 6ca4087118 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 0e69438) 2010-05-23 10:04:05 +02:00
Daniele Alessandri 654b11ba6d Backported changes from the mainline library to the PHP 5.2 branch (up to commit c781e91) 2010-05-22 17:26:01 +02:00
Daniele Alessandri cf758f23d4 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 84cb28e) 2010-05-18 20:28:54 +02:00
Daniele Alessandri 7806614041 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 35f7ea2) 2010-05-16 13:05:56 +02:00
Daniele Alessandri 852959cbd1 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 3edcdc5) 2010-01-28 00:00:01 +01:00
Daniele Alessandri 3ebdf16d1c Backported changes from the mainline library to the PHP 5.2 branch (up to commit c81e02b) 2010-01-23 16:51:07 +01:00
Daniele Alessandri 35142cfbcf Backported changes from the mainline library to the PHP 5.2 branch (up to commit 35016ba) 2010-01-09 14:54:20 +01:00
Daniele Alessandri 0f1d4675cf Backported the test suite to PHP 5.2. This was the last blocking point for a full PHP 5.2-compatible release of Predis." 2009-12-31 17:32:24 +01:00
Daniele Alessandri 465bd45147 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 2a06d84) 2009-12-31 15:21:48 +01:00
Daniele Alessandri 3bfe3897a7 Backported changes from the mainline library to the PHP 5.2 branch (up to commit b757afe) 2009-12-27 11:06:30 +01:00
Daniele Alessandri 0f966af8e3 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 6814845) 2009-12-26 19:48:55 +01:00
Daniele Alessandri e3e0475826 Fixed the pipline example in the README. 2009-12-26 19:17:48 +01:00
Daniele Alessandri 767c488d35 Updated README to reflect the differences of the PHP 5.2 version of Predis. 2009-12-26 18:59:14 +01:00
Daniele Alessandri 1205026fb1 Backported changes from the mainline library to the PHP 5.2 branch (up to commit 6e39491) 2009-12-26 18:22:39 +01:00
Daniele Alessandri 9c314c5b5f Backported changes from the mainline library to the PHP 5.2 branch. 2009-12-16 16:12:51 +01:00
Daniele Alessandri d05a62e82c Updated the examples to match the PHP 5.2 version. 2009-12-04 22:10:54 +01:00
Daniele Alessandri 6769e0de56 First drop of Predis backported to PHP 5.2.x. The library seems to work but it is completely untested (the test suite needs to be backported too). 2009-12-04 22:08:08 +01:00
15 changed files with 1794 additions and 1772 deletions
+43 -43
View File
@@ -35,20 +35,20 @@ v0.6.6 (2011-04-01)
a couple of corner cases. See also ISSUE #27.
v0.6.5 (2011-02-12)
* FIX: due to an untested internal change introduced in v0.6.4, a wrong
handling of bulk reads of zero-length values was producing protocol
* FIX: due to an untested internal change introduced in v0.6.4, a wrong
handling of bulk reads of zero-length values was producing protocol
desynchronization errors (ISSUE #20).
v0.6.4 (2011-02-12)
* Various performance improvements (15% ~ 25%) especially when dealing with
long multibulk replies or when using clustered connections.
* Added the "on_retry" option to Predis\MultiExecBlock that can be used to
* Added the "on_retry" option to Predis_MultiExecBlock that can be used to
specify an external callback (or any callable object) that gets invoked
whenever a transaction is aborted by the server.
* Added inline (p)subscribtion via options when initializing an instance of
Predis\PubSubContext.
Predis_PubSubContext.
v0.6.3 (2011-01-01)
* New commands available in the Redis v2.2 profile (dev):
@@ -58,7 +58,7 @@ v0.6.3 (2011-01-01)
* The abstraction for MULTI/EXEC transactions has been dramatically improved
by providing support for check-and-set (CAS) operations when using Redis >=
2.2. Aborted transactions can also be optionally replayed in automatic up
to a user-defined number of times, after which a Predis\AbortedMultiExec
to a user-defined number of times, after which a Predis_AbortedMultiExec
exception is thrown.
v0.6.2 (2010-11-28)
@@ -73,14 +73,14 @@ v0.6.2 (2010-11-28)
* WATCH also accepts a single array parameter with the keys that should be
monitored during a transaction.
* Improved the behaviour of Predis\MultiExecBlock in certain corner cases.
* Improved the behaviour of Predis_MultiExecBlock in certain corner cases.
* Improved parameters checking for the SORT command.
* FIX: the STORE parameter for the SORT command didn't work correctly when
using '0' as the target key (ISSUE #13).
* FIX: the methods for UNWATCH and DISCARD do not break anymore method
* FIX: the methods for UNWATCH and DISCARD do not break anymore method
chaining with Predis\MultiExecBlock.
v0.6.1 (2010-07-11)
@@ -89,37 +89,37 @@ v0.6.1 (2010-07-11)
* New commands available in the Redis v2.2 profile (dev):
- Misc. : WATCH, UNWATCH
* Optional modifiers for ZRANGE, ZREVRANGE and ZRANGEBYSCORE queries are
supported using an associative array passed as the last argument of their
* Optional modifiers for ZRANGE, ZREVRANGE and ZRANGEBYSCORE queries are
supported using an associative array passed as the last argument of their
respective methods.
* The LIMIT modifier for ZRANGEBYSCORE can be specified using either:
* The LIMIT modifier for ZRANGEBYSCORE can be specified using either:
- an indexed array: array($offset, $count)
- an associative array: array('offset' => $offset, 'count' => $count)
* The method Predis\Client::__construct() now accepts also instances of
Predis\ConnectionParameters.
* The method Predis_Client::__construct() now accepts also instances of
Predis_ConnectionParameters.
* Predis\MultiExecBlock and Predis\PubSubContext now throw an exception
when trying to create their instances using a profile that does not
support the required Redis commands or when the client is connected to
* Predis_MultiExecBlock and Predis_PubSubContext now throw an exception
when trying to create their instances using a profile that does not
support the required Redis commands or when the client is connected to
a cluster of connections.
* Various improvements to Predis\MultiExecBlock:
* Various improvements to Predis_MultiExecBlock:
- fixes and more consistent behaviour across various usage cases.
- support for WATCH and UNWATCH when using the current development
- support for WATCH and UNWATCH when using the current development
profile (Redis v2.2) and aborted transactions.
* New signature for Predis\Client::multiExec() which is now able to accept
an array of options for the underlying instance of Predis\MultiExecBlock.
* New signature for Predis_Client::multiExec() which is now able to accept
an array of options for the underlying instance of Predis_MultiExecBlock.
Backwards compatibility with previous releases of Predis is ensured.
* New signature for Predis\Client::pipeline() which is now able to accept
an array of options for the underlying instance of Predis\CommandPipeline.
Backwards compatibility with previous releases of Predis is ensured.
The method Predis\Client::pipelineSafe() is to be considered deprecated.
* New signature for Predis_Client::pipeline() which is now able to accept
an array of options for the underlying instance of Predis_CommandPipeline.
Backwards compatibility with previous releases of Predis is ensured.
The method Predis_Client::pipelineSafe() is to be considered deprecated.
* FIX: The WEIGHT modifier for ZUNIONSTORE and ZINTERSTORE was handled
* FIX: The WEIGHT modifier for ZUNIONSTORE and ZINTERSTORE was handled
incorrectly with more than two weights specified.
v0.6.0 (2010-05-24)
@@ -133,7 +133,7 @@ v0.6.0 (2010-05-24)
to instances of Redis 1.2.x).
* Support for Redis 1.0 is now optional and it is provided by requiring
'Predis_Compatibility.php' before creating an instance of Predis\Client.
'Predis_Compatibility.php' before creating an instance of Predis_Client.
* New commands added to the Redis 2.0 profile since Predis 0.5.1:
- Strings: SETEX, APPEND, SUBSTR
@@ -143,22 +143,22 @@ v0.6.0 (2010-05-24)
- PubSub : PUBLISH, SUBSCRIBE, UNSUBSCRIBE
- Misc. : DISCARD, CONFIG
* Introduced client-level options with the new Predis\ClientOptions class.
Options can be passed to Predis\Client::__construct in its second argument
as an array or an instance of Predis\ClientOptions. For brevity's sake and
compatibility with older versions, the constructor of Predis\Client still
accepts an instance of Predis\RedisServerProfile in its second argument.
* Introduced client-level options with the new Predis_ClientOptions class.
Options can be passed to Predis_Client::__construct in its second argument
as an array or an instance of Predis_ClientOptions. For brevity's sake and
compatibility with older versions, the constructor of Predis_Client still
accepts an instance of Predis_RedisServerProfile in its second argument.
The currently supported client options are:
- profile [default: "2.0" as of Predis 0.6.0]
specifies which server profile to use when connecting to Redis. This
option accepts an instance of Predis\RedisServerProfile or a string
option accepts an instance of Predis_RedisServerProfile or a string
that indicates the target version.
- key_distribution [default: Predis\Distribution\HashRing]
- key_distribution [default: Predis_Distribution_HashRing]
specifies which key distribution strategy to use to distribute keys
among the servers that compose a cluster. This option accepts an
instance of Predis\Distribution\IDistributionStrategy so that users
instance of Predis_Distribution_IDistributionStrategy so that users
can implement their own key distribution strategy. Optionally, the new
Predis\Distribution\KetamaPureRing class also provides a pure-PHP
Predis_Distribution_KetamaPureRing class also provides a pure-PHP
implementation of the same algorithm used by libketama.
- throw_on_error [default: TRUE]
server errors can optionally be handled "silently": instead of throwing
@@ -187,30 +187,30 @@ v0.6.0 (2010-05-24)
lifecycle. Persistent connections can lead to unpredictable or strange
behaviours, so they should be used with extreme care.
* Introduced the Predis\Pipeline\IPipelineExecutor interface. Classes that
implements this interface are used internally by the Predis\CommandPipeline
* Introduced the Predis_Pipeline_IPipelineExecutor interface. Classes that
implements this interface are used internally by the Predis_CommandPipeline
class to change the behaviour of the pipeline when writing/reading commands
from one or multiple servers. Here is the list of the default executors:
- Predis\Pipeline\StandardExecutor
- Predis_Pipeline_StandardExecutor
Exceptions generated by server errors might be thrown depending on the
options passed to the client (see "throw_on_error"). Instead, protocol
or network errors always throw exceptions. This is the default executor
for single and clustered connections and shares the same behaviour of
Predis 0.5.x.
- Predis\Pipeline\SafeExecutor
- Predis_Pipeline_SafeExecutor
Exceptions generated by server, protocol or network errors are not
thrown, instead they are returned in the response array as instances of
ResponseError or CommunicationException.
- Predis\Pipeline\SafeClusterExecutor
This executor shares the same behaviour of Predis\Pipeline\SafeExecutor
- Predis_Pipeline_SafeClusterExecutor
This executor shares the same behaviour of Predis_Pipeline_SafeExecutor
but it is geared towards clustered connections.
* Support for PUBSUB is handled by the new Predis\PubSubContext class, which
* Support for PUBSUB is handled by the new Predis_PubSubContext class, which
could also be used to build a callback dispatcher for PUBSUB scenarios.
* When connected to a cluster of connections, it is now possible to get a
new Predis\Client instance for a single connection of the cluster by
passing its alias/index to the new Predis\Client::getClientFor() method.
new Predis_Client instance for a single connection of the cluster by
passing its alias/index to the new Predis_Client::getClientFor() method.
* CommandPipeline and MultiExecBlock return their instances when invoking
commands, thus allowing method chaining in pipelines and multi-exec blocks.
+1 -1
View File
@@ -1,4 +1,4 @@
Copyright (c) 2009-2011 Daniele Alessandri
Copyright (c) 2009-2010 Daniele Alessandri
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
+17 -17
View File
@@ -36,7 +36,7 @@ complete coverage of all the features available in Predis.
You don't have to specify a tcp host and port when connecting to Redis instances
running on the localhost on the default port:
$redis = new Predis\Client();
$redis = new Predis_Client();
$redis->set('library', 'predis');
$value = $redis->get('library');
@@ -46,13 +46,13 @@ running on the localhost on the default port:
Pipelining helps with performances when there is the need to issue many commands
to a server in one go:
$redis = new Predis\Client('redis://10.0.0.1:6379/');
$replies = $redis->pipeline(function($pipe) {
$pipe->ping();
$pipe->incrby('counter', 10);
$pipe->incrby('counter', 30);
$pipe->get('counter');
});
$redis = new Predis_Client('redis://10.0.0.1:6379/');
$pipe = $redis->pipeline();
$pipe->ping();
$pipe->incrby('counter', 10);
$pipe->incrby('counter', 30);
$pipe->get('counter');
$replies = $pipe->execute();
### Pipelining multiple commands to multiple instances of Redis (sharding) ##
@@ -62,17 +62,17 @@ Furthermore, a pipeline can be initialized on a cluster of redis instances in th
same exact way they are created on single connection. Sharding is still transparent
to the user:
$redis = new Predis\Client(array(
$redis = new Predis_Client(array(
array('host' => '10.0.0.1', 'port' => 6379),
array('host' => '10.0.0.2', 'port' => 6379)
));
$replies = $redis->pipeline(function($pipe) {
for ($i = 0; $i < 1000; $i++) {
$pipe->set("key:$i", str_pad($i, 4, '0', 0));
$pipe->get("key:$i");
}
});
$pipe = $redis->pipeline();
for ($i = 0; $i < 1000; $i++) {
$pipe->set("key:$i", str_pad($i, 4, '0', 0));
$pipe->get("key:$i");
}
$replies = $pipe->flushPipeline();
### Definition and runtime registration of new commands on the client ###
@@ -84,11 +84,11 @@ its way into a stable Predis release, then you can start off by creating a new
class that matches the command type and its behaviour and then bind it to a
client instance at runtime. Actually, it is easier done than said:
class BrandNewRedisCommand extends \Predis\MultiBulkCommand {
class BrandNewRedisCommand extends Predis_MultiBulkCommand {
public function getCommandId() { return 'NEWCMD'; }
}
$redis = new Predis\Client();
$redis = new Predis_Client();
$redis->getProfile()->registerCommand('BrandNewRedisCommand', 'newcmd');
$redis->newcmd();
+10 -10
View File
@@ -4,17 +4,17 @@ require_once 'SharedConfigurations.php';
// When you have a whole set of consecutive commands to send to
// a redis server, you can use a pipeline to improve performances.
$redis = new Predis\Client($single_server);
$redis = new Predis_Client($single_server);
$replies = $redis->pipeline(function($pipe) {
$pipe->ping();
$pipe->flushdb();
$pipe->incrby('counter', 10);
$pipe->incrby('counter', 30);
$pipe->exists('counter');
$pipe->get('counter');
$pipe->mget('does_not_exist', 'counter');
});
$pipe = $redis->pipeline();
$pipe->ping();
$pipe->flushdb();
$pipe->incrby('counter', 10);
$pipe->incrby('counter', 30);
$pipe->exists('counter');
$pipe->get('counter');
$pipe->mget('does_not_exist', 'counter');
$replies = $pipe->execute();
print_r($replies);
+14 -6
View File
@@ -3,10 +3,10 @@ require_once 'SharedConfigurations.php';
// Developers can customize the distribution strategy used by the client
// to distribute keys among a cluster of servers simply by creating a class
// that implements the Predis\Distribution\IDistributionStrategy interface.
// that implements the Predis_Distribution_IDistributionStrategy interface.
class NaiveDistributionStrategy
implements Predis\Distribution\IDistributionStrategy {
implements Predis_Distribution_IDistributionStrategy {
private $_nodes, $_nodesCount;
@@ -20,10 +20,18 @@ class NaiveDistributionStrategy
$this->_nodesCount++;
}
private static function array_remove($array, $value) {
$newArray = array();
foreach ($array as $k => $v) {
if ($v !== $value) {
$newArray[] = $v;
}
}
return $newArray;
}
public function remove($node) {
$this->_nodes = array_filter($this->_nodes, function($n) use($node) {
return $n !== $node;
});
$this->_nodes = self::array_remove($this->_nodes, $node);
$this->_nodesCount = count($this->_nodes);
}
@@ -44,7 +52,7 @@ $options = array(
'key_distribution' => new NaiveDistributionStrategy(),
);
$redis = new Predis\Client($multiple_servers, $options);
$redis = new Predis_Client($multiple_servers, $options);
for ($i = 0; $i < 100; $i++) {
$redis->set("key:$i", str_pad($i, 4, '0', 0));
+8 -11
View File
@@ -20,22 +20,19 @@ function zpop($client, $zsetKey) {
$options = array(
'cas' => true, // Initialize with support for CAS operations
'watch' => $zsetKey, // Key that needs to be WATCHed to detect changes
'retry' => 3, // Number of retries on aborted transactions, after
// which the client bails out with an exception.
);
$txReply = $client->multiExec($options, function($tx)
use ($zsetKey, &$element) {
@list($element) = $tx->zrange($zsetKey, 0, 0);
if (isset($element)) {
$tx->multi(); // With CAS, MULTI *must* be explicitly invoked.
$tx->zrem($zsetKey, $element);
}
});
$tx = $client->multiExec($options);
@list($element) = $tx->zrange($zsetKey, 0, 0);
if (isset($element)) {
$tx->multi(); // With CAS, MULTI *must* be explicitly invoked.
$tx->zrem($zsetKey, $element);
$tx->exec();
}
return $element;
}
$redis = new Predis\Client($single_server, 'dev');
$redis = new Predis_Client($single_server, 'dev');
$zpopped = zpop($redis, 'zset');
echo isset($zpopped) ? "ZPOPed $zpopped" : "Nothing to ZPOP!", "\n";
?>
+1 -1
View File
@@ -11,7 +11,7 @@ $mkv = array(
'usr:0003' => 'Third user'
);
$redis = new Predis\Client($single_server);
$redis = new Predis_Client($single_server);
$redis->mset($mkv);
$retval = $redis->mget(array_keys($mkv));
+1 -1
View File
@@ -5,7 +5,7 @@ require_once 'SharedConfigurations.php';
// events published on certain channels (PUBSUB).
// Create a client and disable r/w timeout on the socket
$redis = new Predis\Client($single_server + array('read_write_timeout' => 0));
$redis = new Predis_Client($single_server + array('read_write_timeout' => 0));
// Initialize a new pubsub context
$pubsub = $redis->pubSubContext();
+1 -1
View File
@@ -3,7 +3,7 @@ require_once 'SharedConfigurations.php';
// simple set and get scenario
$redis = new Predis\Client($single_server);
$redis = new Predis_Client($single_server);
$redis->set('library', 'predis');
$retval = $redis->get('library');
+757 -755
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+247 -213
View File
@@ -21,11 +21,11 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
/* ConnectionParameters */
function testConnectionParametersDefaultValues() {
$params = new \Predis\ConnectionParameters();
$params = new Predis_ConnectionParameters();
$this->assertEquals(\Predis\ConnectionParameters::DEFAULT_HOST, $params->host);
$this->assertEquals(\Predis\ConnectionParameters::DEFAULT_PORT, $params->port);
$this->assertEquals(\Predis\ConnectionParameters::DEFAULT_TIMEOUT, $params->connection_timeout);
$this->assertEquals(Predis_ConnectionParameters::DEFAULT_HOST, $params->host);
$this->assertEquals(Predis_ConnectionParameters::DEFAULT_PORT, $params->port);
$this->assertEquals(Predis_ConnectionParameters::DEFAULT_TIMEOUT, $params->connection_timeout);
$this->assertNull($params->read_write_timeout);
$this->assertNull($params->database);
$this->assertNull($params->password);
@@ -34,7 +34,7 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
function testConnectionParametersSetupValuesArray() {
$paramsArray = RC::getConnectionParametersArgumentsArray();
$params = new \Predis\ConnectionParameters($paramsArray);
$params = new Predis_ConnectionParameters($paramsArray);
$this->assertEquals($paramsArray['host'], $params->host);
$this->assertEquals($paramsArray['port'], $params->port);
@@ -48,7 +48,7 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
function testConnectionParametersSetupValuesString() {
$paramsArray = RC::getConnectionParametersArgumentsArray();
$paramsString = RC::getConnectionParametersArgumentsString($paramsArray);
$params = new \Predis\ConnectionParameters($paramsArray);
$params = new Predis_ConnectionParameters($paramsArray);
$this->assertEquals($paramsArray['host'], $params->host);
$this->assertEquals($paramsArray['port'], $params->port);
@@ -65,81 +65,81 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
function testCommand_TestArguments() {
$cmdArgs = array('key1', 'key2', 'key3');
$cmd = new \Predis\Commands\GetMultiple();
$cmd = new Predis_Commands_GetMultiple();
$cmd->setArgumentsArray($cmdArgs);
$this->assertEquals($cmdArgs[0], $cmd->getArgument(0));
$this->assertEquals($cmdArgs[1], $cmd->getArgument(1));
$this->assertEquals($cmdArgs[2], $cmd->getArgument(2));
$cmd = new \Predis\Commands\GetMultiple();
$cmd = new Predis_Commands_GetMultiple();
$cmd->setArguments('key1', 'key2', 'key3');
$this->assertEquals($cmdArgs[0], $cmd->getArgument(0));
$this->assertEquals($cmdArgs[1], $cmd->getArgument(1));
$this->assertEquals($cmdArgs[2], $cmd->getArgument(2));
$cmd = new \Predis\Commands\Ping();
$cmd = new Predis_Commands_Ping();
$this->assertNull($cmd->getArgument(0));
}
function testCommand_InlineWithNoArguments() {
$cmd = new \Predis\Compatibility\v1_0\Commands\Ping();
$cmd = new Predis_Compatibility_v1_0_Commands_Ping();
$this->assertInstanceOf('\Predis\InlineCommand', $cmd);
$this->assertInstanceOf('Predis_InlineCommand', $cmd);
$this->assertEquals('PING', $cmd->getCommandId());
$this->assertFalse($cmd->closesConnection());
$this->assertFalse($cmd->canBeHashed());
$this->assertNull($cmd->getHash(new \Predis\Distribution\HashRing()));
$this->assertEquals("PING\r\n", $cmd());
$this->assertNull($cmd->getHash(new Predis_Distribution_HashRing()));
$this->assertEquals("PING\r\n", $cmd->invoke());
}
function testCommand_InlineWithArguments() {
$cmd = new \Predis\Compatibility\v1_0\Commands\Get();
$cmd = new Predis_Compatibility_v1_0_Commands_Get();
$cmd->setArgumentsArray(array('key'));
$this->assertInstanceOf('\Predis\InlineCommand', $cmd);
$this->assertInstanceOf('Predis_InlineCommand', $cmd);
$this->assertEquals('GET', $cmd->getCommandId());
$this->assertFalse($cmd->closesConnection());
$this->assertTrue($cmd->canBeHashed());
$this->assertNotNull($cmd->getHash(new \Predis\Distribution\HashRing()));
$this->assertEquals("GET key\r\n", $cmd());
$this->assertNotNull($cmd->getHash(new Predis_Distribution_HashRing()));
$this->assertEquals("GET key\r\n", $cmd->invoke());
}
function testCommand_BulkWithArguments() {
$cmd = new \Predis\Compatibility\v1_0\Commands\Set();
$cmd = new Predis_Compatibility_v1_0_Commands_Set();
$cmd->setArgumentsArray(array('key', 'value'));
$this->assertInstanceOf('\Predis\BulkCommand', $cmd);
$this->assertInstanceOf('Predis_BulkCommand', $cmd);
$this->assertEquals('SET', $cmd->getCommandId());
$this->assertFalse($cmd->closesConnection());
$this->assertTrue($cmd->canBeHashed());
$this->assertNotNull($cmd->getHash(new \Predis\Distribution\HashRing()));
$this->assertEquals("SET key 5\r\nvalue\r\n", $cmd());
$this->assertNotNull($cmd->getHash(new Predis_Distribution_HashRing()));
$this->assertEquals("SET key 5\r\nvalue\r\n", $cmd->invoke());
}
function testCommand_MultiBulkWithArguments() {
$cmd = new \Predis\Commands\SetMultiple();
$cmd = new Predis_Commands_SetMultiple();
$cmd->setArgumentsArray(array('key1', 'value1', 'key2', 'value2'));
$this->assertInstanceOf('\Predis\MultiBulkCommand', $cmd);
$this->assertInstanceOf('Predis_MultiBulkCommand', $cmd);
$this->assertEquals('MSET', $cmd->getCommandId());
$this->assertFalse($cmd->closesConnection());
$this->assertFalse($cmd->canBeHashed());
$this->assertNotNull($cmd->getHash(new \Predis\Distribution\HashRing()));
$this->assertEquals("*5\r\n$4\r\nMSET\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n", $cmd());
$this->assertNotNull($cmd->getHash(new Predis_Distribution_HashRing()));
$this->assertEquals("*5\r\n$4\r\nMSET\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n", $cmd->invoke());
}
function testCommand_ParseResponse() {
// default parser
$cmd = new \Predis\Commands\Get();
$cmd = new Predis_Commands_Get();
$this->assertEquals('test', $cmd->parseResponse('test'));
// overridden parser (boolean)
$cmd = new \Predis\Commands\Exists();
$cmd = new Predis_Commands_Exists();
$this->assertTrue($cmd->parseResponse('1'));
$this->assertFalse($cmd->parseResponse('0'));
// overridden parser (boolean)
$cmd = new \Predis\Commands\Ping();
$cmd = new Predis_Commands_Ping();
$this->assertTrue($cmd->parseResponse('PONG'));
// overridden parser (complex)
@@ -150,17 +150,17 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
/* RedisServerProfile and derivates */
function testRedisServerProfile_GetSpecificVersions() {
$this->assertInstanceOf('\Predis\RedisServer_v1_0', \Predis\RedisServerProfile::get('1.0'));
$this->assertInstanceOf('\Predis\RedisServer_v1_2', \Predis\RedisServerProfile::get('1.2'));
$this->assertInstanceOf('\Predis\RedisServer_v2_0', \Predis\RedisServerProfile::get('2.0'));
$this->assertInstanceOf('\Predis\RedisServer_vNext', \Predis\RedisServerProfile::get('dev'));
$this->assertInstanceOf('\Predis\RedisServerProfile', \Predis\RedisServerProfile::get('default'));
$this->assertEquals(\Predis\RedisServerProfile::get('default'), \Predis\RedisServerProfile::getDefault());
$this->assertInstanceOf('Predis_RedisServer_v1_0', Predis_RedisServerProfile::get('1.0'));
$this->assertInstanceOf('Predis_RedisServer_v1_2', Predis_RedisServerProfile::get('1.2'));
$this->assertInstanceOf('Predis_RedisServer_v2_0', Predis_RedisServerProfile::get('2.0'));
$this->assertInstanceOf('Predis_RedisServer_vNext', Predis_RedisServerProfile::get('dev'));
$this->assertInstanceOf('Predis_RedisServerProfile', Predis_RedisServerProfile::get('default'));
$this->assertEquals(Predis_RedisServerProfile::get('default'), Predis_RedisServerProfile::getDefault());
}
function testRedisServerProfile_SupportedCommands() {
$profile_10 = \Predis\RedisServerProfile::get('1.0');
$profile_12 = \Predis\RedisServerProfile::get('1.2');
$profile_10 = Predis_RedisServerProfile::get('1.0');
$profile_12 = Predis_RedisServerProfile::get('1.2');
$this->assertTrue($profile_10->supportsCommand('info'));
$this->assertTrue($profile_12->supportsCommand('info'));
@@ -173,32 +173,31 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
}
function testRedisServerProfile_CommandsCreation() {
$profile = \Predis\RedisServerProfile::get('1.0');
$profile = Predis_RedisServerProfile::get('1.0');
$cmdNoArgs = $profile->createCommand('info');
$this->assertInstanceOf('\Predis\Compatibility\v1_0\Commands\Info', $cmdNoArgs);
$this->assertInstanceOf('Predis_Compatibility_v1_0_Commands_Info', $cmdNoArgs);
$this->assertNull($cmdNoArgs->getArgument());
$args = array('key1', 'key2');
$cmdWithArgs = $profile->createCommand('mget', $args);
$this->assertInstanceOf('\Predis\Compatibility\v1_0\Commands\GetMultiple', $cmdWithArgs);
$this->assertInstanceOf('Predis_Compatibility_v1_0_Commands_GetMultiple', $cmdWithArgs);
$this->assertEquals($args[0], $cmdWithArgs->getArgument()); // TODO: why?
$this->assertEquals($args[0], $cmdWithArgs->getArgument(0));
$this->assertEquals($args[1], $cmdWithArgs->getArgument(1));
$bogusCommand = 'not_existing_command';
$expectedMessage = "'$bogusCommand' is not a registered Redis command";
RC::testForClientException($this, $expectedMessage, function()
use($profile, $bogusCommand) {
$profile->createCommand($bogusCommand);
});
RC::testForClientException($this, $expectedMessage, p_anon("\$test", "
\$profile = Predis_RedisServerProfile::getDefault();
\$profile->createCommand('$bogusCommand');
"));
}
function testRedisServerProfile_CommandsRegistration() {
$profile = \Predis\RedisServerProfile::get('1.0');
$profile = Predis_RedisServerProfile::get('1.0');
$cmdId = 'mset';
$cmdClass = '\Predis\Commands\SetMultiple';
$cmdClass = 'Predis_Commands_SetMultiple';
$this->assertFalse($profile->supportsCommand($cmdId));
$profile->registerCommand(new $cmdClass(), $cmdId);
@@ -210,10 +209,10 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
/* ResponseQueued */
function testResponseQueued() {
$response = new \Predis\ResponseQueued();
$response = new Predis_ResponseQueued();
$this->assertTrue($response->skipParse);
$this->assertTrue($response->queued);
$this->assertEquals(\Predis\Protocol::QUEUED, (string)$response);
$this->assertEquals(Predis_Protocol::QUEUED, (string)$response);
}
@@ -221,7 +220,7 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
function testResponseError() {
$errorMessage = 'ERROR MESSAGE';
$response = new \Predis\ResponseError($errorMessage);
$response = new Predis_ResponseError($errorMessage);
$this->assertTrue($response->skipParse);
$this->assertTrue($response->error);
@@ -233,12 +232,12 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
/* Connection */
function testConnection_StringCastReturnsIPAndPort() {
$connection = new \Predis\Connection(RC::getConnectionParameters());
$connection = new Predis_Connection(RC::getConnectionParameters());
$this->assertEquals(RC::SERVER_HOST . ':' . RC::SERVER_PORT, (string) $connection);
}
function testConnection_ConnectDisconnect() {
$connection = new \Predis\Connection(RC::getConnectionParameters());
$connection = new Predis_Connection(RC::getConnectionParameters());
$this->assertFalse($connection->isConnected());
$connection->connect();
@@ -248,8 +247,8 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
}
function testConnection_WriteAndReadCommand() {
$cmd = \Predis\RedisServerProfile::getDefault()->createCommand('ping');
$connection = new \Predis\Connection(RC::getConnectionParameters());
$cmd = Predis_RedisServerProfile::getDefault()->createCommand('ping');
$connection = new Predis_Connection(RC::getConnectionParameters());
$connection->connect();
$connection->writeCommand($cmd);
@@ -257,8 +256,8 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
}
function testConnection_WriteCommandAndCloseConnection() {
$cmd = \Predis\RedisServerProfile::getDefault()->createCommand('quit');
$connection = new \Predis\Connection(new \Predis\ConnectionParameters(
$cmd = Predis_RedisServerProfile::getDefault()->createCommand('quit');
$connection = new Predis_Connection(new Predis_ConnectionParameters(
RC::getConnectionArguments() + array('read_write_timeout' => 0.5)
));
@@ -267,14 +266,20 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$connection->writeCommand($cmd);
$connection->disconnect();
$exceptionMessage = 'Error while reading line from the server';
RC::testForCommunicationException($this, $exceptionMessage, function() use($connection, $cmd) {
$expectedMessage = 'Error while reading line from the server';
$thrownException = null;
try {
$connection->readResponse($cmd);
});
}
catch (Predis_CommunicationException $exception) {
$thrownException = $exception;
}
$this->assertInstanceOf('Predis_CommunicationException', $thrownException);
$this->assertEquals($expectedMessage, $thrownException->getMessage());
}
function testConnection_GetSocketOpensConnection() {
$connection = new \Predis\Connection(RC::getConnectionParameters());
$connection = new Predis_Connection(RC::getConnectionParameters());
$this->assertFalse($connection->isConnected());
$this->assertInternalType('resource', $connection->getSocket());
@@ -282,8 +287,8 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
}
function testConnection_LazyConnect() {
$cmd = \Predis\RedisServerProfile::getDefault()->createCommand('ping');
$connection = new \Predis\Connection(RC::getConnectionParameters());
$cmd = Predis_RedisServerProfile::getDefault()->createCommand('ping');
$connection = new Predis_Connection(RC::getConnectionParameters());
$this->assertFalse($connection->isConnected());
$connection->writeCommand($cmd);
@@ -292,42 +297,53 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
}
function testConnection_RawCommand() {
$connection = new \Predis\Connection(RC::getConnectionParameters());
$connection = new Predis_Connection(RC::getConnectionParameters());
$this->assertEquals('PONG', $connection->rawCommand("PING\r\n"));
}
function testConnection_Alias() {
$connection1 = new \Predis\Connection(RC::getConnectionParameters());
$connection1 = new Predis_Connection(RC::getConnectionParameters());
$this->assertNull($connection1->getParameters()->alias);
$args = array_merge(RC::getConnectionArguments(), array('alias' => 'servername'));
$connection2 = new \Predis\Connection(new \Predis\ConnectionParameters($args));
$connection2 = new Predis_Connection(new Predis_ConnectionParameters($args));
$this->assertEquals('servername', $connection2->getParameters()->alias);
}
function testConnection_ConnectionTimeout() {
$timeout = 3;
$args = array('host' => '1.0.0.1', 'connection_timeout' => $timeout);
$connection = new \Predis\Connection(new \Predis\ConnectionParameters($args));
$connection = new Predis_Connection(new Predis_ConnectionParameters($args));
$start = time();
RC::testForCommunicationException($this, null, function() use($connection) {
$thrownException = null;
try {
$connection->connect();
});
}
catch (Predis_CommunicationException $exception) {
$thrownException = $exception;
}
$this->assertInstanceOf('Predis_CommunicationException', $thrownException);
$this->assertEquals((float)(time() - $start), $timeout, '', 1);
}
function testConnection_ReadTimeout() {
$timeout = 1;
$args = array_merge(RC::getConnectionArguments(), array('read_write_timeout' => $timeout));
$cmdFake = \Predis\RedisServerProfile::getDefault()->createCommand('ping');
$connection = new \Predis\Connection(new \Predis\ConnectionParameters($args));
$cmdFake = Predis_RedisServerProfile::getDefault()->createCommand('ping');
$connection = new Predis_Connection(new Predis_ConnectionParameters($args));
$expectedMessage = 'Error while reading line from the server';
$start = time();
RC::testForCommunicationException($this, $expectedMessage, function() use($connection, $cmdFake) {
$thrownException = null;
try {
$connection->readResponse($cmdFake);
});
}
catch (Predis_CommunicationException $exception) {
$thrownException = $exception;
}
$this->assertInstanceOf('Predis_CommunicationException', $thrownException);
$this->assertEquals($expectedMessage, $thrownException->getMessage());
$this->assertEquals((float)(time() - $start), $timeout, '', 1);
}
@@ -335,32 +351,36 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
/* ResponseReader */
function testResponseReader_OptionIterableMultiBulkReplies() {
$connection = new \Predis\Connection(RC::getConnectionParameters());
$connection = new Predis_Connection(RC::getConnectionParameters());
$connection->getResponseReader()->setOption('iterable_multibulk', false);
$this->assertInternalType('array', $connection->rawCommand("KEYS *\r\n"));
$connection->getResponseReader()->setOption('iterable_multibulk', true);
$this->assertInstanceOf('\Iterator', $connection->rawCommand("KEYS *\r\n"));
$this->assertInstanceOf('Iterator', $connection->rawCommand("KEYS *\r\n"));
}
function testResponseReader_OptionExceptionOnError() {
$connection = new \Predis\Connection(RC::getConnectionParameters());
$connection = new Predis_Connection(RC::getConnectionParameters());
$responseReader = $connection->getResponseReader();
$connection->rawCommand("*3\r\n$3\r\nSET\r\n$3\r\nkey\r\n$5\r\nvalue\r\n");
$rawCmdUnexpected = "*3\r\n$5\r\nLPUSH\r\n$3\r\nkey\r\n$5\r\nvalue\r\n";
$responseReader->setOption('throw_on_error', false);
$errorReply = $connection->rawCommand($rawCmdUnexpected);
$this->assertInstanceOf('\Predis\ResponseError', $errorReply);
$this->assertInstanceOf('Predis_ResponseError', $errorReply);
$this->assertEquals(RC::EXCEPTION_WRONG_TYPE, $errorReply->message);
$responseReader->setOption('throw_on_error', true);
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function()
use ($connection, $rawCmdUnexpected) {
$thrownException = null;
try {
$connection->rawCommand($rawCmdUnexpected);
});
}
catch (Predis_ServerException $exception) {
$thrownException = $exception;
}
$this->assertInstanceOf('Predis_ServerException', $thrownException);
$this->assertEquals(RC::EXCEPTION_WRONG_TYPE, $thrownException->getMessage());
}
function testResponseReader_EmptyBulkResponse() {
@@ -378,13 +398,13 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$pipe = $client->pipeline();
$this->assertInstanceOf('\Predis\CommandPipeline', $pipe);
$this->assertInstanceOf('\Predis\CommandPipeline', $pipe->set('foo', 'bar'));
$this->assertInstanceOf('\Predis\CommandPipeline', $pipe->set('hoge', 'piyo'));
$this->assertInstanceOf('\Predis\CommandPipeline', $pipe->mset(array(
$this->assertInstanceOf('Predis_CommandPipeline', $pipe);
$this->assertInstanceOf('Predis_CommandPipeline', $pipe->set('foo', 'bar'));
$this->assertInstanceOf('Predis_CommandPipeline', $pipe->set('hoge', 'piyo'));
$this->assertInstanceOf('Predis_CommandPipeline', $pipe->mset(array(
'foofoo' => 'barbar', 'hogehoge' => 'piyopiyo'
)));
$this->assertInstanceOf('\Predis\CommandPipeline', $pipe->mget(array(
$this->assertInstanceOf('Predis_CommandPipeline', $pipe->mget(array(
'foo', 'hoge', 'foofoo', 'hogehoge'
)));
@@ -408,11 +428,11 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->pipeline(function($pipe) {
$pipe->ping();
$pipe->set('foo', 'bar');
$pipe->get('foo');
});
$replies = $client->pipeline(p_anon("\$pipe", "
\$pipe->ping();
\$pipe->set('foo', 'bar');
\$pipe->get('foo');
"));
$this->assertInternalType('array', $replies);
$this->assertEquals('bar', $replies[2]);
@@ -422,13 +442,21 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$client = RC::getConnection();
$client->flushdb();
RC::testForClientException($this, 'TEST', function() use($client) {
$client->pipeline(function($pipe) {
$pipe->ping();
$pipe->set('foo', 'bar');
throw new \Predis\ClientException("TEST");
});
});
$expectedMessage = 'TEST';
$thrownException = null;
try {
$client->pipeline(p_anon("\$pipe", "
\$pipe->ping();
\$pipe->set('foo', 'bar');
throw new Predis_ClientException('$expectedMessage');
"));
}
catch (Predis_ClientException $exception) {
$thrownException = $exception;
}
$this->assertInstanceOf('Predis_ClientException', $thrownException);
$this->assertEquals($expectedMessage, $thrownException->getMessage());
$this->assertFalse($client->exists('foo'));
}
@@ -437,14 +465,14 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$client->flushdb();
$client->getResponseReader()->setOption('throw_on_error', false);
$replies = $client->pipeline(function($pipe) {
$pipe->set('foo', 'bar');
$pipe->lpush('foo', 'piyo'); // LIST operation on STRING type returns an ERROR
$pipe->set('hoge', 'piyo');
});
$replies = $client->pipeline(p_anon("\$pipe", "
\$pipe->set('foo', 'bar');
\$pipe->lpush('foo', 'piyo'); // LIST operation on STRING type returns an ERROR
\$pipe->set('hoge', 'piyo');
"));
$this->assertInternalType('array', $replies);
$this->assertInstanceOf('\Predis\ResponseError', $replies[1]);
$this->assertInstanceOf('Predis_ResponseError', $replies[1]);
$this->assertTrue($client->exists('foo'));
$this->assertTrue($client->exists('hoge'));
}
@@ -474,13 +502,13 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$multi = $client->multiExec();
$this->assertInstanceOf('\Predis\MultiExecBlock', $multi);
$this->assertInstanceOf('\Predis\MultiExecBlock', $multi->set('foo', 'bar'));
$this->assertInstanceOf('\Predis\MultiExecBlock', $multi->set('hoge', 'piyo'));
$this->assertInstanceOf('\Predis\MultiExecBlock', $multi->mset(array(
$this->assertInstanceOf('Predis_MultiExecBlock', $multi);
$this->assertInstanceOf('Predis_MultiExecBlock', $multi->set('foo', 'bar'));
$this->assertInstanceOf('Predis_MultiExecBlock', $multi->set('hoge', 'piyo'));
$this->assertInstanceOf('Predis_MultiExecBlock', $multi->mset(array(
'foofoo' => 'barbar', 'hogehoge' => 'piyopiyo'
)));
$this->assertInstanceOf('\Predis\MultiExecBlock', $multi->mget(array(
$this->assertInstanceOf('Predis_MultiExecBlock', $multi->mget(array(
'foo', 'hoge', 'foofoo', 'hogehoge'
)));
@@ -504,21 +532,21 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->multiExec(function($multi) {
$multi->ping();
$multi->set('foo', 'bar');
$multi->get('foo');
});
$replies = $client->multiExec(p_anon("\$multi", "
\$multi->ping();
\$multi->set('foo', 'bar');
\$multi->get('foo');
"));
$this->assertInternalType('array', $replies);
$this->assertEquals('bar', $replies[2]);
}
/**
* @expectedException Predis\ClientException
* @expectedException Predis_ClientException
*/
function testMultiExecBlock_CannotMixFluentInterfaceAndAnonymousBlock() {
$emptyBlock = function($tx) { };
$emptyBlock = p_anon("\$tx", "");
$tx = RC::getConnection()->multiExec()->get('foo')->execute($emptyBlock);
}
@@ -526,17 +554,17 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->multiExec(function($multi) { });
$replies = $client->multiExec(p_anon("\$multi", ""));
$this->assertEquals(0, count($replies));
$options = array('cas' => true);
$replies = $client->multiExec($options, function($multi) { });
$replies = $client->multiExec($options, p_anon("\$multi", ""));
$this->assertEquals(0, count($replies));
$options = array('cas' => true);
$replies = $client->multiExec($options, function($multi) {
$multi->multi();
});
$replies = $client->multiExec($options, p_anon("\$multi", "
\$multi->multi();
"));
$this->assertEquals(0, count($replies));
}
@@ -544,13 +572,21 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$client = RC::getConnection();
$client->flushdb();
RC::testForClientException($this, 'TEST', function() use($client) {
$client->multiExec(function($multi) {
$multi->ping();
$multi->set('foo', 'bar');
throw new \Predis\ClientException("TEST");
});
});
$expectedMessage = 'TEST';
$thrownException = null;
try {
$client->multiExec(p_anon("\$multi", "
\$multi->ping();
\$multi->set('foo', 'bar');
throw new Predis_ClientException('$expectedMessage');
"));
}
catch (Predis_ClientException $exception) {
$thrownException = $exception;
}
$this->assertInstanceOf('Predis_ClientException', $thrownException);
$this->assertEquals($expectedMessage, $thrownException->getMessage());
$this->assertFalse($client->exists('foo'));
}
@@ -559,14 +595,14 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$client->flushdb();
$client->getResponseReader()->setOption('throw_on_error', false);
$replies = $client->multiExec(function($multi) {
$multi->set('foo', 'bar');
$multi->lpush('foo', 'piyo'); // LIST operation on STRING type returns an ERROR
$multi->set('hoge', 'piyo');
});
$multi = $client->multiExec();
$multi->set('foo', 'bar');
$multi->lpush('foo', 'piyo'); // LIST operation on STRING type returns an ERROR
$multi->set('hoge', 'piyo');
$replies = $multi->execute();
$this->assertInternalType('array', $replies);
$this->assertInstanceOf('\Predis\ResponseError', $replies[1]);
$this->assertInstanceOf('Predis_ResponseError', $replies[1]);
$this->assertTrue($client->exists('foo'));
$this->assertTrue($client->exists('hoge'));
}
@@ -575,11 +611,11 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->multiExec(function($multi) {
$multi->set('foo', 'bar');
$multi->discard();
$multi->set('hoge', 'piyo');
});
$multi = $client->multiExec();
$multi->set('foo', 'bar');
$multi->discard();
$multi->set('hoge', 'piyo');
$replies = $multi->execute();
$this->assertEquals(1, count($replies));
$this->assertFalse($client->exists('foo'));
@@ -590,10 +626,7 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$client = RC::getConnection();
$client->flushdb();
$replies = $client->multiExec(function($multi) {
$multi->discard();
});
$replies = $client->multiExec()->discard()->execute();
$this->assertEquals(0, count($replies));
}
@@ -602,17 +635,19 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$client2 = RC::getConnection(true);
$client1->flushdb();
RC::testForAbortedMultiExecException($this, function()
use($client1, $client2) {
$client1->multiExec(array('watch' => 'sentinel'), function($multi)
use ($client2) {
$multi->set('sentinel', 'client1');
$multi->get('sentinel');
$client2->set('sentinel', 'client2');
});
});
$thrownException = null;
try {
$multi = $client1->multiExec(array('watch' => 'sentinel'));
$multi->set('sentinel', 'client1');
$multi->get('sentinel');
$client2->set('sentinel', 'client2');
$multi->execute();
}
catch (PredisException $exception) {
$thrownException = $exception;
}
$this->assertInstanceOf('Predis_AbortedMultiExec', $thrownException);
$this->assertEquals('The current transaction has been aborted by the server', $thrownException->getMessage());
$this->assertEquals('client2', $client1->get('sentinel'));
}
@@ -623,13 +658,13 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$client->set('foo', 'bar');
$options = array('watch' => 'foo', 'cas' => true);
$replies = $client->multiExec($options, function($tx) {
$tx->watch('foobar');
$foo = $tx->get('foo');
$tx->multi();
$tx->set('foobar', $foo);
$tx->mget('foo', 'foobar');
});
$replies = $client->multiExec($options, p_anon("\$tx", "
\$tx->watch('foobar');
\$foo = \$tx->get('foo');
\$tx->multi();
\$tx->set('foobar', \$foo);
\$tx->mget('foo', 'foobar');
"));
$this->assertInternalType('array', $replies);
$this->assertEquals(array(true, array('bar', 'bar')), $replies);
@@ -646,51 +681,52 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
function testMultiExecBlock_RetryOnServerAbort() {
$client1 = RC::getConnection();
$client2 = RC::getConnection(true);
$client1->flushdb();
$retry = 3;
$attempts = 0;
RC::testForAbortedMultiExecException($this, function()
use($client1, $client2, $retry, &$attempts) {
$thrownException = null;
try {
$options = array('watch' => 'sentinel', 'retry' => $retry);
$client1->multiExec($options, function($tx)
use ($client2, &$attempts) {
$attempts++;
$tx->set('sentinel', 'client1');
$tx->get('sentinel');
$client2->set('sentinel', 'client2');
});
});
$client1->multiExec($options, p_anon("\$tx", "
\$tx->set('sentinel', 'client1');
\$tx->get('sentinel');
\$client2 = RC::getConnection(true);
\$client2->incr('attempts');
\$client2->set('sentinel', 'client2');
"));
}
catch (Predis_AbortedMultiExec $exception) {
$thrownException = $exception;
}
$this->assertInstanceOf('Predis_AbortedMultiExec', $thrownException);
$this->assertEquals('The current transaction has been aborted by the server', $thrownException->getMessage());
$this->assertEquals('client2', $client1->get('sentinel'));
$this->assertEquals($retry + 1, $attempts);
$retry = 3;
$attempts = 0;
RC::testForAbortedMultiExecException($this, function()
use($client1, $client2, $retry, &$attempts) {
$this->assertEquals($retry + 1, $client1->get('attempts'));
$client1->del('attempts', 'sentinel');
$thrownException = null;
try {
$options = array(
'watch' => 'sentinel',
'cas' => true,
'retry' => $retry
);
$client1->multiExec($options, function($tx)
use ($client2, &$attempts) {
$attempts++;
$tx->incr('attempts');
$tx->multi();
$tx->set('sentinel', 'client1');
$tx->get('sentinel');
$client2->set('sentinel', 'client2');
});
});
$client1->multiExec($options, p_anon("\$tx", "
\$tx->incr('attempts');
\$tx->multi();
\$tx->set('sentinel', 'client1');
\$tx->get('sentinel');
\$client2 = RC::getConnection(true);
\$client2->set('sentinel', 'client2');
"));
}
catch (Predis_AbortedMultiExec $exception) {
$thrownException = $exception;
}
$this->assertInstanceOf('Predis_AbortedMultiExec', $thrownException);
$this->assertEquals('The current transaction has been aborted by the server', $thrownException->getMessage());
$this->assertEquals('client2', $client1->get('sentinel'));
$this->assertEquals($retry + 1, $attempts);
$this->assertEquals($attempts, $client1->get('attempts'));
$this->assertEquals($retry + 1, $client1->get('attempts'));
}
/**
@@ -708,34 +744,32 @@ class ClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
$client->set('foo', 'bar');
$options = array('watch' => 'foo', 'cas' => true);
$replies = $client->multiExec($options, function($tx) {
$tx->watch('foobar');
$foo = $tx->get('foo');
$tx->multi();
$tx->set('foobar', $foo);
$tx->discard();
$tx->mget('foo', 'foobar');
});
$replies = $client->multiExec($options, p_anon("\$tx", "
\$tx->watch('foobar');
\$foo = \$tx->get('foo');
\$tx->multi();
\$tx->set('foobar', \$foo);
\$tx->discard();
\$tx->mget('foo', 'foobar');
"));
$this->assertInternalType('array', $replies);
$this->assertEquals(array(array('bar', null)), $replies);
$hijack = true;
$client->set('foo', 'bar');
$client2 = RC::getConnection(true);
$options = array('watch' => 'foo', 'cas' => true, 'retry' => 1);
$replies = $client->multiExec($options, function($tx)
use ($client2, &$hijack) {
$foo = $tx->get('foo');
$tx->multi();
$tx->set('foobar', $foo);
$tx->discard();
if ($hijack) {
$hijack = false;
$client2->set('foo', 'hijacked!');
$replies = $client->multiExec($options, p_anon("\$tx", "
\$client2 = RC::getConnection(true);
\$hijack = \$client2->get('foo') !== 'hijacked';
\$foo = \$tx->get('foo');
\$tx->multi();
\$tx->set('foobar', \$foo);
\$tx->discard();
if (\$hijack) {
\$client2->set('foo', 'hijacked!');
}
$tx->mget('foo', 'foobar');
});
\$tx->mget('foo', 'foobar');
"));
$this->assertInternalType('array', $replies);
$this->assertEquals(array(array('hijacked!', null)), $replies);
}
+22 -29
View File
@@ -5,6 +5,10 @@ define('I_AM_AWARE_OF_THE_DESTRUCTIVE_POWER_OF_THIS_TEST_SUITE', false);
// -------------------------------------------------------------------------- //
Predis_RedisServerProfile::registerProfile('Predis_RedisServer_v1_2', '1.2');
Predis_RedisServerProfile::registerProfile('Predis_RedisServer_v2_0', '2.0');
Predis_RedisServerProfile::registerProfile('Predis_RedisServer_v2_2', '2.2');
if (I_AM_AWARE_OF_THE_DESTRUCTIVE_POWER_OF_THIS_TEST_SUITE !== true) {
exit(
"Please set the I_AM_AWARE_OF_THE_DESTRUCTIVE_POWER_OF_THIS_TEST_SUITE " .
@@ -12,16 +16,16 @@ if (I_AM_AWARE_OF_THE_DESTRUCTIVE_POWER_OF_THIS_TEST_SUITE !== true) {
);
}
Predis\RedisServerProfile::registerProfile('\Predis\RedisServer_v1_2', '1.2');
Predis\RedisServerProfile::registerProfile('\Predis\RedisServer_v2_0', '2.0');
Predis\RedisServerProfile::registerProfile('\Predis\RedisServer_v2_2', '2.2');
if (!function_exists('array_union')) {
function array_union(Array $a, Array $b) {
return array_merge($a, array_diff($b, $a));
}
}
function p_anon($param, $function) {
return create_function($param, $function);
}
class RC {
const SERVER_HOST = '127.0.0.1';
const SERVER_PORT = 6379;
@@ -47,12 +51,12 @@ class RC {
}
public static function getConnectionParameters() {
return new Predis\ConnectionParameters(array('host' => RC::SERVER_HOST, 'port' => RC::SERVER_PORT));
return new Predis_ConnectionParameters(array('host' => RC::SERVER_HOST, 'port' => RC::SERVER_PORT));
}
private static function createConnection() {
$serverProfile = Predis\RedisServerProfile::get('2.2');
$connection = new Predis\Client(RC::getConnectionArguments(), $serverProfile);
$serverProfile = Predis_RedisServerProfile::get('2.2');
$connection = new Predis_Client(RC::getConnectionArguments(), $serverProfile);
$connection->connect();
$connection->select(RC::DEFAULT_DATABASE);
return $connection;
@@ -83,7 +87,7 @@ class RC {
$dir = __DIR__;
fwrite($handle, "<?php
require '{$dir}/../lib/Predis.php';
\$redis = Predis\Client::create('$redisUri');
\$redis = Predis_Client::create('$redisUri');
\$redis->rpush('{$op}1', 'a');
\$redis->rpush('{$op}2', 'b');
\$redis->rpush('{$op}3', 'c');
@@ -130,10 +134,10 @@ class RC {
try {
$wrapFunction($testcaseInstance);
}
catch (Predis\ServerException $exception) {
catch (Predis_ServerException $exception) {
$thrownException = $exception;
}
$testcaseInstance->assertInstanceOf('Predis\ServerException', $thrownException);
$testcaseInstance->assertInstanceOf('Predis_ServerException', $thrownException);
if (isset($expectedMessage)) {
$testcaseInstance->assertEquals($expectedMessage, $thrownException->getMessage());
}
@@ -144,10 +148,10 @@ class RC {
try {
$wrapFunction($testcaseInstance);
}
catch (Predis\ClientException $exception) {
catch (Predis_ClientException $exception) {
$thrownException = $exception;
}
$testcaseInstance->assertInstanceOf('Predis\ClientException', $thrownException);
$testcaseInstance->assertInstanceOf('Predis_ClientException', $thrownException);
if (isset($expectedMessage)) {
$testcaseInstance->assertEquals($expectedMessage, $thrownException->getMessage());
}
@@ -158,27 +162,16 @@ class RC {
try {
$wrapFunction($testcaseInstance);
}
catch (Predis\CommunicationException $exception) {
catch (Predis_CommunicationException $exception) {
$thrownException = $exception;
}
$testcaseInstance->assertInstanceOf('Predis\CommunicationException', $thrownException);
$testcaseInstance->assertInstanceOf('Predis_CommunicationException', $thrownException);
if (isset($expectedMessage)) {
$testcaseInstance->assertEquals($expectedMessage, $thrownException->getMessage());
}
}
public static function testForAbortedMultiExecException($testcaseInstance, $wrapFunction) {
$thrownException = null;
try {
$wrapFunction($testcaseInstance);
}
catch (Predis\AbortedMultiExec $exception) {
$thrownException = $exception;
}
$testcaseInstance->assertInstanceOf('Predis\AbortedMultiExec', $thrownException);
}
public static function pushTailAndReturn(Predis\Client $client, $keyName, Array $values, $wipeOut = 0) {
public static function pushTailAndReturn(Predis_Client $client, $keyName, Array $values, $wipeOut = 0) {
if ($wipeOut == true) {
$client->del($keyName);
}
@@ -188,7 +181,7 @@ class RC {
return $values;
}
public static function setAddAndReturn(Predis\Client $client, $keyName, Array $values, $wipeOut = 0) {
public static function setAddAndReturn(Predis_Client $client, $keyName, Array $values, $wipeOut = 0) {
if ($wipeOut == true) {
$client->del($keyName);
}
@@ -198,7 +191,7 @@ class RC {
return $values;
}
public static function zsetAddAndReturn(Predis\Client $client, $keyName, Array $values, $wipeOut = 0) {
public static function zsetAddAndReturn(Predis_Client $client, $keyName, Array $values, $wipeOut = 0) {
// $values: array(SCORE => VALUE, ...);
if ($wipeOut == true) {
$client->del($keyName);
@@ -218,7 +211,7 @@ class RC {
public static function getConnectionParametersArgumentsString($arguments = null) {
// TODO: must be improved
$args = $arguments ?: RC::getConnectionParametersArgumentsArray();
$args = $arguments !== null ? $arguments : RC::getConnectionParametersArgumentsArray();
$paramsString = "redis://{$args['host']}:{$args['port']}/";
$paramsString .= "?connection_timeout={$args['connection_timeout']}&read_write_timeout={$args['read_write_timeout']}";
$paramsString .= "&database={$args['database']}&password={$args['password']}&alias={$args['alias']}";
+316 -328
View File
File diff suppressed because it is too large Load Diff
+4 -1
View File
@@ -1,6 +1,9 @@
<?php
if (!defined(__DIR__)) {
define('__DIR__', dirname(__FILE__));
}
require_once(__DIR__ . '/../lib/Predis.php');
require_once(__DIR__ . '/../lib/Predis_Compatibility.php');
require_once(__DIR__ . '/../test/PredisShared.php');