|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
namespace Doctrine\Tests\Common\Cache; |
|
4
|
|
|
|
|
5
|
|
|
use Doctrine\Common\Cache\Cache; |
|
6
|
|
|
use ArrayObject; |
|
7
|
|
|
|
|
8
|
|
|
abstract class CacheTest extends \Doctrine\Tests\DoctrineTestCase |
|
9
|
|
|
{ |
|
10
|
|
|
/** |
|
11
|
|
|
* @dataProvider provideDataToCache |
|
12
|
|
|
*/ |
|
13
|
|
|
public function testSetContainsFetchDelete($value) |
|
14
|
|
|
{ |
|
15
|
|
|
$cache = $this->_getCacheDriver(); |
|
16
|
|
|
|
|
17
|
|
|
// Test saving a value, checking if it exists, and fetching it back |
|
18
|
|
|
$this->assertTrue($cache->save('key', $value)); |
|
19
|
|
|
$this->assertTrue($cache->contains('key')); |
|
20
|
|
|
if (is_object($value)) { |
|
21
|
|
|
$this->assertEquals($value, $cache->fetch('key'), 'Objects retrieved from the cache must be equal but not necessarily the same reference'); |
|
22
|
|
|
} else { |
|
23
|
|
|
$this->assertSame($value, $cache->fetch('key'), 'Scalar and array data retrieved from the cache must be the same as the original, e.g. same type'); |
|
24
|
|
|
} |
|
25
|
|
|
|
|
26
|
|
|
// Test deleting a value |
|
27
|
|
|
$this->assertTrue($cache->delete('key')); |
|
28
|
|
|
$this->assertFalse($cache->contains('key')); |
|
29
|
|
|
$this->assertFalse($cache->fetch('key')); |
|
30
|
|
|
} |
|
31
|
|
|
|
|
32
|
|
|
/** |
|
33
|
|
|
* @dataProvider provideDataToCache |
|
34
|
|
|
*/ |
|
35
|
|
|
public function testUpdateExistingEntry($value) |
|
36
|
|
|
{ |
|
37
|
|
|
$cache = $this->_getCacheDriver(); |
|
38
|
|
|
|
|
39
|
|
|
$this->assertTrue($cache->save('key', 'old-value')); |
|
40
|
|
|
$this->assertTrue($cache->contains('key')); |
|
41
|
|
|
|
|
42
|
|
|
$this->assertTrue($cache->save('key', $value)); |
|
43
|
|
|
$this->assertTrue($cache->contains('key')); |
|
44
|
|
|
if (is_object($value)) { |
|
45
|
|
|
$this->assertEquals($value, $cache->fetch('key'), 'Objects retrieved from the cache must be equal but not necessarily the same reference'); |
|
46
|
|
|
} else { |
|
47
|
|
|
$this->assertSame($value, $cache->fetch('key'), 'Scalar and array data retrieved from the cache must be the same as the original, e.g. same type'); |
|
48
|
|
|
} |
|
49
|
|
|
} |
|
50
|
|
|
|
|
51
|
|
|
public function testCacheKeyIsCaseSensitive() |
|
52
|
|
|
{ |
|
53
|
|
|
$cache = $this->_getCacheDriver(); |
|
54
|
|
|
|
|
55
|
|
|
$this->assertTrue($cache->save('key', 'value')); |
|
56
|
|
|
$this->assertTrue($cache->contains('key')); |
|
57
|
|
|
$this->assertSame('value', $cache->fetch('key')); |
|
58
|
|
|
|
|
59
|
|
|
$this->assertFalse($cache->contains('KEY')); |
|
60
|
|
|
$this->assertFalse($cache->fetch('KEY')); |
|
61
|
|
|
|
|
62
|
|
|
$cache->delete('KEY'); |
|
63
|
|
|
$this->assertTrue($cache->contains('key', 'Deleting cache item with different case must not affect other cache item')); |
|
|
|
|
|
|
64
|
|
|
} |
|
65
|
|
|
|
|
66
|
|
|
public function testFetchMultiple() |
|
67
|
|
|
{ |
|
68
|
|
|
$cache = $this->_getCacheDriver(); |
|
69
|
|
|
$values = $this->provideDataToCache(); |
|
70
|
|
|
$saved = array(); |
|
71
|
|
|
|
|
72
|
|
|
foreach ($values as $key => $value) { |
|
73
|
|
|
$cache->save($key, $value[0]); |
|
74
|
|
|
|
|
75
|
|
|
$saved[$key] = $value[0]; |
|
76
|
|
|
} |
|
77
|
|
|
|
|
78
|
|
|
$keys = array_keys($saved); |
|
79
|
|
|
|
|
80
|
|
|
$this->assertEquals( |
|
81
|
|
|
$saved, |
|
82
|
|
|
$cache->fetchMultiple($keys), |
|
83
|
|
|
'Testing fetchMultiple with different data types' |
|
84
|
|
|
); |
|
85
|
|
|
$this->assertEquals( |
|
86
|
|
|
array_slice($saved, 0, 1), |
|
87
|
|
|
$cache->fetchMultiple(array_slice($keys, 0, 1)), |
|
88
|
|
|
'Testing fetchMultiple with a single key' |
|
89
|
|
|
); |
|
90
|
|
|
|
|
91
|
|
|
$keysWithNonExisting = array(); |
|
92
|
|
|
$keysWithNonExisting[] = 'non_existing1'; |
|
93
|
|
|
$keysWithNonExisting[] = $keys[0]; |
|
94
|
|
|
$keysWithNonExisting[] = 'non_existing2'; |
|
95
|
|
|
$keysWithNonExisting[] = $keys[1]; |
|
96
|
|
|
$keysWithNonExisting[] = 'non_existing3'; |
|
97
|
|
|
|
|
98
|
|
|
$this->assertEquals( |
|
99
|
|
|
array_slice($saved, 0, 2), |
|
100
|
|
|
$cache->fetchMultiple($keysWithNonExisting), |
|
101
|
|
|
'Testing fetchMultiple with a subset of keys and mixed with non-existing ones' |
|
102
|
|
|
); |
|
103
|
|
|
} |
|
104
|
|
|
|
|
105
|
|
|
public function testFetchMultipleWithNoKeys() |
|
106
|
|
|
{ |
|
107
|
|
|
$cache = $this->_getCacheDriver(); |
|
108
|
|
|
|
|
109
|
|
|
$this->assertSame(array(), $cache->fetchMultiple(array())); |
|
110
|
|
|
} |
|
111
|
|
|
|
|
112
|
|
|
public function testSaveMultiple() |
|
113
|
|
|
{ |
|
114
|
|
|
$cache = $this->_getCacheDriver(); |
|
115
|
|
|
$cache->deleteAll(); |
|
116
|
|
|
|
|
117
|
|
|
$data = array_map(function ($value) { |
|
118
|
|
|
return $value[0]; |
|
119
|
|
|
}, $this->provideDataToCache()); |
|
120
|
|
|
|
|
121
|
|
|
$this->assertTrue($cache->saveMultiple($data)); |
|
122
|
|
|
|
|
123
|
|
|
$keys = array_keys($data); |
|
124
|
|
|
|
|
125
|
|
|
$this->assertEquals($data, $cache->fetchMultiple($keys)); |
|
126
|
|
|
} |
|
127
|
|
|
|
|
128
|
|
|
public function provideDataToCache() |
|
129
|
|
|
{ |
|
130
|
|
|
$obj = new \stdClass(); |
|
131
|
|
|
$obj->foo = 'bar'; |
|
132
|
|
|
$obj2 = new \stdClass(); |
|
133
|
|
|
$obj2->bar = 'foo'; |
|
134
|
|
|
$obj2->obj = $obj; |
|
135
|
|
|
$obj->obj2 = $obj2; |
|
136
|
|
|
|
|
137
|
|
|
return array( |
|
138
|
|
|
'array' => array(array('one', 2, 3.01)), |
|
139
|
|
|
'string' => array('value'), |
|
140
|
|
|
'string_invalid_utf8' => array("\xc3\x28"), |
|
141
|
|
|
'string_null_byte' => array('with'."\0".'null char'), |
|
142
|
|
|
'integer' => array(1), |
|
143
|
|
|
'float' => array(1.5), |
|
144
|
|
|
'object' => array(new ArrayObject(array('one', 2, 3.01))), |
|
145
|
|
|
'object_recursive' => array($obj), |
|
146
|
|
|
'true' => array(true), |
|
147
|
|
|
// the following are considered FALSE in boolean context, but caches should still recognize their existence |
|
148
|
|
|
'null' => array(null), |
|
149
|
|
|
'false' => array(false), |
|
150
|
|
|
'array_empty' => array(array()), |
|
151
|
|
|
'string_zero' => array('0'), |
|
152
|
|
|
'integer_zero' => array(0), |
|
153
|
|
|
'float_zero' => array(0.0), |
|
154
|
|
|
'string_empty' => array(''), |
|
155
|
|
|
); |
|
156
|
|
|
} |
|
157
|
|
|
|
|
158
|
|
|
public function testDeleteIsSuccessfulWhenKeyDoesNotExist() |
|
159
|
|
|
{ |
|
160
|
|
|
$cache = $this->_getCacheDriver(); |
|
161
|
|
|
|
|
162
|
|
|
$cache->delete('key'); |
|
163
|
|
|
$this->assertFalse($cache->contains('key')); |
|
164
|
|
|
$this->assertTrue($cache->delete('key')); |
|
165
|
|
|
} |
|
166
|
|
|
|
|
167
|
|
|
public function testDeleteAll() |
|
168
|
|
|
{ |
|
169
|
|
|
$cache = $this->_getCacheDriver(); |
|
170
|
|
|
|
|
171
|
|
|
$this->assertTrue($cache->save('key1', 1)); |
|
172
|
|
|
$this->assertTrue($cache->save('key2', 2)); |
|
173
|
|
|
$this->assertTrue($cache->deleteAll()); |
|
174
|
|
|
$this->assertFalse($cache->contains('key1')); |
|
175
|
|
|
$this->assertFalse($cache->contains('key2')); |
|
176
|
|
|
} |
|
177
|
|
|
|
|
178
|
|
|
/** |
|
179
|
|
|
* @dataProvider provideCacheIds |
|
180
|
|
|
*/ |
|
181
|
|
|
public function testCanHandleSpecialCacheIds($id) |
|
182
|
|
|
{ |
|
183
|
|
|
$cache = $this->_getCacheDriver(); |
|
184
|
|
|
|
|
185
|
|
|
$this->assertTrue($cache->save($id, 'value')); |
|
186
|
|
|
$this->assertTrue($cache->contains($id)); |
|
187
|
|
|
$this->assertEquals('value', $cache->fetch($id)); |
|
188
|
|
|
|
|
189
|
|
|
$this->assertTrue($cache->delete($id)); |
|
190
|
|
|
$this->assertFalse($cache->contains($id)); |
|
191
|
|
|
$this->assertFalse($cache->fetch($id)); |
|
192
|
|
|
} |
|
193
|
|
|
|
|
194
|
|
|
public function testNoCacheIdCollisions() |
|
195
|
|
|
{ |
|
196
|
|
|
$cache = $this->_getCacheDriver(); |
|
197
|
|
|
|
|
198
|
|
|
$ids = $this->provideCacheIds(); |
|
199
|
|
|
|
|
200
|
|
|
// fill cache with each id having a different value |
|
201
|
|
|
foreach ($ids as $index => $id) { |
|
202
|
|
|
$cache->save($id[0], $index); |
|
203
|
|
|
} |
|
204
|
|
|
|
|
205
|
|
|
// then check value of each cache id |
|
206
|
|
|
foreach ($ids as $index => $id) { |
|
207
|
|
|
$value = $cache->fetch($id[0]); |
|
208
|
|
|
$this->assertNotFalse($value, sprintf('Failed to retrieve data for cache id "%s".', $id[0])); |
|
209
|
|
|
if ($index !== $value) { |
|
210
|
|
|
$this->fail(sprintf('Cache id "%s" collides with id "%s".', $id[0], $ids[$value][0])); |
|
211
|
|
|
} |
|
212
|
|
|
} |
|
213
|
|
|
} |
|
214
|
|
|
|
|
215
|
|
|
/** |
|
216
|
|
|
* Returns cache ids with special characters that should still work. |
|
217
|
|
|
* |
|
218
|
|
|
* For example, the characters :\/<>"*?| are not valid in Windows filenames. So they must be encoded properly. |
|
219
|
|
|
* Each cache id should be considered different from the others. |
|
220
|
|
|
* |
|
221
|
|
|
* @return array |
|
222
|
|
|
*/ |
|
223
|
|
|
public function provideCacheIds() |
|
224
|
|
|
{ |
|
225
|
|
|
return array( |
|
226
|
|
|
array(':'), |
|
227
|
|
|
array('\\'), |
|
228
|
|
|
array('/'), |
|
229
|
|
|
array('<'), |
|
230
|
|
|
array('>'), |
|
231
|
|
|
array('"'), |
|
232
|
|
|
array('*'), |
|
233
|
|
|
array('?'), |
|
234
|
|
|
array('|'), |
|
235
|
|
|
array('['), |
|
236
|
|
|
array(']'), |
|
237
|
|
|
array('ä'), |
|
238
|
|
|
array('a'), |
|
239
|
|
|
array('é'), |
|
240
|
|
|
array('e'), |
|
241
|
|
|
array('.'), // directory traversal |
|
242
|
|
|
array('..'), // directory traversal |
|
243
|
|
|
array('-'), |
|
244
|
|
|
array('_'), |
|
245
|
|
|
array('$'), |
|
246
|
|
|
array('%'), |
|
247
|
|
|
array(' '), |
|
248
|
|
|
array("\0"), |
|
249
|
|
|
array(''), |
|
250
|
|
|
array(str_repeat('a', 300)), // long key |
|
251
|
|
|
array(str_repeat('a', 113)), |
|
252
|
|
|
); |
|
253
|
|
|
} |
|
254
|
|
|
|
|
255
|
|
|
public function testLifetime() |
|
256
|
|
|
{ |
|
257
|
|
|
$cache = $this->_getCacheDriver(); |
|
258
|
|
|
$cache->save('expire', 'value', 1); |
|
259
|
|
|
$this->assertTrue($cache->contains('expire'), 'Data should not be expired yet'); |
|
260
|
|
|
// @TODO should more TTL-based tests pop up, so then we should mock the `time` API instead |
|
261
|
|
|
sleep(2); |
|
262
|
|
|
$this->assertFalse($cache->contains('expire'), 'Data should be expired'); |
|
263
|
|
|
} |
|
264
|
|
|
|
|
265
|
|
|
public function testNoExpire() |
|
266
|
|
|
{ |
|
267
|
|
|
$cache = $this->_getCacheDriver(); |
|
268
|
|
|
$cache->save('noexpire', 'value', 0); |
|
269
|
|
|
// @TODO should more TTL-based tests pop up, so then we should mock the `time` API instead |
|
270
|
|
|
sleep(1); |
|
271
|
|
|
$this->assertTrue($cache->contains('noexpire'), 'Data with lifetime of zero should not expire'); |
|
272
|
|
|
} |
|
273
|
|
|
|
|
274
|
|
|
public function testLongLifetime() |
|
275
|
|
|
{ |
|
276
|
|
|
$cache = $this->_getCacheDriver(); |
|
277
|
|
|
$cache->save('longlifetime', 'value', 30 * 24 * 3600 + 1); |
|
278
|
|
|
$this->assertTrue($cache->contains('longlifetime'), 'Data with lifetime > 30 days should be accepted'); |
|
279
|
|
|
} |
|
280
|
|
|
|
|
281
|
|
|
public function testDeleteAllAndNamespaceVersioningBetweenCaches() |
|
282
|
|
|
{ |
|
283
|
|
|
if ( ! $this->isSharedStorage()) { |
|
284
|
|
|
$this->markTestSkipped('The cache storage needs to be shared.'); |
|
285
|
|
|
} |
|
286
|
|
|
|
|
287
|
|
|
$cache1 = $this->_getCacheDriver(); |
|
288
|
|
|
$cache2 = $this->_getCacheDriver(); |
|
289
|
|
|
|
|
290
|
|
|
$this->assertTrue($cache1->save('key1', 1)); |
|
291
|
|
|
$this->assertTrue($cache2->save('key2', 2)); |
|
292
|
|
|
|
|
293
|
|
|
/* Both providers are initialized with the same namespace version, so |
|
294
|
|
|
* they can see entries set by each other. |
|
295
|
|
|
*/ |
|
296
|
|
|
$this->assertTrue($cache1->contains('key1')); |
|
297
|
|
|
$this->assertTrue($cache1->contains('key2')); |
|
298
|
|
|
$this->assertTrue($cache2->contains('key1')); |
|
299
|
|
|
$this->assertTrue($cache2->contains('key2')); |
|
300
|
|
|
|
|
301
|
|
|
/* Deleting all entries through one provider will only increment the |
|
302
|
|
|
* namespace version on that object (and in the cache itself, which new |
|
303
|
|
|
* instances will use to initialize). The second provider will retain |
|
304
|
|
|
* its original version and still see stale data. |
|
305
|
|
|
*/ |
|
306
|
|
|
$this->assertTrue($cache1->deleteAll()); |
|
307
|
|
|
$this->assertFalse($cache1->contains('key1')); |
|
308
|
|
|
$this->assertFalse($cache1->contains('key2')); |
|
309
|
|
|
$this->assertTrue($cache2->contains('key1')); |
|
310
|
|
|
$this->assertTrue($cache2->contains('key2')); |
|
311
|
|
|
|
|
312
|
|
|
/* A new cache provider should not see the deleted entries, since its |
|
313
|
|
|
* namespace version will be initialized. |
|
314
|
|
|
*/ |
|
315
|
|
|
$cache3 = $this->_getCacheDriver(); |
|
316
|
|
|
$this->assertFalse($cache3->contains('key1')); |
|
317
|
|
|
$this->assertFalse($cache3->contains('key2')); |
|
318
|
|
|
} |
|
319
|
|
|
|
|
320
|
|
|
public function testFlushAll() |
|
321
|
|
|
{ |
|
322
|
|
|
$cache = $this->_getCacheDriver(); |
|
323
|
|
|
|
|
324
|
|
|
$this->assertTrue($cache->save('key1', 1)); |
|
325
|
|
|
$this->assertTrue($cache->save('key2', 2)); |
|
326
|
|
|
$this->assertTrue($cache->flushAll()); |
|
327
|
|
|
$this->assertFalse($cache->contains('key1')); |
|
328
|
|
|
$this->assertFalse($cache->contains('key2')); |
|
329
|
|
|
} |
|
330
|
|
|
|
|
331
|
|
|
public function testFlushAllAndNamespaceVersioningBetweenCaches() |
|
332
|
|
|
{ |
|
333
|
|
|
if ( ! $this->isSharedStorage()) { |
|
334
|
|
|
$this->markTestSkipped('The cache storage needs to be shared.'); |
|
335
|
|
|
} |
|
336
|
|
|
|
|
337
|
|
|
$cache1 = $this->_getCacheDriver(); |
|
338
|
|
|
$cache2 = $this->_getCacheDriver(); |
|
339
|
|
|
|
|
340
|
|
|
/* Deleting all elements from the first provider should increment its |
|
341
|
|
|
* namespace version before saving the first entry. |
|
342
|
|
|
*/ |
|
343
|
|
|
$cache1->deleteAll(); |
|
344
|
|
|
$this->assertTrue($cache1->save('key1', 1)); |
|
345
|
|
|
|
|
346
|
|
|
/* The second provider will be initialized with the same namespace |
|
347
|
|
|
* version upon its first save operation. |
|
348
|
|
|
*/ |
|
349
|
|
|
$this->assertTrue($cache2->save('key2', 2)); |
|
350
|
|
|
|
|
351
|
|
|
/* Both providers have the same namespace version and can see entries |
|
352
|
|
|
* set by each other. |
|
353
|
|
|
*/ |
|
354
|
|
|
$this->assertTrue($cache1->contains('key1')); |
|
355
|
|
|
$this->assertTrue($cache1->contains('key2')); |
|
356
|
|
|
$this->assertTrue($cache2->contains('key1')); |
|
357
|
|
|
$this->assertTrue($cache2->contains('key2')); |
|
358
|
|
|
|
|
359
|
|
|
/* Flushing all entries through one cache will remove all entries from |
|
360
|
|
|
* the cache but leave their namespace version as-is. |
|
361
|
|
|
*/ |
|
362
|
|
|
$this->assertTrue($cache1->flushAll()); |
|
363
|
|
|
$this->assertFalse($cache1->contains('key1')); |
|
364
|
|
|
$this->assertFalse($cache1->contains('key2')); |
|
365
|
|
|
$this->assertFalse($cache2->contains('key1')); |
|
366
|
|
|
$this->assertFalse($cache2->contains('key2')); |
|
367
|
|
|
|
|
368
|
|
|
/* Inserting a new entry will use the same, incremented namespace |
|
369
|
|
|
* version, and it will be visible to both providers. |
|
370
|
|
|
*/ |
|
371
|
|
|
$this->assertTrue($cache1->save('key1', 1)); |
|
372
|
|
|
$this->assertTrue($cache1->contains('key1')); |
|
373
|
|
|
$this->assertTrue($cache2->contains('key1')); |
|
374
|
|
|
|
|
375
|
|
|
/* A new cache provider will be initialized with the original namespace |
|
376
|
|
|
* version and not share any visibility with the first two providers. |
|
377
|
|
|
*/ |
|
378
|
|
|
$cache3 = $this->_getCacheDriver(); |
|
379
|
|
|
$this->assertFalse($cache3->contains('key1')); |
|
380
|
|
|
$this->assertFalse($cache3->contains('key2')); |
|
381
|
|
|
$this->assertTrue($cache3->save('key3', 3)); |
|
382
|
|
|
$this->assertTrue($cache3->contains('key3')); |
|
383
|
|
|
} |
|
384
|
|
|
|
|
385
|
|
|
public function testNamespace() |
|
386
|
|
|
{ |
|
387
|
|
|
$cache = $this->_getCacheDriver(); |
|
388
|
|
|
|
|
389
|
|
|
$cache->setNamespace('ns1_'); |
|
390
|
|
|
|
|
391
|
|
|
$this->assertTrue($cache->save('key1', 1)); |
|
392
|
|
|
$this->assertTrue($cache->contains('key1')); |
|
393
|
|
|
|
|
394
|
|
|
$cache->setNamespace('ns2_'); |
|
395
|
|
|
|
|
396
|
|
|
$this->assertFalse($cache->contains('key1')); |
|
397
|
|
|
} |
|
398
|
|
|
|
|
399
|
|
|
public function testDeleteAllNamespace() |
|
400
|
|
|
{ |
|
401
|
|
|
$cache = $this->_getCacheDriver(); |
|
402
|
|
|
|
|
403
|
|
|
$cache->setNamespace('ns1'); |
|
404
|
|
|
$this->assertFalse($cache->contains('key1')); |
|
405
|
|
|
$cache->save('key1', 'test'); |
|
406
|
|
|
$this->assertTrue($cache->contains('key1')); |
|
407
|
|
|
|
|
408
|
|
|
$cache->setNamespace('ns2'); |
|
409
|
|
|
$this->assertFalse($cache->contains('key1')); |
|
410
|
|
|
$cache->save('key1', 'test'); |
|
411
|
|
|
$this->assertTrue($cache->contains('key1')); |
|
412
|
|
|
|
|
413
|
|
|
$cache->setNamespace('ns1'); |
|
414
|
|
|
$this->assertTrue($cache->contains('key1')); |
|
415
|
|
|
$cache->deleteAll(); |
|
416
|
|
|
$this->assertFalse($cache->contains('key1')); |
|
417
|
|
|
|
|
418
|
|
|
$cache->setNamespace('ns2'); |
|
419
|
|
|
$this->assertTrue($cache->contains('key1')); |
|
420
|
|
|
$cache->deleteAll(); |
|
421
|
|
|
$this->assertFalse($cache->contains('key1')); |
|
422
|
|
|
} |
|
423
|
|
|
|
|
424
|
|
|
/** |
|
425
|
|
|
* @group DCOM-43 |
|
426
|
|
|
*/ |
|
427
|
|
|
public function testGetStats() |
|
428
|
|
|
{ |
|
429
|
|
|
$cache = $this->_getCacheDriver(); |
|
430
|
|
|
$stats = $cache->getStats(); |
|
431
|
|
|
|
|
432
|
|
|
$this->assertArrayHasKey(Cache::STATS_HITS, $stats); |
|
433
|
|
|
$this->assertArrayHasKey(Cache::STATS_MISSES, $stats); |
|
434
|
|
|
$this->assertArrayHasKey(Cache::STATS_UPTIME, $stats); |
|
435
|
|
|
$this->assertArrayHasKey(Cache::STATS_MEMORY_USAGE, $stats); |
|
436
|
|
|
$this->assertArrayHasKey(Cache::STATS_MEMORY_AVAILABLE, $stats); |
|
437
|
|
|
} |
|
438
|
|
|
|
|
439
|
|
|
public function testSaveReturnsTrueWithAndWithoutTTlSet() |
|
440
|
|
|
{ |
|
441
|
|
|
$cache = $this->_getCacheDriver(); |
|
442
|
|
|
$cache->deleteAll(); |
|
443
|
|
|
$this->assertTrue($cache->save('without_ttl', 'without_ttl')); |
|
444
|
|
|
$this->assertTrue($cache->save('with_ttl', 'with_ttl', 3600)); |
|
445
|
|
|
} |
|
446
|
|
|
|
|
447
|
|
|
/** |
|
448
|
|
|
* Return whether multiple cache providers share the same storage. |
|
449
|
|
|
* |
|
450
|
|
|
* This is used for skipping certain tests for shared storage behavior. |
|
451
|
|
|
* |
|
452
|
|
|
* @return bool |
|
453
|
|
|
*/ |
|
454
|
|
|
protected function isSharedStorage() |
|
455
|
|
|
{ |
|
456
|
|
|
return true; |
|
457
|
|
|
} |
|
458
|
|
|
|
|
459
|
|
|
/** |
|
460
|
|
|
* @return \Doctrine\Common\Cache\CacheProvider |
|
461
|
|
|
*/ |
|
462
|
|
|
abstract protected function _getCacheDriver(); |
|
463
|
|
|
} |
|
464
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.