Exemplo n.º 1
0
 /**
  * Test purging the apcu cache store.
  */
 public function test_purge()
 {
     if (!cachestore_apcu::are_requirements_met()) {
         $this->markTestSkipped('Could not test cachestore_apcu. Requirements are not met.');
     }
     $definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_apcu', 'phpunit_test');
     $instance = cachestore_apcu::initialise_unit_test_instance($definition);
     // Test a simple purge return.
     $this->assertTrue($instance->purge());
     // Test purge works.
     $this->assertTrue($instance->set('test', 'monster'));
     $this->assertSame('monster', $instance->get('test'));
     $this->assertTrue($instance->purge());
     $this->assertFalse($instance->get('test'));
     // Test purge with custom data.
     $this->assertTrue($instance->set('test', 'monster'));
     $this->assertSame('monster', $instance->get('test'));
     $this->assertTrue(apcu_store('test', 'pirate', 180));
     $this->assertSame('monster', $instance->get('test'));
     $this->assertTrue(apcu_exists('test'));
     $this->assertSame('pirate', apcu_fetch('test'));
     // Purge and check that our data is gone but the the custom data is still there.
     $this->assertTrue($instance->purge());
     $this->assertFalse($instance->get('test'));
     $this->assertTrue(apcu_exists('test'));
     $this->assertSame('pirate', apcu_fetch('test'));
 }
Exemplo n.º 2
0
 /**
  * Run the unit tests for the store.
  */
 public function test_test_instance()
 {
     $class = $this->get_class_name();
     $modes = $class::get_supported_modes();
     if ($modes & cache_store::MODE_APPLICATION) {
         $definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, $class, 'phpunit_test');
         $instance = new $class($class . '_test', $class::unit_test_configuration());
         if (!$instance->is_ready()) {
             $this->markTestSkipped('Could not test ' . $class . '. No test instance configured for application caches.');
         } else {
             $instance->initialise($definition);
             $this->run_tests($instance);
         }
     }
     if ($modes & cache_store::MODE_SESSION) {
         $definition = cache_definition::load_adhoc(cache_store::MODE_SESSION, $class, 'phpunit_test');
         $instance = new $class($class . '_test', $class::unit_test_configuration());
         if (!$instance->is_ready()) {
             $this->markTestSkipped('Could not test ' . $class . '. No test instance configured for session caches.');
         } else {
             $instance->initialise($definition);
             $this->run_tests($instance);
         }
     }
     if ($modes & cache_store::MODE_REQUEST) {
         $definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, $class, 'phpunit_test');
         $instance = new $class($class . '_test', $class::unit_test_configuration());
         if (!$instance->is_ready()) {
             $this->markTestSkipped('Could not test ' . $class . '. No test instance configured for request caches.');
         } else {
             $instance->initialise($definition);
             $this->run_tests($instance);
         }
     }
 }
Exemplo n.º 3
0
 /**
  * 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);
         if (!$instance) {
             $this->markTestSkipped('Could not test ' . $class . '. No test instance configured for application caches.');
         } else {
             $this->run_tests($instance);
         }
     }
     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);
         if (!$instance) {
             $this->markTestSkipped('Could not test ' . $class . '. No test instance configured for session caches.');
         } else {
             $this->run_tests($instance);
         }
     }
     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);
         if (!$instance) {
             $this->markTestSkipped('Could not test ' . $class . '. No test instance configured for request caches.');
         } else {
             $this->run_tests($instance);
         }
     }
 }
Exemplo n.º 4
0
 /**
  * Sets a key value pair into the static acceleration array.
  *
  * @param string $key The parsed key
  * @param mixed $data
  * @return bool
  */
 protected function static_acceleration_set($key, $data)
 {
     if ($this->staticaccelerationsize !== false && isset($this->staticaccelerationkeys[$key])) {
         $this->staticaccelerationcount--;
         unset($this->staticaccelerationkeys[$key]);
     }
     // We serialize anything that's not;
     // 1. A known scalar safe value.
     // 2. A definition that says it's simpledata.  We trust it that it doesn't contain dangerous references.
     // 3. An object that handles dereferencing by itself.
     if (is_scalar($data) || $this->definition->uses_simple_data() || $data instanceof cache_cached_object) {
         $this->staticaccelerationarray[$key]['data'] = $data;
         $this->staticaccelerationarray[$key]['serialized'] = false;
     } else {
         $this->staticaccelerationarray[$key]['data'] = serialize($data);
         $this->staticaccelerationarray[$key]['serialized'] = true;
     }
     if ($this->staticaccelerationsize !== false) {
         $this->staticaccelerationcount++;
         $this->staticaccelerationkeys[$key] = $key;
         if ($this->staticaccelerationcount > $this->staticaccelerationsize) {
             $dropkey = array_shift($this->staticaccelerationkeys);
             unset($this->staticaccelerationarray[$dropkey]);
             $this->staticaccelerationcount--;
         }
     }
     return true;
 }
