[TASK] Update copyright year to 2013
[Packages/TYPO3.CMS.git] / typo3 / sysext / core / Tests / Unit / Cache / Backend / MemcachedBackendTest.php
1 <?php
2 namespace TYPO3\CMS\Core\Tests\Unit\Cache\Backend;
3
4 /***************************************************************
5 * Copyright notice
6 *
7 * (c) 2009-2013 Ingo Renner <ingo@typo3.org>
8 * All rights reserved
9 *
10 * This script is part of the TYPO3 project. The TYPO3 project is
11 * free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * The GNU General Public License can be found at
17 * http://www.gnu.org/copyleft/gpl.html.
18 *
19 * This script is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * This copyright notice MUST APPEAR in all copies of the script!
25 ***************************************************************/
26
27 /**
28 * Testcase for the cache to memcached backend
29 *
30 * This file is a backport from FLOW3
31 *
32 * @author Ingo Renner <ingo@typo3.org>
33 */
34 class MemcachedBackendTest extends \TYPO3\CMS\Core\Tests\UnitTestCase {
35
36 /**
37 * Sets up this testcase
38 *
39 * @return void
40 */
41 public function setUp() {
42 if (!extension_loaded('memcache')) {
43 $this->markTestSkipped('memcache extension was not available');
44 }
45 try {
46 if (!fsockopen('localhost', 11211)) {
47 $this->markTestSkipped('memcached not reachable');
48 }
49 } catch (\Exception $e) {
50 $this->markTestSkipped('memcached not reachable');
51 }
52 }
53
54 /**
55 * @test
56 * @expectedException \TYPO3\CMS\Core\Cache\Exception
57 */
58 public function setThrowsExceptionIfNoFrontEndHasBeenSet() {
59 $backendOptions = array('servers' => array('localhost:11211'));
60 $backend = new \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend('Testing', $backendOptions);
61 $backend->initializeObject();
62 $data = 'Some data';
63 $identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
64 $backend->set($identifier, $data);
65 }
66
67 /**
68 * @test
69 * @expectedException \TYPO3\CMS\Core\Cache\Exception
70 */
71 public function initializeObjectThrowsExceptionIfNoMemcacheServerIsConfigured() {
72 $backend = new \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend('Testing');
73 $backend->initializeObject();
74 }
75
76 /**
77 * @test
78 */
79 public function itIsPossibleToSetAndCheckExistenceInCache() {
80 $backend = $this->setUpBackend();
81 $data = 'Some data';
82 $identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
83 $backend->set($identifier, $data);
84 $inCache = $backend->has($identifier);
85 $this->assertTrue($inCache, 'Memcache failed to set and check entry');
86 }
87
88 /**
89 * @test
90 */
91 public function itIsPossibleToSetAndGetEntry() {
92 $backend = $this->setUpBackend();
93 $data = 'Some data';
94 $identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
95 $backend->set($identifier, $data);
96 $fetchedData = $backend->get($identifier);
97 $this->assertEquals($data, $fetchedData, 'Memcache failed to set and retrieve data');
98 }
99
100 /**
101 * @test
102 */
103 public function itIsPossibleToRemoveEntryFromCache() {
104 $backend = $this->setUpBackend();
105 $data = 'Some data';
106 $identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
107 $backend->set($identifier, $data);
108 $backend->remove($identifier);
109 $inCache = $backend->has($identifier);
110 $this->assertFalse($inCache, 'Failed to set and remove data from Memcache');
111 }
112
113 /**
114 * @test
115 */
116 public function itIsPossibleToOverwriteAnEntryInTheCache() {
117 $backend = $this->setUpBackend();
118 $data = 'Some data';
119 $identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
120 $backend->set($identifier, $data);
121 $otherData = 'some other data';
122 $backend->set($identifier, $otherData);
123 $fetchedData = $backend->get($identifier);
124 $this->assertEquals($otherData, $fetchedData, 'Memcache failed to overwrite and retrieve data');
125 }
126
127 /**
128 * @test
129 */
130 public function findIdentifiersByTagFindsCacheEntriesWithSpecifiedTag() {
131 $backend = $this->setUpBackend();
132 $data = 'Some data';
133 $identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
134 $backend->set($identifier, $data, array('UnitTestTag%tag1', 'UnitTestTag%tag2'));
135 $retrieved = $backend->findIdentifiersByTag('UnitTestTag%tag1');
136 $this->assertEquals($identifier, $retrieved[0], 'Could not retrieve expected entry by tag.');
137 $retrieved = $backend->findIdentifiersByTag('UnitTestTag%tag2');
138 $this->assertEquals($identifier, $retrieved[0], 'Could not retrieve expected entry by tag.');
139 }
140
141 /**
142 * @test
143 */
144 public function setRemovesTagsFromPreviousSet() {
145 $backend = $this->setUpBackend();
146 $data = 'Some data';
147 $identifier = 'MyIdentifier' . md5(uniqid(mt_rand(), TRUE));
148 $backend->set($identifier, $data, array('UnitTestTag%tag1', 'UnitTestTag%tag2'));
149 $backend->set($identifier, $data, array('UnitTestTag%tag3'));
150 $retrieved = $backend->findIdentifiersByTag('UnitTestTag%tagX');
151 $this->assertEquals(array(), $retrieved, 'Found entry which should no longer exist.');
152 }
153
154 /**
155 * @test
156 */
157 public function hasReturnsFalseIfTheEntryDoesntExist() {
158 $backend = $this->setUpBackend();
159 $identifier = 'NonExistingIdentifier' . md5(uniqid(mt_rand(), TRUE));
160 $inCache = $backend->has($identifier);
161 $this->assertFalse($inCache, '"has" did not return FALSE when checking on non existing identifier');
162 }
163
164 /**
165 * @test
166 */
167 public function removeReturnsFalseIfTheEntryDoesntExist() {
168 $backend = $this->setUpBackend();
169 $identifier = 'NonExistingIdentifier' . md5(uniqid(mt_rand(), TRUE));
170 $inCache = $backend->remove($identifier);
171 $this->assertFalse($inCache, '"remove" did not return FALSE when checking on non existing identifier');
172 }
173
174 /**
175 * @test
176 */
177 public function flushByTagRemovesCacheEntriesWithSpecifiedTag() {
178 $backend = $this->setUpBackend();
179 $data = 'some data' . microtime();
180 $backend->set('BackendMemcacheTest1', $data, array('UnitTestTag%test', 'UnitTestTag%boring'));
181 $backend->set('BackendMemcacheTest2', $data, array('UnitTestTag%test', 'UnitTestTag%special'));
182 $backend->set('BackendMemcacheTest3', $data, array('UnitTestTag%test'));
183 $backend->flushByTag('UnitTestTag%special');
184 $this->assertTrue($backend->has('BackendMemcacheTest1'), 'BackendMemcacheTest1');
185 $this->assertFalse($backend->has('BackendMemcacheTest2'), 'BackendMemcacheTest2');
186 $this->assertTrue($backend->has('BackendMemcacheTest3'), 'BackendMemcacheTest3');
187 }
188
189 /**
190 * @test
191 */
192 public function flushRemovesAllCacheEntries() {
193 $backend = $this->setUpBackend();
194 $data = 'some data' . microtime();
195 $backend->set('BackendMemcacheTest1', $data);
196 $backend->set('BackendMemcacheTest2', $data);
197 $backend->set('BackendMemcacheTest3', $data);
198 $backend->flush();
199 $this->assertFalse($backend->has('BackendMemcacheTest1'), 'BackendMemcacheTest1');
200 $this->assertFalse($backend->has('BackendMemcacheTest2'), 'BackendMemcacheTest2');
201 $this->assertFalse($backend->has('BackendMemcacheTest3'), 'BackendMemcacheTest3');
202 }
203
204 /**
205 * @test
206 */
207 public function flushRemovesOnlyOwnEntries() {
208 $backendOptions = array('servers' => array('localhost:11211'));
209 $thisCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array(), array(), '', FALSE);
210 $thisCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thisCache'));
211 $thisBackend = new \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend('Testing', $backendOptions);
212 $thisBackend->setCache($thisCache);
213 $thisBackend->initializeObject();
214 $thatCache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\AbstractFrontend', array(), array(), '', FALSE);
215 $thatCache->expects($this->any())->method('getIdentifier')->will($this->returnValue('thatCache'));
216 $thatBackend = new \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend('Testing', $backendOptions);
217 $thatBackend->setCache($thatCache);
218 $thatBackend->initializeObject();
219 $thisBackend->set('thisEntry', 'Hello');
220 $thatBackend->set('thatEntry', 'World!');
221 $thatBackend->flush();
222 $this->assertEquals('Hello', $thisBackend->get('thisEntry'));
223 $this->assertFalse($thatBackend->has('thatEntry'));
224 }
225
226 /**
227 * Check if we can store ~5 MB of data, this gives some headroom for the
228 * reflection data.
229 *
230 * @test
231 */
232 public function largeDataIsStored() {
233 $backend = $this->setUpBackend();
234 $data = str_repeat('abcde', 1024 * 1024);
235 $backend->set('tooLargeData', $data);
236 $this->assertTrue($backend->has('tooLargeData'));
237 $this->assertEquals($backend->get('tooLargeData'), $data);
238 }
239
240 /**
241 * Sets up the memcached backend used for testing
242 *
243 * @param array $backendOptions Options for the memcache backend
244 * @return \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend
245 */
246 protected function setUpBackend(array $backendOptions = array()) {
247 $cache = $this->getMock('TYPO3\\CMS\\Core\\Cache\\Frontend\\FrontendInterface', array(), array(), '', FALSE);
248 if ($backendOptions == array()) {
249 $backendOptions = array('servers' => array('localhost:11211'));
250 }
251 $backend = new \TYPO3\CMS\Core\Cache\Backend\MemcachedBackend('Testing', $backendOptions);
252 $backend->setCache($cache);
253 $backend->initializeObject();
254 return $backend;
255 }
256
257 }
258
259 ?>