Compare commits

...

12 Commits

Author SHA1 Message Date
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
10 changed files with 1159 additions and 688 deletions
+14
View File
@@ -0,0 +1,14 @@
v0.5.1
* RPOPLPUSH has been changed from bulk command to inline command in Redis
1.2.1, so ListPopLastPushHead now extends InlineCommand. The old RPOPLPUSH
behavior is still available via the ListPopLastPushHeadBulk class so that
you can override the server profile if you need the old (and uncorrect)
behaviour when connecting to a Redis 1.2.0 instance.
* Added missing support for BGREWRITEAOF for Redis >= 1.2.0
* Implemented a factory method for the RedisServerProfile class to ease the
creation of new server profile instances based on a version string.
v0.5.0
* First versioned release of Predis
+3 -3
View File
@@ -1,5 +1,5 @@
Copyright (c) 2009 Daniele Alessandri
Copyright (c) 2009-2010 Daniele Alessandri
qq
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
@@ -19,4 +19,4 @@ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
OTHER DEALINGS IN THE SOFTWARE.
+31 -22
View File
@@ -5,9 +5,13 @@
Predis is a flexible and feature-complete PHP client library for the Redis key-value
database.
Predis is currently a work-in-progress and it targets PHP >= 5.3, though it is highly
due to be backported to PHP >= 5.2.6 as soon as the public API and the internal design
on the main branch will be considered stable enough.
Predis is currently a work-in-progress and it comes in two flavors:
- the mainline client library, which targets PHP 5.3.x and leverages a lot of the
features introduced in this new version of the PHP interpreter.
- a backport to PHP 5.2.x for those who can not upgrade their environment yet
(it admittedly has a lower priority compared to the mainline library, although we
try to keep the two versions aligned as much as possible).
Please refer to the TODO file to see which issues are still pending and what is due
to be implemented soon in Predis.
@@ -23,12 +27,15 @@ to be implemented soon in Predis.
## Quick examples ##
See the [official wiki](http://wiki.github.com/nrk/predis) of the project for a more
complete coverage of all the features available in Predis.
### Connecting to a local instance of Redis ###
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');
@@ -38,13 +45,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('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) ##
@@ -54,17 +61,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 = Predis\Client::create(
$redis = Predis_Client::create(
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 ###
@@ -76,12 +83,12 @@ 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\InlineCommand {
class BrandNewRedisCommand extends Predis_InlineCommand {
public function getCommandId() { return 'NEWCMD'; }
}
$redis = new Predis\Client();
$redis->registerCommand('BrandNewRedisCommand', 'newcmd');
$redis = new Predis_Client();
$redis->getProfile()->registerCommand('BrandNewRedisCommand', 'newcmd');
$redis->newcmd();
@@ -105,13 +112,15 @@ variable set to E_ALL.
## Dependencies ##
- PHP >= 5.3
- PHP >= 5.3.0 (for the mainline client library)
- PHP >= 5.2.6 (for the backported client library)
- PHPUnit (needed to run the test suite)
## Links ##
### Project ###
- [Source code](http://github.com/nrk/predis/)
- [Wiki](http://wiki.github.com/nrk/predis/)
- [Issue tracker](http://github.com/nrk/predis/issues)
### Related ###
+2 -17
View File
@@ -1,21 +1,6 @@
* Authentication and database selection should be handled transparently by
the client.
* The current behaviour of sending, by default, unshardable commands to the
first registered connection of a ConnectionCluster instance needs to be
verified.
* Documentation! The README is obviously not enought to show how to use
Predis as it does not cover all of its features.
* The included test suite covers almost all the Redis server commands, but a
full battery of tests targeting specific functions of this library is still
missing.
* Support for pipelining commands on one or more connections works, but it
could be optimized for better performances with a cache of computed commands
hashes, but the memory impact still needs to be evalued.
* Add the possibility of flushing the command buffer from inside of a pipeline.
* Switching to/from instances of Connection and ConnectionCluster should be
transparent to the user. Using a ConnectionCluster instance when there is
only one active connection has an unnecessary overhead.
+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 = Predis\Client::create($configurations);
$redis = Predis_Client::create($configurations);
$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);
+1 -1
View File
@@ -11,7 +11,7 @@ $mkv = array(
'usr:0003' => 'Third user'
);
$redis = Predis\Client::create($configurations);
$redis = Predis_Client::create($configurations);
$redis->mset($mkv);
$retval = $redis->mget(array_keys($mkv));
+1 -1
View File
@@ -3,7 +3,7 @@ require_once 'SharedConfigurations.php';
// simple set and get scenario
$redis = Predis\Client::create($configurations);
$redis = Predis_Client::create($configurations);
$redis->set('library', 'predis');
$retval = $redis->get('library');
+792 -462
View File
File diff suppressed because it is too large Load Diff
+28 -6
View File
@@ -11,6 +11,10 @@ if (!function_exists('array_union')) {
}
}
function p_anon($param, $function) {
return create_function($param, $function);
}
class RC {
const SERVER_HOST = '127.0.0.1';
const SERVER_PORT = 6379;
@@ -21,11 +25,13 @@ class RC {
const EXCEPTION_NO_SUCH_KEY = 'no such key';
const EXCEPTION_OUT_OF_RANGE = 'index out of range';
const EXCEPTION_INVALID_DB_IDX = 'invalid DB index';
const EXCEPTION_EXEC_NO_MULTI = 'EXEC without MULTI';
private static $_connection;
private static function createConnection() {
$connection = new Predis\Client(RC::SERVER_HOST, RC::SERVER_PORT);
$serverProfile = Predis_RedisServerProfile::get('dev');
$connection = new Predis_Client(array('host' => RC::SERVER_HOST, 'port' => RC::SERVER_PORT), $serverProfile);
$connection->connect();
$connection->selectDatabase(RC::DEFAULT_DATABASE);
return $connection;
@@ -45,6 +51,22 @@ class RC {
}
}
public static function helperForBlockingPops($op) {
// TODO: I admit that this helper is kinda lame and it does not run
// in a separate process to properly test BLPOP/BRPOP
$redisUri = sprintf('redis://%s:%d/?database=%d', RC::SERVER_HOST, RC::SERVER_PORT, RC::DEFAULT_DATABASE);
$handle = popen('php', 'w');
fwrite($handle, "<?php
require '../lib/Predis.php';
\$redis = Predis_Client::create('$redisUri');
\$redis->rpush('{$op}1', 'a');
\$redis->rpush('{$op}2', 'b');
\$redis->rpush('{$op}3', 'c');
\$redis->rpush('{$op}1', 'd');
?>");
pclose($handle);
}
public static function getArrayOfNumbers() {
return array(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
}
@@ -83,14 +105,14 @@ class RC {
try {
$wrapFunction($testcaseInstance);
}
catch (Predis\ServerException $exception) {
catch (Predis_ServerException $exception) {
$thrownException = $exception;
}
$testcaseInstance->assertType('Predis\ServerException', $thrownException);
$testcaseInstance->assertType('Predis_ServerException', $thrownException);
$testcaseInstance->assertEquals($expectedMessage, $thrownException->getMessage());
}
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->delete($keyName);
}
@@ -100,7 +122,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->delete($keyName);
}
@@ -110,7 +132,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->delete($keyName);
+277 -166
View File
@@ -45,6 +45,25 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertFalse($this->redis->isConnected());
}
function testMultiExec() {
// NOTE: due to a limitation in the current implementation of Predis_Client,
// the replies returned by Predis_Command_Exec are not parsed by their
// respective Predis_Command::parseResponse methods. If you need that
// kind of behaviour, you should use an instance of Predis_MultiExecBlock.
$this->assertTrue($this->redis->multi());
$this->assertType('Predis_ResponseQueued', $this->redis->ping());
$this->assertType('Predis_ResponseQueued', $this->redis->echo('hello'));
$this->assertType('Predis_ResponseQueued', $this->redis->echo('redis'));
$this->assertEquals(array('PONG', 'hello', 'redis'), $this->redis->exec());
$this->assertTrue($this->redis->multi());
$this->assertEquals(array(), $this->redis->exec());
// should throw an exception when trying to EXEC without having previously issued MULTI
RC::testForServerException($this, RC::EXCEPTION_EXEC_NO_MULTI, p_anon("\$test", "
\$test->redis->exec();
"));
}
/* commands operating on string values */
@@ -60,10 +79,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertNull($this->redis->get('fooDoesNotExist'));
// should throw an exception when trying to do a GET on non-string types
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->pushTail('metavars', 'foo');
$test->redis->get('metavars');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->pushTail('metavars', 'foo');
\$test->redis->get('metavars');
"));
}
function testExists() {
@@ -211,9 +230,9 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertEquals('bar', $this->redis->get('foofoo'));
// should throw an excepion then trying to rename non-existing keys
RC::testForServerException($this, RC::EXCEPTION_NO_SUCH_KEY, function($test) {
$test->redis->rename('hoge', 'hogehoge');
});
RC::testForServerException($this, RC::EXCEPTION_NO_SUCH_KEY, p_anon("\$test", "
\$test->redis->rename('hoge', 'hogehoge');
"));
}
function testRenamePreserve() {
@@ -227,9 +246,9 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertTrue($this->redis->exists('hoge'));
// should throw an excepion then trying to rename non-existing keys
RC::testForServerException($this, RC::EXCEPTION_NO_SUCH_KEY, function($test) {
$test->redis->renamePreserve('fuga', 'baz');
});
RC::testForServerException($this, RC::EXCEPTION_NO_SUCH_KEY, p_anon("\$test", "
\$test->redis->renamePreserve('fuga', 'baz');
"));
}
function testExpirationAndTTL() {
@@ -272,11 +291,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertTrue($this->redis->pushTail('metavars', 'hoge'));
// should throw an exception when trying to do a RPUSH on non-list types
// should throw an exception when trying to do a LPUSH on non-list types
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->pushTail('foo', 'bar');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->pushTail('foo', 'bar');
"));
}
function testPushHead() {
@@ -285,10 +303,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertTrue($this->redis->pushHead('metavars', 'hoge'));
// should throw an exception when trying to do a LPUSH on non-list types
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->pushHead('foo', 'bar');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->pushHead('foo', 'bar');
"));
}
function testListLength() {
@@ -299,10 +317,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertEquals(0, $this->redis->listLength('doesnotexist'));
// should throw an exception when trying to do a LLEN on non-list types
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->listLength('foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->listLength('foo');
"));
}
function testListRange() {
@@ -348,10 +366,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertNull($this->redis->listRange('keyDoesNotExist', 0, 1));
// should throw an exception when trying to do a LRANGE on non-list types
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->listRange('foo', 0, -1);
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->listRange('foo', 0, -1);
"));
}
function testListTrim() {
@@ -390,10 +408,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->redis->listRange('numbers', 0, -1)
);
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->listTrim('foo', 0, 1);
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->listTrim('foo', 0, 1);
"));
}
function testListIndex() {
@@ -409,10 +427,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertEquals(7, $this->redis->listIndex('numbers', -3));
$this->assertNull($this->redis->listIndex('numbers', -100));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->listIndex('foo', 0);
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->listIndex('foo', 0);
"));
}
function testListSet() {
@@ -421,14 +439,14 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertTrue($this->redis->listSet('numbers', 5, -5));
$this->assertEquals(-5, $this->redis->listIndex('numbers', 5));
RC::testForServerException($this, RC::EXCEPTION_OUT_OF_RANGE, function($test) {
$test->redis->listSet('numbers', 99, 99);
});
RC::testForServerException($this, RC::EXCEPTION_OUT_OF_RANGE, p_anon("\$test", "
\$test->redis->listSet('numbers', 99, 99);
"));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->listSet('foo', 0, 0);
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->listSet('foo', 0, 0);
"));
}
function testListRemove() {
@@ -452,10 +470,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertEquals(0, $this->redis->listRemove('listDoesNotExist', 2, '_'));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->listRemove('foo', 0, 0);
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->listRemove('foo', 0, 0);
"));
}
function testListPopFirst() {
@@ -475,10 +493,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertNull($this->redis->popFirst('listDoesNotExist'));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->popFirst('foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->popFirst('foo');
"));
}
function testListPopLast() {
@@ -498,10 +516,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertNull($this->redis->popLast('listDoesNotExist'));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->popLast('foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->popLast('foo');
"));
}
@@ -524,15 +542,69 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertEquals(null, $this->redis->listPopLastPushHead('listDoesNotExist1', 'listDoesNotExist2'));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->listPopLastPushHead('foo', 'hoge');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->listPopLastPushHead('foo', 'hoge');
"));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->listPopLastPushHead('temporary', 'foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->listPopLastPushHead('temporary', 'foo');
"));
}
function testListBlockingPopFirst() {
// TODO: this test does not cover all the aspects of BLPOP/BRPOP as it
// does not run with a concurrent client pushing items on lists.
RC::helperForBlockingPops('blpop');
// BLPOP on one key
$start = time();
$item = $this->redis->blpop('blpop3', 5);
$this->assertEquals((float)(time() - $start), 0, '', 1);
$this->assertEquals($item, array('blpop3', 'c'));
// BLPOP on more than one key
$poppedItems = array();
while ($item = $this->redis->blpop('blpop1', 'blpop2', 1)) {
$poppedItems[] = $item;
}
$this->assertEquals(
array(array('blpop1', 'a'), array('blpop1', 'd'), array('blpop2', 'b')),
$poppedItems
);
// check if BLPOP timeouts as expected on empty lists
$start = time();
$this->redis->blpop('blpop4', 2);
$this->assertEquals((float)(time() - $start), 2, '', 1);
}
function testListBlockingPopLast() {
// TODO: this test does not cover all the aspects of BLPOP/BRPOP as it
// does not run with a concurrent client pushing items on lists.
RC::helperForBlockingPops('brpop');
// BRPOP on one key
$start = time();
$item = $this->redis->brpop('brpop3', 5);
$this->assertEquals((float)(time() - $start), 0, '', 1);
$this->assertEquals($item, array('brpop3', 'c'));
// BRPOP on more than one key
$poppedItems = array();
while ($item = $this->redis->brpop('brpop1', 'brpop2', 1)) {
$poppedItems[] = $item;
}
$this->assertEquals(
array(array('brpop1', 'd'), array('brpop1', 'a'), array('brpop2', 'b')),
$poppedItems
);
// check if BRPOP timeouts as expected on empty lists
$start = time();
$this->redis->brpop('brpop4', 2);
$this->assertEquals((float)(time() - $start), 2, '', 1);
}
@@ -543,10 +615,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertTrue($this->redis->setAdd('set', 1));
$this->assertFalse($this->redis->setAdd('set', 0));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->setAdd('foo', 0);
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->setAdd('foo', 0);
"));
}
function testSetRemove() {
@@ -556,10 +628,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertTrue($this->redis->setRemove('set', 4));
$this->assertFalse($this->redis->setRemove('set', 10));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->setRemove('foo', 0);
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->setRemove('foo', 0);
"));
}
function testSetPop() {
@@ -569,10 +641,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertNull($this->redis->setPop('setDoesNotExist'));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->setPop('foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->setPop('foo');
"));
}
function testSetMove() {
@@ -588,12 +660,12 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
// wrong type
$this->redis->set('foo', 'bar');
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setMove('foo', 'setB', 5);
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setMove('setA', 'foo', 5);
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setMove('foo', 'setB', 5);
"));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setMove('setA', 'foo', 5);
"));
}
function testSetCardinality() {
@@ -610,10 +682,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertEquals(0, $this->redis->setCardinality('setDoesNotExist'));
// wrong type
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->setCardinality('foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->setCardinality('foo');
"));
}
function testSetIsMember() {
@@ -625,10 +697,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertFalse($this->redis->setIsMember('setDoesNotExist', 0));
// wrong type
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->setIsMember('foo', 0);
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->setIsMember('foo', 0);
"));
}
function testSetMembers() {
@@ -640,9 +712,9 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
// wrong type
$this->redis->set('foo', 'bar');
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setMembers('foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setMembers('foo');
"));
}
function testSetIntersection() {
@@ -664,12 +736,12 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
// wrong type
$this->redis->set('foo', 'bar');
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setIntersection('foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setIntersection('setA', 'foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setIntersection('foo');
"));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setIntersection('setA', 'foo');
"));
}
function testSetIntersectionStore() {
@@ -699,9 +771,9 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
// wrong type
$this->redis->set('foo', 'bar');
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setIntersectionStore('setA', 'foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setIntersectionStore('setA', 'foo');
"));
}
function testSetUnion() {
@@ -725,12 +797,12 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
// wrong type
$this->redis->set('foo', 'bar');
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setUnion('foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setUnion('setA', 'foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setUnion('foo');
"));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setUnion('setA', 'foo');
"));
}
function testSetUnionStore() {
@@ -762,9 +834,9 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
// wrong type
$this->redis->set('foo', 'bar');
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setUnionStore('setA', 'foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setUnionStore('setA', 'foo');
"));
}
function testSetDifference() {
@@ -788,12 +860,12 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
// wrong type
$this->redis->set('foo', 'bar');
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setDifference('foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setDifference('setA', 'foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setDifference('foo');
"));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setDifference('setA', 'foo');
"));
}
function testSetDifferenceStore() {
@@ -825,9 +897,9 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
// wrong type
$this->redis->set('foo', 'bar');
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setDifferenceStore('setA', 'foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setDifferenceStore('setA', 'foo');
"));
}
function testRandomMember() {
@@ -839,9 +911,9 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
// wrong type
$this->redis->set('foo', 'bar');
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->setRandomMember('foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->setRandomMember('foo');
"));
}
@@ -860,10 +932,30 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertFalse($this->redis->zsetAdd('zset', 2, 'b'));
$this->assertFalse($this->redis->zsetAdd('zset', -2, 'b'));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->zsetAdd('foo', 0, 'a');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->zsetAdd('foo', 0, 'a');
"));
}
function testZsetIncrementBy() {
$this->assertEquals(1, $this->redis->zsetIncrementBy('zsetDoesNotExist', 1, 'foo'));
$this->assertEquals('zset', $this->redis->type('zsetDoesNotExist'));
RC::zsetAddAndReturn($this->redis, 'zset', RC::getZSetArray());
$this->assertEquals(-5, $this->redis->zsetIncrementBy('zset', 5, 'a'));
$this->assertEquals(1, $this->redis->zsetIncrementBy('zset', 1, 'b'));
$this->assertEquals(10, $this->redis->zsetIncrementBy('zset', 0, 'c'));
$this->assertEquals(0, $this->redis->zsetIncrementBy('zset', -20, 'd'));
$this->assertEquals(2, $this->redis->zsetIncrementBy('zset', 2, 'd'));
$this->assertEquals(-10, $this->redis->zsetIncrementBy('zset', -30, 'e'));
$this->assertEquals(1, $this->redis->zsetIncrementBy('zset', 1, 'x'));
// wrong type
$this->redis->set('foo', 'bar');
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->zsetIncrementBy('foo', 1, 'a');
"));
}
function testZsetRemove() {
@@ -872,10 +964,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertTrue($this->redis->zsetRemove('zset', 'a'));
$this->assertFalse($this->redis->zsetRemove('zset', 'x'));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->zsetRemove('foo', 'bar');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->zsetRemove('foo', 'bar');
"));
}
function testZsetRange() {
@@ -921,10 +1013,20 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->redis->zsetRange('zset', -100, 100)
);
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->zsetRange('foo', 0, -1);
});
$this->assertEquals(
array_values(array_keys($zset)),
$this->redis->zsetRange('zset', -100, 100)
);
$this->assertEquals(
array(array('a', -10), array('b', 0), array('c', 10)),
$this->redis->zsetRange('zset', 0, 2, 'withscores')
);
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->zsetRange('foo', 0, -1);
"));
}
function testZsetReverseRange() {
@@ -970,10 +1072,15 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->redis->zsetReverseRange('zset', -100, 100)
);
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->zsetReverseRange('foo', 0, -1);
});
$this->assertEquals(
array(array('f', 30), array('e', 20), array('d', 20)),
$this->redis->zsetReverseRange('zset', 0, 2, 'withscores')
);
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->zsetReverseRange('foo', 0, -1);
"));
}
function testZsetRangeByScore() {
@@ -999,10 +1106,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->redis->zsetRangeByScore('zset', 30, 0)
);
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->zsetRangeByScore('foo', 0, 0);
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->zsetRangeByScore('foo', 0, 0);
"));
}
function testZsetCardinality() {
@@ -1021,10 +1128,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
// non-existing zset
$this->assertEquals(0, $this->redis->zsetCardinality('zsetDoesNotExist'));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->zsetCardinality('foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->zsetCardinality('foo');
"));
}
function testZsetScore() {
@@ -1037,10 +1144,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertNull($this->redis->zsetScore('zset', 'x'));
$this->assertNull($this->redis->zsetScore('zsetDoesNotExist', 'a'));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->zsetScore('foo', 'bar');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->zsetScore('foo', 'bar');
"));
}
function testZsetRemoveRangeByScore() {
@@ -1065,10 +1172,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertEquals(0, $this->redis->zsetRemoveRangeByScore('zsetDoesNotExist', 0, 100));
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->zsetRemoveRangeByScore('foo', 0, 0);
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->zsetRemoveRangeByScore('foo', 0, 0);
"));
}
@@ -1078,13 +1185,13 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertTrue($this->redis->selectDatabase(0));
$this->assertTrue($this->redis->selectDatabase(RC::DEFAULT_DATABASE));
RC::testForServerException($this, RC::EXCEPTION_INVALID_DB_IDX, function($test) {
$test->redis->selectDatabase(32);
});
RC::testForServerException($this, RC::EXCEPTION_INVALID_DB_IDX, p_anon("\$test", "
\$test->redis->selectDatabase(32);
"));
RC::testForServerException($this, RC::EXCEPTION_INVALID_DB_IDX, function($test) {
$test->redis->selectDatabase(-1);
});
RC::testForServerException($this, RC::EXCEPTION_INVALID_DB_IDX, p_anon("\$test", "
\$test->redis->selectDatabase(-1);
"));
}
function testMove() {
@@ -1102,9 +1209,9 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->redis->set('hoge', 'piyo');
// TODO: shouldn't Redis send an EXCEPTION_INVALID_DB_IDX instead of EXCEPTION_OUT_OF_RANGE?
RC::testForServerException($this, RC::EXCEPTION_OUT_OF_RANGE, function($test) {
$test->redis->move('hoge', 32);
});
RC::testForServerException($this, RC::EXCEPTION_OUT_OF_RANGE, p_anon("\$test", "
\$test->redis->move('hoge', 32);
"));
}
function testFlushDatabase() {
@@ -1182,10 +1289,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertEquals(array(1, 2, 3, 10, 30, 100), $this->redis->listRange('ordered', 0, -1));
// wront type
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function($test) {
$test->redis->set('foo', 'bar');
$test->redis->sort('foo');
});
RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, p_anon("\$test", "
\$test->redis->set('foo', 'bar');
\$test->redis->sort('foo');
"));
}
/* remote server control commands */
@@ -1229,6 +1336,10 @@ class RedisCommandTestSuite extends PHPUnit_Framework_TestCase {
$this->assertTrue($this->redis->backgroundSave());
}
function testBackgroundRewriteAppendOnlyFile() {
$this->assertTrue($this->redis->backgroundRewriteAppendOnlyFile());
}
function testLastSave() {
$this->assertGreaterThan(0, $this->redis->lastSave());
}