Exemplo n.º 5
0
 /**
  * Sets an item in the cache given its key and data value.
  *
  * @param string $key The key to use.
  * @param mixed $data The data to set.
  * @return bool True if the operation was a success false otherwise.
  */
 public function set($key, $data)
 {
     if ($this->encode) {
         // We must serialise this data.
         $data = serialize($data);
     }
     return $this->connection->set($this->parse_key($key), $data, MEMCACHE_COMPRESSED, $this->definition->get_ttl());
 }
Exemplo n.º 6
0
 /**
  * Sets many items in the cache in a single transaction.
  *
  * @param array $keyvaluearray An array of key value pairs. Each item in the array will be an associative array with two
  *      keys, 'key' and 'value'.
  * @return int The number of items successfully set. It is up to the developer to check this matches the number of items
  *      sent ... if they care that is.
  */
 public function set_many(array $keyvaluearray)
 {
     $store = array();
     foreach ($keyvaluearray as $pair) {
         $store[$this->prepare_key($pair['key'])] = $pair['value'];
     }
     $result = apcu_store($store, null, $this->definition->get_ttl());
     return count($keyvaluearray) - count($result);
 }
Exemplo n.º 7
0
 /**
  * Sets many items in the cache in a single transaction.
  *
  * @param array $keyvaluearray An array of key value pairs. Each item in the array will be an associative array with two
  *      keys, 'key' and 'value'.
  * @return int The number of items successfully set. It is up to the developer to check this matches the number of items
  *      sent ... if they care that is.
  */
 public function set_many(array $keyvaluearray)
 {
     $count = 0;
     foreach ($keyvaluearray as $pair) {
         if ($this->connection->set($this->parse_key($pair['key']), $pair['value'], MEMCACHE_COMPRESSED, $this->definition->get_ttl())) {
             $count++;
         }
     }
     return $count;
 }
Exemplo n.º 8
0
 /**
  * Sets an item in the cache given its key and data value.
  *
  * @param string $key The key to use.
  * @param mixed $data The data to set.
  * @return bool True if the operation was a success false otherwise.
  */
 public function set($key, $data)
 {
     if ($this->clustered) {
         $status = true;
         foreach ($this->setconnections as $connection) {
             $status = $connection->set($this->parse_key($key), $data, MEMCACHE_COMPRESSED, $this->definition->get_ttl()) && $status;
         }
         return $status;
     }
     return $this->connection->set($this->parse_key($key), $data, MEMCACHE_COMPRESSED, $this->definition->get_ttl());
 }
Exemplo n.º 9
0
 /**
  * Sets many items in the cache in a single transaction.
  *
  * @param array $keyvaluearray An array of key value pairs. Each item in the array will be an associative array with two
  *      keys, 'key' and 'value'.
  * @return int The number of items successfully set. It is up to the developer to check this matches the number of items
  *      sent ... if they care that is.
  */
 public function set_many(array $keyvaluearray)
 {
     $pairs = array();
     foreach ($keyvaluearray as $pair) {
         $pairs[$pair['key']] = $pair['value'];
     }
     if ($this->connection->setMulti($pairs, $this->definition->get_ttl())) {
         return count($keyvaluearray);
     }
     return 0;
 }
Exemplo n.º 10
0
 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);
     $definition2 = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_apcu', 'phpunit_test2');
     $instance2 = cachestore_apcu::initialise_unit_test_instance($definition2);
     $instance->set('test1', 1);
     $this->assertFalse($instance2->get('test1'));
     $instance2->purge();
     $this->assertSame(1, $instance->get('test1'));
 }
 protected function setUp()
 {
     if (!defined('CACHESTORE_REDIS_TEST_SERVER')) {
         $this->markTestSkipped('Must define CACHESTORE_REDIS_TEST_SERVER to test Redis cache store');
     }
     if (!cachestore_redis::are_requirements_met()) {
         $this->markTestSkipped('Requirements for Redis cache store are not met');
     }
     $this->store = new cachestore_redis('test', array('server' => CACHESTORE_REDIS_TEST_SERVER, 'prefix' => 'phpunit'));
     $this->store->initialise(cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'foo_bar', 'baz'));
 }
