[TASK] Shorten the extend class in all unit tests
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Cache / Backend / ApcBackendTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Cache\Backend;
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
17 use TYPO3\CMS\Core\Cache\Backend\ApcBackend;
18 use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface;
19 use TYPO3\TestingFramework\Core\Unit\UnitTestCase;
20
21 /**
22 * Testcase for the APC cache backend.
23 *
24 * NOTE: If you want to execute these tests you need to enable apc in
25 * cli context (apc.enable_cli = 1)
26 */
27 class ApcBackendTest extends UnitTestCase
28 {
29 /**
30 * Sets up this testcase
31 */
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
43 /**
44 * @test
45 */
46 public function setThrowsExceptionIfNoFrontEndHasBeenSet()
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
56 /**
57 * @test
58 */
59 public function itIsPossibleToSetAndCheckExistenceInCache()
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
69 /**
70 * @test
71 */
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
82 /**
83 * @test
84 */
85 public function itIsPossibleToRemoveEntryFromCache()
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
96 /**
97 * @test
98 */
99 public function itIsPossibleToOverwriteAnEntryInTheCache()
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
111 /**
112 * @test
113 */
114 public function findIdentifiersByTagFindsSetEntries()
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
126 /**
127 * @test
128 */
129 public function setRemovesTagsFromPreviousSet()
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
140 /**
141 * @test
142 */
143 public function hasReturnsFalseIfTheEntryDoesNotExist()
144 {
145 $backend = $this->setUpBackend();
146 $identifier = $this->getUniqueId('NonExistingIdentifier');
147 $inCache = $backend->has($identifier);
148 $this->assertFalse($inCache, '"has" did not return FALSE when checking on non existing identifier');
149 }
150
151 /**
152 * @test
153 */
154 public function removeReturnsFalseIfTheEntryDoesntExist()
155 {
156 $backend = $this->setUpBackend();
157 $identifier = $this->getUniqueId('NonExistingIdentifier');
158 $inCache = $backend->remove($identifier);
159 $this->assertFalse($inCache, '"remove" did not return FALSE when checking on non existing identifier');
160 }
161
162 /**
163 * @test
164 */
165 public function flushByTagRemovesCacheEntriesWithSpecifiedTag()
166 {
167 $backend = $this->setUpBackend();
168 $data = 'some data' . microtime();
169 $backend->set('BackendAPCTest1', $data, ['UnitTestTag%test', 'UnitTestTag%boring']);
170 $backend->set('BackendAPCTest2', $data, ['UnitTestTag%test', 'UnitTestTag%special']);
171 $backend->set('BackendAPCTest3', $data, ['UnitTestTag%test']);
172 $backend->flushByTag('UnitTestTag%special');
173 $this->assertTrue($backend->has('BackendAPCTest1'), 'BackendAPCTest1');
174 $this->assertFalse($backend->has('BackendAPCTest2'), 'BackendAPCTest2');
175 $this->assertTrue($backend->has('BackendAPCTest3'), 'BackendAPCTest3');
176 }
177
178 /**
179 * @test
180 */
181 public function flushByTagsRemovesCacheEntriesWithSpecifiedTags()
182 {
183 $backend = $this->setUpBackend();
184 $data = 'some data' . microtime();
185 $backend->set('BackendAPCTest1', $data, ['UnitTestTag%test', 'UnitTestTag%boring']);
186 $backend->set('BackendAPCTest2', $data, ['UnitTestTag%test', 'UnitTestTag%special']);
187 $backend->set('BackendAPCTest3', $data, ['UnitTestTag%test']);
188 $backend->flushByTags(['UnitTestTag%special', 'UnitTestTag%boring']);
189 $this->assertFalse($backend->has('BackendAPCTest1'), 'BackendAPCTest1');
190 $this->assertFalse($backend->has('BackendAPCTest2'), 'BackendAPCTest2');
191 $this->assertTrue($backend->has('BackendAPCTest3'), 'BackendAPCTest3');
192 }
193
194 /**
195 * @test
196 */
197 public function flushRemovesAllCacheEntries()
198 {
199 $backend = $this->setUpBackend();
200 $data = 'some data' . microtime();
201 $backend->set('BackendAPCTest1', $data);
202 $backend->set('BackendAPCTest2', $data);
203 $backend->set('BackendAPCTest3', $data);
204 $backend->flush();
205 $this->assertFalse($backend->has('BackendAPCTest1'), 'BackendAPCTest1');
206 $this->assertFalse($backend->has('BackendAPCTest2'), 'BackendAPCTest2');
207 $this->assertFalse($backend->has('BackendAPCTest3'), 'BackendAPCTest3');
208 }
209
210 /**
211 * @test
212 */
213 public function flushRemovesOnlyOwnEntries()
214 {
215 /** @var \PHPUnit_Framework_MockObject_MockObject|FrontendInterface $thisCache */
216 $thisCache = $this->createMock(FrontendInterface::class);
217 $thisCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thisCache'));
218 $thisBackend = new ApcBackend('Testing');
219 $thisBackend->setCache($thisCache);
220
221 /** @var \PHPUnit_Framework_MockObject_MockObject|FrontendInterface $thatCache */
222 $thatCache = $this->createMock(FrontendInterface::class);
223 $thatCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thatCache'));
224 $thatBackend = new ApcBackend('Testing');
225 $thatBackend->setCache($thatCache);
226 $thisBackend->set('thisEntry', 'Hello');
227 $thatBackend->set('thatEntry', 'World!');
228 $thatBackend->flush();
229 $this->assertEquals('Hello', $thisBackend->get('thisEntry'));
230 $this->assertFalse($thatBackend->has('thatEntry'));
231 }
232
233 /**
234 * Check if we can store ~5 MB of data
235 *
236 * @test
237 */
238 public function largeDataIsStored()
239 {
240 $backend = $this->setUpBackend();
241 $data = str_repeat('abcde', 1024 * 1024);
242 $identifier = $this->getUniqueId('tooLargeData');
243 $backend->set($identifier, $data);
244 $this->assertTrue($backend->has($identifier));
245 $this->assertEquals($backend->get($identifier), $data);
246 }
247
248 /**
249 * @test
250 */
251 public function setTagsOnlyOnceToIdentifier()
252 {
253 $identifier = $this->getUniqueId('MyIdentifier');
254 $tags = ['UnitTestTag%test', 'UnitTestTag%boring'];
255
256 $backend = $this->setUpBackend(true);
257 $backend->_call('addIdentifierToTags', $identifier, $tags);
258 $this->assertSame(
259 $tags,
260 $backend->_call('findTagsByIdentifier', $identifier)
261 );
262
263 $backend->_call('addIdentifierToTags', $identifier, $tags);
264 $this->assertSame(
265 $tags,
266 $backend->_call('findTagsByIdentifier', $identifier)
267 );
268 }
269
270 /**
271 * Sets up the APC backend used for testing
272 *
273 * @param bool $accessible TRUE if backend should be encapsulated in accessible proxy otherwise FALSE.
274 * @return \TYPO3\TestingFramework\Core\AccessibleObjectInterface|ApcBackend
275 */
276 protected function setUpBackend($accessible = false)
277 {
278 /** @var \PHPUnit_Framework_MockObject_MockObject|FrontendInterface $cache */
279 $cache = $this->createMock(FrontendInterface::class);
280 if ($accessible) {
281 $accessibleClassName = $this->buildAccessibleProxy(ApcBackend::class);
282 $backend = new $accessibleClassName('Testing');
283 } else {
284 $backend = new ApcBackend('Testing');
285 }
286 $backend->setCache($cache);
287 return $backend;
288 }
289 }