2 namespace TYPO3\CMS\Core\Tests\Unit\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!
21 class Typo3DatabaseBackendTest
extends \TYPO3\CMS\Core\Tests\UnitTestCase
24 * Helper method to inject a mock frontend to backend instance
26 * @param \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend $backend Current backend instance
27 * @return \TYPO3\CMS\Core\Cache\Frontend\FrontendInterface Mock frontend
29 protected function setUpMockFrontendOfBackend(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
$backend)
31 $mockCache = $this->getMock(\TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend
::class, array(), array(), '', false
);
32 $mockCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('Testing'));
33 $backend->setCache($mockCache);
40 public function setCacheCalculatesCacheTableName()
42 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
43 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
44 $this->setUpMockFrontendOfBackend($backend);
45 $this->assertEquals('cf_Testing', $backend->getCacheTable());
51 public function setCacheCalculatesTagsTableName()
53 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
54 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
55 $this->setUpMockFrontendOfBackend($backend);
56 $this->assertEquals('cf_Testing_tags', $backend->getTagsTable());
61 * @expectedException \TYPO3\CMS\Core\Cache\Exception
63 public function setThrowsExceptionIfFrontendWasNotSet()
65 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
66 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
67 $backend->set('identifier', 'data');
72 * @expectedException \TYPO3\CMS\Core\Cache\Exception\InvalidDataException
74 public function setThrowsExceptionIfDataIsNotAString()
76 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
77 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
78 $this->setUpMockFrontendOfBackend($backend);
79 $data = array('Some data');
80 $entryIdentifier = 'BackendDbTest';
81 $backend->set($entryIdentifier, $data);
87 public function setInsertsEntryInTable()
89 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
90 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
91 $this->setUpMockFrontendOfBackend($backend);
92 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
94 ->expects($this->once())
95 ->method('exec_INSERTquery')
96 ->with('cf_Testing', $this->callback(function (array $data) {
97 if ($data['content'] !== 'someData') {
100 if ($data['identifier'] !== 'anIdentifier') {
105 $backend->set('anIdentifier', 'someData');
111 public function setRemovesAnAlreadyExistingCacheEntryForTheSameIdentifier()
113 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
114 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('remove'), array('Testing'));
115 $this->setUpMockFrontendOfBackend($backend);
116 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
118 $backend->expects($this->once())->method('remove');
119 $data = $this->getUniqueId('someData');
120 $entryIdentifier = 'anIdentifier';
121 $backend->set($entryIdentifier, $data, array(), 500);
127 public function setReallySavesSpecifiedTags()
129 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
130 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
131 $this->setUpMockFrontendOfBackend($backend);
132 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
134 ->expects($this->once())
135 ->method('exec_INSERTmultipleRows')
138 $this->callback(function (array $data) {
139 if ($data[0] === 'identifier' && $data[1] === 'tag') {
144 $this->callback(function (array $data) {
145 if ($data[0][0] !== 'anIdentifier' ||
$data[0][1] !== 'UnitTestTag%tag1') {
148 if ($data[1][0] !== 'anIdentifier' ||
$data[1][1] !== 'UnitTestTag%tag2') {
154 $backend->set('anIdentifier', 'someData', array('UnitTestTag%tag1', 'UnitTestTag%tag2'));
160 public function setSavesCompressedDataWithEnabledCompression()
162 $backendOptions = array(
163 'compression' => true
165 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
166 $backend = $this->getMock(
167 \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class,
169 array('Testing', $backendOptions)
171 $this->setUpMockFrontendOfBackend($backend);
173 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
175 ->expects($this->once())
176 ->method('exec_INSERTquery')
179 $this->callback(function (array $data) {
180 if (@gzuncompress
($data['content']) === 'someData') {
187 $backend->set('anIdentifier', 'someData');
193 public function setWithUnlimitedLifetimeWritesCorrectEntry()
195 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
196 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
197 $this->setUpMockFrontendOfBackend($backend);
199 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
201 ->expects($this->once())
202 ->method('exec_INSERTquery')
205 $this->callback(function (array $data) {
206 $lifetime = $data['expires'];
207 if ($lifetime > 2000000000) {
214 $backend->set('aIdentifier', 'someData', array(), 0);
219 * @expectedException \TYPO3\CMS\Core\Cache\Exception
221 public function getThrowsExceptionIfFrontendWasNotSet()
223 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
224 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
225 $backend->get('identifier');
231 public function getReturnsContentOfTheCorrectCacheEntry()
233 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
234 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
235 $this->setUpMockFrontendOfBackend($backend);
237 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
239 ->expects($this->once())
240 ->method('exec_SELECTgetSingleRow')
241 ->with('content', 'cf_Testing', $this->anything())
242 ->will($this->returnValue(array('content' => 'someData')));
244 $loadedData = $backend->get('aIdentifier');
245 $this->assertEquals('someData', $loadedData);
251 public function getSetsExceededLifetimeQueryPart()
253 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
254 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
255 $this->setUpMockFrontendOfBackend($backend);
257 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
259 ->expects($this->once())
260 ->method('exec_SELECTgetSingleRow')
264 $this->stringContains('identifier = AND cf_Testing.expires >=')
267 $backend->get('aIdentifier');
272 * @expectedException \TYPO3\CMS\Core\Cache\Exception
274 public function hasThrowsExceptionIfFrontendWasNotSet()
276 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
277 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
278 $backend->has('identifier');
284 public function hasReturnsTrueForExistingEntry()
286 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
287 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
288 $this->setUpMockFrontendOfBackend($backend);
290 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
292 ->expects($this->once())
293 ->method('exec_SELECTcountRows')
294 ->with('*', 'cf_Testing', $this->anything())
295 ->will($this->returnValue(1));
297 $this->assertTrue($backend->has('aIdentifier'));
303 public function hasSetsExceededLifetimeQueryPart()
305 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
306 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
307 $this->setUpMockFrontendOfBackend($backend);
309 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
311 ->expects($this->once())
312 ->method('exec_SELECTcountRows')
316 $this->stringContains('identifier = AND cf_Testing.expires >='))
317 ->will($this->returnValue(1));
319 $this->assertTrue($backend->has('aIdentifier'));
324 * @expectedException \TYPO3\CMS\Core\Cache\Exception
326 public function removeThrowsExceptionIfFrontendWasNotSet()
328 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
329 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
330 $backend->remove('identifier');
336 public function removeReallyRemovesACacheEntry()
338 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
339 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
340 $this->setUpMockFrontendOfBackend($backend);
342 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
344 ->expects($this->at(0))
345 ->method('fullQuoteStr')
346 ->will($this->returnValue('aIdentifier'));
348 ->expects($this->at(1))
349 ->method('exec_DELETEquery')
350 ->with('cf_Testing', "identifier = aIdentifier");
352 ->expects($this->at(2))
353 ->method('fullQuoteStr')
354 ->will($this->returnValue('aIdentifier'));
356 ->expects($this->at(3))
357 ->method('exec_DELETEquery')
358 ->with('cf_Testing_tags', "identifier = aIdentifier");
360 $backend->remove('aIdentifier');
365 * @expectedException \TYPO3\CMS\Core\Cache\Exception
367 public function collectGarbageThrowsExceptionIfFrontendWasNotSet()
369 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
370 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
371 $backend->collectGarbage();
377 public function collectGarbageDeletesTagsFromExpiredEntries()
379 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
380 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
381 $this->setUpMockFrontendOfBackend($backend);
383 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
385 ->expects($this->at(1))
386 ->method('sql_fetch_assoc')
387 ->will($this->returnValue(array('identifier' => 'aIdentifier')));
389 ->expects($this->at(2))
390 ->method('fullQuoteStr')
391 ->will($this->returnValue('aIdentifier'));
393 ->expects($this->at(3))
394 ->method('sql_fetch_assoc')
395 ->will($this->returnValue(false
));
397 ->expects($this->at(5))
398 ->method('exec_DELETEquery')
399 ->with('cf_Testing_tags', 'identifier IN (aIdentifier)');
401 $backend->collectGarbage();
407 public function collectGarbageDeletesExpiredEntry()
409 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
410 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
411 $this->setUpMockFrontendOfBackend($backend);
413 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
415 ->expects($this->at(1))
416 ->method('sql_fetch_assoc')
417 ->will($this->returnValue(false
));
419 ->expects($this->at(3))
420 ->method('exec_DELETEquery')
421 ->with('cf_Testing', $this->stringContains('cf_Testing.expires < '));
423 $backend->collectGarbage();
428 * @expectedException \TYPO3\CMS\Core\Cache\Exception
430 public function findIdentifiersByTagThrowsExceptionIfFrontendWasNotSet()
432 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
433 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
434 $backend->findIdentifiersByTag('identifier');
440 public function findIdentifiersByTagFindsCacheEntriesWithSpecifiedTag()
442 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
443 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
444 $this->setUpMockFrontendOfBackend($backend);
446 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
448 ->expects($this->at(0))
449 ->method('fullQuoteStr')
450 ->will($this->returnValue('cf_Testing_tags'));
452 ->expects($this->at(1))
453 ->method('exec_SELECTgetRows')
455 'cf_Testing.identifier',
456 'cf_Testing, cf_Testing_tags',
457 $this->stringContains('cf_Testing_tags.tag = cf_Testing_tags AND cf_Testing.identifier = cf_Testing_tags.identifier AND cf_Testing.expires >= '),
458 'cf_Testing.identifier'
460 ->will($this->returnValue(array(array('identifier' => 'aIdentifier'))));
461 $this->assertSame(array('aIdentifier' => 'aIdentifier'), $backend->findIdentifiersByTag('aTag'));
466 * @expectedException \TYPO3\CMS\Core\Cache\Exception
468 public function flushThrowsExceptionIfFrontendWasNotSet()
470 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
471 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
478 public function flushRemovesAllCacheEntries()
480 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
481 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
482 $this->setUpMockFrontendOfBackend($backend);
484 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
486 ->expects($this->at(0))
487 ->method('exec_TRUNCATEquery')
488 ->with('cf_Testing');
490 ->expects($this->at(1))
491 ->method('exec_TRUNCATEquery')
492 ->with('cf_Testing_tags');
499 * @expectedException \TYPO3\CMS\Core\Cache\Exception
501 public function flushByTagThrowsExceptionIfFrontendWasNotSet()
503 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
504 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
505 $backend->flushByTag(array());
511 public function flushByTagRemovesCacheEntriesWithSpecifiedTag()
513 /** @var \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend|\PHPUnit_Framework_MockObject_MockObject $backend */
514 $backend = $this->getMock(\TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend
::class, array('dummy'), array('Testing'));
515 $this->setUpMockFrontendOfBackend($backend);
517 $GLOBALS['TYPO3_DB'] = $this->getMock(\TYPO3\CMS\Core\Database\DatabaseConnection
::class, array(), array(), '', false
);
519 ->expects($this->at(0))
520 ->method('fullQuoteStr')
521 ->will($this->returnValue('UnitTestTag%special'));
523 ->expects($this->at(1))
524 ->method('exec_SELECTquery')
526 'DISTINCT identifier',
528 'cf_Testing_tags.tag = UnitTestTag%special'
531 ->expects($this->at(2))
532 ->method('sql_fetch_assoc')
533 ->will($this->returnValue(array('identifier' => 'BackendDbTest1')));
535 ->expects($this->at(3))
536 ->method('fullQuoteStr')
537 ->with('BackendDbTest1', 'cf_Testing')
538 ->will($this->returnValue('BackendDbTest1'));
540 ->expects($this->at(4))
541 ->method('sql_fetch_assoc')
542 ->will($this->returnValue(array('identifier' => 'BackendDbTest2')));
544 ->expects($this->at(5))
545 ->method('fullQuoteStr')
546 ->with('BackendDbTest2', 'cf_Testing')
547 ->will($this->returnValue('BackendDbTest2'));
549 ->expects($this->at(6))
550 ->method('sql_fetch_assoc')
551 ->will($this->returnValue(false
));
553 ->expects($this->at(7))
554 ->method('sql_free_result')
555 ->will($this->returnValue(true
));
557 ->expects($this->at(8))
558 ->method('exec_DELETEquery')
559 ->with('cf_Testing', 'identifier IN (BackendDbTest1, BackendDbTest2)');
561 ->expects($this->at(9))
562 ->method('exec_DELETEquery')
563 ->with('cf_Testing_tags', 'identifier IN (BackendDbTest1, BackendDbTest2)');
565 $backend->flushByTag('UnitTestTag%special');