Exemplo n.º 12
0
 /**
  * Parses the key turning it into a string (or array is required) suitable to be passed to the cache store.
  *
  * @param string|int $key As passed to get|set|delete etc.
  * @return string|array String unless the store supports multi-identifiers in which case an array if returned.
  */
 protected function parse_key($key)
 {
     // First up if the store supports multiple keys we'll go with that.
     if ($this->store->supports_multiple_identifiers()) {
         $result = $this->definition->generate_multi_key_parts();
         $result['key'] = $key;
         return $result;
     }
     // If not we need to generate a hash and to for that we use the cache_helper.
     return cache_helper::hash_key($key, $this->definition);
 }
Exemplo n.º 13
0
 /**
  * Creates the required cachestore for the tests to run against Redis.
  *
  * @return cachestore_redis
  */
 protected function create_cachestore_redis()
 {
     /** @var cache_definition $definition */
     $definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_redis', 'phpunit_test');
     $store = new cachestore_redis('Test', cachestore_redis::unit_test_configuration());
     $store->initialise($definition);
     $this->store = $store;
     if (!$store) {
         $this->markTestSkipped();
     }
     return $store;
 }
Exemplo n.º 14
0
 /**
  * Returns the item from the static acceleration array if it exists there.
  *
  * @param string $key The parsed key
  * @return mixed|false The data from the static acceleration array or false if it wasn't there.
  */
 protected function get_from_persist_cache($key)
 {
     // This method of checking if an array was supplied is faster than is_array.
     if ($key === (array) $key) {
         $key = $key['key'];
     }
     // This isset check is faster than array_key_exists but will return false
     // for null values, meaning null values will come from backing store not
     // the static acceleration array. We think this okay because null usage should be
     // very rare (see comment in MDL-39472).
     if (!$this->staticacceleration || !isset($this->staticaccelerationarray[$key])) {
         $result = false;
     } else {
         $data = $this->staticaccelerationarray[$key];
         if (!$this->has_a_ttl() || !$data instanceof cache_ttl_wrapper) {
             if ($data instanceof cache_cached_object) {
                 $data = $data->restore_object();
             }
             $result = $data;
         } else {
             if ($data->has_expired()) {
                 $this->delete_from_persist_cache($key);
                 $result = false;
             } else {
                 if ($data instanceof cache_cached_object) {
                     $data = $data->restore_object();
                 }
                 $result = $data->data;
             }
         }
     }
     if ($result) {
         if ($this->perfdebug) {
             cache_helper::record_cache_hit('** static acceleration **', $this->definition->get_id());
         }
         if ($this->staticaccelerationsize > 1 && $this->staticaccelerationcount > 1) {
             // Check to see if this is the last item on the static acceleration keys array.
             if (end($this->staticaccelerationkeys) !== $key) {
                 // It isn't the last item.
                 // Move the item to the end of the array so that it is last to be removed.
                 unset($this->staticaccelerationkeys[$key]);
                 $this->staticaccelerationkeys[$key] = $key;
             }
         }
         return $result;
     } else {
         if ($this->perfdebug) {
             cache_helper::record_cache_miss('** static acceleration **', $this->definition->get_id());
         }
         return false;
     }
 }
Exemplo n.º 15
0
 /**
  * A small additional test to make sure definitions that hash a hash starting with a number work OK
  */
 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_test_instance($definition);
     if (!$instance) {
         $this->markTestSkipped();
     }
     $this->assertTrue($instance->set(1, 'alpha'));
     $this->assertTrue($instance->set(2, 'beta'));
     $this->assertEquals('alpha', $instance->get(1));
     $this->assertEquals('beta', $instance->get(2));
     $this->assertEquals(array(1 => 'alpha', 2 => 'beta'), $instance->get_many(array(1, 2)));
 }
Exemplo n.º 16
0
 /**
  * Sets an item in the cache given its key and data value.
  *
  * @param string $key The key to use.
  * @param mixed $data The data to set.
  * @return bool True if the operation was a success false otherwise.
  */
 public function set($key, $data)
 {
     if ($this->encode) {
         // We must serialise this data.
         $data = serialize($data);
     }
     if ($this->clustered) {
         $status = true;
         foreach ($this->setconnections as $connection) {
             $status = $connection->set($this->parse_key($key), $data, MEMCACHE_COMPRESSED, $this->definition->get_ttl()) && $status;
         }
         return $status;
     }
     return $this->connection->set($this->parse_key($key), $data, MEMCACHE_COMPRESSED, $this->definition->get_ttl());
 }
