Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.

Differences Between: [Versions 310 and 401] [Versions 39 and 401]

   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  namespace core_cache;
  18  
  19  use cache_config_testing;
  20  use cache_config_writer;
  21  use cache_factory;
  22  use cache_store;
  23  
  24  defined('MOODLE_INTERNAL') || die();
  25  
  26  // Include the necessary evils.
  27  global $CFG;
  28  require_once($CFG->dirroot.'/cache/locallib.php');
  29  require_once($CFG->dirroot.'/cache/tests/fixtures/lib.php');
  30  
  31  /**
  32   * PHPunit tests for the cache API and in particular the cache config writer.
  33   *
  34   * @package    core_cache
  35   * @category   test
  36   * @copyright  2012 Sam Hemelryk
  37   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  38   */
  39  class config_writer_test extends \advanced_testcase {
  40  
  41      /**
  42       * Set things back to the default before each test.
  43       */
  44      public function setUp(): void {
  45          parent::setUp();
  46          cache_factory::reset();
  47          cache_config_testing::create_default_configuration();
  48      }
  49  
  50      /**
  51       * Final task is to reset the cache system
  52       */
  53      public static function tearDownAfterClass(): void {
  54          parent::tearDownAfterClass();
  55          cache_factory::reset();
  56      }
  57  
  58      /**
  59       * Test getting an instance. Pretty basic.
  60       */
  61      public function test_instance() {
  62          $config = cache_config_writer::instance();
  63          $this->assertInstanceOf('cache_config_writer', $config);
  64      }
  65  
  66      /**
  67       * Test the default configuration.
  68       */
  69      public function test_default_configuration() {
  70          $config = cache_config_writer::instance();
  71  
  72          // First check stores.
  73          $stores = $config->get_all_stores();
  74          $hasapplication = false;
  75          $hassession = false;
  76          $hasrequest = false;
  77          foreach ($stores as $store) {
  78              // Check the required keys.
  79              $this->assertArrayHasKey('name', $store);
  80              $this->assertArrayHasKey('plugin', $store);
  81              $this->assertArrayHasKey('modes', $store);
  82              $this->assertArrayHasKey('default', $store);
  83              // Check the mode, we need at least one default store of each mode.
  84              if (!empty($store['default'])) {
  85                  if ($store['modes'] & cache_store::MODE_APPLICATION) {
  86                      $hasapplication = true;
  87                  }
  88                  if ($store['modes'] & cache_store::MODE_SESSION) {
  89                      $hassession = true;
  90                  }
  91                  if ($store['modes'] & cache_store::MODE_REQUEST) {
  92                      $hasrequest = true;
  93                  }
  94              }
  95          }
  96          $this->assertTrue($hasapplication, 'There is no default application cache store.');
  97          $this->assertTrue($hassession, 'There is no default session cache store.');
  98          $this->assertTrue($hasrequest, 'There is no default request cache store.');
  99  
 100          // Next check the definitions.
 101          $definitions = $config->get_definitions();
 102          $eventinvalidation = false;
 103          foreach ($definitions as $definition) {
 104              // Check the required keys.
 105              $this->assertArrayHasKey('mode', $definition);
 106              $this->assertArrayHasKey('component', $definition);
 107              $this->assertArrayHasKey('area', $definition);
 108              if ($definition['component'] === 'core' && $definition['area'] === 'eventinvalidation') {
 109                  $eventinvalidation = true;
 110              }
 111          }
 112          $this->assertTrue($eventinvalidation, 'Missing the event invalidation definition.');
 113  
 114          // Next mode mappings
 115          $mappings = $config->get_mode_mappings();
 116          $hasapplication = false;
 117          $hassession = false;
 118          $hasrequest = false;
 119          foreach ($mappings as $mode) {
 120              // Check the required keys.
 121              $this->assertArrayHasKey('mode', $mode);
 122              $this->assertArrayHasKey('store', $mode);
 123  
 124              if ($mode['mode'] === cache_store::MODE_APPLICATION) {
 125                  $hasapplication = true;
 126              }
 127              if ($mode['mode'] === cache_store::MODE_SESSION) {
 128                  $hassession = true;
 129              }
 130              if ($mode['mode'] === cache_store::MODE_REQUEST) {
 131                  $hasrequest = true;
 132              }
 133          }
 134          $this->assertTrue($hasapplication, 'There is no mapping for the application mode.');
 135          $this->assertTrue($hassession, 'There is no mapping for the session mode.');
 136          $this->assertTrue($hasrequest, 'There is no mapping for the request mode.');
 137  
 138          // Finally check config locks
 139          $locks = $config->get_locks();
 140          foreach ($locks as $lock) {
 141              $this->assertArrayHasKey('name', $lock);
 142              $this->assertArrayHasKey('type', $lock);
 143              $this->assertArrayHasKey('default', $lock);
 144          }
 145          // There has to be at least the default lock.
 146          $this->assertTrue(count($locks) > 0);
 147      }
 148  
 149      /**
 150       * Test updating the definitions.
 151       */
 152      public function test_update_definitions() {
 153          $config = cache_config_writer::instance();
 154          // Remove the definition.
 155          $config->phpunit_remove_definition('core/string');
 156          $definitions = $config->get_definitions();
 157          // Check it is gone.
 158          $this->assertFalse(array_key_exists('core/string', $definitions));
 159          // Update definitions. This should re-add it.
 160          cache_config_writer::update_definitions();
 161          $definitions = $config->get_definitions();
 162          // Check it is back again.
 163          $this->assertTrue(array_key_exists('core/string', $definitions));
 164      }
 165  
 166      /**
 167       * Test adding/editing/deleting store instances.
 168       */
 169      public function test_add_edit_delete_plugin_instance() {
 170          $config = cache_config_writer::instance();
 171          $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores());
 172          $this->assertArrayNotHasKey('addplugintestwlock', $config->get_all_stores());
 173          // Add a default file instance.
 174          $config->add_store_instance('addplugintest', 'file');
 175  
 176          cache_factory::reset();
 177          $config = cache_config_writer::instance();
 178          $this->assertArrayHasKey('addplugintest', $config->get_all_stores());
 179  
 180          // Add a store with a lock described.
 181          $config->add_store_instance('addplugintestwlock', 'file', array('lock' => 'default_file_lock'));
 182          $this->assertArrayHasKey('addplugintestwlock', $config->get_all_stores());
 183  
 184          $config->delete_store_instance('addplugintest');
 185          $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores());
 186          $this->assertArrayHasKey('addplugintestwlock', $config->get_all_stores());
 187  
 188          $config->delete_store_instance('addplugintestwlock');
 189          $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores());
 190          $this->assertArrayNotHasKey('addplugintestwlock', $config->get_all_stores());
 191  
 192          // Add a default file instance.
 193          $config->add_store_instance('storeconfigtest', 'file', array('test' => 'a', 'one' => 'two'));
 194          $stores = $config->get_all_stores();
 195          $this->assertArrayHasKey('storeconfigtest', $stores);
 196          $this->assertArrayHasKey('configuration', $stores['storeconfigtest']);
 197          $this->assertArrayHasKey('test', $stores['storeconfigtest']['configuration']);
 198          $this->assertArrayHasKey('one', $stores['storeconfigtest']['configuration']);
 199          $this->assertEquals('a', $stores['storeconfigtest']['configuration']['test']);
 200          $this->assertEquals('two', $stores['storeconfigtest']['configuration']['one']);
 201  
 202          $config->edit_store_instance('storeconfigtest', 'file', array('test' => 'b', 'one' => 'three'));
 203          $stores = $config->get_all_stores();
 204          $this->assertArrayHasKey('storeconfigtest', $stores);
 205          $this->assertArrayHasKey('configuration', $stores['storeconfigtest']);
 206          $this->assertArrayHasKey('test', $stores['storeconfigtest']['configuration']);
 207          $this->assertArrayHasKey('one', $stores['storeconfigtest']['configuration']);
 208          $this->assertEquals('b', $stores['storeconfigtest']['configuration']['test']);
 209          $this->assertEquals('three', $stores['storeconfigtest']['configuration']['one']);
 210  
 211          $config->delete_store_instance('storeconfigtest');
 212  
 213          try {
 214              $config->delete_store_instance('default_application');
 215              $this->fail('Default store deleted. This should not be possible!');
 216          } catch (\Exception $e) {
 217              $this->assertInstanceOf('cache_exception', $e);
 218          }
 219  
 220          try {
 221              $config->delete_store_instance('some_crazy_store');
 222              $this->fail('You should not be able to delete a store that does not exist.');
 223          } catch (\Exception $e) {
 224              $this->assertInstanceOf('cache_exception', $e);
 225          }
 226  
 227          try {
 228              // Try with a plugin that does not exist.
 229              $config->add_store_instance('storeconfigtest', 'shallowfail', array('test' => 'a', 'one' => 'two'));
 230              $this->fail('You should not be able to add an instance of a store that does not exist.');
 231          } catch (\Exception $e) {
 232              $this->assertInstanceOf('cache_exception', $e);
 233          }
 234      }
 235  
 236      /**
 237       * Test setting some mode mappings.
 238       */
 239      public function test_set_mode_mappings() {
 240          $config = cache_config_writer::instance();
 241          $this->assertTrue($config->add_store_instance('setmodetest', 'file'));
 242          $this->assertTrue($config->set_mode_mappings(array(
 243              cache_store::MODE_APPLICATION => array('setmodetest', 'default_application'),
 244              cache_store::MODE_SESSION => array('default_session'),
 245              cache_store::MODE_REQUEST => array('default_request'),
 246          )));
 247          $mappings = $config->get_mode_mappings();
 248          $setmodetestfound = false;
 249          foreach ($mappings as $mapping) {
 250              if ($mapping['store'] == 'setmodetest' && $mapping['mode'] == cache_store::MODE_APPLICATION) {
 251                  $setmodetestfound = true;
 252              }
 253          }
 254          $this->assertTrue($setmodetestfound, 'Set mapping did not work as expected.');
 255      }
 256  
 257      /**
 258       * Test setting some definition mappings.
 259       */
 260      public function test_set_definition_mappings() {
 261          $config = cache_config_testing::instance(true);
 262          $config->phpunit_add_definition('phpunit/testdefinition', array(
 263              'mode' => cache_store::MODE_APPLICATION,
 264              'component' => 'phpunit',
 265              'area' => 'testdefinition'
 266          ));
 267  
 268          $config = cache_config_writer::instance();
 269          $this->assertTrue($config->add_store_instance('setdefinitiontest', 'file'));
 270          $this->assertIsArray($config->get_definition_by_id('phpunit/testdefinition'));
 271          $config->set_definition_mappings('phpunit/testdefinition', array('setdefinitiontest', 'default_application'));
 272  
 273          try {
 274              $config->set_definition_mappings('phpunit/testdefinition', array('something that does not exist'));
 275              $this->fail('You should not be able to set a mapping for a store that does not exist.');
 276          } catch (\Exception $e) {
 277              $this->assertInstanceOf('coding_exception', $e);
 278          }
 279  
 280          try {
 281              $config->set_definition_mappings('something/crazy', array('setdefinitiontest'));
 282              $this->fail('You should not be able to set a mapping for a definition that does not exist.');
 283          } catch (\Exception $e) {
 284              $this->assertInstanceOf('coding_exception', $e);
 285          }
 286      }
 287  }