mirror of
https://github.com/moodle/moodle.git
synced 2025-03-14 12:40:01 +01:00
MDL-56273 cache: Use cache initialise always.
purge_all() and purge_by_definition() look in the configuration for which caches are available and then creates them to purge them. The configuration stores the values used by initialise(), not initialise_unit_test_instance() and would therefore fail to purge all caches if they were not purged by another means. In the case of filestore, it's purged by unit tests, in the case of memcache(d), it purges the whole store when a single definition is requested. Therefore all configuration was moved into the configuration file during unit tests and does not have any special override codes in the unit test infrastructure.
This commit is contained in:
parent
577bd70d38
commit
a169739d5d
9
cache/classes/dummystore.php
vendored
9
cache/classes/dummystore.php
vendored
@ -262,6 +262,15 @@ class cachestore_dummy extends cache_store {
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the appropriate configuration required for unit testing.
|
||||
*
|
||||
* @return array Array of unit test configuration data to be used by initialise().
|
||||
*/
|
||||
public static function unit_test_configuration() {
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this instance.
|
||||
* @return string
|
||||
|
24
cache/classes/store.php
vendored
24
cache/classes/store.php
vendored
@ -81,15 +81,11 @@ interface cache_store_interface {
|
||||
public static function initialise_test_instance(cache_definition $definition);
|
||||
|
||||
/**
|
||||
* Initialises a test instance for unit tests.
|
||||
* Generates the appropriate configuration required for unit testing.
|
||||
*
|
||||
* This differs from initialise_test_instance in that it doesn't rely on interacting with the config table.
|
||||
*
|
||||
* @since 2.8
|
||||
* @param cache_definition $definition
|
||||
* @return cache_store|false
|
||||
* @return array Array of unit test configuration data to be used by initialise().
|
||||
*/
|
||||
public static function initialise_unit_test_instance(cache_definition $definition);
|
||||
public static function unit_test_configuration();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -369,20 +365,6 @@ abstract class cache_store implements cache_store_interface {
|
||||
return clone($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialises a test instance for unit tests.
|
||||
*
|
||||
* This differs from initialise_test_instance in that it doesn't rely on interacting with the config table.
|
||||
* By default however it calls initialise_test_instance to support backwards compatibility.
|
||||
*
|
||||
* @since 2.8
|
||||
* @param cache_definition $definition
|
||||
* @return cache_store|false
|
||||
*/
|
||||
public static function initialise_unit_test_instance(cache_definition $definition) {
|
||||
return static::initialise_test_instance($definition);
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be overridden to return any warnings this store instance should make to the admin.
|
||||
*
|
||||
|
31
cache/stores/apcu/lib.php
vendored
31
cache/stores/apcu/lib.php
vendored
@ -369,23 +369,12 @@ class cachestore_apcu extends cache_store implements cache_is_key_aware, cache_i
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an instance of the cache store that can be used for testing.
|
||||
* Generates the appropriate configuration required for unit testing.
|
||||
*
|
||||
* @param cache_definition $definition
|
||||
* @return cachestore_apcu|false
|
||||
* @return array Array of unit test configuration data to be used by initialise().
|
||||
*/
|
||||
public static function initialise_unit_test_instance(cache_definition $definition) {
|
||||
if (!self::are_requirements_met()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$store = new cachestore_apcu('Test APCu', array('prefix' => 'phpunit'));
|
||||
if (!$store->is_ready()) {
|
||||
return false;
|
||||
}
|
||||
$store->initialise($definition);
|
||||
|
||||
return $store;
|
||||
public static function unit_test_configuration() {
|
||||
return array('prefix' => 'phpunit');
|
||||
}
|
||||
|
||||
/**
|
||||
@ -416,4 +405,16 @@ class cachestore_apcu extends cache_store implements cache_is_key_aware, cache_i
|
||||
}
|
||||
$editform->set_data($data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this cache store instance is both suitable for testing, and ready for testing.
|
||||
*
|
||||
* Cache stores that support being used as the default store for unit and acceptance testing should
|
||||
* override this function and return true if there requirements have been met.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function ready_to_be_used_for_testing() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
10
cache/stores/apcu/tests/apcu_test.php
vendored
10
cache/stores/apcu/tests/apcu_test.php
vendored
@ -57,7 +57,8 @@ class cachestore_apcu_test extends cachestore_tests {
|
||||
*/
|
||||
public function test_cross_application_interaction() {
|
||||
$definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_apcu', 'phpunit_test');
|
||||
$instance = cachestore_apcu::initialise_unit_test_instance($definition);
|
||||
$instance = new cachestore_apcu('Test', cachestore_apcu::unit_test_configuration());
|
||||
$instance->initialise($definition);
|
||||
|
||||
// Test purge with custom data.
|
||||
$this->assertTrue($instance->set('test', 'monster'));
|
||||
@ -75,9 +76,12 @@ class cachestore_apcu_test extends cachestore_tests {
|
||||
|
||||
public function test_different_caches_have_different_prefixes() {
|
||||
$definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_apcu', 'phpunit_test');
|
||||
$instance = cachestore_apcu::initialise_unit_test_instance($definition);
|
||||
$instance = new cachestore_apcu('Test', cachestore_apcu::unit_test_configuration());
|
||||
$instance->initialise($definition);
|
||||
|
||||
$definition2 = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_apcu', 'phpunit_test2');
|
||||
$instance2 = cachestore_apcu::initialise_unit_test_instance($definition2);
|
||||
$instance2 = new cachestore_apcu('Test', cachestore_apcu::unit_test_configuration());
|
||||
$instance2->initialise($definition2);
|
||||
|
||||
$instance->set('test1', 1);
|
||||
$this->assertFalse($instance2->get('test1'));
|
||||
|
9
cache/stores/file/lib.php
vendored
9
cache/stores/file/lib.php
vendored
@ -677,6 +677,15 @@ class cachestore_file extends cache_store implements cache_is_key_aware, cache_i
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the appropriate configuration required for unit testing.
|
||||
*
|
||||
* @return array Array of unit test configuration data to be used by initialise().
|
||||
*/
|
||||
public static function unit_test_configuration() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes your madness to a file.
|
||||
*
|
||||
|
22
cache/stores/memcache/lib.php
vendored
22
cache/stores/memcache/lib.php
vendored
@ -582,24 +582,16 @@ class cachestore_memcache extends cache_store implements cache_is_configurable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a test instance for unit tests if possible.
|
||||
* @param cache_definition $definition
|
||||
* @return bool|cachestore_memcache
|
||||
* Generates the appropriate configuration required for unit testing.
|
||||
*
|
||||
* @return array Array of unit test configuration data to be used by initialise().
|
||||
*/
|
||||
public static function initialise_unit_test_instance(cache_definition $definition) {
|
||||
if (!self::are_requirements_met()) {
|
||||
return false;
|
||||
}
|
||||
public static function unit_test_configuration() {
|
||||
// If the configuration is not defined correctly, return only the configuration know about.
|
||||
if (!defined('TEST_CACHESTORE_MEMCACHE_TESTSERVERS')) {
|
||||
return false;
|
||||
return [];
|
||||
}
|
||||
$configuration = array();
|
||||
$configuration['servers'] = explode("\n", TEST_CACHESTORE_MEMCACHE_TESTSERVERS);
|
||||
|
||||
$store = new cachestore_memcache('Test memcache', $configuration);
|
||||
$store->initialise($definition);
|
||||
|
||||
return $store;
|
||||
return ['servers' => explode("\n", TEST_CACHESTORE_MEMCACHE_TESTSERVERS)];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -57,7 +57,8 @@ class cachestore_memcache_test extends cachestore_tests {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_memcache', 'phpunit_test');
|
||||
$instance = cachestore_memcache::initialise_unit_test_instance($definition);
|
||||
$instance = new cachestore_memcache('Memcache Test', cachestore_memcache::unit_test_configuration());
|
||||
$instance->initialise($definition);
|
||||
|
||||
if (!$instance) { // Something prevented memcache store to be inited (extension, TEST_CACHESTORE_MEMCACHE_TESTSERVERS...).
|
||||
$this->markTestSkipped();
|
||||
|
23
cache/stores/memcached/lib.php
vendored
23
cache/stores/memcached/lib.php
vendored
@ -739,25 +739,16 @@ class cachestore_memcached extends cache_store implements cache_is_configurable
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a test instance for unit tests if possible.
|
||||
* @param cache_definition $definition
|
||||
* @return bool|cachestore_memcached
|
||||
* Generates the appropriate configuration required for unit testing.
|
||||
*
|
||||
* @return array Array of unit test configuration data to be used by initialise().
|
||||
*/
|
||||
public static function initialise_unit_test_instance(cache_definition $definition) {
|
||||
if (!self::are_requirements_met()) {
|
||||
return false;
|
||||
}
|
||||
public static function unit_test_configuration() {
|
||||
// If the configuration is not defined correctly, return only the configuration know about.
|
||||
if (!defined('TEST_CACHESTORE_MEMCACHED_TESTSERVERS')) {
|
||||
return false;
|
||||
return [];
|
||||
}
|
||||
|
||||
$configuration = array();
|
||||
$configuration['servers'] = explode("\n", TEST_CACHESTORE_MEMCACHED_TESTSERVERS);
|
||||
|
||||
$store = new cachestore_memcached('Test memcached', $configuration);
|
||||
$store->initialise($definition);
|
||||
|
||||
return $store;
|
||||
return ['servers' => explode("\n", TEST_CACHESTORE_MEMCACHED_TESTSERVERS)];
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -61,9 +61,11 @@ class cachestore_memcached_test extends cachestore_tests {
|
||||
$this->resetAfterTest(true);
|
||||
|
||||
$definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_memcached', 'phpunit_test');
|
||||
$instance = cachestore_memcached::initialise_unit_test_instance($definition);
|
||||
$instance = new cachestore_memcached('Memcached Test', cachestore_memcached::unit_test_configuration());
|
||||
$instance->initialise($definition);
|
||||
|
||||
if (!$instance) { // Something prevented memcached store to be inited (extension, TEST_CACHESTORE_MEMCACHED_TESTSERVERS...).
|
||||
if (!$instance->is_ready()) {
|
||||
// Something prevented memcached store to be inited (extension, TEST_CACHESTORE_MEMCACHED_TESTSERVERS...).
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
|
19
cache/stores/mongodb/lib.php
vendored
19
cache/stores/mongodb/lib.php
vendored
@ -571,25 +571,16 @@ class cachestore_mongodb extends cache_store implements cache_is_configurable {
|
||||
* @param cache_definition $definition
|
||||
* @return false
|
||||
*/
|
||||
public static function initialise_unit_test_instance(cache_definition $definition) {
|
||||
if (!self::are_requirements_met()) {
|
||||
return false;
|
||||
}
|
||||
if (!defined('TEST_CACHESTORE_MONGODB_TESTSERVER')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
public static function unit_test_configuration() {
|
||||
$configuration = array();
|
||||
$configuration['servers'] = explode("\n", TEST_CACHESTORE_MONGODB_TESTSERVER);
|
||||
$configuration['usesafe'] = 1;
|
||||
|
||||
$store = new cachestore_mongodb('Test mongodb', $configuration);
|
||||
if (!$store->is_ready()) {
|
||||
return false;
|
||||
// If the configuration is not defined correctly, return only the configuration know about.
|
||||
if (defined('TEST_CACHESTORE_MONGODB_TESTSERVER')) {
|
||||
$configuration['servers'] = explode("\n", TEST_CACHESTORE_MONGODB_TESTSERVER);
|
||||
}
|
||||
$store->initialise($definition);
|
||||
|
||||
return $store;
|
||||
return $configuration;
|
||||
}
|
||||
|
||||
/**
|
||||
|
5
cache/stores/mongodb/tests/mongodb_test.php
vendored
5
cache/stores/mongodb/tests/mongodb_test.php
vendored
@ -56,9 +56,10 @@ class cachestore_mongodb_test extends cachestore_tests {
|
||||
public function test_collection_name() {
|
||||
// This generates a definition that has a hash starting with a number. MDL-46208.
|
||||
$definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_mongodb', 'abc');
|
||||
$instance = cachestore_mongodb::initialise_unit_test_instance($definition);
|
||||
$instance = new cachestore_mongodb('MongoDB_Test', cachestore_mongodb::unit_test_configuration());
|
||||
$instance->initialise($definition);
|
||||
|
||||
if (!$instance) {
|
||||
if (!$instance->is_ready()) {
|
||||
$this->markTestSkipped();
|
||||
}
|
||||
|
||||
|
8
cache/stores/session/lib.php
vendored
8
cache/stores/session/lib.php
vendored
@ -516,6 +516,14 @@ class cachestore_session extends session_data_store implements cache_is_key_awar
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the appropriate configuration required for unit testing.
|
||||
*
|
||||
* @return array Array of unit test configuration data to be used by initialise().
|
||||
*/
|
||||
public static function unit_test_configuration() {
|
||||
return array();
|
||||
}
|
||||
/**
|
||||
* Returns the name of this instance.
|
||||
* @return string
|
||||
|
9
cache/stores/static/lib.php
vendored
9
cache/stores/static/lib.php
vendored
@ -492,6 +492,15 @@ class cachestore_static extends static_data_store implements cache_is_key_aware,
|
||||
return $cache;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates the appropriate configuration required for unit testing.
|
||||
*
|
||||
* @return array Array of unit test configuration data to be used by initialise().
|
||||
*/
|
||||
public static function unit_test_configuration() {
|
||||
return array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the name of this instance.
|
||||
* @return string
|
||||
|
6
cache/tests/cache_test.php
vendored
6
cache/tests/cache_test.php
vendored
@ -1315,8 +1315,10 @@ class core_cache_testcase extends advanced_testcase {
|
||||
|
||||
$configfile = $CFG->dataroot.'/muc/config.php';
|
||||
|
||||
// That's right, we're deleting the config file.
|
||||
$this->assertTrue(@unlink($configfile));
|
||||
// The config file will not exist yet as we've not done anything with the cache.
|
||||
// reset_all_data removes the file and without a call to create a configuration it doesn't exist
|
||||
// as yet.
|
||||
$this->assertFileNotExists($configfile);
|
||||
|
||||
// Disable the cache
|
||||
cache_phpunit_factory::phpunit_disable();
|
||||
|
49
cache/tests/fixtures/lib.php
vendored
49
cache/tests/fixtures/lib.php
vendored
@ -73,13 +73,13 @@ class cache_config_testing extends cache_config_writer {
|
||||
if (class_exists($class) && $class::ready_to_be_used_for_testing()) {
|
||||
/* @var cache_store $class */
|
||||
$writer->configstores['test_application'] = array(
|
||||
'use_test_store' => true,
|
||||
'name' => 'test_application',
|
||||
'plugin' => $expectedstore,
|
||||
'alt' => $writer->configstores[$defaultapplication],
|
||||
'modes' => $class::get_supported_modes(),
|
||||
'features' => $class::get_supported_features()
|
||||
'features' => $class::get_supported_features(),
|
||||
'configuration' => $class::unit_test_configuration()
|
||||
);
|
||||
|
||||
$defaultapplication = 'test_application';
|
||||
}
|
||||
}
|
||||
@ -535,47 +535,4 @@ class cache_phpunit_factory extends cache_factory {
|
||||
public static function phpunit_disable() {
|
||||
parent::disable();
|
||||
}
|
||||
|
||||
/**
|
||||
* @var bool Whether the warning notice about alternative cache store used has been displayed.
|
||||
*/
|
||||
protected $altcachestorenotice = false;
|
||||
|
||||
/**
|
||||
* Creates a store instance given its name and configuration.
|
||||
*
|
||||
* If the store has already been instantiated then the original object will be returned. (reused)
|
||||
*
|
||||
* @param string $name The name of the store (must be unique remember)
|
||||
* @param array $details
|
||||
* @param cache_definition $definition The definition to instantiate it for.
|
||||
* @return boolean|cache_store
|
||||
*/
|
||||
public function create_store_from_config($name, array $details, cache_definition $definition) {
|
||||
|
||||
if (isset($details['use_test_store'])) {
|
||||
// name, plugin, alt
|
||||
$class = 'cachestore_'.$details['plugin'];
|
||||
$method = 'initialise_unit_test_instance';
|
||||
if (class_exists($class) && method_exists($class, $method)) {
|
||||
$instance = $class::$method($definition);
|
||||
|
||||
if ($instance) {
|
||||
return $instance;
|
||||
}
|
||||
}
|
||||
|
||||
// Notify user that alternative store is being used, so action can be taken.
|
||||
if (!$this->altcachestorenotice) {
|
||||
echo PHP_EOL . "++ WARNING: " . 'Failed to use "' . $details['plugin'] . '" cache store, alt "' .
|
||||
$details['alt']['plugin'] . '" cache store is used.' . PHP_EOL . PHP_EOL;
|
||||
$this->altcachestorenotice = true;
|
||||
}
|
||||
$details = $details['alt'];
|
||||
$details['class'] = 'cachestore_'.$details['plugin'];
|
||||
$name = $details['name'];
|
||||
}
|
||||
|
||||
return parent::create_store_from_config($name, $details, $definition);
|
||||
}
|
||||
}
|
26
cache/tests/fixtures/stores.php
vendored
26
cache/tests/fixtures/stores.php
vendored
@ -42,19 +42,29 @@ abstract class cachestore_tests extends advanced_testcase {
|
||||
*/
|
||||
abstract protected function get_class_name();
|
||||
|
||||
/**
|
||||
* Sets up the fixture, for example, open a network connection.
|
||||
* This method is called before a test is executed.
|
||||
*/
|
||||
public function setUp() {
|
||||
$class = $this->get_class_name();
|
||||
if (!class_exists($class) || !$class::are_requirements_met()) {
|
||||
$this->markTestSkipped('Could not test '.$class.'. Requirements are not met.');
|
||||
}
|
||||
parent::setUp();
|
||||
}
|
||||
/**
|
||||
* Run the unit tests for the store.
|
||||
*/
|
||||
public function test_test_instance() {
|
||||
$class = $this->get_class_name();
|
||||
if (!class_exists($class) || !method_exists($class, 'initialise_test_instance') || !$class::are_requirements_met()) {
|
||||
$this->markTestSkipped('Could not test '.$class.'. Requirements are not met.');
|
||||
}
|
||||
|
||||
$modes = $class::get_supported_modes();
|
||||
if ($modes & cache_store::MODE_APPLICATION) {
|
||||
$definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, $class, 'phpunit_test');
|
||||
$instance = $class::initialise_unit_test_instance($definition);
|
||||
$instance = new $class($class.'_test', $class::unit_test_configuration());
|
||||
$instance->initialise($definition);
|
||||
|
||||
if (!$instance) {
|
||||
$this->markTestSkipped('Could not test '.$class.'. No test instance configured for application caches.');
|
||||
} else {
|
||||
@ -63,7 +73,9 @@ abstract class cachestore_tests extends advanced_testcase {
|
||||
}
|
||||
if ($modes & cache_store::MODE_SESSION) {
|
||||
$definition = cache_definition::load_adhoc(cache_store::MODE_SESSION, $class, 'phpunit_test');
|
||||
$instance = $class::initialise_unit_test_instance($definition);
|
||||
$instance = new $class($class.'_test', $class::unit_test_configuration());
|
||||
$instance->initialise($definition);
|
||||
|
||||
if (!$instance) {
|
||||
$this->markTestSkipped('Could not test '.$class.'. No test instance configured for session caches.');
|
||||
} else {
|
||||
@ -72,7 +84,9 @@ abstract class cachestore_tests extends advanced_testcase {
|
||||
}
|
||||
if ($modes & cache_store::MODE_REQUEST) {
|
||||
$definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, $class, 'phpunit_test');
|
||||
$instance = $class::initialise_unit_test_instance($definition);
|
||||
$instance = new $class($class.'_test', $class::unit_test_configuration());
|
||||
$instance->initialise($definition);
|
||||
|
||||
if (!$instance) {
|
||||
$this->markTestSkipped('Could not test '.$class.'. No test instance configured for request caches.');
|
||||
} else {
|
||||
|
2
cache/upgrade.txt
vendored
2
cache/upgrade.txt
vendored
@ -13,6 +13,8 @@ Information provided here is intended especially for developers.
|
||||
- cache_store::cleanup()
|
||||
* cachestore_dummy::cleanup() has been deprecated.
|
||||
* cachestore_dummy::instance_deleted() implemented in lieu of cachestore_dummy::cleanup().
|
||||
* Added cache_store::unit_test_configuration() to calculate unit testing configuration.
|
||||
* Remove cache_store:initialise_unit_test_instance() as it is incompatible with cache_helper purge functions.
|
||||
|
||||
=== 3.1 ===
|
||||
* Cache stores has a new feature DEREFERENCES_OBJECTS.
|
||||
|
@ -814,12 +814,13 @@ abstract class testing_util {
|
||||
make_temp_directory('');
|
||||
make_cache_directory('');
|
||||
make_localcache_directory('');
|
||||
// Purge all data from the caches. This is required for consistency between tests.
|
||||
// Any file caches that happened to be within the data root will have already been clearer (because we just deleted cache)
|
||||
// and now we will purge any other caches as well. This must be done before the cache_factory::reset() as that
|
||||
// removes all definitions of caches and purge does not have valid caches to operate on.
|
||||
cache_helper::purge_all();
|
||||
// Reset the cache API so that it recreates it's required directories as well.
|
||||
cache_factory::reset();
|
||||
// Purge all data from the caches. This is required for consistency.
|
||||
// Any file caches that happened to be within the data root will have already been clearer (because we just deleted cache)
|
||||
// and now we will purge any other caches as well.
|
||||
cache_helper::purge_all();
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
x
Reference in New Issue
Block a user