2 // This file is part of Moodle - http://moodle.org/
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.
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.
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/>.
18 * PHPunit tests for the cache API and in particular things in locallib.php
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.
25 * @copyright 2012 Sam Hemelryk
26 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
29 defined('MOODLE_INTERNAL') || die();
31 // Include the necessary evils.
33 require_once($CFG->dirroot.'/cache/locallib.php');
34 require_once($CFG->dirroot.'/cache/tests/fixtures/lib.php');
37 * PHPunit tests for the cache API and in particular the cache config writer.
39 * @copyright 2012 Sam Hemelryk
40 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
42 class cache_config_writer_phpunit_tests extends advanced_testcase {
45 * Set things back to the default before each test.
47 public function setUp() {
49 cache_factory::reset();
50 cache_config_phpunittest::create_default_configuration();
54 * Test getting an instance. Pretty basic.
56 public function test_instance() {
57 $config = cache_config_writer::instance();
58 $this->assertInstanceOf('cache_config_writer', $config);
62 * Test the default configuration.
64 public function test_default_configuration() {
65 $config = cache_config_writer::instance();
67 // First check stores.
68 $stores = $config->get_all_stores();
69 $hasapplication = false;
72 foreach ($stores as $store) {
73 // Check the required keys.
74 $this->assertArrayHasKey('name', $store);
75 $this->assertArrayHasKey('plugin', $store);
76 $this->assertArrayHasKey('modes', $store);
77 $this->assertArrayHasKey('default', $store);
78 // Check the mode, we need at least one default store of each mode.
79 if (!empty($store['default'])) {
80 if ($store['modes'] & cache_store::MODE_APPLICATION) {
81 $hasapplication = true;
83 if ($store['modes'] & cache_store::MODE_SESSION) {
86 if ($store['modes'] & cache_store::MODE_REQUEST) {
91 $this->assertTrue($hasapplication, 'There is no default application cache store.');
92 $this->assertTrue($hassession, 'There is no default session cache store.');
93 $this->assertTrue($hasrequest, 'There is no default request cache store.');
95 // Next check the definitions.
96 $definitions = $config->get_definitions();
97 $eventinvalidation = false;
98 foreach ($definitions as $definition) {
99 // Check the required keys.
100 $this->assertArrayHasKey('mode', $definition);
101 $this->assertArrayHasKey('component', $definition);
102 $this->assertArrayHasKey('area', $definition);
103 if ($definition['component'] === 'core' && $definition['area'] === 'eventinvalidation') {
104 $eventinvalidation = true;
107 $this->assertTrue($eventinvalidation, 'Missing the event invalidation definition.');
109 // Next mode mappings
110 $mappings = $config->get_mode_mappings();
111 $hasapplication = false;
114 foreach ($mappings as $mode) {
115 // Check the required keys.
116 $this->assertArrayHasKey('mode', $mode);
117 $this->assertArrayHasKey('store', $mode);
119 if ($mode['mode'] === cache_store::MODE_APPLICATION) {
120 $hasapplication = true;
122 if ($mode['mode'] === cache_store::MODE_SESSION) {
125 if ($mode['mode'] === cache_store::MODE_REQUEST) {
129 $this->assertTrue($hasapplication, 'There is no mapping for the application mode.');
130 $this->assertTrue($hassession, 'There is no mapping for the session mode.');
131 $this->assertTrue($hasrequest, 'There is no mapping for the request mode.');
133 // Finally check config locks
134 $locks = $config->get_locks();
135 foreach ($locks as $lock) {
136 $this->assertArrayHasKey('name', $lock);
137 $this->assertArrayHasKey('type', $lock);
138 $this->assertArrayHasKey('default', $lock);
140 // There has to be at least the default lock.
141 $this->assertTrue(count($locks) > 0);
145 * Test updating the definitions.
147 public function test_update_definitions() {
148 $config = cache_config_writer::instance();
149 $earlydefinitions = $config->get_definitions();
151 cache_factory::reset();
152 cache_config_writer::update_definitions();
154 $config = cache_config_writer::instance();
155 $latedefinitions = $config->get_definitions();
157 $this->assertSame($latedefinitions, $earlydefinitions);
161 * Test adding/editing/deleting store instances.
163 public function test_add_edit_delete_plugin_instance() {
164 $config = cache_config_writer::instance();
165 $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores());
166 $this->assertArrayNotHasKey('addplugintestwlock', $config->get_all_stores());
167 // Add a default file instance.
168 $config->add_plugin_instance('addplugintest', 'file');
170 cache_factory::reset();
171 $config = cache_config_writer::instance();
172 $this->assertArrayHasKey('addplugintest', $config->get_all_stores());
174 // Add a store with a lock described.
175 $config->add_plugin_instance('addplugintestwlock', 'file', array('lock' => 'default_file_lock'));
176 $this->assertArrayHasKey('addplugintestwlock', $config->get_all_stores());
178 $config->delete_store('addplugintest');
179 $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores());
180 $this->assertArrayHasKey('addplugintestwlock', $config->get_all_stores());
182 $config->delete_store('addplugintestwlock');
183 $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores());
184 $this->assertArrayNotHasKey('addplugintestwlock', $config->get_all_stores());
186 // Add a default file instance.
187 $config->add_plugin_instance('storeconfigtest', 'file', array('test' => 'a', 'one' => 'two'));
188 $stores = $config->get_all_stores();
189 $this->assertArrayHasKey('storeconfigtest', $stores);
190 $this->assertArrayHasKey('configuration', $stores['storeconfigtest']);
191 $this->assertArrayHasKey('test', $stores['storeconfigtest']['configuration']);
192 $this->assertArrayHasKey('one', $stores['storeconfigtest']['configuration']);
193 $this->assertEquals('a', $stores['storeconfigtest']['configuration']['test']);
194 $this->assertEquals('two', $stores['storeconfigtest']['configuration']['one']);
196 $config->edit_plugin_instance('storeconfigtest', 'file', array('test' => 'b', 'one' => 'three'));
197 $stores = $config->get_all_stores();
198 $this->assertArrayHasKey('storeconfigtest', $stores);
199 $this->assertArrayHasKey('configuration', $stores['storeconfigtest']);
200 $this->assertArrayHasKey('test', $stores['storeconfigtest']['configuration']);
201 $this->assertArrayHasKey('one', $stores['storeconfigtest']['configuration']);
202 $this->assertEquals('b', $stores['storeconfigtest']['configuration']['test']);
203 $this->assertEquals('three', $stores['storeconfigtest']['configuration']['one']);
205 $config->delete_store('storeconfigtest');
208 $config->delete_store('default_application');
209 $this->fail('Default store deleted. This should not be possible!');
210 } catch (Exception $e) {
211 $this->assertInstanceOf('cache_exception', $e);
215 $config->delete_store('some_crazy_store');
216 $this->fail('You should not be able to delete a store that does not exist.');
217 } catch (Exception $e) {
218 $this->assertInstanceOf('cache_exception', $e);
222 // Try with a plugin that does not exist.
223 $config->add_plugin_instance('storeconfigtest', 'shallowfail', array('test' => 'a', 'one' => 'two'));
224 $this->fail('You should not be able to add an instance of a store that does not exist.');
225 } catch (Exception $e) {
226 $this->assertInstanceOf('cache_exception', $e);
231 * Test setting some mode mappings.
233 public function test_set_mode_mappings() {
234 $config = cache_config_writer::instance();
235 $this->assertTrue($config->add_plugin_instance('setmodetest', 'file'));
236 $this->assertTrue($config->set_mode_mappings(array(
237 cache_store::MODE_APPLICATION => array('setmodetest', 'default_application'),
238 cache_store::MODE_SESSION => array('default_session'),
239 cache_store::MODE_REQUEST => array('default_request'),
241 $mappings = $config->get_mode_mappings();
242 $setmodetestfound = false;
243 foreach ($mappings as $mapping) {
244 if ($mapping['store'] == 'setmodetest' && $mapping['mode'] == cache_store::MODE_APPLICATION) {
245 $setmodetestfound = true;
248 $this->assertTrue($setmodetestfound, 'Set mapping did not work as expected.');
252 * Test setting some definition mappings.
254 public function test_set_definition_mappings() {
255 $config = cache_config_phpunittest::instance(true);
256 $config->phpunit_add_definition('phpunit/testdefinition', array(
257 'mode' => cache_store::MODE_APPLICATION,
258 'component' => 'phpunit',
259 'area' => 'testdefinition'
262 $config = cache_config_writer::instance();
263 $this->assertTrue($config->add_plugin_instance('setdefinitiontest', 'file'));
264 $this->assertInternalType('array', $config->get_definition_by_id('phpunit/testdefinition'));
265 $config->set_definition_mappings('phpunit/testdefinition', array('setdefinitiontest', 'default_application'));
268 $config->set_definition_mappings('phpunit/testdefinition', array('something that does not exist'));
269 $this->fail('You should not be able to set a mapping for a store that does not exist.');
270 } catch (Exception $e) {
271 $this->assertInstanceOf('coding_exception', $e);
275 $config->set_definition_mappings('something/crazy', array('setdefinitiontest'));
276 $this->fail('You should not be able to set a mapping for a definition that does not exist.');
277 } catch (Exception $e) {
278 $this->assertInstanceOf('coding_exception', $e);
284 * PHPunit tests for the cache API and in particular the cache_administration_helper
286 * @copyright 2012 Sam Hemelryk
287 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
289 class cache_administration_helper_phpunit_tests extends advanced_testcase {
292 * Set things back to the default before each test.
294 public function setUp() {
296 cache_factory::reset();
297 cache_config_phpunittest::create_default_configuration();
301 * Test the numerous summaries the helper can produce.
303 public function test_get_summaries() {
304 // First the preparation.
305 $config = cache_config_writer::instance();
306 $this->assertTrue($config->add_plugin_instance('summariesstore', 'file'));
307 $config->set_definition_mappings('core/eventinvalidation', array('summariesstore'));
308 $this->assertTrue($config->set_mode_mappings(array(
309 cache_store::MODE_APPLICATION => array('summariesstore'),
310 cache_store::MODE_SESSION => array('default_session'),
311 cache_store::MODE_REQUEST => array('default_request'),
314 $storesummaries = cache_administration_helper::get_store_summaries();
315 $this->assertInternalType('array', $storesummaries);
316 $this->assertArrayHasKey('summariesstore', $storesummaries);
317 $summary = $storesummaries['summariesstore'];
319 $this->assertArrayHasKey('name', $summary);
320 $this->assertArrayHasKey('plugin', $summary);
321 $this->assertArrayHasKey('default', $summary);
322 $this->assertArrayHasKey('isready', $summary);
323 $this->assertArrayHasKey('requirementsmet', $summary);
324 $this->assertArrayHasKey('mappings', $summary);
325 $this->assertArrayHasKey('modes', $summary);
326 $this->assertArrayHasKey('supports', $summary);
327 // Check the important/known values
328 $this->assertEquals('summariesstore', $summary['name']);
329 $this->assertEquals('file', $summary['plugin']);
330 $this->assertEquals(0, $summary['default']);
331 $this->assertEquals(1, $summary['isready']);
332 $this->assertEquals(1, $summary['requirementsmet']);
333 $this->assertEquals(1, $summary['mappings']);
335 $definitionsummaries = cache_administration_helper::get_definition_summaries();
336 $this->assertInternalType('array', $definitionsummaries);
337 $this->assertArrayHasKey('core/eventinvalidation', $definitionsummaries);
338 $summary = $definitionsummaries['core/eventinvalidation'];
340 $this->assertArrayHasKey('id', $summary);
341 $this->assertArrayHasKey('name', $summary);
342 $this->assertArrayHasKey('mode', $summary);
343 $this->assertArrayHasKey('component', $summary);
344 $this->assertArrayHasKey('area', $summary);
345 $this->assertArrayHasKey('mappings', $summary);
346 // Check the important/known values
347 $this->assertEquals('core/eventinvalidation', $summary['id']);
348 $this->assertInstanceOf('lang_string', $summary['name']);
349 $this->assertEquals(cache_store::MODE_APPLICATION, $summary['mode']);
350 $this->assertEquals('core', $summary['component']);
351 $this->assertEquals('eventinvalidation', $summary['area']);
352 $this->assertInternalType('array', $summary['mappings']);
353 $this->assertContains('summariesstore', $summary['mappings']);
355 $pluginsummaries = cache_administration_helper::get_plugin_summaries();
356 $this->assertInternalType('array', $pluginsummaries);
357 $this->assertArrayHasKey('file', $pluginsummaries);
358 $summary = $pluginsummaries['file'];
360 $this->assertArrayHasKey('name', $summary);
361 $this->assertArrayHasKey('requirementsmet', $summary);
362 $this->assertArrayHasKey('instances', $summary);
363 $this->assertArrayHasKey('modes', $summary);
364 $this->assertArrayHasKey('supports', $summary);
365 $this->assertArrayHasKey('canaddinstance', $summary);
367 $locksummaries = cache_administration_helper::get_lock_summaries();
368 $this->assertInternalType('array', $locksummaries);
369 $this->assertTrue(count($locksummaries) > 0);
371 $mappings = cache_administration_helper::get_default_mode_stores();
372 $this->assertInternalType('array', $mappings);
373 $this->assertCount(3, $mappings);
374 $this->assertArrayHasKey(cache_store::MODE_APPLICATION, $mappings);
375 $this->assertInternalType('array', $mappings[cache_store::MODE_APPLICATION]);
376 $this->assertContains('summariesstore', $mappings[cache_store::MODE_APPLICATION]);
378 $potentials = cache_administration_helper::get_definition_store_options('core', 'eventinvalidation');
379 $this->assertInternalType('array', $potentials); // Currently used, suitable, default
380 $this->assertCount(3, $potentials);
381 $this->assertArrayHasKey('summariesstore', $potentials[0]);
382 $this->assertArrayHasKey('summariesstore', $potentials[1]);
383 $this->assertArrayHasKey('default_application', $potentials[1]);
387 * Test instantiating an add store form.
389 public function test_get_add_store_form() {
390 $form = cache_administration_helper::get_add_store_form('file');
391 $this->assertInstanceOf('moodleform', $form);
394 $form = cache_administration_helper::get_add_store_form('somethingstupid');
395 $this->fail('You should not be able to create an add form for a store plugin that does not exist.');
396 } catch (moodle_exception $e) {
397 $this->assertInstanceOf('coding_exception', $e, 'Needs to be: ' .get_class($e)." ::: ".$e->getMessage());
402 * Test instantiating a form to edit a store instance.
404 public function test_get_edit_store_form() {
405 $config = cache_config_writer::instance();
406 $this->assertTrue($config->add_plugin_instance('summariesstore', 'file'));
408 $form = cache_administration_helper::get_edit_store_form('file', 'summariesstore');
409 $this->assertInstanceOf('moodleform', $form);
412 $form = cache_administration_helper::get_edit_store_form('somethingstupid', 'moron');
413 $this->fail('You should not be able to create an edit form for a store plugin that does not exist.');
414 } catch (moodle_exception $e) {
415 $this->assertInstanceOf('coding_exception', $e);
419 $form = cache_administration_helper::get_edit_store_form('file', 'blisters');
420 $this->fail('You should not be able to create an edit form for a store plugin that does not exist.');
421 } catch (moodle_exception $e) {
422 $this->assertInstanceOf('coding_exception', $e);