|
TYPO3 API
SVNRelease
|
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2010-2011 Christian Kuhn <lolli@schwarzbu.ch> 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * 00017 * This script is distributed in the hope that it will be useful, 00018 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 * GNU General Public License for more details. 00021 * 00022 * This copyright notice MUST APPEAR in all copies of the script! 00023 ***************************************************************/ 00024 00025 /** 00026 * Testcase for the cache to redis backend 00027 * 00028 * This class has functional tests as well as implementation tests: 00029 * - The functional tests make API calls to the backend and check expected behaviour 00030 * - The implementation tests make additional calls with an own redis instance to 00031 * check stored data structures in the redis server, which can not be checked 00032 * by functional tests alone. Those tests will fail if any changes 00033 * to the internal data structure are done. 00034 * 00035 * Warning: 00036 * The unit tests use and flush redis database numbers 0 and 1! 00037 * 00038 * @author Christian Kuhn <lolli@schwarzbu.ch> 00039 * @package TYPO3 00040 * @subpackage tests 00041 */ 00042 class t3lib_cache_backend_RedisBackendTest extends tx_phpunit_testcase { 00043 /** 00044 * If set, the tearDown() method will flush the cache used by this unit test. 00045 * 00046 * @var t3lib_cache_backend_RedisBackend 00047 */ 00048 protected $backend = NULL; 00049 00050 /** 00051 * Own redis instance used in implementation tests 00052 * 00053 * @var Redis 00054 */ 00055 protected $redis = NULL; 00056 00057 /** 00058 * Set up this testcase 00059 * 00060 * @author Christian Kuhn <lolli@schwarzbu.ch> 00061 */ 00062 public function setUp() { 00063 if (!extension_loaded('redis')) { 00064 $this->markTestSkipped('redis extension was not available'); 00065 } 00066 00067 try { 00068 if (!@fsockopen('127.0.0.1', 6379)) { 00069 $this->markTestSkipped('redis server not reachable'); 00070 } 00071 } catch (Exception $e) { 00072 $this->markTestSkipped('redis server not reachable'); 00073 } 00074 } 00075 00076 /** 00077 * Sets up the redis backend used for testing 00078 * 00079 * @param array Options for the redis backend 00080 * @author Christian Kuhn <lolli@schwarzbu.ch> 00081 */ 00082 protected function setUpBackend(array $backendOptions = array()) { 00083 $mockCache = $this->getMock('t3lib_cache_frontend_Frontend', array(), array(), '', FALSE); 00084 $mockCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('TestCache')); 00085 00086 $this->backend = new t3lib_cache_backend_RedisBackend($backendOptions); 00087 $this->backend->setCache($mockCache); 00088 } 00089 00090 /** 00091 * Sets up an own redis instance for implementation tests 00092 * 00093 * @author Christian Kuhn <lolli@schwarzbu.ch> 00094 */ 00095 protected function setUpRedis() { 00096 $this->redis = new Redis(); 00097 $this->redis->connect('127.0.0.1', 6379); 00098 } 00099 00100 /** 00101 * Tear down this testcase 00102 * 00103 * @author Christian Kuhn <lolli@schwarzbu.ch> 00104 */ 00105 public function tearDown() { 00106 if ($this->backend instanceof t3lib_cache_backend_RedisBackend) { 00107 $this->backend->flush(); 00108 } 00109 00110 unset($this->redis, $this->backend); 00111 } 00112 00113 /** 00114 * @test Functional 00115 * @author Christian Kuhn <lolli@schwarzbu.ch> 00116 */ 00117 public function constructorThrowsNoExceptionIfPasswordOptionIsSet() { 00118 $this->setUpBackend(array('password' => 'foo')); 00119 } 00120 00121 /** 00122 * @test Functional 00123 * @author Christian Kuhn <lolli@schwarzbu.ch> 00124 */ 00125 public function constructorThrowsNoExceptionIfGivenDatabaseWasSuccessfullySelected() { 00126 $this->setUpBackend(array('database' => 1)); 00127 } 00128 00129 /** 00130 * @test Functional 00131 * @author Christian Kuhn <lolli@schwarzbu.ch> 00132 * @expectedException InvalidArgumentException 00133 */ 00134 public function setDatabaseThrowsExceptionIfGivenDatabaseNumberIsNotAnInteger() { 00135 $this->setUpBackend(array('database' => 'foo')); 00136 } 00137 00138 /** 00139 * @test Functional 00140 * @author Christian Kuhn <lolli@schwarzbu.ch> 00141 * @expectedException InvalidArgumentException 00142 */ 00143 public function setDatabaseThrowsExceptionIfGivenDatabaseNumberIsNegative() { 00144 $this->setUpBackend(array('database' => -1)); 00145 } 00146 00147 /** 00148 * @test Functional 00149 * @author Christian Kuhn <lolli@schwarzbu.ch> 00150 * @expectedException InvalidArgumentException 00151 */ 00152 public function setCompressionThrowsExceptionIfCompressionParameterIsNotOfTypeBoolean() { 00153 $this->setUpBackend(array('compression' => 'foo')); 00154 } 00155 00156 /** 00157 * @test Functional 00158 * @author Christian Kuhn <lolli@schwarzbu.ch> 00159 * @expectedException InvalidArgumentException 00160 */ 00161 public function setCompressionLevelThrowsExceptionIfCompressionLevelIsNotInteger() { 00162 $this->setUpBackend(array('compressionLevel' => 'foo')); 00163 } 00164 00165 /** 00166 * @test Functional 00167 * @author Christian Kuhn <lolli@schwarzbu.ch> 00168 * @expectedException InvalidArgumentException 00169 */ 00170 public function setCompressionLevelThrowsExceptionIfCompressionLevelIsNotBetweenMinusOneAndNine() { 00171 $this->setUpBackend(array('compressionLevel' => 11)); 00172 } 00173 00174 /** 00175 * @test Functional 00176 * @author Christian Kuhn <lolli@schwarzbu.ch> 00177 * @expectedException InvalidArgumentException 00178 */ 00179 public function setThrowsExceptionIfIdentifierIsNotAString() { 00180 $this->setUpBackend(); 00181 $this->backend->set(array(), 'data'); 00182 } 00183 00184 /** 00185 * @test Functional 00186 * @author Christian Kuhn <lolli@schwarzbu.ch> 00187 * @expectedException t3lib_cache_Exception_InvalidData 00188 */ 00189 public function setThrowsExceptionIfDataIsNotAString() { 00190 $this->setUpBackend(); 00191 $this->backend->set('identifier' . uniqid(), array()); 00192 } 00193 00194 /** 00195 * @test Functional 00196 * @author Christian Kuhn <lolli@schwarzbu.ch> 00197 * @expectedException InvalidArgumentException 00198 */ 00199 public function setThrowsExceptionIfLifetimeIsNegative() { 00200 $this->setUpBackend(); 00201 $this->backend->set('identifier' . uniqid(), 'data', array(), -42); 00202 } 00203 00204 /** 00205 * @test Functional 00206 * @author Christian Kuhn <lolli@schwarzbu.ch> 00207 * @expectedException InvalidArgumentException 00208 */ 00209 public function setThrowsExceptionIfLifetimeIsNotNullOrAnInteger() { 00210 $this->setUpBackend(); 00211 $this->backend->set('identifier' . uniqid(), 'data', array(), array()); 00212 } 00213 00214 /** 00215 * @test Implementation 00216 * @author Christian Kuhn <lolli@schwarzbu.ch> 00217 */ 00218 public function setStoresEntriesInSelectedDatabase() { 00219 $this->setUpRedis(); 00220 $this->redis->select(1); 00221 00222 $this->setUpBackend(array('database' => 1)); 00223 $identifier = 'identifier' . uniqid(); 00224 $this->backend->set($identifier, 'data'); 00225 00226 $this->assertTrue($this->redis->exists('identData:' . $identifier)); 00227 } 00228 00229 /** 00230 * @test Implementation 00231 * @author Christian Kuhn <lolli@schwarzbu.ch> 00232 */ 00233 public function setSavesStringDataTypeForIdentifierToDataEntry() { 00234 $this->setUpBackend(); 00235 $this->setUpRedis(); 00236 00237 $identifier = 'identifier' . uniqid(); 00238 $this->backend->set($identifier, 'data'); 00239 00240 $this->assertSame(Redis::REDIS_STRING, $this->redis->type('identData:' . $identifier)); 00241 } 00242 00243 /** 00244 * @test Implementation 00245 * @author Christian Kuhn <lolli@schwarzbu.ch> 00246 */ 00247 public function setSavesEntryWithDefaultLifeTime() { 00248 $this->setUpBackend(); 00249 $this->setUpRedis(); 00250 00251 $identifier = 'identifier' . uniqid(); 00252 $defaultLifetime = 42; 00253 $this->backend->setDefaultLifetime($defaultLifetime); 00254 $this->backend->set($identifier, 'data'); 00255 00256 $lifetimeRegisteredInBackend = $this->redis->ttl('identData:' . $identifier); 00257 $this->assertSame($defaultLifetime, $lifetimeRegisteredInBackend); 00258 } 00259 00260 /** 00261 * @test Implementation 00262 * @author Christian Kuhn <lolli@schwarzbu.ch> 00263 */ 00264 public function setSavesEntryWithSpecifiedLifeTime() { 00265 $this->setUpBackend(); 00266 $this->setUpRedis(); 00267 00268 $identifier = 'identifier' . uniqid(); 00269 $lifetime = 43; 00270 $this->backend->set($identifier, 'data', array(), $lifetime); 00271 00272 $lifetimeRegisteredInBackend = $this->redis->ttl('identData:' . $identifier); 00273 $this->assertSame($lifetime, $lifetimeRegisteredInBackend); 00274 } 00275 00276 /** 00277 * @test Implementation 00278 * @author Christian Kuhn <lolli@schwarzbu.ch> 00279 */ 00280 public function setSavesEntryWithUnlimitedLifeTime() { 00281 $this->setUpBackend(); 00282 $this->setUpRedis(); 00283 00284 $identifier = 'identifier' . uniqid(); 00285 $this->backend->set($identifier, 'data', array(), 0); 00286 00287 $lifetimeRegisteredInBackend = $this->redis->ttl('identData:' . $identifier); 00288 $this->assertSame(31536000, $lifetimeRegisteredInBackend); 00289 } 00290 00291 /** 00292 * @test Functional 00293 * @author Christian Jul Jensen <julle@typo3.org> 00294 * @author Christian Kuhn <lolli@schwarzbu.ch> 00295 */ 00296 public function setOverwritesExistingEntryWithNewData() { 00297 $this->setUpBackend(); 00298 $data = 'data 1'; 00299 $identifier = 'identifier' . uniqid(); 00300 $this->backend->set($identifier, $data); 00301 $otherData = 'data 2'; 00302 $this->backend->set($identifier, $otherData); 00303 $fetchedData = $this->backend->get($identifier); 00304 $this->assertSame($otherData, $fetchedData); 00305 } 00306 00307 /** 00308 * @test Implementation 00309 * @author Christian Kuhn <lolli@schwarzbu.ch> 00310 */ 00311 public function setOverwritesExistingEntryWithSpecifiedLifetime() { 00312 $this->setUpBackend(); 00313 $this->setUpRedis(); 00314 00315 $data = 'data'; 00316 $identifier = 'identifier' . uniqid(); 00317 $this->backend->set($identifier, $data); 00318 $lifetime = 42; 00319 $this->backend->set($identifier, $data, array(), $lifetime); 00320 00321 $lifetimeRegisteredInBackend = $this->redis->ttl('identData:' . $identifier); 00322 $this->assertSame($lifetime, $lifetimeRegisteredInBackend); 00323 } 00324 00325 /** 00326 * @test Implementation 00327 * @author Christian Kuhn <lolli@schwarzbu.ch> 00328 */ 00329 public function setOverwritesExistingEntryWithNewDefaultLifetime() { 00330 $this->setUpBackend(); 00331 $this->setUpRedis(); 00332 00333 $data = 'data'; 00334 $identifier = 'identifier' . uniqid(); 00335 $lifetime = 42; 00336 $this->backend->set($identifier, $data, array(), $lifetime); 00337 $newDefaultLifetime = 43; 00338 $this->backend->setDefaultLifetime($newDefaultLifetime); 00339 $this->backend->set($identifier, $data, array(), $newDefaultLifetime); 00340 00341 $lifetimeRegisteredInBackend = $this->redis->ttl('identData:' . $identifier); 00342 $this->assertSame($newDefaultLifetime, $lifetimeRegisteredInBackend); 00343 } 00344 00345 /** 00346 * @test Implementation 00347 * @author Christian Kuhn <lolli@schwarzbu.ch> 00348 */ 00349 public function setOverwritesExistingEntryWithNewUnlimitedLifetime() { 00350 $this->setUpBackend(); 00351 $this->setUpRedis(); 00352 00353 $data = 'data'; 00354 $identifier = 'identifier' . uniqid(); 00355 $lifetime = 42; 00356 $this->backend->set($identifier, $data, array(), $lifetime); 00357 $this->backend->set($identifier, $data, array(), 0); 00358 00359 $lifetimeRegisteredInBackend = $this->redis->ttl('identData:' . $identifier); 00360 $this->assertSame(31536000, $lifetimeRegisteredInBackend); 00361 } 00362 00363 /** 00364 * @test Implementation 00365 * @author Christian Kuhn <lolli@schwarzbu.ch> 00366 */ 00367 public function setSavesSetDataTypeForIdentifierToTagsSet() { 00368 $this->setUpBackend(); 00369 $this->setUpRedis(); 00370 00371 $identifier = 'identifier' . uniqid(); 00372 $this->backend->set($identifier, 'data', array('tag')); 00373 00374 $this->assertSame(Redis::REDIS_SET, $this->redis->type('identTags:' . $identifier)); 00375 } 00376 00377 /** 00378 * @test Implementation 00379 * @author Christian Kuhn <lolli@schwarzbu.ch> 00380 */ 00381 public function setSavesSpecifiedTagsInIdentifierToTagsSet() { 00382 $this->setUpBackend(); 00383 $this->setUpRedis(); 00384 00385 $identifier = 'identifier' . uniqid(); 00386 $tags = array('thatTag', 'thisTag'); 00387 $this->backend->set($identifier, 'data', $tags); 00388 00389 $savedTags = $this->redis->sMembers('identTags:' . $identifier); 00390 sort($savedTags); 00391 $this->assertSame($tags, $savedTags); 00392 } 00393 00394 /** 00395 * @test Implementation 00396 * @author Christian Kuhn <lolli@schwarzbu.ch> 00397 */ 00398 public function setRemovesAllPreviouslySetTagsFromIdentifierToTagsSet() { 00399 $this->setUpBackend(); 00400 $this->setUpRedis(); 00401 00402 $identifier = 'identifier' . uniqid(); 00403 $tags = array('fooTag', 'barTag'); 00404 $this->backend->set($identifier, 'data', $tags); 00405 $this->backend->set($identifier, 'data', array()); 00406 00407 $this->assertSame(array(), $this->redis->sMembers('identTags:' . $identifier)); 00408 } 00409 00410 /** 00411 * @test Implementation 00412 * @author Christian Kuhn <lolli@schwarzbu.ch> 00413 */ 00414 public function setRemovesMultiplePreviouslySetTagsFromIdentifierToTagsSet() { 00415 $this->setUpBackend(); 00416 $this->setUpRedis(); 00417 00418 $identifier = 'identifier' . uniqid(); 00419 $firstTagSet = array('tag1', 'tag2', 'tag3', 'tag4'); 00420 $this->backend->set($identifier, 'data', $firstTagSet); 00421 $secondTagSet = array('tag1', 'tag3'); 00422 $this->backend->set($identifier, 'data', $secondTagSet); 00423 00424 $actualTagSet = $this->redis->sMembers('identTags:' . $identifier); 00425 sort($actualTagSet); 00426 $this->assertSame($secondTagSet, $actualTagSet); 00427 } 00428 00429 /** 00430 * @test Implementation 00431 * @author Christian Kuhn <lolli@schwarzbu.ch> 00432 */ 00433 public function setSavesSetDataTypeForTagToIdentifiersSet() { 00434 $this->setUpBackend(); 00435 $this->setUpRedis(); 00436 00437 $identifier = 'identifier' . uniqid(); 00438 $tag = 'tag'; 00439 $this->backend->set($identifier, 'data', array($tag)); 00440 00441 $this->assertSame(Redis::REDIS_SET, $this->redis->type('tagIdents:' . $tag)); 00442 } 00443 00444 /** 00445 * @test Implementation 00446 * @author Christian Kuhn <lolli@schwarzbu.ch> 00447 */ 00448 public function setSavesIdentifierInTagToIdentifiersSetOfSpecifiedTag() { 00449 $this->setUpBackend(); 00450 $this->setUpRedis(); 00451 00452 $identifier = 'identifier' . uniqid(); 00453 $tag = 'thisTag'; 00454 $this->backend->set($identifier, 'data', array($tag)); 00455 00456 $savedTagToIdentifiersMemberArray = $this->redis->sMembers('tagIdents:' . $tag); 00457 $this->assertSame(array($identifier), $savedTagToIdentifiersMemberArray); 00458 } 00459 00460 /** 00461 * @test Implementation 00462 * @author Christian Kuhn <lolli@schwarzbu.ch> 00463 */ 00464 public function setAppendsSecondIdentifierInTagToIdentifiersEntry() { 00465 $this->setUpBackend(); 00466 $this->setUpRedis(); 00467 00468 $firstIdentifier = 'identifier' . uniqid(); 00469 $tag = 'thisTag'; 00470 $this->backend->set($firstIdentifier, 'data', array($tag)); 00471 $secondIdentifier = 'identifier' . uniqid(); 00472 $this->backend->set($secondIdentifier, 'data', array($tag)); 00473 00474 $savedTagToIdentifiersMemberArray = $this->redis->sMembers('tagIdents:' . $tag); 00475 sort($savedTagToIdentifiersMemberArray); 00476 $identifierArray = array($firstIdentifier, $secondIdentifier); 00477 sort($identifierArray); 00478 $this->assertSame(array($firstIdentifier, $secondIdentifier), $savedTagToIdentifiersMemberArray); 00479 } 00480 00481 /** 00482 * @test Implementation 00483 * @author Christian Kuhn <lolli@schwarzbu.ch> 00484 */ 00485 public function setRemovesIdentifierFromTagToIdentifiersEntryIfTagIsOmittedOnConsecutiveSet() { 00486 $this->setUpBackend(); 00487 $this->setUpRedis(); 00488 00489 $identifier = 'identifier' . uniqid(); 00490 $tag = 'thisTag'; 00491 $this->backend->set($identifier, 'data', array($tag)); 00492 $this->backend->set($identifier, 'data', array()); 00493 00494 $savedTagToIdentifiersMemberArray = $this->redis->sMembers('tagIdents:' . $tag); 00495 $this->assertSame(array(), $savedTagToIdentifiersMemberArray); 00496 } 00497 00498 /** 00499 * @test Implementation 00500 * @author Christian Kuhn <lolli@schwarzbu.ch> 00501 */ 00502 public function setAddsIdentifierInTagToIdentifiersEntryIfTagIsAddedOnConsecutiveSet() { 00503 $this->setUpBackend(); 00504 $this->setUpRedis(); 00505 00506 $identifier = 'identifier' . uniqid(); 00507 $this->backend->set($identifier, 'data'); 00508 $tag = 'thisTag'; 00509 $this->backend->set($identifier, 'data', array($tag)); 00510 00511 $savedTagToIdentifiersMemberArray = $this->redis->sMembers('tagIdents:' . $tag); 00512 $this->assertSame(array($identifier), $savedTagToIdentifiersMemberArray); 00513 } 00514 00515 /** 00516 * @test Implementation 00517 * @author Christian Kuhn <lolli@schwarzbu.ch> 00518 */ 00519 public function setSavesCompressedDataWithEnabledCompression() { 00520 $this->setUpBackend( 00521 array( 00522 'compression' => TRUE, 00523 ) 00524 ); 00525 $this->setUpRedis(); 00526 00527 $identifier = 'identifier' . uniqid(); 00528 $data = 'some data ' . microtime(); 00529 $this->backend->set($identifier, $data); 00530 00531 $uncompresedStoredData = ''; 00532 try { 00533 $uncompresedStoredData = @gzuncompress($this->redis->get('identData:' . $identifier)); 00534 } catch (Exception $e) { 00535 } 00536 00537 $this->assertEquals($data, $uncompresedStoredData, 'Original and compressed data don\'t match'); 00538 } 00539 00540 /** 00541 * @test Implementation 00542 * @author Christian Kuhn <lolli@schwarzbu.ch> 00543 */ 00544 public function setSavesPlaintextDataWithEnabledCompressionAndCompressionLevel0() { 00545 $this->setUpBackend( 00546 array( 00547 'compression' => TRUE, 00548 'compressionLevel' => 0, 00549 ) 00550 ); 00551 $this->setUpRedis(); 00552 00553 $identifier = 'identifier' . uniqid(); 00554 $data = 'some data ' . microtime(); 00555 $this->backend->set($identifier, $data); 00556 00557 $this->assertGreaterThan(0, substr_count($this->redis->get('identData:' . $identifier), $data), 'Plaintext data not found'); 00558 } 00559 00560 /** 00561 * @test Functional 00562 * @author Christian Kuhn <lolli@schwarzbu.ch> 00563 * @expectedException InvalidArgumentException 00564 */ 00565 public function hasThrowsExceptionIfIdentifierIsNotAString() { 00566 $this->setUpBackend(); 00567 $this->backend->has(array()); 00568 } 00569 00570 /** 00571 * @test Functional 00572 * @author Christian Kuhn <lolli@schwarzbu.ch> 00573 */ 00574 public function hasReturnsFalseForNotExistingEntry() { 00575 $this->setUpBackend(); 00576 $identifier = 'identifier' . uniqid(); 00577 $this->assertFalse($this->backend->has($identifier)); 00578 } 00579 00580 /** 00581 * @test Functional 00582 * @author Christian Kuhn <lolli@schwarzbu.ch> 00583 */ 00584 public function hasReturnsTrueForPreviouslySetEntry() { 00585 $this->setUpBackend(); 00586 $identifier = 'identifier' . uniqid(); 00587 $this->backend->set($identifier, 'data'); 00588 $this->assertTrue($this->backend->has($identifier)); 00589 } 00590 00591 /** 00592 * @test Functional 00593 * @author Christian Kuhn <lolli@schwarzbu.ch> 00594 * @expectedException InvalidArgumentException 00595 */ 00596 public function getThrowsExceptionIfIdentifierIsNotAString() { 00597 $this->setUpBackend(); 00598 $this->backend->get(array()); 00599 } 00600 00601 /** 00602 * @test Functional 00603 * @author Christian Kuhn <lolli@schwarzbu.ch> 00604 */ 00605 public function getReturnsPreviouslyCompressedSetEntry() { 00606 $this->setUpBackend( 00607 array( 00608 'compression' => TRUE, 00609 ) 00610 ); 00611 $data = 'data'; 00612 $identifier = 'identifier' . uniqid(); 00613 $this->backend->set($identifier, $data); 00614 $fetchedData = $this->backend->get($identifier); 00615 $this->assertSame($data, $fetchedData); 00616 } 00617 00618 /** 00619 * @test Functional 00620 * @author Christian Kuhn <lolli@schwarzbu.ch> 00621 */ 00622 public function getReturnsPreviouslySetEntry() { 00623 $this->setUpBackend(); 00624 $data = 'data'; 00625 $identifier = 'identifier' . uniqid(); 00626 $this->backend->set($identifier, $data); 00627 $fetchedData = $this->backend->get($identifier); 00628 $this->assertSame($data, $fetchedData); 00629 } 00630 00631 /** 00632 * @test Functional 00633 * @author Christian Kuhn <lolli@schwarzbu.ch> 00634 * @expectedException InvalidArgumentException 00635 */ 00636 public function removeThrowsExceptionIfIdentifierIsNotAString() { 00637 $this->setUpBackend(); 00638 $this->backend->remove(array()); 00639 } 00640 00641 /** 00642 * @test Functional 00643 * @author Christian Kuhn <lolli@schwarzbu.ch> 00644 */ 00645 public function removeReturnsFalseIfNoEntryWasDeleted() { 00646 $this->setUpBackend(); 00647 $this->assertFalse($this->backend->remove('identifier' . uniqid())); 00648 } 00649 00650 /** 00651 * @test Functional 00652 * @author Christian Kuhn <lolli@schwarzbu.ch> 00653 */ 00654 public function removeReturnsTrueIfAnEntryWasDeleted() { 00655 $this->setUpBackend(); 00656 $identifier = 'identifier' . uniqid(); 00657 $this->backend->set($identifier, 'data'); 00658 $this->assertTrue($this->backend->remove($identifier)); 00659 } 00660 00661 /** 00662 * @test Functional 00663 * @author Christian Jul Jensen <julle@typo3.org> 00664 * @author Christian Kuhn <lolli@schwarzbu.ch> 00665 */ 00666 public function removeDeletesEntryFromCache() { 00667 $this->setUpBackend(); 00668 $identifier = 'identifier' . uniqid(); 00669 $this->backend->set($identifier, 'data'); 00670 $this->backend->remove($identifier); 00671 $this->assertFalse($this->backend->has($identifier)); 00672 } 00673 00674 /** 00675 * @test Implementation 00676 * @author Christian Kuhn <lolli@schwarzbu.ch> 00677 */ 00678 public function removeDeletesIdentifierToTagEntry() { 00679 $this->setUpBackend(); 00680 $this->setUpRedis(); 00681 00682 $identifier = 'identifier' . uniqid(); 00683 $tag = 'thisTag'; 00684 $this->backend->set($identifier, 'data', array($tag)); 00685 $this->backend->remove($identifier); 00686 00687 $this->assertFalse($this->redis->exists('identTags:' . $identifier)); 00688 } 00689 00690 /** 00691 * @test Implementation 00692 * @author Christian Kuhn <lolli@schwarzbu.ch> 00693 */ 00694 public function removeDeletesIdentifierFromTagToIdentifiersSet() { 00695 $this->setUpBackend(); 00696 $this->setUpRedis(); 00697 00698 $identifier = 'identifier' . uniqid(); 00699 $tag = 'thisTag'; 00700 $this->backend->set($identifier, 'data', array($tag)); 00701 $this->backend->remove($identifier); 00702 00703 $tagToIdentifiersMemberArray = $this->redis->sMembers('tagIdents:' . $tag); 00704 $this->assertSame(array(), $tagToIdentifiersMemberArray); 00705 } 00706 00707 /** 00708 * @test Implementation 00709 * @author Christian Kuhn <lolli@schwarzbu.ch> 00710 */ 00711 public function removeDeletesIdentifierFromTagToIdentifiersSetWithMultipleEntries() { 00712 $this->setUpBackend(); 00713 $this->setUpRedis(); 00714 00715 $firstIdentifier = 'identifier' . uniqid(); 00716 $secondIdentifier = 'identifier' . uniqid(); 00717 $tag = 'thisTag'; 00718 $this->backend->set($firstIdentifier, 'data', array($tag)); 00719 $this->backend->set($secondIdentifier, 'data', array($tag)); 00720 $this->backend->remove($firstIdentifier); 00721 00722 $tagToIdentifiersMemberArray = $this->redis->sMembers('tagIdents:' . $tag); 00723 $this->assertSame(array($secondIdentifier), $tagToIdentifiersMemberArray); 00724 } 00725 00726 /** 00727 * @test Functional 00728 * @author Christian Kuhn <lolli@schwarzbu.ch> 00729 * @expectedException InvalidArgumentException 00730 */ 00731 public function findIdentifiersByTagThrowsExceptionIfTagIsNotAString() { 00732 $this->setUpBackend(); 00733 $this->backend->findIdentifiersByTag(array()); 00734 } 00735 00736 /** 00737 * @test Functional 00738 * @author Christian Kuhn <lolli@schwarzbu.ch> 00739 */ 00740 public function findIdentifiersByTagReturnsEmptyArrayForNotExistingTag() { 00741 $this->setUpBackend(); 00742 $this->assertSame(array(), $this->backend->findIdentifiersByTag('thisTag')); 00743 } 00744 00745 /** 00746 * @test Functional 00747 * @author Christian Kuhn <lolli@schwarzbu.ch> 00748 */ 00749 public function findIdentifiersByTagReturnsAllIdentifiersTagedWithSpecifiedTag() { 00750 $this->setUpBackend(); 00751 00752 $firstIdentifier = 'identifier' . uniqid(); 00753 $secondIdentifier = 'identifier' . uniqid(); 00754 $thirdIdentifier = 'identifier' . uniqid(); 00755 $tagsForFirstIdentifier = array('thisTag'); 00756 $tagsForSecondIdentifier = array('thatTag'); 00757 $tagsForThirdIdentifier = array('thisTag', 'thatTag'); 00758 00759 $this->backend->set($firstIdentifier, 'data', $tagsForFirstIdentifier); 00760 $this->backend->set($secondIdentifier, 'data', $tagsForSecondIdentifier); 00761 $this->backend->set($thirdIdentifier, 'data', $tagsForThirdIdentifier); 00762 00763 $expectedResult = array($firstIdentifier, $thirdIdentifier); 00764 $actualResult = $this->backend->findIdentifiersByTag('thisTag'); 00765 sort($actualResult); 00766 00767 $this->assertSame($expectedResult, $actualResult); 00768 } 00769 00770 /** 00771 * @test Functional 00772 * @author Christian Kuhn <lolli@schwarzbu.ch> 00773 */ 00774 public function findIdentifiersByTagsReturnEmptyArrayForNotExistingTag() { 00775 $this->setUpBackend(); 00776 $this->assertEquals(array(), $this->backend->findIdentifiersByTags(array('thisTags'))); 00777 } 00778 00779 /** 00780 * @test Functional 00781 * @author Christian Kuhn <lolli@schwarzbu.ch> 00782 */ 00783 public function findIdentifiersByTagsReturnsIdentifiersTaggedWithAllSpecifiedTags() { 00784 $this->setUpBackend(); 00785 00786 $identifier = 'identifier' . uniqid(); 00787 $this->backend->set($identifier . 'A', 'data', array('tag1')); 00788 $this->backend->set($identifier . 'B', 'data', array('tag2')); 00789 $this->backend->set($identifier . 'C', 'data', array('tag1', 'tag2')); 00790 $this->backend->set($identifier . 'D', 'data', array('tag1', 'tag2', 'tag3')); 00791 00792 $expectedResult = array($identifier . 'C', $identifier . 'D'); 00793 $actualResult = $this->backend->findIdentifiersByTags(array('tag1', 'tag2')); 00794 sort($actualResult); 00795 00796 $this->assertEquals($expectedResult, $actualResult); 00797 } 00798 00799 00800 00801 /** 00802 * @test Implementation 00803 * @author Christian Kuhn <lolli@schwarzbu.ch> 00804 */ 00805 public function flushRemovesAllEntriesFromCache() { 00806 $this->setUpBackend(); 00807 $this->setUpRedis(); 00808 00809 $identifier = 'identifier' . uniqid(); 00810 $this->backend->set($identifier, 'data'); 00811 $this->backend->flush(); 00812 00813 $this->assertSame(array(), $this->redis->getKeys('*')); 00814 } 00815 00816 /** 00817 * @test Functional 00818 * @author Christian Kuhn <lolli@schwarzbu.ch> 00819 * @expectedException InvalidArgumentException 00820 */ 00821 public function flushByTagThrowsExceptionIfTagIsNotAString() { 00822 $this->setUpBackend(); 00823 $this->backend->flushByTag(array()); 00824 } 00825 00826 /** 00827 * @test Functional 00828 * @author Christian Kuhn <lolli@schwarzbu.ch> 00829 */ 00830 public function flushByTagRemovesEntriesTaggedWithSpecifiedTag() { 00831 $this->setUpBackend(); 00832 00833 $identifier = 'identifier' . uniqid(); 00834 $this->backend->set($identifier . 'A', 'data', array('tag1')); 00835 $this->backend->set($identifier . 'B', 'data', array('tag2')); 00836 $this->backend->set($identifier . 'C', 'data', array('tag1', 'tag2')); 00837 $this->backend->flushByTag('tag1'); 00838 00839 $expectedResult = array(FALSE, TRUE, FALSE); 00840 $actualResult = array( 00841 $this->backend->has($identifier . 'A'), 00842 $this->backend->has($identifier . 'B'), 00843 $this->backend->has($identifier . 'C'), 00844 ); 00845 $this->assertSame($expectedResult, $actualResult); 00846 } 00847 00848 /** 00849 * @test Implementation 00850 * @author Christian Kuhn <lolli@schwarzbu.ch> 00851 */ 00852 public function flushByTagRemovesTemporarySet() { 00853 $this->setUpBackend(); 00854 $this->setUpRedis(); 00855 00856 $identifier = 'identifier' . uniqid(); 00857 $this->backend->set($identifier . 'A', 'data', array('tag1')); 00858 $this->backend->set($identifier . 'C', 'data', array('tag1', 'tag2')); 00859 $this->backend->flushByTag('tag1'); 00860 00861 $this->assertSame(array(), $this->redis->getKeys('temp*')); 00862 } 00863 00864 /** 00865 * @test Implementation 00866 * @author Christian Kuhn <lolli@schwarzbu.ch> 00867 */ 00868 public function flushByTagRemovesIdentifierToTagsSetOfEntryTaggedWithGivenTag() { 00869 $this->setUpBackend(); 00870 $this->setUpRedis(); 00871 00872 $identifier = 'identifier' . uniqid(); 00873 $tag = 'tag1'; 00874 $this->backend->set($identifier, 'data', array($tag)); 00875 $this->backend->flushByTag($tag); 00876 00877 $this->assertFalse($this->redis->exists('identTags:' . $identifier)); 00878 } 00879 00880 /** 00881 * @test Implementation 00882 * @author Christian Kuhn <lolli@schwarzbu.ch> 00883 */ 00884 public function flushByTagDoesNotRemoveIdentifierToTagsSetOfUnrelatedEntry() { 00885 $this->setUpBackend(); 00886 $this->setUpRedis(); 00887 00888 $identifierToBeRemoved = 'identifier' . uniqid(); 00889 $tagToRemove = 'tag1'; 00890 $this->backend->set($identifierToBeRemoved, 'data', array($tagToRemove)); 00891 00892 $identifierNotToBeRemoved = 'identifier' . uniqid(); 00893 $tagNotToRemove = 'tag2'; 00894 $this->backend->set($identifierNotToBeRemoved, 'data', array($tagNotToRemove)); 00895 00896 $this->backend->flushByTag($tagToRemove); 00897 00898 $this->assertSame(array($tagNotToRemove), $this->redis->sMembers('identTags:' . $identifierNotToBeRemoved)); 00899 } 00900 00901 /** 00902 * @test Implementation 00903 * @author Christian Kuhn <lolli@schwarzbu.ch> 00904 */ 00905 public function flushByTagRemovesTagToIdentifiersSetOfGivenTag() { 00906 $this->setUpBackend(); 00907 $this->setUpRedis(); 00908 00909 $identifier = 'identifier' . uniqid(); 00910 $tag = 'tag1'; 00911 $this->backend->set($identifier, 'data', array($tag)); 00912 $this->backend->flushByTag($tag); 00913 00914 $this->assertFalse($this->redis->exists('tagIdents:' . $tag)); 00915 } 00916 00917 /** 00918 * @test Implementation 00919 * @author Christian Kuhn <lolli@schwarzbu.ch> 00920 */ 00921 public function flushByTagRemovesIdentifiersTaggedWithGivenTagFromTagToIdentifiersSets() { 00922 $this->setUpBackend(); 00923 $this->setUpRedis(); 00924 00925 $identifier = 'identifier' . uniqid(); 00926 $this->backend->set($identifier . 'A', 'data', array('tag1', 'tag2')); 00927 $this->backend->set($identifier . 'B', 'data', array('tag1', 'tag2')); 00928 $this->backend->set($identifier . 'C', 'data', array('tag2')); 00929 00930 $this->backend->flushByTag('tag1'); 00931 00932 $this->assertSame(array($identifier . 'C'), $this->redis->sMembers('tagIdents:tag2')); 00933 } 00934 00935 /** 00936 * @test Implementation 00937 * @author Christian Kuhn <lolli@schwarzbu.ch> 00938 */ 00939 public function flushByTagsRemovesEntriesTaggedWithSpecifiedTags() { 00940 $this->setUpBackend(); 00941 00942 $identifier = 'identifier' . uniqid(); 00943 $this->backend->set($identifier . 'A', 'data', array('tag1')); 00944 $this->backend->set($identifier . 'B', 'data', array('tag2')); 00945 $this->backend->set($identifier . 'C', 'data', array('tag3')); 00946 $this->backend->set($identifier . 'D', 'data', array('tag1', 'tag2')); 00947 $this->backend->set($identifier . 'E', 'data', array('tag1', 'tag3')); 00948 $this->backend->flushByTags(array('tag1', 'tag2')); 00949 00950 $expectedResult = array(FALSE, FALSE, TRUE, FALSE, FALSE); 00951 $actualResult = array( 00952 $this->backend->has($identifier . 'A'), 00953 $this->backend->has($identifier . 'B'), 00954 $this->backend->has($identifier . 'C'), 00955 $this->backend->has($identifier . 'D'), 00956 $this->backend->has($identifier . 'E'), 00957 ); 00958 00959 $this->assertEquals($expectedResult, $actualResult); 00960 } 00961 00962 /** 00963 * @test Implementation 00964 * @author Christian Kuhn <lolli@schwarzbu.ch> 00965 */ 00966 public function flushByTagsRemovesIdentifierToTagsSetOfEntriesTaggedWithGivenTags() { 00967 $this->setUpBackend(); 00968 $this->setUpRedis(); 00969 00970 $identifier = 'identifier' . uniqid(); 00971 $this->backend->set($identifier . 'A', 'data', array('tag1', 'tag2')); 00972 $this->backend->set($identifier . 'B', 'data', array('tag1', 'tag3')); 00973 $this->backend->set($identifier . 'C', 'data', array('tag2', 'tag4')); 00974 $this->backend->set($identifier . 'D', 'data', array('tag3', 'tag4')); 00975 00976 $this->backend->flushByTags(array('tag1', 'tag2')); 00977 00978 $expectedResult = array(FALSE, FALSE, FALSE, TRUE); 00979 $actualResult = array( 00980 $this->redis->exists('identTags:' . $identifier . 'A'), 00981 $this->redis->exists('identTags:' . $identifier . 'B'), 00982 $this->redis->exists('identTags:' . $identifier . 'C'), 00983 $this->redis->exists('identTags:' . $identifier . 'D'), 00984 ); 00985 00986 $this->assertEquals($expectedResult, $actualResult); 00987 } 00988 00989 /** 00990 * @test Implementation 00991 * @author Christian Kuhn <lolli@schwarzbu.ch> 00992 */ 00993 public function flushByTagsRemovesTagToIdentifiersSetsOfGivenTags() { 00994 $this->setUpBackend(); 00995 $this->setUpRedis(); 00996 00997 $identifier = 'identifier' . uniqid(); 00998 $this->backend->set($identifier . 'A', 'data', array('tag1', 'tag2')); 00999 $this->backend->set($identifier . 'B', 'data', array('tag1', 'tag3')); 01000 $this->backend->set($identifier . 'C', 'data', array('tag2', 'tag4')); 01001 $this->backend->set($identifier . 'D', 'data', array('tag3', 'tag4')); 01002 01003 $this->backend->flushByTags(array('tag1', 'tag2')); 01004 01005 $expectedResult = array(FALSE, FALSE, TRUE, TRUE); 01006 $actualResult = array( 01007 $this->redis->exists('tagIdents:tag1'), 01008 $this->redis->exists('tagIdents:tag2'), 01009 $this->redis->exists('tagIdents:tag3'), 01010 $this->redis->exists('tagIdents:tag4'), 01011 ); 01012 01013 $this->assertEquals($expectedResult, $actualResult); 01014 } 01015 01016 /** 01017 * @test Implementation 01018 * @author Christian Kuhn <lolli@schwarzbu.ch> 01019 */ 01020 public function flushByTagsRemovesIdentifiersTaggedWithGivenTagsFromTagToIdentifiersSets() { 01021 $this->setUpBackend(); 01022 $this->setUpRedis(); 01023 01024 $identifier = 'identifier' . uniqid(); 01025 $this->backend->set('A' . $identifier, 'data', array('tag1', 'tag2')); 01026 $this->backend->set('B' . $identifier, 'data', array('tag1', 'tag3')); 01027 $this->backend->set('C' . $identifier, 'data', array('tag3', 'tag4')); 01028 $this->backend->set('D' . $identifier, 'data', array('tag3', 'tag4', 'tag5')); 01029 01030 $this->backend->flushByTags(array('tag1', 'tag2')); 01031 01032 $expectedResult = array( 01033 array('C' . $identifier, 'D' . $identifier), 01034 array('C' . $identifier, 'D' . $identifier), 01035 array('D' . $identifier), 01036 ); 01037 01038 $tag3Identifiers = $this->redis->sMembers('tagIdents:tag3'); 01039 $tag4Identifiers = $this->redis->sMembers('tagIdents:tag4'); 01040 $tag5Identifiers = $this->redis->sMembers('tagIdents:tag5'); 01041 sort($tag3Identifiers); 01042 sort($tag4Identifiers); 01043 01044 $actualResult = array( 01045 $tag3Identifiers, 01046 $tag4Identifiers, 01047 $tag5Identifiers, 01048 ); 01049 01050 $this->assertEquals($expectedResult, $actualResult); 01051 } 01052 01053 /** 01054 * @test Implementation 01055 * @author Christian Kuhn <lolli@schwarzbu.ch> 01056 */ 01057 public function collectGarbageDoesNotRemoveNotExpiredIdentifierToDataEntry() { 01058 $this->setUpBackend(); 01059 $this->setUpRedis(); 01060 01061 $identifier = 'identifier' . uniqid(); 01062 $this->backend->set($identifier . 'A', 'data', array('tag')); 01063 $this->backend->set($identifier . 'B', 'data', array('tag')); 01064 01065 $this->redis->delete('identData:' . $identifier . 'A'); 01066 01067 $this->backend->collectGarbage(); 01068 01069 $this->assertTrue($this->redis->exists('identData:' . $identifier . 'B')); 01070 } 01071 01072 /** 01073 * @test Implementation 01074 * @author Christian Kuhn <lolli@schwarzbu.ch> 01075 */ 01076 public function collectGarbageRemovesLeftOverIdentifierToTagsSet() { 01077 $this->setUpBackend(); 01078 $this->setUpRedis(); 01079 01080 $identifier = 'identifier' . uniqid(); 01081 $this->backend->set($identifier . 'A', 'data', array('tag')); 01082 $this->backend->set($identifier . 'B', 'data', array('tag')); 01083 01084 $this->redis->delete('identData:' . $identifier . 'A'); 01085 01086 $this->backend->collectGarbage(); 01087 01088 $expectedResult = array(FALSE, TRUE); 01089 $actualResult = array( 01090 $this->redis->exists('identTags:' . $identifier . 'A'), 01091 $this->redis->exists('identTags:' . $identifier . 'B'), 01092 ); 01093 $this->assertSame($expectedResult, $actualResult); 01094 } 01095 01096 /** 01097 * @test Implementation 01098 * @author Christian Kuhn <lolli@schwarzbu.ch> 01099 */ 01100 public function collectGarbageRemovesExpiredIdentifierFromTagsToIdentifierSet() { 01101 $this->setUpBackend(); 01102 $this->setUpRedis(); 01103 01104 $identifier = 'identifier' . uniqid(); 01105 $this->backend->set($identifier . 'A', 'data', array('tag1', 'tag2')); 01106 $this->backend->set($identifier . 'B', 'data', array('tag2')); 01107 01108 $this->redis->delete('identData:' . $identifier . 'A'); 01109 01110 $this->backend->collectGarbage(); 01111 01112 $expectedResult = array( 01113 array(), 01114 array($identifier . 'B') 01115 ); 01116 $actualResult = array( 01117 $this->redis->sMembers('tagIdents:tag1'), 01118 $this->redis->sMembers('tagIdents:tag2'), 01119 ); 01120 $this->assertSame($expectedResult, $actualResult); 01121 } 01122 } 01123 ?>
1.8.0