PredisConnectionTestCase.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335
  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;
  11. use PredisTestCase;
  12. use Predis\Profile;
  13. /**
  14. * @group realm-connection
  15. */
  16. abstract class PredisConnectionTestCase extends PredisTestCase
  17. {
  18. /**
  19. * @group disconnected
  20. * @group slow
  21. * @expectedException Predis\Connection\ConnectionException
  22. */
  23. public function testThrowExceptionWhenUnableToConnect()
  24. {
  25. $parameters = array('host' => '169.254.10.10', 'timeout' => 0.5);
  26. $connection = $this->getConnection($profile, false, $parameters);
  27. $connection->executeCommand($this->getProfile()->createCommand('ping'));
  28. }
  29. // ******************************************************************** //
  30. // ---- INTEGRATION TESTS --------------------------------------------- //
  31. // ******************************************************************** //
  32. /**
  33. * @group connected
  34. */
  35. public function testConnectForcesConnection()
  36. {
  37. $connection = $this->getConnection();
  38. $this->assertFalse($connection->isConnected());
  39. $connection->connect();
  40. $this->assertTrue($connection->isConnected());
  41. }
  42. /**
  43. * @group connected
  44. * @expectedException Predis\ClientException
  45. * @expectedExceptionMessage Connection already estabilished
  46. */
  47. public function testThrowsExceptionOnConnectWhenAlreadyConnected()
  48. {
  49. $connection = $this->getConnection();
  50. $connection->connect();
  51. $connection->connect();
  52. }
  53. /**
  54. * @group connected
  55. */
  56. public function testDisconnectForcesDisconnection()
  57. {
  58. $connection = $this->getConnection();
  59. $connection->connect();
  60. $this->assertTrue($connection->isConnected());
  61. $connection->disconnect();
  62. $this->assertFalse($connection->isConnected());
  63. }
  64. /**
  65. * @group disconnected
  66. */
  67. public function testDoesNotThrowExceptionOnDisconnectWhenAlreadyDisconnected()
  68. {
  69. $connection = $this->getConnection();
  70. $this->assertFalse($connection->isConnected());
  71. $connection->disconnect();
  72. $this->assertFalse($connection->isConnected());
  73. }
  74. /**
  75. * @group connected
  76. */
  77. public function testGetResourceForcesConnection()
  78. {
  79. $connection = $this->getConnection();
  80. $this->assertFalse($connection->isConnected());
  81. $this->assertInternalType('resource', $connection->getResource());
  82. $this->assertTrue($connection->isConnected());
  83. }
  84. /**
  85. * @group connected
  86. */
  87. public function testSendingCommandForcesConnection()
  88. {
  89. $connection = $this->getConnection($profile);
  90. $cmdPing = $profile->createCommand('ping');
  91. $this->assertEquals('PONG', $connection->executeCommand($cmdPing));
  92. $this->assertTrue($connection->isConnected());
  93. }
  94. /**
  95. * @group connected
  96. */
  97. public function testExecutesCommandOnServer()
  98. {
  99. $connection = $this->getConnection($profile);
  100. $cmdPing = $this->getMock($profile->getCommandClass('ping'), array('parseResponse'));
  101. $cmdPing->expects($this->never())
  102. ->method('parseResponse');
  103. $this->assertEquals('PONG', $connection->executeCommand($cmdPing));
  104. }
  105. /**
  106. * @group connected
  107. */
  108. public function testWritesCommandToServer()
  109. {
  110. $connection = $this->getConnection($profile);
  111. $cmdEcho = $this->getMock($profile->getCommandClass('echo'), array('parseResponse'));
  112. $cmdEcho->setArguments(array('ECHOED'));
  113. $cmdEcho->expects($this->never())
  114. ->method('parseResponse');
  115. $connection->writeRequest($cmdEcho);
  116. $connection->disconnect();
  117. }
  118. /**
  119. * @group connected
  120. */
  121. public function testReadsCommandFromServer()
  122. {
  123. $connection = $this->getConnection($profile);
  124. $cmdEcho = $this->getMock($profile->getCommandClass('echo'), array('parseResponse'));
  125. $cmdEcho->setArguments(array('ECHOED'));
  126. $cmdEcho->expects($this->never())
  127. ->method('parseResponse');
  128. $connection->writeRequest($cmdEcho);
  129. $this->assertSame('ECHOED', $connection->readResponse($cmdEcho));
  130. }
  131. /**
  132. * @group connected
  133. */
  134. public function testIsAbleToWriteMultipleCommandsAndReadThemBackForPipelining()
  135. {
  136. $connection = $this->getConnection($profile);
  137. $cmdPing = $this->getMock($profile->getCommandClass('ping'), array('parseResponse'));
  138. $cmdPing->expects($this->never())
  139. ->method('parseResponse');
  140. $cmdEcho = $this->getMock($profile->getCommandClass('echo'), array('parseResponse'));
  141. $cmdEcho->setArguments(array('ECHOED'));
  142. $cmdEcho->expects($this->never())
  143. ->method('parseResponse');
  144. $connection = $this->getConnection();
  145. $connection->writeRequest($cmdPing);
  146. $connection->writeRequest($cmdEcho);
  147. $this->assertEquals('PONG', $connection->readResponse($cmdPing));
  148. $this->assertSame('ECHOED', $connection->readResponse($cmdEcho));
  149. }
  150. /**
  151. * @group connected
  152. */
  153. public function testSendsInitializationCommandsOnConnection()
  154. {
  155. $connection = $this->getConnection($profile, true);
  156. $cmdPing = $this->getMock($profile->getCommandClass('ping'), array('getArguments'));
  157. $cmdPing->expects($this->once())
  158. ->method('getArguments')
  159. ->will($this->returnValue(array()));
  160. $cmdEcho = $this->getMock($profile->getCommandClass('echo'), array('getArguments'));
  161. $cmdEcho->expects($this->once())
  162. ->method('getArguments')
  163. ->will($this->returnValue(array('ECHOED')));
  164. $connection->pushInitCommand($cmdPing);
  165. $connection->pushInitCommand($cmdEcho);
  166. $connection->connect();
  167. }
  168. /**
  169. * @group connected
  170. */
  171. public function testReadsStatusReplies()
  172. {
  173. $connection = $this->getConnection($profile, true);
  174. $connection->writeRequest($profile->createCommand('set', array('foo', 'bar')));
  175. $this->assertInstanceOf('Predis\Response\Status', $connection->read());
  176. $connection->writeRequest($profile->createCommand('ping'));
  177. $this->assertInstanceOf('Predis\Response\Status', $connection->read());
  178. $connection->writeRequest($profile->createCommand('multi'));
  179. $connection->writeRequest($profile->createCommand('ping'));
  180. $this->assertInstanceOf('Predis\Response\Status', $connection->read());
  181. $this->assertInstanceOf('Predis\Response\Status', $connection->read());
  182. }
  183. /**
  184. * @group connected
  185. */
  186. public function testReadsBulkReplies()
  187. {
  188. $connection = $this->getConnection($profile, true);
  189. $connection->executeCommand($profile->createCommand('set', array('foo', 'bar')));
  190. $connection->writeRequest($profile->createCommand('get', array('foo')));
  191. $this->assertSame('bar', $connection->read());
  192. $connection->writeRequest($profile->createCommand('get', array('hoge')));
  193. $this->assertNull($connection->read());
  194. }
  195. /**
  196. * @group connected
  197. */
  198. public function testReadsIntegerReplies()
  199. {
  200. $connection = $this->getConnection($profile, true);
  201. $connection->executeCommand($profile->createCommand('rpush', array('metavars', 'foo', 'hoge', 'lol')));
  202. $connection->writeRequest($profile->createCommand('llen', array('metavars')));
  203. $this->assertSame(3, $connection->read());
  204. }
  205. /**
  206. * @group connected
  207. */
  208. public function testReadsErrorRepliesAsResponseErrorObjects()
  209. {
  210. $connection = $this->getConnection($profile, true);
  211. $connection->executeCommand($profile->createCommand('set', array('foo', 'bar')));
  212. $connection->writeRequest($profile->createCommand('rpush', array('foo', 'baz')));
  213. $this->assertInstanceOf('Predis\Response\Error', $error = $connection->read());
  214. $this->assertRegExp('/[ERR|WRONGTYPE] Operation against a key holding the wrong kind of value/', $error->getMessage());
  215. }
  216. /**
  217. * @group connected
  218. */
  219. public function testReadsMultibulkRepliesAsArrays()
  220. {
  221. $connection = $this->getConnection($profile, true);
  222. $connection->executeCommand($profile->createCommand('rpush', array('metavars', 'foo', 'hoge', 'lol')));
  223. $connection->writeRequest($profile->createCommand('lrange', array('metavars', 0, -1)));
  224. $this->assertSame(array('foo', 'hoge', 'lol'), $connection->read());
  225. }
  226. /**
  227. * @group connected
  228. * @group slow
  229. * @expectedException Predis\Connection\ConnectionException
  230. */
  231. public function testThrowsExceptionOnConnectionTimeout()
  232. {
  233. $connection = $this->getConnection($_, false, array('host' => '169.254.10.10', 'timeout' => 0.5));
  234. $connection->connect();
  235. }
  236. /**
  237. * @group connected
  238. * @group slow
  239. * @expectedException Predis\Connection\ConnectionException
  240. */
  241. public function testThrowsExceptionOnReadWriteTimeout()
  242. {
  243. $connection = $this->getConnection($profile, true, array('read_write_timeout' => 0.5));
  244. $connection->executeCommand($profile->createCommand('brpop', array('foo', 3)));
  245. }
  246. // ******************************************************************** //
  247. // ---- HELPER METHODS ------------------------------------------------ //
  248. // ******************************************************************** //
  249. /**
  250. * Returns a named array with the default connection parameters and their values.
  251. *
  252. * @return array Default connection parameters.
  253. */
  254. protected function getDefaultParametersArray()
  255. {
  256. return array(
  257. 'scheme' => 'tcp',
  258. 'host' => REDIS_SERVER_HOST,
  259. 'port' => REDIS_SERVER_PORT,
  260. 'database' => REDIS_SERVER_DBNUM,
  261. 'read_write_timeout' => 2,
  262. );
  263. }
  264. /**
  265. * Returns a new instance of a connection instance.
  266. *
  267. * @param Profile\ProfileInterface $profile Reference to the server profile instance.
  268. * @param Boolean $initialize Push default initialization commands (SELECT and FLUSHDB).
  269. * @param array $parameters Additional connection parameters.
  270. * @return StreamConnection
  271. */
  272. protected abstract function getConnection(&$profile = null, $initialize = false, array $parameters = array());
  273. }