KetamaRingTest.php 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. <?php
  2. /*
  3. * This file is part of the Predis package.
  4. *
  5. * (c) Daniele Alessandri <suppakilla@gmail.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Predis\Cluster\Distributor;
  11. /**
  12. *
  13. */
  14. class KetamaRingTest extends PredisDistributorTestCase
  15. {
  16. /**
  17. * {@inheritdoc}
  18. */
  19. public function getDistributorInstance()
  20. {
  21. return new KetamaRing();
  22. }
  23. /**
  24. * @group disconnected
  25. */
  26. public function testHash()
  27. {
  28. $ring = $this->getDistributorInstance();
  29. list(, $hash) = unpack('V', md5('foobar', true));
  30. $this->assertEquals($hash, $ring->hash('foobar'));
  31. }
  32. /**
  33. * @group disconnected
  34. */
  35. public function testSingleNodeInRing()
  36. {
  37. $node = '127.0.0.1:7000';
  38. $ring = $this->getDistributorInstance();
  39. $ring->add($node);
  40. $expected = array_fill(0, 20, $node);
  41. $actual = $this->getNodes($ring, 20);
  42. $this->assertSame($expected, $actual);
  43. }
  44. /**
  45. * @group disconnected
  46. */
  47. public function testMultipleNodesInRing()
  48. {
  49. $ring = $this->getSampleDistribution(array(
  50. '127.0.0.1:7000',
  51. '127.0.0.1:7001',
  52. '127.0.0.1:7002',
  53. ));
  54. $expected = array(
  55. '127.0.0.1:7000',
  56. '127.0.0.1:7001',
  57. '127.0.0.1:7000',
  58. '127.0.0.1:7002',
  59. '127.0.0.1:7000',
  60. '127.0.0.1:7001',
  61. '127.0.0.1:7000',
  62. '127.0.0.1:7001',
  63. '127.0.0.1:7000',
  64. '127.0.0.1:7002',
  65. '127.0.0.1:7000',
  66. '127.0.0.1:7000',
  67. '127.0.0.1:7001',
  68. '127.0.0.1:7000',
  69. '127.0.0.1:7001',
  70. '127.0.0.1:7002',
  71. '127.0.0.1:7000',
  72. '127.0.0.1:7002',
  73. '127.0.0.1:7001',
  74. '127.0.0.1:7002',
  75. );
  76. $actual = $this->getNodes($ring, 20);
  77. $this->assertSame($expected, $actual);
  78. }
  79. /**
  80. * @group disconnected
  81. */
  82. public function testSubsequendAddAndRemoveFromRing()
  83. {
  84. $ring = $this->getDistributorInstance();
  85. $expected1 = array_fill(0, 10, '127.0.0.1:7000');
  86. $expected3 = array_fill(0, 10, '127.0.0.1:7001');
  87. $expected2 = array(
  88. '127.0.0.1:7000',
  89. '127.0.0.1:7001',
  90. '127.0.0.1:7000',
  91. '127.0.0.1:7001',
  92. '127.0.0.1:7000',
  93. '127.0.0.1:7001',
  94. '127.0.0.1:7000',
  95. '127.0.0.1:7001',
  96. '127.0.0.1:7000',
  97. '127.0.0.1:7001',
  98. );
  99. $ring->add('127.0.0.1:7000');
  100. $actual1 = $this->getNodes($ring, 10);
  101. $ring->add('127.0.0.1:7001');
  102. $actual2 = $this->getNodes($ring, 10);
  103. $ring->remove('127.0.0.1:7000');
  104. $actual3 = $this->getNodes($ring, 10);
  105. $this->assertSame($expected1, $actual1);
  106. $this->assertSame($expected2, $actual2);
  107. $this->assertSame($expected3, $actual3);
  108. }
  109. /**
  110. * @group disconnected
  111. */
  112. public function testGetByValue()
  113. {
  114. $ring = $this->getSampleDistribution(array(
  115. '127.0.0.1:7000',
  116. '127.0.0.1:7001',
  117. '127.0.0.1:7002',
  118. ));
  119. $this->assertSame('127.0.0.1:7001', $ring->get('uid:256'));
  120. $this->assertSame('127.0.0.1:7002', $ring->get('uid:281'));
  121. $this->assertSame('127.0.0.1:7001', $ring->get('uid:312'));
  122. $this->assertSame('127.0.0.1:7000', $ring->get('uid:432'));
  123. $this->assertSame('127.0.0.1:7000', $ring->get('uid:500'));
  124. $this->assertSame('127.0.0.1:7002', $ring->get('uid:641'));
  125. }
  126. /**
  127. * @group disconnected
  128. */
  129. public function testGetByHash()
  130. {
  131. $ring = $this->getSampleDistribution(array(
  132. '127.0.0.1:7000',
  133. '127.0.0.1:7001',
  134. '127.0.0.1:7002',
  135. ));
  136. $this->assertSame('127.0.0.1:7001', $ring->getByHash(PHP_INT_SIZE == 4 ? -591277534 : 3703689762)); // uid:256
  137. $this->assertSame('127.0.0.1:7002', $ring->getByHash(PHP_INT_SIZE == 4 ? -1632011260 : 2662956036)); // uid:281
  138. $this->assertSame('127.0.0.1:7001', $ring->getByHash(PHP_INT_SIZE == 4 ? 345494622 : 345494622)); // uid:312
  139. $this->assertSame('127.0.0.1:7000', $ring->getByHash(PHP_INT_SIZE == 4 ? -1042625818 : 3252341478)); // uid:432
  140. $this->assertSame('127.0.0.1:7000', $ring->getByHash(PHP_INT_SIZE == 4 ? -465463623 : 3829503673)); // uid:500
  141. $this->assertSame('127.0.0.1:7002', $ring->getByHash(PHP_INT_SIZE == 4 ? 2141928822 : 2141928822)); // uid:641
  142. }
  143. /**
  144. * @group disconnected
  145. */
  146. public function testGetBySlot()
  147. {
  148. $ring = $this->getSampleDistribution(array(
  149. '127.0.0.1:7000',
  150. '127.0.0.1:7001',
  151. '127.0.0.1:7002',
  152. ));
  153. $this->assertSame('127.0.0.1:7001', $ring->getBySlot(PHP_INT_SIZE == 4 ? -585685153 : 3709282143)); // uid:256
  154. $this->assertSame('127.0.0.1:7002', $ring->getBySlot(PHP_INT_SIZE == 4 ? -1617239533 : 2677727763)); // uid:281
  155. $this->assertSame('127.0.0.1:7001', $ring->getBySlot(PHP_INT_SIZE == 4 ? 353009954 : 353009954)); // uid:312
  156. $this->assertSame('127.0.0.1:7000', $ring->getBySlot(PHP_INT_SIZE == 4 ? -1037794023 : 3257173273)); // uid:432
  157. $this->assertSame('127.0.0.1:7000', $ring->getBySlot(PHP_INT_SIZE == 4 ? -458724341 : 3836242955)); // uid:500
  158. $this->assertSame('127.0.0.1:7002', $ring->getBySlot(PHP_INT_SIZE == 4 ? -2143763192 : 2151204104)); // uid:641
  159. // Test first and last slots
  160. $this->assertSame('127.0.0.1:7002', $ring->getBySlot(PHP_INT_SIZE == 4 ? -2135629153 : 2159338143));
  161. $this->assertSame('127.0.0.1:7000', $ring->getBySlot(PHP_INT_SIZE == 4 ? 2137506232 : 2137506232));
  162. // Test non-existing slot
  163. $this->assertNull($ring->getBySlot(0));
  164. }
  165. /**
  166. * @group disconnected
  167. */
  168. public function testCallbackToGetNodeHash()
  169. {
  170. $node = '127.0.0.1:7000';
  171. $callable = $this->getMock('stdClass', array('__invoke'));
  172. $callable
  173. ->expects($this->once())
  174. ->method('__invoke')
  175. ->with($node)
  176. ->will($this->returnValue($node));
  177. $distributor = new KetamaRing($callable);
  178. $distributor->add($node);
  179. $this->getNodes($distributor);
  180. }
  181. }