PredisConnectionTestCase.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  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 Predis\Profile;
  12. use PredisTestCase;
  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. */
  45. public function testDoesNotThrowExceptionOnConnectWhenAlreadyConnected()
  46. {
  47. $connection = $this->getConnection();
  48. $connection->connect();
  49. $this->assertTrue($connection->isConnected());
  50. $connection->connect();
  51. $this->assertTrue($connection->isConnected());
  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. $profile = $this->getProfile();
  100. $connection = $this->getConnection($profile);
  101. $cmdPing = $this->getMock($profile->getCommandClass('ping'), array('parseResponse'));
  102. $cmdPing->expects($this->never())
  103. ->method('parseResponse');
  104. $this->assertEquals('PONG', $connection->executeCommand($cmdPing));
  105. }
  106. /**
  107. * @group connected
  108. */
  109. public function testWritesCommandToServer()
  110. {
  111. $profile = $this->getProfile();
  112. $connection = $this->getConnection($profile);
  113. $cmdEcho = $this->getMock($profile->getCommandClass('echo'), array('parseResponse'));
  114. $cmdEcho->setArguments(array('ECHOED'));
  115. $cmdEcho->expects($this->never())
  116. ->method('parseResponse');
  117. $connection->writeRequest($cmdEcho);
  118. $connection->disconnect();
  119. }
  120. /**
  121. * @group connected
  122. */
  123. public function testReadsCommandFromServer()
  124. {
  125. $profile = $this->getProfile();
  126. $connection = $this->getConnection($profile);
  127. $cmdEcho = $this->getMock($profile->getCommandClass('echo'), array('parseResponse'));
  128. $cmdEcho->setArguments(array('ECHOED'));
  129. $cmdEcho->expects($this->never())
  130. ->method('parseResponse');
  131. $connection->writeRequest($cmdEcho);
  132. $this->assertSame('ECHOED', $connection->readResponse($cmdEcho));
  133. }
  134. /**
  135. * @group connected
  136. */
  137. public function testIsAbleToWriteMultipleCommandsAndReadThemBackForPipelining()
  138. {
  139. $profile = $this->getProfile();
  140. $cmdPing = $this->getMock($profile->getCommandClass('ping'), array('parseResponse'));
  141. $cmdPing->expects($this->never())
  142. ->method('parseResponse');
  143. $cmdEcho = $this->getMock($profile->getCommandClass('echo'), array('parseResponse'));
  144. $cmdEcho->setArguments(array('ECHOED'));
  145. $cmdEcho->expects($this->never())
  146. ->method('parseResponse');
  147. $connection = $this->getConnection();
  148. $connection->writeRequest($cmdPing);
  149. $connection->writeRequest($cmdEcho);
  150. $this->assertEquals('PONG', $connection->readResponse($cmdPing));
  151. $this->assertSame('ECHOED', $connection->readResponse($cmdEcho));
  152. }
  153. /**
  154. * @group connected
  155. */
  156. public function testSendsInitializationCommandsOnConnection()
  157. {
  158. $profile = $this->getProfile();
  159. $connection = $this->getConnection($profile, true);
  160. $cmdPing = $this->getMock($profile->getCommandClass('ping'), array('getArguments'));
  161. $cmdPing->expects($this->once())
  162. ->method('getArguments')
  163. ->will($this->returnValue(array()));
  164. $cmdEcho = $this->getMock($profile->getCommandClass('echo'), array('getArguments'));
  165. $cmdEcho->expects($this->once())
  166. ->method('getArguments')
  167. ->will($this->returnValue(array('ECHOED')));
  168. $connection->addConnectCommand($cmdPing);
  169. $connection->addConnectCommand($cmdEcho);
  170. $connection->connect();
  171. }
  172. /**
  173. * @group connected
  174. */
  175. public function testReadsStatusResponses()
  176. {
  177. $profile = $this->getProfile();
  178. $connection = $this->getConnection($profile, true);
  179. $connection->writeRequest($profile->createCommand('set', array('foo', 'bar')));
  180. $this->assertInstanceOf('Predis\Response\Status', $connection->read());
  181. $connection->writeRequest($profile->createCommand('ping'));
  182. $this->assertInstanceOf('Predis\Response\Status', $connection->read());
  183. $connection->writeRequest($profile->createCommand('multi'));
  184. $connection->writeRequest($profile->createCommand('ping'));
  185. $this->assertInstanceOf('Predis\Response\Status', $connection->read());
  186. $this->assertInstanceOf('Predis\Response\Status', $connection->read());
  187. }
  188. /**
  189. * @group connected
  190. */
  191. public function testReadsBulkResponses()
  192. {
  193. $profile = $this->getProfile();
  194. $connection = $this->getConnection($profile, true);
  195. $connection->executeCommand($profile->createCommand('set', array('foo', 'bar')));
  196. $connection->writeRequest($profile->createCommand('get', array('foo')));
  197. $this->assertSame('bar', $connection->read());
  198. $connection->writeRequest($profile->createCommand('get', array('hoge')));
  199. $this->assertNull($connection->read());
  200. }
  201. /**
  202. * @group connected
  203. */
  204. public function testReadsIntegerResponses()
  205. {
  206. $profile = $this->getProfile();
  207. $connection = $this->getConnection($profile, true);
  208. $connection->executeCommand($profile->createCommand('rpush', array('metavars', 'foo', 'hoge', 'lol')));
  209. $connection->writeRequest($profile->createCommand('llen', array('metavars')));
  210. $this->assertSame(3, $connection->read());
  211. }
  212. /**
  213. * @group connected
  214. */
  215. public function testReadsErrorResponsesAsResponseErrorObjects()
  216. {
  217. $profile = $this->getProfile();
  218. $connection = $this->getConnection($profile, true);
  219. $connection->executeCommand($profile->createCommand('set', array('foo', 'bar')));
  220. $connection->writeRequest($profile->createCommand('rpush', array('foo', 'baz')));
  221. $this->assertInstanceOf('Predis\Response\Error', $error = $connection->read());
  222. $this->assertRegExp('/[ERR|WRONGTYPE] Operation against a key holding the wrong kind of value/', $error->getMessage());
  223. }
  224. /**
  225. * @group connected
  226. */
  227. public function testReadsMultibulkResponsesAsArrays()
  228. {
  229. $profile = $this->getProfile();
  230. $connection = $this->getConnection($profile, true);
  231. $connection->executeCommand($profile->createCommand('rpush', array('metavars', 'foo', 'hoge', 'lol')));
  232. $connection->writeRequest($profile->createCommand('lrange', array('metavars', 0, -1)));
  233. $this->assertSame(array('foo', 'hoge', 'lol'), $connection->read());
  234. }
  235. /**
  236. * @group connected
  237. * @group slow
  238. * @expectedException \Predis\Connection\ConnectionException
  239. */
  240. public function testThrowsExceptionOnConnectionTimeout()
  241. {
  242. $connection = $this->getConnection($_, false, array('host' => '169.254.10.10', 'timeout' => 0.5));
  243. $connection->connect();
  244. }
  245. /**
  246. * @group connected
  247. * @group slow
  248. * @expectedException \Predis\Connection\ConnectionException
  249. */
  250. public function testThrowsExceptionOnReadWriteTimeout()
  251. {
  252. $profile = $this->getProfile();
  253. $connection = $this->getConnection($profile, true, array('read_write_timeout' => 0.5));
  254. $connection->executeCommand($profile->createCommand('brpop', array('foo', 3)));
  255. }
  256. // ******************************************************************** //
  257. // ---- HELPER METHODS ------------------------------------------------ //
  258. // ******************************************************************** //
  259. /**
  260. * Returns a named array with the default connection parameters and their values.
  261. *
  262. * @return array Default connection parameters.
  263. */
  264. protected function getDefaultParametersArray()
  265. {
  266. return array(
  267. 'scheme' => 'tcp',
  268. 'host' => REDIS_SERVER_HOST,
  269. 'port' => REDIS_SERVER_PORT,
  270. 'database' => REDIS_SERVER_DBNUM,
  271. 'read_write_timeout' => 2,
  272. );
  273. }
  274. /**
  275. * Returns a new instance of a connection instance.
  276. *
  277. * @param Profile\ProfileInterface $profile Reference to the server profile instance.
  278. * @param bool $initialize Push default initialization commands (SELECT and FLUSHDB).
  279. * @param array $parameters Additional connection parameters.
  280. *
  281. * @return StreamConnection
  282. */
  283. abstract protected function getConnection(&$profile = null, $initialize = false, array $parameters = array());
  284. }