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