TYPO3 CMS  TYPO3_7-6
MemcachedBackendTest.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 
19 
26 {
32  protected function setUp()
33  {
34  if (!extension_loaded('memcache') && !extension_loaded('memcached')) {
35  $this->markTestSkipped('Neither "memcache" nor "memcached" extension is available');
36  }
37  if (!getenv('typo3TestingMemcachedHost')) {
38  $this->markTestSkipped('environment variable "typo3TestingMemcachedHost" must be set to run this test');
39  }
40  // Note we assume that if that typo3TestingMemcachedHost env is set, we can use that for testing,
41  // there is no test to see if the daemon is actually up and running. Tests will fail if env
42  // is set but daemon is down.
43  }
44 
48  protected function initializeSubject()
49  {
50  // We know this env is set, otherwise setUp() would skip the tests
51  $memcachedHost = getenv('typo3TestingMemcachedHost');
52  // If typo3TestingMemcachedPort env is set, use it, otherwise fall back to standard port
53  $env = getenv('typo3TestingMemcachedPort');
54  $memcachedPort = is_string($env) ? (int)$env : 11211;
55 
57  $cache = $this->getMock(\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface::class, [], [], '', false);
58 
59  $subject = new MemcachedBackend('Testing', [ 'servers' => [$memcachedHost . ':' . $memcachedPort] ]);
60  $subject->setCache($cache);
61  $subject->initializeObject();
62  return $subject;
63  }
64 
70  {
71  // We know this env is set, otherwise setUp() would skip the tests
72  $memcachedHost = getenv('typo3TestingMemcachedHost');
73  // If typo3TestingMemcachedPort env is set, use it, otherwise fall back to standard port
74  $env = getenv('typo3TestingMemcachedPort');
75  $memcachedPort = is_string($env) ? (int)$env : 11211;
76 
77  $backend = new MemcachedBackend('Testing', [ 'servers' => [$memcachedHost . ':' . $memcachedPort] ]);
78  $backend->initializeObject();
79  $data = 'Some data';
80  $identifier = $this->getUniqueId('MyIdentifier');
81  $backend->set($identifier, $data);
82  }
83 
89  {
90  $backend = new MemcachedBackend('Testing');
91  $backend->initializeObject();
92  }
93 
98  {
99  $backend = $this->initializeSubject();
100  $data = 'Some data';
101  $identifier = $this->getUniqueId('MyIdentifier');
102  $backend->set($identifier, $data);
103  $inCache = $backend->has($identifier);
104  $this->assertTrue($inCache, 'Memcache failed to set and check entry');
105  }
106 
111  {
112  $backend = $this->initializeSubject();
113  $data = 'Some data';
114  $identifier = $this->getUniqueId('MyIdentifier');
115  $backend->set($identifier, $data);
116  $fetchedData = $backend->get($identifier);
117  $this->assertEquals($data, $fetchedData, 'Memcache failed to set and retrieve data');
118  }
119 
124  {
125  $backend = $this->initializeSubject();
126  $data = 'Some data';
127  $identifier = $this->getUniqueId('MyIdentifier');
128  $backend->set($identifier, $data);
129  $backend->remove($identifier);
130  $inCache = $backend->has($identifier);
131  $this->assertFalse($inCache, 'Failed to set and remove data from Memcache');
132  }
133 
138  {
139  $backend = $this->initializeSubject();
140  $data = 'Some data';
141  $identifier = $this->getUniqueId('MyIdentifier');
142  $backend->set($identifier, $data);
143  $otherData = 'some other data';
144  $backend->set($identifier, $otherData);
145  $fetchedData = $backend->get($identifier);
146  $this->assertEquals($otherData, $fetchedData, 'Memcache failed to overwrite and retrieve data');
147  }
148 
153  {
154  $backend = $this->initializeSubject();
155  $data = 'Some data';
156  $identifier = $this->getUniqueId('MyIdentifier');
157  $backend->set($identifier, $data, ['UnitTestTag%tag1', 'UnitTestTag%tag2']);
158  $retrieved = $backend->findIdentifiersByTag('UnitTestTag%tag1');
159  $this->assertEquals($identifier, $retrieved[0], 'Could not retrieve expected entry by tag.');
160  $retrieved = $backend->findIdentifiersByTag('UnitTestTag%tag2');
161  $this->assertEquals($identifier, $retrieved[0], 'Could not retrieve expected entry by tag.');
162  }
163 
168  {
169  $backend = $this->initializeSubject();
170  $data = 'Some data';
171  $identifier = $this->getUniqueId('MyIdentifier');
172  $backend->set($identifier, $data, ['UnitTestTag%tag1', 'UnitTestTag%tag2']);
173  $backend->set($identifier, $data, ['UnitTestTag%tag3']);
174  $retrieved = $backend->findIdentifiersByTag('UnitTestTag%tagX');
175  $this->assertEquals([], $retrieved, 'Found entry which should no longer exist.');
176  }
177 
182  {
183  $backend = $this->initializeSubject();
184  $identifier = $this->getUniqueId('NonExistingIdentifier');
185  $inCache = $backend->has($identifier);
186  $this->assertFalse($inCache, '"has" did not return FALSE when checking on non existing identifier');
187  }
188 
193  {
194  $backend = $this->initializeSubject();
195  $identifier = $this->getUniqueId('NonExistingIdentifier');
196  $inCache = $backend->remove($identifier);
197  $this->assertFalse($inCache, '"remove" did not return FALSE when checking on non existing identifier');
198  }
199 
204  {
205  $backend = $this->initializeSubject();
206  $data = 'some data' . microtime();
207  $backend->set('BackendMemcacheTest1', $data, ['UnitTestTag%test', 'UnitTestTag%boring']);
208  $backend->set('BackendMemcacheTest2', $data, ['UnitTestTag%test', 'UnitTestTag%special']);
209  $backend->set('BackendMemcacheTest3', $data, ['UnitTestTag%test']);
210  $backend->flushByTag('UnitTestTag%special');
211  $this->assertTrue($backend->has('BackendMemcacheTest1'), 'BackendMemcacheTest1');
212  $this->assertFalse($backend->has('BackendMemcacheTest2'), 'BackendMemcacheTest2');
213  $this->assertTrue($backend->has('BackendMemcacheTest3'), 'BackendMemcacheTest3');
214  }
215 
219  public function flushRemovesAllCacheEntries()
220  {
221  $backend = $this->initializeSubject();
222  $data = 'some data' . microtime();
223  $backend->set('BackendMemcacheTest1', $data);
224  $backend->set('BackendMemcacheTest2', $data);
225  $backend->set('BackendMemcacheTest3', $data);
226  $backend->flush();
227  $this->assertFalse($backend->has('BackendMemcacheTest1'), 'BackendMemcacheTest1');
228  $this->assertFalse($backend->has('BackendMemcacheTest2'), 'BackendMemcacheTest2');
229  $this->assertFalse($backend->has('BackendMemcacheTest3'), 'BackendMemcacheTest3');
230  }
231 
235  public function flushRemovesOnlyOwnEntries()
236  {
237  // We know this env is set, otherwise setUp() would skip the tests
238  $memcachedHost = getenv('typo3TestingMemcachedHost');
239  // If typo3TestingMemcachedPort env is set, use it, otherwise fall back to standard port
240  $env = getenv('typo3TestingMemcachedPort');
241  $memcachedPort = is_string($env) ? (int)$env : 11211;
242 
244  $thisCache = $this->getMock(\TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class, [], [], '', false);
245  $thisCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thisCache'));
246  $thisBackend = new MemcachedBackend('Testing', [ 'servers' => [$memcachedHost . ':' . $memcachedPort] ]);
247  $thisBackend->setCache($thisCache);
248  $thisBackend->initializeObject();
249 
251  $thatCache = $this->getMock(\TYPO3\CMS\Core\Cache\Frontend\AbstractFrontend::class, [], [], '', false);
252  $thatCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thatCache'));
253  $thatBackend = new MemcachedBackend('Testing', [ 'servers' => [$memcachedHost . ':' . $memcachedPort] ]);
254  $thatBackend->setCache($thatCache);
255  $thatBackend->initializeObject();
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 
269  public function largeDataIsStored()
270  {
271  $backend = $this->initializeSubject();
272  $data = str_repeat('abcde', 1024 * 1024);
273  $backend->set('tooLargeData', $data);
274  $this->assertTrue($backend->has('tooLargeData'));
275  $this->assertEquals($backend->get('tooLargeData'), $data);
276  }
277 
281  public function setTagsOnlyOnceToIdentifier()
282  {
283  // We know this env is set, otherwise setUp() would skip the tests
284  $memcachedHost = getenv('typo3TestingMemcachedHost');
285  // If typo3TestingMemcachedPort env is set, use it, otherwise fall back to standard port
286  $env = getenv('typo3TestingMemcachedPort');
287  $memcachedPort = is_string($env) ? (int)$env : 11211;
288 
289  $accessibleClassName = $this->buildAccessibleProxy(MemcachedBackend::class);
290  $backend = new $accessibleClassName('Testing', [ 'servers' => [$memcachedHost . ':' . $memcachedPort] ]);
291 
293  $cache = $this->getMock(\TYPO3\CMS\Core\Cache\Frontend\FrontendInterface::class, [], [], '', false);
294  $backend->setCache($cache);
295  $backend->initializeObject();
296 
297  $identifier = $this->getUniqueId('MyIdentifier');
298  $tags = ['UnitTestTag%test', 'UnitTestTag%boring'];
299 
300  $backend->_call('addIdentifierToTags', $identifier, $tags);
301  $this->assertSame(
302  $tags,
303  $backend->_call('findTagsByIdentifier', $identifier)
304  );
305 
306  $backend->_call('addIdentifierToTags', $identifier, $tags);
307  $this->assertSame(
308  $tags,
309  $backend->_call('findTagsByIdentifier', $identifier)
310  );
311  }
312 }