PredisClusterTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  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\Connection\Cluster;
  11. use PredisTestCase;
  12. /**
  13. *
  14. */
  15. class PredisClusterTest extends PredisTestCase
  16. {
  17. /**
  18. * @group disconnected
  19. */
  20. public function testExposesCommandHashStrategy()
  21. {
  22. $cluster = new PredisCluster();
  23. $this->assertInstanceOf('Predis\Cluster\PredisStrategy', $cluster->getClusterStrategy());
  24. }
  25. /**
  26. * @group disconnected
  27. */
  28. public function testAddingConnectionsToCluster()
  29. {
  30. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001');
  31. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  32. $cluster = new PredisCluster();
  33. $cluster->add($connection1);
  34. $cluster->add($connection2);
  35. $this->assertSame(2, count($cluster));
  36. $this->assertSame($connection1, $cluster->getConnectionById('127.0.0.1:7001'));
  37. $this->assertSame($connection2, $cluster->getConnectionById('127.0.0.1:7002'));
  38. }
  39. /**
  40. * @group disconnected
  41. */
  42. public function testAddingConnectionsWithAliasParameterToCluster()
  43. {
  44. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001?alias=node01');
  45. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002?alias=node02');
  46. $cluster = new PredisCluster();
  47. $cluster->add($connection1);
  48. $cluster->add($connection2);
  49. $this->assertSame(2, count($cluster));
  50. $this->assertSame($connection1, $cluster->getConnectionByAlias('node01'));
  51. $this->assertSame($connection2, $cluster->getConnectionByAlias('node02'));
  52. }
  53. /**
  54. * @group disconnected
  55. */
  56. public function testRemovingConnectionsFromCluster()
  57. {
  58. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001?alias=node01');
  59. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  60. $connection3 = $this->getMockConnection('tcp://127.0.0.1:7003');
  61. $cluster = new PredisCluster();
  62. $cluster->add($connection1);
  63. $cluster->add($connection2);
  64. $this->assertTrue($cluster->remove($connection1));
  65. $this->assertNull($cluster->getConnectionByAlias('node02'));
  66. $this->assertFalse($cluster->remove($connection3));
  67. $this->assertCount(1, $cluster);
  68. }
  69. /**
  70. * @group disconnected
  71. */
  72. public function testConnectForcesAllConnectionsToConnect()
  73. {
  74. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001');
  75. $connection1
  76. ->expects($this->once())
  77. ->method('connect');
  78. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  79. $connection2
  80. ->expects($this->once())
  81. ->method('connect');
  82. $cluster = new PredisCluster();
  83. $cluster->add($connection1);
  84. $cluster->add($connection2);
  85. $cluster->connect();
  86. }
  87. /**
  88. * @group disconnected
  89. */
  90. public function testDisconnectForcesAllConnectionsToDisconnect()
  91. {
  92. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001');
  93. $connection1
  94. ->expects($this->once())
  95. ->method('disconnect');
  96. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  97. $connection2
  98. ->expects($this->once())
  99. ->method('disconnect');
  100. $cluster = new PredisCluster();
  101. $cluster->add($connection1);
  102. $cluster->add($connection2);
  103. $cluster->disconnect();
  104. }
  105. /**
  106. * @group disconnected
  107. */
  108. public function testIsConnectedReturnsTrueIfAtLeastOneConnectionIsOpen()
  109. {
  110. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001');
  111. $connection1
  112. ->expects($this->once())
  113. ->method('isConnected')
  114. ->will($this->returnValue(false));
  115. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  116. $connection2
  117. ->expects($this->once())
  118. ->method('isConnected')
  119. ->will($this->returnValue(true));
  120. $cluster = new PredisCluster();
  121. $cluster->add($connection1);
  122. $cluster->add($connection2);
  123. $this->assertTrue($cluster->isConnected());
  124. }
  125. /**
  126. * @group disconnected
  127. */
  128. public function testIsConnectedReturnsFalseIfAllConnectionsAreClosed()
  129. {
  130. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001');
  131. $connection1
  132. ->expects($this->once())
  133. ->method('isConnected')
  134. ->will($this->returnValue(false));
  135. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  136. $connection2
  137. ->expects($this->once())
  138. ->method('isConnected')
  139. ->will($this->returnValue(false));
  140. $cluster = new PredisCluster();
  141. $cluster->add($connection1);
  142. $cluster->add($connection2);
  143. $this->assertFalse($cluster->isConnected());
  144. }
  145. /**
  146. * @group disconnected
  147. */
  148. public function testCanReturnAnIteratorForConnections()
  149. {
  150. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001');
  151. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  152. $cluster = new PredisCluster();
  153. $cluster->add($connection1);
  154. $cluster->add($connection2);
  155. $this->assertInstanceOf('Iterator', $iterator = $cluster->getIterator());
  156. $connections = iterator_to_array($iterator);
  157. $this->assertSame(array(
  158. '127.0.0.1:7001' => $connection1,
  159. '127.0.0.1:7002' => $connection2,
  160. ), iterator_to_array($iterator));
  161. }
  162. /**
  163. * @group disconnected
  164. */
  165. public function testReturnsCorrectConnectionUsingSlot()
  166. {
  167. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001');
  168. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  169. $cluster = new PredisCluster();
  170. $cluster->add($connection1);
  171. $cluster->add($connection2);
  172. $this->assertSame($connection1, $cluster->getConnectionBySlot(1839357934));
  173. $this->assertSame($connection2, $cluster->getConnectionBySlot(2146453549));
  174. }
  175. /**
  176. * @group disconnected
  177. */
  178. public function testReturnsCorrectConnectionUsingKey()
  179. {
  180. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001');
  181. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  182. $cluster = new PredisCluster();
  183. $cluster->add($connection1);
  184. $cluster->add($connection2);
  185. $this->assertSame($connection1, $cluster->getConnectionByKey('node01:5431'));
  186. $this->assertSame($connection2, $cluster->getConnectionByKey('node02:3212'));
  187. $this->assertSame($connection1, $cluster->getConnectionByKey('prefix:{node01:5431}'));
  188. $this->assertSame($connection2, $cluster->getConnectionByKey('prefix:{node02:3212}'));
  189. }
  190. /**
  191. * @group disconnected
  192. */
  193. public function testReturnsCorrectConnectionUsingCommandInstance()
  194. {
  195. $commands = $this->getCommandFactory();
  196. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001');
  197. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  198. $cluster = new PredisCluster();
  199. $cluster->add($connection1);
  200. $cluster->add($connection2);
  201. $set = $commands->createCommand('set', array('node01:5431', 'foobar'));
  202. $get = $commands->createCommand('get', array('node01:5431'));
  203. $this->assertSame($connection1, $cluster->getConnectionByCommand($set));
  204. $this->assertSame($connection1, $cluster->getConnectionByCommand($get));
  205. $set = $commands->createCommand('set', array('prefix:{node01:5431}', 'foobar'));
  206. $get = $commands->createCommand('get', array('prefix:{node01:5431}'));
  207. $this->assertSame($connection1, $cluster->getConnectionByCommand($set));
  208. $this->assertSame($connection1, $cluster->getConnectionByCommand($get));
  209. $set = $commands->createCommand('set', array('node02:3212', 'foobar'));
  210. $get = $commands->createCommand('get', array('node02:3212'));
  211. $this->assertSame($connection2, $cluster->getConnectionByCommand($set));
  212. $this->assertSame($connection2, $cluster->getConnectionByCommand($get));
  213. $set = $commands->createCommand('set', array('prefix:{node02:3212}', 'foobar'));
  214. $get = $commands->createCommand('get', array('prefix:{node02:3212}'));
  215. $this->assertSame($connection2, $cluster->getConnectionByCommand($set));
  216. $this->assertSame($connection2, $cluster->getConnectionByCommand($get));
  217. }
  218. /**
  219. * @group disconnected
  220. * @expectedException \Predis\NotSupportedException
  221. * @expectedExceptionMessage Cannot use 'PING' over clusters of connections.
  222. */
  223. public function testThrowsExceptionOnNonShardableCommand()
  224. {
  225. $ping = $this->getCommandFactory()->createCommand('ping');
  226. $cluster = new PredisCluster();
  227. $cluster->add($this->getMockConnection('tcp://127.0.0.1:6379'));
  228. $cluster->getConnectionByCommand($ping);
  229. }
  230. /**
  231. * @group disconnected
  232. */
  233. public function testSupportsKeyHashTags()
  234. {
  235. $commands = $this->getCommandFactory();
  236. $connection1 = $this->getMockConnection('tcp://127.0.0.1:6379');
  237. $connection2 = $this->getMockConnection('tcp://127.0.0.1:6380');
  238. $cluster = new PredisCluster();
  239. $cluster->add($connection1);
  240. $cluster->add($connection2);
  241. $set = $commands->createCommand('set', array('{node:1001}:foo', 'foobar'));
  242. $get = $commands->createCommand('get', array('{node:1001}:foo'));
  243. $this->assertSame($connection1, $cluster->getConnectionByCommand($set));
  244. $this->assertSame($connection1, $cluster->getConnectionByCommand($get));
  245. $set = $commands->createCommand('set', array('{node:1001}:bar', 'foobar'));
  246. $get = $commands->createCommand('get', array('{node:1001}:bar'));
  247. $this->assertSame($connection1, $cluster->getConnectionByCommand($set));
  248. $this->assertSame($connection1, $cluster->getConnectionByCommand($get));
  249. }
  250. /**
  251. * @group disconnected
  252. */
  253. public function testWritesCommandToCorrectConnection()
  254. {
  255. $command = $this->getCommandFactory()->createCommand('get', array('node01:5431'));
  256. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001');
  257. $connection1
  258. ->expects($this->once())
  259. ->method('writeRequest')
  260. ->with($command);
  261. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  262. $connection2
  263. ->expects($this->never())
  264. ->method('writeRequest');
  265. $cluster = new PredisCluster();
  266. $cluster->add($connection1);
  267. $cluster->add($connection2);
  268. $cluster->writeRequest($command);
  269. }
  270. /**
  271. * @group disconnected
  272. */
  273. public function testReadsCommandFromCorrectConnection()
  274. {
  275. $command = $this->getCommandFactory()->createCommand('get', array('node02:3212'));
  276. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001');
  277. $connection1
  278. ->expects($this->never())
  279. ->method('readResponse');
  280. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  281. $connection2
  282. ->expects($this->once())
  283. ->method('readResponse')
  284. ->with($command);
  285. $cluster = new PredisCluster();
  286. $cluster->add($connection1);
  287. $cluster->add($connection2);
  288. $cluster->readResponse($command);
  289. }
  290. /**
  291. * @group disconnected
  292. */
  293. public function testExecutesCommandOnCorrectConnection()
  294. {
  295. $command = $this->getCommandFactory()->createCommand('get', array('node01:5431'));
  296. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001');
  297. $connection1
  298. ->expects($this->once())
  299. ->method('executeCommand')
  300. ->with($command);
  301. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002');
  302. $connection2
  303. ->expects($this->never())
  304. ->method('executeCommand');
  305. $cluster = new PredisCluster();
  306. $cluster->add($connection1);
  307. $cluster->add($connection2);
  308. $cluster->executeCommand($command);
  309. }
  310. /**
  311. * @group disconnected
  312. */
  313. public function testCanBeSerialized()
  314. {
  315. $connection1 = $this->getMockConnection('tcp://127.0.0.1:7001?alias=first');
  316. $connection2 = $this->getMockConnection('tcp://127.0.0.1:7002?alias=second');
  317. $cluster = new PredisCluster();
  318. $cluster->add($connection1);
  319. $cluster->add($connection2);
  320. // We use the following line to initialize the underlying hashring.
  321. $cluster->getConnectionByKey('foo');
  322. $unserialized = unserialize(serialize($cluster));
  323. $this->assertEquals($cluster, $unserialized);
  324. }
  325. }