Commit 3d930170 authored by Alexander Opitz's avatar Alexander Opitz Committed by Markus Klein
Browse files

[BUGFIX] Too many tags by identifier in CacheBackends

This applies to Apc/Memcached/Wincache/Xcache backends.

After an array_merge the values aren't unique. This leads to duplicate
tags per identifier. This patch changes that and also moves the
findTagsByIdentifier call out of the foreach loop.

Resolves: #59587
Releases: 6.3, 6.2, 6.1
Change-Id: Id31e16fa4bba11038ba692a483fb9a33808d95fa
Reviewed-on: https://review.typo3.org/30767
Reviewed-by: Wouter Wolters
Tested-by: Wouter Wolters
Reviewed-by: Markus Klein
Tested-by: Markus Klein
parent 97cfa181
......@@ -254,19 +254,28 @@ class ApcBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend implement
* @return void
*/
protected function addIdentifierToTags($entryIdentifier, array $tags) {
// Get identifier-to-tag index to look for updates
$existingTags = $this->findTagsByIdentifier($entryIdentifier);
$existingTagsUpdated = FALSE;
foreach ($tags as $tag) {
// Update tag-to-identifier index
$identifiers = $this->findIdentifiersByTag($tag);
if (array_search($entryIdentifier, $identifiers) === FALSE) {
if (!in_array($entryIdentifier, $identifiers, TRUE)) {
$identifiers[] = $entryIdentifier;
apc_store($this->getIdentifierPrefix() . 'tag_' . $tag, $identifiers);
}
// Update identifier-to-tag index
$existingTags = $this->findTagsByIdentifier($entryIdentifier);
if (array_search($entryIdentifier, $existingTags) === FALSE) {
apc_store($this->getIdentifierPrefix() . 'ident_' . $entryIdentifier, array_merge($existingTags, $tags));
// Test if identifier-to-tag index needs update
if (!in_array($tag, $existingTags, TRUE)) {
$existingTags[] = $tag;
$existingTagsUpdated = TRUE;
}
}
// Update identifier-to-tag index if needed
if ($existingTagsUpdated) {
apc_store($this->getIdentifierPrefix() . 'ident_' . $entryIdentifier, $existingTags);
}
}
/**
......
......@@ -315,19 +315,28 @@ class MemcachedBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend imp
* @return void
*/
protected function addIdentifierToTags($entryIdentifier, array $tags) {
// Get identifier-to-tag index to look for updates
$existingTags = $this->findTagsByIdentifier($entryIdentifier);
$existingTagsUpdated = FALSE;
foreach ($tags as $tag) {
// Update tag-to-identifier index
$identifiers = $this->findIdentifiersByTag($tag);
if (array_search($entryIdentifier, $identifiers) === FALSE) {
if (!in_array($entryIdentifier, $identifiers, TRUE)) {
$identifiers[] = $entryIdentifier;
$this->memcache->set($this->identifierPrefix . 'tag_' . $tag, $identifiers);
}
// Update identifier-to-tag index
$existingTags = $this->findTagsByIdentifier($entryIdentifier);
if (array_search($tag, $existingTags) === FALSE) {
$this->memcache->set($this->identifierPrefix . 'ident_' . $entryIdentifier, array_merge($existingTags, $tags));
// Test if identifier-to-tag index needs update
if (!in_array($tag, $existingTags, TRUE)) {
$existingTags[] = $tag;
$existingTagsUpdated = TRUE;
}
}
// Update identifier-to-tag index if needed
if ($existingTagsUpdated) {
$this->memcache->set($this->identifierPrefix . 'ident_' . $entryIdentifier, $existingTags);
}
}
/**
......
......@@ -38,7 +38,7 @@ namespace TYPO3\CMS\Core\Cache\Backend;
class WincacheBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend implements \TYPO3\CMS\Core\Cache\Backend\TaggableBackendInterface {
/**
* A prefix to seperate stored data from other data possible stored in the wincache
* A prefix to separate stored data from other data possible stored in the wincache
*
* @var string
*/
......@@ -156,6 +156,7 @@ class WincacheBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend impl
/**
* Removes all cache entries of this cache
*
* @throws \TYPO3\CMS\Core\Cache\Exception
* @return void
*/
public function flush() {
......@@ -187,19 +188,28 @@ class WincacheBackend extends \TYPO3\CMS\Core\Cache\Backend\AbstractBackend impl
* @return void
*/
protected function addIdentifierToTags($entryIdentifier, array $tags) {
// Get identifier-to-tag index to look for updates
$existingTags = $this->findTagsByIdentifier($entryIdentifier);
$existingTagsUpdated = FALSE;
foreach ($tags as $tag) {
// Update tag-to-identifier index
$identifiers = $this->findIdentifiersByTag($tag);
if (array_search($entryIdentifier, $identifiers) === FALSE) {
if (!in_array($entryIdentifier, $identifiers, TRUE)) {
$identifiers[] = $entryIdentifier;
wincache_ucache_set($this->identifierPrefix . 'tag_' . $tag, $identifiers);
}
// Update identifier-to-tag index
$existingTags = $this->findTagsByIdentifier($entryIdentifier);
if (array_search($entryIdentifier, $existingTags) === FALSE) {
wincache_ucache_set($this->identifierPrefix . 'ident_' . $entryIdentifier, array_merge($existingTags, $tags));
// Test if identifier-to-tag index needs update
if (!in_array($tag, $existingTags, TRUE)) {
$existingTags[] = $tag;
$existingTagsUpdated = TRUE;
}
}
// Update identifier-to-tag index if needed
if ($existingTagsUpdated) {
wincache_ucache_set($this->identifierPrefix . 'ident_' . $entryIdentifier, $existingTags);
}
}
/**
......
<?php
namespace TYPO3\CMS\Core\Cache\Backend;
use TYPO3\CMS\Core\Cache\Exception;
/**
* This file is part of the TYPO3 CMS project.
......@@ -221,19 +220,30 @@ class XcacheBackend extends AbstractBackend implements TaggableBackendInterface
if ($this->runningFromCliOrWrongConfiguration()) {
return;
}
// Get identifier-to-tag index to look for updates
$existingTags = $this->findTagsByIdentifier($entryIdentifier);
$existingTagsUpdated = FALSE;
foreach ($tags as $tag) {
// Update tag-to-identifier index
$identifiers = $this->findIdentifiersByTag($tag);
if (array_search($entryIdentifier, $identifiers) === FALSE) {
if (!in_array($entryIdentifier, $identifiers, TRUE)) {
$identifiers[] = $entryIdentifier;
xcache_set($this->identifierPrefix . 'tag_' . $tag, $identifiers);
}
// Update identifier-to-tag index
$existingTags = $this->findTagsByIdentifier($entryIdentifier);
if (array_search($entryIdentifier, $existingTags) === FALSE) {
xcache_set($this->identifierPrefix . 'ident_' . $entryIdentifier, array_merge($existingTags, $tags));
// Test if identifier-to-tag index needs update
if (!in_array($tag, $existingTags, TRUE)) {
$existingTags[] = $tag;
$existingTagsUpdated = TRUE;
}
}
// Update identifier-to-tag index if needed
if ($existingTagsUpdated) {
xcache_set($this->identifierPrefix . 'ident_' . $entryIdentifier, $existingTags);
}
}
/**
......
......@@ -14,6 +14,8 @@ namespace TYPO3\CMS\Core\Tests\Unit\Cache\Backend;
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Cache\Backend\ApcBackend;
/**
* Testcase for the APC cache backend.
*
......@@ -46,7 +48,7 @@ class ApcBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
* @expectedException \TYPO3\CMS\Core\Cache\Exception
*/
public function setThrowsExceptionIfNoFrontEndHasBeenSet() {
$backend = new \TYPO3\CMS\Core\Cache\Backend\ApcBackend('Testing');
$backend = new ApcBackend('Testing');
$data = 'Some data';
$identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
$backend->set($identifier, $data);
......@@ -134,12 +136,13 @@ class ApcBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
* @test
*/
public function setCacheIsSettingIdentifierPrefixWithCacheIdentifier() {
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $cacheMock */
$cacheMock = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\FrontendInterface', array(), array(), '', FALSE);
$cacheMock->expects($this->any())->method('getIdentifier')->will($this->returnValue(
'testidentifier'
));
/** @var $backendMock \TYPO3\CMS\Core\Cache\Backend\ApcBackend */
/** @var $backendMock \PHPUnit_Framework_MockObject_MockObject|ApcBackend */
$backendMock = $this->getMock(
'TYPO3\\CMS\\Core\\Cache\\Backend\\ApcBackend',
array('setIdentifierPrefix','getCurrentUserData','getPathSite'),
......@@ -162,7 +165,7 @@ class ApcBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
/**
* @test
*/
public function hasReturnsFalseIfTheEntryDoesntExist() {
public function hasReturnsFalseIfTheEntryDoesNotExist() {
$backend = $this->setUpBackend();
$identifier = 'NonExistingIdentifier' . md5(uniqid(mt_rand(), TRUE));
$inCache = $backend->has($identifier);
......@@ -216,13 +219,16 @@ class ApcBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
* @test
*/
public function flushRemovesOnlyOwnEntries() {
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $thisCache */
$thisCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\FrontendInterface', array(), array(), '', FALSE);
$thisCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thisCache'));
$thisBackend = new \TYPO3\CMS\Core\Cache\Backend\ApcBackend('Testing');
$thisBackend = new ApcBackend('Testing');
$thisBackend->setCache($thisCache);
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $thatCache */
$thatCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\FrontendInterface', array(), array(), '', FALSE);
$thatCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thatCache'));
$thatBackend = new \TYPO3\CMS\Core\Cache\Backend\ApcBackend('Testing');
$thatBackend = new ApcBackend('Testing');
$thatBackend->setCache($thatCache);
$thisBackend->set('thisEntry', 'Hello');
$thatBackend->set('thatEntry', 'World!');
......@@ -245,14 +251,42 @@ class ApcBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
$this->assertEquals($backend->get($identifier), $data);
}
/**
* @test
*/
public function setTagsOnlyOnceToIdentifier() {
$identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
$tags = array('UnitTestTag%test', 'UnitTestTag%boring');
$backend = $this->setUpBackend(TRUE);
$backend->_call('addIdentifierToTags', $identifier, $tags);
$this->assertSame(
$tags,
$backend->_call('findTagsByIdentifier', $identifier)
);
$backend->_call('addIdentifierToTags', $identifier, $tags);
$this->assertSame(
$tags,
$backend->_call('findTagsByIdentifier', $identifier)
);
}
/**
* Sets up the APC backend used for testing
*
* @return \TYPO3\CMS\Core\Cache\Backend\ApcBackend
* @param bool $accessible TRUE if backend should be encapsulated in accessible proxy otherwise FALSE.
* @return \TYPO3\CMS\Core\Tests\AccessibleObjectInterface|ApcBackend
*/
protected function setUpBackend() {
protected function setUpBackend($accessible = FALSE) {
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $cache */
$cache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\FrontendInterface', array(), array(), '', FALSE);
$backend = new \TYPO3\CMS\Core\Cache\Backend\ApcBackend('Testing');
if ($accessible) {
$accessibleClassName = $this->buildAccessibleProxy('\\TYPO3\\CMS\\Core\\Cache\\Backend\\ApcBackend');
$backend = new $accessibleClassName('Testing');
} else {
$backend = new ApcBackend('Testing');
}
$backend->setCache($cache);
return $backend;
}
......
......@@ -14,6 +14,8 @@ namespace TYPO3\CMS\Core\Tests\Unit\Cache\Backend;
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Cache\Backend\MemcachedBackend;
/**
* Testcase for the cache to memcached backend
*
......@@ -47,7 +49,7 @@ class MemcachedBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
*/
public function setThrowsExceptionIfNoFrontEndHasBeenSet() {
$backendOptions = array('servers' => array('localhost:11211'));
$backend = new \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend('Testing', $backendOptions);
$backend = new MemcachedBackend('Testing', $backendOptions);
$backend->initializeObject();
$data = 'Some data';
$identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
......@@ -59,7 +61,7 @@ class MemcachedBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
* @expectedException \TYPO3\CMS\Core\Cache\Exception
*/
public function initializeObjectThrowsExceptionIfNoMemcacheServerIsConfigured() {
$backend = new \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend('Testing');
$backend = new MemcachedBackend('Testing');
$backend->initializeObject();
}
......@@ -196,14 +198,17 @@ class MemcachedBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
*/
public function flushRemovesOnlyOwnEntries() {
$backendOptions = array('servers' => array('localhost:11211'));
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $thisCache */
$thisCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array(), array(), '', FALSE);
$thisCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thisCache'));
$thisBackend = new \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend('Testing', $backendOptions);
$thisBackend = new MemcachedBackend('Testing', $backendOptions);
$thisBackend->setCache($thisCache);
$thisBackend->initializeObject();
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $thatCache */
$thatCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array(), array(), '', FALSE);
$thatCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thatCache'));
$thatBackend = new \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend('Testing', $backendOptions);
$thatBackend = new MemcachedBackend('Testing', $backendOptions);
$thatBackend->setCache($thatCache);
$thatBackend->initializeObject();
$thisBackend->set('thisEntry', 'Hello');
......@@ -227,18 +232,47 @@ class MemcachedBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
$this->assertEquals($backend->get('tooLargeData'), $data);
}
/**
* @test
*/
public function setTagsOnlyOnceToIdentifier() {
$backendOptions = array('servers' => array('localhost:11211'));
$identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
$tags = array('UnitTestTag%test', 'UnitTestTag%boring');
$backend = $this->setUpBackend($backendOptions, TRUE);
$backend->_call('addIdentifierToTags', $identifier, $tags);
$this->assertSame(
$tags,
$backend->_call('findTagsByIdentifier', $identifier)
);
$backend->_call('addIdentifierToTags', $identifier, $tags);
$this->assertSame(
$tags,
$backend->_call('findTagsByIdentifier', $identifier)
);
}
/**
* Sets up the memcached backend used for testing
*
* @param array $backendOptions Options for the memcache backend
* @return \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend
* @param bool $accessible TRUE if backend should be encapsulated in accessible proxy otherwise FALSE.
* @return \TYPO3\CMS\Core\Tests\AccessibleObjectInterface|MemcachedBackend
*/
protected function setUpBackend(array $backendOptions = array()) {
protected function setUpBackend(array $backendOptions = array(), $accessible = FALSE) {
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $cache */
$cache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\FrontendInterface', array(), array(), '', FALSE);
if ($backendOptions == array()) {
$backendOptions = array('servers' => array('localhost:11211'));
}
$backend = new \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend('Testing', $backendOptions);
if ($accessible) {
$accessibleClassName = $this->buildAccessibleProxy('\\TYPO3\\CMS\\Core\\Cache\\Backend\\MemcachedBackend');
$backend = new $accessibleClassName('Testing', $backendOptions);
} else {
$backend = new MemcachedBackend('Testing', $backendOptions);
}
$backend->setCache($cache);
$backend->initializeObject();
return $backend;
......
......@@ -14,6 +14,8 @@ namespace TYPO3\CMS\Core\Tests\Unit\Cache\Backend;
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Cache\Backend\WincacheBackend;
/**
* Testcase for the WinCache cache backend
*
......@@ -37,7 +39,7 @@ class WincacheBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
* @expectedException \TYPO3\CMS\Core\Cache\Exception
*/
public function setThrowsExceptionIfNoFrontEndHasBeenSet() {
$backend = new \TYPO3\CMS\Core\Cache\Backend\WincacheBackend('Testing');
$backend = new WincacheBackend('Testing');
$data = 'Some data';
$identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
$backend->set($identifier, $data);
......@@ -175,13 +177,16 @@ class WincacheBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
* @test
*/
public function flushRemovesOnlyOwnEntries() {
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $thisCache */
$thisCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\FrontendInterface', array(), array(), '', FALSE);
$thisCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thisCache'));
$thisBackend = new \TYPO3\CMS\Core\Cache\Backend\WincacheBackend('Testing');
$thisBackend = new WincacheBackend('Testing');
$thisBackend->setCache($thisCache);
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $thatCache */
$thatCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\FrontendInterface', array(), array(), '', FALSE);
$thatCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thatCache'));
$thatBackend = new \TYPO3\CMS\Core\Cache\Backend\WincacheBackend('Testing');
$thatBackend = new WincacheBackend('Testing');
$thatBackend->setCache($thatCache);
$thisBackend->set('thisEntry', 'Hello');
$thatBackend->set('thatEntry', 'World!');
......@@ -204,14 +209,42 @@ class WincacheBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
$this->assertEquals($backend->get($identifier), $data);
}
/**
* @test
*/
public function setTagsOnlyOnceToIdentifier() {
$identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
$tags = array('UnitTestTag%test', 'UnitTestTag%boring');
$backend = $this->setUpBackend(TRUE);
$backend->_call('addIdentifierToTags', $identifier, $tags);
$this->assertSame(
$tags,
$backend->_call('findTagsByIdentifier', $identifier)
);
$backend->_call('addIdentifierToTags', $identifier, $tags);
$this->assertSame(
$tags,
$backend->_call('findTagsByIdentifier', $identifier)
);
}
/**
* Sets up the WinCache backend used for testing
*
* @return \TYPO3\CMS\Core\Cache\Backend\WincacheBackend
* @param bool $accessible TRUE if backend should be encapsulated in accessible proxy otherwise FALSE.
* @return \TYPO3\CMS\Core\Tests\AccessibleObjectInterface|WincacheBackend
*/
protected function setUpBackend() {
protected function setUpBackend($accessible = FALSE) {
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $cache */
$cache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\FrontendInterface', array(), array(), '', FALSE);
$backend = new \TYPO3\CMS\Core\Cache\Backend\WincacheBackend('Testing');
if ($accessible) {
$accessibleClassName = $this->buildAccessibleProxy('\\TYPO3\\CMS\\Core\\Cache\\Backend\\WincacheBackend');
$backend = new $accessibleClassName('Testing');
} else {
$backend = new WincacheBackend('Testing');
}
$backend->setCache($cache);
return $backend;
}
......
......@@ -14,6 +14,8 @@ namespace TYPO3\CMS\Core\Tests\Unit\Cache\Backend;
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Core\Cache\Backend\XcacheBackend;
/**
* Test case
*
......@@ -40,7 +42,7 @@ class XcacheBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
* @expectedException \TYPO3\CMS\Core\Cache\Exception
*/
public function setThrowsExceptionIfNoFrontEndHasBeenSet() {
$backend = new \TYPO3\CMS\Core\Cache\Backend\XcacheBackend('Testing');
$backend = new XcacheBackend('Testing');
$data = 'Some data';
$identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
$backend->set($identifier, $data);
......@@ -178,13 +180,16 @@ class XcacheBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
* @test
*/
public function flushRemovesOnlyOwnEntries() {
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $thisCache */
$thisCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\FrontendInterface', array(), array(), '', FALSE);
$thisCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thisCache'));
$thisBackend = new \TYPO3\CMS\Core\Cache\Backend\XcacheBackend('Testing');
$thisBackend = new XcacheBackend('Testing');
$thisBackend->setCache($thisCache);
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $thatCache */
$thatCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\FrontendInterface', array(), array(), '', FALSE);
$thatCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thatCache'));
$thatBackend = new \TYPO3\CMS\Core\Cache\Backend\XcacheBackend('Testing');
$thatBackend = new XcacheBackend('Testing');
$thatBackend->setCache($thatCache);
$thisBackend->set('thisEntry', 'Hello');
$thatBackend->set('thatEntry', 'World!');
......@@ -207,14 +212,42 @@ class XcacheBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
$this->assertEquals($backend->get($identifier), $data);
}
/**
* @test
*/
public function setTagsOnlyOnceToIdentifier() {
$identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
$tags = array('UnitTestTag%test', 'UnitTestTag%boring');
$backend = $this->setUpBackend(TRUE);
$backend->_call('addIdentifierToTags', $identifier, $tags);
$this->assertSame(
$tags,
$backend->_call('findTagsByIdentifier', $identifier)
);
$backend->_call('addIdentifierToTags', $identifier, $tags);
$this->assertSame(
$tags,
$backend->_call('findTagsByIdentifier', $identifier)
);
}
/**
* Sets up the xcache backend used for testing
*
* @return \TYPO3\CMS\Core\Cache\Backend\XcacheBackend
* @param bool $accessible TRUE if backend should be encapsulated in accessible proxy otherwise FALSE.
* @return \TYPO3\CMS\Core\Tests\AccessibleObjectInterface|XcacheBackend
*/
protected function setUpBackend() {
protected function setUpBackend($accessible = FALSE) {
/** @var \PHPUnit_Framework_MockObject_MockObject|\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface $cache */
$cache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\FrontendInterface', array(), array(), '', FALSE);
$backend = new \TYPO3\CMS\Core\Cache\Backend\XcacheBackend('Testing');
if ($accessible) {
$accessibleClassName = $this->buildAccessibleProxy('\\TYPO3\\CMS\\Core\\Cache\\Backend\\XcacheBackend');
$backend = new $accessibleClassName('Testing');
} else {
$backend = new XcacheBackend('Testing');
}
$backend->setCache($cache);
return $backend;
}
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment