2 namespace TYPO3\CMS\Core\Tests\Functional\Cache\Backend
;
5 * This file is part of the TYPO3 CMS project.
7 * It is free software; you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License, either version 2
9 * of the License, or any later version.
11 * For the full copyright and license information, please read the
12 * LICENSE.txt file that was distributed with this source code.
14 * The TYPO3 project - inspiring people to share!
16 use TYPO3\CMS\Core\Cache\Backend\RedisBackend
;
17 use TYPO3\CMS\Core\Cache\Exception\InvalidDataException
;
18 use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
;
19 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase
;
22 * Test case for the cache to redis backend
25 * These functional tests use and flush redis database numbers 0 and 1 on the
26 * redis host specified by environment variable typo3RedisHost
28 * @requires extension redis
30 class RedisBackendTest
extends FunctionalTestCase
35 protected function setUp()
37 // Note this functional does NOT call parent::setUp() since it does
38 // not need a full blown instance and database
39 if (!getenv('typo3TestingRedisHost')) {
40 $this->markTestSkipped('environment variable "typo3TestingRedisHost" must be set to run this test');
42 // Note we assume that if that typo3TestingRedisHost env is set, we can use that for testing,
43 // there is no test to see if the daemon is actually up and running. Tests will fail if env
44 // is set but daemon is down.
48 * Sets up the redis cache backend used for testing
50 protected function setUpSubject(array $backendOptions = []): RedisBackend
52 // We know this env is set, otherwise setUp() would skip the tests
53 $backendOptions['hostname'] = getenv('typo3TestingRedisHost');
54 // If typo3TestingRedisPort env is set, use it, otherwise fall back to standard port
55 $env = getenv('typo3TestingRedisPort');
56 $backendOptions['port'] = is_string($env) ?
(int)$env : 6379;
58 $frontendProphecy = $this->prophesize(FrontendInterface
::class);
59 $frontendProphecy->getIdentifier()->willReturn('cache_pages');
61 $subject = new RedisBackend('Testing', $backendOptions);
62 $subject->setCache($frontendProphecy->reveal());
63 $subject->initializeObject();
69 * Sets up a test-internal redis connection to check implementation details
71 protected function setUpRedis(): \Redis
73 // We know this env is set, otherwise setUp() would skip the tests
74 $redisHost = getenv('typo3TestingRedisHost');
75 // If typo3TestingRedisPort env is set, use it, otherwise fall back to standard port
76 $env = getenv('typo3TestingRedisPort');
77 $redisPort = is_string($env) ?
(int)$env : 6379;
79 $redis = new \
Redis();
80 $redis->connect($redisHost, $redisPort);
87 public function setDatabaseThrowsExceptionIfGivenDatabaseNumberIsNotAnInteger()
89 $this->expectException(\InvalidArgumentException
::class);
90 $this->expectExceptionCode(1279763057);
92 $this->setUpSubject(['database' => 'foo']);
98 public function setDatabaseThrowsExceptionIfGivenDatabaseNumberIsNegative()
100 $this->expectException(\InvalidArgumentException
::class);
101 $this->expectExceptionCode(1279763534);
103 $this->setUpSubject(['database' => -1]);
109 public function setCompressionThrowsExceptionIfCompressionParameterIsNotOfTypeBoolean()
111 $this->expectException(\InvalidArgumentException
::class);
112 $this->expectExceptionCode(1289679153);
114 $this->setUpSubject(['compression' => 'foo']);
120 public function setCompressionLevelThrowsExceptionIfCompressionLevelIsNotInteger()
122 $this->expectException(\InvalidArgumentException
::class);
123 $this->expectExceptionCode(1289679154);
125 $this->setUpSubject(['compressionLevel' => 'foo']);
131 public function setCompressionLevelThrowsExceptionIfCompressionLevelIsNotBetweenMinusOneAndNine()
133 $this->expectException(\InvalidArgumentException
::class);
134 $this->expectExceptionCode(1289679155);
136 $this->setUpSubject(['compressionLevel' => 11]);
142 public function setConnectionTimeoutThrowsExceptionIfConnectionTimeoutIsNotInteger()
144 $this->expectException(\InvalidArgumentException
::class);
145 $this->expectExceptionCode(1487849315);
147 $this->setUpSubject(['connectionTimeout' => 'foo']);
153 public function setConnectionTimeoutThrowsExceptionIfConnectionTimeoutIsNegative()
155 $this->expectException(\InvalidArgumentException
::class);
156 $this->expectExceptionCode(1487849326);
158 $this->setUpSubject(['connectionTimeout' => -1]);
164 public function setThrowsExceptionIfIdentifierIsNotAString()
166 $this->expectException(\InvalidArgumentException
::class);
167 $this->expectExceptionCode(1377006651);
169 $subject = $this->setUpSubject();
170 $subject->set([], 'data');
176 public function setThrowsExceptionIfDataIsNotAString()
178 $this->expectException(InvalidDataException
::class);
179 $this->expectExceptionCode(1279469941);
181 $subject = $this->setUpSubject();
182 $subject->set($this->getUniqueId('identifier'), []);
188 public function setThrowsExceptionIfLifetimeIsNegative()
190 $this->expectException(\InvalidArgumentException
::class);
191 $this->expectExceptionCode(1279487573);
193 $subject = $this->setUpSubject();
194 $subject->set($this->getUniqueId('identifier'), 'data', [], -42);
200 public function setThrowsExceptionIfLifetimeIsNotNullOrAnInteger()
202 $this->expectException(\InvalidArgumentException
::class);
203 $this->expectExceptionCode(1279488008);
205 $subject = $this->setUpSubject();
206 $subject->set($this->getUniqueId('identifier'), 'data', [], []);
212 public function setStoresEntriesInSelectedDatabase()
214 $redis = $this->setUpRedis();
216 $subject = $this->setUpSubject(['database' => 1]);
217 $identifier = $this->getUniqueId('identifier');
218 $subject->set($identifier, 'data');
219 $result = $redis->exists('identData:' . $identifier);
220 if (is_int($result)) {
221 // Since 3.1.4 of phpredis/phpredis the return types has been changed
222 $result = (bool)$result;
224 $this->assertTrue($result);
230 public function setSavesStringDataTypeForIdentifierToDataEntry()
232 $subject = $this->setUpSubject();
233 $redis = $this->setUpRedis();
234 $identifier = $this->getUniqueId('identifier');
235 $subject->set($identifier, 'data');
236 $this->assertSame(\Redis
::REDIS_STRING
, $redis->type('identData:' . $identifier));
242 public function setSavesEntryWithDefaultLifeTime()
244 $subject = $this->setUpSubject();
245 $redis = $this->setUpRedis();
246 $identifier = $this->getUniqueId('identifier');
247 $defaultLifetime = 42;
248 $subject->setDefaultLifetime($defaultLifetime);
249 $subject->set($identifier, 'data');
250 $lifetimeRegisteredInBackend = $redis->ttl('identData:' . $identifier);
251 $this->assertSame($defaultLifetime, $lifetimeRegisteredInBackend);
257 public function setSavesEntryWithSpecifiedLifeTime()
259 $subject = $this->setUpSubject();
260 $redis = $this->setUpRedis();
261 $identifier = $this->getUniqueId('identifier');
263 $subject->set($identifier, 'data', [], $lifetime);
264 $lifetimeRegisteredInBackend = $redis->ttl('identData:' . $identifier);
265 $this->assertSame($lifetime, $lifetimeRegisteredInBackend);
271 public function setSavesEntryWithUnlimitedLifeTime()
273 $subject = $this->setUpSubject();
274 $redis = $this->setUpRedis();
275 $identifier = $this->getUniqueId('identifier');
276 $subject->set($identifier, 'data', [], 0);
277 $lifetimeRegisteredInBackend = $redis->ttl('identData:' . $identifier);
278 $this->assertSame(31536000, $lifetimeRegisteredInBackend);
284 public function setOverwritesExistingEntryWithNewData()
286 $subject = $this->setUpSubject();
288 $identifier = $this->getUniqueId('identifier');
289 $subject->set($identifier, $data);
290 $otherData = 'data 2';
291 $subject->set($identifier, $otherData);
292 $fetchedData = $subject->get($identifier);
293 $this->assertSame($otherData, $fetchedData);
299 public function setOverwritesExistingEntryWithSpecifiedLifetime()
301 $subject = $this->setUpSubject();
302 $redis = $this->setUpRedis();
304 $identifier = $this->getUniqueId('identifier');
305 $subject->set($identifier, $data);
307 $subject->set($identifier, $data, [], $lifetime);
308 $lifetimeRegisteredInBackend = $redis->ttl('identData:' . $identifier);
309 $this->assertSame($lifetime, $lifetimeRegisteredInBackend);
315 public function setOverwritesExistingEntryWithNewDefaultLifetime()
317 $subject = $this->setUpSubject();
318 $redis = $this->setUpRedis();
320 $identifier = $this->getUniqueId('identifier');
322 $subject->set($identifier, $data, [], $lifetime);
323 $newDefaultLifetime = 43;
324 $subject->setDefaultLifetime($newDefaultLifetime);
325 $subject->set($identifier, $data, [], $newDefaultLifetime);
326 $lifetimeRegisteredInBackend = $redis->ttl('identData:' . $identifier);
327 $this->assertSame($newDefaultLifetime, $lifetimeRegisteredInBackend);
333 public function setOverwritesExistingEntryWithNewUnlimitedLifetime()
335 $subject = $this->setUpSubject();
336 $redis = $this->setUpRedis();
338 $identifier = $this->getUniqueId('identifier');
340 $subject->set($identifier, $data, [], $lifetime);
341 $subject->set($identifier, $data, [], 0);
342 $lifetimeRegisteredInBackend = $redis->ttl('identData:' . $identifier);
343 $this->assertSame(31536000, $lifetimeRegisteredInBackend);
349 public function setSavesSetDataTypeForIdentifierToTagsSet()
351 $subject = $this->setUpSubject();
352 $redis = $this->setUpRedis();
353 $identifier = $this->getUniqueId('identifier');
354 $subject->set($identifier, 'data', ['tag']);
355 $this->assertSame(\Redis
::REDIS_SET
, $redis->type('identTags:' . $identifier));
361 public function setSavesSpecifiedTagsInIdentifierToTagsSet()
363 $subject = $this->setUpSubject();
364 $redis = $this->setUpRedis();
365 $identifier = $this->getUniqueId('identifier');
366 $tags = ['thatTag', 'thisTag'];
367 $subject->set($identifier, 'data', $tags);
368 $savedTags = $redis->sMembers('identTags:' . $identifier);
370 $this->assertSame($tags, $savedTags);
376 public function setRemovesAllPreviouslySetTagsFromIdentifierToTagsSet()
378 $subject = $this->setUpSubject();
379 $redis = $this->setUpRedis();
380 $identifier = $this->getUniqueId('identifier');
381 $tags = ['fooTag', 'barTag'];
382 $subject->set($identifier, 'data', $tags);
383 $subject->set($identifier, 'data', []);
384 $this->assertSame([], $redis->sMembers('identTags:' . $identifier));
390 public function setRemovesMultiplePreviouslySetTagsFromIdentifierToTagsSet()
392 $subject = $this->setUpSubject();
393 $redis = $this->setUpRedis();
394 $identifier = $this->getUniqueId('identifier');
395 $firstTagSet = ['tag1', 'tag2', 'tag3', 'tag4'];
396 $subject->set($identifier, 'data', $firstTagSet);
397 $secondTagSet = ['tag1', 'tag3'];
398 $subject->set($identifier, 'data', $secondTagSet);
399 $actualTagSet = $redis->sMembers('identTags:' . $identifier);
401 $this->assertSame($secondTagSet, $actualTagSet);
407 public function setSavesSetDataTypeForTagToIdentifiersSet()
409 $subject = $this->setUpSubject();
410 $redis = $this->setUpRedis();
411 $identifier = $this->getUniqueId('identifier');
413 $subject->set($identifier, 'data', [$tag]);
414 $this->assertSame(\Redis
::REDIS_SET
, $redis->type('tagIdents:' . $tag));
420 public function setSavesIdentifierInTagToIdentifiersSetOfSpecifiedTag()
422 $subject = $this->setUpSubject();
423 $redis = $this->setUpRedis();
424 $identifier = $this->getUniqueId('identifier');
426 $subject->set($identifier, 'data', [$tag]);
427 $savedTagToIdentifiersMemberArray = $redis->sMembers('tagIdents:' . $tag);
428 $this->assertSame([$identifier], $savedTagToIdentifiersMemberArray);
434 public function setAppendsSecondIdentifierInTagToIdentifiersEntry()
436 $subject = $this->setUpSubject();
437 $redis = $this->setUpRedis();
438 $firstIdentifier = $this->getUniqueId('identifier1-');
440 $subject->set($firstIdentifier, 'data', [$tag]);
441 $secondIdentifier = $this->getUniqueId('identifier2-');
442 $subject->set($secondIdentifier, 'data', [$tag]);
443 $savedTagToIdentifiersMemberArray = $redis->sMembers('tagIdents:' . $tag);
444 sort($savedTagToIdentifiersMemberArray);
445 $identifierArray = [$firstIdentifier, $secondIdentifier];
446 sort($identifierArray);
447 $this->assertSame([$firstIdentifier, $secondIdentifier], $savedTagToIdentifiersMemberArray);
453 public function setRemovesIdentifierFromTagToIdentifiersEntryIfTagIsOmittedOnConsecutiveSet()
455 $subject = $this->setUpSubject();
456 $redis = $this->setUpRedis();
457 $identifier = $this->getUniqueId('identifier');
459 $subject->set($identifier, 'data', [$tag]);
460 $subject->set($identifier, 'data', []);
461 $savedTagToIdentifiersMemberArray = $redis->sMembers('tagIdents:' . $tag);
462 $this->assertSame([], $savedTagToIdentifiersMemberArray);
468 public function setAddsIdentifierInTagToIdentifiersEntryIfTagIsAddedOnConsecutiveSet()
470 $subject = $this->setUpSubject();
471 $redis = $this->setUpRedis();
472 $identifier = $this->getUniqueId('identifier');
473 $subject->set($identifier, 'data');
475 $subject->set($identifier, 'data', [$tag]);
476 $savedTagToIdentifiersMemberArray = $redis->sMembers('tagIdents:' . $tag);
477 $this->assertSame([$identifier], $savedTagToIdentifiersMemberArray);
483 public function setSavesCompressedDataWithEnabledCompression()
485 $subject = $this->setUpSubject([
486 'compression' => true
488 $redis = $this->setUpRedis();
489 $identifier = $this->getUniqueId('identifier');
490 $data = 'some data ' . microtime();
491 $subject->set($identifier, $data);
492 $uncompresedStoredData = '';
494 $uncompresedStoredData = @gzuncompress
($redis->get('identData:' . $identifier));
495 } catch (\Exception
$e) {
497 $this->assertEquals($data, $uncompresedStoredData, 'Original and compressed data don\'t match');
503 public function setSavesPlaintextDataWithEnabledCompressionAndCompressionLevel0()
505 $subject = $this->setUpSubject([
506 'compression' => true,
507 'compressionLevel' => 0
509 $redis = $this->setUpRedis();
510 $identifier = $this->getUniqueId('identifier');
511 $data = 'some data ' . microtime();
512 $subject->set($identifier, $data);
513 $this->assertGreaterThan(0, substr_count($redis->get('identData:' . $identifier), $data), 'Plaintext data not found');
519 public function hasThrowsExceptionIfIdentifierIsNotAString()
521 $this->expectException(\InvalidArgumentException
::class);
522 $this->expectExceptionCode(1377006653);
524 $subject = $this->setUpSubject();
531 public function hasReturnsFalseForNotExistingEntry()
533 $subject = $this->setUpSubject();
534 $identifier = $this->getUniqueId('identifier');
535 $this->assertFalse($subject->has($identifier));
541 public function hasReturnsTrueForPreviouslySetEntry()
543 $subject = $this->setUpSubject();
544 $identifier = $this->getUniqueId('identifier');
545 $subject->set($identifier, 'data');
546 $this->assertTrue($subject->has($identifier));
552 public function getThrowsExceptionIfIdentifierIsNotAString()
554 $this->expectException(\InvalidArgumentException
::class);
555 //@todo Add exception code with redis extension
557 $subject = $this->setUpSubject();
564 public function getReturnsPreviouslyCompressedSetEntry()
566 $subject = $this->setUpSubject([
567 'compression' => true
570 $identifier = $this->getUniqueId('identifier');
571 $subject->set($identifier, $data);
572 $fetchedData = $subject->get($identifier);
573 $this->assertSame($data, $fetchedData);
579 public function getReturnsPreviouslySetEntry()
581 $subject = $this->setUpSubject();
583 $identifier = $this->getUniqueId('identifier');
584 $subject->set($identifier, $data);
585 $fetchedData = $subject->get($identifier);
586 $this->assertSame($data, $fetchedData);
592 public function removeThrowsExceptionIfIdentifierIsNotAString()
594 $this->expectException(\InvalidArgumentException
::class);
595 $this->expectExceptionCode(1377006654);
597 $subject = $this->setUpSubject();
598 $subject->remove([]);
604 public function removeReturnsFalseIfNoEntryWasDeleted()
606 $subject = $this->setUpSubject();
607 $this->assertFalse($subject->remove($this->getUniqueId('identifier')));
613 public function removeReturnsTrueIfAnEntryWasDeleted()
615 $subject = $this->setUpSubject();
616 $identifier = $this->getUniqueId('identifier');
617 $subject->set($identifier, 'data');
618 $this->assertTrue($subject->remove($identifier));
624 public function removeDeletesEntryFromCache()
626 $subject = $this->setUpSubject();
627 $identifier = $this->getUniqueId('identifier');
628 $subject->set($identifier, 'data');
629 $subject->remove($identifier);
630 $this->assertFalse($subject->has($identifier));
636 public function removeDeletesIdentifierToTagEntry()
638 $subject = $this->setUpSubject();
639 $redis = $this->setUpRedis();
640 $identifier = $this->getUniqueId('identifier');
642 $subject->set($identifier, 'data', [$tag]);
643 $subject->remove($identifier);
644 $result = $redis->exists('identTags:' . $identifier);
645 if (is_int($result)) {
646 // Since 3.1.4 of phpredis/phpredis the return types has been changed
647 $result = (bool)$result;
649 $this->assertFalse($result);
655 public function removeDeletesIdentifierFromTagToIdentifiersSet()
657 $subject = $this->setUpSubject();
658 $redis = $this->setUpRedis();
659 $identifier = $this->getUniqueId('identifier');
661 $subject->set($identifier, 'data', [$tag]);
662 $subject->remove($identifier);
663 $tagToIdentifiersMemberArray = $redis->sMembers('tagIdents:' . $tag);
664 $this->assertSame([], $tagToIdentifiersMemberArray);
670 public function removeDeletesIdentifierFromTagToIdentifiersSetWithMultipleEntries()
672 $subject = $this->setUpSubject();
673 $redis = $this->setUpRedis();
674 $firstIdentifier = $this->getUniqueId('identifier');
675 $secondIdentifier = $this->getUniqueId('identifier');
677 $subject->set($firstIdentifier, 'data', [$tag]);
678 $subject->set($secondIdentifier, 'data', [$tag]);
679 $subject->remove($firstIdentifier);
680 $tagToIdentifiersMemberArray = $redis->sMembers('tagIdents:' . $tag);
681 $this->assertSame([$secondIdentifier], $tagToIdentifiersMemberArray);
687 public function findIdentifiersByTagThrowsExceptionIfTagIsNotAString()
689 $this->expectException(\InvalidArgumentException
::class);
690 $this->expectExceptionCode(1377006655);
692 $subject = $this->setUpSubject();
693 $subject->findIdentifiersByTag([]);
699 public function findIdentifiersByTagReturnsEmptyArrayForNotExistingTag()
701 $subject = $this->setUpSubject();
702 $this->assertSame([], $subject->findIdentifiersByTag('thisTag'));
708 public function findIdentifiersByTagReturnsAllIdentifiersTagedWithSpecifiedTag()
710 $subject = $this->setUpSubject();
711 $firstIdentifier = $this->getUniqueId('identifier1-');
712 $secondIdentifier = $this->getUniqueId('identifier2-');
713 $thirdIdentifier = $this->getUniqueId('identifier3-');
714 $tagsForFirstIdentifier = ['thisTag'];
715 $tagsForSecondIdentifier = ['thatTag'];
716 $tagsForThirdIdentifier = ['thisTag', 'thatTag'];
717 $subject->set($firstIdentifier, 'data', $tagsForFirstIdentifier);
718 $subject->set($secondIdentifier, 'data', $tagsForSecondIdentifier);
719 $subject->set($thirdIdentifier, 'data', $tagsForThirdIdentifier);
720 $expectedResult = [$firstIdentifier, $thirdIdentifier];
721 $actualResult = $subject->findIdentifiersByTag('thisTag');
723 $this->assertSame($expectedResult, $actualResult);
729 public function flushRemovesAllEntriesFromCache()
731 $subject = $this->setUpSubject();
732 $redis = $this->setUpRedis();
733 $identifier = $this->getUniqueId('identifier');
734 $subject->set($identifier, 'data');
736 $this->assertSame([], $redis->getKeys('*'));
742 public function flushByTagThrowsExceptionIfTagIsNotAString()
744 $this->expectException(\InvalidArgumentException
::class);
745 $this->expectExceptionCode(1377006656);
747 $subject = $this->setUpSubject();
748 $subject->flushByTag([]);
754 public function flushByTagRemovesEntriesTaggedWithSpecifiedTag()
756 $subject = $this->setUpSubject();
757 $identifier = $this->getUniqueId('identifier');
758 $subject->set($identifier . 'A', 'data', ['tag1']);
759 $subject->set($identifier . 'B', 'data', ['tag2']);
760 $subject->set($identifier . 'C', 'data', ['tag1', 'tag2']);
761 $subject->flushByTag('tag1');
762 $expectedResult = [false, true, false];
764 $subject->has($identifier . 'A'),
765 $subject->has($identifier . 'B'),
766 $subject->has($identifier . 'C')
768 $this->assertSame($expectedResult, $actualResult);
774 public function flushByTagsRemovesEntriesTaggedWithSpecifiedTags()
776 $subject = $this->setUpSubject();
777 $identifier = $this->getUniqueId('identifier');
778 $subject->set($identifier . 'A', 'data', ['tag1']);
779 $subject->set($identifier . 'B', 'data', ['tag2']);
780 $subject->set($identifier . 'C', 'data', ['tag1', 'tag2']);
781 $subject->set($identifier . 'D', 'data', ['tag3']);
782 $subject->flushByTags(['tag1', 'tag2']);
783 $expectedResult = [false, false, false, true];
785 $subject->has($identifier . 'A'),
786 $subject->has($identifier . 'B'),
787 $subject->has($identifier . 'C'),
788 $subject->has($identifier . 'D')
790 $this->assertSame($expectedResult, $actualResult);
796 public function flushByTagRemovesTemporarySet()
798 $subject = $this->setUpSubject();
799 $redis = $this->setUpRedis();
800 $identifier = $this->getUniqueId('identifier');
801 $subject->set($identifier . 'A', 'data', ['tag1']);
802 $subject->set($identifier . 'C', 'data', ['tag1', 'tag2']);
803 $subject->flushByTag('tag1');
804 $this->assertSame([], $redis->getKeys('temp*'));
810 public function flushByTagRemovesIdentifierToTagsSetOfEntryTaggedWithGivenTag()
812 $subject = $this->setUpSubject();
813 $redis = $this->setUpRedis();
814 $identifier = $this->getUniqueId('identifier');
816 $subject->set($identifier, 'data', [$tag]);
817 $subject->flushByTag($tag);
818 $result = $redis->exists('identTags:' . $identifier);
819 if (is_int($result)) {
820 // Since 3.1.4 of phpredis/phpredis the return types has been changed
821 $result = (bool)$result;
823 $this->assertFalse($result);
829 public function flushByTagDoesNotRemoveIdentifierToTagsSetOfUnrelatedEntry()
831 $subject = $this->setUpSubject();
832 $redis = $this->setUpRedis();
833 $identifierToBeRemoved = $this->getUniqueId('identifier');
834 $tagToRemove = 'tag1';
835 $subject->set($identifierToBeRemoved, 'data', [$tagToRemove]);
836 $identifierNotToBeRemoved = $this->getUniqueId('identifier');
837 $tagNotToRemove = 'tag2';
838 $subject->set($identifierNotToBeRemoved, 'data', [$tagNotToRemove]);
839 $subject->flushByTag($tagToRemove);
840 $this->assertSame([$tagNotToRemove], $redis->sMembers('identTags:' . $identifierNotToBeRemoved));
846 public function flushByTagRemovesTagToIdentifiersSetOfGivenTag()
848 $subject = $this->setUpSubject();
849 $redis = $this->setUpRedis();
850 $identifier = $this->getUniqueId('identifier');
852 $subject->set($identifier, 'data', [$tag]);
853 $subject->flushByTag($tag);
854 $result = $redis->exists('tagIdents:' . $tag);
855 if (is_int($result)) {
856 // Since 3.1.4 of phpredis/phpredis the return types has been changed
857 $result = (bool)$result;
859 $this->assertFalse($result);
865 public function flushByTagRemovesIdentifiersTaggedWithGivenTagFromTagToIdentifiersSets()
867 $subject = $this->setUpSubject();
868 $redis = $this->setUpRedis();
869 $identifier = $this->getUniqueId('identifier');
870 $subject->set($identifier . 'A', 'data', ['tag1', 'tag2']);
871 $subject->set($identifier . 'B', 'data', ['tag1', 'tag2']);
872 $subject->set($identifier . 'C', 'data', ['tag2']);
873 $subject->flushByTag('tag1');
874 $this->assertSame([$identifier . 'C'], $redis->sMembers('tagIdents:tag2'));
880 public function collectGarbageDoesNotRemoveNotExpiredIdentifierToDataEntry()
882 $subject = $this->setUpSubject();
883 $redis = $this->setUpRedis();
884 $identifier = $this->getUniqueId('identifier');
885 $subject->set($identifier . 'A', 'data', ['tag']);
886 $subject->set($identifier . 'B', 'data', ['tag']);
887 $redis->delete('identData:' . $identifier . 'A');
888 $subject->collectGarbage();
889 $result = $redis->exists('identData:' . $identifier . 'B');
890 if (is_int($result)) {
891 // Since 3.1.4 of phpredis/phpredis the return types has been changed
892 $result = (bool)$result;
894 $this->assertTrue($result);
900 public function collectGarbageRemovesLeftOverIdentifierToTagsSet()
902 $subject = $this->setUpSubject();
903 $redis = $this->setUpRedis();
904 $identifier = $this->getUniqueId('identifier');
905 $subject->set($identifier . 'A', 'data', ['tag']);
906 $subject->set($identifier . 'B', 'data', ['tag']);
907 $redis->delete('identData:' . $identifier . 'A');
908 $subject->collectGarbage();
909 $expectedResult = [false, true];
910 $resultA = $redis->exists('identTags:' . $identifier . 'A');
911 $resultB = $redis->exists('identTags:' . $identifier . 'B');
912 if (is_int($resultA)) {
913 // Since 3.1.4 of phpredis/phpredis the return types has been changed
914 $resultA = (bool)$resultA;
916 if (is_int($resultB)) {
917 // Since 3.1.4 of phpredis/phpredis the return types has been changed
918 $resultB = (bool)$resultB;
924 $this->assertSame($expectedResult, $actualResult);
930 public function collectGarbageRemovesExpiredIdentifierFromTagsToIdentifierSet()
932 $subject = $this->setUpSubject();
933 $redis = $this->setUpRedis();
934 $identifier = $this->getUniqueId('identifier');
935 $subject->set($identifier . 'A', 'data', ['tag1', 'tag2']);
936 $subject->set($identifier . 'B', 'data', ['tag2']);
937 $redis->delete('identData:' . $identifier . 'A');
938 $subject->collectGarbage();
944 $redis->sMembers('tagIdents:tag1'),
945 $redis->sMembers('tagIdents:tag2')
947 $this->assertSame($expectedResult, $actualResult);