diff --git a/.gitattributes b/.gitattributes index f39ca25e..e702f711 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,6 +1,8 @@ * text=auto -/tests export-ignore +/tests/PHPUnit export-ignore +/tests/Predis export-ignore +/tests/bootstrap.php export-ignore /.editorconfig export-ignore /.gitattributes export-ignore /.gitignore export-ignore diff --git a/CHANGELOG.md b/CHANGELOG.md index ae59606d..24a97d7d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,31 @@ +v1.1.4 (2020-xx-xx) +================================================================================ + +- __FIX__: initializing an iteration over a client instance when it is connected + to a standalone Redis server will not throw an exception anymore, instead it + will return an iterator that will run for just one loop returning a new client + instance using the underlying single-node connection (ISSUE #552, PR #556). + +- __FIX__: `Predis\Cluster\Distributor\HashRingaddNodeToRing()` was calculating + the hash required for distribution by using `crc32()` directly instead of the + method `Predis\Cluster\Hash\HashGeneratorInterface::hash()` implemented by the + class itself. This bug fix does not have any impact on existing clusters that + use client-side sharding based on this distributor simply because it does not + take any external hash generators so distribution is not going to be affected. + + +v1.1.3 (2020-08-18) +================================================================================ + +- Ensure compatibility with PHP 8. + +- Moved repository from `github.com/nrk/predis` to `github.com/predis/predis`. + +- __FIX__: Moved `cweagans/composer-patches` dependency to `require-dev`. + +- __FIX__: Include PHPUnit `.patch` files in exports. + + v1.1.2 (2020-08-11) ================================================================================ diff --git a/src/Client.php b/src/Client.php index 6e492f81..795bbbd4 100644 --- a/src/Client.php +++ b/src/Client.php @@ -535,7 +535,9 @@ class Client implements ClientInterface, \IteratorAggregate $connection = $this->getConnection(); if (!$connection instanceof \Traversable) { - throw new ClientException('The underlying connection is not traversable'); + return new \ArrayIterator(array( + (string) $connection => new static($connection, $this->getOptions()) + )); } foreach ($connection as $node) { diff --git a/src/Cluster/Distributor/HashRing.php b/src/Cluster/Distributor/HashRing.php index db864d91..a0c7ae80 100644 --- a/src/Cluster/Distributor/HashRing.php +++ b/src/Cluster/Distributor/HashRing.php @@ -161,7 +161,7 @@ class HashRing implements DistributorInterface, HashGeneratorInterface $replicas = (int) round($weightRatio * $totalNodes * $replicas); for ($i = 0; $i < $replicas; ++$i) { - $key = crc32("$nodeHash:$i"); + $key = $this->hash("$nodeHash:$i"); $ring[$key] = $nodeObject; } } diff --git a/tests/Predis/ClientTest.php b/tests/Predis/ClientTest.php index 93ef909f..865a8657 100644 --- a/tests/Predis/ClientTest.php +++ b/tests/Predis/ClientTest.php @@ -853,15 +853,17 @@ class ClientTest extends PredisTestCase /** * @group disconnected - * @expectedException \Predis\ClientException - * @expectedExceptionMessage The underlying connection is not traversable */ - public function testGetIteratorWithNonTraversableConnectionThrowsException() + public function testGetIteratorWithNonTraversableConnectionNoException() { - $connection = $this->getMock('Predis\Connection\NodeConnectionInterface'); + $connection = $this->getMockConnection('tcp://127.0.0.1:6381'); $client = new Client($connection); - $client->getIterator(); + $iterator = $client->getIterator(); + + $this->assertInstanceOf('\Predis\Client', $nodeClient = $iterator->current()); + $this->assertSame($connection, $nodeClient->getConnection()); + $this->assertSame('127.0.0.1:6381', $iterator->key()); } // ******************************************************************** // diff --git a/tests/Predis/Command/ServerCommandTest.php b/tests/Predis/Command/ServerCommandTest.php index a4aa4080..c89a8283 100644 --- a/tests/Predis/Command/ServerCommandTest.php +++ b/tests/Predis/Command/ServerCommandTest.php @@ -102,13 +102,24 @@ class ServerCommandTest extends PredisCommandTestCase { $redis = $this->getClient(); + $expected = array(array('get', 2, array('readonly', 'fast'), 1, 1, 1)); + + // NOTE: starting with Redis 6.0 and the introduction of Access Control + // Lists, COMMAND INFO returns an additional array for each specified + // command in yhe request with a list of the ACL categories associated + // to a command. We simply append this additional array in the expected + // response if the test suite is executed against Redis >= 6.0. + if ($this->isRedisServerVersion('>=', '6.0')) { + $expected[0][] = array('@read', '@string', '@fast'); + } + + $this->assertCount(1, $response = $redis->command('INFO', 'GET')); + // NOTE: we use assertEquals instead of assertSame because Redis returns // flags as +STATUS responses, represented by Predis with instances of // Predis\Response\Status instead of plain strings. This class responds // to __toString() so the string conversion is implicit, but assertSame // checks for strict equality while assertEquals is loose. - $expected = array(array('get', 2, array('readonly', 'fast'), 1, 1, 1)); - $this->assertCount(1, $response = $redis->command('INFO', 'GET')); $this->assertEquals($expected, $response); }