Compare commits

...

20 Commits

Author SHA1 Message Date
Till Krüss b1d3255ed9 tag v2.2.2 2023-09-13 09:42:03 -07:00
Till Krüss cbf394b882 Disable CLIENT SETINFO calls by default (#1399)
Add `client_info` parameter
2023-09-13 09:35:49 -07:00
Till Krüss c6bf644872 bump dev version 2023-09-13 09:34:52 -07:00
Vladyslav Vildanov 16bdd83d23 Added EXPIRETIME command to KeyPrefixProcessor (#1369)
* Added EXPIRETIME command to KeyPrefixProcessor

* Fixed test responses for Redis 7.2

* Marked test as relay-incompatible
2023-08-25 14:27:24 -07:00
Vladyslav Vildanov 912af82bfd Added support for CLUSTER container command (#1360)
* Added support for CLUSTER container command

* Codestyle fixes
2023-08-17 09:34:01 +03:00
Vladyslav Vildanov 2d74db1bde Changes related to Redis 7.2 image update (#1366)
* Added new assertion, fixed RESP3 JSON responses and versions

* Removed expectations for error messages

* Changed tests group for RESP3 not supported tests

* Removed 3.x test case

* Added missing test decorators

* Fixed typo

* Removed redisgraph module upload, as not a part of a redis-stack anymore
2023-08-16 08:18:45 -07:00
Till Krüss c5ee202179 bump version (#1365)
* bump version

* Update Client.php
2023-08-15 16:06:03 -07:00
Till Krüss 5f2b410a74 Update CHANGELOG.md (#1364)
* Update CHANGELOG.md

* Update CHANGELOG.md

* Update CHANGELOG.md
2023-08-15 16:01:46 -07:00
Vladyslav Vildanov f6cf2afe47 Updated CHANGELOG.md (#1363)
* Updated CHANGELOG.md

* Added quotes to CHANGELOG.md

* Codestyle fix
2023-08-15 08:43:46 -07:00
Vladyslav Vildanov 311cd2b79e Added support for WAITAOF command (#1357)
* Added support for WAITAOF command

* Added call to parent setUp method
2023-08-14 09:18:19 +03:00
Vladyslav Vildanov ffd31cfdef Added missing redis-stack commands to KeyPrefix processor (#1358) 2023-08-10 18:57:16 +03:00
Vladyslav Vildanov 1b2fd527ed Added support for Redis 7.0 arguments (#1359) 2023-08-10 18:57:00 +03:00
Vladyslav Vildanov 4172d2265f Client set name and version on connection (#1347)
* Added client metadata on server connection

* Added try...catch around server exception to supress CLIENT command errors

* Added exclusion for Relay connection
2023-08-03 09:04:04 +03:00
Vladyslav Vildanov a3311d6869 2.2.1 version changes (#1349) 2023-08-03 09:03:21 +03:00
Vladyslav Vildanov df14e11c3a Added support for tests running against redis cluster (#1236)
* Added support for tests running against redis cluster

* Test coverage

* Added comment about master nodes

* Codestyle fix

* Revert changes

* Revert DBNUM

* Added cluster endpoints to relay tests env configuration

* Exclude cluster tests from relay tests environment

* Removed TODO comment

* Changed cluster image version to unstable

* Updated configuration to match unstable cluster

* Fixed path

* Updated cluster CI configuration

* Removed redundant flag

* Removed backslash

* Updated file path

* Updated file path variable

* Added docker cluster initialization as additional step

* Run cluster tests as separate workflow

* Codestyle fixes

* Updated exported files

* Added additional timeout so cluster image could be settled

* Added support for different cluster image, use docker compose for cluster tests CI

* Remove unused flag

* Removed variable from volume path

* Added sleep timeout to allow docker setup after running

* Added timeout before tests run

* Updated linter settings

* Include indent changes for.sh files

* Added missing coverage

* Revert expected files and mark docker folder as exclusion

* Specify folder itself as excluded

* Moved cluster tests as separate job in tests.yml

* Updated name to contain cluster word

---------

Co-authored-by: Chayim <chayim@users.noreply.github.com>
2023-07-24 10:21:43 +03:00
Vladyslav Vildanov 7c2e8e01d8 Added support for FUNCTION KILL, FUNCTION LIST, FUNCTION STATS commands (#1334)
* Added support for FUNCTION KILL, FUNCTION LIST, FUNCTION STATS commands

* Marked tests as relay-incompatible
2023-07-12 09:58:00 +03:00
Vladyslav Vildanov 0b6ab4dea4 Added support for CLIENT NO-EVICT command (#1335) 2023-07-12 09:57:42 +03:00
Vladyslav Vildanov dd64569e06 Added support for FUNCTION DUMP, FUNCTION FLUSH, FUNCTION RESTORE commands (#1332) 2023-07-03 10:41:32 +03:00
Vladyslav Vildanov 90da582efc Fixed bug with incorrect multiple words processing (#1325)
* Fixed bug with incorrect multiple words processing

* Convert subcommand string to lower case

* Update SubcommandStrategyResolver.php

* Added test coverage

* Codestyle fixes

---------

Co-authored-by: Till Krüss <tillkruss@users.noreply.github.com>
2023-06-21 12:00:58 +03:00
Till Krüss 732abc88a2 Update CHANGELOG.md 2023-06-14 13:42:52 +03:00
173 changed files with 1967 additions and 55 deletions
+1 -1
View File
@@ -3,4 +3,4 @@ skip=./.git
check-hidden=
check-filenames=
builtin=clear,rare,informal,usage,code,names
ignore-words-list=master,masters,slave,slaves,whitelist,cas,exat,smove,SUGGET,sugget
ignore-words-list=master,masters,slave,slaves,whitelist,cas,exat,smove,SUGGET,sugget,ro
+1 -1
View File
@@ -14,7 +14,7 @@ block_comment_end = */
[*.php]
max_line_length = 150
[*.{md,yml,yaml,neon}]
[*.{md,yml,yaml,neon,sh}]
indent_size = 2
[tests/**.php]
+1 -1
View File
@@ -136,7 +136,7 @@ jobs:
EXPECTED="LICENSE,README.md,autoload.php,composer.json"
CURRENT="$(
git archive HEAD \
| tar --list --exclude="src" --exclude="src/*" --exclude="bin" --exclude="bin/*" \
| tar --list --exclude="src" --exclude="src/*" --exclude="bin" --exclude="bin/*" --exclude="docker" --exclude="docker/*" \
| paste --serial --delimiters=","
)"
echo "CURRENT =${CURRENT}"
+43
View File
@@ -78,3 +78,46 @@ jobs:
run: |
wget "https://github.com/php-coveralls/php-coveralls/releases/download/v2.5.3/php-coveralls.phar"
php ./php-coveralls.phar -v
predis-cluster:
name: PHP ${{ matrix.php }} (Redis Cluster latest)
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
php:
- '7.2'
- '7.3'
- '7.4'
- '8.0'
- '8.1'
- '8.2'
steps:
- name: Checkout repository
uses: actions/checkout@v3
- name: Run redis cluster
uses: isbang/compose-action@v1.4.1
with:
compose-file: "./docker/unstable_cluster/docker-compose.yml"
- name: Setup PHP with Composer and extensions
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php }}
extensions: relay
coverage: ${{ (matrix.php == '8.1') && 'xdebug' || 'none' }}
- name: Install Composer dependencies
uses: ramsey/composer-install@v2
with:
dependency-versions: highest
composer-options: ${{ matrix.php == '8.0' && '--ignore-platform-reqs' || '' }}
- name: Run tests against cluster
run: |
sleep 5 # Timeout to make sure that docker image is setup
vendor/bin/phpunit --group cluster
+25 -1
View File
@@ -1,7 +1,31 @@
## Changelog
## v2.2.2 (2023-09-13)
### Added
- Added `client_info` client parameter
- Added support for `CLUSTER` container command
### Fixed
- Fixed `EXPIRETIME` not using `prefix`
- Disabled `CLIENT SETINFO` calls by default
## v2.2.1 (2023-08-15)
### Added
- Added support for `WAITAOF` command (#1357)
- Added support for `SHUTDOWN` command (#1359)
- Added support for `FUNCTION` command (#1332)
- Added support for new optional `PEXPIRE`, `PEXPIREAT` and `COMMAND`
- Added missing Redis Stack commands to `KeyPrefixProcessor` (#1358)
### Changed
- Set client name and version when establishing a connection (#1347)
## v2.2.0 (2023-06-14)
Predis v2.2.0 introduces official support for [Redis Stack](https://redis.io/docs/stack/) as well as a [Relay](https://github.com/cachewerk/relay) integration for substantially [faster read performance](https://github.com/predis/predis/wiki/Using-Relay).
### Added
- Added support for [Relay](https://github.com/predis/predis/wiki/Using-Relay) (#1263)
- Added support for `FCALL_RO` command (#1191)
@@ -9,7 +33,7 @@
- Added support for `ACL SETUSER, GETUSER, DRYRUN` commands (#1193)
### Changed
- Minor code style and typehint changes (#1311)
- Minor code style and type-hint changes (#1311)
### Fixed
- Fixed prefixes for `XTRIM` and `XREVRANGE` commands (#1230)
+1 -1
View File
@@ -1 +1 @@
2.2.0-RC1
2.2.2
+7
View File
@@ -0,0 +1,7 @@
FROM redis/redis-stack-server:latest as rss
COPY create_cluster.sh /create_cluster.sh
RUN ls -R /opt/redis-stack
RUN chmod a+x /create_cluster.sh
ENTRYPOINT [ "/create_cluster.sh"]
+47
View File
@@ -0,0 +1,47 @@
#! /bin/bash
mkdir -p /nodes
touch /nodes/nodemap
if [ -z ${START_PORT} ]; then
START_PORT=6372
fi
if [ -z ${END_PORT} ]; then
END_PORT=6377
fi
if [ ! -z "$3" ]; then
START_PORT=$2
START_PORT=$3
fi
echo "STARTING: ${START_PORT}"
echo "ENDING: ${END_PORT}"
for PORT in `seq ${START_PORT} ${END_PORT}`; do
mkdir -p /nodes/$PORT
if [[ -e /redis.conf ]]; then
cp /redis.conf /nodes/$PORT/redis.conf
else
touch /nodes/$PORT/redis.conf
fi
cat << EOF >> /nodes/$PORT/redis.conf
port ${PORT}
cluster-enabled yes
daemonize yes
logfile /redis.log
dir /nodes/$PORT
EOF
set -x
/opt/redis-stack/bin/redis-server /nodes/$PORT/redis.conf
sleep 1
if [ $? -ne 0 ]; then
echo "Redis failed to start, exiting."
continue
fi
echo 127.0.0.1:$PORT >> /nodes/nodemap
done
if [ -z "${REDIS_PASSWORD}" ]; then
echo yes | /opt/redis-stack/bin/redis-cli --cluster create `seq -f 127.0.0.1:%g ${START_PORT} ${END_PORT}` --cluster-replicas 1
else
echo yes | opt/redis-stack/bin/redis-cli -a ${REDIS_PASSWORD} --cluster create `seq -f 127.0.0.1:%g ${START_PORT} ${END_PORT}` --cluster-replicas 1
fi
tail -f /redis.log
@@ -0,0 +1,17 @@
version: "3.9"
services:
cluster:
container_name: redis-cluster
build:
context: .
dockerfile: Dockerfile
ports:
- "6372:6372"
- "6373:6373"
- "6374:6374"
- "6375:6375"
- "6376:6376"
- "6377:6378"
volumes:
- "./redis.conf:/redis.conf:ro"
+8
View File
@@ -0,0 +1,8 @@
# Redis Cluster config file will be shared across all nodes.
# Do not change the following configurations that are already set:
# port, cluster-enabled, daemonize, logfile, dir
protected-mode no
loadmodule /opt/redis-stack/lib/redisearch.so
loadmodule /opt/redis-stack/lib/redistimeseries.so
loadmodule /opt/redis-stack/lib/rejson.so
loadmodule /opt/redis-stack/lib/redisbloom.so
+41
View File
@@ -0,0 +1,41 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
use Predis\Client;
require __DIR__ . '/../shared.php';
// Example of WAITAOF command usage:
// 1. Enable appendonly mode if it's not (command works only in appendonly mode)
$client = new Client($single_server);
$info = $client->info();
$enabled = false;
if ($info['Persistence']['aof_enabled'] === '0') {
$client->config('set', 'appendonly', 'yes');
$enabled = true;
}
// 2. Set key value pair
$response = $client->set('foo', 'bar');
echo "Key-value pair set status: {$response}\n";
// 3. Run WAITAOF command to make sure that all previous writes was fsynced
$response = $client->waitaof(1, 0, 0);
echo "Quantity of local instances that was fsynced - {$response[0]}, quantity of replicas - {$response[1]}";
// 4. Disable appendonly mode if it was enabled during script execution
if ($enabled) {
$client->config('set', 'appendonly', 'no');
}
+6
View File
@@ -20,10 +20,12 @@
<groups>
<exclude>
<group>relay-incompatible</group>
<group>relay-resp3</group>
<group>realm-webdis</group>
<group>realm-stack</group>
<group>ext-curl</group>
<group>ext-phpiredis</group>
<group>cluster</group>
</exclude>
</groups>
@@ -38,5 +40,9 @@
<const name="REDIS_SERVER_PORT" value="6379" />
<const name="REDIS_SERVER_DBNUM" value="0" />
<env name="USE_RELAY" value="true" />
<!-- Redis Cluster -->
<!-- Only master nodes endpoints included -->
<const name="REDIS_CLUSTER_ENDPOINTS" value="127.0.0.1:6372,127.0.0.1:6373,127.0.0.1:6374" />
</php>
</phpunit>
+5
View File
@@ -33,6 +33,7 @@
<group>ext-relay</group>
<group>ext-curl</group>
<group>ext-phpiredis</group>
<group>cluster</group>
<!-- <group>connected</group> -->
<!-- <group>disconnected</group> -->
<!-- <group>commands</group> -->
@@ -51,5 +52,9 @@
<const name="REDIS_SERVER_PORT" value="6379" />
<const name="REDIS_SERVER_DBNUM" value="0" />
<env name="USE_RELAY" value="false" />
<!-- Redis Cluster -->
<!-- Only master nodes endpoints included -->
<const name="REDIS_CLUSTER_ENDPOINTS" value="127.0.0.1:6372,127.0.0.1:6373,127.0.0.1:6374" />
</php>
</phpunit>
+1 -1
View File
@@ -53,7 +53,7 @@ use Traversable;
*/
class Client implements ClientInterface, IteratorAggregate
{
public const VERSION = '2.2.0-RC1';
public const VERSION = '2.2.2';
/** @var OptionsInterface */
private $options;
+4
View File
@@ -39,6 +39,7 @@ use Predis\Command\Argument\TimeSeries\MRangeArguments;
use Predis\Command\Argument\TimeSeries\RangeArguments;
use Predis\Command\CommandInterface;
use Predis\Command\Redis\Container\ACL;
use Predis\Command\Redis\Container\CLUSTER;
use Predis\Command\Redis\Container\FunctionContainer;
use Predis\Command\Redis\Container\Json\JSONDEBUG;
use Predis\Command\Redis\Container\Search\FTCONFIG;
@@ -304,12 +305,14 @@ use Predis\Command\Redis\Container\Search\FTCURSOR;
* @method $this exec()
* @method $this multi()
* @method $this unwatch()
* @method $this waitaof(int $numLocal, int $numReplicas, int $timeout)
* @method $this watch($key)
* @method $this eval($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
* @method $this eval_ro(string $script, array $keys, ...$argument)
* @method $this evalsha($script, $numkeys, $keyOrArg1 = null, $keyOrArgN = null)
* @method $this evalsha_ro(string $sha1, array $keys, ...$argument)
* @method $this script($subcommand, $argument = null)
* @method $this shutdown(bool $noSave = null, bool $now = false, bool $force = false, bool $abort = false)
* @method $this auth($password)
* @method $this echo($message)
* @method $this ping($message = null)
@@ -338,6 +341,7 @@ use Predis\Command\Redis\Container\Search\FTCURSOR;
* @method $this geosearchstore(string $destination, string $source, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $storeDist = false)
*
* Container commands
* @property CLUSTER $cluster
* @property FunctionContainer $function
* @property FTCONFIG $ftconfig
* @property FTCURSOR $ftcursor
+4
View File
@@ -40,6 +40,7 @@ use Predis\Command\Argument\TimeSeries\RangeArguments;
use Predis\Command\CommandInterface;
use Predis\Command\FactoryInterface;
use Predis\Command\Redis\Container\ACL;
use Predis\Command\Redis\Container\CLUSTER;
use Predis\Command\Redis\Container\FunctionContainer;
use Predis\Command\Redis\Container\Json\JSONDEBUG;
use Predis\Command\Redis\Container\Search\FTCONFIG;
@@ -322,12 +323,14 @@ use Predis\Response\Status;
* @method array|null exec()
* @method mixed multi()
* @method mixed unwatch()
* @method array waitaof(int $numLocal, int $numReplicas, int $timeout)
* @method mixed watch(string $key)
* @method mixed eval(string $script, int $numkeys, string ...$keyOrArg = null)
* @method mixed eval_ro(string $script, array $keys, ...$argument)
* @method mixed evalsha(string $script, int $numkeys, string ...$keyOrArg = null)
* @method mixed evalsha_ro(string $sha1, array $keys, ...$argument)
* @method mixed script($subcommand, $argument = null)
* @method Status shutdown(bool $noSave = null, bool $now = false, bool $force = false, bool $abort = false)
* @method mixed auth(string $password)
* @method string echo(string $message)
* @method mixed ping(string $message = null)
@@ -356,6 +359,7 @@ use Predis\Response\Status;
* @method int geosearchstore(string $destination, string $source, FromInterface $from, ByInterface $by, ?string $sorting = null, int $count = -1, bool $any = false, bool $storeDist = false)
*
* Container commands
* @property CLUSTER $cluster
* @property FunctionContainer $function
* @property FTCONFIG $ftconfig
* @property FTCURSOR $ftcursor
+17
View File
@@ -53,6 +53,7 @@ abstract class ClusterStrategy implements StrategyInterface
'SORT' => [$this, 'getKeyFromSortCommand'],
'DUMP' => $getKeyFromFirstArgument,
'RESTORE' => $getKeyFromFirstArgument,
'FLUSHDB' => [$this, 'getFakeKey'],
/* commands operating on string values */
'APPEND' => $getKeyFromFirstArgument,
@@ -163,6 +164,9 @@ abstract class ClusterStrategy implements StrategyInterface
'EVAL' => [$this, 'getKeyFromScriptingCommands'],
'EVALSHA' => [$this, 'getKeyFromScriptingCommands'],
/* server */
'INFO' => [$this, 'getFakeKey'],
/* commands performing geospatial operations */
'GEOADD' => $getKeyFromFirstArgument,
'GEOHASH' => $getKeyFromFirstArgument,
@@ -170,6 +174,9 @@ abstract class ClusterStrategy implements StrategyInterface
'GEODIST' => $getKeyFromFirstArgument,
'GEORADIUS' => [$this, 'getKeyFromGeoradiusCommands'],
'GEORADIUSBYMEMBER' => [$this, 'getKeyFromGeoradiusCommands'],
/* cluster */
'CLUSTER' => [$this, 'getFakeKey'],
];
}
@@ -216,6 +223,16 @@ abstract class ClusterStrategy implements StrategyInterface
$this->commands[$commandID] = $callback;
}
/**
* Get fake key for commands with no key argument.
*
* @return string
*/
protected function getFakeKey(): string
{
return 'key';
}
/**
* Extracts the key from the first argument of a command instance.
*
@@ -189,6 +189,111 @@ class KeyPrefixProcessor implements ProcessorInterface
/* ---------------- Redis 6.2 ---------------- */
'GETDEL' => $prefixFirst,
/* ---------------- Redis 7.0 ---------------- */
'EXPIRETIME' => $prefixFirst,
/* RedisJSON */
'JSON.ARRAPPEND' => $prefixFirst,
'JSON.ARRINDEX' => $prefixFirst,
'JSON.ARRINSERT' => $prefixFirst,
'JSON.ARRLEN' => $prefixFirst,
'JSON.ARRPOP' => $prefixFirst,
'JSON.ARRTRIM' => $prefixFirst,
'JSON.CLEAR' => $prefixFirst,
'JSON.DEBUG MEMORY' => $prefixFirst,
'JSON.DEL' => $prefixFirst,
'JSON.FORGET' => $prefixFirst,
'JSON.GET' => $prefixFirst,
'JSON.MGET' => $prefixAll,
'JSON.NUMINCRBY' => $prefixFirst,
'JSON.OBJKEYS' => $prefixFirst,
'JSON.OBJLEN' => $prefixFirst,
'JSON.RESP' => $prefixFirst,
'JSON.SET' => $prefixFirst,
'JSON.STRAPPEND' => $prefixFirst,
'JSON.STRLEN' => $prefixFirst,
'JSON.TOGGLE' => $prefixFirst,
'JSON.TYPE' => $prefixFirst,
/* RedisBloom */
'BF.ADD' => $prefixFirst,
'BF.EXISTS' => $prefixFirst,
'BF.INFO' => $prefixFirst,
'BF.INSERT' => $prefixFirst,
'BF.LOADCHUNK' => $prefixFirst,
'BF.MADD' => $prefixFirst,
'BF.MEXISTS' => $prefixFirst,
'BF.RESERVE' => $prefixFirst,
'BF.SCANDUMP' => $prefixFirst,
'CF.ADD' => $prefixFirst,
'CF.ADDNX' => $prefixFirst,
'CF.COUNT' => $prefixFirst,
'CF.DEL' => $prefixFirst,
'CF.EXISTS' => $prefixFirst,
'CF.INFO' => $prefixFirst,
'CF.INSERT' => $prefixFirst,
'CF.INSERTNX' => $prefixFirst,
'CF.LOADCHUNK' => $prefixFirst,
'CF.MEXISTS' => $prefixFirst,
'CF.RESERVE' => $prefixFirst,
'CF.SCANDUMP' => $prefixFirst,
'CMS.INCRBY' => $prefixFirst,
'CMS.INFO' => $prefixFirst,
'CMS.INITBYDIM' => $prefixFirst,
'CMS.INITBYPROB' => $prefixFirst,
'CMS.QUERY' => $prefixFirst,
'TDIGEST.ADD' => $prefixFirst,
'TDIGEST.BYRANK' => $prefixFirst,
'TDIGEST.BYREVRANK' => $prefixFirst,
'TDIGEST.CDF' => $prefixFirst,
'TDIGEST.CREATE' => $prefixFirst,
'TDIGEST.INFO' => $prefixFirst,
'TDIGEST.MAX' => $prefixFirst,
'TDIGEST.MIN' => $prefixFirst,
'TDIGEST.QUANTILE' => $prefixFirst,
'TDIGEST.RANK' => $prefixFirst,
'TDIGEST.RESET' => $prefixFirst,
'TDIGEST.REVRANK' => $prefixFirst,
'TDIGEST.TRIMMED_MEAN' => $prefixFirst,
'TOPK.ADD' => $prefixFirst,
'TOPK.INCRBY' => $prefixFirst,
'TOPK.INFO' => $prefixFirst,
'TOPK.LIST' => $prefixFirst,
'TOPK.QUERY' => $prefixFirst,
'TOPK.RESERVE' => $prefixFirst,
/* RediSearch */
'FT.AGGREGATE' => $prefixFirst,
'FT.ALTER' => $prefixFirst,
'FT.CREATE' => $prefixFirst,
'FT.CURSOR DEL' => $prefixFirst,
'FT.CURSOR READ' => $prefixFirst,
'FT.DROPINDEX' => $prefixFirst,
'FT.EXPLAIN' => $prefixFirst,
'FT.INFO' => $prefixFirst,
'FT.PROFILE' => $prefixFirst,
'FT.SEARCH' => $prefixFirst,
'FT.SPELLCHECK' => $prefixFirst,
'FT.SYNDUMP' => $prefixFirst,
'FT.SYNUPDATE' => $prefixFirst,
'FT.TAGVALS' => $prefixFirst,
/* Redis TimeSeries */
'TS.ADD' => $prefixFirst,
'TS.ALTER' => $prefixFirst,
'TS.CREATE' => $prefixFirst,
'TS.DECRBY' => $prefixFirst,
'TS.DEL' => $prefixFirst,
'TS.GET' => $prefixFirst,
'TS.INCRBY' => $prefixFirst,
'TS.INFO' => $prefixFirst,
'TS.MGET' => $prefixFirst,
'TS.MRANGE' => $prefixFirst,
'TS.MREVRANGE' => $prefixFirst,
'TS.QUERYINDEX' => $prefixFirst,
'TS.RANGE' => $prefixFirst,
'TS.REVRANGE' => $prefixFirst,
];
}
+26
View File
@@ -0,0 +1,26 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* 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;
/**
* @see https://redis.io/commands/?name=cluster
*/
class CLUSTER extends RedisCommand
{
public function getId()
{
return 'CLUSTER';
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis\Container;
use Predis\Response\Status;
/**
* @method Status addSlotsRange(int ...$startEndSlots)
* @method Status delSlotsRange(int ...$startEndSlots)
* @method array links()
* @method array shards()
*/
class CLUSTER extends AbstractContainer
{
public function getContainerCommandId(): string
{
return 'CLUSTER';
}
}
@@ -15,8 +15,14 @@ namespace Predis\Command\Redis\Container;
use Predis\Response\Status;
/**
* @method string load(string $functionCode, bool $replace = 'false')
* @method Status delete(string $libraryName)
* @method string dump()
* @method Status flush(?string $mode = null)
* @method Status kill()
* @method array list(string $libraryNamePattern = null, bool $withCode = false)
* @method string load(string $functionCode, bool $replace = 'false')
* @method Status restore(string $value, string $policy = null)
* @method array stats()
*/
class FunctionContainer extends AbstractContainer
{
+1 -1
View File
@@ -41,7 +41,7 @@ class FUNCTIONS extends RedisCommand
public function setArguments(array $arguments)
{
$strategy = $this->strategyResolver->resolve('functions', $arguments[0]);
$strategy = $this->strategyResolver->resolve('functions', strtolower($arguments[0]));
$arguments = $strategy->processArguments($arguments);
parent::setArguments($arguments);
+32
View File
@@ -26,4 +26,36 @@ class SHUTDOWN extends RedisCommand
{
return 'SHUTDOWN';
}
/**
* {@inheritdoc}
*/
public function setArguments(array $arguments)
{
if (empty($arguments)) {
parent::setArguments($arguments);
return;
}
$processedArguments = [];
if (array_key_exists(0, $arguments) && null !== $arguments[0]) {
$processedArguments[] = ($arguments[0]) ? 'SAVE' : 'NOSAVE';
}
if (array_key_exists(1, $arguments) && false !== $arguments[1]) {
$processedArguments[] = 'NOW';
}
if (array_key_exists(2, $arguments) && false !== $arguments[2]) {
$processedArguments[] = 'FORCE';
}
if (array_key_exists(3, $arguments) && false !== $arguments[3]) {
$processedArguments[] = 'ABORT';
}
parent::setArguments($processedArguments);
}
}
+29
View File
@@ -0,0 +1,29 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* 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;
/**
* @see https://redis.io/commands/waitaof/
*
* This command blocks the current client until all the previous write commands are acknowledged
* as having been fsynced to the AOF of the local Redis and/or at least the specified number of replicas.
*/
class WAITAOF extends RedisCommand
{
public function getId()
{
return 'WAITAOF';
}
}
@@ -0,0 +1,26 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Strategy\ContainerCommands\Functions;
use Predis\Command\Strategy\SubcommandStrategyInterface;
class DumpStrategy implements SubcommandStrategyInterface
{
/**
* {@inheritDoc}
*/
public function processArguments(array $arguments): array
{
return $arguments;
}
}
@@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Strategy\ContainerCommands\Functions;
use Predis\Command\Strategy\SubcommandStrategyInterface;
class FlushStrategy implements SubcommandStrategyInterface
{
/**
* {@inheritDoc}
*/
public function processArguments(array $arguments): array
{
$processedArguments = [$arguments[0]];
if (array_key_exists(1, $arguments) && null !== $arguments[1]) {
$processedArguments[] = strtoupper($arguments[1]);
}
return $processedArguments;
}
}
@@ -0,0 +1,26 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Strategy\ContainerCommands\Functions;
use Predis\Command\Strategy\SubcommandStrategyInterface;
class KillStrategy implements SubcommandStrategyInterface
{
/**
* {@inheritDoc}
*/
public function processArguments(array $arguments): array
{
return $arguments;
}
}
@@ -0,0 +1,36 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Strategy\ContainerCommands\Functions;
use Predis\Command\Strategy\SubcommandStrategyInterface;
class ListStrategy implements SubcommandStrategyInterface
{
/**
* {@inheritDoc}
*/
public function processArguments(array $arguments): array
{
$processedArguments = [$arguments[0]];
if (array_key_exists(1, $arguments) && null !== $arguments[1]) {
array_push($processedArguments, 'LIBRARYNAME', $arguments[1]);
}
if (array_key_exists(2, $arguments) && true === $arguments[2]) {
$processedArguments[] = 'WITHCODE';
}
return $processedArguments;
}
}
@@ -0,0 +1,32 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Strategy\ContainerCommands\Functions;
use Predis\Command\Strategy\SubcommandStrategyInterface;
class RestoreStrategy implements SubcommandStrategyInterface
{
/**
* {@inheritDoc}
*/
public function processArguments(array $arguments): array
{
$processedArguments = [$arguments[0], $arguments[1]];
if (array_key_exists(2, $arguments) && null !== $arguments[2]) {
$processedArguments[] = strtoupper($arguments[2]);
}
return $processedArguments;
}
}
@@ -0,0 +1,26 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Strategy\ContainerCommands\Functions;
use Predis\Command\Strategy\SubcommandStrategyInterface;
class StatsStrategy implements SubcommandStrategyInterface
{
/**
* {@inheritDoc}
*/
public function processArguments(array $arguments): array
{
return $arguments;
}
}
@@ -18,13 +18,28 @@ class SubcommandStrategyResolver implements StrategyResolverInterface
{
private const CONTAINER_COMMANDS_NAMESPACE = 'Predis\Command\Strategy\ContainerCommands';
/**
* @var ?string
*/
private $separator;
public function __construct(string $separator = null)
{
$this->separator = $separator;
}
/**
* {@inheritDoc}
*/
public function resolve(string $commandId, string $subcommandId): SubcommandStrategyInterface
{
$subcommandStrategyClass = ucfirst(strtolower($subcommandId)) . 'Strategy';
$commandDirectoryName = ucfirst(strtolower($commandId));
$subcommandStrategyClass = ucwords($subcommandId) . 'Strategy';
$commandDirectoryName = ucwords($commandId);
if (!is_null($this->separator)) {
$subcommandStrategyClass = str_replace($this->separator, '', $subcommandStrategyClass);
$commandDirectoryName = str_replace($this->separator, '', $commandDirectoryName);
}
if (class_exists(
$containerCommandClass = self::CONTAINER_COMMANDS_NAMESPACE . '\\' . $commandDirectoryName . '\\' . $subcommandStrategyClass
+13
View File
@@ -14,6 +14,7 @@ namespace Predis\Connection;
use InvalidArgumentException;
use Predis\Command\CommandInterface;
use Predis\Command\RawCommand;
use Predis\CommunicationException;
use Predis\Protocol\ProtocolException;
@@ -27,6 +28,10 @@ abstract class AbstractConnection implements NodeConnectionInterface
private $cachedId;
protected $parameters;
/**
* @var RawCommand[]
*/
protected $initCommands = [];
/**
@@ -101,6 +106,14 @@ abstract class AbstractConnection implements NodeConnectionInterface
$this->initCommands[] = $command;
}
/**
* {@inheritdoc}
*/
public function getInitCommands(): array
{
return $this->initCommands;
}
/**
* {@inheritdoc}
*/
+11
View File
@@ -13,6 +13,7 @@
namespace Predis\Connection;
use InvalidArgumentException;
use Predis\Client;
use Predis\Command\RawCommand;
use ReflectionClass;
use UnexpectedValueException;
@@ -174,6 +175,16 @@ class Factory implements FactoryInterface
);
}
if ($parameters->client_info ?? false && !$connection instanceof RelayConnection) {
$connection->addConnectCommand(
new RawCommand('CLIENT', ['SETINFO', 'LIB-NAME', 'predis'])
);
$connection->addConnectCommand(
new RawCommand('CLIENT', ['SETINFO', 'LIB-VER', Client::VERSION])
);
}
if (isset($parameters->database) && strlen($parameters->database)) {
$connection->addConnectCommand(
new RawCommand('SELECT', [$parameters->database])
+1
View File
@@ -31,6 +31,7 @@ namespace Predis\Connection;
* @property string $database Database index (see the SELECT command).
* @property bool $async_connect Performs the connect() operation asynchronously.
* @property bool $tcp_nodelay Toggles the Nagle's algorithm for coalescing.
* @property bool $client_info Whether to set LIB-NAME and LIB-VER when connecting.
* @property bool $cache (Relay only) Whether to use in-memory caching.
* @property string $serializer (Relay only) Serializer used for data serialization.
* @property string $compression (Relay only) Algorithm used for data compression.
@@ -211,6 +211,7 @@ class SentinelReplication implements ReplicationInterface
$this->master = $connection;
} elseif ('sentinel' === $role) {
$this->sentinels[] = $connection;
// sentinels are not considered part of the pool.
return;
} else {
+3 -1
View File
@@ -231,7 +231,9 @@ class StreamConnection extends AbstractConnection
foreach ($this->initCommands as $command) {
$response = $this->executeCommand($command);
if ($response instanceof ErrorResponseInterface) {
if ($response instanceof ErrorResponseInterface && $command->getId() === 'CLIENT') {
// Do nothing on CLIENT SETINFO command failure
} elseif ($response instanceof ErrorResponseInterface) {
$this->onConnectionError("`{$command->getId()}` failed: {$response->getMessage()}", 0);
}
}
@@ -0,0 +1,81 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace PHPUnit;
use PHPUnit\Framework\Constraint\Constraint;
class AssertSameWithPrecisionConstraint extends Constraint
{
/**
* @var mixed
*/
private $expectedValue;
/**
* @var int
*/
private $precision;
public function __construct($expectedValue, int $precision)
{
$this->expectedValue = $expectedValue;
$this->precision = $precision;
}
/**
* {@inheritdoc}
*/
public function matches($other): bool
{
if (gettype($this->expectedValue) !== gettype($other)) {
return false;
}
if (is_array($other)) {
$other = array_map([$this, 'roundToPrecision'], $other);
$this->expectedValue = array_map([$this, 'roundToPrecision'], $this->expectedValue);
return !array_diff($this->expectedValue, $other);
}
$other = $this->roundToPrecision($other);
$this->expectedValue = $this->roundToPrecision($this->expectedValue);
return $other === $this->expectedValue;
}
/**
* {@inheritDoc}
*/
public function toString(): string
{
return 'given value matches another value with given precision';
}
/**
* {@inheritdoc}
*/
protected function failureDescription($other): string
{
return $this->toString();
}
/**
* @param mixed $numeric
* @return float
*/
private function roundToPrecision($numeric): float
{
return round((float) $numeric, $this->precision);
}
}
+5 -1
View File
@@ -61,7 +61,11 @@ abstract class PredisCommandTestCase extends PredisTestCase
);
}
$client = $this->createClient(null, null, $flushdb);
if ($this->isClusterTest()) {
$client = $this->createClient(null, ['cluster' => 'redis'], $flushdb);
} else {
$client = $this->createClient(null, null, $flushdb);
}
return $client;
}
+60
View File
@@ -10,6 +10,7 @@
* file that was distributed with this source code.
*/
use PHPUnit\AssertSameWithPrecisionConstraint;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\OneOfConstraint;
use PHPUnit\Util\Test as TestUtil;
@@ -131,6 +132,20 @@ abstract class PredisTestCase extends \PHPUnit\Framework\TestCase
$this->assertThat($actual, new OneOfConstraint($expected), $message);
}
/**
* Asserts that two values (of the same type) have the same values with given precision.
*
* @param mixed $expected Expected value
* @param mixed $actual Actual value
* @param int $precision Precision value should be round to
* @param string $message Optional assertion message
* @return void
*/
public function assertSameWithPrecision($expected, $actual, int $precision = 0, string $message = ''): void
{
$this->assertThat($actual, new AssertSameWithPrecisionConstraint($expected, $precision), $message);
}
/**
* Asserts that a string matches a given regular expression.
*
@@ -153,6 +168,10 @@ abstract class PredisTestCase extends \PHPUnit\Framework\TestCase
*/
protected function getDefaultParametersArray(): array
{
if ($this->isClusterTest()) {
return $this->prepareClusterEndpoints();
}
return [
'scheme' => 'tcp',
'host' => constant('REDIS_SERVER_HOST'),
@@ -237,6 +256,15 @@ abstract class PredisTestCase extends \PHPUnit\Framework\TestCase
getenv('USE_RELAY') ? ['connections' => 'relay'] : []
);
if ($this->isClusterTest()) {
$options = array_merge(
[
'cluster' => 'redis',
],
$options
);
}
$client = new Client($parameters, $options);
$client->connect();
@@ -537,4 +565,36 @@ abstract class PredisTestCase extends \PHPUnit\Framework\TestCase
$this->markTestSkipped($message);
}
}
/**
* Check annotations if it's matches to cluster test scenario.
*
* @return bool
*/
protected function isClusterTest(): bool
{
$annotations = TestUtil::parseTestMethodAnnotations(
get_class($this),
$this->getName(false)
);
return isset($annotations['method']['requiresRedisVersion'], $annotations['method']['group'])
&& !empty($annotations['method']['requiresRedisVersion'])
&& in_array('connected', $annotations['method']['group'], true)
&& in_array('cluster', $annotations['method']['group'], true);
}
/**
* Parse comma-separated cluster endpoints and convert them into tcp strings.
*
* @return array
*/
protected function prepareClusterEndpoints(): array
{
$endpoints = explode(',', constant('REDIS_CLUSTER_ENDPOINTS'));
return array_map(static function (string $elem) {
return 'tcp://' . $elem;
}, $endpoints);
}
}
+30
View File
@@ -1253,6 +1253,36 @@ class ClientTest extends PredisTestCase
$this->assertSame('127.0.0.1:6381', $iterator->key());
}
/**
* @group connected
* @group relay-incompatible
* @requiresRedisVersion >= 7.2.0
*/
public function testDoNoSetClientInfoOnConnection(): void
{
$client = new Client($this->getParameters());
$libName = $client->client('LIST')[0]['lib-name'];
$libVer = $client->client('LIST')[0]['lib-ver'];
$this->assertEmpty($libName);
$this->assertEmpty($libVer);
}
/**
* @group connected
* @group relay-incompatible
* @requiresRedisVersion >= 7.2.0
*/
public function testSetClientInfoOnConnectionWhenEnabled(): void
{
$client = new Client($this->getParameters(['client_info' => true]));
$libName = $client->client('LIST')[0]['lib-name'];
$libVer = $client->client('LIST')[0]['lib-ver'];
$this->assertSame('predis', $libName);
$this->assertSame(Client::VERSION, $libVer);
}
// ******************************************************************** //
// ---- HELPER METHODS ------------------------------------------------ //
// ******************************************************************** //
@@ -106,6 +106,21 @@ class PredisStrategyTest extends PredisTestCase
}
}
/**
* @group disconnected
*/
public function testFakeKeyCommandsWithOneKey(): void
{
$strategy = $this->getClusterStrategy();
$commands = $this->getCommandFactory();
$arguments = [];
foreach ($this->getExpectedCommands('keys-fake') as $commandID) {
$command = $commands->create($commandID, $arguments);
$this->assertNotNull($strategy->getSlot($command), $commandID);
}
}
/**
* @group disconnected
*/
@@ -327,6 +342,7 @@ class PredisStrategyTest extends PredisTestCase
'SORT' => 'variable',
'DUMP' => 'keys-first',
'RESTORE' => 'keys-first',
'FLUSHDB' => 'keys-fake',
/* commands operating on string values */
'APPEND' => 'keys-first',
@@ -437,6 +453,9 @@ class PredisStrategyTest extends PredisTestCase
'EVAL' => 'keys-script',
'EVALSHA' => 'keys-script',
/* server */
'INFO' => 'keys-fake',
/* commands performing geospatial operations */
'GEOADD' => 'keys-first',
'GEOHASH' => 'keys-first',
@@ -444,6 +463,9 @@ class PredisStrategyTest extends PredisTestCase
'GEODIST' => 'keys-first',
'GEORADIUS' => 'keys-georadius',
'GEORADIUSBYMEMBER' => 'keys-georadius',
/* cluster */
'CLUSTER' => 'keys-fake',
];
if (isset($type)) {
@@ -134,6 +134,21 @@ class RedisStrategyTest extends PredisTestCase
}
}
/**
* @group disconnected
*/
public function testFakeKeyCommandsWithOneKey(): void
{
$strategy = $this->getClusterStrategy();
$commands = $this->getCommandFactory();
$arguments = [];
foreach ($this->getExpectedCommands('keys-fake') as $commandID) {
$command = $commands->create($commandID, $arguments);
$this->assertNotNull($strategy->getSlot($command), $commandID);
}
}
/**
* @group disconnected
*/
@@ -350,6 +365,7 @@ class RedisStrategyTest extends PredisTestCase
'SORT' => 'keys-first', // TODO
'DUMP' => 'keys-first',
'RESTORE' => 'keys-first',
'FLUSHDB' => 'keys-fake',
/* commands operating on string values */
'APPEND' => 'keys-first',
@@ -460,6 +476,9 @@ class RedisStrategyTest extends PredisTestCase
'EVAL' => 'keys-script',
'EVALSHA' => 'keys-script',
/* server */
'INFO' => 'keys-fake',
/* commands performing geospatial operations */
'GEOADD' => 'keys-first',
'GEOHASH' => 'keys-first',
@@ -467,6 +486,9 @@ class RedisStrategyTest extends PredisTestCase
'GEODIST' => 'keys-first',
'GEORADIUS' => 'keys-georadius',
'GEORADIUSBYMEMBER' => 'keys-georadius',
/* cluster */
'CLUSTER' => 'keys-fake',
];
if (isset($type)) {
@@ -978,6 +978,11 @@ class KeyPrefixProcessorTest extends PredisTestCase
['key'],
['prefix:key'],
],
/* ---------------- Redis 7.0 ---------------- */
['EXPIRETIME',
['key'],
['prefix:key'],
],
];
}
}
+1 -1
View File
@@ -101,7 +101,7 @@ class ACL_Test extends PredisCommandTestCase
$redis->acl->dryRun('Test', 'SET', 'foo', 'bar')
);
$this->assertEquals(
"This user has no permissions to run the 'get' command",
"User Test has no permissions to run the 'get' command",
$redis->acl->dryRun('Test', 'GET', 'foo')
);
}
@@ -61,8 +61,9 @@ class BFADD_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0
* @requiresRedisBfVersion >= 1.0.0
*/
public function testAddGivenItemIntoBloomFilter(): void
{
@@ -75,7 +76,8 @@ class BFADD_Test extends PredisCommandTestCase
/**
* @group connected
* @requiresRedisBfVersion >= 1.0
* @group relay-incompatible
* @requiresRedisBfVersion >= 1.0.0
*/
public function testThrowsExceptionOnWrongType(): void
{
@@ -60,8 +60,9 @@ class BFEXISTS_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0
* @requiresRedisBfVersion >= 1.0.0
*/
public function testExistsReturnsExistingItemWithinBloomFilter(): void
{
@@ -61,6 +61,7 @@ class BFINFO_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider filtersProvider
* @param array $filter
* @param string $key
@@ -98,7 +99,8 @@ class BFINFO_Test extends PredisCommandTestCase
/**
* @group connected
* @requiresRedisBfVersion >= 1.0
* @group relay-resp3
* @requiresRedisBfVersion >= 1.0.0
*/
public function testThrowsExceptionOnWrongType(): void
{
@@ -60,6 +60,7 @@ class BFINSERT_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider filtersProvider
* @param array $arguments
* @param string $key
@@ -101,6 +102,7 @@ class BFINSERT_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -134,6 +136,7 @@ class BFINSERT_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider unexpectedValuesProvider
* @param array $arguments
* @param string $expectedExceptionMessage
@@ -61,6 +61,7 @@ class BFLOADCHUNK_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -61,8 +61,9 @@ class BFMADD_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0
* @requiresRedisBfVersion >= 1.0.0
*/
public function testAddGivenItemsIntoBloomFilter(): void
{
@@ -75,7 +76,8 @@ class BFMADD_Test extends PredisCommandTestCase
/**
* @group connected
* @requiresRedisBfVersion >= 1.0
* @group relay-incompatible
* @requiresRedisBfVersion >= 1.0.0
*/
public function testThrowsExceptionOnWrongType(): void
{
@@ -60,8 +60,9 @@ class BFMEXISTS_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0
* @requiresRedisBfVersion >= 1.0.0
*/
public function testExistsReturnsExistingItemsWithinBloomFilter(): void
{
@@ -60,6 +60,7 @@ class BFRESERVE_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider filtersProvider
* @param array $filter
* @param string $key
@@ -98,7 +99,8 @@ class BFRESERVE_Test extends PredisCommandTestCase
/**
* @group connected
* @requiresRedisBfVersion >= 1.0
* @group relay-resp3
* @requiresRedisBfVersion >= 1.0.0
*/
public function testThrowsExceptionOnWrongType(): void
{
@@ -61,6 +61,7 @@ class BFSCANDUMP_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -172,6 +172,18 @@ BUFFER;
$this->assertEquals($expectedConnectionName, $redis->client('GETNAME'));
}
/**
* @group connected
* @requiresRedisVersion >= 7.0.0
*/
public function testSetNoEvictModeForCurrentConnection(): void
{
$redis = $this->getClient();
$this->assertEquals('OK', $redis->client('NO-EVICT', 'ON'));
$this->assertEquals('OK', $redis->client('NO-EVICT', 'OFF'));
}
/**
* @return array
*/
+117
View File
@@ -0,0 +1,117 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis;
class CLUSTER_Test extends PredisCommandTestCase
{
/**
* {@inheritDoc}
*/
protected function getExpectedCommand(): string
{
return CLUSTER::class;
}
/**
* {@inheritDoc}
*/
protected function getExpectedId(): string
{
return 'CLUSTER';
}
/**
* @group disconnected
*/
public function testFilterArgumentsOfAddSlotsRange(): void
{
$arguments = ['ADDSLOTSRANGE', 1, 1000];
$expected = ['ADDSLOTSRANGE', 1, 1000];
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @group disconnected
*/
public function testFilterArgumentsOfDelSlotsRange(): void
{
$arguments = ['DELSLOTSRANGE', 1, 1000];
$expected = ['DELSLOTSRANGE', 1, 1000];
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @group disconnected
*/
public function testFilterArgumentsOfLinks(): void
{
$arguments = ['LINKS'];
$expected = ['LINKS'];
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @group disconnected
*/
public function testFilterArgumentsOfShards(): void
{
$arguments = ['SHARDS'];
$expected = ['SHARDS'];
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSame($expected, $command->getArguments());
}
/**
* @group connected
* @group cluster
* @return void
* @requiresRedisVersion >= 7.0.0
*/
public function testAddSlotsRangeToGivenNode(): void
{
$redis = $this->getClient();
[$startSlot, $endSlot] = $redis->cluster->shards()[0][1];
$this->assertEquals('OK', $redis->cluster->delSlotsRange($startSlot, $endSlot));
$this->assertEquals('OK', $redis->cluster->addSlotsRange($startSlot, $endSlot));
}
/**
* @group connected
* @group cluster
* @return void
* @requiresRedisVersion >= 7.0.0
*/
public function testLinksReturnsClusterPeerLinks(): void
{
$redis = $this->getClient();
$this->assertNotEmpty($redis->cluster->links());
}
}
@@ -0,0 +1,27 @@
<?php
/*
* This file is part of the Predis package.
*
* (c) 2009-2020 Daniele Alessandri
* (c) 2021-2023 Till Krüss
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Predis\Command\Redis\Container;
use Predis\ClientInterface;
use PredisTestCase;
class CLUSTER_Test extends PredisTestCase
{
public function testGetContainerCommandId(): void
{
$mockClient = $this->getMockBuilder(ClientInterface::class)->getMock();
$command = new CLUSTER($mockClient);
$this->assertSame('CLUSTER', $command->getContainerCommandId());
}
}
@@ -61,6 +61,7 @@ class CMSINCRBY_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider sketchesProvider
* @param array $incrementArguments
* @param array $queryArguments
@@ -64,6 +64,7 @@ class CMSINFO_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 2.0.0
*/
@@ -61,6 +61,7 @@ class CMSINITBYDIM_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 2.0.0
*/
@@ -61,6 +61,7 @@ class CMSINITBYPROB_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 2.0.0
*/
@@ -59,6 +59,7 @@ class CMSMERGE_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider sketchesProvider
* @param array $mergeArguments
* @param string $destinationKey
@@ -107,6 +108,7 @@ class CMSMERGE_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 2.0.0
*/
@@ -125,6 +127,7 @@ class CMSMERGE_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 2.0.0
*/
@@ -61,6 +61,7 @@ class CMSQUERY_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider sketchesProvider
* @param array $queryArguments
* @param array $expectedResponse
@@ -61,6 +61,7 @@ class CFADDNX_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -61,6 +61,7 @@ class CFADD_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -60,6 +60,7 @@ class CFCOUNT_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -61,6 +61,7 @@ class CFDEL_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -60,6 +60,7 @@ class CFEXISTS_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -62,6 +62,7 @@ class CFINFO_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -51,6 +51,7 @@ class CFINSERTNX_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider filtersProvider
* @param array $filterArguments
* @param string $key
@@ -76,6 +77,7 @@ class CFINSERTNX_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -107,6 +109,7 @@ class CFINSERTNX_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -52,6 +52,7 @@ class CFINSERT_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider filtersProvider
* @param array $filterArguments
* @param string $key
@@ -77,6 +78,7 @@ class CFINSERT_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -110,6 +112,7 @@ class CFINSERT_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -125,6 +128,7 @@ class CFINSERT_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -61,6 +61,7 @@ class CFLOADCHUNK_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
@@ -60,8 +60,9 @@ class CFMEXISTS_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0
* @requiresRedisBfVersion >= 1.0.0
*/
public function testExistsReturnsExistingItemsWithinCuckooFilter(): void
{
@@ -51,6 +51,7 @@ class CFRESERVE_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider filtersProvider
* @param array $filterArguments
* @param int $expectedCapacity
@@ -61,6 +61,7 @@ class CFSCANDUMP_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisBfVersion >= 1.0.0
*/
+255 -5
View File
@@ -70,6 +70,84 @@ class FUNCTIONS_Test extends PredisCommandTestCase
$this->assertSameValues($expected, $command->getArguments());
}
/**
* @group disconnected
*/
public function testDumpFilterArguments(): void
{
$arguments = ['DUMP'];
$expected = ['DUMP'];
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSameValues($expected, $command->getArguments());
}
/**
* @group disconnected
*/
public function testKillFilterArguments(): void
{
$arguments = ['KILL'];
$expected = ['KILL'];
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSameValues($expected, $command->getArguments());
}
/**
* @group disconnected
*/
public function testStatsFilterArguments(): void
{
$arguments = ['STATS'];
$expected = ['STATS'];
$command = $this->getCommand();
$command->setArguments($arguments);
$this->assertSameValues($expected, $command->getArguments());
}
/**
* @dataProvider flushArgumentsProvider
* @group disconnected
*/
public function testFlushFilterArguments(array $actualArguments, array $expectedResponse): void
{
$command = $this->getCommand();
$command->setArguments($actualArguments);
$this->assertSameValues($expectedResponse, $command->getArguments());
}
/**
* @dataProvider restoreArgumentsProvider
* @group disconnected
*/
public function testRestoreFilterArguments(array $actualArguments, array $expectedResponse): void
{
$command = $this->getCommand();
$command->setArguments($actualArguments);
$this->assertSameValues($expectedResponse, $command->getArguments());
}
/**
* @dataProvider listArgumentsProvider
* @group disconnected
*/
public function testListFilterArguments(array $actualArguments, array $expectedResponse): void
{
$command = $this->getCommand();
$command->setArguments($actualArguments);
$this->assertSameValues($expectedResponse, $command->getArguments());
}
/**
* @group disconnected
*/
@@ -86,7 +164,7 @@ class FUNCTIONS_Test extends PredisCommandTestCase
public function testLoadFunctionAddFunctionIntoGivenLibrary(): void
{
$redis = $this->getClient();
$redis->executeRaw(['FUNCTION', 'FLUSH']);
$redis->function->flush();
$actualResponse = $redis->function->load(
"#!lua name={$this->libName} \n redis.register_function('myfunc', function(keys, args) return args[1] end)"
@@ -105,7 +183,7 @@ class FUNCTIONS_Test extends PredisCommandTestCase
public function testLoadFunctionOverridesExistingFunctionWithReplaceArgumentGiven(): void
{
$redis = $this->getClient();
$redis->executeRaw(['FUNCTION', 'FLUSH']);
$redis->function->flush();
$actualResponse = $redis->function->load(
"#!lua name={$this->libName} \n redis.register_function('myfunc', function(keys, args) return args[1] end)"
@@ -132,7 +210,7 @@ class FUNCTIONS_Test extends PredisCommandTestCase
public function testLoadFunctionThrowsErrorOnAlreadyExistingLibraryGiven(): void
{
$redis = $this->getClient();
$redis->executeRaw(['FUNCTION', 'FLUSH']);
$redis->function->flush();
$actualResponse = $redis->function->load(
"#!lua name={$this->libName} \n redis.register_function('myfunc', function(keys, args) return args[1] end)"
@@ -160,7 +238,7 @@ class FUNCTIONS_Test extends PredisCommandTestCase
public function testDeleteFunctionRemovesAlreadyExistingLibrary(): void
{
$redis = $this->getClient();
$redis->executeRaw(['FUNCTION', 'FLUSH']);
$redis->function->flush();
$actualResponse = $redis->function->load(
"#!lua name={$this->libName} \n redis.register_function('myfunc', function(keys, args) return args[1] end)"
@@ -170,6 +248,112 @@ class FUNCTIONS_Test extends PredisCommandTestCase
$this->assertEquals('OK', $redis->function->delete($this->libName));
}
/**
* @group connected
* @return void
* @requiresRedisVersion >= 7.0.0
*/
public function testDumpReturnsSerializedPayloadOfLibrary(): void
{
$redis = $this->getClient();
$redis->function->flush();
$libName = $redis->function->load(
"#!lua name={$this->libName} \n redis.register_function('myfunc', function(keys, args) return args[1] end)"
);
$this->assertSame($this->libName, $libName);
$this->assertStringContainsString($libName, $redis->function->dump());
}
/**
* @group connected
* @return void
* @requiresRedisVersion >= 7.0.0
*/
public function testFlushRemovesAllLibraries(): void
{
$redis = $this->getClient();
$redis->function->flush();
$libName = $redis->function->load(
"#!lua name={$this->libName} \n redis.register_function('myfunc', function(keys, args) return args[1] end)"
);
$this->assertEquals($this->libName, $libName);
$this->assertEquals('OK', $redis->function->flush());
}
/**
* @group connected
* @return void
* @requiresRedisVersion >= 7.0.0
*/
public function testRestoresLibraryFromSerializedPayload(): void
{
$redis = $this->getClient();
$redis->function->flush();
$libName = $redis->function->load(
"#!lua name={$this->libName} \n redis.register_function('myfunc', function(keys, args) return args[1] end)"
);
$this->assertEquals($this->libName, $libName);
$serializedPayload = $redis->function->dump();
$this->assertStringContainsString($libName, $serializedPayload);
$redis->function->flush();
$this->assertEquals('OK', $redis->function->restore($serializedPayload));
}
/**
* @group connected
* @group relay-incompatible
* @return void
* @requiresRedisVersion >= 7.0.0
*/
public function testListReturnsListOfAvailableFunctions(): void
{
$redis = $this->getClient();
$redis->function->flush();
$expectedResponse = [
[
'library_name', 'mylib', 'engine', 'LUA', 'functions',
[
['name', 'myfunc', 'description', null, 'flags', []],
],
],
];
$libName = $redis->function->load(
"#!lua name={$this->libName} \n redis.register_function('myfunc', function(keys, args) return args[1] end)"
);
$this->assertEquals($this->libName, $libName);
$this->assertSame($expectedResponse, $redis->function->list());
}
/**
* @group connected
* @group relay-incompatible
* @return void
* @requiresRedisVersion >= 7.0.0
*/
public function testStatsReturnsInformationAboutRunningScript(): void
{
$redis = $this->getClient();
$redis->function->flush();
$expectedResponse = ['running_script', null, 'engines', ['LUA', ['libraries_count', 1, 'functions_count', 1]]];
$libName = $redis->function->load(
"#!lua name={$this->libName} \n redis.register_function('myfunc', function(keys, args) return args[1] end)"
);
$this->assertEquals($this->libName, $libName);
$this->assertSame($expectedResponse, $redis->function->stats());
}
/**
* @group connected
* @return void
@@ -178,11 +362,77 @@ class FUNCTIONS_Test extends PredisCommandTestCase
public function testDeleteFunctionThrowsErrorOnNonExistingLibrary(): void
{
$redis = $this->getClient();
$redis->executeRaw(['FUNCTION', 'FLUSH']);
$redis->function->flush();
$this->expectException(ServerException::class);
$this->expectExceptionMessage('ERR Library not found');
$redis->function->delete($this->libName);
}
/**
* @group connected
* @return void
* @requiresRedisVersion >= 7.0.0
*/
public function testKillThrowsExceptionOnNonExistingRunningScript(): void
{
$redis = $this->getClient();
$redis->function->flush();
$this->expectException(ServerException::class);
$this->expectExceptionMessage('NOTBUSY No scripts in execution right now.');
$redis->function->kill();
}
public function flushArgumentsProvider(): array
{
return [
'with default arguments' => [
['FLUSH', null],
['FLUSH'],
],
'with mode argument' => [
['FLUSH', 'sync'],
['FLUSH', 'SYNC'],
],
];
}
public function restoreArgumentsProvider(): array
{
return [
'with default arguments' => [
['RESTORE', 'value', null],
['RESTORE', 'value'],
],
'with mode argument' => [
['RESTORE', 'value', 'append'],
['RESTORE', 'value', 'APPEND'],
],
];
}
public function listArgumentsProvider(): array
{
return [
'with default arguments' => [
['LIST', null, false],
['LIST'],
],
'with LIBRARYNAME modifier' => [
['LIST', 'libraryname', false],
['LIST', 'LIBRARYNAME', 'libraryname'],
],
'with WITHCODE modifier' => [
['LIST', null, true],
['LIST', 'WITHCODE'],
],
'with all arguments' => [
['LIST', 'libraryname', true],
['LIST', 'LIBRARYNAME', 'libraryname', 'WITHCODE'],
],
];
}
}
@@ -60,6 +60,7 @@ class JSONARRAPPEND_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONARRINDEX_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONARRINSERT_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONARRLEN_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONARRPOP_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONARRTRIM_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONCLEAR_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -56,6 +56,7 @@ class JSONDEBUG_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONDEL_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONFORGET_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -59,6 +59,7 @@ class JSONGET_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonData
* @param string $key
@@ -101,6 +102,7 @@ class JSONGET_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider unexpectedValuesProvider
* @param array $arguments
* @param string $expectedExceptionMessage
@@ -57,6 +57,7 @@ class JSONMERGE_Test extends PredisCommandTestCase
/**
* @dataProvider jsonProvider
* @group connected
* @group relay-resp3
* @param array $setArguments
* @param array $mergeArguments
* @param string $expectedResponse
@@ -60,6 +60,7 @@ class JSONMGET_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $firstJson
* @param array $secondJson
@@ -57,6 +57,7 @@ class JSONMSET_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisJsonVersion >= 2.6.0
*/
@@ -70,6 +71,7 @@ class JSONMSET_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @return void
* @requiresRedisJsonVersion >= 2.6.0
*/
@@ -60,6 +60,7 @@ class JSONNUMINCRBY_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONOBJKEYS_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONOBJLEN_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -61,6 +61,7 @@ class JSONRESP_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -59,6 +59,7 @@ class JSONSET_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param string $key
* @param string $defaultJson
@@ -60,6 +60,7 @@ class JSONSTRAPPEND_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONSTRLEN_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONTOGGLE_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
@@ -60,6 +60,7 @@ class JSONTYPE_Test extends PredisCommandTestCase
/**
* @group connected
* @group relay-resp3
* @dataProvider jsonProvider
* @param array $jsonArguments
* @param string $key
+14 -1
View File
@@ -82,7 +82,7 @@ class OBJECT_Test extends PredisCommandTestCase
/**
* @group connected
* @requiresRedisVersion >= 2.2.3
* @requiresRedisVersion < 7.2.0
*/
public function testObjectEncoding(): void
{
@@ -92,6 +92,19 @@ class OBJECT_Test extends PredisCommandTestCase
$this->assertMatchesRegularExpression('/[zip|quick]list/', $redis->object('ENCODING', 'list:metavars'));
}
/**
* @group connected
* @requiresRedisVersion >= 7.2.0
*/
public function testObjectEncodingReturnsUpdatedResponse(): void
{
$redis = $this->getClient();
$redis->lpush('list:metavars', 'foo', 'bar');
$this->assertSame('listpack', $redis->object('ENCODING', 'list:metavars'));
}
/**
* @group connected
* @requiresRedisVersion >= 2.2.3
+13
View File
@@ -134,4 +134,17 @@ class SET_Test extends PredisCommandTestCase
$this->assertEquals('OK', $redis->set('foo', 'barbar', 'XX'));
$this->assertNull($redis->set('foofoo', 'barbar', 'XX'));
}
/**
* @group connected
* @group cluster
* @requiresRedisVersion >= 3.0.0
* @return void
*/
public function testSetStringValueInClusterMode(): void
{
$redis = $this->getClient();
$this->assertEquals('OK', $redis->set('foo', 'bar'));
}
}

Some files were not shown because too many files have changed in this diff Show More