SlotMapTest.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471
  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;
  11. use PredisTestCase;
  12. /**
  13. *
  14. */
  15. class SlotMapTest extends PredisTestCase
  16. {
  17. /**
  18. * @group disconnected
  19. */
  20. public function testIsValidReturnsTrueOnValidSlot()
  21. {
  22. $this->assertTrue(SlotMap::isValid(0));
  23. $this->assertTrue(SlotMap::isValid(16383));
  24. $this->assertTrue(SlotMap::isValid(5000));
  25. $this->assertTrue(SlotMap::isValid('5000'));
  26. }
  27. /**
  28. * @group disconnected
  29. */
  30. public function testIsValidReturnsFalseOnInvalidSlot()
  31. {
  32. $this->assertFalse(SlotMap::isValid(-1));
  33. $this->assertFalse(SlotMap::isValid(16384));
  34. }
  35. /**
  36. * @group disconnected
  37. */
  38. public function testIsValidRangeReturnsTrueOnValidSlotRange()
  39. {
  40. $this->assertTrue(SlotMap::isValidRange(0, 16383));
  41. $this->assertTrue(SlotMap::isValidRange(2000, 2999));
  42. $this->assertTrue(SlotMap::isValidRange(3000, 3000));
  43. }
  44. /**
  45. * @group disconnected
  46. */
  47. public function testIsValidRangeReturnsFalseOnInvalidSlotRange()
  48. {
  49. $this->assertFalse(SlotMap::isValidRange(0, 16384));
  50. $this->assertFalse(SlotMap::isValidRange(-1, 16383));
  51. $this->assertFalse(SlotMap::isValidRange(-1, 16384));
  52. $this->assertFalse(SlotMap::isValidRange(2999, 2000));
  53. }
  54. /**
  55. * @group disconnected
  56. */
  57. public function testToArrayReturnsEmptyArrayOnEmptySlotMap()
  58. {
  59. $slotmap = new SlotMap();
  60. $this->assertEmpty($slotmap->toArray());
  61. }
  62. /**
  63. * @group disconnected
  64. */
  65. public function testSetSlotsAssignsSpecifiedNodeToSlotRange()
  66. {
  67. $slotmap = new SlotMap();
  68. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  69. $slotmap->setSlots(5461, 10922, '127.0.0.1:6380');
  70. $slotmap->setSlots(10923, 16383, '127.0.0.1:6381');
  71. $expectedMap = array_merge(
  72. array_fill(0, 5461, '127.0.0.1:6379'),
  73. array_fill(5461, 5462, '127.0.0.1:6380'),
  74. array_fill(10923, 5461, '127.0.0.1:6381')
  75. );
  76. $this->assertSame($expectedMap, $slotmap->toArray());
  77. }
  78. /**
  79. * @group disconnected
  80. */
  81. public function testSetSlotsOverwritesSlotRange()
  82. {
  83. $slotmap = new SlotMap();
  84. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  85. $slotmap->setSlots(1000, 2000, '127.0.0.1:6380');
  86. $expectedMap =
  87. array_fill(0, 5461, '127.0.0.1:6379') +
  88. array_fill(1000, 2000, '127.0.0.1:6380');
  89. $this->assertSame($expectedMap, $slotmap->toArray());
  90. }
  91. /**
  92. * @group disconnected
  93. */
  94. public function testSetSlotsAssignsSingleSlotWhenFirstAndLastSlotMatch()
  95. {
  96. $slotmap = new SlotMap();
  97. $slotmap->setSlots(10, 10, '127.0.0.1:6379');
  98. $this->assertSame(array(10 => '127.0.0.1:6379'), $slotmap->toArray());
  99. }
  100. /**
  101. * @group disconnected
  102. */
  103. public function testSetSlotsCastsValueToString()
  104. {
  105. $slotmap = new SlotMap();
  106. $connection = $this->getMockConnection();
  107. $connection
  108. ->expects($this->once())
  109. ->method('__toString')
  110. ->will($this->returnValue('127.0.0.1:6379'));
  111. $slotmap->setSlots(10, 10, $connection);
  112. $this->assertSame(array(10 => '127.0.0.1:6379'), $slotmap->toArray());
  113. }
  114. /**
  115. * @group disconnected
  116. * @expectedException \OutOfBoundsException
  117. * @expectedExceptionMessage Invalid slot range 0-16384 for `127.0.0.1:6379`
  118. */
  119. public function testSetSlotsThrowsExceptionOnInvalidSlotRange()
  120. {
  121. $slotmap = new SlotMap();
  122. $slotmap->setSlots(0, 16384, '127.0.0.1:6379');
  123. }
  124. /**
  125. * @group disconnected
  126. */
  127. public function testGetSlotsReturnsEmptyArrayOnEmptySlotMap()
  128. {
  129. $slotmap = new SlotMap();
  130. $this->assertEmpty($slotmap->getSlots(3, 11));
  131. }
  132. /**
  133. * @group disconnected
  134. */
  135. public function testGetSlotsReturnsDictionaryOfSlotsWithAssignedNodes()
  136. {
  137. $slotmap = new SlotMap();
  138. $slotmap->setSlots(0, 5, '127.0.0.1:6379');
  139. $slotmap->setSlots(10, 13, '127.0.0.1:6380');
  140. $expectedMap = array(
  141. 3 => '127.0.0.1:6379',
  142. 4 => '127.0.0.1:6379',
  143. 5 => '127.0.0.1:6379',
  144. 10 => '127.0.0.1:6380',
  145. 11 => '127.0.0.1:6380',
  146. );
  147. $this->assertSame($expectedMap, $slotmap->getSlots(3, 11));
  148. }
  149. /**
  150. * @group disconnected
  151. */
  152. public function testGetSlotsReturnsEmptyArrayOnEmptySlotRange()
  153. {
  154. $slotmap = new SlotMap();
  155. $slotmap->setSlots(0, 5, '127.0.0.1:6379');
  156. $slotmap->setSlots(10, 13, '127.0.0.1:6380');
  157. $this->assertEmpty($slotmap->getSlots(100, 200));
  158. }
  159. /**
  160. * @group disconnected
  161. * @expectedException \OutOfBoundsException
  162. * @expectedExceptionMessage Invalid slot range 0-16384
  163. */
  164. public function testGetSlotsThrowsExceptionOnInvalidSlotRange()
  165. {
  166. $slotmap = new SlotMap();
  167. $slotmap->getSlots(0, 16384);
  168. }
  169. /**
  170. * @group disconnected
  171. */
  172. public function testIsEmptyReturnsTrueOnEmptySlotMap()
  173. {
  174. $slotmap = new SlotMap();
  175. $this->assertTrue($slotmap->isEmpty());
  176. }
  177. /**
  178. * @group disconnected
  179. */
  180. public function testIsEmptyReturnsFalseOnNonEmptySlotMap()
  181. {
  182. $slotmap = new SlotMap();
  183. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  184. $this->assertFalse($slotmap->isEmpty());
  185. }
  186. /**
  187. * @group disconnected
  188. */
  189. public function testCountReturnsZeroOnEmptySlotMap()
  190. {
  191. $slotmap = new SlotMap();
  192. $this->assertSame(0, count($slotmap));
  193. }
  194. /**
  195. * @group disconnected
  196. */
  197. public function testCountReturnsAssignedSlotsInSlotMap()
  198. {
  199. $slotmap = new SlotMap();
  200. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  201. $this->assertSame(5461, count($slotmap));
  202. $slotmap->setSlots(5461, 10922, '127.0.0.1:6380');
  203. $this->assertSame(10923, count($slotmap));
  204. $slotmap->setSlots(10923, 16383, '127.0.0.1:6381');
  205. $this->assertSame(16384, count($slotmap));
  206. }
  207. /**
  208. * @group disconnected
  209. */
  210. public function testResetEmptiesSlotMap()
  211. {
  212. $slotmap = new SlotMap();
  213. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  214. $slotmap->setSlots(5461, 10922, '127.0.0.1:6380');
  215. $slotmap->setSlots(10923, 16383, '127.0.0.1:6381');
  216. $this->assertFalse($slotmap->isEmpty());
  217. $slotmap->reset();
  218. $this->assertTrue($slotmap->isEmpty());
  219. }
  220. /**
  221. * @group disconnected
  222. */
  223. public function testGetNodesReturnsEmptyArrayOnEmptySlotMap()
  224. {
  225. $slotmap = new SlotMap();
  226. $this->assertEmpty($slotmap->getNodes());
  227. }
  228. /**
  229. * @group disconnected
  230. */
  231. public function testGetNodesReturnsArrayOfNodesInSlotMap()
  232. {
  233. $slotmap = new SlotMap();
  234. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  235. $slotmap->setSlots(5461, 10922, '127.0.0.1:6380');
  236. $slotmap->setSlots(10923, 16383, '127.0.0.1:6381');
  237. $this->assertSame(array('127.0.0.1:6379', '127.0.0.1:6380', '127.0.0.1:6381'), $slotmap->getNodes());
  238. }
  239. /**
  240. * @group disconnected
  241. */
  242. public function testOffsetExistsReturnsTrueOnAssignedSlot()
  243. {
  244. $slotmap = new SlotMap();
  245. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  246. $this->assertTrue(isset($slotmap[0]));
  247. $this->assertTrue(isset($slotmap[2000]));
  248. }
  249. /**
  250. * @group disconnected
  251. */
  252. public function testOffsetExistsReturnsFalseOnAssignedSlot()
  253. {
  254. $slotmap = new SlotMap();
  255. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  256. $this->assertFalse(isset($slotmap[6000]));
  257. }
  258. /**
  259. * @group disconnected
  260. */
  261. public function testOffsetExistsReturnsFalseOnInvalidSlot()
  262. {
  263. $slotmap = new SlotMap();
  264. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  265. $this->assertFalse(isset($slotmap[-100]));
  266. $this->assertFalse(isset($slotmap[16384]));
  267. }
  268. /**
  269. * @group disconnected
  270. */
  271. public function testOffsetGetReturnsNodeOfAssignedSlot()
  272. {
  273. $slotmap = new SlotMap();
  274. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  275. $slotmap->setSlots(5461, 10922, '127.0.0.1:6380');
  276. $slotmap->setSlots(10923, 16383, '127.0.0.1:6381');
  277. $this->assertSame('127.0.0.1:6379', $slotmap[0]);
  278. $this->assertSame('127.0.0.1:6380', $slotmap[5461]);
  279. $this->assertSame('127.0.0.1:6381', $slotmap[10923]);
  280. }
  281. /**
  282. * @group disconnected
  283. */
  284. public function testOffsetGetReturnsNullOnUnassignedSlot()
  285. {
  286. $slotmap = new SlotMap();
  287. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  288. $this->assertNull($slotmap[5461]);
  289. }
  290. /**
  291. * @group disconnected
  292. */
  293. public function testOffsetGetReturnsNullOnInvalidSlot()
  294. {
  295. $slotmap = new SlotMap();
  296. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  297. $this->assertNull($slotmap[-100]);
  298. $this->assertNull($slotmap[16384]);
  299. }
  300. /**
  301. * @group disconnected
  302. */
  303. public function testOffsetUnsetRemovesSlotAssignment()
  304. {
  305. $slotmap = new SlotMap();
  306. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  307. $this->assertTrue(isset($slotmap[100]));
  308. unset($slotmap[100]);
  309. $this->assertFalse(isset($slotmap[100]));
  310. }
  311. /**
  312. * @group disconnected
  313. */
  314. public function testOffsetUnsetDoesNotDoAnythingOnUnassignedSlot()
  315. {
  316. $slotmap = new SlotMap();
  317. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  318. $this->assertFalse(isset($slotmap[5461]));
  319. unset($slotmap[5461]);
  320. $this->assertFalse(isset($slotmap[5461]));
  321. }
  322. /**
  323. * @group disconnected
  324. */
  325. public function testOffsetSetAssignsNodeToSlot()
  326. {
  327. $slotmap = new SlotMap();
  328. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  329. $this->assertSame('127.0.0.1:6380', $slotmap[100] = '127.0.0.1:6380');
  330. $this->assertSame('127.0.0.1:6380', $slotmap[100]);
  331. $this->assertNull($slotmap[5461]);
  332. $this->assertSame('127.0.0.1:6380', $slotmap[5461] = '127.0.0.1:6380');
  333. $this->assertSame('127.0.0.1:6380', $slotmap[5461]);
  334. }
  335. /**
  336. * @group disconnected
  337. */
  338. public function testOffsetSetCastsValueToString()
  339. {
  340. $slotmap = new SlotMap();
  341. $connection = $this->getMockConnection();
  342. $connection
  343. ->expects($this->once())
  344. ->method('__toString')
  345. ->will($this->returnValue('127.0.0.1:6379'));
  346. $this->assertSame($connection, $slotmap[0] = $connection);
  347. $this->assertSame('127.0.0.1:6379', $slotmap[0]);
  348. }
  349. /**
  350. * @group disconnected
  351. * @expectedException \OutOfBoundsException
  352. * @expectedExceptionMessage Invalid slot 16384 for `127.0.0.1:6379`
  353. */
  354. public function testOffsetSetThrowsExceptionOnInvalidSlot()
  355. {
  356. $slotmap = new SlotMap();
  357. $slotmap[16384] = '127.0.0.1:6379';
  358. }
  359. /**
  360. * @group disconnected
  361. */
  362. public function testGetIteratorReturnsIteratorOverSlotMap()
  363. {
  364. $slotmap = new SlotMap();
  365. $slotmap->setSlots(0, 5460, '127.0.0.1:6379');
  366. $slotmap->setSlots(5461, 10922, '127.0.0.1:6380');
  367. $slotmap->setSlots(10923, 16383, '127.0.0.1:6381');
  368. $expectedMap = array_merge(
  369. array_fill(0, 5461, '127.0.0.1:6379'),
  370. array_fill(5461, 5462, '127.0.0.1:6380'),
  371. array_fill(10923, 5461, '127.0.0.1:6381')
  372. );
  373. $this->assertSame($expectedMap, iterator_to_array($slotmap));
  374. }
  375. }