PredisClientFeatures.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. <?php
  2. require_once 'PredisShared.php';
  3. require_once '../lib/addons/RedisVersion1_0.php';
  4. class PredisClientFeaturesTestSuite extends PHPUnit_Framework_TestCase {
  5. public $redis;
  6. protected function setUp() {
  7. $this->redis = RC::getConnection();
  8. $this->redis->flushdb();
  9. }
  10. protected function tearDown() {
  11. }
  12. protected function onNotSuccessfulTest(Exception $exception) {
  13. // drops and reconnect to a redis server on uncaught exceptions
  14. RC::resetConnection();
  15. parent::onNotSuccessfulTest($exception);
  16. }
  17. /* ConnectionParameters */
  18. function testConnectionParametersDefaultValues() {
  19. $params = new \Predis\ConnectionParameters();
  20. $this->assertEquals(\Predis\ConnectionParameters::DEFAULT_HOST, $params->host);
  21. $this->assertEquals(\Predis\ConnectionParameters::DEFAULT_PORT, $params->port);
  22. $this->assertEquals(\Predis\ConnectionParameters::DEFAULT_TIMEOUT, $params->connection_timeout);
  23. $this->assertNull($params->read_write_timeout);
  24. $this->assertNull($params->database);
  25. $this->assertNull($params->password);
  26. $this->assertNull($params->alias);
  27. }
  28. function testConnectionParametersSetupValuesArray() {
  29. $paramsArray = RC::getConnectionParametersArgumentsArray();
  30. $params = new \Predis\ConnectionParameters($paramsArray);
  31. $this->assertEquals($paramsArray['host'], $params->host);
  32. $this->assertEquals($paramsArray['port'], $params->port);
  33. $this->assertEquals($paramsArray['connection_timeout'], $params->connection_timeout);
  34. $this->assertEquals($paramsArray['read_write_timeout'], $params->read_write_timeout);
  35. $this->assertEquals($paramsArray['database'], $params->database);
  36. $this->assertEquals($paramsArray['password'], $params->password);
  37. $this->assertEquals($paramsArray['alias'], $params->alias);
  38. }
  39. function testConnectionParametersSetupValuesString() {
  40. $paramsArray = RC::getConnectionParametersArgumentsArray();
  41. $paramsString = RC::getConnectionParametersArgumentsString($paramsArray);
  42. $params = new \Predis\ConnectionParameters($paramsArray);
  43. $this->assertEquals($paramsArray['host'], $params->host);
  44. $this->assertEquals($paramsArray['port'], $params->port);
  45. $this->assertEquals($paramsArray['connection_timeout'], $params->connection_timeout);
  46. $this->assertEquals($paramsArray['read_write_timeout'], $params->read_write_timeout);
  47. $this->assertEquals($paramsArray['database'], $params->database);
  48. $this->assertEquals($paramsArray['password'], $params->password);
  49. $this->assertEquals($paramsArray['alias'], $params->alias);
  50. }
  51. /* Command and derivates */
  52. function testCommand_TestArguments() {
  53. $cmdArgs = array('key1', 'key2', 'key3');
  54. $cmd = new \Predis\Commands\GetMultiple();
  55. $cmd->setArgumentsArray($cmdArgs);
  56. $this->assertEquals($cmdArgs[0], $cmd->getArgument(0));
  57. $this->assertEquals($cmdArgs[1], $cmd->getArgument(1));
  58. $this->assertEquals($cmdArgs[2], $cmd->getArgument(2));
  59. $cmd = new \Predis\Commands\GetMultiple();
  60. $cmd->setArguments('key1', 'key2', 'key3');
  61. $this->assertEquals($cmdArgs[0], $cmd->getArgument(0));
  62. $this->assertEquals($cmdArgs[1], $cmd->getArgument(1));
  63. $this->assertEquals($cmdArgs[2], $cmd->getArgument(2));
  64. $cmd = new \Predis\Commands\Ping();
  65. $this->assertNull($cmd->getArgument(0));
  66. }
  67. function testCommand_InlineWithNoArguments() {
  68. $cmd = new \Predis\Compatibility\v1_0\Commands\Ping();
  69. $this->assertType('\Predis\InlineCommand', $cmd);
  70. $this->assertEquals('PING', $cmd->getCommandId());
  71. $this->assertFalse($cmd->closesConnection());
  72. $this->assertFalse($cmd->canBeHashed());
  73. $this->assertNull($cmd->getHash(new \Predis\Distribution\HashRing()));
  74. $this->assertEquals("PING\r\n", $cmd->serialize());
  75. }
  76. function testCommand_InlineWithArguments() {
  77. $cmd = new \Predis\Compatibility\v1_0\Commands\Get();
  78. $cmd->setArgumentsArray(array('key'));
  79. $this->assertType('\Predis\InlineCommand', $cmd);
  80. $this->assertEquals('GET', $cmd->getCommandId());
  81. $this->assertFalse($cmd->closesConnection());
  82. $this->assertTrue($cmd->canBeHashed());
  83. $this->assertNotNull($cmd->getHash(new \Predis\Distribution\HashRing()));
  84. $this->assertEquals("GET key\r\n", $cmd->serialize());
  85. }
  86. function testCommand_BulkWithArguments() {
  87. $cmd = new \Predis\Compatibility\v1_0\Commands\Set();
  88. $cmd->setArgumentsArray(array('key', 'value'));
  89. $this->assertType('\Predis\BulkCommand', $cmd);
  90. $this->assertEquals('SET', $cmd->getCommandId());
  91. $this->assertFalse($cmd->closesConnection());
  92. $this->assertTrue($cmd->canBeHashed());
  93. $this->assertNotNull($cmd->getHash(new \Predis\Distribution\HashRing()));
  94. $this->assertEquals("SET key 5\r\nvalue\r\n", $cmd->serialize());
  95. }
  96. function testCommand_MultiBulkWithArguments() {
  97. $cmd = new \Predis\Commands\SetMultiple();
  98. $cmd->setArgumentsArray(array('key1', 'value1', 'key2', 'value2'));
  99. $this->assertType('\Predis\Command', $cmd);
  100. $this->assertEquals('MSET', $cmd->getCommandId());
  101. $this->assertFalse($cmd->closesConnection());
  102. $this->assertFalse($cmd->canBeHashed());
  103. $this->assertNotNull($cmd->getHash(new \Predis\Distribution\HashRing()));
  104. $this->assertEquals("*5\r\n$4\r\nMSET\r\n$4\r\nkey1\r\n$6\r\nvalue1\r\n$4\r\nkey2\r\n$6\r\nvalue2\r\n", $cmd->serialize());
  105. }
  106. function testCommand_ParseResponse() {
  107. // default parser
  108. $cmd = new \Predis\Commands\Get();
  109. $this->assertEquals('test', $cmd->parseResponse('test'));
  110. // overridden parser (boolean)
  111. $cmd = new \Predis\Commands\Exists();
  112. $this->assertTrue($cmd->parseResponse('1'));
  113. $this->assertFalse($cmd->parseResponse('0'));
  114. // overridden parser (boolean)
  115. $cmd = new \Predis\Commands\Ping();
  116. $this->assertTrue($cmd->parseResponse('PONG'));
  117. // overridden parser (complex)
  118. // TODO: emulate a respons to INFO
  119. }
  120. /* RedisServerProfile and derivates */
  121. function testRedisServerProfile_GetSpecificVersions() {
  122. $this->assertType('\Predis\RedisServer_v1_0', \Predis\RedisServerProfile::get('1.0'));
  123. $this->assertType('\Predis\RedisServer_v1_2', \Predis\RedisServerProfile::get('1.2'));
  124. $this->assertType('\Predis\RedisServer_v2_0', \Predis\RedisServerProfile::get('2.0'));
  125. $this->assertType('\Predis\RedisServer_vNext', \Predis\RedisServerProfile::get('dev'));
  126. $this->assertType('\Predis\RedisServerProfile', \Predis\RedisServerProfile::get('default'));
  127. $this->assertEquals(\Predis\RedisServerProfile::get('default'), \Predis\RedisServerProfile::getDefault());
  128. }
  129. function testRedisServerProfile_SupportedCommands() {
  130. $profile_10 = \Predis\RedisServerProfile::get('1.0');
  131. $profile_12 = \Predis\RedisServerProfile::get('1.2');
  132. $this->assertTrue($profile_10->supportsCommand('info'));
  133. $this->assertTrue($profile_12->supportsCommand('info'));
  134. $this->assertFalse($profile_10->supportsCommand('mset'));
  135. $this->assertTrue($profile_12->supportsCommand('mset'));
  136. $this->assertFalse($profile_10->supportsCommand('multi'));
  137. $this->assertFalse($profile_12->supportsCommand('multi'));
  138. }
  139. function testRedisServerProfile_CommandsCreation() {
  140. $profile = \Predis\RedisServerProfile::get('1.0');
  141. $cmdNoArgs = $profile->createCommand('info');
  142. $this->assertType('\Predis\Compatibility\v1_0\Commands\Info', $cmdNoArgs);
  143. $this->assertNull($cmdNoArgs->getArgument());
  144. $args = array('key1', 'key2');
  145. $cmdWithArgs = $profile->createCommand('mget', $args);
  146. $this->assertType('\Predis\Compatibility\v1_0\Commands\GetMultiple', $cmdWithArgs);
  147. $this->assertEquals($args[0], $cmdWithArgs->getArgument()); // TODO: why?
  148. $this->assertEquals($args[0], $cmdWithArgs->getArgument(0));
  149. $this->assertEquals($args[1], $cmdWithArgs->getArgument(1));
  150. $bogusCommand = 'not_existing_command';
  151. $expectedMessage = "'$bogusCommand' is not a registered Redis command";
  152. RC::testForClientException($this, $expectedMessage, function()
  153. use($profile, $bogusCommand) {
  154. $profile->createCommand($bogusCommand);
  155. });
  156. }
  157. function testRedisServerProfile_CommandsRegistration() {
  158. $profile = \Predis\RedisServerProfile::get('1.0');
  159. $cmdId = 'mset';
  160. $cmdClass = '\Predis\Commands\SetMultiple';
  161. $this->assertFalse($profile->supportsCommand($cmdId));
  162. $profile->registerCommand(new $cmdClass(), $cmdId);
  163. $this->assertTrue($profile->supportsCommand($cmdId));
  164. $this->assertType($cmdClass, $profile->createCommand($cmdId));
  165. }
  166. /* ResponseQueued */
  167. function testResponseQueued() {
  168. $response = new \Predis\ResponseQueued();
  169. $this->assertTrue($response->queued);
  170. $this->assertEquals(\Predis\Protocol::QUEUED, (string)$response);
  171. }
  172. /* ResponseError */
  173. function testResponseError() {
  174. $errorMessage = 'ERROR MESSAGE';
  175. $response = new \Predis\ResponseError($errorMessage);
  176. $this->assertTrue($response->error);
  177. $this->assertEquals($errorMessage, $response->message);
  178. $this->assertEquals($errorMessage, (string)$response);
  179. }
  180. /* Connection */
  181. function testConnection_StringCastReturnsIPAndPort() {
  182. $connection = new \Predis\TcpConnection(RC::getConnectionParameters());
  183. $this->assertEquals(RC::SERVER_HOST . ':' . RC::SERVER_PORT, (string) $connection);
  184. }
  185. function testConnection_ConnectDisconnect() {
  186. $connection = new \Predis\TcpConnection(RC::getConnectionParameters());
  187. $this->assertFalse($connection->isConnected());
  188. $connection->connect();
  189. $this->assertTrue($connection->isConnected());
  190. $connection->disconnect();
  191. $this->assertFalse($connection->isConnected());
  192. }
  193. function testConnection_WriteAndReadCommand() {
  194. $cmd = \Predis\RedisServerProfile::getDefault()->createCommand('ping');
  195. $connection = new \Predis\TcpConnection(RC::getConnectionParameters());
  196. $connection->connect();
  197. $connection->writeCommand($cmd);
  198. $this->assertTrue($connection->readResponse($cmd));
  199. }
  200. function testConnection_WriteCommandAndCloseConnection() {
  201. $cmd = \Predis\RedisServerProfile::getDefault()->createCommand('quit');
  202. $connection = new \Predis\TcpConnection(RC::getConnectionParameters());
  203. $connection->connect();
  204. $this->assertTrue($connection->isConnected());
  205. $connection->writeCommand($cmd);
  206. $exceptionMessage = 'Error while reading line from the server';
  207. RC::testForCommunicationException($this, $exceptionMessage, function() use($connection, $cmd) {
  208. $connection->readResponse($cmd);
  209. });
  210. //$this->assertFalse($connection->isConnected());
  211. }
  212. function testConnection_GetSocketOpensConnection() {
  213. $connection = new \Predis\TcpConnection(RC::getConnectionParameters());
  214. $this->assertFalse($connection->isConnected());
  215. $this->assertType('resource', $connection->getSocket());
  216. $this->assertTrue($connection->isConnected());
  217. }
  218. function testConnection_LazyConnect() {
  219. $cmd = \Predis\RedisServerProfile::getDefault()->createCommand('ping');
  220. $connection = new \Predis\TcpConnection(RC::getConnectionParameters());
  221. $this->assertFalse($connection->isConnected());
  222. $connection->writeCommand($cmd);
  223. $this->assertTrue($connection->isConnected());
  224. $this->assertTrue($connection->readResponse($cmd));
  225. }
  226. function testConnection_RawCommand() {
  227. $connection = new \Predis\TcpConnection(RC::getConnectionParameters());
  228. $this->assertEquals('PONG', $connection->rawCommand("PING\r\n"));
  229. }
  230. function testConnection_Alias() {
  231. $connection1 = new \Predis\TcpConnection(RC::getConnectionParameters());
  232. $this->assertNull($connection1->getParameters()->alias);
  233. $args = array_merge(RC::getConnectionArguments(), array('alias' => 'servername'));
  234. $connection2 = new \Predis\TcpConnection(new \Predis\ConnectionParameters($args));
  235. $this->assertEquals('servername', $connection2->getParameters()->alias);
  236. }
  237. function testConnection_ConnectionTimeout() {
  238. $timeout = 3;
  239. $args = array('host' => '1.0.0.1', 'connection_timeout' => $timeout);
  240. $connection = new \Predis\TcpConnection(new \Predis\ConnectionParameters($args));
  241. $start = time();
  242. RC::testForCommunicationException($this, null, function() use($connection) {
  243. $connection->connect();
  244. });
  245. $this->assertEquals((float)(time() - $start), $timeout, '', 1);
  246. }
  247. function testConnection_ReadTimeout() {
  248. $timeout = 1;
  249. $args = array_merge(RC::getConnectionArguments(), array('read_write_timeout' => $timeout));
  250. $cmdFake = \Predis\RedisServerProfile::getDefault()->createCommand('ping');
  251. $connection = new \Predis\TcpConnection(new \Predis\ConnectionParameters($args));
  252. $expectedMessage = 'Error while reading line from the server';
  253. $start = time();
  254. RC::testForCommunicationException($this, $expectedMessage, function() use($connection, $cmdFake) {
  255. $connection->readResponse($cmdFake);
  256. });
  257. $this->assertEquals((float)(time() - $start), $timeout, '', 1);
  258. }
  259. /* ResponseReader */
  260. function testResponseReader_OptionIterableMultiBulkReplies() {
  261. $connection = new \Predis\TcpConnection(RC::getConnectionParameters());
  262. $responseReader = $connection->getResponseReader();
  263. $responseReader->setHandler(
  264. \Predis\Protocol::PREFIX_MULTI_BULK,
  265. new \Predis\ResponseMultiBulkHandler()
  266. );
  267. $this->assertType('array', $connection->rawCommand("KEYS *\r\n"));
  268. $responseReader->setHandler(
  269. \Predis\Protocol::PREFIX_MULTI_BULK,
  270. new \Predis\ResponseMultiBulkStreamHandler()
  271. );
  272. $this->assertType('\Iterator', $connection->rawCommand("KEYS *\r\n"));
  273. }
  274. function testResponseReader_OptionExceptionOnError() {
  275. $connection = new \Predis\TcpConnection(RC::getConnectionParameters());
  276. $responseReader = $connection->getResponseReader();
  277. $connection->rawCommand("SET key 5\r\nvalue\r\n");
  278. $rawCmdUnexpected = "LPUSH key 5\r\nvalue\r\n";
  279. $responseReader->setHandler(
  280. \Predis\Protocol::PREFIX_ERROR,
  281. new \Predis\ResponseErrorSilentHandler()
  282. );
  283. $errorReply = $connection->rawCommand($rawCmdUnexpected);
  284. $this->assertType('\Predis\ResponseError', $errorReply);
  285. $this->assertEquals(RC::EXCEPTION_WRONG_TYPE, $errorReply->message);
  286. $responseReader->setHandler(
  287. \Predis\Protocol::PREFIX_ERROR,
  288. new \Predis\ResponseErrorHandler()
  289. );
  290. RC::testForServerException($this, RC::EXCEPTION_WRONG_TYPE, function()
  291. use ($connection, $rawCmdUnexpected) {
  292. $connection->rawCommand($rawCmdUnexpected);
  293. });
  294. }
  295. /* Client initialization */
  296. function testClientInitialization_SingleConnectionParameters() {
  297. $params1 = array_merge(RC::getConnectionArguments(), array(
  298. 'connection_timeout' => 10,
  299. 'read_write_timeout' => 30,
  300. 'alias' => 'connection_alias',
  301. ));
  302. $params2 = RC::getConnectionParametersArgumentsString($params1);
  303. $params3 = new \Predis\ConnectionParameters($params1);
  304. $params4 = new \Predis\TcpConnection($params3);
  305. foreach (array($params1, $params2, $params3, $params4) as $params) {
  306. $client = new \Predis\Client($params);
  307. $parameters = $client->getConnection()->getParameters();
  308. $this->assertEquals($params1['host'], $parameters->host);
  309. $this->assertEquals($params1['port'], $parameters->port);
  310. $this->assertEquals($params1['connection_timeout'], $parameters->connection_timeout);
  311. $this->assertEquals($params1['read_write_timeout'], $parameters->read_write_timeout);
  312. $this->assertEquals($params1['alias'], $parameters->alias);
  313. $this->assertNull($parameters->password);
  314. }
  315. }
  316. function testClientInitialization_ClusterConnectionParameters() {
  317. $params1 = array_merge(RC::getConnectionArguments(), array(
  318. 'connection_timeout' => 10,
  319. 'read_write_timeout' => 30,
  320. ));
  321. $params2 = RC::getConnectionParametersArgumentsString($params1);
  322. $params3 = new \Predis\ConnectionParameters($params1);
  323. $params4 = new \Predis\TcpConnection($params3);
  324. $client = new \Predis\Client(array($params1, $params2, $params3, $params4));
  325. foreach ($client->getConnection() as $connection) {
  326. $parameters = $connection->getParameters();
  327. $this->assertEquals($params1['host'], $parameters->host);
  328. $this->assertEquals($params1['port'], $parameters->port);
  329. $this->assertEquals($params1['connection_timeout'], $parameters->connection_timeout);
  330. $this->assertEquals($params1['read_write_timeout'], $parameters->read_write_timeout);
  331. $this->assertNull($parameters->password);
  332. }
  333. }
  334. /* Client + CommandPipeline */
  335. function testCommandPipeline_Simple() {
  336. $client = RC::getConnection();
  337. $client->flushdb();
  338. $pipe = $client->pipeline();
  339. $this->assertType('\Predis\CommandPipeline', $pipe);
  340. $this->assertType('\Predis\CommandPipeline', $pipe->set('foo', 'bar'));
  341. $this->assertType('\Predis\CommandPipeline', $pipe->set('hoge', 'piyo'));
  342. $this->assertType('\Predis\CommandPipeline', $pipe->mset(array(
  343. 'foofoo' => 'barbar', 'hogehoge' => 'piyopiyo'
  344. )));
  345. $this->assertType('\Predis\CommandPipeline', $pipe->mget(array(
  346. 'foo', 'hoge', 'foofoo', 'hogehoge'
  347. )));
  348. $replies = $pipe->execute();
  349. $this->assertType('array', $replies);
  350. $this->assertEquals(4, count($replies));
  351. $this->assertEquals(4, count($replies[3]));
  352. $this->assertEquals('barbar', $replies[3][2]);
  353. }
  354. function testCommandPipeline_FluentInterface() {
  355. $client = RC::getConnection();
  356. $client->flushdb();
  357. $replies = $client->pipeline()->ping()->set('foo', 'bar')->get('foo')->execute();
  358. $this->assertType('array', $replies);
  359. $this->assertEquals('bar', $replies[2]);
  360. }
  361. function testCommandPipeline_CallableAnonymousBlock() {
  362. $client = RC::getConnection();
  363. $client->flushdb();
  364. $replies = $client->pipeline(function($pipe) {
  365. $pipe->ping();
  366. $pipe->set('foo', 'bar');
  367. $pipe->get('foo');
  368. });
  369. $this->assertType('array', $replies);
  370. $this->assertEquals('bar', $replies[2]);
  371. }
  372. function testCommandPipeline_ClientExceptionInCallableBlock() {
  373. $client = RC::getConnection();
  374. $client->flushdb();
  375. RC::testForClientException($this, 'TEST', function() use($client) {
  376. $client->pipeline(function($pipe) {
  377. $pipe->ping();
  378. $pipe->set('foo', 'bar');
  379. throw new \Predis\ClientException("TEST");
  380. });
  381. });
  382. $this->assertFalse($client->exists('foo'));
  383. }
  384. function testCommandPipeline_ServerExceptionInCallableBlock() {
  385. $client = RC::getConnection();
  386. $client->flushdb();
  387. $client->getResponseReader()->setHandler('-', new \Predis\ResponseErrorSilentHandler());
  388. $replies = $client->pipeline(function($pipe) {
  389. $pipe->set('foo', 'bar');
  390. $pipe->lpush('foo', 'piyo'); // LIST operation on STRING type returns an ERROR
  391. $pipe->set('hoge', 'piyo');
  392. });
  393. $this->assertType('array', $replies);
  394. $this->assertType('\Predis\ResponseError', $replies[1]);
  395. $this->assertTrue($client->exists('foo'));
  396. $this->assertTrue($client->exists('hoge'));
  397. }
  398. function testCommandPipeline_Flush() {
  399. $client = RC::getConnection();
  400. $client->flushdb();
  401. $pipe = $client->pipeline();
  402. $pipe->set('foo', 'bar')->set('hoge', 'piyo');
  403. $pipe->flushPipeline();
  404. $pipe->ping()->mget(array('foo', 'hoge'));
  405. $replies = $pipe->execute();
  406. $this->assertType('array', $replies);
  407. $this->assertEquals(4, count($replies));
  408. $this->assertEquals('bar', $replies[3][0]);
  409. $this->assertEquals('piyo', $replies[3][1]);
  410. }
  411. /* Client + MultiExecBlock */
  412. function testMultiExecBlock_Simple() {
  413. $client = RC::getConnection();
  414. $client->flushdb();
  415. $multi = $client->multiExec();
  416. $this->assertType('\Predis\MultiExecBlock', $multi);
  417. $this->assertType('\Predis\MultiExecBlock', $multi->set('foo', 'bar'));
  418. $this->assertType('\Predis\MultiExecBlock', $multi->set('hoge', 'piyo'));
  419. $this->assertType('\Predis\MultiExecBlock', $multi->mset(array(
  420. 'foofoo' => 'barbar', 'hogehoge' => 'piyopiyo'
  421. )));
  422. $this->assertType('\Predis\MultiExecBlock', $multi->mget(array(
  423. 'foo', 'hoge', 'foofoo', 'hogehoge'
  424. )));
  425. $replies = $multi->execute();
  426. $this->assertType('array', $replies);
  427. $this->assertEquals(4, count($replies));
  428. $this->assertEquals(4, count($replies[3]));
  429. $this->assertEquals('barbar', $replies[3][2]);
  430. }
  431. function testMultiExecBlock_FluentInterface() {
  432. $client = RC::getConnection();
  433. $client->flushdb();
  434. $replies = $client->multiExec()->ping()->set('foo', 'bar')->get('foo')->execute();
  435. $this->assertType('array', $replies);
  436. $this->assertEquals('bar', $replies[2]);
  437. }
  438. function testMultiExecBlock_CallableAnonymousBlock() {
  439. $client = RC::getConnection();
  440. $client->flushdb();
  441. $replies = $client->multiExec(function($multi) {
  442. $multi->ping();
  443. $multi->set('foo', 'bar');
  444. $multi->get('foo');
  445. });
  446. $this->assertType('array', $replies);
  447. $this->assertEquals('bar', $replies[2]);
  448. }
  449. function testMultiExecBlock_EmptyCallableBlock() {
  450. $client = RC::getConnection();
  451. $client->flushdb();
  452. $replies = $client->multiExec(function($multi) { });
  453. $this->assertEquals(0, count($replies));
  454. }
  455. function testMultiExecBlock_ClientExceptionInCallableBlock() {
  456. $client = RC::getConnection();
  457. $client->flushdb();
  458. RC::testForClientException($this, 'TEST', function() use($client) {
  459. $client->multiExec(function($multi) {
  460. $multi->ping();
  461. $multi->set('foo', 'bar');
  462. throw new \Predis\ClientException("TEST");
  463. });
  464. });
  465. $this->assertFalse($client->exists('foo'));
  466. }
  467. function testMultiExecBlock_ServerExceptionInCallableBlock() {
  468. $client = RC::getConnection();
  469. $client->flushdb();
  470. $client->getResponseReader()->setHandler('-', new \Predis\ResponseErrorSilentHandler());
  471. $replies = $client->multiExec(function($multi) {
  472. $multi->set('foo', 'bar');
  473. $multi->lpush('foo', 'piyo'); // LIST operation on STRING type returns an ERROR
  474. $multi->set('hoge', 'piyo');
  475. });
  476. $this->assertType('array', $replies);
  477. $this->assertType('\Predis\ResponseError', $replies[1]);
  478. $this->assertTrue($client->exists('foo'));
  479. $this->assertTrue($client->exists('hoge'));
  480. }
  481. function testMultiExecBlock_Discard() {
  482. $client = RC::getConnection();
  483. $client->flushdb();
  484. $replies = $client->multiExec(function($multi) {
  485. $multi->set('foo', 'bar');
  486. $multi->discard();
  487. $multi->set('hoge', 'piyo');
  488. });
  489. $this->assertEquals(1, count($replies));
  490. $this->assertFalse($client->exists('foo'));
  491. $this->assertTrue($client->exists('hoge'));
  492. }
  493. function testMultiExecBlock_DiscardEmpty() {
  494. $client = RC::getConnection();
  495. $client->flushdb();
  496. $replies = $client->multiExec(function($multi) {
  497. $multi->discard();
  498. });
  499. $this->assertEquals(0, count($replies));
  500. }
  501. function testMultiExecBlock_Watch() {
  502. $client1 = RC::getConnection();
  503. $client2 = RC::getConnection(true);
  504. $client1->flushdb();
  505. RC::testForAbortedMultiExecException($this, function()
  506. use($client1, $client2) {
  507. $client1->multiExec(array('watch' => 'sentinel'), function($multi)
  508. use ($client2) {
  509. $multi->set('sentinel', 'client1');
  510. $multi->get('sentinel');
  511. $client2->set('sentinel', 'client2');
  512. });
  513. });
  514. $this->assertEquals('client2', $client1->get('sentinel'));
  515. }
  516. }
  517. ?>