Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 3.9.x will end* 10 May 2021 (12 months).
  • Bug fixes for security issues in 3.9.x will end* 8 May 2023 (36 months).
  • PHP version: minimum PHP 7.2.0 Note: minimum PHP version has increased since Moodle 3.8. PHP 7.3.x and 7.4.x are supported too.

Differences Between: [Versions 39 and 310] [Versions 39 and 311] [Versions 39 and 400] [Versions 39 and 401] [Versions 39 and 402] [Versions 39 and 403]

   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 core_cache_config_writer_testcase 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_testing::create_default_configuration();
  51      }
  52  
  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  
  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          // Remove the definition.
 158          $config->phpunit_remove_definition('core/string');
 159          $definitions = $config->get_definitions();
 160          // Check it is gone.
 161          $this->assertFalse(array_key_exists('core/string', $definitions));
 162          // Update definitions. This should re-add it.
 163          cache_config_writer::update_definitions();
 164          $definitions = $config->get_definitions();
 165          // Check it is back again.
 166          $this->assertTrue(array_key_exists('core/string', $definitions));
 167      }
 168  
 169      /**
 170       * Test adding/editing/deleting store instances.
 171       */
 172      public function test_add_edit_delete_plugin_instance() {
 173          $config = cache_config_writer::instance();
 174          $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores());
 175          $this->assertArrayNotHasKey('addplugintestwlock', $config->get_all_stores());
 176          // Add a default file instance.
 177          $config->add_store_instance('addplugintest', 'file');
 178  
 179          cache_factory::reset();
 180          $config = cache_config_writer::instance();
 181          $this->assertArrayHasKey('addplugintest', $config->get_all_stores());
 182  
 183          // Add a store with a lock described.
 184          $config->add_store_instance('addplugintestwlock', 'file', array('lock' => 'default_file_lock'));
 185          $this->assertArrayHasKey('addplugintestwlock', $config->get_all_stores());
 186  
 187          $config->delete_store_instance('addplugintest');
 188          $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores());
 189          $this->assertArrayHasKey('addplugintestwlock', $config->get_all_stores());
 190  
 191          $config->delete_store_instance('addplugintestwlock');
 192          $this->assertArrayNotHasKey('addplugintest', $config->get_all_stores());
 193          $this->assertArrayNotHasKey('addplugintestwlock', $config->get_all_stores());
 194  
 195          // Add a default file instance.
 196          $config->add_store_instance('storeconfigtest', 'file', array('test' => 'a', 'one' => 'two'));
 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('a', $stores['storeconfigtest']['configuration']['test']);
 203          $this->assertEquals('two', $stores['storeconfigtest']['configuration']['one']);
 204  
 205          $config->edit_store_instance('storeconfigtest', 'file', array('test' => 'b', 'one' => 'three'));
 206          $stores = $config->get_all_stores();
 207          $this->assertArrayHasKey('storeconfigtest', $stores);
 208          $this->assertArrayHasKey('configuration', $stores['storeconfigtest']);
 209          $this->assertArrayHasKey('test', $stores['storeconfigtest']['configuration']);
 210          $this->assertArrayHasKey('one', $stores['storeconfigtest']['configuration']);
 211          $this->assertEquals('b', $stores['storeconfigtest']['configuration']['test']);
 212          $this->assertEquals('three', $stores['storeconfigtest']['configuration']['one']);
 213  
 214          $config->delete_store_instance('storeconfigtest');
 215  
 216          try {
 217              $config->delete_store_instance('default_application');
 218              $this->fail('Default store deleted. This should not be possible!');
 219          } catch (Exception $e) {
 220              $this->assertInstanceOf('cache_exception', $e);
 221          }
 222  
 223          try {
 224              $config->delete_store_instance('some_crazy_store');
 225              $this->fail('You should not be able to delete a store that does not exist.');
 226          } catch (Exception $e) {
 227              $this->assertInstanceOf('cache_exception', $e);
 228          }
 229  
 230          try {
 231              // Try with a plugin that does not exist.
 232              $config->add_store_instance('storeconfigtest', 'shallowfail', array('test' => 'a', 'one' => 'two'));
 233              $this->fail('You should not be able to add an instance of a store that does not exist.');
 234          } catch (Exception $e) {
 235              $this->assertInstanceOf('cache_exception', $e);
 236          }
 237      }
 238  
 239      /**
 240       * Test setting some mode mappings.
 241       */
 242      public function test_set_mode_mappings() {
 243          $config = cache_config_writer::instance();
 244          $this->assertTrue($config->add_store_instance('setmodetest', 'file'));
 245          $this->assertTrue($config->set_mode_mappings(array(
 246              cache_store::MODE_APPLICATION => array('setmodetest', 'default_application'),
 247              cache_store::MODE_SESSION => array('default_session'),
 248              cache_store::MODE_REQUEST => array('default_request'),
 249          )));
 250          $mappings = $config->get_mode_mappings();
 251          $setmodetestfound = false;
 252          foreach ($mappings as $mapping) {
 253              if ($mapping['store'] == 'setmodetest' && $mapping['mode'] == cache_store::MODE_APPLICATION) {
 254                  $setmodetestfound = true;
 255              }
 256          }
 257          $this->assertTrue($setmodetestfound, 'Set mapping did not work as expected.');
 258      }
 259  
 260      /**
 261       * Test setting some definition mappings.
 262       */
 263      public function test_set_definition_mappings() {
 264          $config = cache_config_testing::instance(true);
 265          $config->phpunit_add_definition('phpunit/testdefinition', array(
 266              'mode' => cache_store::MODE_APPLICATION,
 267              'component' => 'phpunit',
 268              'area' => 'testdefinition'
 269          ));
 270  
 271          $config = cache_config_writer::instance();
 272          $this->assertTrue($config->add_store_instance('setdefinitiontest', 'file'));
 273          $this->assertInternalType('array', $config->get_definition_by_id('phpunit/testdefinition'));
 274          $config->set_definition_mappings('phpunit/testdefinition', array('setdefinitiontest', 'default_application'));
 275  
 276          try {
 277              $config->set_definition_mappings('phpunit/testdefinition', array('something that does not exist'));
 278              $this->fail('You should not be able to set a mapping for a store that does not exist.');
 279          } catch (Exception $e) {
 280              $this->assertInstanceOf('coding_exception', $e);
 281          }
 282  
 283          try {
 284              $config->set_definition_mappings('something/crazy', array('setdefinitiontest'));
 285              $this->fail('You should not be able to set a mapping for a definition that does not exist.');
 286          } catch (Exception $e) {
 287              $this->assertInstanceOf('coding_exception', $e);
 288          }
 289      }
 290  }