Exemplo n.º 17
0
 /**
  * Testing cachestore_file::get with prescan enabled and with
  * deleting the cache between the prescan and the call to get.
  *
  * The deleting of cache simulates some other process purging
  * the cache.
  */
 public function test_cache_get_with_prescan_and_purge()
 {
     global $CFG;
     $definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, 'cachestore_file', 'phpunit_test');
     $name = 'File test';
     $path = make_cache_directory('cachestore_file_test');
     $cache = new cachestore_file($name, array('path' => $path, 'prescan' => true));
     $cache->initialise($definition);
     $cache->set('testing', 'value');
     $path = make_cache_directory('cachestore_file_test');
     $cache = new cachestore_file($name, array('path' => $path, 'prescan' => true));
     $cache->initialise($definition);
     // Let's pretend that some other process purged caches.
     remove_dir($CFG->cachedir . '/cachestore_file_test', true);
     make_cache_directory('cachestore_file_test');
     $cache->get('testing');
 }
Exemplo n.º 18
0
 /**
  * Sets many items in the cache in a single transaction.
  *
  * @param array $keyvaluearray An array of key value pairs. Each item in the array will be an associative array with two
  *      keys, 'key' and 'value'.
  * @return int The number of items successfully set. It is up to the developer to check this matches the number of items
  *      sent ... if they care that is.
  */
 public function set_many(array $keyvaluearray)
 {
     $pairs = array();
     foreach ($keyvaluearray as $pair) {
         $pairs[$pair['key']] = $pair['value'];
     }
     $status = true;
     if ($this->clustered) {
         foreach ($this->setconnections as $connection) {
             $status = $connection->setMulti($pairs, $this->definition->get_ttl()) && $status;
         }
     } else {
         $status = $this->connection->setMulti($pairs, $this->definition->get_ttl());
     }
     if ($status) {
         return count($keyvaluearray);
     }
     return 0;
 }
Exemplo n.º 19
0
 /**
  * Tests the valid keys to ensure they work.
  */
 public function test_valid_keys()
 {
     $definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_memcached', 'phpunit_test');
     $instance = cachestore_memcached::initialise_test_instance($definition);
     if (!$instance) {
         // Something prevented memcached store to be inited (extension, TEST_CACHESTORE_MEMCACHED_TESTSERVERS...).
         $this->markTestSkipped();
     }
     $keys = array('abc', 'ABC', '123', 'aB1', '1aB', 'a-1', '1-a', '-a1', 'a1-', 'a_1', '1_a', '_a1', 'a1_');
     foreach ($keys as $key) {
         $this->assertTrue($instance->set($key, $key), "Failed to set key `{$key}`");
     }
     foreach ($keys as $key) {
         $this->assertEquals($key, $instance->get($key), "Failed to get key `{$key}`");
     }
     $values = $instance->get_many($keys);
     foreach ($values as $key => $value) {
         $this->assertEquals($key, $value);
     }
 }
Exemplo n.º 20
0
 /**
  * Test the maxsize option.
  */
 public function test_maxsize()
 {
     $defid = 'phpunit/testmaxsize';
     $config = cache_config_phpunittest::instance();
     $config->phpunit_add_definition($defid, array('mode' => cache_store::MODE_REQUEST, 'component' => 'phpunit', 'area' => 'testmaxsize', 'maxsize' => 3));
     $definition = cache_definition::load($defid, $config->get_definition_by_id($defid));
     $instance = cachestore_static::initialise_test_instance($definition);
     $this->assertTrue($instance->set('key1', 'value1'));
     $this->assertTrue($instance->set('key2', 'value2'));
     $this->assertTrue($instance->set('key3', 'value3'));
     $this->assertTrue($instance->has('key1'));
     $this->assertTrue($instance->has('key2'));
     $this->assertTrue($instance->has('key3'));
     $this->assertTrue($instance->set('key4', 'value4'));
     $this->assertTrue($instance->set('key5', 'value5'));
     $this->assertFalse($instance->has('key1'));
     $this->assertFalse($instance->has('key2'));
     $this->assertTrue($instance->has('key3'));
     $this->assertTrue($instance->has('key4'));
     $this->assertTrue($instance->has('key5'));
     $this->assertFalse($instance->get('key1'));
     $this->assertFalse($instance->get('key2'));
     $this->assertEquals('value3', $instance->get('key3'));
     $this->assertEquals('value4', $instance->get('key4'));
     $this->assertEquals('value5', $instance->get('key5'));
     // Test adding one more.
     $this->assertTrue($instance->set('key6', 'value6'));
     $this->assertFalse($instance->get('key3'));
     // Test reducing and then adding to make sure we don't lost one.
     $this->assertTrue($instance->delete('key6'));
     $this->assertTrue($instance->set('key7', 'value7'));
     $this->assertEquals('value4', $instance->get('key4'));
     // Set the same key three times to make sure it doesn't count overrides.
     for ($i = 0; $i < 3; $i++) {
         $this->assertTrue($instance->set('key8', 'value8'));
     }
     $this->assertEquals('value7', $instance->get('key7'), 'Overrides are incorrectly incrementing size');
     // Test adding many.
     $this->assertEquals(3, $instance->set_many(array(array('key' => 'keyA', 'value' => 'valueA'), array('key' => 'keyB', 'value' => 'valueB'), array('key' => 'keyC', 'value' => 'valueC'))));
     $this->assertEquals(array('key4' => false, 'key5' => false, 'key6' => false, 'key7' => false, 'keyA' => 'valueA', 'keyB' => 'valueB', 'keyC' => 'valueC'), $instance->get_many(array('key4', 'key5', 'key6', 'key7', 'keyA', 'keyB', 'keyC')));
 }
