MDL-45513 cache: added support to unit tests for alt cache stores

This commit is contained in:
Sam Hemelryk 2014-05-12 08:38:43 +12:00
parent 8e478c99d3
commit 79a8ea653c
7 changed files with 91 additions and 9 deletions

View File

@ -100,8 +100,8 @@ class cache_config {
* @return bool True if it exists
*/
public static function config_file_exists() {
// Allow for late static binding.
return file_exists(self::get_config_file_path());
// Allow for late static binding by using static.
return file_exists(static::get_config_file_path());
}
/**
@ -324,7 +324,8 @@ class cache_config {
*/
protected function include_configuration() {
$configuration = array();
$cachefile = self::get_config_file_path();
// We need to allow for late static bindings to allow for class path mudling happending for unit tests.
$cachefile = static::get_config_file_path();
if (!file_exists($cachefile)) {
throw new cache_exception('Default cache config could not be found. It should have already been created by now.');

View File

@ -325,11 +325,21 @@ class cache_factory {
public function create_config_instance($writer = false) {
global $CFG;
// Check if we need to create a config file with defaults.
$needtocreate = !cache_config::config_file_exists();
// The class to use.
$class = 'cache_config';
// Check if this is a PHPUnit test and redirect to the phpunit config classes if it is.
if (defined('PHPUNIT_TEST') && PHPUNIT_TEST) {
require_once($CFG->dirroot.'/cache/locallib.php');
require_once($CFG->dirroot.'/cache/tests/fixtures/lib.php');
// We have just a single class for PHP unit tests. We don't care enough about its
// performance to do otherwise and having a single method allows us to inject things into it
// while testing.
$class = 'cache_config_phpunittest';
}
// Check if we need to create a config file with defaults.
$needtocreate = !$class::config_file_exists();
if ($writer || $needtocreate) {
require_once($CFG->dirroot.'/cache/locallib.php');
$class .= '_writer';
@ -350,6 +360,7 @@ class cache_factory {
// Create the default configuration.
// Update the state, we are now initialising the cache.
self::set_state(self::STATE_INITIALISING);
/** @var cache_config_writer $class */
$configuration = $class::create_default_configuration();
if ($configuration !== true) {
// Failed to create the default configuration. Disable the cache stores and update the state.

2
cache/locallib.php vendored
View File

@ -68,7 +68,7 @@ class cache_config_writer extends cache_config {
*/
protected function config_save() {
global $CFG;
$cachefile = self::get_config_file_path();
$cachefile = static::get_config_file_path();
$directory = dirname($cachefile);
if ($directory !== $CFG->dataroot && !file_exists($directory)) {
$result = make_writable_directory($directory, false);

View File

@ -165,9 +165,9 @@ class core_cache_administration_helper_testcase extends advanced_testcase {
*/
public function test_get_edit_store_form() {
$config = cache_config_writer::instance();
$this->assertTrue($config->add_store_instance('summariesstore', 'file'));
$this->assertTrue($config->add_store_instance('test_get_edit_store_form', 'file'));
$form = cache_administration_helper::get_edit_store_form('file', 'summariesstore');
$form = cache_administration_helper::get_edit_store_form('file', 'test_get_edit_store_form');
$this->assertInstanceOf('moodleform', $form);
try {

View File

@ -62,6 +62,14 @@ class core_cache_testcase extends advanced_testcase {
* Tests cache configuration
*/
public function test_cache_config() {
global $CFG;
if (!empty($CFG->altcacheconfigpath)) {
// We need to skip this test - it checks the default config structure, but very likely we arn't using the
// default config structure here so theres no point in running the test.
$this->markTestSkipped('Skipped testing default cache config structure as alt cache path is being used.');
}
$instance = cache_config::instance();
$this->assertInstanceOf('cache_config_phpunittest', $instance);
@ -1074,6 +1082,9 @@ class core_cache_testcase extends advanced_testcase {
*/
public function test_alt_cache_path() {
global $CFG;
if ($CFG->altcacheconfigpath) {
$this->markTestSkipped('Skipped testing alt cache path as it is already being used.');
}
$this->resetAfterTest();
$CFG->altcacheconfigpath = $CFG->dataroot.'/cache/altcacheconfigpath';
$instance = cache_config_phpunittest::instance();
@ -1150,6 +1161,12 @@ class core_cache_testcase extends advanced_testcase {
public function test_disable() {
global $CFG;
if (!empty($CFG->altcacheconfigpath)) {
// We can't run this test as it requires us to delete the cache configuration script which we just
// cant do with a custom path in play.
$this->markTestSkipped('Skipped testing cache disable functionality as alt cache path is being used.');
}
$configfile = $CFG->dataroot.'/muc/config.php';
// That's right, we're deleting the config file.

View File

@ -36,6 +36,47 @@ defined('MOODLE_INTERNAL') || die();
*/
class cache_config_phpunittest extends cache_config_writer {
/**
* Returns the expected path to the configuration file.
*
* We override this function to add handling for $CFG->altcacheconfigpath.
* We want to support it so that people can run unit tests against alternative cache setups.
* However we don't want to ever make changes to the file at $CFG->altcacheconfigpath so we
* always use dataroot and copy the alt file there as required.
*
* @throws cache_exception
* @return string The absolute path
*/
protected static function get_config_file_path() {
global $CFG;
// We always use this path.
$configpath = $CFG->dataroot.'/muc/config.php';
if (!empty($CFG->altcacheconfigpath)) {
$path = $CFG->altcacheconfigpath;
if (is_dir($path) && is_writable($path)) {
// Its a writable directory, thats fine. Convert it to a file.
$path = $CFG->altcacheconfigpath.'/cacheconfig.php';
}
if (is_readable($path)) {
$directory = dirname($configpath);
if ($directory !== $CFG->dataroot && !file_exists($directory)) {
$result = make_writable_directory($directory, false);
if (!$result) {
throw new cache_exception('ex_configcannotsave', 'cache', '', null, 'Cannot create config directory. Check the permissions on your moodledata directory.');
}
}
// We don't care that this fails but we should let the developer know.
if (!is_readable($configpath) && !@copy($path, $configpath)) {
debugging('Failed to copy alt cache config file to required location');
}
}
}
// We always use the dataroot location.
return $configpath;
}
/**
* Adds a definition to the stack
* @param string $area
@ -56,6 +97,17 @@ class cache_config_phpunittest extends cache_config_writer {
}
}
$this->configdefinitions[$area] = $properties;
switch ($properties['mode']) {
case cache_store::MODE_APPLICATION:
$this->phpunit_add_definition_mapping($area, 'default_application', 0);
break;
case cache_store::MODE_SESSION:
$this->phpunit_add_definition_mapping($area, 'default_session', 0);
break;
case cache_store::MODE_REQUEST:
$this->phpunit_add_definition_mapping($area, 'default_request', 0);
break;
}
}
/**

View File

@ -181,6 +181,7 @@ $CFG->dboptions = isset($CFG->phpunit_dboptions) ? $CFG->phpunit_dboptions : $CF
$allowed = array('wwwroot', 'dataroot', 'dirroot', 'admin', 'directorypermissions', 'filepermissions',
'dbtype', 'dblibrary', 'dbhost', 'dbname', 'dbuser', 'dbpass', 'prefix', 'dboptions',
'proxyhost', 'proxyport', 'proxytype', 'proxyuser', 'proxypassword', 'proxybypass', // keep proxy settings from config.php
'altcacheconfigpath'
);
$productioncfg = (array)$CFG;
$CFG = new stdClass();