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