Exemplo n.º 21
0
 /**
  * Returns the item from the persist cache if it exists there.
  *
  * @param string $key The parsed key
  * @return mixed|false The data from the persist cache or false if it wasn't there.
  */
 protected function get_from_persist_cache($key)
 {
     if (is_array($key)) {
         $key = $key['key'];
     }
     if (!$this->persist || !array_key_exists($key, $this->persistcache)) {
         $result = false;
     } else {
         $data = $this->persistcache[$key];
         if (!$this->has_a_ttl() || !$data instanceof cache_ttl_wrapper) {
             if ($data instanceof cache_cached_object) {
                 $data = $data->restore_object();
             }
             $result = $data;
         } else {
             if ($data->has_expired()) {
                 $this->delete_from_persist_cache($key);
                 $result = false;
             } else {
                 if ($data instanceof cache_cached_object) {
                     $data = $data->restore_object();
                 }
                 $result = $data->data;
             }
         }
     }
     if ($result) {
         if ($this->perfdebug) {
             cache_helper::record_cache_hit('** static persist **', $this->definition->get_id());
         }
         return $result;
     } else {
         if ($this->perfdebug) {
             cache_helper::record_cache_miss('** static persist **', $this->definition->get_id());
         }
         return false;
     }
 }
Exemplo n.º 22
0
 /**
  * Returns an array of stores that would meet the requirements for every definition.
  *
  * These stores would be 100% suitable to map as defaults for cache modes.
  *
  * @return array[] An array of stores, keys are the store names.
  */
 public static function get_stores_suitable_for_mode_default()
 {
     $factory = cache_factory::instance();
     $config = $factory->create_config_instance();
     $requirements = 0;
     foreach ($config->get_definitions() as $definition) {
         $definition = cache_definition::load($definition['component'] . '/' . $definition['area'], $definition);
         $requirements = $requirements | $definition->get_requirements_bin();
     }
     $stores = array();
     foreach ($config->get_all_stores() as $name => $store) {
         if (!empty($store['features']) && $store['features'] & $requirements) {
             $stores[$name] = $store;
         }
     }
     return $stores;
 }
Exemplo n.º 23
0
 /**
  * Initialises the cache.
  *
  * Once this has been done the cache is all set to be used.
  *
  * @param cache_definition $definition
  */
 public function initialise(cache_definition $definition)
 {
     $this->storeid = $definition->generate_definition_hash();
     $this->store =& self::register_store_id($this->name . '-' . $definition->get_id());
     $this->ttl = $definition->get_ttl();
     $maxsize = $definition->get_maxsize();
     if ($maxsize !== null) {
         // Must be a positive int.
         $this->maxsize = abs((int) $maxsize);
         $this->storecount = count($this->store);
     }
     $this->check_ttl();
 }
Exemplo n.º 24
0
 /**
  * Tests that memcached cache store flushes entire cache when it is using a dedicated cache.
  */
 public function test_dedicated_cache()
 {
     if (!cachestore_memcached::are_requirements_met() || !defined('TEST_CACHESTORE_MEMCACHED_TESTSERVERS')) {
         $this->markTestSkipped('Could not test cachestore_memcached. Requirements are not met.');
     }
     $definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_memcached', 'phpunit_test');
     $cachestore = $this->create_test_cache_with_config($definition, array('isshared' => false));
     $connection = new Memcached(crc32(__METHOD__));
     $connection->addServers($this->get_servers(TEST_CACHESTORE_MEMCACHED_TESTSERVERS));
     $connection->setOptions(array(Memcached::OPT_COMPRESSION => true, Memcached::OPT_SERIALIZER => Memcached::SERIALIZER_PHP, Memcached::OPT_PREFIX_KEY => 'phpunit_', Memcached::OPT_BUFFER_WRITES => false));
     // We must flush first to make sure nothing is there.
     $connection->flush();
     // Test the cachestore.
     $this->assertFalse($cachestore->get('test'));
     $this->assertTrue($cachestore->set('test', 'cachestore'));
     $this->assertSame('cachestore', $cachestore->get('test'));
     // Test the connection.
     $this->assertFalse($connection->get('test'));
     $this->assertEquals(Memcached::RES_NOTFOUND, $connection->getResultCode());
     $this->assertTrue($connection->set('test', 'connection'));
     $this->assertSame('connection', $connection->get('test'));
     // Test both again and make sure the values are correct.
     $this->assertSame('cachestore', $cachestore->get('test'));
     $this->assertSame('connection', $connection->get('test'));
     // Purge the cachestore and check the connection was also purged.
     $this->assertTrue($cachestore->purge());
     $this->assertFalse($cachestore->get('test'));
     $this->assertFalse($connection->get('test'));
 }
Exemplo n.º 25
0
 /**
  * Hashes a descriptive key to make it shorter and still unique.
  * @param string|int $key
  * @param cache_definition $definition
  * @return string
  */
 public static function hash_key($key, cache_definition $definition)
 {
     if ($definition->uses_simple_keys()) {
         if (debugging() && preg_match('#[^a-zA-Z0-9_]#', $key)) {
             throw new coding_exception('Cache definition ' . $definition->get_id() . ' requires simple keys. Invalid key provided.', $key);
         }
         // We put the key first so that we can be sure the start of the key changes.
         return (string) $key . '-' . $definition->generate_single_key_prefix();
     }
     $key = $definition->generate_single_key_prefix() . '-' . $key;
     return sha1($key);
 }
Exemplo n.º 26
0
 /**
  * Creates a definition instance or returns the existing one if it has already been created.
  * @param string $component
  * @param string $area
  * @param string $aggregate
  * @return cache_definition
  */
 public function create_definition($component, $area, $aggregate = null)
 {
     $id = $component . '/' . $area;
     if ($aggregate) {
         $id .= '::' . $aggregate;
     }
     if (!array_key_exists($id, $this->definitions)) {
         // This is the first time this definition has been requested.
         if ($this->is_initialising()) {
             // We're initialising the cache right now. Don't try to create another config instance.
             // We'll just use an ad-hoc cache for the time being.
             $definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, $component, $area);
         } else {
             // Load all the known definitions and find the desired one.
             $instance = $this->create_config_instance();
             $definition = $instance->get_definition_by_id($id);
             if (!$definition) {
                 // Oh-oh the definition doesn't exist.
                 // There are several things that could be going on here.
                 // We may be installing/upgrading a site and have hit a definition that hasn't been used before.
                 // Of the developer may be trying to use a newly created definition.
                 if ($this->is_updating()) {
                     // The cache is presently initialising and the requested cache definition has not been found.
                     // This means that the cache initialisation has requested something from a cache (I had recursive nightmares about this).
                     // To serve this purpose and avoid errors we are going to make use of an ad-hoc cache rather than
                     // search for the definition which would possibly cause an infitite loop trying to initialise the cache.
                     $definition = cache_definition::load_adhoc(cache_store::MODE_REQUEST, $component, $area);
                     if ($aggregate !== null) {
                         // If you get here you deserve a warning. We have to use an ad-hoc cache here, so we can't find the definition and therefor
                         // can't find any information about the datasource or any of its aggregated.
                         // Best of luck.
                         debugging('An unknown cache was requested during development with an aggregate that could not be loaded. Ad-hoc cache used instead.', DEBUG_DEVELOPER);
                         $aggregate = null;
                     }
                 } else {
                     // Either a typo of the developer has just created the definition and is using it for the first time.
                     $this->reset();
                     $instance = $this->create_config_instance(true);
                     $instance->update_definitions();
                     $definition = $instance->get_definition_by_id($id);
                     if (!$definition) {
                         throw new coding_exception('The requested cache definition does not exist.' . $id, $id);
                     } else {
                         if (!$this->is_disabled()) {
                             debugging('Cache definitions reparsed causing cache reset in order to locate definition.
                             You should bump the version number to ensure definitions are reprocessed.', DEBUG_DEVELOPER);
                         }
                     }
                     $definition = cache_definition::load($id, $definition, $aggregate);
                 }
             } else {
                 $definition = cache_definition::load($id, $definition, $aggregate);
             }
         }
         $this->definitions[$id] = $definition;
     }
     return $this->definitions[$id];
 }
Exemplo n.º 27
0
 /**
  * Initialises the store instance for a definition.
  * @param cache_definition $definition
  */
 public function initialise(cache_definition $definition)
 {
     // If the definition isn't using static acceleration then we need to be store data here.
     // The reasoning behind this is that:
     //   - If the definition is using static acceleration then the cache loader is going to
     //     store things in its static array.
     //   - If the definition is not using static acceleration then the cache loader won't try to store anything
     //     and we will need to store it here in order to make sure it is accessible.
     if ($definition->get_mode() !== self::MODE_APPLICATION) {
         // Neither the request cache nor the session cache provide static acceleration.
         $this->persist = true;
     } else {
         $this->persist = !$definition->use_static_acceleration();
     }
 }
Exemplo n.º 28
0
 /**
  * Initialises the store instance for use.
  *
  * Once this has been done the cache is all set to be used.
  *
  * @param cache_definition $definition
  * @throws coding_exception
  */
 public function initialise(cache_definition $definition)
 {
     if ($this->is_initialised()) {
         throw new coding_exception('This mongodb instance has already been initialised.');
     }
     $this->database = $this->connection->selectDB($this->databasename);
     $this->definitionhash = 'm' . $definition->generate_definition_hash();
     $this->collection = $this->database->selectCollection($this->definitionhash);
     $options = array('name' => 'idx_key');
     if ($this->legacymongo) {
         $options['safe'] = $this->usesafe;
     } else {
         $options['w'] = $this->usesafe ? 1 : 0;
     }
     $this->collection->ensureIndex(array('key' => 1), $options);
 }
Exemplo n.º 29
0
 /**
  * Gets all of the stores that are to be used for the given definition.
  *
  * @param cache_definition $definition
  * @return array
  */
 public function get_stores_for_definition(cache_definition $definition)
 {
     // Check if MUC has been disabled.
     $factory = cache_factory::instance();
     if ($factory->stores_disabled()) {
         // Yip its been disabled.
         // To facilitate this we are going to always return an empty array of stores to use.
         // This will force all cache instances to use the cachestore_dummy.
         // MUC will still be used essentially so that code using it will still continue to function but because no cache stores
         // are being used interaction with MUC will be purely based around a static var.
         return array();
     }
     $availablestores = $this->get_stores($definition->get_mode(), $definition->get_requirements_bin());
     $stores = array();
     $id = $definition->get_id();
     // Now get any mappings and give them priority.
     foreach ($this->configdefinitionmappings as $mapping) {
         if ($mapping['definition'] !== $id) {
             continue;
         }
         $storename = $mapping['store'];
         if (!array_key_exists($storename, $availablestores)) {
             continue;
         }
         if (array_key_exists($storename, $stores)) {
             $store = $stores[$storename];
             unset($stores[$storename]);
             $stores[$storename] = $store;
         } else {
             $stores[$storename] = $availablestores[$storename];
         }
     }
     if (empty($stores) && !$definition->is_for_mappings_only()) {
         $mode = $definition->get_mode();
         // Load the default stores.
         foreach ($this->configmodemappings as $mapping) {
             if ($mapping['mode'] === $mode && array_key_exists($mapping['store'], $availablestores)) {
                 $store = $availablestores[$mapping['store']];
                 if (empty($store['mappingsonly'])) {
                     $stores[$mapping['store']] = $store;
                 }
             }
         }
     }
     return $stores;
 }
