diff --git a/src/Connection/AbstractConnection.php b/src/Connection/AbstractConnection.php index e8be6c62..fd77050e 100644 --- a/src/Connection/AbstractConnection.php +++ b/src/Connection/AbstractConnection.php @@ -14,6 +14,7 @@ namespace Predis\Connection; use InvalidArgumentException; use Predis\Command\CommandInterface; +use Predis\Command\RawCommand; use Predis\CommunicationException; use Predis\Protocol\Parser\ParserStrategyResolver; use Predis\Protocol\Parser\Strategy\ParserStrategyInterface; @@ -34,6 +35,10 @@ abstract class AbstractConnection implements NodeConnectionInterface private $cachedId; protected $parameters; + + /** + * @var RawCommand[] + */ protected $initCommands = []; /** diff --git a/src/Connection/Factory.php b/src/Connection/Factory.php index 411a0d7b..6b93c7b6 100644 --- a/src/Connection/Factory.php +++ b/src/Connection/Factory.php @@ -13,6 +13,7 @@ namespace Predis\Connection; use InvalidArgumentException; +use Predis\Client; use Predis\Command\RawCommand; use ReflectionClass; use UnexpectedValueException; @@ -173,6 +174,16 @@ class Factory implements FactoryInterface ); } + if (!$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->protocol) && (int) $parameters->protocol > 2) { $connection->addConnectCommand( new RawCommand('HELLO', [$parameters->protocol, 'SETNAME', 'predis']) diff --git a/src/Connection/StreamConnection.php b/src/Connection/StreamConnection.php index 8fc60688..8150a583 100644 --- a/src/Connection/StreamConnection.php +++ b/src/Connection/StreamConnection.php @@ -235,7 +235,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); } } diff --git a/tests/Predis/ClientTest.php b/tests/Predis/ClientTest.php index 11e5e6c7..8a8d26bc 100644 --- a/tests/Predis/ClientTest.php +++ b/tests/Predis/ClientTest.php @@ -1308,6 +1308,20 @@ class ClientTest extends PredisTestCase $this->assertSame('127.0.0.1:6381', $iterator->key()); } + /** + * @group connected + * @requiresRedisVersion >= 7.2.0 + */ + public function testSetClientInfoOnConnection(): void + { + $client = new Client($this->getParameters()); + $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 ------------------------------------------------ // // ******************************************************************** // diff --git a/tests/Predis/Connection/FactoryTest.php b/tests/Predis/Connection/FactoryTest.php index 59f58eed..c0ac90ab 100644 --- a/tests/Predis/Connection/FactoryTest.php +++ b/tests/Predis/Connection/FactoryTest.php @@ -12,6 +12,7 @@ namespace Predis\Connection; +use Predis\Client; use Predis\Command\RawCommand; use PredisTestCase; use ReflectionObject; @@ -303,10 +304,12 @@ class FactoryTest extends PredisTestCase ->method('getParameters') ->willReturn($parameters); $connection - ->expects($this->exactly(2)) + ->expects($this->exactly(4)) ->method('addConnectCommand') ->withConsecutive( [$this->isRedisCommand('AUTH', ['foobar'])], + [$this->isRedisCommand('CLIENT', ['SETINFO', 'LIB-NAME', 'predis'])], + [$this->isRedisCommand('CLIENT', ['SETINFO', 'LIB-VER', Client::VERSION])], [$this->isRedisCommand('SELECT', ['0'])] ); @@ -332,9 +335,13 @@ class FactoryTest extends PredisTestCase $connection->expects($this->once()) ->method('getParameters') ->will($this->returnValue($parameters)); - $connection->expects($this->once()) + $connection->expects($this->exactly(3)) ->method('addConnectCommand') - ->with($this->isRedisCommand('AUTH', ['foobar'])); + ->withConsecutive( + [$this->isRedisCommand('AUTH', ['foobar'])], + [$this->isRedisCommand('CLIENT', ['SETINFO', 'LIB-NAME', 'predis'])], + [$this->isRedisCommand('CLIENT', ['SETINFO', 'LIB-VER', Client::VERSION])] + ); $factory = new Factory(); @@ -359,9 +366,13 @@ class FactoryTest extends PredisTestCase $connection->expects($this->once()) ->method('getParameters') ->will($this->returnValue($parameters)); - $connection->expects($this->once()) + $connection->expects($this->exactly(3)) ->method('addConnectCommand') - ->with($this->isRedisCommand('AUTH', ['myusername', 'foobar'])); + ->withConsecutive( + [$this->isRedisCommand('AUTH', ['myusername', 'foobar'])], + [$this->isRedisCommand('CLIENT', ['SETINFO', 'LIB-NAME', 'predis'])], + [$this->isRedisCommand('CLIENT', ['SETINFO', 'LIB-VER', Client::VERSION])] + ); $factory = new Factory(); @@ -385,8 +396,12 @@ class FactoryTest extends PredisTestCase $connection->expects($this->once()) ->method('getParameters') ->will($this->returnValue($parameters)); - $connection->expects($this->never()) - ->method('addConnectCommand'); + $connection->expects($this->exactly(2)) + ->method('addConnectCommand') + ->withConsecutive( + [$this->isRedisCommand('CLIENT', ['SETINFO', 'LIB-NAME', 'predis'])], + [$this->isRedisCommand('CLIENT', ['SETINFO', 'LIB-VER', Client::VERSION])] + ); $factory = new Factory(); @@ -411,8 +426,12 @@ class FactoryTest extends PredisTestCase $connection->expects($this->once()) ->method('getParameters') ->will($this->returnValue($parameters)); - $connection->expects($this->never()) - ->method('addConnectCommand'); + $connection->expects($this->exactly(2)) + ->method('addConnectCommand') + ->withConsecutive( + [$this->isRedisCommand('CLIENT', ['SETINFO', 'LIB-NAME', 'predis'])], + [$this->isRedisCommand('CLIENT', ['SETINFO', 'LIB-VER', Client::VERSION])] + ); $factory = new Factory(); @@ -539,6 +558,27 @@ class FactoryTest extends PredisTestCase $factory->create('test://127.0.0.1'); } + /** + * @group disconnected + * @return void + */ + public function testSetClientNameAndVersionOnConnection(): void + { + $parameters = []; + + $factory = new Factory(); + $connection = $factory->create($parameters); + $initCommands = $connection->getInitCommands(); + + $this->assertInstanceOf(RawCommand::class, $initCommands[0]); + $this->assertSame('CLIENT', $initCommands[0]->getId()); + $this->assertSame(['SETINFO', 'LIB-NAME', 'predis'], $initCommands[0]->getArguments()); + + $this->assertInstanceOf(RawCommand::class, $initCommands[1]); + $this->assertSame('CLIENT', $initCommands[1]->getId()); + $this->assertSame(['SETINFO', 'LIB-VER', Client::VERSION], $initCommands[1]->getArguments()); + } + /** * @group disconnected * @return void @@ -552,7 +592,7 @@ class FactoryTest extends PredisTestCase $initCommands = $connection->getInitCommands(); $this->assertInstanceOf(RawCommand::class, $initCommands[0]); - $this->assertSame('HELLO', $initCommands[0]->getId()); + $this->assertSame('HELLO', $initCommands[2]->getId()); } // ******************************************************************** // diff --git a/tests/Predis/Connection/StreamConnectionTest.php b/tests/Predis/Connection/StreamConnectionTest.php index ffcbf5d1..99f5b0e8 100644 --- a/tests/Predis/Connection/StreamConnectionTest.php +++ b/tests/Predis/Connection/StreamConnectionTest.php @@ -13,6 +13,7 @@ namespace Predis\Connection; use PHPUnit\Framework\MockObject\MockObject; +use Predis\Client; use Predis\Command\RawCommand; use Predis\Response\Error as ErrorResponse; @@ -196,6 +197,24 @@ class StreamConnectionTest extends PredisConnectionTestCase $this->assertFalse($options['socket']['tcp_nodelay']); } + /** + * @group connected + * @requiresRedisVersion < 7.0.0 + */ + public function testConnectDoNotThrowsExceptionOnClientCommandError(): void + { + $connection = $this->createConnectionWithParams([]); + $connection->addConnectCommand( + new RawCommand('CLIENT', ['SETINFO', 'LIB-NAME', 'predis']) + ); + $connection->addConnectCommand( + new RawCommand('CLIENT', ['SETINFO', 'LIB-VER', Client::VERSION]) + ); + + $connection->connect(); + $this->assertTrue(true); + } + /** * @group disconnected * @return void