From 9b7963be8abf23acb8bbc99aeda01579c2bd5707 Mon Sep 17 00:00:00 2001 From: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> Date: Thu, 18 May 2023 11:04:32 +0300 Subject: [PATCH] Add RESP3 response handle (#1298) * Add RESP3 response handle * Fix replication connection to return parameters of any connection role * Removed expectations on unstable error messages * Codestyle fixes --- src/Client.php | 7 ++- src/Command/Command.php | 8 +++ src/Command/CommandInterface.php | 8 +++ src/Command/RawCommand.php | 8 +++ src/Connection/Cluster/PredisCluster.php | 22 ++++++++ src/Connection/Cluster/RedisCluster.php | 22 ++++++++ src/Connection/ConnectionInterface.php | 7 +++ .../Replication/MasterSlaveReplication.php | 19 +++++++ .../Replication/SentinelReplication.php | 21 +++++++ src/Pipeline/Atomic.php | 7 ++- src/Pipeline/Pipeline.php | 7 ++- src/Transaction/MultiExec.php | 7 ++- tests/Predis/ClientTest.php | 55 +++++++++++++++++++ tests/Predis/Command/CommandTest.php | 11 ++++ .../Command/Redis/Search/FTINFO_Test.php | 1 - .../Redis/TimeSeries/TSDECRBY_Test.php | 1 - .../Redis/TimeSeries/TSINCRBY_Test.php | 1 - .../Command/Redis/TimeSeries/TSMADD_Test.php | 1 - .../Connection/Cluster/PredisClusterTest.php | 39 +++++++++++++ .../Connection/Cluster/RedisClusterTest.php | 42 ++++++++++++++ .../MasterSlaveReplicationTest.php | 22 ++++++++ .../Replication/SentinelReplicationTest.php | 36 ++++++++++++ tests/Predis/Monitor/ConsumerTest.php | 21 +++++++ tests/Predis/Pipeline/AtomicTest.php | 11 ++++ tests/Predis/Pipeline/PipelineTest.php | 34 ++++++++++++ tests/Predis/Transaction/MultiExecTest.php | 10 ++++ 26 files changed, 420 insertions(+), 8 deletions(-) diff --git a/src/Client.php b/src/Client.php index 91c126f4..66dfdc42 100644 --- a/src/Client.php +++ b/src/Client.php @@ -347,6 +347,7 @@ class Client implements ClientInterface, IteratorAggregate public function executeCommand(CommandInterface $command) { $response = $this->connection->executeCommand($command); + $parameters = $this->connection->getParameters(); if ($response instanceof ResponseInterface) { if ($response instanceof ErrorResponseInterface) { @@ -356,7 +357,11 @@ class Client implements ClientInterface, IteratorAggregate return $response; } - return $command->parseResponse($response); + if ($parameters->protocol === 2) { + return $command->parseResponse($response); + } + + return $command->parseResp3Response($response); } /** diff --git a/src/Command/Command.php b/src/Command/Command.php index 68629c45..280eb688 100644 --- a/src/Command/Command.php +++ b/src/Command/Command.php @@ -80,6 +80,14 @@ abstract class Command implements CommandInterface return $data; } + /** + * {@inheritdoc} + */ + public function parseResp3Response($data) + { + return $data; + } + /** * Normalizes the arguments array passed to a Redis command. * diff --git a/src/Command/CommandInterface.php b/src/Command/CommandInterface.php index 20480316..bd2d933b 100644 --- a/src/Command/CommandInterface.php +++ b/src/Command/CommandInterface.php @@ -77,4 +77,12 @@ interface CommandInterface * @return mixed */ public function parseResponse($data); + + /** + * Parses RESP3 protocol response and returns a PHP object. + * + * @param mixed $data + * @return mixed + */ + public function parseResp3Response($data); } diff --git a/src/Command/RawCommand.php b/src/Command/RawCommand.php index 61b22311..96143918 100644 --- a/src/Command/RawCommand.php +++ b/src/Command/RawCommand.php @@ -120,4 +120,12 @@ final class RawCommand implements CommandInterface { return $data; } + + /** + * {@inheritdoc} + */ + public function parseResp3Response($data) + { + return $data; + } } diff --git a/src/Connection/Cluster/PredisCluster.php b/src/Connection/Cluster/PredisCluster.php index 0ba29bb5..f1039dbb 100644 --- a/src/Connection/Cluster/PredisCluster.php +++ b/src/Connection/Cluster/PredisCluster.php @@ -19,6 +19,7 @@ use Predis\Cluster\PredisStrategy; use Predis\Cluster\StrategyInterface; use Predis\Command\CommandInterface; use Predis\Connection\NodeConnectionInterface; +use Predis\Connection\ParametersInterface; use Predis\NotSupportedException; use ReturnTypeWillChange; @@ -48,6 +49,11 @@ class PredisCluster implements ClusterInterface, IteratorAggregate, Countable */ private $distributor; + /** + * @var ParametersInterface + */ + private $connectionParameters; + /** * @param StrategyInterface $strategy Optional cluster strategy. */ @@ -98,6 +104,10 @@ class PredisCluster implements ClusterInterface, IteratorAggregate, Countable { $parameters = $connection->getParameters(); + if (!isset($this->connectionParameters)) { + $this->connectionParameters = $parameters; + } + $this->pool[(string) $connection] = $connection; if (isset($parameters->alias)) { @@ -120,6 +130,10 @@ class PredisCluster implements ClusterInterface, IteratorAggregate, Countable unset($this->aliases[$alias]); } + if (empty($this->pool) && isset($this->connectionParameters)) { + $this->connectionParameters = null; + } + return true; } @@ -240,4 +254,12 @@ class PredisCluster implements ClusterInterface, IteratorAggregate, Countable { return $this->getConnectionByCommand($command)->executeCommand($command); } + + /** + * {@inheritdoc} + */ + public function getParameters(): ?ParametersInterface + { + return $this->connectionParameters; + } } diff --git a/src/Connection/Cluster/RedisCluster.php b/src/Connection/Cluster/RedisCluster.php index e0376940..186ec883 100644 --- a/src/Connection/Cluster/RedisCluster.php +++ b/src/Connection/Cluster/RedisCluster.php @@ -25,6 +25,7 @@ use Predis\Command\RawCommand; use Predis\Connection\ConnectionException; use Predis\Connection\FactoryInterface; use Predis\Connection\NodeConnectionInterface; +use Predis\Connection\ParametersInterface; use Predis\NotSupportedException; use Predis\Response\Error as ErrorResponse; use Predis\Response\ErrorInterface as ErrorResponseInterface; @@ -63,6 +64,11 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable private $retryLimit = 5; private $retryInterval = 10; + /** + * @var ParametersInterface + */ + private $connectionParameters; + /** * @param FactoryInterface $connections Optional connection factory. * @param StrategyInterface $strategy Optional cluster strategy. @@ -149,6 +155,10 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable */ public function add(NodeConnectionInterface $connection) { + if (!isset($this->connectionParameters)) { + $this->connectionParameters = $connection->getParameters(); + } + $this->pool[(string) $connection] = $connection; $this->slotmap->reset(); } @@ -163,6 +173,10 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable $this->slots = array_diff($this->slots, [$connection]); unset($this->pool[$id]); + if (empty($this->pool) && isset($this->connectionParameters)) { + $this->connectionParameters = null; + } + return true; } @@ -669,4 +683,12 @@ class RedisCluster implements ClusterInterface, IteratorAggregate, Countable { $this->useClusterSlots = (bool) $value; } + + /** + * {@inheritdoc} + */ + public function getParameters(): ?ParametersInterface + { + return $this->connectionParameters; + } } diff --git a/src/Connection/ConnectionInterface.php b/src/Connection/ConnectionInterface.php index fc201461..69ffcae0 100644 --- a/src/Connection/ConnectionInterface.php +++ b/src/Connection/ConnectionInterface.php @@ -62,4 +62,11 @@ interface ConnectionInterface * @return mixed */ public function executeCommand(CommandInterface $command); + + /** + * Returns the parameters used to initialize the connection. + * + * @return ParametersInterface + */ + public function getParameters(); } diff --git a/src/Connection/Replication/MasterSlaveReplication.php b/src/Connection/Replication/MasterSlaveReplication.php index 9d57a5ac..fabc7c66 100644 --- a/src/Connection/Replication/MasterSlaveReplication.php +++ b/src/Connection/Replication/MasterSlaveReplication.php @@ -19,6 +19,7 @@ use Predis\Command\RawCommand; use Predis\Connection\ConnectionException; use Predis\Connection\FactoryInterface; use Predis\Connection\NodeConnectionInterface; +use Predis\Connection\ParametersInterface; use Predis\Replication\MissingMasterException; use Predis\Replication\ReplicationStrategy; use Predis\Response\ErrorInterface as ResponseErrorInterface; @@ -550,4 +551,22 @@ class MasterSlaveReplication implements ReplicationInterface { return ['master', 'slaves', 'pool', 'aliases', 'strategy']; } + + /** + * {@inheritdoc} + */ + public function getParameters(): ?ParametersInterface + { + if (isset($this->master)) { + return $this->master->getParameters(); + } + + $slave = $this->pickSlave(); + + if (null !== $slave) { + return $slave->getParameters(); + } + + return null; + } } diff --git a/src/Connection/Replication/SentinelReplication.php b/src/Connection/Replication/SentinelReplication.php index 13fbedb1..bbd1a0a2 100644 --- a/src/Connection/Replication/SentinelReplication.php +++ b/src/Connection/Replication/SentinelReplication.php @@ -20,6 +20,7 @@ use Predis\Connection\ConnectionException; use Predis\Connection\FactoryInterface as ConnectionFactoryInterface; use Predis\Connection\NodeConnectionInterface; use Predis\Connection\Parameters; +use Predis\Connection\ParametersInterface; use Predis\Replication\ReplicationStrategy; use Predis\Replication\RoleException; use Predis\Response\Error; @@ -771,4 +772,24 @@ class SentinelReplication implements ReplicationInterface 'master', 'slaves', 'pool', 'service', 'sentinels', 'connectionFactory', 'strategy', ]; } + + /** + * {@inheritdoc} + */ + public function getParameters(): ?ParametersInterface + { + if (isset($this->master)) { + return $this->master->getParameters(); + } + + if (!empty($this->slaves)) { + return $this->slaves[0]->getParameters(); + } + + if (!empty($this->sentinels)) { + return $this->sentinels[0]->getParameters(); + } + + return null; + } } diff --git a/src/Pipeline/Atomic.php b/src/Pipeline/Atomic.php index 09e19ead..e6387e01 100644 --- a/src/Pipeline/Atomic.php +++ b/src/Pipeline/Atomic.php @@ -97,13 +97,18 @@ class Atomic extends Pipeline $responses = []; $sizeOfPipe = count($commands); $exceptions = $this->throwServerExceptions(); + $protocolVersion = (int) $connection->getParameters()->protocol; for ($i = 0; $i < $sizeOfPipe; ++$i) { $command = $commands->dequeue(); $response = $executed[$i]; if (!$response instanceof ResponseInterface) { - $responses[] = $command->parseResponse($response); + if ($protocolVersion === 2) { + $responses[] = $command->parseResponse($response); + } else { + $responses[] = $command->parseResp3Response($response); + } } elseif ($response instanceof ErrorResponseInterface && $exceptions) { $this->exception($connection, $response); } else { diff --git a/src/Pipeline/Pipeline.php b/src/Pipeline/Pipeline.php index 3e1011f2..09b7c287 100644 --- a/src/Pipeline/Pipeline.php +++ b/src/Pipeline/Pipeline.php @@ -137,13 +137,18 @@ class Pipeline implements ClientContextInterface $responses = []; $exceptions = $this->throwServerExceptions(); + $protocolVersion = (int) $connection->getParameters()->protocol; while (!$commands->isEmpty()) { $command = $commands->dequeue(); $response = $connection->readResponse($command); if (!$response instanceof ResponseInterface) { - $responses[] = $command->parseResponse($response); + if ($protocolVersion === 2) { + $responses[] = $command->parseResponse($response); + } else { + $responses[] = $command->parseResp3Response($response); + } } elseif ($response instanceof ErrorResponseInterface && $exceptions) { $this->exception($connection, $response); } else { diff --git a/src/Transaction/MultiExec.php b/src/Transaction/MultiExec.php index 1f99d2a9..2793bad1 100644 --- a/src/Transaction/MultiExec.php +++ b/src/Transaction/MultiExec.php @@ -393,6 +393,7 @@ class MultiExec implements ClientContextInterface $response = []; $commands = $this->commands; $size = count($execResponse); + $protocolVersion = $this->client->getConnection()->getParameters()->protocol; if ($size !== count($commands)) { $this->onProtocolError('EXEC returned an unexpected number of response items.'); @@ -405,7 +406,11 @@ class MultiExec implements ClientContextInterface throw new ServerException($cmdResponse->getMessage()); } - $response[$i] = $commands->dequeue()->parseResponse($cmdResponse); + if ($protocolVersion === 2) { + $response[$i] = $commands->dequeue()->parseResponse($cmdResponse); + } else { + $response[$i] = $commands->dequeue()->parseResp3Response($cmdResponse); + } } return $response; diff --git a/tests/Predis/ClientTest.php b/tests/Predis/ClientTest.php index 04bac903..a8043538 100644 --- a/tests/Predis/ClientTest.php +++ b/tests/Predis/ClientTest.php @@ -17,6 +17,7 @@ use PHPUnit\Framework\MockObject\MockObject; use Predis\Command\Factory as CommandFactory; use Predis\Command\Processor\KeyPrefixProcessor; use Predis\Connection\NodeConnectionInterface; +use Predis\Connection\Parameters; use Predis\Connection\ParametersInterface; use Predis\Connection\Replication\MasterSlaveReplication; use PredisTestCase; @@ -548,12 +549,51 @@ class ClientTest extends PredisTestCase ['foo', 'bar', 'hoge', 'piyo'] ); + $connection + ->expects($this->exactly(2)) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $client = new Client($connection); $this->assertEquals('PONG', $client->executeCommand($ping)); $this->assertSame(['foo' => 'bar', 'hoge' => 'piyo'], $client->executeCommand($hgetall)); } + /** + * @group disconnected + */ + public function testExecuteCommandReturnsResp3ParsedResponses(): void + { + $commands = $this->getCommandFactory(); + + $ping = $commands->create('ping', []); + $get = $commands->create('get', []); + + $connection = $this->getMockBuilder('Predis\Connection\ConnectionInterface')->getMock(); + $connection + ->expects($this->exactly(2)) + ->method('executeCommand') + ->withConsecutive( + [$ping], + [$get] + ) + ->willReturnOnConsecutiveCalls( + new Response\Status('PONG'), + [] + ); + + $connection + ->expects($this->exactly(2)) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 3])); + + $client = new Client($connection); + + $this->assertEquals('PONG', $client->executeCommand($ping)); + $this->assertSame([], $client->executeCommand($get)); + } + /** * @group disconnected */ @@ -609,6 +649,11 @@ class ClientTest extends PredisTestCase ->with($this->isInstanceOf('Predis\Command\Redis\PING')) ->willReturn('PONG'); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $commands = $this->getMockBuilder('Predis\Command\FactoryInterface')->getMock(); $commands ->expects($this->once()) @@ -1159,6 +1204,11 @@ class ClientTest extends PredisTestCase public function testMonitorReturnsMonitorConsumer(): void { $connection = $this->getMockBuilder('Predis\Connection\NodeConnectionInterface')->getMock(); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $client = new Client($connection); $this->assertInstanceOf('Predis\Monitor\Consumer', $monitor = $client->monitor()); @@ -1195,6 +1245,11 @@ class ClientTest extends PredisTestCase 'OK' ); + $connection + ->expects($this->exactly(2)) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $client = new Client($connection); $this->assertTrue($client->executeCommand($command)); diff --git a/tests/Predis/Command/CommandTest.php b/tests/Predis/Command/CommandTest.php index 00121c5c..537f8154 100644 --- a/tests/Predis/Command/CommandTest.php +++ b/tests/Predis/Command/CommandTest.php @@ -92,6 +92,17 @@ class CommandTest extends PredisTestCase $this->assertEquals($response, $command->parseResponse($response)); } + /** + * @group disconnected + */ + public function testParseResp3Response(): void + { + $response = 'response-buffer'; + $command = $this->getMockForAbstractClass('Predis\Command\Command'); + + $this->assertEquals($response, $command->parseResp3Response($response)); + } + /** * @group disconnected */ diff --git a/tests/Predis/Command/Redis/Search/FTINFO_Test.php b/tests/Predis/Command/Redis/Search/FTINFO_Test.php index 04a5c9d4..e3c02d53 100644 --- a/tests/Predis/Command/Redis/Search/FTINFO_Test.php +++ b/tests/Predis/Command/Redis/Search/FTINFO_Test.php @@ -93,7 +93,6 @@ class FTINFO_Test extends PredisCommandTestCase $redis = $this->getClient(); $this->expectException(ServerException::class); - $this->expectExceptionMessage('Unknown index name'); $redis->ftinfo('index'); } diff --git a/tests/Predis/Command/Redis/TimeSeries/TSDECRBY_Test.php b/tests/Predis/Command/Redis/TimeSeries/TSDECRBY_Test.php index 4edaeaf7..d7be5538 100644 --- a/tests/Predis/Command/Redis/TimeSeries/TSDECRBY_Test.php +++ b/tests/Predis/Command/Redis/TimeSeries/TSDECRBY_Test.php @@ -143,7 +143,6 @@ class TSDECRBY_Test extends PredisCommandTestCase ); $this->expectException(ServerException::class); - $this->expectExceptionMessage('TSDB: timestamp must be equal to or higher than the maximum existing timestamp'); $redis->tsdecrby('temperature:2:32', 27, (new DecrByArguments())->timestamp(123123123122)); } diff --git a/tests/Predis/Command/Redis/TimeSeries/TSINCRBY_Test.php b/tests/Predis/Command/Redis/TimeSeries/TSINCRBY_Test.php index c369ac2d..b44aa213 100644 --- a/tests/Predis/Command/Redis/TimeSeries/TSINCRBY_Test.php +++ b/tests/Predis/Command/Redis/TimeSeries/TSINCRBY_Test.php @@ -143,7 +143,6 @@ class TSINCRBY_Test extends PredisCommandTestCase ); $this->expectException(ServerException::class); - $this->expectExceptionMessage('TSDB: timestamp must be equal to or higher than the maximum existing timestamp'); $redis->tsincrby('temperature:2:32', 27, (new IncrByArguments())->timestamp(123123123122)); } diff --git a/tests/Predis/Command/Redis/TimeSeries/TSMADD_Test.php b/tests/Predis/Command/Redis/TimeSeries/TSMADD_Test.php index 246ca6b7..4f258795 100644 --- a/tests/Predis/Command/Redis/TimeSeries/TSMADD_Test.php +++ b/tests/Predis/Command/Redis/TimeSeries/TSMADD_Test.php @@ -97,7 +97,6 @@ class TSMADD_Test extends PredisCommandTestCase $redis = $this->getClient(); $this->expectException(ServerException::class); - $this->expectExceptionMessage("ERR wrong number of arguments for 'ts.madd' command"); $redis->tsmadd('temperature:2:32', 123123123123, 27, 'temperature:2:33', 123123123124); } diff --git a/tests/Predis/Connection/Cluster/PredisClusterTest.php b/tests/Predis/Connection/Cluster/PredisClusterTest.php index 80f37f82..af8829b0 100644 --- a/tests/Predis/Connection/Cluster/PredisClusterTest.php +++ b/tests/Predis/Connection/Cluster/PredisClusterTest.php @@ -12,6 +12,8 @@ namespace Predis\Connection\Cluster; +use Predis\Connection\Parameters; +use Predis\Connection\ParametersInterface; use PredisTestCase; class PredisClusterTest extends PredisTestCase @@ -83,6 +85,24 @@ class PredisClusterTest extends PredisTestCase $this->assertCount(1, $cluster); } + /** + * @group disconnected + */ + public function testRemoveConnectionsUnsetParametersOnEmptyConnectionPool(): void + { + $connection = $this->getMockConnection('tcp://127.0.0.1:7001?alias=node01'); + + $cluster = new PredisCluster(); + + $cluster->add($connection); + + $this->assertInstanceOf(ParametersInterface::class, $cluster->getParameters()); + + $cluster->remove($connection); + + $this->assertNull($cluster->getParameters()); + } + /** * @group disconnected */ @@ -413,4 +433,23 @@ class PredisClusterTest extends PredisTestCase $this->assertEquals($cluster, $unserialized); } + + /** + * @group disconnected + */ + public function testGetParameters(): void + { + $connection = $this->getMockConnection('tcp://127.0.0.1:7001?protocol=3'); + $expectedParameters = new Parameters([ + 'scheme' => 'tcp', + 'host' => '127.0.0.1', + 'port' => 7001, + 'protocol' => '3', + ]); + + $cluster = new PredisCluster(); + $cluster->add($connection); + + $this->assertEquals($expectedParameters, $cluster->getParameters()); + } } diff --git a/tests/Predis/Connection/Cluster/RedisClusterTest.php b/tests/Predis/Connection/Cluster/RedisClusterTest.php index 7cf28a66..47a6342c 100644 --- a/tests/Predis/Connection/Cluster/RedisClusterTest.php +++ b/tests/Predis/Connection/Cluster/RedisClusterTest.php @@ -16,6 +16,8 @@ use PHPUnit\Framework\MockObject\MockObject; use Predis\Cluster; use Predis\Command; use Predis\Connection; +use Predis\Connection\Parameters; +use Predis\Connection\ParametersInterface; use Predis\Response; use PredisTestCase; @@ -93,6 +95,25 @@ class RedisClusterTest extends PredisTestCase $this->assertCount(1, $cluster); } + /** + * @group disconnected + */ + public function testRemoveConnectionsUnsetParametersOnEmptyConnectionPool(): void + { + $factory = $this->getMockBuilder('Predis\Connection\FactoryInterface')->getMock(); + $connection = $this->getMockConnection('tcp://127.0.0.1:7001?alias=node01'); + + $cluster = new RedisCluster($factory); + + $cluster->add($connection); + + $this->assertInstanceOf(ParametersInterface::class, $cluster->getParameters()); + + $cluster->remove($connection); + + $this->assertNull($cluster->getParameters()); + } + /** * @group disconnected */ @@ -1438,4 +1459,25 @@ class RedisClusterTest extends PredisTestCase $this->assertCount(16384, $cluster->getSlotMap()); } + + /** + * @group disconnected + */ + public function testGetParameters(): void + { + $connection = $this->getMockConnection('tcp://127.0.0.1:7001?protocol=3'); + $factory = $this->getMockBuilder('Predis\Connection\FactoryInterface')->getMock(); + + $expectedParameters = new Parameters([ + 'scheme' => 'tcp', + 'host' => '127.0.0.1', + 'port' => 7001, + 'protocol' => '3', + ]); + + $cluster = new RedisCluster($factory); + $cluster->add($connection); + + $this->assertEquals($expectedParameters, $cluster->getParameters()); + } } diff --git a/tests/Predis/Connection/Replication/MasterSlaveReplicationTest.php b/tests/Predis/Connection/Replication/MasterSlaveReplicationTest.php index 0aea2273..2d35c7fa 100644 --- a/tests/Predis/Connection/Replication/MasterSlaveReplicationTest.php +++ b/tests/Predis/Connection/Replication/MasterSlaveReplicationTest.php @@ -1436,4 +1436,26 @@ repl_backlog_histlen:12978 $this->assertEquals($master, $unserialized->getConnectionByRole('master')); $this->assertEquals($slave1, $unserialized->getConnectionByRole('slave')); } + + /** + * @dataProvider connectionsProvider + * @group disconnected + */ + public function testGetParameters(string $connection): void + { + $connection = $this->getMockConnection($connection); + + $replication = new MasterSlaveReplication(); + $replication->add($connection); + + $this->assertSame($connection->getParameters(), $replication->getParameters()); + } + + public function connectionsProvider(): array + { + return [ + 'master connection' => ['tcp://127.0.0.1:6379?role=master'], + 'slave connection' => ['tcp://127.0.0.1:6379'], + ]; + } } diff --git a/tests/Predis/Connection/Replication/SentinelReplicationTest.php b/tests/Predis/Connection/Replication/SentinelReplicationTest.php index 1dcc532c..8fdfd619 100644 --- a/tests/Predis/Connection/Replication/SentinelReplicationTest.php +++ b/tests/Predis/Connection/Replication/SentinelReplicationTest.php @@ -1517,6 +1517,42 @@ class SentinelReplicationTest extends PredisTestCase $replication->updateSentinels(); } + /** + * @dataProvider connectionsProvider + * @group disconnected + */ + public function testGetParameters(string $connection): void + { + $sentinel = $this->getMockSentinelConnection('tcp://127.0.0.1:5381?role=sentinel'); + $connection = $this->getMockConnection($connection); + + $replication = $this->getReplicationConnection('srv', [$sentinel]); + $replication->add($connection); + + $this->assertSame($connection->getParameters(), $replication->getParameters()); + } + + /** + * @group disconnected + * @return void + */ + public function testGetParametersReturnsSentinelParametersOnEmptyConnectionPool(): void + { + $sentinel = $this->getMockSentinelConnection('tcp://127.0.0.1:5381?role=sentinel'); + + $replication = $this->getReplicationConnection('srv', [$sentinel]); + + $this->assertSame($sentinel->getParameters(), $replication->getParameters()); + } + + public function connectionsProvider(): array + { + return [ + 'master connection' => ['tcp://127.0.0.1:6379?role=master'], + 'slave connection' => ['tcp://127.0.0.1:6379'], + ]; + } + // ******************************************************************** // // ---- HELPER METHODS ------------------------------------------------ // // ******************************************************************** // diff --git a/tests/Predis/Monitor/ConsumerTest.php b/tests/Predis/Monitor/ConsumerTest.php index 4fb8b2f5..8e9288dc 100644 --- a/tests/Predis/Monitor/ConsumerTest.php +++ b/tests/Predis/Monitor/ConsumerTest.php @@ -13,6 +13,7 @@ namespace Predis\Monitor; use Predis\Client; +use Predis\Connection\Parameters; use Predis\Monitor\Consumer as MonitorConsumer; use PredisTestCase; @@ -92,6 +93,11 @@ class ConsumerTest extends PredisTestCase { $connection = $this->getMockBuilder('Predis\Connection\NodeConnectionInterface')->getMock(); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + /** @var \Predis\ClientInterface */ $client = $this->getMockBuilder('Predis\Client') ->onlyMethods(['disconnect']) @@ -113,6 +119,11 @@ class ConsumerTest extends PredisTestCase { $connection = $this->getMockBuilder('Predis\Connection\NodeConnectionInterface')->getMock(); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + /** @var \Predis\ClientInterface */ $client = $this->getMockBuilder('Predis\Client') ->onlyMethods(['disconnect']) @@ -140,6 +151,11 @@ class ConsumerTest extends PredisTestCase ->method('read') ->willReturn($message); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $client = new Client($connection); $monitor = new MonitorConsumer($client); @@ -165,6 +181,11 @@ class ConsumerTest extends PredisTestCase ->method('read') ->willReturn($message); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $client = new Client($connection); $monitor = new MonitorConsumer($client); diff --git a/tests/Predis/Pipeline/AtomicTest.php b/tests/Predis/Pipeline/AtomicTest.php index ef0830a1..a2ab7ab0 100644 --- a/tests/Predis/Pipeline/AtomicTest.php +++ b/tests/Predis/Pipeline/AtomicTest.php @@ -13,6 +13,7 @@ namespace Predis\Pipeline; use Predis\Client; +use Predis\Connection\Parameters; use Predis\Response; use PredisTestCase; @@ -55,6 +56,11 @@ class AtomicTest extends PredisTestCase $queued ); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $pipeline = new Atomic(new Client($connection)); $pipeline->ping(); @@ -241,6 +247,11 @@ class AtomicTest extends PredisTestCase $queued ); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $pipeline = new Atomic(new Client($connection, ['exceptions' => false])); $pipeline->ping(); diff --git a/tests/Predis/Pipeline/PipelineTest.php b/tests/Predis/Pipeline/PipelineTest.php index 74ded602..3fafe1ab 100644 --- a/tests/Predis/Pipeline/PipelineTest.php +++ b/tests/Predis/Pipeline/PipelineTest.php @@ -18,6 +18,7 @@ use Predis\Client; use Predis\ClientException; use Predis\ClientInterface; use Predis\Command\CommandInterface; +use Predis\Connection\Parameters; use Predis\Response; use PredisTestCase; use stdClass; @@ -87,6 +88,11 @@ class PipelineTest extends PredisTestCase ->method('readResponse') ->willReturn($object); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $pipeline = new Pipeline(new Client($connection)); $pipeline->ping(); @@ -110,6 +116,11 @@ class PipelineTest extends PredisTestCase ->method('readResponse') ->willReturn($error); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $pipeline = new Pipeline(new Client($connection)); $pipeline->ping(); @@ -131,6 +142,11 @@ class PipelineTest extends PredisTestCase ->method('readResponse') ->willReturn($error); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $client = new Client($connection, ['exceptions' => false]); $pipeline = new Pipeline($client); @@ -208,6 +224,11 @@ class PipelineTest extends PredisTestCase ->method('readResponse') ->willReturnCallback($this->getReadCallback()); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $pipeline = new Pipeline(new Client($connection)); $pipeline->echo('one'); @@ -249,6 +270,11 @@ class PipelineTest extends PredisTestCase ->method('readResponse') ->willReturnCallback($this->getReadCallback()); + $connection + ->expects($this->exactly(2)) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $pipeline = new Pipeline(new Client($connection)); $pipeline->echo('one'); @@ -278,6 +304,10 @@ class PipelineTest extends PredisTestCase ->expects($this->exactly(3)) ->method('readResponse') ->willReturn($pong); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); $pipeline = new Pipeline(new Client($connection)); @@ -344,6 +374,10 @@ class PipelineTest extends PredisTestCase ->expects($this->exactly(4)) ->method('readResponse') ->willReturnCallback($this->getReadCallback()); + $connection + ->expects($this->once()) + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); $pipeline = new Pipeline(new Client($connection)); diff --git a/tests/Predis/Transaction/MultiExecTest.php b/tests/Predis/Transaction/MultiExecTest.php index e42d0251..6fa316a2 100644 --- a/tests/Predis/Transaction/MultiExecTest.php +++ b/tests/Predis/Transaction/MultiExecTest.php @@ -18,6 +18,7 @@ use Predis\Client; use Predis\ClientInterface; use Predis\Command\CommandInterface; use Predis\Connection\NodeConnectionInterface; +use Predis\Connection\Parameters; use Predis\Response; use PredisTestCase; use RuntimeException; @@ -850,6 +851,10 @@ class MultiExecTest extends PredisTestCase ->method('executeCommand') ->willReturnCallback($executeCallback); + $connection + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + return $connection; } @@ -867,6 +872,11 @@ class MultiExecTest extends PredisTestCase protected function getMockedTransaction($executeCallback, $txOpts = null, $clientOpts = null): MultiExec { $connection = $this->getMockedConnection($executeCallback); + + $connection + ->method('getParameters') + ->willReturn(new Parameters(['protocol' => 2])); + $client = new Client($connection, $clientOpts ?: []); $transaction = new MultiExec($client, $txOpts ?: []);