Compare commits

..

9 Commits

Author SHA1 Message Date
Till Krüss ff59f74581 bump version 2022-10-11 09:52:29 -07:00
Mehmet Tolga Avcioglu 1a0eb7ee85 sentinel default to no password when replica authentication is used (#807)
* set default nopass if password is not provided

* remove debug output

* added tests for noauth sentinel

* Update SentinelReplication.php

Co-authored-by: Mehmet Tolga Avcioglu <mehmet.avcioglu@pusula.net.tr>
Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
2022-10-06 08:14:47 -07:00
Tobias Bengtsson bb6c1a7b6d Add partial support for Stream commands (#804)
Adds support for the following commands not related to groups/consumers:
XADD, XDEL, XLEN, XRANGE, XREVRANGE, XTRIM.
2022-09-27 09:39:17 -07:00
streamingsystems 42c33a406f Check if socket is resource before reading (#802) 2022-09-18 15:01:02 -07:00
Stefano Borghi 7ad74217c2 check resource before writing, w/ test (#800) 2022-09-16 17:03:13 -07:00
Alexandru Pătrănescu 72d7675563 improve PHP 8.2 support (#797)
* use static::class . '::<method>' instead of 'static::method'

* extract concatenation so it can be improved easier at a later point

one improvement at some point could be to replace static::class . '::<method>' with static::<method>(...) in PHP 8.1+

Co-authored-by: Alexandru Patranescu <alexandru.patranescu@payu.com>
2022-09-08 11:25:37 -07:00
Till Krüss 8b5fa92856 mention php version [no ci] 2022-09-06 07:34:14 -07:00
Till Krüss 076a62e3d3 bump version to 2.0.2 2022-09-06 07:32:44 -07:00
Dries Vints 85dc1752b7 PHP 8.2 Support (#796) 2022-09-06 07:13:46 -07:00
22 changed files with 1498 additions and 136 deletions
+1 -1
View File
@@ -20,7 +20,7 @@ jobs:
strategy:
fail-fast: false
matrix:
php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1']
php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2']
redis-versions: ['3', '4', '5', '6', '7']
steps:
+11
View File
@@ -1,5 +1,16 @@
## Changelog
## v2.0.3 (2022-10-11)
- Improved PHP 8.2 support
- Call `is_resource()` before reading/writing
- Added partial support for Redis Stream commands
- Fixed Sentinel authentication issue
## v2.0.2 (2022-09-06)
- Fixed PHP 8.2 deprecation notice: Use of "static" in callables
## v2.0.1 (2022-09-04)
- Added retry interval to `RedisCluster` with a default of `10ms`
+1 -1
View File
@@ -1 +1 @@
2.0.1
2.0.3
+1 -1
View File
@@ -40,7 +40,7 @@ use Predis\Transaction\MultiExec as MultiExecTransaction;
*/
class Client implements ClientInterface, \IteratorAggregate
{
const VERSION = '2.0.1';
const VERSION = '2.0.3';
/** @var OptionsInterface */
private $options;
+6
View File
@@ -116,6 +116,12 @@ use Predis\Response\Status;
* @method string[] sunion(array|string $keys)
* @method int sunionstore(string $destination, array|string $keys)
* @method int touch(string[]|string $keyOrKeys, string ...$keys = null)
* @method string xadd(string $key, array $dictionary, string $id = '*', array $options = null)
* @method int xdel(string $key, string ...$id)
* @method int xlen(string $key)
* @method array xrevrange(string $key, string $end, string $start, ?int $count = null)
* @method array xrange(string $key, string $start, string $end, ?int $count = null)
* @method string xtrim(string $key, array|string $strategy, string $threshold, array $options = null)
* @method int zadd(string $key, array $membersAndScoresDictionary)
* @method int zcard(string $key)
* @method string zcount(string $key, int|string $min, int|string $max)
+143 -131
View File
@@ -31,142 +31,154 @@ class KeyPrefixProcessor implements ProcessorInterface
public function __construct($prefix)
{
$this->prefix = $prefix;
$this->commands = array(
$prefixFirst = static::class . '::first';
$prefixAll = static::class . '::all';
$prefixInterleaved = static::class . '::interleaved';
$prefixSkipFirst = static::class . '::skipFirst';
$prefixSkipLast = static::class . '::skipLast';
$prefixSort = static::class . '::sort';
$prefixEvalKeys = static::class . '::evalKeys';
$prefixZsetStore = static::class . '::zsetStore';
$prefixMigrate = static::class . '::migrate';
$prefixGeoradius = static::class . '::georadius';
$this->commands = [
/* ---------------- Redis 1.2 ---------------- */
'EXISTS' => 'static::all',
'DEL' => 'static::all',
'TYPE' => 'static::first',
'KEYS' => 'static::first',
'RENAME' => 'static::all',
'RENAMENX' => 'static::all',
'EXPIRE' => 'static::first',
'EXPIREAT' => 'static::first',
'TTL' => 'static::first',
'MOVE' => 'static::first',
'SORT' => 'static::sort',
'DUMP' => 'static::first',
'RESTORE' => 'static::first',
'SET' => 'static::first',
'SETNX' => 'static::first',
'MSET' => 'static::interleaved',
'MSETNX' => 'static::interleaved',
'GET' => 'static::first',
'MGET' => 'static::all',
'GETSET' => 'static::first',
'INCR' => 'static::first',
'INCRBY' => 'static::first',
'DECR' => 'static::first',
'DECRBY' => 'static::first',
'RPUSH' => 'static::first',
'LPUSH' => 'static::first',
'LLEN' => 'static::first',
'LRANGE' => 'static::first',
'LTRIM' => 'static::first',
'LINDEX' => 'static::first',
'LSET' => 'static::first',
'LREM' => 'static::first',
'LPOP' => 'static::first',
'RPOP' => 'static::first',
'RPOPLPUSH' => 'static::all',
'SADD' => 'static::first',
'SREM' => 'static::first',
'SPOP' => 'static::first',
'SMOVE' => 'static::skipLast',
'SCARD' => 'static::first',
'SISMEMBER' => 'static::first',
'SINTER' => 'static::all',
'SINTERSTORE' => 'static::all',
'SUNION' => 'static::all',
'SUNIONSTORE' => 'static::all',
'SDIFF' => 'static::all',
'SDIFFSTORE' => 'static::all',
'SMEMBERS' => 'static::first',
'SRANDMEMBER' => 'static::first',
'ZADD' => 'static::first',
'ZINCRBY' => 'static::first',
'ZREM' => 'static::first',
'ZRANGE' => 'static::first',
'ZREVRANGE' => 'static::first',
'ZRANGEBYSCORE' => 'static::first',
'ZCARD' => 'static::first',
'ZSCORE' => 'static::first',
'ZREMRANGEBYSCORE' => 'static::first',
'EXISTS' => $prefixAll,
'DEL' => $prefixAll,
'TYPE' => $prefixFirst,
'KEYS' => $prefixFirst,
'RENAME' => $prefixAll,
'RENAMENX' => $prefixAll,
'EXPIRE' => $prefixFirst,
'EXPIREAT' => $prefixFirst,
'TTL' => $prefixFirst,
'MOVE' => $prefixFirst,
'SORT' => $prefixSort,
'DUMP' => $prefixFirst,
'RESTORE' => $prefixFirst,
'SET' => $prefixFirst,
'SETNX' => $prefixFirst,
'MSET' => $prefixInterleaved,
'MSETNX' => $prefixInterleaved,
'GET' => $prefixFirst,
'MGET' => $prefixAll,
'GETSET' => $prefixFirst,
'INCR' => $prefixFirst,
'INCRBY' => $prefixFirst,
'DECR' => $prefixFirst,
'DECRBY' => $prefixFirst,
'RPUSH' => $prefixFirst,
'LPUSH' => $prefixFirst,
'LLEN' => $prefixFirst,
'LRANGE' => $prefixFirst,
'LTRIM' => $prefixFirst,
'LINDEX' => $prefixFirst,
'LSET' => $prefixFirst,
'LREM' => $prefixFirst,
'LPOP' => $prefixFirst,
'RPOP' => $prefixFirst,
'RPOPLPUSH' => $prefixAll,
'SADD' => $prefixFirst,
'SREM' => $prefixFirst,
'SPOP' => $prefixFirst,
'SMOVE' => $prefixSkipLast,
'SCARD' => $prefixFirst,
'SISMEMBER' => $prefixFirst,
'SINTER' => $prefixAll,
'SINTERSTORE' => $prefixAll,
'SUNION' => $prefixAll,
'SUNIONSTORE' => $prefixAll,
'SDIFF' => $prefixAll,
'SDIFFSTORE' => $prefixAll,
'SMEMBERS' => $prefixFirst,
'SRANDMEMBER' => $prefixFirst,
'ZADD' => $prefixFirst,
'ZINCRBY' => $prefixFirst,
'ZREM' => $prefixFirst,
'ZRANGE' => $prefixFirst,
'ZREVRANGE' => $prefixFirst,
'ZRANGEBYSCORE' => $prefixFirst,
'ZCARD' => $prefixFirst,
'ZSCORE' => $prefixFirst,
'ZREMRANGEBYSCORE' => $prefixFirst,
/* ---------------- Redis 2.0 ---------------- */
'SETEX' => 'static::first',
'APPEND' => 'static::first',
'SUBSTR' => 'static::first',
'BLPOP' => 'static::skipLast',
'BRPOP' => 'static::skipLast',
'ZUNIONSTORE' => 'static::zsetStore',
'ZINTERSTORE' => 'static::zsetStore',
'ZCOUNT' => 'static::first',
'ZRANK' => 'static::first',
'ZREVRANK' => 'static::first',
'ZREMRANGEBYRANK' => 'static::first',
'HSET' => 'static::first',
'HSETNX' => 'static::first',
'HMSET' => 'static::first',
'HINCRBY' => 'static::first',
'HGET' => 'static::first',
'HMGET' => 'static::first',
'HDEL' => 'static::first',
'HEXISTS' => 'static::first',
'HLEN' => 'static::first',
'HKEYS' => 'static::first',
'HVALS' => 'static::first',
'HGETALL' => 'static::first',
'SUBSCRIBE' => 'static::all',
'UNSUBSCRIBE' => 'static::all',
'PSUBSCRIBE' => 'static::all',
'PUNSUBSCRIBE' => 'static::all',
'PUBLISH' => 'static::first',
'SETEX' => $prefixFirst,
'APPEND' => $prefixFirst,
'SUBSTR' => $prefixFirst,
'BLPOP' => $prefixSkipLast,
'BRPOP' => $prefixSkipLast,
'ZUNIONSTORE' => $prefixZsetStore,
'ZINTERSTORE' => $prefixZsetStore,
'ZCOUNT' => $prefixFirst,
'ZRANK' => $prefixFirst,
'ZREVRANK' => $prefixFirst,
'ZREMRANGEBYRANK' => $prefixFirst,
'HSET' => $prefixFirst,
'HSETNX' => $prefixFirst,
'HMSET' => $prefixFirst,
'HINCRBY' => $prefixFirst,
'HGET' => $prefixFirst,
'HMGET' => $prefixFirst,
'HDEL' => $prefixFirst,
'HEXISTS' => $prefixFirst,
'HLEN' => $prefixFirst,
'HKEYS' => $prefixFirst,
'HVALS' => $prefixFirst,
'HGETALL' => $prefixFirst,
'SUBSCRIBE' => $prefixAll,
'UNSUBSCRIBE' => $prefixAll,
'PSUBSCRIBE' => $prefixAll,
'PUNSUBSCRIBE' => $prefixAll,
'PUBLISH' => $prefixFirst,
/* ---------------- Redis 2.2 ---------------- */
'PERSIST' => 'static::first',
'STRLEN' => 'static::first',
'SETRANGE' => 'static::first',
'GETRANGE' => 'static::first',
'SETBIT' => 'static::first',
'GETBIT' => 'static::first',
'RPUSHX' => 'static::first',
'LPUSHX' => 'static::first',
'LINSERT' => 'static::first',
'BRPOPLPUSH' => 'static::skipLast',
'ZREVRANGEBYSCORE' => 'static::first',
'WATCH' => 'static::all',
'PERSIST' => $prefixFirst,
'STRLEN' => $prefixFirst,
'SETRANGE' => $prefixFirst,
'GETRANGE' => $prefixFirst,
'SETBIT' => $prefixFirst,
'GETBIT' => $prefixFirst,
'RPUSHX' => $prefixFirst,
'LPUSHX' => $prefixFirst,
'LINSERT' => $prefixFirst,
'BRPOPLPUSH' => $prefixSkipLast,
'ZREVRANGEBYSCORE' => $prefixFirst,
'WATCH' => $prefixAll,
/* ---------------- Redis 2.6 ---------------- */
'PTTL' => 'static::first',
'PEXPIRE' => 'static::first',
'PEXPIREAT' => 'static::first',
'PSETEX' => 'static::first',
'INCRBYFLOAT' => 'static::first',
'BITOP' => 'static::skipFirst',
'BITCOUNT' => 'static::first',
'HINCRBYFLOAT' => 'static::first',
'EVAL' => 'static::evalKeys',
'EVALSHA' => 'static::evalKeys',
'MIGRATE' => 'static::migrate',
'PTTL' => $prefixFirst,
'PEXPIRE' => $prefixFirst,
'PEXPIREAT' => $prefixFirst,
'PSETEX' => $prefixFirst,
'INCRBYFLOAT' => $prefixFirst,
'BITOP' => $prefixSkipFirst,
'BITCOUNT' => $prefixFirst,
'HINCRBYFLOAT' => $prefixFirst,
'EVAL' => $prefixEvalKeys,
'EVALSHA' => $prefixEvalKeys,
'MIGRATE' => $prefixMigrate,
/* ---------------- Redis 2.8 ---------------- */
'SSCAN' => 'static::first',
'ZSCAN' => 'static::first',
'HSCAN' => 'static::first',
'PFADD' => 'static::first',
'PFCOUNT' => 'static::all',
'PFMERGE' => 'static::all',
'ZLEXCOUNT' => 'static::first',
'ZRANGEBYLEX' => 'static::first',
'ZREMRANGEBYLEX' => 'static::first',
'ZREVRANGEBYLEX' => 'static::first',
'BITPOS' => 'static::first',
'SSCAN' => $prefixFirst,
'ZSCAN' => $prefixFirst,
'HSCAN' => $prefixFirst,
'PFADD' => $prefixFirst,
'PFCOUNT' => $prefixAll,
'PFMERGE' => $prefixAll,
'ZLEXCOUNT' => $prefixFirst,
'ZRANGEBYLEX' => $prefixFirst,
'ZREMRANGEBYLEX' => $prefixFirst,
'ZREVRANGEBYLEX' => $prefixFirst,
'BITPOS' => $prefixFirst,
/* ---------------- Redis 3.2 ---------------- */
'HSTRLEN' => 'static::first',
'BITFIELD' => 'static::first',
'GEOADD' => 'static::first',
'GEOHASH' => 'static::first',
'GEOPOS' => 'static::first',
'GEODIST' => 'static::first',
'GEORADIUS' => 'static::georadius',
'GEORADIUSBYMEMBER' => 'static::georadius',
);
'HSTRLEN' => $prefixFirst,
'BITFIELD' => $prefixFirst,
'GEOADD' => $prefixFirst,
'GEOHASH' => $prefixFirst,
'GEOPOS' => $prefixFirst,
'GEODIST' => $prefixFirst,
'GEORADIUS' => $prefixGeoradius,
'GEORADIUSBYMEMBER' => $prefixGeoradius,
];
}
/**
@@ -197,7 +209,7 @@ class KeyPrefixProcessor implements ProcessorInterface
if ($command instanceof PrefixableCommandInterface) {
$command->prefixKeys($this->prefix);
} elseif (isset($this->commands[$commandID = strtoupper($command->getId())])) {
call_user_func($this->commands[$commandID], $command, $this->prefix);
$this->commands[$commandID]($command, $this->prefix);
}
}
+65
View File
@@ -0,0 +1,65 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
use Predis\Command\Command as RedisCommand;
/**
* @link http://redis.io/commands/xadd
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class XADD extends RedisCommand
{
/**
* {@inheritdoc}
*/
public function getId()
{
return 'XADD';
}
/**
* {@inheritdoc}
*/
public function setArguments(array $arguments)
{
$args = array();
$args[] = $arguments[0];
$options = $arguments[3] ?? [];
if (isset($options['nomkstream']) && $options['nomkstream']) {
$args[] = 'NOMKSTREAM';
}
if (isset($options['trim']) && is_array($options['trim'])) {
array_push($args, ...$options['trim']);
if (isset($options['limit'])) {
$args[] = 'LIMIT';
$args[] = $options['limit'];
}
}
// ID, default to * to let Redis set it
$args[] = $arguments[2] ?? '*';
if (isset($arguments[1]) && is_array($arguments[1])) {
foreach ($arguments[1] as $key => $val) {
$args[] = $key;
$args[] = $val;
}
}
parent::setArguments($args);
}
}
+40
View File
@@ -0,0 +1,40 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
use Predis\Command\Command as RedisCommand;
/**
* @link http://redis.io/commands/xdel
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class XDEL extends RedisCommand
{
/**
* {@inheritdoc}
*/
public function getId()
{
return 'XDEL';
}
/**
* {@inheritdoc}
*/
public function setArguments(array $arguments)
{
$arguments = self::normalizeVariadic($arguments);
parent::setArguments($arguments);
}
}
+30
View File
@@ -0,0 +1,30 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
use Predis\Command\Command as RedisCommand;
/**
* @link http://redis.io/commands/xlen
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class XLEN extends RedisCommand
{
/**
* {@inheritdoc}
*/
public function getId()
{
return 'XLEN';
}
}
+63
View File
@@ -0,0 +1,63 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
use Predis\Command\Command as RedisCommand;
/**
* @link http://redis.io/commands/xrange
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class XRANGE extends RedisCommand
{
/**
* {@inheritdoc}
*/
public function getId()
{
return 'XRANGE';
}
/**
* {@inheritdoc}
*/
public function setArguments(array $arguments)
{
if (count($arguments) === 4) {
$arguments[] = $arguments[3];
$arguments[3] = 'COUNT';
}
parent::setArguments($arguments);
}
/**
* {@inheritdoc}
*/
public function parseResponse($data)
{
$result = array();
foreach ($data as $entry) {
$processed = array();
$count = count($entry[1]);
for ($i = 0; $i < $count; ++$i) {
$processed[$entry[1][$i]] = $entry[1][++$i];
}
$result[$entry[0]] = $processed;
}
return $result;
}
}
+28
View File
@@ -0,0 +1,28 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
/**
* @link http://redis.io/commands/xrevrange
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class XREVRANGE extends XRANGE
{
/**
* {@inheritdoc}
*/
public function getId()
{
return 'XREVRANGE';
}
}
+55
View File
@@ -0,0 +1,55 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
use Predis\Command\Command as RedisCommand;
/**
* @link http://redis.io/commands/xtrim
*
* @author Daniele Alessandri <suppakilla@gmail.com>
*/
class XTRIM extends RedisCommand
{
/**
* {@inheritdoc}
*/
public function getId()
{
return 'XTRIM';
}
/**
* {@inheritdoc}
*/
public function setArguments(array $arguments)
{
$args = [];
$options = $arguments[3] ?? [];
$args[] = $arguments[0];
// Either e.g. 'MAXLEN' or ['MAXLEN', '~']
if (is_array($arguments[1])) {
array_push($args, ...$arguments[1]);
} else {
$args[] = $arguments[1];
}
$args[] = $arguments[2];
if (isset($options['limit'])) {
$args[] = 'LIMIT';
$args[] = $options['limit'];
}
parent::setArguments($args);
}
}
@@ -269,6 +269,12 @@ class SentinelReplication implements ReplicationInterface
$parameters['database'] = null;
$parameters['username'] = null;
// don't leak password from between configurations
// https://github.com/predis/predis/pull/807/#discussion_r985764770
if (! isset($parameters['password'])) {
$parameters['password'] = null;
}
if (!isset($parameters['timeout'])) {
$parameters['timeout'] = $this->sentinelTimeout;
}
+2 -2
View File
@@ -260,7 +260,7 @@ class StreamConnection extends AbstractConnection
$socket = $this->getResource();
while (($length = strlen($buffer)) > 0) {
$written = @fwrite($socket, $buffer);
$written = is_resource($socket) ? @fwrite($socket, $buffer) : false;
if ($length === $written) {
return;
@@ -304,7 +304,7 @@ class StreamConnection extends AbstractConnection
$bytesLeft = ($size += 2);
do {
$chunk = fread($socket, min($bytesLeft, 4096));
$chunk = is_resource($socket) ? fread($socket, min($bytesLeft, 4096)) : false;
if ($chunk === false || $chunk === '') {
$this->onConnectionError('Error while reading bytes from the server.');
+290
View File
@@ -0,0 +1,290 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
/**
* @group commands
* @group realm-stream
*/
class XADD_Test extends PredisCommandTestCase
{
/**
* @group disconnected
* @dataProvider dataFilterArguments
*/
public function testFilterArguments(array $arguments, array $expected): void
{
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
public function dataFilterArguments(): array
{
$data = [];
$data[] = [
[
'stream',
['key' => 'val'],
'*',
['trim' => ['MINID', '~', '0-1'], 'limit' => 5, 'nomkstream' => true]
],
['stream', 'NOMKSTREAM', 'MINID', '~', '0-1', 'LIMIT', 5, '*', 'key', 'val'],
];
$data[] = [
[
'stream',
['key1' => 'val1', 'key2' => 'val2'],
'*',
['trim' => ['MINID', '~', '0-1'], 'limit' => 5, 'nomkstream' => true]
],
['stream', 'NOMKSTREAM', 'MINID', '~', '0-1', 'LIMIT', 5, '*', 'key1', 'val1', 'key2', 'val2'],
];
$data[] = [
[
'stream',
['key' => 'val'],
'*',
['trim' => ['MINID', '~', '0-1'], 'limit' => 5]
],
['stream', 'MINID', '~', '0-1', 'LIMIT', 5, '*', 'key', 'val'],
];
$data[] = [
[
'stream',
['key' => 'val'],
'*',
['trim' => ['MINID', '~', '0-1']]
],
['stream', 'MINID', '~', '0-1', '*', 'key', 'val'],
];
$data[] = [
[
'stream',
['key' => 'val'],
'*',
['trim' => ['MINID', '0-1']]
],
['stream', 'MINID', '0-1', '*', 'key', 'val'],
];
$data[] = [
['stream', ['key' => 'val'], '2-3'],
['stream', '2-3', 'key', 'val'],
];
$data[] = [
['stream', ['key' => 'val']],
['stream', '*', 'key', 'val'],
];
return $data;
}
/**
* {@inheritdoc}
*/
protected function getExpectedCommand(): string
{
return 'Predis\Command\Redis\XADD';
}
/**
* {@inheritdoc}
*/
protected function getExpectedId(): string
{
return 'XADD';
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testAddsToStreamWithDefaults(): void
{
$redis = $this->getClient();
$redis->xadd('stream', ['key' => 'val']);
$this->assertSame(1, $redis->xlen('stream'));
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testAddsToStreamWithSpecificId(): void
{
$redis = $this->getClient();
$id = time() . '-123';
$redis->xadd('stream', ['key' => 'val'], $id);
$response = $redis->xrange('stream', $id, $id);
$this->assertCount(1, $response);
$this->assertNotNull($response[$id]);
}
/**
* @group connected
* @requiresRedisVersion >= 6.2.0
*/
public function testNomkstreamWhenStreamDoesNotExist(): void
{
$redis = $this->getClient();
$redis->xadd('new-stream', ['key' => 'val'], '*', ['nomkstream' => true]);
$this->assertSame(0, $redis->exists('new-stream'));
}
/**
* @group connected
* @requiresRedisVersion >= 6.2.0
*/
public function testNomkstreamWhenStreamExists(): void
{
$redis = $this->getClient();
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val'], '*', ['nomkstream' => true]);
$this->assertSame(1, $redis->exists('stream'));
$this->assertSame(2, $redis->xlen('stream'));
}
/**
* @group connected
* @requiresRedisVersion >= 6.2.0
*/
public function testTrimOnMinidExact(): void
{
$redis = $this->getClient();
$redis->xadd('stream', ['key' => 'val']);
$id = $redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val'], '*', ['trim' => ['MINID', $id]]);
$this->assertSame(2, $redis->xlen('stream'));
}
/**
* @group connected
* @requiresRedisVersion >= 6.2.0
*/
public function testTrimOnMinidInexact(): void
{
$redis = $this->getClient();
$config = $redis->config('get', 'stream-node-max-entries');
$oldStreamNodeMaxEntries = (int) array_pop($config);
$redis->config('set', 'stream-node-max-entries', 2);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$id = $redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val'], '*', ['trim' => ['MINID', '~', $id]]);
$this->assertSame(3, $redis->xlen('stream'));
$redis->config('set', 'stream-node-max-entries', $oldStreamNodeMaxEntries);
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testTrimOnMaxlenExact(): void
{
$redis = $this->getClient();
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val'], '*', ['trim' => ['MAXLEN', 2]]);
$this->assertSame(2, $redis->xlen('stream'));
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testTrimOnMaxlenInexact(): void
{
$redis = $this->getClient();
$config = $redis->config('get', 'stream-node-max-entries');
$oldStreamNodeMaxEntries = (int) array_pop($config);
$redis->config('set', 'stream-node-max-entries', 2);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val'], '*', ['trim' => ['MAXLEN', '~', 2]]);
$this->assertSame(3, $redis->xlen('stream'));
$redis->config('set', 'stream-node-max-entries', $oldStreamNodeMaxEntries);
}
/**
* @group connected
* @requiresRedisVersion >= 6.2.0
*/
public function testTrimOnMaxlenWithLimit(): void
{
$redis = $this->getClient();
$config = $redis->config('get', 'stream-node-max-entries');
$oldStreamNodeMaxEntries = (int) array_pop($config);
$redis->config('set', 'stream-node-max-entries', 2);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd(
'stream',
['key' => 'val'],
'*',
['trim' => ['MAXLEN', '~', 2], 'limit' => 2]
);
$this->assertSame(4, $redis->xlen('stream'));
$redis->config('set', 'stream-node-max-entries', $oldStreamNodeMaxEntries);
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testThrowsExceptionOnWrongType(): void
{
$this->expectException('Predis\Response\ServerException');
$this->expectExceptionMessage('Operation against a key holding the wrong kind of value');
$redis = $this->getClient();
$redis->set('foo', 'bar');
$redis->xadd('foo', ['key' => 'val']);
}
}
+90
View File
@@ -0,0 +1,90 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
/**
* @group commands
* @group realm-stream
*/
class XDEL_Test extends PredisCommandTestCase
{
/**
* {@inheritdoc}
*/
protected function getExpectedCommand(): string
{
return 'Predis\Command\Redis\XDEL';
}
/**
* {@inheritdoc}
*/
protected function getExpectedId(): string
{
return 'XDEL';
}
/**
* @group disconnected
*/
public function testFilterArguments(): void
{
$arguments = array('stream', 'id1', 'id2', 'id3');
$expected = array('stream', 'id1', 'id2', 'id3');
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @group disconnected
*/
public function testParseResponse(): void
{
$this->assertSame(1, $this->getCommand()->parseResponse(1));
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testRemovesSpecifiedMembers(): void
{
$redis = $this->getClient();
$redis->xadd('stream', ['key0' => 'val0'], '0-1');
$redis->xadd('stream', ['key1' => 'val1'], '1-1');
$redis->xadd('stream', ['key2' => 'val2'], '2-1');
$this->assertSame(2, $redis->xdel('stream', '0-1', '2-1', '99-1'));
$this->assertSame(['1-1' => ['key1' => 'val1']], $redis->xrange('stream', '-', '+'));
$this->assertSame(0, $redis->xdel('stream', '0-1'));
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testThrowsExceptionOnWrongType(): void
{
$this->expectException('Predis\Response\ServerException');
$this->expectExceptionMessage('Operation against a key holding the wrong kind of value');
$redis = $this->getClient();
$redis->set('foo', 'bar');
$redis->xdel('foo', 'bar');
}
}
+99
View File
@@ -0,0 +1,99 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
/**
* @group commands
* @group realm-stream
*/
class XLEN_Test extends PredisCommandTestCase
{
/**
* {@inheritdoc}
*/
protected function getExpectedCommand(): string
{
return 'Predis\Command\Redis\XLEN';
}
/**
* {@inheritdoc}
*/
protected function getExpectedId(): string
{
return 'XLEN';
}
/**
* @group disconnected
*/
public function testFilterArguments(): void
{
$arguments = array('key');
$expected = array('key');
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @group disconnected
*/
public function testParseResponse(): void
{
$this->assertSame(1, $this->getCommand()->parseResponse(1));
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testReturnsLengthOfList(): void
{
$redis = $this->getClient();
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$this->assertSame(2, $redis->xlen('stream'));
$redis->xadd('stream', ['key' => 'val']);
$this->assertSame(3, $redis->xlen('stream'));
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testReturnsZeroLengthOnNonExistingList(): void
{
$redis = $this->getClient();
$this->assertSame(0, $redis->llen('stream'));
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testThrowsExceptionOnWrongType(): void
{
$this->expectException('Predis\Response\ServerException');
$this->expectExceptionMessage('Operation against a key holding the wrong kind of value');
$redis = $this->getClient();
$redis->set('foo', 'bar');
$redis->xlen('foo');
}
}
+159
View File
@@ -0,0 +1,159 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
/**
* @group commands
* @group realm-stream
*/
class XRANGE_Test extends PredisCommandTestCase
{
/**
* {@inheritdoc}
*/
protected function getExpectedCommand(): string
{
return 'Predis\Command\Redis\XRANGE';
}
/**
* {@inheritdoc}
*/
protected function getExpectedId(): string
{
return 'XRANGE';
}
/**
* @group disconnected
*/
public function testFilterArguments(): void
{
$arguments = array('stream', '0-1', '1-2', 123);
$expected = array('stream', '0-1', '1-2', 'COUNT', 123);
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @group disconnected
*/
public function testFilterArgumentsNoCount(): void
{
$arguments = array('stream', '0-1', '1-2');
$expected = array('stream', '0-1', '1-2');
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @group disconnected
*/
public function testParseResponse(): void
{
$raw = array(array('0-1', ['key', 'val']));
$expected = array('0-1' => ['key' => 'val']);
$command = $this->getCommand();
$this->assertSame($expected, $command->parseResponse($raw));
}
/**
* @group disconnected
*/
public function testParseResponseMultipleKeys(): void
{
$raw = array(array('0-1', ['key1', 'val1', 'key2', 'val2']));
$expected = array('0-1' => ['key1' => 'val1', 'key2' => 'val2']);
$command = $this->getCommand();
$this->assertSame($expected, $command->parseResponse($raw));
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testReturnsElementsInRange(): void
{
$redis = $this->getClient();
for ($i = 0; $i < 10; $i++) {
$redis->xadd('stream', ['key' . $i => 'val' . $i], $i . '-1');
}
$this->assertSame(array(), $redis->xrange('stream', '1-1', '0-1'));
$this->assertSame(
array('0-1' => ['key0' => 'val0']),
$redis->xrange('stream', '0-1', '0-1')
);
$this->assertSame(
array('0-1' => ['key0' => 'val0'], '1-1' => ['key1' => 'val1']),
$redis->xrange('stream', '0-1', '1-1')
);
$this->assertSame(
array('0-1' => ['key0' => 'val0'], '1-1' => ['key1' => 'val1']),
$redis->xrange('stream', '-', '1-1')
);
$this->assertSame(
array('8-1' => ['key8' => 'val8'], '9-1' => ['key9' => 'val9']),
$redis->xrange('stream', '8-1', '+')
);
$this->assertSame(
array('5-1' => ['key5' => 'val5'], '6-1' => ['key6' => 'val6']),
$redis->xrange('stream', '5-1', '6-1')
);
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testMultipleKeys(): void
{
$redis = $this->getClient();
$redis->xadd('stream', ['key1' => 'val1', 'key2' => 'val2'], '0-1');
$redis->xadd('stream', ['key1' => 'val1', 'key2' => 'val2'], '1-1');
$this->assertSame(
array(
'0-1' => ['key1' => 'val1', 'key2' => 'val2'],
'1-1' => ['key1' => 'val1', 'key2' => 'val2'],
),
$redis->xrange('stream', '-', '+')
);
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testThrowsExceptionOnWrongType(): void
{
$this->expectException('Predis\Response\ServerException');
$this->expectExceptionMessage('Operation against a key holding the wrong kind of value');
$redis = $this->getClient();
$redis->set('foo', 'bar');
$redis->xrange('foo', '0-1', '1-1');
}
}
@@ -0,0 +1,159 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
/**
* @group commands
* @group realm-stream
*/
class XREVRANGE_Test extends PredisCommandTestCase
{
/**
* {@inheritdoc}
*/
protected function getExpectedCommand(): string
{
return 'Predis\Command\Redis\XREVRANGE';
}
/**
* {@inheritdoc}
*/
protected function getExpectedId(): string
{
return 'XREVRANGE';
}
/**
* @group disconnected
*/
public function testFilterArguments(): void
{
$arguments = array('stream', '1-1', '0-1', 123);
$expected = array('stream', '1-1', '0-1', 'COUNT', 123);
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @group disconnected
*/
public function testFilterArgumentsNoCount(): void
{
$arguments = array('stream', '1-1', '0-1');
$expected = array('stream', '1-1', '0-1');
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @group disconnected
*/
public function testParseResponse(): void
{
$raw = array(array('0-1', ['key', 'val']));
$expected = array('0-1' => ['key' => 'val']);
$command = $this->getCommand();
$this->assertSame($expected, $command->parseResponse($raw));
}
/**
* @group disconnected
*/
public function testParseResponseMultipleKeys(): void
{
$raw = array(array('0-1', ['key1', 'val1', 'key2', 'val2']));
$expected = array('0-1' => ['key1' => 'val1', 'key2' => 'val2']);
$command = $this->getCommand();
$this->assertSame($expected, $command->parseResponse($raw));
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testReturnsElementsInRange(): void
{
$redis = $this->getClient();
for ($i = 0; $i < 10; $i++) {
$redis->xadd('stream', ['key' . $i => 'val' . $i], $i . '-1');
}
$this->assertSame(array(), $redis->xrevrange('stream', '0-1', '1-1'));
$this->assertSame(
array('0-1' => ['key0' => 'val0']),
$redis->xrevrange('stream', '0-1', '0-1')
);
$this->assertSame(
array('1-1' => ['key1' => 'val1'], '0-1' => ['key0' => 'val0']),
$redis->xrevrange('stream', '1-1', '0-1')
);
$this->assertSame(
array('1-1' => ['key1' => 'val1'], '0-1' => ['key0' => 'val0']),
$redis->xrevrange('stream', '1-1', '-')
);
$this->assertSame(
array('9-1' => ['key9' => 'val9'], '8-1' => ['key8' => 'val8']),
$redis->xrevrange('stream', '+', '8-1')
);
$this->assertSame(
array('6-1' => ['key6' => 'val6'], '5-1' => ['key5' => 'val5']),
$redis->xrevrange('stream', '6-1', '5-1')
);
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testMultipleKeys(): void
{
$redis = $this->getClient();
$redis->xadd('stream', ['key1' => 'val1', 'key2' => 'val2'], '0-1');
$redis->xadd('stream', ['key1' => 'val1', 'key2' => 'val2'], '1-1');
$this->assertSame(
array(
'1-1' => ['key1' => 'val1', 'key2' => 'val2'],
'0-1' => ['key1' => 'val1', 'key2' => 'val2'],
),
$redis->xrevrange('stream', '+', '-')
);
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testThrowsExceptionOnWrongType(): void
{
$this->expectException('Predis\Response\ServerException');
$this->expectExceptionMessage('Operation against a key holding the wrong kind of value');
$redis = $this->getClient();
$redis->set('foo', 'bar');
$redis->xrevrange('foo', '1-1', '0-1');
}
}
+201
View File
@@ -0,0 +1,201 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) Daniele Alessandri <suppakilla@gmail.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
/**
* @group commands
* @group realm-stream
*/
class XTRIM_Test extends PredisCommandTestCase
{
/**
* {@inheritdoc}
*/
protected function getExpectedCommand(): string
{
return 'Predis\Command\Redis\XTRIM';
}
/**
* {@inheritdoc}
*/
protected function getExpectedId(): string
{
return 'XTRIM';
}
/**
* @group disconnected
* @dataProvider dataFilterArguments
*/
public function testFilterArguments(array $arguments, array $expected): void
{
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
public function dataFilterArguments(): array
{
return [
[
['stream', ['MINID', '~'], '0-1', ['limit' => 10]],
['stream', 'MINID', '~', '0-1', 'LIMIT', 10],
],
[
['stream', ['MINID'], '0-1', ['limit' => 10]],
['stream', 'MINID', '0-1', 'LIMIT', 10],
],
[
['stream', 'MINID', '0-1', ['limit' => 10]],
['stream', 'MINID', '0-1', 'LIMIT', 10],
],
[
['stream', 'MINID', '0-1'],
['stream', 'MINID', '0-1'],
],
];
}
/**
* @group disconnected
*/
public function testParseResponse(): void
{
$this->assertSame(1, $this->getCommand()->parseResponse(1));
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testTrimOnMaxlenExact(): void
{
$redis = $this->getClient();
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$res = $redis->xtrim('stream', 'MAXLEN', 2);
$this->assertSame(1, $res);
$this->assertSame(2, $redis->xlen('stream'));
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testTrimOnMaxlenInexact(): void
{
$redis = $this->getClient();
$config = $redis->config('get', 'stream-node-max-entries');
$oldStreamNodeMaxEntries = (int) array_pop($config);
$redis->config('set', 'stream-node-max-entries', 2);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$res = $redis->xtrim('stream', ['MAXLEN', '~'], 2);
$this->assertSame(2, $res);
$this->assertSame(3, $redis->xlen('stream'));
$redis->config('set', 'stream-node-max-entries', $oldStreamNodeMaxEntries);
}
/**
* @group connected
* @requiresRedisVersion >= 6.2.0
*/
public function testTrimOnMinidExact(): void
{
$redis = $this->getClient();
$redis->xadd('stream', ['key' => 'val']);
$id = $redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$res = $redis->xtrim('stream', 'MINID', $id);
$this->assertSame(1, $res);
$this->assertSame(2, $redis->xlen('stream'));
}
/**
* @group connected
* @requiresRedisVersion >= 6.2.0
*/
public function testTrimOnMinidInexact(): void
{
$redis = $this->getClient();
$config = $redis->config('get', 'stream-node-max-entries');
$oldStreamNodeMaxEntries = (int) array_pop($config);
$redis->config('set', 'stream-node-max-entries', 2);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$id = $redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$res = $redis->xtrim('stream', ['MINID', '~'], $id);
$this->assertSame(2, $res);
$this->assertSame(3, $redis->xlen('stream'));
$redis->config('set', 'stream-node-max-entries', $oldStreamNodeMaxEntries);
}
/**
* @group connected
* @requiresRedisVersion >= 6.2.0
*/
public function testTrimOnMaxlenWithLimit(): void
{
$redis = $this->getClient();
$config = $redis->config('get', 'stream-node-max-entries');
$oldStreamNodeMaxEntries = (int) array_pop($config);
$redis->config('set', 'stream-node-max-entries', 2);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$redis->xadd('stream', ['key' => 'val']);
$res = $redis->xtrim('stream', ['MAXLEN', '~'], 2, ['limit' => 2]);
$this->assertSame(2, $res);
$this->assertSame(4, $redis->xlen('stream'));
$redis->config('set', 'stream-node-max-entries', $oldStreamNodeMaxEntries);
}
/**
* @group connected
* @requiresRedisVersion >= 5.0.0
*/
public function testThrowsExceptionOnWrongType(): void
{
$this->expectException('Predis\Response\ServerException');
$this->expectExceptionMessage('Operation against a key holding the wrong kind of value');
$redis = $this->getClient();
$redis->set('key', 'foo');
$redis->xtrim('key', 'MAXLEN', 2);
}
}
@@ -62,6 +62,7 @@ class SentinelReplicationTest extends PredisTestCase
$this->assertArrayNotHasKey('database', $parameters, 'Parameter `database` was expected to not exist in connection parameters');
$this->assertArrayNotHasKey('username', $parameters, 'Parameter `username` was expected to not exist in connection parameters');
$this->assertArrayNotHasKey('password', $parameters, 'Parameter `password` was expected to not exist in connection parameters');
}
/**
@@ -117,6 +118,30 @@ class SentinelReplicationTest extends PredisTestCase
$this->assertNotNull($parameters->database);
}
/**
* @group disconnected
*/
public function testConnectionParametersInstanceForSentinelConnectionIsNotModifiedEmptyPassword(): void
{
$sentinel1 = Connection\Parameters::create('tcp://127.0.0.1:5381?role=sentinel&database=1&password=');
$sentinel2 = Connection\Parameters::create('tcp://127.0.0.1:5381?role=sentinel&database=1');
$replication1 = $this->getReplicationConnection('svc', array($sentinel1));
$replication2 = $this->getReplicationConnection('svc', array($sentinel2));
$parameters1 = $replication1->getSentinelConnection()->getParameters();
$parameters2 = $replication2->getSentinelConnection()->getParameters();
$this->assertSame($sentinel1, $parameters1);
$this->assertSame($sentinel2, $parameters2);
$this->assertNull($parameters1->password);
$this->assertNull($parameters2->password);
$this->assertNotNull($parameters1->database);
$this->assertNotNull($parameters2->database);
}
/**
* @group disconnected
*/
@@ -57,6 +57,29 @@ class StreamConnectionTest extends PredisConnectionTestCase
$connection->connect();
}
/**
* @group disconnected
*/
public function testDoesntThrowErrorOnInvalidResource(): void
{
$this->expectException('Predis\Connection\ConnectionException');
$cmdSelect = RawCommand::create('SELECT', '1000');
$invalidResource = null;
/** @var NodeConnectionInterface|MockObject */
$connection = $this
->getMockBuilder($this->getConnectionClass())
->onlyMethods(array('getResource'))
->setConstructorArgs(array(new Parameters()))
->getMock();
$connection
->method('getResource')
->willReturn($invalidResource);
$connection->writeRequest($cmdSelect);
}
// ******************************************************************** //
// ---- INTEGRATION TESTS --------------------------------------------- //
// ******************************************************************** //