Commit | Line | Data |
---|---|---|
42f2c59e SH |
1 | <?php |
2 | // This file is part of Moodle - http://moodle.org/ | |
3 | // | |
4 | // Moodle is free software: you can redistribute it and/or modify | |
5 | // it under the terms of the GNU General Public License as published by | |
6 | // the Free Software Foundation, either version 3 of the License, or | |
7 | // (at your option) any later version. | |
8 | // | |
9 | // Moodle is distributed in the hope that it will be useful, | |
10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 | // GNU General Public License for more details. | |
13 | // | |
14 | // You should have received a copy of the GNU General Public License | |
15 | // along with Moodle. If not, see <http://www.gnu.org/licenses/>. | |
16 | ||
17 | /** | |
18 | * PHPunit tests for the cache API and in particular things in locallib.php | |
19 | * | |
20 | * This file is part of Moodle's cache API, affectionately called MUC. | |
21 | * It contains the components that are requried in order to use caching. | |
22 | * | |
23 | * @package core | |
24 | * @category cache | |
25 | * @copyright 2012 Sam Hemelryk | |
26 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
27 | */ | |
28 | ||
29 | defined('MOODLE_INTERNAL') || die(); | |
30 | ||
31 | // Include the necessary evils. | |
32 | global $CFG; | |
33 | require_once($CFG->dirroot.'/cache/locallib.php'); | |
34 | require_once($CFG->dirroot.'/cache/tests/fixtures/lib.php'); | |
35 | ||
36 | /** | |
37 | * PHPunit tests for the cache API and in particular the cache config writer. | |
38 | * | |
39 | * @copyright 2012 Sam Hemelryk | |
40 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
41 | */ | |
42 | class cache_config_writer_phpunit_tests extends advanced_testcase { | |
43 | ||
44 | /** | |
45 | * Set things back to the default before each test. | |
46 | */ | |
47 | public function setUp() { | |
48 | parent::setUp(); | |
49 | cache_factory::reset(); | |
50 | cache_config_phpunittest::create_default_configuration(); | |
51 | } | |
52 | ||
3680c61a SH |
53 | /** |
54 | * Final task is to reset the cache system | |
55 | */ | |
56 | public static function tearDownAfterClass() { | |
57 | parent::tearDownAfterClass(); | |
58 | cache_factory::reset(); | |
59 | } | |
60 | ||
42f2c59e SH |
61 | /** |
62 | * Test getting an instance. Pretty basic. | |
63 | */ | |
64 | public function test_instance() { | |
65 | $config = cache_config_writer::instance(); | |
66 | $this->assertInstanceOf('cache_config_writer', $config); | |
67 | } | |
68 | ||
69 | /** | |
70 | * Test the default configuration. | |
71 | */ | |
72 | public function test_default_configuration() { | |
73 | $config = cache_config_writer::instance(); | |
74 | ||
75 | // First check stores. | |
76 | $stores = $config->get_all_stores(); | |
77 | $hasapplication = false; | |
78 | $hassession = false; | |
79 | $hasrequest = false; | |
80 | foreach ($stores as $store) { | |
81 | // Check the required keys. | |
82 | $this->assertArrayHasKey('name', $store); | |
83 | $this->assertArrayHasKey('plugin', $store); | |
84 | $this->assertArrayHasKey('modes', $store); | |
85 | $this->assertArrayHasKey('default', $store); | |
86 | // Check the mode, we need at least one default store of each mode. | |
87 | if (!empty($store['default'])) { | |
88 | if ($store['modes'] & cache_store::MODE_APPLICATION) { | |
89 | $hasapplication = true; | |
90 | } | |
91 | if ($store['modes'] & cache_store::MODE_SESSION) { | |
92 | $hassession = true; | |
93 | } | |
94 | if ($store['modes'] & cache_store::MODE_REQUEST) { | |
95 | $hasrequest = true; | |
96 | } | |
97 | } | |
98 | } | |
99 | $this->assertTrue($hasapplication, 'There is no default application cache store.'); | |
100 | $this->assertTrue($hassession, 'There is no default session cache store.'); | |
101 | $this->assertTrue($hasrequest, 'There is no default request cache store.'); | |
102 | ||
103 | // Next check the definitions. | |
104 | $definitions = $config->get_definitions(); | |
105 | $eventinvalidation = false; | |
106 | foreach ($definitions as $definition) { | |
107 | // Check the required keys. | |
108 | $this->assertArrayHasKey('mode', $definition); | |
109 | $this->assertArrayHasKey('component', $definition); | |
110 | $this->assertArrayHasKey('area', $definition); | |
111 | if ($definition['component'] === 'core' && $definition['area'] === 'eventinvalidation') { | |
112 | $eventinvalidation = true; | |
113 | } | |
114 | } | |
115 | $this->assertTrue($eventinvalidation, 'Missing the event invalidation definition.'); | |
116 | ||
117 | // Next mode mappings | |
118 | $mappings = $config->get_mode_mappings(); | |
119 | $hasapplication = false; | |
120 | $hassession = false; | |
121 | $hasrequest = false; | |
122 | foreach ($mappings as $mode) { | |
123 | // Check the required keys. | |
124 | $this->assertArrayHasKey('mode', $mode); | |
125 | $this->assertArrayHasKey('store', $mode); | |
126 | ||
127 | if ($mode['mode'] === cache_store::MODE_APPLICATION) { | |
128 | $hasapplication = true; | |
129 | } | |
130 | if ($mode['mode'] === cache_store::MODE_SESSION) { | |
131 | $hassession = true; | |
132 | } | |
133 | if ($mode['mode'] === cache_store::MODE_REQUEST) { | |
134 | $hasrequest = true; | |
135 | } | |
136 | } | |
137 | $this->assertTrue($hasapplication, 'There is no mapping for the application mode.'); | |
138 | $this->assertTrue($hassession, 'There is no mapping for the session mode.'); | |
139 | $this->assertTrue($hasrequest, 'There is no mapping for the request mode.'); | |
140 | ||
141 | // Finally check config locks | |
142 | $locks = $config->get_locks(); | |
143 | foreach ($locks as $lock) { | |
144 | $this->assertArrayHasKey('name', $lock); | |
145 | $this->assertArrayHasKey('type', $lock); | |
146 | $this->assertArrayHasKey('default', $lock); | |
147 | } | |
148 | // There has to be at least the default lock. | |
149 | $this->assertTrue(count($locks) > 0); | |
150 | } | |
151 | ||
152 | /** | |
153 | * Test updating the definitions. | |
154 | */ | |
155 | public function test_update_definitions() { | |
156 | $config = cache_config_writer::instance(); | |
157 | $earlydefinitions = $config->get_definitions(); | |
158 | unset($config); | |
159 | cache_factory::reset(); | |
160 | cache_config_writer::update_definitions(); | |
161 | ||
162 | $config = cache_config_writer::instance(); | |
163 | $latedefinitions = $config->get_definitions(); | |
164 | ||
165 | $this->assertSame($latedefinitions, $earlydefinitions); | |
166 | } | |
167 | ||
168 | /** | |
169 | * Test adding/editing/deleting store instances. | |
170 | */ | |
171 | public function test_add_edit_delete_plugin_instance() { | |
172 | $config = cache_config_writer::instance(); | |
173 | $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores()); | |
174 | $this->assertArrayNotHasKey('addplugintestwlock', $config->get_all_stores()); | |
175 | // Add a default file instance. | |
26ce56fd | 176 | $config->add_store_instance('addplugintest', 'file'); |
42f2c59e SH |
177 | |
178 | cache_factory::reset(); | |
179 | $config = cache_config_writer::instance(); | |
180 | $this->assertArrayHasKey('addplugintest', $config->get_all_stores()); | |
181 | ||
182 | // Add a store with a lock described. | |
26ce56fd | 183 | $config->add_store_instance('addplugintestwlock', 'file', array('lock' => 'default_file_lock')); |
42f2c59e SH |
184 | $this->assertArrayHasKey('addplugintestwlock', $config->get_all_stores()); |
185 | ||
26ce56fd | 186 | $config->delete_store_instance('addplugintest'); |
42f2c59e SH |
187 | $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores()); |
188 | $this->assertArrayHasKey('addplugintestwlock', $config->get_all_stores()); | |
189 | ||
26ce56fd | 190 | $config->delete_store_instance('addplugintestwlock'); |
42f2c59e SH |
191 | $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores()); |
192 | $this->assertArrayNotHasKey('addplugintestwlock', $config->get_all_stores()); | |
193 | ||
194 | // Add a default file instance. | |
26ce56fd | 195 | $config->add_store_instance('storeconfigtest', 'file', array('test' => 'a', 'one' => 'two')); |
42f2c59e SH |
196 | $stores = $config->get_all_stores(); |
197 | $this->assertArrayHasKey('storeconfigtest', $stores); | |
198 | $this->assertArrayHasKey('configuration', $stores['storeconfigtest']); | |
199 | $this->assertArrayHasKey('test', $stores['storeconfigtest']['configuration']); | |
200 | $this->assertArrayHasKey('one', $stores['storeconfigtest']['configuration']); | |
201 | $this->assertEquals('a', $stores['storeconfigtest']['configuration']['test']); | |
202 | $this->assertEquals('two', $stores['storeconfigtest']['configuration']['one']); | |
203 | ||
26ce56fd | 204 | $config->edit_store_instance('storeconfigtest', 'file', array('test' => 'b', 'one' => 'three')); |
42f2c59e SH |
205 | $stores = $config->get_all_stores(); |
206 | $this->assertArrayHasKey('storeconfigtest', $stores); | |
207 | $this->assertArrayHasKey('configuration', $stores['storeconfigtest']); | |
208 | $this->assertArrayHasKey('test', $stores['storeconfigtest']['configuration']); | |
209 | $this->assertArrayHasKey('one', $stores['storeconfigtest']['configuration']); | |
210 | $this->assertEquals('b', $stores['storeconfigtest']['configuration']['test']); | |
211 | $this->assertEquals('three', $stores['storeconfigtest']['configuration']['one']); | |
212 | ||
26ce56fd | 213 | $config->delete_store_instance('storeconfigtest'); |
42f2c59e SH |
214 | |
215 | try { | |
26ce56fd | 216 | $config->delete_store_instance('default_application'); |
42f2c59e SH |
217 | $this->fail('Default store deleted. This should not be possible!'); |
218 | } catch (Exception $e) { | |
219 | $this->assertInstanceOf('cache_exception', $e); | |
220 | } | |
221 | ||
222 | try { | |
26ce56fd | 223 | $config->delete_store_instance('some_crazy_store'); |
42f2c59e SH |
224 | $this->fail('You should not be able to delete a store that does not exist.'); |
225 | } catch (Exception $e) { | |
226 | $this->assertInstanceOf('cache_exception', $e); | |
227 | } | |
228 | ||
229 | try { | |
230 | // Try with a plugin that does not exist. | |
26ce56fd | 231 | $config->add_store_instance('storeconfigtest', 'shallowfail', array('test' => 'a', 'one' => 'two')); |
42f2c59e SH |
232 | $this->fail('You should not be able to add an instance of a store that does not exist.'); |
233 | } catch (Exception $e) { | |
234 | $this->assertInstanceOf('cache_exception', $e); | |
235 | } | |
236 | } | |
237 | ||
238 | /** | |
239 | * Test setting some mode mappings. | |
240 | */ | |
241 | public function test_set_mode_mappings() { | |
242 | $config = cache_config_writer::instance(); | |
26ce56fd | 243 | $this->assertTrue($config->add_store_instance('setmodetest', 'file')); |
42f2c59e SH |
244 | $this->assertTrue($config->set_mode_mappings(array( |
245 | cache_store::MODE_APPLICATION => array('setmodetest', 'default_application'), | |
246 | cache_store::MODE_SESSION => array('default_session'), | |
247 | cache_store::MODE_REQUEST => array('default_request'), | |
248 | ))); | |
249 | $mappings = $config->get_mode_mappings(); | |
250 | $setmodetestfound = false; | |
251 | foreach ($mappings as $mapping) { | |
252 | if ($mapping['store'] == 'setmodetest' && $mapping['mode'] == cache_store::MODE_APPLICATION) { | |
253 | $setmodetestfound = true; | |
254 | } | |
255 | } | |
256 | $this->assertTrue($setmodetestfound, 'Set mapping did not work as expected.'); | |
257 | } | |
258 | ||
259 | /** | |
260 | * Test setting some definition mappings. | |
261 | */ | |
262 | public function test_set_definition_mappings() { | |
263 | $config = cache_config_phpunittest::instance(true); | |
264 | $config->phpunit_add_definition('phpunit/testdefinition', array( | |
265 | 'mode' => cache_store::MODE_APPLICATION, | |
266 | 'component' => 'phpunit', | |
267 | 'area' => 'testdefinition' | |
268 | )); | |
269 | ||
270 | $config = cache_config_writer::instance(); | |
26ce56fd | 271 | $this->assertTrue($config->add_store_instance('setdefinitiontest', 'file')); |
42f2c59e SH |
272 | $this->assertInternalType('array', $config->get_definition_by_id('phpunit/testdefinition')); |
273 | $config->set_definition_mappings('phpunit/testdefinition', array('setdefinitiontest', 'default_application')); | |
274 | ||
275 | try { | |
276 | $config->set_definition_mappings('phpunit/testdefinition', array('something that does not exist')); | |
277 | $this->fail('You should not be able to set a mapping for a store that does not exist.'); | |
278 | } catch (Exception $e) { | |
279 | $this->assertInstanceOf('coding_exception', $e); | |
280 | } | |
281 | ||
282 | try { | |
283 | $config->set_definition_mappings('something/crazy', array('setdefinitiontest')); | |
284 | $this->fail('You should not be able to set a mapping for a definition that does not exist.'); | |
285 | } catch (Exception $e) { | |
286 | $this->assertInstanceOf('coding_exception', $e); | |
287 | } | |
288 | } | |
289 | } | |
290 | ||
291 | /** | |
292 | * PHPunit tests for the cache API and in particular the cache_administration_helper | |
293 | * | |
294 | * @copyright 2012 Sam Hemelryk | |
295 | * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later | |
296 | */ | |
297 | class cache_administration_helper_phpunit_tests extends advanced_testcase { | |
298 | ||
299 | /** | |
300 | * Set things back to the default before each test. | |
301 | */ | |
302 | public function setUp() { | |
303 | parent::setUp(); | |
304 | cache_factory::reset(); | |
305 | cache_config_phpunittest::create_default_configuration(); | |
306 | } | |
307 | ||
3680c61a SH |
308 | /** |
309 | * Final task is to reset the cache system | |
310 | */ | |
311 | public static function tearDownAfterClass() { | |
312 | parent::tearDownAfterClass(); | |
313 | cache_factory::reset(); | |
314 | } | |
315 | ||
42f2c59e SH |
316 | /** |
317 | * Test the numerous summaries the helper can produce. | |
318 | */ | |
319 | public function test_get_summaries() { | |
320 | // First the preparation. | |
321 | $config = cache_config_writer::instance(); | |
26ce56fd | 322 | $this->assertTrue($config->add_store_instance('summariesstore', 'file')); |
42f2c59e SH |
323 | $config->set_definition_mappings('core/eventinvalidation', array('summariesstore')); |
324 | $this->assertTrue($config->set_mode_mappings(array( | |
325 | cache_store::MODE_APPLICATION => array('summariesstore'), | |
326 | cache_store::MODE_SESSION => array('default_session'), | |
327 | cache_store::MODE_REQUEST => array('default_request'), | |
328 | ))); | |
329 | ||
26ce56fd | 330 | $storesummaries = cache_administration_helper::get_store_instance_summaries(); |
42f2c59e SH |
331 | $this->assertInternalType('array', $storesummaries); |
332 | $this->assertArrayHasKey('summariesstore', $storesummaries); | |
333 | $summary = $storesummaries['summariesstore']; | |
334 | // Check the keys | |
335 | $this->assertArrayHasKey('name', $summary); | |
336 | $this->assertArrayHasKey('plugin', $summary); | |
337 | $this->assertArrayHasKey('default', $summary); | |
338 | $this->assertArrayHasKey('isready', $summary); | |
339 | $this->assertArrayHasKey('requirementsmet', $summary); | |
340 | $this->assertArrayHasKey('mappings', $summary); | |
341 | $this->assertArrayHasKey('modes', $summary); | |
342 | $this->assertArrayHasKey('supports', $summary); | |
343 | // Check the important/known values | |
344 | $this->assertEquals('summariesstore', $summary['name']); | |
345 | $this->assertEquals('file', $summary['plugin']); | |
346 | $this->assertEquals(0, $summary['default']); | |
347 | $this->assertEquals(1, $summary['isready']); | |
348 | $this->assertEquals(1, $summary['requirementsmet']); | |
349 | $this->assertEquals(1, $summary['mappings']); | |
350 | ||
351 | $definitionsummaries = cache_administration_helper::get_definition_summaries(); | |
352 | $this->assertInternalType('array', $definitionsummaries); | |
353 | $this->assertArrayHasKey('core/eventinvalidation', $definitionsummaries); | |
354 | $summary = $definitionsummaries['core/eventinvalidation']; | |
355 | // Check the keys | |
356 | $this->assertArrayHasKey('id', $summary); | |
357 | $this->assertArrayHasKey('name', $summary); | |
358 | $this->assertArrayHasKey('mode', $summary); | |
359 | $this->assertArrayHasKey('component', $summary); | |
360 | $this->assertArrayHasKey('area', $summary); | |
361 | $this->assertArrayHasKey('mappings', $summary); | |
362 | // Check the important/known values | |
363 | $this->assertEquals('core/eventinvalidation', $summary['id']); | |
364 | $this->assertInstanceOf('lang_string', $summary['name']); | |
365 | $this->assertEquals(cache_store::MODE_APPLICATION, $summary['mode']); | |
366 | $this->assertEquals('core', $summary['component']); | |
367 | $this->assertEquals('eventinvalidation', $summary['area']); | |
368 | $this->assertInternalType('array', $summary['mappings']); | |
369 | $this->assertContains('summariesstore', $summary['mappings']); | |
370 | ||
26ce56fd | 371 | $pluginsummaries = cache_administration_helper::get_store_plugin_summaries(); |
42f2c59e SH |
372 | $this->assertInternalType('array', $pluginsummaries); |
373 | $this->assertArrayHasKey('file', $pluginsummaries); | |
374 | $summary = $pluginsummaries['file']; | |
375 | // Check the keys | |
376 | $this->assertArrayHasKey('name', $summary); | |
377 | $this->assertArrayHasKey('requirementsmet', $summary); | |
378 | $this->assertArrayHasKey('instances', $summary); | |
379 | $this->assertArrayHasKey('modes', $summary); | |
380 | $this->assertArrayHasKey('supports', $summary); | |
381 | $this->assertArrayHasKey('canaddinstance', $summary); | |
382 | ||
383 | $locksummaries = cache_administration_helper::get_lock_summaries(); | |
384 | $this->assertInternalType('array', $locksummaries); | |
385 | $this->assertTrue(count($locksummaries) > 0); | |
386 | ||
387 | $mappings = cache_administration_helper::get_default_mode_stores(); | |
388 | $this->assertInternalType('array', $mappings); | |
389 | $this->assertCount(3, $mappings); | |
390 | $this->assertArrayHasKey(cache_store::MODE_APPLICATION, $mappings); | |
391 | $this->assertInternalType('array', $mappings[cache_store::MODE_APPLICATION]); | |
392 | $this->assertContains('summariesstore', $mappings[cache_store::MODE_APPLICATION]); | |
393 | ||
394 | $potentials = cache_administration_helper::get_definition_store_options('core', 'eventinvalidation'); | |
395 | $this->assertInternalType('array', $potentials); // Currently used, suitable, default | |
396 | $this->assertCount(3, $potentials); | |
397 | $this->assertArrayHasKey('summariesstore', $potentials[0]); | |
398 | $this->assertArrayHasKey('summariesstore', $potentials[1]); | |
399 | $this->assertArrayHasKey('default_application', $potentials[1]); | |
400 | } | |
401 | ||
402 | /** | |
403 | * Test instantiating an add store form. | |
404 | */ | |
405 | public function test_get_add_store_form() { | |
406 | $form = cache_administration_helper::get_add_store_form('file'); | |
407 | $this->assertInstanceOf('moodleform', $form); | |
408 | ||
409 | try { | |
410 | $form = cache_administration_helper::get_add_store_form('somethingstupid'); | |
411 | $this->fail('You should not be able to create an add form for a store plugin that does not exist.'); | |
412 | } catch (moodle_exception $e) { | |
413 | $this->assertInstanceOf('coding_exception', $e, 'Needs to be: ' .get_class($e)." ::: ".$e->getMessage()); | |
414 | } | |
415 | } | |
416 | ||
417 | /** | |
418 | * Test instantiating a form to edit a store instance. | |
419 | */ | |
420 | public function test_get_edit_store_form() { | |
421 | $config = cache_config_writer::instance(); | |
26ce56fd | 422 | $this->assertTrue($config->add_store_instance('summariesstore', 'file')); |
42f2c59e SH |
423 | |
424 | $form = cache_administration_helper::get_edit_store_form('file', 'summariesstore'); | |
425 | $this->assertInstanceOf('moodleform', $form); | |
426 | ||
427 | try { | |
428 | $form = cache_administration_helper::get_edit_store_form('somethingstupid', 'moron'); | |
429 | $this->fail('You should not be able to create an edit form for a store plugin that does not exist.'); | |
430 | } catch (moodle_exception $e) { | |
431 | $this->assertInstanceOf('coding_exception', $e); | |
432 | } | |
433 | ||
434 | try { | |
435 | $form = cache_administration_helper::get_edit_store_form('file', 'blisters'); | |
436 | $this->fail('You should not be able to create an edit form for a store plugin that does not exist.'); | |
437 | } catch (moodle_exception $e) { | |
438 | $this->assertInstanceOf('coding_exception', $e); | |
439 | } | |
440 | } | |
5dd68a75 SH |
441 | |
442 | /** | |
443 | * Test the hash_key functionality. | |
444 | */ | |
445 | public function test_hash_key() { | |
446 | global $CFG; | |
447 | ||
448 | $currentdebugging = $CFG->debug; | |
449 | ||
450 | $CFG->debug = E_ALL; | |
451 | ||
452 | // First with simplekeys | |
453 | $instance = cache_config_phpunittest::instance(true); | |
454 | $instance->phpunit_add_definition('phpunit/hashtest', array( | |
455 | 'mode' => cache_store::MODE_APPLICATION, | |
456 | 'component' => 'phpunit', | |
457 | 'area' => 'hashtest', | |
458 | 'simplekeys' => true | |
459 | )); | |
460 | $factory = cache_factory::instance(); | |
461 | $definition = $factory->create_definition('phpunit', 'hashtest'); | |
462 | ||
463 | $result = cache_helper::hash_key('test', $definition); | |
464 | $this->assertEquals('test-'.$definition->generate_single_key_prefix(), $result); | |
465 | ||
466 | try { | |
467 | cache_helper::hash_key('test/test', $definition); | |
468 | $this->fail('Invalid key was allowed, you should see this.'); | |
469 | } catch (coding_exception $e) { | |
470 | $this->assertEquals('test/test', $e->debuginfo); | |
471 | } | |
472 | ||
473 | // Second without simple keys | |
474 | $instance->phpunit_add_definition('phpunit/hashtest2', array( | |
475 | 'mode' => cache_store::MODE_APPLICATION, | |
476 | 'component' => 'phpunit', | |
477 | 'area' => 'hashtest2', | |
478 | 'simplekeys' => false | |
479 | )); | |
480 | $definition = $factory->create_definition('phpunit', 'hashtest2'); | |
481 | ||
482 | $result = cache_helper::hash_key('test', $definition); | |
483 | $this->assertEquals(sha1($definition->generate_single_key_prefix().'-test'), $result); | |
484 | ||
485 | $result = cache_helper::hash_key('test/test', $definition); | |
486 | $this->assertEquals(sha1($definition->generate_single_key_prefix().'-test/test'), $result); | |
487 | ||
488 | $CFG->debug = $currentdebugging; | |
489 | } | |
490 | } |