‪TYPO3CMS  ‪main
ApcuBackendTest.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use PHPUnit\Framework\Attributes\DataProvider;
21 use PHPUnit\Framework\Attributes\Test;
26 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
27 
32 final class ‪ApcuBackendTest extends FunctionalTestCase
33 {
34  protected bool ‪$initializeDatabase = false;
35 
36  protected function ‪setUp(): void
37  {
38  // APCu module is called apcu, but options are prefixed with apc
39  if (!extension_loaded('apcu') || !(bool)ini_get('apc.enabled') || !(bool)ini_get('apc.enable_cli')) {
40  self::markTestSkipped('APCu extension was not available, or it was disabled for CLI.');
41  }
42  if (ini_get('apc.slam_defense')) {
43  self::markTestSkipped('This testcase can only be executed with apc.slam_defense = 0');
44  }
45  parent::setUp();
46  }
47 
48  protected function ‪tearDown(): void
49  {
50  apcu_clear_cache();
51  parent::tearDown();
52  }
53 
54  #[Test]
56  {
57  $backend = new ‪ApcuBackend('Testing');
58  $data = 'Some data';
60  $this->expectException(Exception::class);
61  $this->expectExceptionCode(1232986118);
62  $backend->set(‪$identifier, $data);
63  }
64 
65  #[Test]
67  {
68  $backend = new ‪ApcuBackend('Testing');
69  $backend->setCache($this->createMock(FrontendInterface::class));
70  $data = 'Some data';
72  $backend->set(‪$identifier, $data);
73  self::assertTrue($backend->has(‪$identifier));
74  }
75 
76  public static function ‪itIsPossibleToSetAndGetEntryDataProvider(): iterable
77  {
78  yield [ 5 ];
79  yield [ 5.23 ];
80  yield [ 'foo' ];
81  yield [ false ];
82  yield [ true ];
83  yield [ null ];
84  yield [ ['foo', 'bar'] ];
85  }
86 
87  #[DataProvider('itIsPossibleToSetAndGetEntryDataProvider')]
88  #[Test]
89  public function ‪itIsPossibleToSetAndGetEntry(mixed $data): void
90  {
91  $backend = new ‪ApcuBackend('Testing');
92  $backend->setCache($this->createMock(FrontendInterface::class));
94  $backend->set(‪$identifier, $data);
95  self::assertSame($data, $backend->get(‪$identifier));
96  }
97 
98  #[Test]
99  public function ‪itIsPossibleToSetAndGetObject(): void
100  {
101  $backend = new ‪ApcuBackend('Testing');
102  $backend->setCache($this->createMock(FrontendInterface::class));
104  $object = new \stdClass();
105  $object->foo = 'foo';
106  $backend->set(‪$identifier, $object);
107  $fetchedData = $backend->get(‪$identifier);
108  self::assertEquals($object, $fetchedData);
109  }
110 
111  #[Test]
113  {
114  $backend = new ‪ApcuBackend('Testing');
115  $backend->setCache($this->createMock(FrontendInterface::class));
116  $data = 'Some data';
118  $backend->set(‪$identifier, $data);
119  $backend->remove(‪$identifier);
120  self::assertFalse($backend->has(‪$identifier));
121  }
122 
123  #[Test]
125  {
126  $backend = new ‪ApcuBackend('Testing');
127  $backend->setCache($this->createMock(FrontendInterface::class));
128  $data = 'Some data';
130  $backend->set(‪$identifier, $data);
131  $otherData = 'some other data';
132  $backend->set(‪$identifier, $otherData);
133  $fetchedData = $backend->get(‪$identifier);
134  self::assertEquals($otherData, $fetchedData);
135  }
136 
137  #[Test]
139  {
140  $backend = new ‪ApcuBackend('Testing');
141  $backend->setCache($this->createMock(FrontendInterface::class));
142  $data = 'Some data';
144  $backend->set(‪$identifier, $data, ['UnitTestTag%tag1', 'UnitTestTag%tag2']);
145  $retrieved = $backend->findIdentifiersByTag('UnitTestTag%tag1');
146  self::assertEquals(‪$identifier, $retrieved[0]);
147  $retrieved = $backend->findIdentifiersByTag('UnitTestTag%tag2');
148  self::assertEquals(‪$identifier, $retrieved[0]);
149  }
150 
151  #[Test]
152  public function ‪setRemovesTagsFromPreviousSet(): void
153  {
154  $backend = new ‪ApcuBackend('Testing');
155  $backend->setCache($this->createMock(FrontendInterface::class));
156  $data = 'Some data';
158  $backend->set(‪$identifier, $data, ['UnitTestTag%tag1', 'UnitTestTag%tagX']);
159  $backend->set(‪$identifier, $data, ['UnitTestTag%tag3']);
160  $retrieved = $backend->findIdentifiersByTag('UnitTestTag%tagX');
161  self::assertEquals([], $retrieved);
162  }
163 
164  #[Test]
166  {
167  $backend = new ‪ApcuBackend('Testing');
168  $backend->setCache($this->createMock(FrontendInterface::class));
169  ‪$identifier = ‪StringUtility::getUniqueId('NonExistingIdentifier');
170  self::assertFalse($backend->has(‪$identifier));
171  }
172 
173  #[Test]
175  {
176  $backend = new ‪ApcuBackend('Testing');
177  $backend->setCache($this->createMock(FrontendInterface::class));
178  ‪$identifier = ‪StringUtility::getUniqueId('NonExistingIdentifier');
179  self::assertFalse($backend->remove(‪$identifier));
180  }
181 
182  #[Test]
184  {
185  $backend = new ‪ApcuBackend('Testing');
186  $backend->setCache($this->createMock(FrontendInterface::class));
187  $data = 'some data' . microtime();
188  $backend->set('BackendAPCUTest1', $data, ['UnitTestTag%test', 'UnitTestTag%boring']);
189  $backend->set('BackendAPCUTest2', $data, ['UnitTestTag%test', 'UnitTestTag%special']);
190  $backend->set('BackendAPCUTest3', $data, ['UnitTestTag%test']);
191  $backend->flushByTag('UnitTestTag%special');
192  self::assertTrue($backend->has('BackendAPCUTest1'));
193  self::assertFalse($backend->has('BackendAPCUTest2'));
194  self::assertTrue($backend->has('BackendAPCUTest3'));
195  }
196 
197  #[Test]
199  {
200  $backend = new ‪ApcuBackend('Testing');
201  $backend->setCache($this->createMock(FrontendInterface::class));
202  $data = 'some data' . microtime();
203  $backend->set('BackendAPCUTest1', $data, ['UnitTestTag%test', 'UnitTestTag%boring']);
204  $backend->set('BackendAPCUTest2', $data, ['UnitTestTag%test', 'UnitTestTag%special']);
205  $backend->set('BackendAPCUTest3', $data, ['UnitTestTag%test']);
206  $backend->flushByTags(['UnitTestTag%special', 'UnitTestTag%boring']);
207  self::assertFalse($backend->has('BackendAPCUTest1'), 'BackendAPCTest1');
208  self::assertFalse($backend->has('BackendAPCUTest2'), 'BackendAPCTest2');
209  self::assertTrue($backend->has('BackendAPCUTest3'), 'BackendAPCTest3');
210  }
211 
212  #[Test]
213  public function ‪flushRemovesAllCacheEntries(): void
214  {
215  $backend = new ‪ApcuBackend('Testing');
216  $backend->setCache($this->createMock(FrontendInterface::class));
217  $data = 'some data' . microtime();
218  $backend->set('BackendAPCUTest1', $data);
219  $backend->set('BackendAPCUTest2', $data);
220  $backend->set('BackendAPCUTest3', $data);
221  $backend->flush();
222  self::assertFalse($backend->has('BackendAPCUTest1'));
223  self::assertFalse($backend->has('BackendAPCUTest2'));
224  self::assertFalse($backend->has('BackendAPCUTest3'));
225  }
226 
227  #[Test]
228  public function ‪flushRemovesOnlyOwnEntries(): void
229  {
230  $thisCache = $this->createMock(FrontendInterface::class);
231  $thisCache->method('getIdentifier')->willReturn('thisCache');
232  $thisBackend = new ‪ApcuBackend('Testing');
233  $thisBackend->setCache($thisCache);
234 
235  $thatCache = $this->createMock(FrontendInterface::class);
236  $thatCache->method('getIdentifier')->willReturn('thatCache');
237  $thatBackend = new ‪ApcuBackend('Testing');
238  $thatBackend->setCache($thatCache);
239  $thisBackend->set('thisEntry', 'Hello');
240  $thatBackend->set('thatEntry', 'World!');
241  $thatBackend->flush();
242  self::assertEquals('Hello', $thisBackend->get('thisEntry'));
243  self::assertFalse($thatBackend->has('thatEntry'));
244  }
245 
249  #[Test]
250  public function ‪largeDataIsStored(): void
251  {
252  $backend = new ‪ApcuBackend('Testing');
253  $backend->setCache($this->createMock(FrontendInterface::class));
254  $data = str_repeat('abcde', 1024 * 1024);
256  $backend->set(‪$identifier, $data);
257  self::assertTrue($backend->has(‪$identifier));
258  self::assertEquals($backend->get(‪$identifier), $data);
259  }
260 
261  #[Test]
262  public function ‪setTagsOnlyOnceToIdentifier(): void
263  {
265  $tags = ['UnitTestTag%test', 'UnitTestTag%boring'];
266 
267  $backend = new ‪ApcuBackend('Testing');
268  $backend->setCache($this->createMock(FrontendInterface::class));
269  $backend->set(‪$identifier, 'testData', $tags);
270  $backend->set(‪$identifier, 'testData', $tags);
271  // Expect exactly 4 entries:
272  // 1 data entry, 2 tag-to-identifier indexes, 1 identifier-to-tag index
273  self::assertSame(4, count(apcu_cache_info()['cache_list']));
274  }
275 }
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\tearDown
‪tearDown()
Definition: ApcuBackendTest.php:48
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\$initializeDatabase
‪bool $initializeDatabase
Definition: ApcuBackendTest.php:34
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\itIsPossibleToSetAndGetEntryDataProvider
‪static itIsPossibleToSetAndGetEntryDataProvider()
Definition: ApcuBackendTest.php:76
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend
Definition: ApcuBackendTest.php:18
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\removeReturnsFalseIfTheEntryDoesntExist
‪removeReturnsFalseIfTheEntryDoesntExist()
Definition: ApcuBackendTest.php:174
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\setTagsOnlyOnceToIdentifier
‪setTagsOnlyOnceToIdentifier()
Definition: ApcuBackendTest.php:262
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\hasReturnsFalseIfTheEntryDoesNotExist
‪hasReturnsFalseIfTheEntryDoesNotExist()
Definition: ApcuBackendTest.php:165
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\itIsPossibleToRemoveEntryFromCache
‪itIsPossibleToRemoveEntryFromCache()
Definition: ApcuBackendTest.php:112
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\findIdentifiersByTagFindsSetEntries
‪findIdentifiersByTagFindsSetEntries()
Definition: ApcuBackendTest.php:138
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\flushRemovesAllCacheEntries
‪flushRemovesAllCacheEntries()
Definition: ApcuBackendTest.php:213
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\setThrowsExceptionIfNoFrontEndHasBeenSet
‪setThrowsExceptionIfNoFrontEndHasBeenSet()
Definition: ApcuBackendTest.php:55
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\itIsPossibleToSetAndCheckExistenceInCache
‪itIsPossibleToSetAndCheckExistenceInCache()
Definition: ApcuBackendTest.php:66
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\flushByTagsRemovesCacheEntriesWithSpecifiedTags
‪flushByTagsRemovesCacheEntriesWithSpecifiedTags()
Definition: ApcuBackendTest.php:198
‪TYPO3\CMS\Core\Cache\Backend\ApcuBackend
Definition: ApcuBackend.php:45
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\flushByTagRemovesCacheEntriesWithSpecifiedTag
‪flushByTagRemovesCacheEntriesWithSpecifiedTag()
Definition: ApcuBackendTest.php:183
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest
Definition: ApcuBackendTest.php:33
‪TYPO3\CMS\Core\Cache\Exception
Definition: DuplicateIdentifierException.php:16
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\setRemovesTagsFromPreviousSet
‪setRemovesTagsFromPreviousSet()
Definition: ApcuBackendTest.php:152
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\itIsPossibleToSetAndGetObject
‪itIsPossibleToSetAndGetObject()
Definition: ApcuBackendTest.php:99
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\itIsPossibleToSetAndGetEntry
‪itIsPossibleToSetAndGetEntry(mixed $data)
Definition: ApcuBackendTest.php:89
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\flushRemovesOnlyOwnEntries
‪flushRemovesOnlyOwnEntries()
Definition: ApcuBackendTest.php:228
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:24
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\itIsPossibleToOverwriteAnEntryInTheCache
‪itIsPossibleToOverwriteAnEntryInTheCache()
Definition: ApcuBackendTest.php:124
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\setUp
‪setUp()
Definition: ApcuBackendTest.php:36
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\ApcuBackendTest\largeDataIsStored
‪largeDataIsStored()
Definition: ApcuBackendTest.php:250
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37
‪TYPO3\CMS\Core\Utility\StringUtility\getUniqueId
‪static getUniqueId(string $prefix='')
Definition: StringUtility.php:57