‪TYPO3CMS  ‪main
MemcachedBackendTest.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\Test;
25 use TYPO3\TestingFramework\Core\Functional\FunctionalTestCase;
26 
27 final class ‪MemcachedBackendTest extends FunctionalTestCase
28 {
29  protected bool ‪$initializeDatabase = false;
30 
34  protected function ‪setUp(): void
35  {
36  if (!extension_loaded('memcache') && !extension_loaded('memcached')) {
37  self::markTestSkipped('Neither "memcache" nor "memcached" extension was available');
38  }
39  if (!getenv('typo3TestingMemcachedHost')) {
40  self::markTestSkipped('environment variable "typo3TestingMemcachedHost" must be set to run this test');
41  }
42  // Note we assume that if that typo3TestingMemcachedHost env is set, we can use that for testing,
43  // there is no test to see if the daemon is actually up and running. Tests will fail if env
44  // is set but daemon is down.
45 
46  parent::setUp();
47  }
48 
53  {
54  // We know this env is set, otherwise setUp() would skip the tests
55  $memcachedHost = getenv('typo3TestingMemcachedHost');
56  // If typo3TestingMemcachedPort env is set, use it, otherwise fall back to standard port
57  $env = getenv('typo3TestingMemcachedPort');
58  $memcachedPort = is_string($env) ? (int)$env : 11211;
59 
60  $subject = new ‪MemcachedBackend('Testing', [ 'servers' => [$memcachedHost . ':' . $memcachedPort] ]);
61  $subject->initializeObject();
62  return $subject;
63  }
64 
65  #[Test]
67  {
68  $subject = $this->‪initializeSubject();
69 
70  $this->expectException(Exception::class);
71  $this->expectExceptionCode(1207149215);
72 
73  $subject->set(‪StringUtility::getUniqueId('MyIdentifier'), 'some data');
74  }
75 
76  #[Test]
78  {
79  $subject = new ‪MemcachedBackend('Testing');
80  $this->expectException(Exception::class);
81  $this->expectExceptionCode(1213115903);
82  $subject->initializeObject();
83  }
84 
85  #[Test]
87  {
88  $frontendMock = $this->createMock(FrontendInterface::class);
89  $frontendMock->method('getIdentifier')->willReturn('pages');
90 
91  $subject = $this->‪initializeSubject();
92  $subject->setCache($frontendMock);
93 
95  $subject->set(‪$identifier, 'Some data');
96  self::assertTrue($subject->has(‪$identifier));
97  }
98 
99  #[Test]
100  public function ‪itIsPossibleToSetAndGetEntry(): void
101  {
102  $frontendMock = $this->createMock(FrontendInterface::class);
103  $frontendMock->method('getIdentifier')->willReturn('pages');
104 
105  $subject = $this->‪initializeSubject();
106  $subject->setCache($frontendMock);
107 
108  $data = 'Some data';
110  $subject->set(‪$identifier, $data);
111  self::assertEquals($data, $subject->get(‪$identifier));
112  }
113 
114  #[Test]
116  {
117  $frontendMock = $this->createMock(FrontendInterface::class);
118  $frontendMock->method('getIdentifier')->willReturn('pages');
119 
120  $subject = $this->‪initializeSubject();
121  $subject->setCache($frontendMock);
122 
123  $data = [
124  'string' => 'Serialize a string',
125  'integer' => 0,
126  'anotherIntegerValue' => 123456,
127  'float' => 12.34,
128  'bool' => true,
129  'array' => [
130  0 => 'test',
131  1 => 'another test',
132  ],
133  ];
134 
135  $subject->set('myIdentifier', $data);
136  self::assertSame($data, $subject->get('myIdentifier'));
137  }
138 
142  #[Test]
143  public function ‪largeDataIsStored(): void
144  {
145  $frontendMock = $this->createMock(FrontendInterface::class);
146  $frontendMock->method('getIdentifier')->willReturn('pages');
147 
148  $subject = $this->‪initializeSubject();
149  $subject->setCache($frontendMock);
150 
151  $data = str_repeat('abcde', 1024 * 1024);
152  $subject->set('tooLargeData', $data);
153  self::assertTrue($subject->has('tooLargeData'));
154  self::assertEquals($subject->get('tooLargeData'), $data);
155  }
156 
157  #[Test]
159  {
160  $frontendMock = $this->createMock(FrontendInterface::class);
161  $frontendMock->method('getIdentifier')->willReturn('pages');
162 
163  $subject = $this->‪initializeSubject();
164  $subject->setCache($frontendMock);
165 
166  $data = 'Some data';
168  $subject->set(‪$identifier, $data);
169  $subject->remove(‪$identifier);
170  self::assertFalse($subject->has(‪$identifier));
171  }
172 
173  #[Test]
175  {
176  $frontendMock = $this->createMock(FrontendInterface::class);
177  $frontendMock->method('getIdentifier')->willReturn('pages');
178 
179  $subject = $this->‪initializeSubject();
180  $subject->setCache($frontendMock);
181 
182  $data = 'Some data';
184  $subject->set(‪$identifier, $data);
185  $otherData = 'some other data';
186  $subject->set(‪$identifier, $otherData);
187  self::assertEquals($otherData, $subject->get(‪$identifier));
188  }
189 
190  #[Test]
192  {
193  $frontendMock = $this->createMock(FrontendInterface::class);
194  $frontendMock->method('getIdentifier')->willReturn('pages');
195 
196  $subject = $this->‪initializeSubject();
197  $subject->setCache($frontendMock);
198 
199  $data = 'Some data';
201  $subject->set(‪$identifier, $data, ['UnitTestTag%tag1', 'UnitTestTag%tag2']);
202  $retrieved = $subject->findIdentifiersByTag('UnitTestTag%tag1');
203  self::assertEquals(‪$identifier, $retrieved[0]);
204  $retrieved = $subject->findIdentifiersByTag('UnitTestTag%tag2');
205  self::assertEquals(‪$identifier, $retrieved[0]);
206  }
207 
208  #[Test]
209  public function ‪setRemovesTagsFromPreviousSet(): void
210  {
211  $frontendMock = $this->createMock(FrontendInterface::class);
212  $frontendMock->method('getIdentifier')->willReturn('pages');
213 
214  $subject = $this->‪initializeSubject();
215  $subject->setCache($frontendMock);
216 
217  $data = 'Some data';
219  $subject->set(‪$identifier, $data, ['UnitTestTag%tag1', 'UnitTestTag%tag2']);
220  $subject->set(‪$identifier, $data, ['UnitTestTag%tag3']);
221  self::assertEquals([], $subject->findIdentifiersByTag('UnitTestTag%tagX'));
222  }
223 
224  #[Test]
226  {
227  $frontendMock = $this->createMock(FrontendInterface::class);
228  $frontendMock->method('getIdentifier')->willReturn('pages');
229 
230  $subject = $this->‪initializeSubject();
231  $subject->setCache($frontendMock);
232 
233  ‪$identifier = ‪StringUtility::getUniqueId('NonExistingIdentifier');
234  self::assertFalse($subject->has(‪$identifier));
235  }
236 
237  #[Test]
239  {
240  $frontendMock = $this->createMock(FrontendInterface::class);
241  $frontendMock->method('getIdentifier')->willReturn('pages');
242 
243  $subject = $this->‪initializeSubject();
244  $subject->setCache($frontendMock);
245 
246  ‪$identifier = ‪StringUtility::getUniqueId('NonExistingIdentifier');
247  self::assertFalse($subject->remove(‪$identifier));
248  }
249 
250  #[Test]
252  {
253  $frontendMock = $this->createMock(FrontendInterface::class);
254  $frontendMock->method('getIdentifier')->willReturn('pages');
255 
256  $subject = $this->‪initializeSubject();
257  $subject->setCache($frontendMock);
258 
259  $data = 'some data' . microtime();
260  $subject->set('BackendMemcacheTest1', $data, ['UnitTestTag%test', 'UnitTestTag%boring']);
261  $subject->set('BackendMemcacheTest2', $data, ['UnitTestTag%test', 'UnitTestTag%special']);
262  $subject->set('BackendMemcacheTest3', $data, ['UnitTestTag%test']);
263  $subject->flushByTag('UnitTestTag%special');
264  self::assertTrue($subject->has('BackendMemcacheTest1'));
265  self::assertFalse($subject->has('BackendMemcacheTest2'));
266  self::assertTrue($subject->has('BackendMemcacheTest3'));
267  }
268 
269  #[Test]
271  {
272  $frontendMock = $this->createMock(FrontendInterface::class);
273  $frontendMock->method('getIdentifier')->willReturn('pages');
274 
275  $subject = $this->‪initializeSubject();
276  $subject->setCache($frontendMock);
277 
278  $data = 'some data' . microtime();
279  $subject->set('BackendMemcacheTest1', $data, ['UnitTestTag%test', 'UnitTestTag%boring']);
280  $subject->set('BackendMemcacheTest2', $data, ['UnitTestTag%test', 'UnitTestTag%special']);
281  $subject->set('BackendMemcacheTest3', $data, ['UnitTestTag%test']);
282  $subject->flushByTags(['UnitTestTag%special', 'UnitTestTag%boring']);
283  self::assertFalse($subject->has('BackendMemcacheTest1'));
284  self::assertFalse($subject->has('BackendMemcacheTest2'));
285  self::assertTrue($subject->has('BackendMemcacheTest3'));
286  }
287 
288  #[Test]
289  public function ‪flushRemovesAllCacheEntries(): void
290  {
291  $frontendMock = $this->createMock(FrontendInterface::class);
292  $frontendMock->method('getIdentifier')->willReturn('pages');
293 
294  $subject = $this->‪initializeSubject();
295  $subject->setCache($frontendMock);
296 
297  $data = 'some data' . microtime();
298  $subject->set('BackendMemcacheTest1', $data);
299  $subject->set('BackendMemcacheTest2', $data);
300  $subject->set('BackendMemcacheTest3', $data);
301  $subject->flush();
302  self::assertFalse($subject->has('BackendMemcacheTest1'));
303  self::assertFalse($subject->has('BackendMemcacheTest2'));
304  self::assertFalse($subject->has('BackendMemcacheTest3'));
305  }
306 
307  #[Test]
308  public function ‪flushRemovesOnlyOwnEntries(): void
309  {
310  $thisFrontendMock = $this->createMock(FrontendInterface::class);
311  $thisFrontendMock->method('getIdentifier')->willReturn('thisCache');
312  $thisBackend = $this->‪initializeSubject();
313  $thisBackend->setCache($thisFrontendMock);
314 
315  $thatFrontendMock = $this->createMock(FrontendInterface::class);
316  $thatFrontendMock->method('getIdentifier')->willReturn('thatCache');
317  $thatBackend = $this->‪initializeSubject();
318  $thatBackend->setCache($thatFrontendMock);
319 
320  $thisBackend->set('thisEntry', 'Hello');
321  $thatBackend->set('thatEntry', 'World!');
322  $thatBackend->flush();
323 
324  self::assertEquals('Hello', $thisBackend->get('thisEntry'));
325  self::assertFalse($thatBackend->has('thatEntry'));
326  }
327 }
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\itIsPossibleToSetAndGetEntry
‪itIsPossibleToSetAndGetEntry()
Definition: MemcachedBackendTest.php:100
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\initializeObjectThrowsExceptionIfNoMemcacheServerIsConfigured
‪initializeObjectThrowsExceptionIfNoMemcacheServerIsConfigured()
Definition: MemcachedBackendTest.php:77
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\findIdentifiersByTagFindsCacheEntriesWithSpecifiedTag
‪findIdentifiersByTagFindsCacheEntriesWithSpecifiedTag()
Definition: MemcachedBackendTest.php:191
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\setThrowsExceptionIfNoFrontEndHasBeenSet
‪setThrowsExceptionIfNoFrontEndHasBeenSet()
Definition: MemcachedBackendTest.php:66
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\setRemovesTagsFromPreviousSet
‪setRemovesTagsFromPreviousSet()
Definition: MemcachedBackendTest.php:209
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend
Definition: ApcuBackendTest.php:18
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\$initializeDatabase
‪bool $initializeDatabase
Definition: MemcachedBackendTest.php:29
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\initializeSubject
‪initializeSubject()
Definition: MemcachedBackendTest.php:52
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\flushRemovesAllCacheEntries
‪flushRemovesAllCacheEntries()
Definition: MemcachedBackendTest.php:289
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest
Definition: MemcachedBackendTest.php:28
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\itIsPossibleToRemoveEntryFromCache
‪itIsPossibleToRemoveEntryFromCache()
Definition: MemcachedBackendTest.php:158
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\itIsPossibleToOverwriteAnEntryInTheCache
‪itIsPossibleToOverwriteAnEntryInTheCache()
Definition: MemcachedBackendTest.php:174
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\largeDataIsStored
‪largeDataIsStored()
Definition: MemcachedBackendTest.php:143
‪TYPO3\CMS\Core\Cache\Exception
Definition: DuplicateIdentifierException.php:16
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\hasReturnsFalseIfTheEntryDoesntExist
‪hasReturnsFalseIfTheEntryDoesntExist()
Definition: MemcachedBackendTest.php:225
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\removeReturnsFalseIfTheEntryDoesntExist
‪removeReturnsFalseIfTheEntryDoesntExist()
Definition: MemcachedBackendTest.php:238
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\flushByTagsRemovesCacheEntriesWithSpecifiedTags
‪flushByTagsRemovesCacheEntriesWithSpecifiedTags()
Definition: MemcachedBackendTest.php:270
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\getReturnsPreviouslySetDataWithVariousTypes
‪getReturnsPreviouslySetDataWithVariousTypes()
Definition: MemcachedBackendTest.php:115
‪TYPO3\CMS\Core\Cache\Backend\MemcachedBackend
Definition: MemcachedBackend.php:46
‪TYPO3\CMS\Core\Utility\StringUtility
Definition: StringUtility.php:24
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\itIsPossibleToSetAndCheckExistenceInCache
‪itIsPossibleToSetAndCheckExistenceInCache()
Definition: MemcachedBackendTest.php:86
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\flushRemovesOnlyOwnEntries
‪flushRemovesOnlyOwnEntries()
Definition: MemcachedBackendTest.php:308
‪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
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\flushByTagRemovesCacheEntriesWithSpecifiedTag
‪flushByTagRemovesCacheEntriesWithSpecifiedTag()
Definition: MemcachedBackendTest.php:251
‪TYPO3\CMS\Core\Tests\Functional\Cache\Backend\MemcachedBackendTest\setUp
‪setUp()
Definition: MemcachedBackendTest.php:34