[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
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 * Support library for the cache PHPUnit tests. 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 require_once($CFG->dirroot.'/cache/locallib.php'); 32 33 /** 34 * Override the default cache configuration for our own maniacle purposes. 35 * 36 * @copyright 2012 Sam Hemelryk 37 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 38 */ 39 class cache_config_phpunittest extends cache_config_writer { 40 41 /** 42 * Creates the default configuration and saves it. 43 * 44 * This function calls config_save, however it is safe to continue using it afterwards as this function should only ever 45 * be called when there is no configuration file already. 46 * 47 * @param bool $forcesave If set to true then we will forcefully save the default configuration file. 48 * @return true|array Returns true if the default configuration was successfully created. 49 * Returns a configuration array if it could not be saved. This is a bad situation. Check your error logs. 50 */ 51 public static function create_default_configuration($forcesave = false) { 52 global $CFG; 53 // HACK ALERT. 54 // We probably need to come up with a better way to create the default stores, or at least ensure 100% that the 55 // default store plugins are protected from deletion. 56 $writer = new self; 57 $writer->configstores = self::get_default_stores(); 58 $writer->configdefinitions = self::locate_definitions(); 59 $defaultapplication = 'default_application'; 60 61 $appdefine = defined('TEST_CACHE_USING_APPLICATION_STORE') ? TEST_CACHE_USING_APPLICATION_STORE : false; 62 if ($appdefine !== false && preg_match('/^[a-zA-Z][a-zA-Z0-9_]+$/', $appdefine)) { 63 $expectedstore = $appdefine; 64 $expecteddefine = 'TEST_CACHESTORE_'.strtoupper($expectedstore).'_TESTSERVERS'; 65 $file = $CFG->dirroot.'/cache/stores/'.$appdefine.'/lib.php'; 66 $class = 'cachestore_'.$appdefine; 67 if (file_exists($file)) { 68 require_once($file); 69 } 70 if (defined($expecteddefine) && class_exists($class)) { 71 /** @var cache_store $class */ 72 $writer->configstores['test_application'] = array( 73 'use_test_store' => true, 74 'name' => 'test_application', 75 'plugin' => $expectedstore, 76 'alt' => $writer->configstores[$defaultapplication], 77 'modes' => $class::get_supported_modes(), 78 'features' => $class::get_supported_features() 79 ); 80 $defaultapplication = 'test_application'; 81 } 82 } 83 84 $writer->configmodemappings = array( 85 array( 86 'mode' => cache_store::MODE_APPLICATION, 87 'store' => $defaultapplication, 88 'sort' => -1 89 ), 90 array( 91 'mode' => cache_store::MODE_SESSION, 92 'store' => 'default_session', 93 'sort' => -1 94 ), 95 array( 96 'mode' => cache_store::MODE_REQUEST, 97 'store' => 'default_request', 98 'sort' => -1 99 ) 100 ); 101 $writer->configlocks = array( 102 'default_file_lock' => array( 103 'name' => 'cachelock_file_default', 104 'type' => 'cachelock_file', 105 'dir' => 'filelocks', 106 'default' => true 107 ) 108 ); 109 110 $factory = cache_factory::instance(); 111 // We expect the cache to be initialising presently. If its not then something has gone wrong and likely 112 // we are now in a loop. 113 if (!$forcesave && $factory->get_state() !== cache_factory::STATE_INITIALISING) { 114 return $writer->generate_configuration_array(); 115 } 116 $factory->set_state(cache_factory::STATE_SAVING); 117 $writer->config_save(); 118 return true; 119 } 120 121 /** 122 * Returns the expected path to the configuration file. 123 * 124 * We override this function to add handling for $CFG->altcacheconfigpath. 125 * We want to support it so that people can run unit tests against alternative cache setups. 126 * However we don't want to ever make changes to the file at $CFG->altcacheconfigpath so we 127 * always use dataroot and copy the alt file there as required. 128 * 129 * @throws cache_exception 130 * @return string The absolute path 131 */ 132 protected static function get_config_file_path() { 133 global $CFG; 134 // We always use this path. 135 $configpath = $CFG->dataroot.'/muc/config.php'; 136 137 if (!empty($CFG->altcacheconfigpath)) { 138 139 if (defined('PHPUNIT_TEST') && PHPUNIT_TEST && 140 (!defined('TEST_CACHE_USING_ALT_CACHE_CONFIG_PATH') || !TEST_CACHE_USING_ALT_CACHE_CONFIG_PATH)) { 141 // We're within a unit test, but TEST_CACHE_USING_ALT_CACHE_CONFIG_PATH has not being defined or is 142 // false, we want to use the default. 143 return $configpath; 144 } 145 146 $path = $CFG->altcacheconfigpath; 147 if (is_dir($path) && is_writable($path)) { 148 // Its a writable directory, thats fine. Convert it to a file. 149 $path = $CFG->altcacheconfigpath.'/cacheconfig.php'; 150 } 151 if (is_readable($path)) { 152 $directory = dirname($configpath); 153 if ($directory !== $CFG->dataroot && !file_exists($directory)) { 154 $result = make_writable_directory($directory, false); 155 if (!$result) { 156 throw new cache_exception('ex_configcannotsave', 'cache', '', null, 'Cannot create config directory. Check the permissions on your moodledata directory.'); 157 } 158 } 159 // We don't care that this fails but we should let the developer know. 160 if (!is_readable($configpath) && !@copy($path, $configpath)) { 161 debugging('Failed to copy alt cache config file to required location'); 162 } 163 } 164 } 165 166 // We always use the dataroot location. 167 return $configpath; 168 } 169 170 /** 171 * Adds a definition to the stack 172 * @param string $area 173 * @param array $properties 174 * @param bool $addmapping By default this method adds a definition and a mapping for that definition. You can 175 * however set this to false if you only want it to add the definition and not the mapping. 176 */ 177 public function phpunit_add_definition($area, array $properties, $addmapping = true) { 178 if (!array_key_exists('overrideclass', $properties)) { 179 switch ($properties['mode']) { 180 case cache_store::MODE_APPLICATION: 181 $properties['overrideclass'] = 'cache_phpunit_application'; 182 break; 183 case cache_store::MODE_SESSION: 184 $properties['overrideclass'] = 'cache_phpunit_session'; 185 break; 186 case cache_store::MODE_REQUEST: 187 $properties['overrideclass'] = 'cache_phpunit_request'; 188 break; 189 } 190 } 191 $this->configdefinitions[$area] = $properties; 192 if ($addmapping) { 193 switch ($properties['mode']) { 194 case cache_store::MODE_APPLICATION: 195 $this->phpunit_add_definition_mapping($area, 'default_application', 0); 196 break; 197 case cache_store::MODE_SESSION: 198 $this->phpunit_add_definition_mapping($area, 'default_session', 0); 199 break; 200 case cache_store::MODE_REQUEST: 201 $this->phpunit_add_definition_mapping($area, 'default_request', 0); 202 break; 203 } 204 } 205 } 206 207 /** 208 * Removes a definition. 209 * @param string $name 210 */ 211 public function phpunit_remove_definition($name) { 212 unset($this->configdefinitions[$name]); 213 } 214 215 /** 216 * Removes the configured stores so that there are none available. 217 */ 218 public function phpunit_remove_stores() { 219 $this->configstores = array(); 220 } 221 222 /** 223 * Forcefully adds a file store. 224 * 225 * @param string $name 226 */ 227 public function phpunit_add_file_store($name) { 228 $this->configstores[$name] = array( 229 'name' => $name, 230 'plugin' => 'file', 231 'configuration' => array( 232 'path' => '' 233 ), 234 'features' => 6, 235 'modes' => 3, 236 'mappingsonly' => false, 237 'class' => 'cachestore_file', 238 'default' => false, 239 'lock' => 'cachelock_file_default' 240 ); 241 } 242 243 /** 244 * Forcefully adds a session store. 245 * 246 * @param string $name 247 */ 248 public function phpunit_add_session_store($name) { 249 $this->configstores[$name] = array( 250 'name' => $name, 251 'plugin' => 'session', 252 'configuration' => array(), 253 'features' => 14, 254 'modes' => 2, 255 'default' => true, 256 'class' => 'cachestore_session', 257 'lock' => 'cachelock_file_default', 258 ); 259 } 260 261 /** 262 * Forcefully injects a definition => store mapping. 263 * 264 * This function does no validation, you should only be calling if it you know 265 * exactly what to expect. 266 * 267 * @param string $definition 268 * @param string $store 269 * @param int $sort 270 */ 271 public function phpunit_add_definition_mapping($definition, $store, $sort) { 272 $this->configdefinitionmappings[] = array( 273 'store' => $store, 274 'definition' => $definition, 275 'sort' => (int)$sort 276 ); 277 } 278 279 /** 280 * Overrides the default site identifier used by the Cache API so that we can be sure of what it is. 281 * 282 * @return string 283 */ 284 public function get_site_identifier() { 285 global $CFG; 286 return $CFG->wwwroot.'phpunit'; 287 } 288 } 289 290 /** 291 * Dummy object for testing cacheable object interface and interaction 292 * 293 * @copyright 2012 Sam Hemelryk 294 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 295 */ 296 class cache_phpunit_dummy_object extends stdClass implements cacheable_object { 297 /** 298 * Test property 1 299 * @var string 300 */ 301 public $property1; 302 /** 303 * Test property 1 304 * @var string 305 */ 306 public $property2; 307 /** 308 * Constructor 309 * @param string $property1 310 * @param string $property2 311 */ 312 public function __construct($property1, $property2) { 313 $this->property1 = $property1; 314 $this->property2 = $property2; 315 } 316 /** 317 * Prepares this object for caching 318 * @return array 319 */ 320 public function prepare_to_cache() { 321 return array($this->property1.'_ptc', $this->property2.'_ptc'); 322 } 323 /** 324 * Returns this object from the cache 325 * @param array $data 326 * @return cache_phpunit_dummy_object 327 */ 328 public static function wake_from_cache($data) { 329 return new cache_phpunit_dummy_object(array_shift($data).'_wfc', array_shift($data).'_wfc'); 330 } 331 } 332 333 /** 334 * Dummy data source object for testing data source interface and implementation 335 * 336 * @copyright 2012 Sam Hemelryk 337 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 338 */ 339 class cache_phpunit_dummy_datasource implements cache_data_source { 340 /** 341 * Returns an instance of this object for use with the cache. 342 * 343 * @param cache_definition $definition 344 * @return cache_phpunit_dummy_datasource 345 */ 346 public static function get_instance_for_cache(cache_definition $definition) { 347 return new cache_phpunit_dummy_datasource(); 348 } 349 350 /** 351 * Loads a key for the cache. 352 * 353 * @param string $key 354 * @return string 355 */ 356 public function load_for_cache($key) { 357 return $key.' has no value really.'; 358 } 359 360 /** 361 * Loads many keys for the cache 362 * 363 * @param array $keys 364 * @return array 365 */ 366 public function load_many_for_cache(array $keys) { 367 $return = array(); 368 foreach ($keys as $key) { 369 $return[$key] = $key.' has no value really.'; 370 } 371 return $return; 372 } 373 } 374 375 /** 376 * PHPUnit application cache loader. 377 * 378 * Used to expose things we could not otherwise see within an application cache. 379 * 380 * @copyright 2012 Sam Hemelryk 381 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 382 */ 383 class cache_phpunit_application extends cache_application { 384 385 /** 386 * Returns the class of the store immediately associated with this cache. 387 * @return string 388 */ 389 public function phpunit_get_store_class() { 390 return get_class($this->get_store()); 391 } 392 393 /** 394 * Returns all the interfaces the cache store implements. 395 * @return array 396 */ 397 public function phpunit_get_store_implements() { 398 return class_implements($this->get_store()); 399 } 400 401 /** 402 * Returns the given key directly from the static acceleration array. 403 * 404 * @param string $key 405 * @return false|mixed 406 */ 407 public function phpunit_static_acceleration_get($key) { 408 $key = $this->parse_key($key); 409 return $this->static_acceleration_get($key); 410 } 411 } 412 413 /** 414 * PHPUnit session cache loader. 415 * 416 * Used to expose things we could not otherwise see within an session cache. 417 * 418 * @copyright 2012 Sam Hemelryk 419 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 420 */ 421 class cache_phpunit_session extends cache_session { 422 423 /** 424 * Returns the class of the store immediately associated with this cache. 425 * @return string 426 */ 427 public function phpunit_get_store_class() { 428 return get_class($this->get_store()); 429 } 430 431 /** 432 * Returns all the interfaces the cache store implements. 433 * @return array 434 */ 435 public function phpunit_get_store_implements() { 436 return class_implements($this->get_store()); 437 } 438 } 439 440 /** 441 * PHPUnit request cache loader. 442 * 443 * Used to expose things we could not otherwise see within an request cache. 444 * 445 * @copyright 2012 Sam Hemelryk 446 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 447 */ 448 class cache_phpunit_request extends cache_request { 449 450 /** 451 * Returns the class of the store immediately associated with this cache. 452 * @return string 453 */ 454 public function phpunit_get_store_class() { 455 return get_class($this->get_store()); 456 } 457 458 /** 459 * Returns all the interfaces the cache store implements. 460 * @return array 461 */ 462 public function phpunit_get_store_implements() { 463 return class_implements($this->get_store()); 464 } 465 } 466 467 /** 468 * Dummy overridden cache loader class that we can use to test overriding loader functionality. 469 * 470 * @copyright 2012 Sam Hemelryk 471 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 472 */ 473 class cache_phpunit_dummy_overrideclass extends cache_application { 474 // Satisfying the code pre-checker is just part of my day job. 475 } 476 477 /** 478 * Cache PHPUnit specific factory. 479 * 480 * @copyright 2012 Sam Hemelryk 481 * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later 482 */ 483 class cache_phpunit_factory extends cache_factory { 484 /** 485 * Exposes the cache_factory's disable method. 486 * 487 * Perhaps one day that method will be made public, for the time being it is protected. 488 */ 489 public static function phpunit_disable() { 490 parent::disable(); 491 } 492 493 /** 494 * Creates a store instance given its name and configuration. 495 * 496 * If the store has already been instantiated then the original object will be returned. (reused) 497 * 498 * @param string $name The name of the store (must be unique remember) 499 * @param array $details 500 * @param cache_definition $definition The definition to instantiate it for. 501 * @return boolean|cache_store 502 */ 503 public function create_store_from_config($name, array $details, cache_definition $definition) { 504 505 if (isset($details['use_test_store'])) { 506 // name, plugin, alt 507 $class = 'cachestore_'.$details['plugin']; 508 $method = 'initialise_unit_test_instance'; 509 if (class_exists($class) && method_exists($class, $method)) { 510 $instance = $class::$method($definition); 511 512 if ($instance) { 513 return $instance; 514 } 515 } 516 $details = $details['alt']; 517 $name = $details['name']; 518 } 519 520 return parent::create_store_from_config($name, $details, $definition); 521 } 522 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |