View source
<?php
class MemcacheTestCase extends DrupalWebTestCase {
protected $profile = 'testing';
protected $default_bin = 'cache_memcache';
protected $default_cid = 'test_temporary';
protected $default_value = 'MemcacheTest';
function setUp() {
parent::setUp(func_get_args());
variable_set("cache_flush_{$this->default_bin}", 0);
variable_set('cache_class_cache_memcache', 'MemcacheDrupal');
$this
->resetVariables();
}
protected function checkCacheExists($cid, $var, $bin = NULL) {
if ($bin == NULL) {
$bin = $this->default_bin;
}
$cache = cache_get($cid, $bin);
return isset($cache->data) && $cache->data == $var;
}
protected function assertCacheExists($message, $var = NULL, $cid = NULL, $bin = NULL) {
if ($bin == NULL) {
$bin = $this->default_bin;
}
if ($cid == NULL) {
$cid = $this->default_cid;
}
if ($var == NULL) {
$var = $this->default_value;
}
$this
->assertTrue($this
->checkCacheExists($cid, $var, $bin), $message);
}
function assertCacheRemoved($message, $cid = NULL, $bin = NULL) {
if ($bin == NULL) {
$bin = $this->default_bin;
}
if ($cid == NULL) {
$cid = $this->default_cid;
}
$cache = cache_get($cid, $bin);
$this
->assertFalse($cache, $message);
}
protected function generalWipe($bin = NULL) {
if ($bin == NULL) {
$bin = $this->default_bin;
}
cache_clear_all(NULL, $bin);
}
function resetVariables() {
_cache_get_object($this->default_bin)
->reloadVariables();
}
}
class MemCacheSavingCase extends MemcacheTestCase {
public static function getInfo() {
return array(
'name' => 'Memcache saving test',
'description' => 'Check our variables are saved and restored the right way.',
'group' => 'Memcache',
);
}
function setUp() {
parent::setUp();
}
function testString() {
$this
->checkVariable($this
->randomName(100));
}
function testInteger() {
$this
->checkVariable(100);
}
function testDouble() {
$this
->checkVariable(1.29);
}
function testArray() {
$this
->checkVariable(array(
'drupal1',
'drupal2' => 'drupal3',
'drupal4' => array(
'drupal5',
'drupal6',
),
));
}
function testObject() {
$test_object = new stdClass();
$test_object->test1 = $this
->randomName(100);
$test_object->test2 = 100;
$test_object->test3 = array(
'drupal1',
'drupal2' => 'drupal3',
'drupal4' => array(
'drupal5',
'drupal6',
),
);
cache_set('test_object', $test_object, 'cache');
$cache = cache_get('test_object', 'cache');
$this
->assertTrue(isset($cache->data) && $cache->data == $test_object, t('Object is saved and restored properly.'));
}
function testStringLongKey() {
$this
->checkVariable($this
->randomName(100), 'ThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydogThequickbrownfoxjumpsoverthelazydog');
}
function testStringSpecialKey() {
$this
->checkVariable($this
->randomName(100), 'Qwerty!@#$%^&*()_+-=[]\\;\',./<>?:"{}|£¢');
}
function checkVariable($var, $key = 'test_var') {
cache_set($key, $var, 'cache');
$cache = cache_get($key, 'cache');
$this
->assertTrue(isset($cache->data) && $cache->data === $var, t('@type is saved and restored properly!key.', array(
'@type' => ucfirst(gettype($var)),
'!key' => $key != 'test_var' ? t(' with key @key', array(
'@key' => $key,
)) : '',
)));
}
}
class MemCacheGetMultipleUnitTest extends MemcacheTestCase {
public static function getInfo() {
return array(
'name' => 'Fetching multiple cache items',
'description' => 'Confirm that multiple records are fetched correctly.',
'group' => 'Memcache',
);
}
function setUp() {
parent::setUp();
}
function testCacheMultiple() {
$item1 = $this
->randomName(10);
$item2 = $this
->randomName(10);
cache_set('test:item1', $item1, $this->default_bin);
cache_set('test:item2', $item2, $this->default_bin);
$this
->assertTrue($this
->checkCacheExists('test:item1', $item1), t('Item 1 is cached.'));
$this
->assertTrue($this
->checkCacheExists('test:item2', $item2), t('Item 2 is cached.'));
$item_ids = array(
'test:item1',
'test:item2',
);
$items = cache_get_multiple($item_ids, $this->default_bin);
$this
->assertEqual($items['test:item1']->data, $item1, t('Item was returned from cache successfully.'));
$this
->assertEqual($items['test:item2']->data, $item2, t('Item was returned from cache successfully.'));
$this
->assertTrue(empty($item_ids), t('Ids of returned items have been removed.'));
cache_clear_all('test:item2', $this->default_bin);
$item_ids = array(
'test:item1',
'test:item2',
);
$items = cache_get_multiple($item_ids, $this->default_bin);
$this
->assertEqual($items['test:item1']->data, $item1, t('Item was returned from cache successfully.'));
$this
->assertFalse(isset($items['test:item2']), t('Item was not returned from the cache.'));
$this
->assertTrue(count($items) == 1, t('Only valid cache entries returned.'));
$this
->assertTrue(count($item_ids) == 1, t('Invalid cache ids still present.'));
}
}
class MemCacheClearCase extends MemcacheTestCase {
public static function getInfo() {
return array(
'name' => 'Cache clear test',
'description' => 'Check our clearing is done the proper way.',
'group' => 'Memcache',
);
}
function setUp() {
parent::setUp('memcache_test');
$this->default_value = $this
->randomName(10);
}
function testClearCidNoLifetime() {
$this
->clearCidTest();
}
function testClearCidLifetime() {
variable_set('cache_lifetime', 6000);
$this
->clearCidTest();
}
function testClearWildcardNoLifetime() {
$this
->clearWildcardPrefixTest();
}
function testClearWildcardLifetime() {
variable_set('cache_lifetime', 6000);
$this
->clearWildcardPrefixTest();
}
function testClearWildcardFull() {
cache_set('test_cid_clear1', $this->default_value, $this->default_bin);
cache_set('test_cid_clear2', $this->default_value, $this->default_bin);
$this
->assertTrue($this
->checkCacheExists('test_cid_clear1', $this->default_value) && $this
->checkCacheExists('test_cid_clear2', $this->default_value), t('Two caches were created for checking cid "*" with wildcard true.'));
cache_clear_all('*', $this->default_bin, TRUE);
$this
->assertFalse($this
->checkCacheExists('test_cid_clear1', $this->default_value) || $this
->checkCacheExists('test_cid_clear2', $this->default_value), t('Two caches removed after clearing cid "*" with wildcard true.'));
}
function testClearCacheLifetime() {
variable_set('cache_lifetime', 600);
$this
->resetVariables();
cache_set('test_cid', $this->default_value, $this->default_bin, time() + 3600);
$this
->assertTrue($this
->checkCacheExists('test_cid', $this->default_value), 'Cache item was created successfully.');
cache_set('test_cid_2', $this->default_value, $this->default_bin);
cache_clear_all(MEMCACHE_CONTENT_CLEAR, $this->default_bin);
$this
->assertFalse($this
->checkCacheExists('test_cid', $this->default_value), 'Cache item was cleared successfully.');
$this
->assertTrue($this
->checkCacheExists('test_cid_2', $this->default_value), 'Cache item was not cleared');
unset($_SESSION['cache_flush']);
$this
->assertTrue($this
->checkCacheExists('test_cid', $this->default_value), 'Cache item is still returned due to minimum cache lifetime.');
variable_set('cache_content_flush_' . $this->default_bin, 0);
variable_set('cache_lifetime', 1);
cache_set('test_cid_1', $this->default_value, $this->default_bin, time() + 6000);
$this
->assertTrue($this
->checkCacheExists('test_cid', $this->default_value), 'Cache item was created successfully.');
sleep(2);
cache_clear_all(MEMCACHE_CONTENT_CLEAR, $this->default_bin);
$this
->assertFalse($this
->checkCacheExists('test_cid', $this->default_value), 'Cache item is not returned once minimum cache lifetime has expired.');
variable_set('cache_content_flush_' . $this->default_bin, 0);
variable_set('cache_lifetime', 6000);
$this
->resetVariables();
sleep(1);
cache_set('test_cid', $this->default_value, $this->default_bin, time() + 6000);
$this
->assertTrue($this
->checkCacheExists('test_cid', $this->default_value), 'Cache item was created successfully.');
cache_set('test_cid_2', $this->default_value, $this->default_bin);
$this
->assertTrue($this
->checkCacheExists('test_cid_2', $this->default_value), 'Cache item was created successfully.');
cache_clear_all('*', $this->default_bin, TRUE);
$this
->assertFalse($this
->checkCacheExists('test_cid', $this->default_value), 'Cache item was cleared successfully.');
$this
->assertFalse($this
->checkCacheExists('test_cid_2', $this->default_value), 'Cache item was cleared successfully.');
}
function testWildCardOptimizations() {
cache_set('foo:1', $this->default_value, $this->default_bin);
$this
->assertCacheExists(t('Foo cache was set.'), $this->default_value, 'foo:1');
cache_clear_all('foo', $this->default_bin, TRUE);
$this
->assertCacheRemoved(t('Foo cache was invalidated.'), 'foo:1');
cache_set('foobar', $this->default_value, $this->default_bin);
cache_set('foofoo', $this->default_value, $this->default_bin);
$this
->assertCacheExists(t('Foobar cache set.'), $this->default_value, 'foobar');
$this
->assertCacheExists(t('Foofoo cache set.'), $this->default_value, 'foofoo');
cache_clear_all('foobar', $this->default_bin, TRUE);
$this
->assertCacheRemoved(t('Foobar cache invalidated.'), 'foobar');
$this
->assertCacheExists(t('Foofoo cache still valid.'), $this->default_value, 'foofoo');
cache_set('bar:1', $this->default_value, $this->default_bin);
$this
->assertCacheExists(t('Bar cache was set.'), $this->default_value, 'bar:1');
cache_clear_all('bar', $this->default_bin, TRUE);
$this
->assertCacheRemoved(t('Bar cache invalidated.'), 'bar:1');
$this
->assertCacheExists(t('Foofoo cache still valid.'), $this->default_value, 'foofoo');
cache_set('bar:2', $this->default_value, $this->default_bin);
cache_clear_all('ba', $this->default_bin, TRUE);
$this
->assertCacheRemoved(t('Bar:1 cache invalidated.'), 'bar:1');
$this
->assertCacheRemoved(t('Bar:2 cache invalidated.'), 'bar:2');
$this
->assertCacheRemoved(t('Foofoo cache invalidated.'), 'foofoo');
}
function clearCidTest() {
cache_set('test_cid_clear', $this->default_value, $this->default_bin);
$this
->assertCacheExists(t('Cache was set for clearing cid.'), $this->default_value, 'test_cid_clear');
cache_clear_all('test_cid_clear', $this->default_bin);
$this
->assertCacheRemoved(t('Cache was removed after clearing cid.'), 'test_cid_clear');
cache_set('test_cid_clear1', $this->default_value, $this->default_bin);
cache_set('test_cid_clear2', $this->default_value, $this->default_bin);
$this
->assertTrue($this
->checkCacheExists('test_cid_clear1', $this->default_value) && $this
->checkCacheExists('test_cid_clear2', $this->default_value), t('Two caches were created for checking cid "*" with wildcard false.'));
cache_clear_all('*', $this->default_bin);
$this
->assertTrue($this
->checkCacheExists('test_cid_clear1', $this->default_value) && $this
->checkCacheExists('test_cid_clear2', $this->default_value), t('Two caches still exists after clearing cid "*" with wildcard false.'));
}
function clearWildcardPrefixTest() {
$this
->resetVariables();
cache_set('test_cid_clear:1', $this->default_value, $this->default_bin);
cache_set('test_cid_clear:2', $this->default_value, $this->default_bin);
$this
->assertTrue($this
->checkCacheExists('test_cid_clear:1', $this->default_value) && $this
->checkCacheExists('test_cid_clear:2', $this->default_value), t('Two caches were created for checking cid substring with wildcard true.'));
cache_clear_all('test_cid_clear:', $this->default_bin, TRUE);
$this
->assertFalse($this
->checkCacheExists('test_cid_clear:1', $this->default_value) || $this
->checkCacheExists('test_cid_clear:2', $this->default_value), t('Two caches removed after clearing cid substring with wildcard true.'));
cache_set('test_cid_clear:1', $this->default_value, $this->default_bin);
$this
->assertTrue($this
->checkCacheExists('test_cid_clear:1', $this->default_value), 'The cache was created successfully.');
cache_clear_all('test_', $this->default_bin, TRUE);
$this
->assertFalse($this
->checkCacheExists('test_cid_clear:1', $this->default_value), 'The cache was cleared successfully.');
$wildcard = '.wildcard-' . 'test_cid_clear:';
dmemcache_delete($wildcard, $this->default_bin);
$this
->assertFalse($this
->checkCacheExists('test_cid_clear:1', $this->default_value), 'The cache was cleared successfully.');
}
function testClearWildcardOnSeparatePages() {
$random_wildcard = $this
->randomName(2) . ':' . $this
->randomName(3);
$random_key = $random_wildcard . ':' . $this
->randomName(4) . ':' . $this
->randomName(2);
$random_value = $this
->randomName();
$this
->drupalGetAJAX('memcache-test/clear-cache');
$data = $this
->drupalGetAJAX('memcache-test/set/' . $random_key . '/' . $random_value);
$this
->assertTrue(is_array($data), 'Cache has data.');
$this
->assertEqual($random_key, $data['cid'], 'Cache keys match.');
$this
->assertEqual($random_value, $data['data'], 'Cache values match.');
$data = $this
->drupalGetAJAX('memcache-test/get/' . $random_key);
$this
->assertEqual($random_key, $data['cid'], 'Cache keys match.');
$this
->assertEqual($random_value, $data['data'], 'Cache values match.');
$this
->drupalGet('memcache-test/wildcard-clear/' . $random_wildcard);
$data = $this
->drupalGetAJAX('memcache-test/get/' . $random_key);
$this
->assertFalse($data, 'Cache was properly flushed.');
$data = $this
->drupalGetAJAX('memcache-test/set/' . $random_key . '/' . $random_value);
$this
->assertTrue(is_array($data), 'Cache has data.');
$this
->assertEqual($random_key, $data['cid'], 'Cache keys match.');
$this
->assertEqual($random_value, $data['data'], 'Cache values match.');
$data = $this
->drupalGetAJAX('memcache-test/get/' . $random_key);
$this
->assertEqual($random_key, $data['cid'], 'Cache keys match.');
$this
->assertEqual($random_value, $data['data'], 'Cache values match.');
$this
->drupalGet('memcache-test/wildcard-clear/' . $random_wildcard);
$data = $this
->drupalGetAJAX('memcache-test/get/' . $random_key);
$this
->assertFalse($data, 'Cache was properly flushed.');
}
}
class MemCacheRealWorldCase extends DrupalWebTestCase {
public static function getInfo() {
return array(
'name' => 'Real world cache tests',
'description' => 'Test some real world cache scenarios.',
'group' => 'Memcache',
);
}
function setUp() {
parent::setUp('menu');
}
function testMenu() {
$account = $this
->drupalCreateUser(array(
'access administration pages',
'administer blocks',
'administer menu',
'create article content',
));
$this
->drupalLogin($account);
$item = $this
->addMenuLink();
$original_title = $item['link_title'];
$this
->drupalGet('');
$this
->assertText($original_title, 'Menu item displayed in frontend');
for ($i = 0; $i < 3; $i++) {
$edit = array();
$edit['link_title'] = $this
->randomName(16);
$this
->drupalPost("admin/structure/menu/item/{$item['mlid']}/edit", $edit, t('Save'));
if (!$this
->assertResponse(200)) {
break;
}
if (!$this
->drupalGet('admin/structure/menu/manage/' . $item['menu_name'])) {
break;
}
$this
->assertText($edit['link_title'], 'Menu link was edited');
$this
->drupalGet('');
if (!$this
->assertText($edit['link_title'], 'Change is reflected in frontend')) {
break;
}
}
}
function addMenuLink($plid = 0, $link = '<front>', $menu_name = 'main-menu') {
$this
->drupalGet("admin/structure/menu/manage/{$menu_name}/add");
$this
->assertResponse(200);
$title = '!OriginalLink_' . $this
->randomName(16);
$edit = array(
'link_path' => $link,
'link_title' => $title,
'description' => '',
'enabled' => TRUE,
'expanded' => TRUE,
'parent' => $menu_name . ':' . $plid,
'weight' => '0',
);
$this
->drupalPost(NULL, $edit, t('Save'));
$this
->assertResponse(200);
$this
->assertText($title, 'Menu link was added');
$item = db_query('SELECT * FROM {menu_links} WHERE link_title = :title', array(
':title' => $title,
))
->fetchAssoc();
return $item;
}
}
class MemCacheStatisticsTestCase extends MemcacheTestCase {
public static function getInfo() {
return array(
'name' => 'Statistics tests',
'description' => 'Test that statistics are being recorded appropriately.',
'group' => 'Memcache',
);
}
function setUp() {
parent::setUp('memcache_admin');
$conf['cache_default_class'] = 'MemCacheDrupal';
$conf['cache_class_cache_form'] = 'DrupalDatabaseCache';
}
function testBootstrapStatistics() {
global $_memcache_statistics;
$test_full_key = dmemcache_key($this->default_cid, $this->default_bin);
$expected_statistic_set[] = array(
'set',
$this->default_bin,
$test_full_key,
'',
);
$expected_statistic_get[] = array(
'get',
$this->default_bin,
$test_full_key,
1,
);
$cache_bootstrap_cids = array(
'variables',
'bootstrap_modules',
'lookup_cache',
'system_list',
'module_implements',
);
variable_set('show_memcache_statistics', TRUE);
drupal_static_reset('dmemcache_collect_stats');
$this
->drupalGet('<front>');
$this
->assertNoRaw('<div id="memcache-devel">', 'Statistics not present.');
$account = $this
->drupalCreateUser();
$this
->drupalLogin($account);
$this
->assertNoRaw('<div id="memcache-devel">', 'Statistics not present.');
$account = $this
->drupalCreateUser(array(
'access memcache statistics',
));
$this
->drupalLogin($account);
$this
->drupalGet('<front>');
foreach ($cache_bootstrap_cids as $stat) {
$key = $GLOBALS['drupal_test_info']['test_run_id'] . 'cache_bootstrap-' . $stat;
$this
->assertRaw("<td>get</td><td>cache_bootstrap</td><td>{$key}</td>", t('Key @key found.', array(
'@key' => $key,
)));
}
foreach ($cache_bootstrap_cids as $stat) {
_cache_get_object('cache_bootstrap')
->clear($stat);
}
$this
->drupalGet('<front>');
foreach ($cache_bootstrap_cids as $stat) {
$key = $GLOBALS['drupal_test_info']['test_run_id'] . 'cache_bootstrap-' . $stat;
$this
->assertRaw("<td>get</td><td>cache_bootstrap</td><td>{$key}</td>", t('Key @key found (get).', array(
'@key' => $key,
)));
$this
->assertRaw("<td>set</td><td>cache_bootstrap</td><td>{$key}</td>", t('Key @key found (set).', array(
'@key' => $key,
)));
}
$_memcache_statistics = array();
cache_set($this->default_cid, $this->default_value, $this->default_bin);
$this
->assertEqual($_memcache_statistics, $expected_statistic_set);
$_memcache_statistics = array();
cache_get($this->default_cid, $this->default_bin);
$this
->assertEqual($_memcache_statistics, $expected_statistic_get);
variable_set('show_memcache_statistics', FALSE);
drupal_static_reset('dmemcache_collect_stats');
$this
->drupalGet('<front>');
$this
->assertNoRaw('<div id="memcache-devel">', 'Statistics not present.');
$_memcache_statistics = array();
cache_set($this->default_cid, $this->default_value, $this->default_bin);
$this
->assertEqual($_memcache_statistics, array());
$_memcache_statistics = array();
cache_get($this->default_cid, $this->default_bin);
$this
->assertEqual($_memcache_statistics, array());
}
}