PredisClusterTest.php 12 KB

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