RedisConnectionTest.php 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  1. <?php
  2. namespace Illuminate\Tests\Redis;
  3. use Illuminate\Contracts\Events\Dispatcher;
  4. use Illuminate\Foundation\Application;
  5. use Illuminate\Foundation\Testing\Concerns\InteractsWithRedis;
  6. use Illuminate\Redis\Connections\Connection;
  7. use Illuminate\Redis\Connections\PhpRedisConnection;
  8. use Illuminate\Redis\RedisManager;
  9. use Mockery as m;
  10. use PHPUnit\Framework\TestCase;
  11. use Predis\Client;
  12. use Redis;
  13. class RedisConnectionTest extends TestCase
  14. {
  15. use InteractsWithRedis;
  16. protected function setUp(): void
  17. {
  18. parent::setUp();
  19. $this->setUpRedis();
  20. }
  21. protected function tearDown(): void
  22. {
  23. parent::tearDown();
  24. $this->tearDownRedis();
  25. m::close();
  26. }
  27. public function testItSetsValuesWithExpiry()
  28. {
  29. foreach ($this->connections() as $redis) {
  30. $redis->set('one', 'mohamed', 'EX', 5, 'NX');
  31. $this->assertSame('mohamed', $redis->get('one'));
  32. $this->assertNotEquals(-1, $redis->ttl('one'));
  33. // It doesn't override when NX mode
  34. $redis->set('one', 'taylor', 'EX', 5, 'NX');
  35. $this->assertSame('mohamed', $redis->get('one'));
  36. // It overrides when XX mode
  37. $redis->set('one', 'taylor', 'EX', 5, 'XX');
  38. $this->assertSame('taylor', $redis->get('one'));
  39. // It fails if XX mode is on and key doesn't exist
  40. $redis->set('two', 'taylor', 'PX', 5, 'XX');
  41. $this->assertNull($redis->get('two'));
  42. $redis->set('three', 'mohamed', 'PX', 5000);
  43. $this->assertSame('mohamed', $redis->get('three'));
  44. $this->assertNotEquals(-1, $redis->ttl('three'));
  45. $this->assertNotEquals(-1, $redis->pttl('three'));
  46. $redis->flushall();
  47. }
  48. }
  49. public function testItDeletesKeys()
  50. {
  51. foreach ($this->connections() as $redis) {
  52. $redis->set('one', 'mohamed');
  53. $redis->set('two', 'mohamed');
  54. $redis->set('three', 'mohamed');
  55. $redis->del('one');
  56. $this->assertNull($redis->get('one'));
  57. $this->assertNotNull($redis->get('two'));
  58. $this->assertNotNull($redis->get('three'));
  59. $redis->del('two', 'three');
  60. $this->assertNull($redis->get('two'));
  61. $this->assertNull($redis->get('three'));
  62. $redis->flushall();
  63. }
  64. }
  65. public function testItChecksForExistence()
  66. {
  67. foreach ($this->connections() as $redis) {
  68. $redis->set('one', 'mohamed');
  69. $redis->set('two', 'mohamed');
  70. $this->assertEquals(1, $redis->exists('one'));
  71. $this->assertEquals(0, $redis->exists('nothing'));
  72. $this->assertEquals(2, $redis->exists('one', 'two'));
  73. $this->assertEquals(2, $redis->exists('one', 'two', 'nothing'));
  74. $redis->flushall();
  75. }
  76. }
  77. public function testItExpiresKeys()
  78. {
  79. foreach ($this->connections() as $redis) {
  80. $redis->set('one', 'mohamed');
  81. $this->assertEquals(-1, $redis->ttl('one'));
  82. $this->assertEquals(1, $redis->expire('one', 10));
  83. $this->assertNotEquals(-1, $redis->ttl('one'));
  84. $this->assertEquals(0, $redis->expire('nothing', 10));
  85. $redis->set('two', 'mohamed');
  86. $this->assertEquals(-1, $redis->ttl('two'));
  87. $this->assertEquals(1, $redis->pexpire('two', 10));
  88. $this->assertNotEquals(-1, $redis->pttl('two'));
  89. $this->assertEquals(0, $redis->pexpire('nothing', 10));
  90. $redis->flushall();
  91. }
  92. }
  93. public function testItRenamesKeys()
  94. {
  95. foreach ($this->connections() as $redis) {
  96. $redis->set('one', 'mohamed');
  97. $redis->rename('one', 'two');
  98. $this->assertNull($redis->get('one'));
  99. $this->assertSame('mohamed', $redis->get('two'));
  100. $redis->set('three', 'adam');
  101. $redis->renamenx('two', 'three');
  102. $this->assertSame('mohamed', $redis->get('two'));
  103. $this->assertSame('adam', $redis->get('three'));
  104. $redis->renamenx('two', 'four');
  105. $this->assertNull($redis->get('two'));
  106. $this->assertSame('mohamed', $redis->get('four'));
  107. $this->assertSame('adam', $redis->get('three'));
  108. $redis->flushall();
  109. }
  110. }
  111. public function testItAddsMembersToSortedSet()
  112. {
  113. foreach ($this->connections() as $redis) {
  114. $redis->zadd('set', 1, 'mohamed');
  115. $this->assertEquals(1, $redis->zcard('set'));
  116. $redis->zadd('set', 2, 'taylor', 3, 'adam');
  117. $this->assertEquals(3, $redis->zcard('set'));
  118. $redis->zadd('set', ['jeffrey' => 4, 'matt' => 5]);
  119. $this->assertEquals(5, $redis->zcard('set'));
  120. $redis->zadd('set', 'NX', 1, 'beric');
  121. $this->assertEquals(6, $redis->zcard('set'));
  122. $redis->zadd('set', 'NX', ['joffrey' => 1]);
  123. $this->assertEquals(7, $redis->zcard('set'));
  124. $redis->zadd('set', 'XX', ['ned' => 1]);
  125. $this->assertEquals(7, $redis->zcard('set'));
  126. $this->assertEquals(1, $redis->zadd('set', ['sansa' => 10]));
  127. $this->assertEquals(0, $redis->zadd('set', 'XX', 'CH', ['arya' => 11]));
  128. $redis->zadd('set', ['mohamed' => 100]);
  129. $this->assertEquals(100, $redis->zscore('set', 'mohamed'));
  130. $redis->flushall();
  131. }
  132. }
  133. public function testItCountsMembersInSortedSet()
  134. {
  135. foreach ($this->connections() as $redis) {
  136. $redis->zadd('set', ['jeffrey' => 1, 'matt' => 10]);
  137. $this->assertEquals(1, $redis->zcount('set', 1, 5));
  138. $this->assertEquals(2, $redis->zcount('set', '-inf', '+inf'));
  139. $this->assertEquals(2, $redis->zcard('set'));
  140. $redis->flushall();
  141. }
  142. }
  143. public function testItIncrementsScoreOfSortedSet()
  144. {
  145. foreach ($this->connections() as $redis) {
  146. $redis->zadd('set', ['jeffrey' => 1, 'matt' => 10]);
  147. $redis->zincrby('set', 2, 'jeffrey');
  148. $this->assertEquals(3, $redis->zscore('set', 'jeffrey'));
  149. $redis->flushall();
  150. }
  151. }
  152. public function testItSetsKeyIfNotExists()
  153. {
  154. foreach ($this->connections() as $redis) {
  155. $redis->set('name', 'mohamed');
  156. $this->assertSame(0, $redis->setnx('name', 'taylor'));
  157. $this->assertSame('mohamed', $redis->get('name'));
  158. $this->assertSame(1, $redis->setnx('boss', 'taylor'));
  159. $this->assertSame('taylor', $redis->get('boss'));
  160. $redis->flushall();
  161. }
  162. }
  163. public function testItSetsHashFieldIfNotExists()
  164. {
  165. foreach ($this->connections() as $redis) {
  166. $redis->hset('person', 'name', 'mohamed');
  167. $this->assertSame(0, $redis->hsetnx('person', 'name', 'taylor'));
  168. $this->assertSame('mohamed', $redis->hget('person', 'name'));
  169. $this->assertSame(1, $redis->hsetnx('person', 'boss', 'taylor'));
  170. $this->assertSame('taylor', $redis->hget('person', 'boss'));
  171. $redis->flushall();
  172. }
  173. }
  174. public function testItCalculatesIntersectionOfSortedSetsAndStores()
  175. {
  176. foreach ($this->connections() as $redis) {
  177. $redis->zadd('set1', ['jeffrey' => 1, 'matt' => 2, 'taylor' => 3]);
  178. $redis->zadd('set2', ['jeffrey' => 2, 'matt' => 3]);
  179. $redis->zinterstore('output', ['set1', 'set2']);
  180. $this->assertEquals(2, $redis->zcard('output'));
  181. $this->assertEquals(3, $redis->zscore('output', 'jeffrey'));
  182. $this->assertEquals(5, $redis->zscore('output', 'matt'));
  183. $redis->zinterstore('output2', ['set1', 'set2'], [
  184. 'weights' => [3, 2],
  185. 'aggregate' => 'sum',
  186. ]);
  187. $this->assertEquals(7, $redis->zscore('output2', 'jeffrey'));
  188. $this->assertEquals(12, $redis->zscore('output2', 'matt'));
  189. $redis->zinterstore('output3', ['set1', 'set2'], [
  190. 'weights' => [3, 2],
  191. 'aggregate' => 'min',
  192. ]);
  193. $this->assertEquals(3, $redis->zscore('output3', 'jeffrey'));
  194. $this->assertEquals(6, $redis->zscore('output3', 'matt'));
  195. $redis->flushall();
  196. }
  197. }
  198. public function testItCalculatesUnionOfSortedSetsAndStores()
  199. {
  200. foreach ($this->connections() as $redis) {
  201. $redis->zadd('set1', ['jeffrey' => 1, 'matt' => 2, 'taylor' => 3]);
  202. $redis->zadd('set2', ['jeffrey' => 2, 'matt' => 3]);
  203. $redis->zunionstore('output', ['set1', 'set2']);
  204. $this->assertEquals(3, $redis->zcard('output'));
  205. $this->assertEquals(3, $redis->zscore('output', 'jeffrey'));
  206. $this->assertEquals(5, $redis->zscore('output', 'matt'));
  207. $this->assertEquals(3, $redis->zscore('output', 'taylor'));
  208. $redis->zunionstore('output2', ['set1', 'set2'], [
  209. 'weights' => [3, 2],
  210. 'aggregate' => 'sum',
  211. ]);
  212. $this->assertEquals(7, $redis->zscore('output2', 'jeffrey'));
  213. $this->assertEquals(12, $redis->zscore('output2', 'matt'));
  214. $this->assertEquals(9, $redis->zscore('output2', 'taylor'));
  215. $redis->zunionstore('output3', ['set1', 'set2'], [
  216. 'weights' => [3, 2],
  217. 'aggregate' => 'min',
  218. ]);
  219. $this->assertEquals(3, $redis->zscore('output3', 'jeffrey'));
  220. $this->assertEquals(6, $redis->zscore('output3', 'matt'));
  221. $this->assertEquals(9, $redis->zscore('output3', 'taylor'));
  222. $redis->flushall();
  223. }
  224. }
  225. public function testItReturnsRangeInSortedSet()
  226. {
  227. foreach ($this->connections() as $connector => $redis) {
  228. $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10]);
  229. $this->assertEquals(['jeffrey', 'matt'], $redis->zrange('set', 0, 1));
  230. $this->assertEquals(['jeffrey', 'matt', 'taylor'], $redis->zrange('set', 0, -1));
  231. if ($connector === 'predis') {
  232. $this->assertEquals(['jeffrey' => 1, 'matt' => 5], $redis->zrange('set', 0, 1, 'withscores'));
  233. } else {
  234. $this->assertEquals(['jeffrey' => 1, 'matt' => 5], $redis->zrange('set', 0, 1, true));
  235. }
  236. $redis->flushall();
  237. }
  238. }
  239. public function testItReturnsRevRangeInSortedSet()
  240. {
  241. foreach ($this->connections() as $connector => $redis) {
  242. $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10]);
  243. $this->assertEquals(['taylor', 'matt'], $redis->ZREVRANGE('set', 0, 1));
  244. $this->assertEquals(['taylor', 'matt', 'jeffrey'], $redis->ZREVRANGE('set', 0, -1));
  245. if ($connector === 'predis') {
  246. $this->assertEquals(['matt' => 5, 'taylor' => 10], $redis->ZREVRANGE('set', 0, 1, 'withscores'));
  247. } else {
  248. $this->assertEquals(['matt' => 5, 'taylor' => 10], $redis->ZREVRANGE('set', 0, 1, true));
  249. }
  250. $redis->flushall();
  251. }
  252. }
  253. public function testItReturnsRangeByScoreInSortedSet()
  254. {
  255. foreach ($this->connections() as $redis) {
  256. $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10]);
  257. $this->assertEquals(['jeffrey'], $redis->zrangebyscore('set', 0, 3));
  258. $this->assertEquals(['matt' => 5, 'taylor' => 10], $redis->zrangebyscore('set', 0, 11, [
  259. 'withscores' => true,
  260. 'limit' => [
  261. 'offset' => 1,
  262. 'count' => 2,
  263. ],
  264. ]));
  265. $this->assertEquals(['matt' => 5, 'taylor' => 10], $redis->zrangebyscore('set', 0, 11, [
  266. 'withscores' => true,
  267. 'limit' => [1, 2],
  268. ]));
  269. $redis->flushall();
  270. }
  271. }
  272. public function testItReturnsRevRangeByScoreInSortedSet()
  273. {
  274. foreach ($this->connections() as $redis) {
  275. $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10]);
  276. $this->assertEquals(['taylor'], $redis->ZREVRANGEBYSCORE('set', 10, 6));
  277. $this->assertEquals(['matt' => 5, 'jeffrey' => 1], $redis->ZREVRANGEBYSCORE('set', 10, 0, [
  278. 'withscores' => true,
  279. 'limit' => [
  280. 'offset' => 1,
  281. 'count' => 2,
  282. ],
  283. ]));
  284. $this->assertEquals(['matt' => 5, 'jeffrey' => 1], $redis->ZREVRANGEBYSCORE('set', 10, 0, [
  285. 'withscores' => true,
  286. 'limit' => [1, 2],
  287. ]));
  288. $redis->flushall();
  289. }
  290. }
  291. public function testItReturnsRankInSortedSet()
  292. {
  293. foreach ($this->connections() as $redis) {
  294. $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10]);
  295. $this->assertEquals(0, $redis->zrank('set', 'jeffrey'));
  296. $this->assertEquals(2, $redis->zrank('set', 'taylor'));
  297. $redis->flushall();
  298. }
  299. }
  300. public function testItReturnsScoreInSortedSet()
  301. {
  302. foreach ($this->connections() as $redis) {
  303. $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10]);
  304. $this->assertEquals(1, $redis->zscore('set', 'jeffrey'));
  305. $this->assertEquals(10, $redis->zscore('set', 'taylor'));
  306. $redis->flushall();
  307. }
  308. }
  309. public function testItRemovesMembersInSortedSet()
  310. {
  311. foreach ($this->connections() as $redis) {
  312. $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10, 'adam' => 11]);
  313. $redis->zrem('set', 'jeffrey');
  314. $this->assertEquals(3, $redis->zcard('set'));
  315. $redis->zrem('set', 'matt', 'adam');
  316. $this->assertEquals(1, $redis->zcard('set'));
  317. $redis->flushall();
  318. }
  319. }
  320. public function testItRemovesMembersByScoreInSortedSet()
  321. {
  322. foreach ($this->connections() as $redis) {
  323. $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10, 'adam' => 11]);
  324. $redis->ZREMRANGEBYSCORE('set', 5, '+inf');
  325. $this->assertEquals(1, $redis->zcard('set'));
  326. $redis->flushall();
  327. }
  328. }
  329. public function testItRemovesMembersByRankInSortedSet()
  330. {
  331. foreach ($this->connections() as $redis) {
  332. $redis->zadd('set', ['jeffrey' => 1, 'matt' => 5, 'taylor' => 10, 'adam' => 11]);
  333. $redis->ZREMRANGEBYRANK('set', 1, -1);
  334. $this->assertEquals(1, $redis->zcard('set'));
  335. $redis->flushall();
  336. }
  337. }
  338. public function testItSetsMultipleHashFields()
  339. {
  340. foreach ($this->connections() as $redis) {
  341. $redis->hmset('hash', ['name' => 'mohamed', 'hobby' => 'diving']);
  342. $this->assertEquals(['name' => 'mohamed', 'hobby' => 'diving'], $redis->hgetall('hash'));
  343. $redis->hmset('hash2', 'name', 'mohamed', 'hobby', 'diving');
  344. $this->assertEquals(['name' => 'mohamed', 'hobby' => 'diving'], $redis->hgetall('hash2'));
  345. $redis->flushall();
  346. }
  347. }
  348. public function testItGetsMultipleHashFields()
  349. {
  350. foreach ($this->connections() as $redis) {
  351. $redis->hmset('hash', ['name' => 'mohamed', 'hobby' => 'diving']);
  352. $this->assertEquals(['mohamed', 'diving'],
  353. $redis->hmget('hash', 'name', 'hobby')
  354. );
  355. $this->assertEquals(['mohamed', 'diving'],
  356. $redis->hmget('hash', ['name', 'hobby'])
  357. );
  358. $redis->flushall();
  359. }
  360. }
  361. public function testItGetsMultipleKeys()
  362. {
  363. $valueSet = ['name' => 'mohamed', 'hobby' => 'diving'];
  364. foreach ($this->connections() as $redis) {
  365. $redis->mset($valueSet);
  366. $this->assertEquals(
  367. array_values($valueSet),
  368. $redis->mget(array_keys($valueSet))
  369. );
  370. $redis->flushall();
  371. }
  372. }
  373. public function testItFlushes()
  374. {
  375. foreach ($this->connections() as $redis) {
  376. $redis->set('name', 'Till');
  377. $this->assertSame(1, $redis->exists('name'));
  378. $redis->flushdb();
  379. $this->assertSame(0, $redis->exists('name'));
  380. }
  381. }
  382. public function testItFlushesAsynchronous()
  383. {
  384. foreach ($this->connections() as $redis) {
  385. $redis->set('name', 'Till');
  386. $this->assertSame(1, $redis->exists('name'));
  387. $redis->flushdb('ASYNC');
  388. $this->assertSame(0, $redis->exists('name'));
  389. }
  390. }
  391. public function testItRunsEval()
  392. {
  393. foreach ($this->connections() as $redis) {
  394. if ($redis instanceof PhpRedisConnection) {
  395. // User must decide what needs to be serialized and compressed.
  396. $redis->eval('redis.call("set", KEYS[1], ARGV[1])', 1, 'name', ...$redis->pack(['mohamed']));
  397. } else {
  398. $redis->eval('redis.call("set", KEYS[1], ARGV[1])', 1, 'name', 'mohamed');
  399. }
  400. $this->assertSame('mohamed', $redis->get('name'));
  401. $redis->flushall();
  402. }
  403. }
  404. public function testItRunsPipes()
  405. {
  406. foreach ($this->connections() as $redis) {
  407. $result = $redis->pipeline(function ($pipe) {
  408. $pipe->set('test:pipeline:1', 1);
  409. $pipe->get('test:pipeline:1');
  410. $pipe->set('test:pipeline:2', 2);
  411. $pipe->get('test:pipeline:2');
  412. });
  413. $this->assertCount(4, $result);
  414. $this->assertEquals(1, $result[1]);
  415. $this->assertEquals(2, $result[3]);
  416. $redis->flushall();
  417. }
  418. }
  419. public function testItRunsTransactions()
  420. {
  421. foreach ($this->connections() as $redis) {
  422. $result = $redis->transaction(function ($pipe) {
  423. $pipe->set('test:transaction:1', 1);
  424. $pipe->get('test:transaction:1');
  425. $pipe->set('test:transaction:2', 2);
  426. $pipe->get('test:transaction:2');
  427. });
  428. $this->assertCount(4, $result);
  429. $this->assertEquals(1, $result[1]);
  430. $this->assertEquals(2, $result[3]);
  431. $redis->flushall();
  432. }
  433. }
  434. public function testItRunsRawCommand()
  435. {
  436. foreach ($this->connections() as $redis) {
  437. $redis->executeRaw(['SET', 'test:raw:1', '1']);
  438. $this->assertEquals(
  439. 1, $redis->executeRaw(['GET', 'test:raw:1'])
  440. );
  441. $redis->flushall();
  442. }
  443. }
  444. public function testItDispatchesQueryEvent()
  445. {
  446. foreach ($this->connections() as $redis) {
  447. $redis->setEventDispatcher($events = m::mock(Dispatcher::class));
  448. $events->shouldReceive('dispatch')->once()->with(m::on(function ($event) {
  449. $this->assertSame('get', $event->command);
  450. $this->assertEquals(['foobar'], $event->parameters);
  451. $this->assertSame('default', $event->connectionName);
  452. $this->assertInstanceOf(Connection::class, $event->connection);
  453. return true;
  454. }));
  455. $redis->get('foobar');
  456. $redis->unsetEventDispatcher();
  457. }
  458. }
  459. public function testItPersistsConnection()
  460. {
  461. if (PHP_ZTS) {
  462. $this->markTestSkipped('PhpRedis does not support persistent connections with PHP_ZTS enabled.');
  463. }
  464. $this->assertSame(
  465. 'laravel',
  466. $this->connections()['persistent']->getPersistentID()
  467. );
  468. }
  469. public function testItScansForKeys()
  470. {
  471. foreach ($this->connections() as $redis) {
  472. $initialKeys = ['test:scan:1', 'test:scan:2'];
  473. foreach ($initialKeys as $k => $key) {
  474. $redis->set($key, 'test');
  475. $initialKeys[$k] = $this->getPrefix($redis->client()).$key;
  476. }
  477. $iterator = null;
  478. do {
  479. [$cursor, $returnedKeys] = $redis->scan($iterator);
  480. if (! is_array($returnedKeys)) {
  481. $returnedKeys = [$returnedKeys];
  482. }
  483. foreach ($returnedKeys as $returnedKey) {
  484. $this->assertContains($returnedKey, $initialKeys);
  485. }
  486. } while ($iterator > 0);
  487. $redis->flushAll();
  488. }
  489. }
  490. public function testItZscansForKeys()
  491. {
  492. foreach ($this->connections() as $redis) {
  493. $members = [100 => 'test:zscan:1', 200 => 'test:zscan:2'];
  494. foreach ($members as $score => $member) {
  495. $redis->zadd('set', $score, $member);
  496. }
  497. $iterator = null;
  498. $result = [];
  499. do {
  500. [$iterator, $returnedMembers] = $redis->zscan('set', $iterator);
  501. if (! is_array($returnedMembers)) {
  502. $returnedMembers = [$returnedMembers];
  503. }
  504. foreach ($returnedMembers as $member => $score) {
  505. $this->assertArrayHasKey((int) $score, $members);
  506. $this->assertContains($member, $members);
  507. }
  508. $result += $returnedMembers;
  509. } while ($iterator > 0);
  510. $this->assertCount(2, $result);
  511. $iterator = null;
  512. [$iterator, $returned] = $redis->zscan('set', $iterator, ['match' => 'test:unmatch:*']);
  513. $this->assertEmpty($returned);
  514. $iterator = null;
  515. [$iterator, $returned] = $redis->zscan('set', $iterator, ['count' => 5]);
  516. $this->assertCount(2, $returned);
  517. $redis->flushAll();
  518. }
  519. }
  520. public function testItHscansForKeys()
  521. {
  522. foreach ($this->connections() as $redis) {
  523. $fields = ['name' => 'mohamed', 'hobby' => 'diving'];
  524. foreach ($fields as $field => $value) {
  525. $redis->hset('hash', $field, $value);
  526. }
  527. $iterator = null;
  528. $result = [];
  529. do {
  530. [$iterator, $returnedFields] = $redis->hscan('hash', $iterator);
  531. foreach ($returnedFields as $field => $value) {
  532. $this->assertArrayHasKey($field, $fields);
  533. $this->assertContains($value, $fields);
  534. }
  535. $result += $returnedFields;
  536. } while ($iterator > 0);
  537. $this->assertCount(2, $result);
  538. $iterator = null;
  539. [$iterator, $returned] = $redis->hscan('hash', $iterator, ['match' => 'test:unmatch:*']);
  540. $this->assertEmpty($returned);
  541. $iterator = null;
  542. [$iterator, $returned] = $redis->hscan('hash', $iterator, ['count' => 5]);
  543. $this->assertCount(2, $returned);
  544. $redis->flushAll();
  545. }
  546. }
  547. public function testItSscansForKeys()
  548. {
  549. foreach ($this->connections() as $redis) {
  550. $members = ['test:sscan:1', 'test:sscan:2'];
  551. foreach ($members as $member) {
  552. $redis->sadd('set', $member);
  553. }
  554. $iterator = null;
  555. $result = [];
  556. do {
  557. [$iterator, $returnedMembers] = $redis->sscan('set', $iterator);
  558. foreach ($returnedMembers as $member) {
  559. $this->assertContains($member, $members);
  560. array_push($result, $member);
  561. }
  562. } while ($iterator > 0);
  563. $this->assertCount(2, $result);
  564. $iterator = null;
  565. [$iterator, $returned] = $redis->sscan('set', $iterator, ['match' => 'test:unmatch:*']);
  566. $this->assertEmpty($returned);
  567. $iterator = null;
  568. [$iterator, $returned] = $redis->sscan('set', $iterator, ['count' => 5]);
  569. $this->assertCount(2, $returned);
  570. $redis->flushAll();
  571. }
  572. }
  573. public function testItSPopsForKeys()
  574. {
  575. foreach ($this->connections() as $redis) {
  576. $members = ['test:spop:1', 'test:spop:2', 'test:spop:3', 'test:spop:4'];
  577. foreach ($members as $member) {
  578. $redis->sadd('set', $member);
  579. }
  580. $result = $redis->spop('set');
  581. $this->assertIsNotArray($result);
  582. $this->assertContains($result, $members);
  583. $result = $redis->spop('set', 1);
  584. $this->assertIsArray($result);
  585. $this->assertCount(1, $result);
  586. $result = $redis->spop('set', 2);
  587. $this->assertIsArray($result);
  588. $this->assertCount(2, $result);
  589. $redis->flushAll();
  590. }
  591. }
  592. public function testPhpRedisScanOption()
  593. {
  594. foreach ($this->connections() as $redis) {
  595. if ($redis->client() instanceof Client) {
  596. continue;
  597. }
  598. $iterator = null;
  599. do {
  600. $returned = $redis->scan($iterator);
  601. if ($redis->client()->getOption(Redis::OPT_SCAN) === Redis::SCAN_RETRY) {
  602. $this->assertEmpty($returned);
  603. }
  604. } while ($iterator > 0);
  605. }
  606. }
  607. private function getPrefix($client)
  608. {
  609. if ($client instanceof Redis) {
  610. return $client->getOption(Redis::OPT_PREFIX);
  611. }
  612. return $client->getOptions()->prefix;
  613. }
  614. public function testMacroable()
  615. {
  616. Connection::macro('foo', function () {
  617. return 'foo';
  618. });
  619. foreach ($this->connections() as $redis) {
  620. $this->assertSame(
  621. 'foo',
  622. $redis->foo()
  623. );
  624. }
  625. }
  626. public function connections()
  627. {
  628. $connections = [
  629. 'predis' => $this->redis['predis']->connection(),
  630. 'phpredis' => $this->redis['phpredis']->connection(),
  631. ];
  632. $host = env('REDIS_HOST', '127.0.0.1');
  633. $port = env('REDIS_PORT', 6379);
  634. $connections[] = (new RedisManager(new Application, 'phpredis', [
  635. 'cluster' => false,
  636. 'default' => [
  637. 'url' => "redis://user@$host:$port",
  638. 'host' => 'overwrittenByUrl',
  639. 'port' => 'overwrittenByUrl',
  640. 'database' => 5,
  641. 'options' => ['prefix' => 'laravel:'],
  642. 'timeout' => 0.5,
  643. ],
  644. ]))->connection();
  645. $connections['persistent'] = (new RedisManager(new Application, 'phpredis', [
  646. 'cluster' => false,
  647. 'default' => [
  648. 'host' => $host,
  649. 'port' => $port,
  650. 'database' => 6,
  651. 'options' => ['prefix' => 'laravel:'],
  652. 'timeout' => 0.5,
  653. 'persistent' => true,
  654. 'persistent_id' => 'laravel',
  655. ],
  656. ]))->connection();
  657. $connections[] = (new RedisManager(new Application, 'phpredis', [
  658. 'cluster' => false,
  659. 'default' => [
  660. 'host' => $host,
  661. 'port' => $port,
  662. 'database' => 7,
  663. 'options' => ['serializer' => Redis::SERIALIZER_JSON],
  664. 'timeout' => 0.5,
  665. ],
  666. ]))->connection();
  667. $connections[] = (new RedisManager(new Application, 'phpredis', [
  668. 'cluster' => false,
  669. 'default' => [
  670. 'host' => $host,
  671. 'port' => $port,
  672. 'database' => 8,
  673. 'options' => ['scan' => Redis::SCAN_RETRY],
  674. 'timeout' => 0.5,
  675. ],
  676. ]))->connection();
  677. if (defined('Redis::COMPRESSION_LZF')) {
  678. $connections['compression_lzf'] = (new RedisManager(new Application, 'phpredis', [
  679. 'cluster' => false,
  680. 'default' => [
  681. 'host' => $host,
  682. 'port' => $port,
  683. 'database' => 9,
  684. 'options' => [
  685. 'compression' => Redis::COMPRESSION_LZF,
  686. 'name' => 'compression_lzf',
  687. ],
  688. 'timeout' => 0.5,
  689. ],
  690. ]))->connection();
  691. }
  692. if (defined('Redis::COMPRESSION_ZSTD')) {
  693. $connections['compression_zstd'] = (new RedisManager(new Application, 'phpredis', [
  694. 'cluster' => false,
  695. 'default' => [
  696. 'host' => $host,
  697. 'port' => $port,
  698. 'database' => 10,
  699. 'options' => [
  700. 'compression' => Redis::COMPRESSION_ZSTD,
  701. 'name' => 'compression_zstd',
  702. ],
  703. 'timeout' => 0.5,
  704. ],
  705. ]))->connection();
  706. $connections['compression_zstd_default'] = (new RedisManager(new Application, 'phpredis', [
  707. 'cluster' => false,
  708. 'default' => [
  709. 'host' => $host,
  710. 'port' => $port,
  711. 'database' => 11,
  712. 'options' => [
  713. 'compression' => Redis::COMPRESSION_ZSTD,
  714. 'compression_level' => Redis::COMPRESSION_ZSTD_DEFAULT,
  715. 'name' => 'compression_zstd_default',
  716. ],
  717. 'timeout' => 0.5,
  718. ],
  719. ]))->connection();
  720. $connections['compression_zstd_min'] = (new RedisManager(new Application, 'phpredis', [
  721. 'cluster' => false,
  722. 'default' => [
  723. 'host' => $host,
  724. 'port' => $port,
  725. 'database' => 12,
  726. 'options' => [
  727. 'compression' => Redis::COMPRESSION_ZSTD,
  728. 'compression_level' => Redis::COMPRESSION_ZSTD_MIN,
  729. 'name' => 'compression_zstd_min',
  730. ],
  731. 'timeout' => 0.5,
  732. ],
  733. ]))->connection();
  734. $connections['compression_zstd_max'] = (new RedisManager(new Application, 'phpredis', [
  735. 'cluster' => false,
  736. 'default' => [
  737. 'host' => $host,
  738. 'port' => $port,
  739. 'database' => 13,
  740. 'options' => [
  741. 'compression' => Redis::COMPRESSION_ZSTD,
  742. 'compression_level' => Redis::COMPRESSION_ZSTD_MAX,
  743. 'name' => 'compression_zstd_max',
  744. ],
  745. 'timeout' => 0.5,
  746. ],
  747. ]))->connection();
  748. }
  749. if (defined('Redis::COMPRESSION_LZ4')) {
  750. $connections['compression_lz4'] = (new RedisManager(new Application, 'phpredis', [
  751. 'cluster' => false,
  752. 'default' => [
  753. 'host' => $host,
  754. 'port' => $port,
  755. 'database' => 14,
  756. 'options' => [
  757. 'compression' => Redis::COMPRESSION_LZ4,
  758. 'name' => 'compression_lz4',
  759. ],
  760. 'timeout' => 0.5,
  761. ],
  762. ]))->connection();
  763. $connections['compression_lz4_default'] = (new RedisManager(new Application, 'phpredis', [
  764. 'cluster' => false,
  765. 'default' => [
  766. 'host' => $host,
  767. 'port' => $port,
  768. 'database' => 15,
  769. 'options' => [
  770. 'compression' => Redis::COMPRESSION_LZ4,
  771. 'compression_level' => 0,
  772. 'name' => 'compression_lz4_default',
  773. ],
  774. 'timeout' => 0.5,
  775. ],
  776. ]))->connection();
  777. $connections['compression_lz4_min'] = (new RedisManager(new Application, 'phpredis', [
  778. 'cluster' => false,
  779. 'default' => [
  780. 'host' => $host,
  781. 'port' => $port,
  782. 'database' => 16,
  783. 'options' => [
  784. 'compression' => Redis::COMPRESSION_LZ4,
  785. 'compression_level' => 1,
  786. 'name' => 'compression_lz4_min',
  787. ],
  788. 'timeout' => 0.5,
  789. ],
  790. ]))->connection();
  791. $connections['compression_lz4_max'] = (new RedisManager(new Application, 'phpredis', [
  792. 'cluster' => false,
  793. 'default' => [
  794. 'host' => $host,
  795. 'port' => $port,
  796. 'database' => 17,
  797. 'options' => [
  798. 'compression' => Redis::COMPRESSION_LZ4,
  799. 'compression_level' => 12,
  800. 'name' => 'compression_lz4_max',
  801. ],
  802. 'timeout' => 0.5,
  803. ],
  804. ]))->connection();
  805. }
  806. return $connections;
  807. }
  808. }