<?php
abstract class UpgradePathTestCase extends DrupalWebTestCase {
var $databaseDumpFiles = array();
var $upgradedSite = FALSE;
var $upgradeErrors = array();
var $loadedModules = array();
var $zlibInstalled = TRUE;
var $pendingUpdates = TRUE;
function __construct($test_id = NULL) {
parent::__construct($test_id);
$this->zlibInstalled = function_exists('gzopen');
}
protected function prepareD7Session() {
$this
->curlInitialize();
$sid = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55));
$session_name = update_get_d6_session_name();
curl_setopt($this->curlHandle, CURLOPT_COOKIE, rawurlencode($session_name) . '=' . rawurlencode($sid));
drupal_save_session(TRUE);
db_add_field('sessions', 'ssid', array(
'description' => "Secure session ID. The value is generated by Drupal's session handlers.",
'type' => 'varchar',
'length' => 128,
'not null' => TRUE,
'default' => '',
));
_drupal_session_write($sid, '');
db_drop_field('sessions', 'ssid');
drupal_save_session(FALSE);
}
protected function setUp() {
if (!$this->zlibInstalled) {
parent::setUp();
return;
}
global $user, $language, $conf;
require_once DRUPAL_ROOT . '/includes/update.inc';
$this->upgradedSite = FALSE;
$this->upgradeErrors = array();
$this->loadedModules = module_list();
$this
->prepareDatabasePrefix();
$this
->prepareEnvironment();
if (!$this->setupEnvironment) {
return FALSE;
}
$conf = array();
drupal_static_reset();
$this
->changeDatabasePrefix();
if (!$this->setupDatabasePrefix) {
return FALSE;
}
spl_autoload_unregister('drupal_autoload_class');
spl_autoload_unregister('drupal_autoload_interface');
foreach ($this->databaseDumpFiles as $file) {
if (substr($file, -3) == '.gz') {
$file = "compress.zlib://{$file}";
}
require $file;
}
$this
->variable_set('file_public_path', $this->public_files_directory);
$this
->variable_set('file_private_path', $this->private_files_directory);
$this
->variable_set('file_temporary_path', $this->temp_files_directory);
$this
->pass('Finished loading the dump.');
drupal_save_session(FALSE);
$user = db_query('SELECT * FROM {users} WHERE uid = :uid', array(
':uid' => 1,
))
->fetchObject();
$this
->prepareD7Session();
$this
->variable_set('clean_url', $this->originalCleanUrl);
$this
->variable_set('site_mail', 'simpletest@example.com');
drupal_set_time_limit($this->timeLimit);
$this->setup = TRUE;
}
protected function variable_set($name, $value) {
db_delete('variable')
->condition('name', $name)
->execute();
db_insert('variable')
->fields(array(
'name' => $name,
'value' => serialize($value),
))
->execute();
try {
cache_clear_all('variables', 'cache');
cache_clear_all('variables', 'cache_bootstrap');
} catch (Exception $e) {
}
}
protected function refreshVariables() {
if (!$this->upgradedSite) {
return parent::refreshVariables();
}
}
protected function performUpgrade($register_errors = TRUE) {
if (!$this->zlibInstalled) {
$this
->fail(t('Missing zlib requirement for upgrade tests.'));
return FALSE;
}
$update_url = $GLOBALS['base_url'] . '/update.php';
$this
->drupalGet($update_url, array(
'external' => TRUE,
));
if (!$this
->assertResponse(200)) {
return FALSE;
}
$this
->drupalPost(NULL, array(), t('Continue'));
if (!$this
->assertResponse(200)) {
return FALSE;
}
$content = $this
->drupalGetContent();
if (strpos($content, t('No pending updates.')) !== FALSE) {
$this
->pass(t('No pending updates and therefore no upgrade process to test.'));
$this->pendingUpdates = FALSE;
return TRUE;
}
$this
->drupalPost(NULL, array(), t('Apply pending updates'));
if (!$this
->assertResponse(200)) {
return FALSE;
}
foreach ($this
->xpath('//li[@class=:class]', array(
':class' => 'failure',
)) as $element) {
$message = strip_tags($element
->asXML());
$this->upgradeErrors[] = $message;
if ($register_errors) {
$this
->fail($message);
}
}
if (!empty($this->upgradeErrors)) {
return FALSE;
}
$this
->drupalGet($update_url, array(
'external' => TRUE,
));
$this
->drupalPost(NULL, array(), t('Continue'));
if (!$this
->assertText(t('No pending updates.'), 'No pending updates at the end of the update process.')) {
return FALSE;
}
$this->upgradedSite = TRUE;
$new_modules = array_diff(module_list(TRUE), $this->loadedModules);
foreach ($new_modules as $module) {
drupal_load('module', $module);
}
module_implements('', FALSE, TRUE);
drupal_static_reset();
drupal_flush_all_caches();
$this
->refreshVariables();
$this
->checkPermissions(array(), TRUE);
return TRUE;
}
protected function uninstallModulesExcept(array $modules) {
$required_modules = array(
'block',
'dblog',
'filter',
'node',
'system',
'update',
'user',
);
$modules = array_merge($required_modules, $modules);
db_delete('system')
->condition('type', 'module')
->condition('name', $modules, 'NOT IN')
->execute();
}
}
abstract class UpdatePathTestCase extends UpgradePathTestCase {
protected function prepareD7Session() {
$this
->curlInitialize();
$sid = drupal_hash_base64(uniqid(mt_rand(), TRUE) . drupal_random_bytes(55));
curl_setopt($this->curlHandle, CURLOPT_COOKIE, rawurlencode(session_name()) . '=' . rawurlencode($sid));
drupal_save_session(TRUE);
_drupal_session_write($sid, '');
drupal_save_session(FALSE);
}
}
class BasicUpgradePath extends UpgradePathTestCase {
public static function getInfo() {
return array(
'name' => 'Basic upgrade path',
'description' => 'Basic upgrade path tests.',
'group' => 'Upgrade path',
);
}
public function setUp() {
$this->databaseDumpFiles = array(
drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-6.bare.database.php',
);
parent::setUp();
}
public function testFailedUpgrade() {
db_drop_table('access');
$this
->assertFalse($this
->performUpgrade(FALSE) && $this->pendingUpdates, 'A failed upgrade should return messages.');
}
public function testBasicUpgrade() {
$this
->assertTrue($this
->performUpgrade(), 'The upgrade was completed successfully.');
$this
->drupalGet('');
$this
->assertResponse(200);
$this
->drupalGet('user');
$this
->clickLink(t('Edit'));
$this
->assertEqual($this
->getUrl(), url('user/1/edit', array(
'absolute' => TRUE,
)), 'We are still logged in as admin at the end of the upgrade.');
$this
->drupalLogout();
$this
->drupalLogin((object) array(
'uid' => 1,
'name' => 'admin',
'pass_raw' => 'admin',
));
$this
->drupalLogout();
$this
->drupalLogin((object) array(
'uid' => 1,
'name' => 'admin',
'pass_raw' => 'admin',
));
$this
->assertText('Drupal 6', 'The site name is correctly displayed.');
$this
->drupalGet('admin');
$this
->assertText(t('Content'));
$this
->assertText(t('Appearance'));
$this
->assertText(t('People'));
$this
->assertText(t('Configuration'));
$this
->assertText(t('Reports'));
$this
->assertText(t('Structure'));
$this
->assertText(t('Modules'));
$result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(
':user_autocomplete' => 'user/autocomplete',
))
->fetchField();
$this
->assertFalse($result, 'No {menu_links} entry exists for user/autocomplete');
$update_d6 = variable_get('update_d6', FALSE);
$this
->assertFalse($update_d6, 'The D6 upgrade flag variable has been correctly disabled.');
}
}
class BasicStandardUpdatePath extends UpdatePathTestCase {
public static function getInfo() {
return array(
'name' => 'Basic standard + all profile update path',
'description' => 'Basic update path tests for a standard profile install with all enabled modules.',
'group' => 'Upgrade path',
);
}
public function setUp() {
$this->databaseDumpFiles = array(
drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.bare.standard_all.database.php.gz',
);
parent::setUp();
}
public function testBasicStandardUpdate() {
$this
->assertTrue($this
->performUpgrade(), 'The upgrade was completed successfully.');
$this
->drupalGet('');
$this
->assertResponse(200);
$this
->drupalGet('user');
$this
->clickLink(t('Edit'));
$this
->assertEqual($this
->getUrl(), url('user/1/edit', array(
'absolute' => TRUE,
)), 'We are still logged in as admin at the end of the upgrade.');
$this
->drupalLogout();
$this
->drupalLogin((object) array(
'uid' => 1,
'name' => 'admin',
'pass_raw' => 'admin',
));
$this
->drupalLogout();
$this
->drupalLogin((object) array(
'uid' => 1,
'name' => 'admin',
'pass_raw' => 'admin',
));
$this
->assertText('Drupal', 'The site name is correctly displayed.');
$this
->drupalGet('admin');
$this
->assertText(t('Content'));
$this
->assertText(t('Appearance'));
$this
->assertText(t('People'));
$this
->assertText(t('Configuration'));
$this
->assertText(t('Reports'));
$this
->assertText(t('Structure'));
$this
->assertText(t('Modules'));
$result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(
':user_autocomplete' => 'user/autocomplete',
))
->fetchField();
$this
->assertFalse($result, 'No {menu_links} entry exists for user/autocomplete');
}
}
class BasicMinimalUpdatePath extends UpdatePathTestCase {
public static function getInfo() {
return array(
'name' => 'Basic minimal profile update path',
'description' => 'Basic update path tests for a minimal profile install.',
'group' => 'Upgrade path',
);
}
public function setUp() {
$this->databaseDumpFiles = array(
drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.bare.minimal.database.php.gz',
);
parent::setUp();
}
public function testBasicMinimalUpdate() {
$this
->assertTrue($this
->performUpgrade(), 'The upgrade was completed successfully.');
$this
->drupalGet('');
$this
->assertResponse(200);
$this
->drupalGet('user');
$this
->clickLink(t('Edit'));
$this
->assertEqual($this
->getUrl(), url('user/1/edit', array(
'absolute' => TRUE,
)), 'We are still logged in as admin at the end of the upgrade.');
$this
->drupalLogout();
$this
->drupalLogin((object) array(
'uid' => 1,
'name' => 'admin',
'pass_raw' => 'admin',
));
$this
->drupalLogout();
$this
->drupalLogin((object) array(
'uid' => 1,
'name' => 'admin',
'pass_raw' => 'admin',
));
$this
->assertText('Drupal', 'The site name is correctly displayed.');
$this
->drupalGet('admin');
$this
->assertText(t('Content'));
$this
->assertText(t('Appearance'));
$this
->assertText(t('People'));
$this
->assertText(t('Configuration'));
$this
->assertText(t('Reports'));
$this
->assertText(t('Structure'));
$this
->assertText(t('Modules'));
$result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(
':user_autocomplete' => 'user/autocomplete',
))
->fetchField();
$this
->assertFalse($result, 'No {menu_links} entry exists for user/autocomplete');
$admin_date_format = 'j M y';
$edit = array(
'date_format' => $admin_date_format,
);
$this
->drupalPost('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
$admin_date_format_uppercase = 'j M Y';
$edit = array(
'date_format' => $admin_date_format_uppercase,
);
$this
->drupalPost('admin/config/regional/date-time/formats/add', $edit, t('Add format'));
$this
->assertText(t('Custom date format added.'));
$this
->assertTrue(db_index_exists('date_formats', 'formats'), 'Unique key on {date_formats} exists');
}
}
class FilledStandardUpdatePath extends UpdatePathTestCase {
public static function getInfo() {
return array(
'name' => 'Basic standard + all profile update path, populated database',
'description' => 'Basic update path tests for a standard profile install with all enabled modules and a populated database.',
'group' => 'Upgrade path',
);
}
public function setUp() {
$this->databaseDumpFiles = array(
drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.filled.standard_all.database.php.gz',
);
parent::setUp();
}
public function testFilledStandardUpdate() {
$this
->assertTrue($this
->performUpgrade(), 'The upgrade was completed successfully.');
$this
->drupalGet('');
$this
->assertResponse(200);
$this
->drupalGet('user');
$this
->clickLink(t('Edit'));
$this
->assertEqual($this
->getUrl(), url('user/1/edit', array(
'absolute' => TRUE,
)), 'We are still logged in as admin at the end of the upgrade.');
$this
->drupalLogout();
$this
->drupalLogin((object) array(
'uid' => 1,
'name' => 'admin',
'pass_raw' => 'admin',
));
$this
->drupalLogout();
$this
->drupalLogin((object) array(
'uid' => 1,
'name' => 'admin',
'pass_raw' => 'admin',
));
$this
->assertText('Drupal', 'The site name is correctly displayed.');
$this
->drupalGet('admin');
$this
->assertText(t('Content'));
$this
->assertText(t('Appearance'));
$this
->assertText(t('People'));
$this
->assertText(t('Configuration'));
$this
->assertText(t('Reports'));
$this
->assertText(t('Structure'));
$this
->assertText(t('Modules'));
$result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(
':user_autocomplete' => 'user/autocomplete',
))
->fetchField();
$this
->assertFalse($result, 'No {menu_links} entry exists for user/autocomplete');
}
}
class FilledMinimalUpdatePath extends UpdatePathTestCase {
public static function getInfo() {
return array(
'name' => 'Basic minimal profile update path, populated database',
'description' => 'Basic update path tests for a minimal profile install with a populated database.',
'group' => 'Upgrade path',
);
}
public function setUp() {
$this->databaseDumpFiles = array(
drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.filled.minimal.database.php.gz',
);
parent::setUp();
}
public function testFilledStandardUpdate() {
$this
->assertTrue($this
->performUpgrade(), 'The upgrade was completed successfully.');
$this
->drupalGet('');
$this
->assertResponse(200);
$this
->drupalGet('user');
$this
->clickLink(t('Edit'));
$this
->assertEqual($this
->getUrl(), url('user/1/edit', array(
'absolute' => TRUE,
)), 'We are still logged in as admin at the end of the upgrade.');
$this
->drupalLogout();
$this
->drupalLogin((object) array(
'uid' => 1,
'name' => 'admin',
'pass_raw' => 'admin',
));
$this
->drupalLogout();
$this
->drupalLogin((object) array(
'uid' => 1,
'name' => 'admin',
'pass_raw' => 'admin',
));
$this
->assertText('Drupal', 'The site name is correctly displayed.');
$this
->drupalGet('admin');
$this
->assertText(t('Content'));
$this
->assertText(t('Appearance'));
$this
->assertText(t('People'));
$this
->assertText(t('Configuration'));
$this
->assertText(t('Reports'));
$this
->assertText(t('Structure'));
$this
->assertText(t('Modules'));
$result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(
':user_autocomplete' => 'user/autocomplete',
))
->fetchField();
$this
->assertFalse($result, 'No {menu_links} entry exists for user/autocomplete');
}
}