TYPO3 CMS  TYPO3_8-7
ApcBackendTest.php
Go to the documentation of this file.
1 <?php
3 
4 /*
5  * This file is part of the TYPO3 CMS project.
6  *
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.
10  *
11  * For the full copyright and license information, please read the
12  * LICENSE.txt file that was distributed with this source code.
13  *
14  * The TYPO3 project - inspiring people to share!
15  */
16 
18 
27 class ApcBackendTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase
28 {
32  protected function setUp()
33  {
34  // Currently APCu identifies itself both as "apcu" and "apc" (for compatibility) although it doesn't provide the APC-opcache functionality
35  if (!extension_loaded('apc') || ini_get('apc.enabled') == 0 || ini_get('apc.enable_cli') == 0) {
36  $this->markTestSkipped('APC/APCu extension was not available, or it was disabled for CLI.');
37  }
38  if (ini_get('apc.slam_defense') == 1) {
39  $this->markTestSkipped('This testcase can only be executed with apc.slam_defense = Off');
40  }
41  }
42 
47  {
48  $backend = new ApcBackend('Testing');
49  $data = 'Some data';
50  $identifier = $this->getUniqueId('MyIdentifier');
51  $this->expectException(\TYPO3\CMS\Core\Cache\Exception::class);
52  $this->expectExceptionCode(1232986818);
53  $backend->set($identifier, $data);
54  }
55 
60  {
61  $backend = $this->setUpBackend();
62  $data = 'Some data';
63  $identifier = $this->getUniqueId('MyIdentifier');
64  $backend->set($identifier, $data);
65  $inCache = $backend->has($identifier);
66  $this->assertTrue($inCache, 'APC backend failed to set and check entry');
67  }
68 
72  public function itIsPossibleToSetAndGetEntry()
73  {
74  $backend = $this->setUpBackend();
75  $data = 'Some data';
76  $identifier = $this->getUniqueId('MyIdentifier');
77  $backend->set($identifier, $data);
78  $fetchedData = $backend->get($identifier);
79  $this->assertEquals($data, $fetchedData, 'APC backend failed to set and retrieve data');
80  }
81 
86  {
87  $backend = $this->setUpBackend();
88  $data = 'Some data';
89  $identifier = $this->getUniqueId('MyIdentifier');
90  $backend->set($identifier, $data);
91  $backend->remove($identifier);
92  $inCache = $backend->has($identifier);
93  $this->assertFalse($inCache, 'Failed to set and remove data from APC backend');
94  }
95 
100  {
101  $backend = $this->setUpBackend();
102  $data = 'Some data';
103  $identifier = $this->getUniqueId('MyIdentifier');
104  $backend->set($identifier, $data);
105  $otherData = 'some other data';
106  $backend->set($identifier, $otherData);
107  $fetchedData = $backend->get($identifier);
108  $this->assertEquals($otherData, $fetchedData, 'APC backend failed to overwrite and retrieve data');
109  }
110 
115  {
116  $backend = $this->setUpBackend();
117  $data = 'Some data';
118  $identifier = $this->getUniqueId('MyIdentifier');
119  $backend->set($identifier, $data, ['UnitTestTag%tag1', 'UnitTestTag%tag2']);
120  $retrieved = $backend->findIdentifiersByTag('UnitTestTag%tag1');
121  $this->assertEquals($identifier, $retrieved[0], 'Could not retrieve expected entry by tag.');
122  $retrieved = $backend->findIdentifiersByTag('UnitTestTag%tag2');
123  $this->assertEquals($identifier, $retrieved[0], 'Could not retrieve expected entry by tag.');
124  }
125 
130  {
131  $backend = $this->setUpBackend();
132  $data = 'Some data';
133  $identifier = $this->getUniqueId('MyIdentifier');
134  $backend->set($identifier, $data, ['UnitTestTag%tag1', 'UnitTestTag%tagX']);
135  $backend->set($identifier, $data, ['UnitTestTag%tag3']);
136  $retrieved = $backend->findIdentifiersByTag('UnitTestTag%tagX');
137  $this->assertEquals([], $retrieved, 'Found entry which should no longer exist.');
138  }
139 
143  public function setCacheIsSettingIdentifierPrefixWithCacheIdentifier()
144  {
146  $cacheMock = $this->createMock(\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface::class);
147  $cacheMock->expects($this->any())->method('getIdentifier')->will($this->returnValue(
148  'testidentifier'
149  ));
150 
152  $backendMock = $this->getMockBuilder(ApcBackend::class)
153  ->setMethods(['setIdentifierPrefix', 'getCurrentUserData', 'getPathSite'])
154  ->setConstructorArgs(['testcontext'])
155  ->getMock();
156 
157  $backendMock->expects($this->once())->method('getCurrentUserData')->will(
158  $this->returnValue(['name' => 'testname'])
159  );
160 
161  $backendMock->expects($this->once())->method('getPathSite')->will(
162  $this->returnValue('testpath')
163  );
164 
165  $expectedIdentifier = 'TYPO3_' . \TYPO3\CMS\Core\Utility\GeneralUtility::shortMD5('testpath' . 'testname' . 'testcontext' . 'testidentifier', 12);
166  $backendMock->expects($this->once())->method('setIdentifierPrefix')->with($expectedIdentifier);
167  $backendMock->setCache($cacheMock);
168  }
169 
174  {
175  $backend = $this->setUpBackend();
176  $identifier = $this->getUniqueId('NonExistingIdentifier');
177  $inCache = $backend->has($identifier);
178  $this->assertFalse($inCache, '"has" did not return FALSE when checking on non existing identifier');
179  }
180 
185  {
186  $backend = $this->setUpBackend();
187  $identifier = $this->getUniqueId('NonExistingIdentifier');
188  $inCache = $backend->remove($identifier);
189  $this->assertFalse($inCache, '"remove" did not return FALSE when checking on non existing identifier');
190  }
191 
196  {
197  $backend = $this->setUpBackend();
198  $data = 'some data' . microtime();
199  $backend->set('BackendAPCTest1', $data, ['UnitTestTag%test', 'UnitTestTag%boring']);
200  $backend->set('BackendAPCTest2', $data, ['UnitTestTag%test', 'UnitTestTag%special']);
201  $backend->set('BackendAPCTest3', $data, ['UnitTestTag%test']);
202  $backend->flushByTag('UnitTestTag%special');
203  $this->assertTrue($backend->has('BackendAPCTest1'), 'BackendAPCTest1');
204  $this->assertFalse($backend->has('BackendAPCTest2'), 'BackendAPCTest2');
205  $this->assertTrue($backend->has('BackendAPCTest3'), 'BackendAPCTest3');
206  }
207 
212  {
213  $backend = $this->setUpBackend();
214  $data = 'some data' . microtime();
215  $backend->set('BackendAPCTest1', $data, ['UnitTestTag%test', 'UnitTestTag%boring']);
216  $backend->set('BackendAPCTest2', $data, ['UnitTestTag%test', 'UnitTestTag%special']);
217  $backend->set('BackendAPCTest3', $data, ['UnitTestTag%test']);
218  $backend->flushByTags(['UnitTestTag%special', 'UnitTestTag%boring']);
219  $this->assertFalse($backend->has('BackendAPCTest1'), 'BackendAPCTest1');
220  $this->assertFalse($backend->has('BackendAPCTest2'), 'BackendAPCTest2');
221  $this->assertTrue($backend->has('BackendAPCTest3'), 'BackendAPCTest3');
222  }
223 
227  public function flushRemovesAllCacheEntries()
228  {
229  $backend = $this->setUpBackend();
230  $data = 'some data' . microtime();
231  $backend->set('BackendAPCTest1', $data);
232  $backend->set('BackendAPCTest2', $data);
233  $backend->set('BackendAPCTest3', $data);
234  $backend->flush();
235  $this->assertFalse($backend->has('BackendAPCTest1'), 'BackendAPCTest1');
236  $this->assertFalse($backend->has('BackendAPCTest2'), 'BackendAPCTest2');
237  $this->assertFalse($backend->has('BackendAPCTest3'), 'BackendAPCTest3');
238  }
239 
243  public function flushRemovesOnlyOwnEntries()
244  {
246  $thisCache = $this->createMock(\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface::class);
247  $thisCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thisCache'));
248  $thisBackend = new ApcBackend('Testing');
249  $thisBackend->setCache($thisCache);
250 
252  $thatCache = $this->createMock(\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface::class);
253  $thatCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thatCache'));
254  $thatBackend = new ApcBackend('Testing');
255  $thatBackend->setCache($thatCache);
256  $thisBackend->set('thisEntry', 'Hello');
257  $thatBackend->set('thatEntry', 'World!');
258  $thatBackend->flush();
259  $this->assertEquals('Hello', $thisBackend->get('thisEntry'));
260  $this->assertFalse($thatBackend->has('thatEntry'));
261  }
262 
268  public function largeDataIsStored()
269  {
270  $backend = $this->setUpBackend();
271  $data = str_repeat('abcde', 1024 * 1024);
272  $identifier = $this->getUniqueId('tooLargeData');
273  $backend->set($identifier, $data);
274  $this->assertTrue($backend->has($identifier));
275  $this->assertEquals($backend->get($identifier), $data);
276  }
277 
281  public function setTagsOnlyOnceToIdentifier()
282  {
283  $identifier = $this->getUniqueId('MyIdentifier');
284  $tags = ['UnitTestTag%test', 'UnitTestTag%boring'];
285 
286  $backend = $this->setUpBackend(true);
287  $backend->_call('addIdentifierToTags', $identifier, $tags);
288  $this->assertSame(
289  $tags,
290  $backend->_call('findTagsByIdentifier', $identifier)
291  );
292 
293  $backend->_call('addIdentifierToTags', $identifier, $tags);
294  $this->assertSame(
295  $tags,
296  $backend->_call('findTagsByIdentifier', $identifier)
297  );
298  }
299 
306  protected function setUpBackend($accessible = false)
307  {
309  $cache = $this->createMock(\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface::class);
310  if ($accessible) {
311  $accessibleClassName = $this->buildAccessibleProxy(ApcBackend::class);
312  $backend = new $accessibleClassName('Testing');
313  } else {
314  $backend = new ApcBackend('Testing');
315  }
316  $backend->setCache($cache);
317  return $backend;
318  }
319 }