Exemplo n.º 30
0
 /**
  * Tests the clustering feature.
  */
 public function test_clustered()
 {
     $this->resetAfterTest(true);
     if (!defined('TEST_CACHESTORE_MEMCACHE_TESTSERVERS')) {
         $this->markTestSkipped();
     }
     $testservers = explode("\n", trim(TEST_CACHESTORE_MEMCACHE_TESTSERVERS));
     if (count($testservers) < 2) {
         $this->markTestSkipped();
     }
     // User the first server as our primary.
     set_config('testservers', $testservers[0], 'cachestore_memcache');
     set_config('testsetservers', TEST_CACHESTORE_MEMCACHE_TESTSERVERS, 'cachestore_memcache');
     set_config('testclustered', true, 'cachestore_memcache');
     // First and instance that we can use to test the second server.
     $definition = cache_definition::load_adhoc(cache_store::MODE_APPLICATION, 'cachestore_memcache', 'phpunit_test');
     $instance = cachestore_memcache::initialise_test_instance($definition);
     if (!$instance) {
         $this->markTestSkipped();
     }
     // Now we are going to setup a connection to each independent server.
     set_config('testclustered', false, 'cachestore_memcache');
     set_config('testsetservers', '', 'cachestore_memcache');
     $checkinstances = array();
     foreach ($testservers as $testserver) {
         set_config('testservers', $testserver, 'cachestore_memcache');
         $checkinstance = cachestore_memcache::initialise_test_instance($definition);
         if (!$checkinstance) {
             $this->markTestSkipped();
         }
         $checkinstances[] = $checkinstance;
     }
     $keys = array('abc', 'ABC', '123', 'aB1', '1aB', 'a-1', '1-a', '-a1', 'a1-', 'a_1', '1_a', '_a1', 'a1_');
     // Set each key.
     foreach ($keys as $key) {
         $this->assertTrue($instance->set($key, $key), "Failed to set key `{$key}`");
     }
     // Check each key.
     foreach ($keys as $key) {
         $this->assertEquals($key, $instance->get($key), "Failed to get key `{$key}`");
         foreach ($checkinstances as $id => $checkinstance) {
             $this->assertEquals($key, $checkinstance->get($key), "Failed to get key `{$key}` from server {$id}");
         }
     }
     // Reset a key.
     $this->assertTrue($instance->set($keys[0], 'New'), "Failed to reset key `{$key}`");
     $this->assertEquals('New', $instance->get($keys[0]), "Failed to get reset key `{$key}`");
     foreach ($checkinstances as $id => $checkinstance) {
         $this->assertEquals('New', $checkinstance->get($keys[0]), "Failed to get reset key `{$key}` from server {$id}");
     }
     // Delete and check that we can't retrieve.
     foreach ($keys as $key) {
         $this->assertTrue($instance->delete($key), "Failed to delete key `{$key}`");
         $this->assertFalse($instance->get($key), "Retrieved deleted key `{$key}`");
         foreach ($checkinstances as $id => $checkinstance) {
             $this->assertFalse($checkinstance->get($key), "Retrieved deleted key `{$key}` from server {$id}");
         }
     }
     // Try set many, and check that count is correct.
     $many = array();
     foreach ($keys as $key) {
         $many[] = array('key' => $key, 'value' => $key);
     }
     $returncount = $instance->set_many($many);
     $this->assertEquals(count($many), $returncount, 'Set many count didn\'t match');
     // Check keys retrieved with get_many.
     $values = $instance->get_many($keys);
     foreach ($keys as $key) {
         $this->assertTrue(isset($values[$key]), "Failed to get_many key `{$key}`");
         $this->assertEquals($key, $values[$key], "Failed to match get_many key `{$key}`");
     }
     foreach ($checkinstances as $id => $checkinstance) {
         $values = $checkinstance->get_many($keys);
         foreach ($keys as $key) {
             $this->assertTrue(isset($values[$key]), "Failed to get_many key `{$key}` from server {$id}");
             $this->assertEquals($key, $values[$key], "Failed to get_many key `{$key}` from server {$id}");
         }
     }
     // Delete many, make sure count matches.
     $returncount = $instance->delete_many($keys);
     $this->assertEquals(count($many), $returncount, 'Delete many count didn\'t match');
     // Check that each key was deleted.
     foreach ($keys as $key) {
         $this->assertFalse($instance->get($key), "Retrieved many deleted key `{$key}`");
         foreach ($checkinstances as $id => $checkinstance) {
             $this->assertFalse($checkinstance->get($key), "Retrieved many deleted key `{$key}` from server {$id}");
         }
     }
     // Set the keys again.
     $returncount = $instance->set_many($many);
     $this->assertEquals(count($many), $returncount, 'Set many count didn\'t match');
     // Purge.
     $this->assertTrue($instance->purge(), 'Failure to purge');
     // Delete and check that we can't retrieve.
     foreach ($keys as $key) {
         $this->assertFalse($instance->get($key), "Retrieved purged key `{$key}`");
         foreach ($checkinstances as $id => $checkinstance) {
             $this->assertFalse($checkinstance->get($key), "Retrieved purged key `{$key}` from server 2");
         }
     }
 }