ILIAS  trunk Revision v11.0_alpha-3011-gc6b235a2e85
CacheTest.php
Go to the documentation of this file.
1<?php
2
19namespace ILIAS\Cache;
20
22use PHPUnit\Framework\Attributes\DataProvider;
28use PHPUnit\Framework\TestCase;
33
34require_once(__DIR__ . '/../../../../vendor/composer/vendor/autoload.php');
35
39class CacheTest extends TestCase
40{
41 public const TEST_CONTAINER = 'test_container';
43
44 protected function setUp(): void
45 {
46 $language_mock = $this->createMock(\ilLanguage::class);
47 $this->refinery = new Factory(
48 new \ILIAS\Data\Factory(),
49 $language_mock
50 );
51 // prevent chached values between tests
52 $static_flush = new PHPStatic($this->getConfig(Config::PHPSTATIC));
53 $static_flush->flush();
54 }
55
59 protected function getConfig(string $adaptor_name = Config::PHPSTATIC): Config
60 {
61 return new Config(
62 $adaptor_name,
63 true,
64 [self::TEST_CONTAINER],
65 new class () extends NullNodeRepository {
66 public function getNodes(): array
67 {
68 return [new Node('127.0.0.1', 11211, 100)];
69 }
70 }
71 );
72 }
73
74 public function testActivatedComponents(): void
75 {
76 $config = new Config(
78 true,
79 ['one', 'two']
80 );
81
82 $services = new Services($config);
83 $this->assertInstanceOf(ActiveContainer::class, $services->get($this->getDummyRequest('one')));
84 $this->assertInstanceOf(ActiveContainer::class, $services->get($this->getDummyRequest('two')));
85 $this->assertInstanceOf(VoidContainer::class, $services->get($this->getDummyRequest('three')));
86
87 $config = new Config(
89 true,
90 ['*']
91 );
92 $services = new Services($config);
93 $this->assertInstanceOf(ActiveContainer::class, $services->get($this->getDummyRequest('one')));
94 $this->assertInstanceOf(ActiveContainer::class, $services->get($this->getDummyRequest('two')));
95 $this->assertInstanceOf(ActiveContainer::class, $services->get($this->getDummyRequest('three')));
96 }
97
98 public function testMultipleContainers(): void
99 {
100 $config = new Config(
102 true,
103 ['one', 'two']
104 );
105
106 $services = new Services($config);
107
108 $one = $this->getDummyRequest('one');
109 $two = $this->getDummyRequest('two');
110 $three = $this->getDummyRequest('three');
111
112 $this->assertSame('one', $one->getContainerKey());
113 $this->assertSame('two', $two->getContainerKey());
114 $this->assertSame('three', $three->getContainerKey());
115
116 $container_one = $services->get($one);
117 $container_two = $services->get($two);
118 $container_three = $services->get($three);
119
120 $this->assertInstanceOf(ActiveContainer::class, $container_one);
121 $this->assertInstanceOf(ActiveContainer::class, $container_two);
122 $this->assertInstanceOf(VoidContainer::class, $container_three);
123
124 $container_one->set('test', 'test_value');
125 $this->assertTrue($container_one->has('test'));
126 $this->assertSame('test_value', $container_one->get('test', $this->refinery->to()->string()));
127
128 $container_two->set('test', 'test_value');
129 $this->assertTrue($container_two->has('test'));
130 $this->assertSame('test_value', $container_two->get('test', $this->refinery->to()->string()));
131
132 $container_three->set('test', 'test_value');
133 $this->assertFalse($container_three->has('test'));
134 $this->assertNull($container_three->get('test', $this->refinery->to()->string()));
135 }
136
137 public function testLock(): void
138 {
139 $services = new Services($this->getConfig());
140 $container = $services->get($this->getDummyRequest(self::TEST_CONTAINER));
141 $container->unlock();
142
143 $container->set('test', 'test_value');
144 $this->assertTrue($container->has('test'));
145 $this->assertSame('test_value', $container->get('test', $this->refinery->to()->string()));
146
147 $container->lock(1 / 1000);
148 $this->assertTrue($container->isLocked());
149 $this->assertFalse($container->has('test'));
150 $this->assertNull($container->get('test', $this->refinery->to()->string()));
151 usleep(1000);
152 $this->assertFalse($container->isLocked());
153 $this->assertTrue($container->has('test'));
154 $this->assertSame('test_value', $container->get('test', $this->refinery->to()->string()));
155
156 // Second Run
157 $container->lock(1 / 1000);
158 $this->assertTrue($container->isLocked());
159 $this->assertFalse($container->has('test'));
160 $this->assertNull($container->get('test', $this->refinery->to()->string()));
161 usleep(100);
162 $this->assertTrue($container->isLocked());
163 $this->assertFalse($container->has('test'));
164 $this->assertNull($container->get('test', $this->refinery->to()->string()));
165
166 usleep(5000); // to avoid problems with the next test
167 $this->assertFalse($container->isLocked());
168 }
169
170 public static function getInvalidLockTimes(): \Iterator
171 {
172 yield [-10];
173 yield [-1];
174 yield [301];
175 yield [300.1];
176 }
177
178 #[DataProvider('getInvalidLockTimes')]
179 public function testInvalidLockTimes(float|int $time): void
180 {
181 $services = new Services($this->getConfig());
182 $container = $services->get($this->getDummyRequest(self::TEST_CONTAINER));
183 $this->expectException(\InvalidArgumentException::class);
184 $container->lock($time);
185 }
186
187 public function testDelete(): void
188 {
189 $services = new Services($this->getConfig());
190 $container = $services->get($this->getDummyRequest(self::TEST_CONTAINER));
191
192 $container->set('test', 'test_value');
193 $this->assertTrue($container->has('test'));
194 $this->assertSame('test_value', $container->get('test', $this->refinery->to()->string()));
195
196 $container->delete('test');
197 $this->assertFalse($container->has('test'));
198 $this->assertNull($container->get('test', $this->refinery->to()->string()));
199 }
200
201 public function testDefaultAdaptor(): void
202 {
203 $request = $this->getDummyRequest(self::TEST_CONTAINER);
204
205 $to_string = $this->refinery->kindlyTo()->string();
206
207 $config = $this->getConfig();
208
209 $static = new PHPStatic($config);
210 $this->assertTrue($static->isAvailable());
211
212 $services = new Services($config);
213 $container = $services->get($request);
214 $this->assertInstanceOf(ActiveContainer::class, $container);
215 $this->assertSame(Config::PHPSTATIC, $container->getAdaptorName());
216 $this->assertSame(self::TEST_CONTAINER, $container->getContainerName());
217
218 $this->assertFalse($container->has('test'));
219 $container->set('test', 'test_value');
220 $this->assertTrue($container->has('test'));
221 $this->assertSame('test_value', $container->get('test', $to_string));
222 $container->delete('test');
223 $this->assertFalse($container->has('test'));
224
225 $container->set('test2', 'test_value2');
226 $container->set('test3', 'test_value3');
227 $this->assertTrue($container->has('test2'));
228 $this->assertTrue($container->has('test3'));
229
230 $container->flush();
231
232 $this->assertFalse($container->has('test2'));
233 $this->assertFalse($container->has('test3'));
234 }
235
236 public function testFlush(): void
237 {
238 $services = new Services($this->getConfig());
239 $container = $services->get($this->getDummyRequest(self::TEST_CONTAINER));
240
241 $container->set('test', 'test_value');
242 $this->assertTrue($container->has('test'));
243 $this->assertSame('test_value', $container->get('test', $this->refinery->to()->string()));
244
245 $container->flush();
246 $this->assertFalse($container->has('test'));
247 $this->assertNull($container->get('test', $this->refinery->to()->string()));
248
249 $container->set('test', 'test_value');
250 $this->assertTrue($container->has('test'));
251 $this->assertSame('test_value', $container->get('test', $this->refinery->to()->string()));
252
253 $services->flushAdapter();
254 $this->assertFalse($container->has('test'));
255 $this->assertNull($container->get('test', $this->refinery->to()->string()));
256 }
257
258 public function testAPCAdapter(): void
259 {
260 $config = $this->getConfig(Config::APCU);
261 $services = new Services($config);
262 $container = $services->get($this->getDummyRequest(self::TEST_CONTAINER));
263 $this->assertSame(Config::APCU, $container->getAdaptorName());
264 $this->assertSame(self::TEST_CONTAINER, $container->getContainerName());
265
266 $apcu = new APCu($config);
267 if (!$apcu->isAvailable() || !(bool) ini_get('apc.enable_cli')) {
268 $this->markTestSkipped('APCu is not available or not enabled for CLI');
269 }
270
271 $to_string = $this->refinery->kindlyTo()->string();
272
273 $this->assertFalse($container->has('test'));
274 $container->set('test', 'test_value');
275 $this->assertTrue($container->has('test'));
276 $this->assertSame('test_value', $container->get('test', $to_string));
277 $container->delete('test');
278 $this->assertFalse($container->has('test'));
279
280 $container->set('test2', 'test_value2');
281 $container->set('test3', 'test_value3');
282 $this->assertTrue($container->has('test2'));
283 $this->assertTrue($container->has('test3'));
284
285 $container->flush();
286
287 $this->assertFalse($container->has('test2'));
288 $this->assertFalse($container->has('test3'));
289 }
290
295 private function deactivatedTestMemcachedAdapter(): void
296 {
297 $config = $this->getConfig(Config::MEMCACHED);
298 $services = new Services($config);
299 $container = $services->get($this->getDummyRequest(self::TEST_CONTAINER));
300 $this->assertSame(Config::MEMCACHED, $container->getAdaptorName());
301 $this->assertSame(self::TEST_CONTAINER, $container->getContainerName());
302
303 $apcu = new Memcached($config);
304 if (!$apcu->isAvailable()) {
305 $this->markTestSkipped('Memcached is not available');
306 }
307
308 $this->assertFalse($container->has('test'));
309 $container->set('test', 'test_value');
310 $this->assertTrue($container->has('test'));
311 $this->assertSame('test_value', $container->get('test'));
312 $container->delete('test');
313 $this->assertFalse($container->has('test'));
314
315 $container->set('test2', 'test_value2');
316 $container->set('test3', 'test_value3');
317 $this->assertTrue($container->has('test2'));
318 $this->assertTrue($container->has('test3'));
319
320 $container->flush();
321
322 $this->assertFalse($container->has('test2'));
323 $this->assertFalse($container->has('test3'));
324 }
325
326 public function testObjectStorage(): void
327 {
328 $services = new Services($this->getConfig());
329 $container = $services->get($this->getDummyRequest(self::TEST_CONTAINER));
330
331 $first_object = new \stdClass();
332 $first_object->test = 'test';
333 $container->set('first_object', serialize($first_object));
334
335 $this->assertTrue($container->has('first_object'));
336
337 $to_string = $this->refinery->kindlyTo()->string();
338
339 $data = $container->get('first_object', $to_string);
340 $first_object_from_cache = unserialize($data, ['allowed_classes' => [\stdClass::class]]);
341 $this->assertInstanceOf(\stdClass::class, $first_object_from_cache);
342 $this->assertEquals($first_object, $first_object_from_cache);
343 }
344
345 public function testTypes(): void
346 {
347 $services = new Services($this->getConfig());
348 $container = $services->get($this->getDummyRequest(self::TEST_CONTAINER));
349
350 // TRANSFORMATION
351 $to_string = $this->refinery->to()->string();
352 $to_int = $this->refinery->to()->int();
353 $to_array = $this->refinery->to()->listOf($to_string);
354 $to_bool = $this->refinery->to()->bool();
355
356 // STRING
357 $string = 'test';
358 $container->set('string', $string);
359 $this->assertTrue($container->has('string'));
360 $string_from_cache = $container->get('string', $to_string);
361 $this->assertSame($string, $string_from_cache);
362 $this->assertEquals(null, $container->get('string', $to_int));
363 $this->assertEquals(null, $container->get('string', $to_bool));
364 $this->assertEquals(null, $container->get('string', $to_array));
365 $this->assertIsString($string_from_cache);
366
367 // ARRAY
368 $array = ['test', 'test2', 'test3'];
369 $container->set('array', $array);
370 $this->assertTrue($container->has('array'));
371 $array_from_cache = $container->get('array', $to_array);
372 $this->assertSame($array, $array_from_cache);
373 $this->assertEquals(null, $container->get('array', $to_int));
374 $this->assertEquals(null, $container->get('array', $to_bool));
375 $this->assertEquals(null, $container->get('array', $to_string));
376 $this->assertIsArray($array_from_cache);
377
378 // BOOL
379 $bool = true;
380 $container->set('bool', $bool);
381 $this->assertTrue($container->has('bool'));
382 $bool_from_cache = $container->get('bool', $to_bool);
383 $this->assertEquals($bool, $bool_from_cache);
384 $this->assertEquals(null, $container->get('bool', $to_int));
385 $this->assertEquals(null, $container->get('bool', $to_array));
386 $this->assertEquals(null, $container->get('bool', $to_string));
387 $this->assertIsBool($bool_from_cache);
388
389 // ARRAY Different values
390 $array_with_different_values = ['test' => true, 'test2' => 123, 'test3' => ['test' => 'test'], 'test4' => null];
391 $container->set('array_with_different_values', $array_with_different_values);
392 $this->assertTrue($container->has('array_with_different_values'));
393
394 $trafo = $this->refinery->to()->dictOf(
395 $this->refinery->custom()->transformation(
396 fn($value) => $value
397 )
398 );
399
400 $array_with_different_values_from_cache = $container->get('array_with_different_values', $trafo);
401 $this->assertEquals($array_with_different_values, $array_with_different_values_from_cache);
402 $this->assertIsArray($array_with_different_values_from_cache);
403 $this->assertIsBool($array_with_different_values_from_cache['test']);
404 $this->assertIsInt($array_with_different_values_from_cache['test2']);
405 $this->assertIsArray($array_with_different_values_from_cache['test3']);
406 $this->assertNull($array_with_different_values_from_cache['test4']);
407
408 $this->assertEquals(null, $container->get('array_with_different_values', $to_int));
409 $this->assertEquals(null, $container->get('array_with_different_values', $to_bool));
410 $this->assertEquals(null, $container->get('array_with_different_values', $to_string));
411
412 // INT
413 $int = 123;
414 $container->set('int', $int);
415 $this->assertTrue($container->has('int'));
416 $int_from_cache = $container->get('int', $to_int);
417 $this->assertSame($int, $int_from_cache);
418 $this->assertEquals(null, $container->get('int', $to_string));
419 $this->assertEquals(null, $container->get('int', $to_bool));
420 $this->assertEquals(null, $container->get('int', $to_array));
421 $this->assertIsInt($int_from_cache);
422 }
423
424 public function testIncomatibleType(): void
425 {
426 $services = new Services($this->getConfig());
427 $container = $services->get(
428 $this->getDummyRequest(self::TEST_CONTAINER)
429 );
430
431 $this->expectException(\TypeError::class);
432 $container->set('test', new \stdClass());
433 }
434
435 public function testIncomatibleNestedType(): void
436 {
437 $services = new Services($this->getConfig());
438 $container = $services->get(
439 $this->getDummyRequest(self::TEST_CONTAINER)
440 );
441 $array_with_incompatible_type_in_it = [
442 'test' => 'test',
443 'test2' => 'test2',
444 'test3' => ['test' => new \stdClass()]
445 ];
446 $this->expectException(\InvalidArgumentException::class);
447 $container->set(
448 'array_with_incompatible_type_in_it',
449 $array_with_incompatible_type_in_it
450 );
451 }
452
453 public function testIncomatibleTypeNested(): void
454 {
455 $services = new Services($this->getConfig());
456 $container = $services->get($this->getDummyRequest(self::TEST_CONTAINER));
457
458 $array_with_incompatible_type_in_it = [
459 'test' => 'test',
460 'test2' => 'test2',
461 'test3' => ['test' => new \stdClass()]
462 ];
463 $this->expectException(\InvalidArgumentException::class);
464 $container->set('array_with_incompatible_type_in_it', $array_with_incompatible_type_in_it);
465 }
466
467 protected function getDummyRequest(string $container_key): Request
468 {
469 return new BaseRequest($container_key);
470 }
471}
static getInvalidLockTimes()
Definition: CacheTest.php:170
getConfig(string $adaptor_name=Config::PHPSTATIC)
Definition: CacheTest.php:59
getDummyRequest(string $container_key)
Definition: CacheTest.php:467
testInvalidLockTimes(float|int $time)
Definition: CacheTest.php:179
deactivatedTestMemcachedAdapter()
@description this test cannot be executed in the CI on github sincewe do not have a memcached server ...
Definition: CacheTest.php:295
Builds data types.
Definition: Factory.php:36
This file is part of ILIAS, a powerful learning management system published by ILIAS open source e-Le...
Interface Observer \BackgroundTasks Contains several chained tasks and infos about them.
$container
@noRector
Definition: wac.php:37