diff options
Diffstat (limited to 'modules/simpletest/tests/upgrade/upgrade.test')
-rw-r--r-- | modules/simpletest/tests/upgrade/upgrade.test | 416 |
1 files changed, 401 insertions, 15 deletions
diff --git a/modules/simpletest/tests/upgrade/upgrade.test b/modules/simpletest/tests/upgrade/upgrade.test index 7f934fe7b..01e1806cd 100644 --- a/modules/simpletest/tests/upgrade/upgrade.test +++ b/modules/simpletest/tests/upgrade/upgrade.test @@ -28,9 +28,60 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase { var $loadedModules = array(); /** + * Flag to indicate whether zlib is installed or not. + */ + var $zlibInstalled = TRUE; + + /** + * Flag to indicate whether there are pending updates or not. + */ + var $pendingUpdates = TRUE; + + /** + * Constructs an UpgradePathTestCase object. + * + * @param $test_id + * (optional) The ID of the test. Tests with the same id are reported + * together. + */ + function __construct($test_id = NULL) { + parent::__construct($test_id); + $this->zlibInstalled = function_exists('gzopen'); + } + + /** + * Prepares the appropriate session for the release of Drupal being upgraded. + */ + protected function prepareD7Session() { + // Generate and set a D6-compatible session cookie. + $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)); + + // Force our way into the session of the child site. + drupal_save_session(TRUE); + // A session cannot be written without the ssid column which is missing on + // Drupal 6 sites. + 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, ''); + // Remove the temporarily added ssid column. + db_drop_field('sessions', 'ssid'); + drupal_save_session(FALSE); + } + + /** * Override of DrupalWebTestCase::setUp() specialized for upgrade testing. */ protected function setUp() { + // We are going to set a missing zlib requirement property for usage + // during the performUpgrade() and tearDown() methods. Also set that the + // tests failed. + if (!$this->zlibInstalled) { + parent::setUp(); + return; + } + global $user, $language, $conf; // Load the Update API. @@ -92,7 +143,11 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase { $conf = array(); // Load the database from the portable PHP dump. + // The files may be gzipped. foreach ($this->databaseDumpFiles as $file) { + if (substr($file, -3) == '.gz') { + $file = "compress.zlib://$file"; + } require $file; } @@ -109,20 +164,7 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase { $user = db_query('SELECT * FROM {users} WHERE uid = :uid', array(':uid' => 1))->fetchObject(); // Generate and set a D6-compatible session cookie. - $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)); - - // Force our way into the session of the child site. - drupal_save_session(TRUE); - // A session cannot be written without the ssid column which is missing on - // Drupal 6 sites. - 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, ''); - // Remove the temporarily added ssid column. - db_drop_field('sessions', 'ssid'); - drupal_save_session(FALSE); + $this->prepareD7Session(); // Restore necessary variables. $this->variable_set('clean_url', $clean_url_original); @@ -137,6 +179,11 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase { protected function tearDown() { global $user, $language; + if (!$this->zlibInstalled) { + parent::tearDown(); + return; + } + // In case a fatal error occurred that was not in the test process read the // log to pick up any fatal errors. simpletest_log_read($this->testId, $this->databasePrefix, get_class($this), TRUE); @@ -231,6 +278,11 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase { * TRUE if the upgrade succeeded, FALSE otherwise. */ 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'; // Load the first update screen. @@ -245,6 +297,14 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase { return FALSE; } + // The test should pass if there are no pending updates. + $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; + } + // Go! $this->drupalPost(NULL, array(), t('Apply pending updates')); if (!$this->assertResponse(200)) { @@ -319,6 +379,26 @@ abstract class UpgradePathTestCase extends DrupalWebTestCase { } /** + * Performs end-to-end point test of the release update path. + */ +abstract class UpdatePathTestCase extends UpgradePathTestCase { + /** + * Overrides UpgradePathTestCase::prepareD7Session(). + */ + protected function prepareD7Session() { + // Generate and set a D7-compatible session cookie. + $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)); + + // Force our way into the session of the child site. + drupal_save_session(TRUE); + _drupal_session_write($sid, ''); + drupal_save_session(FALSE); + } +} + +/** * Perform basic upgrade tests. * * Load a bare installation of Drupal 6 and run the upgrade process on it. @@ -351,7 +431,7 @@ class BasicUpgradePath extends UpgradePathTestCase { // Destroy a table that the upgrade process needs. db_drop_table('access'); // Assert that the upgrade fails. - $this->assertFalse($this->performUpgrade(FALSE), t('A failed upgrade should return messages.')); + $this->assertFalse($this->performUpgrade(FALSE) && $this->pendingUpdates, t('A failed upgrade should return messages.')); } /** @@ -408,3 +488,309 @@ class BasicUpgradePath extends UpgradePathTestCase { $this->assertFalse($update_d6, t('The D6 upgrade flag variable has been correctly disabled.')); } } + +/** + * Performs point release update tests on a bare database. + * + * Loads an installation of Drupal 7.0 and runs the update process on it. + * + * The install contains the standard profile (plus all optional) modules + * without any content so that an update from any of the modules under this + * profile installation can be wholly tested. + */ +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() { + // Path to the database dump files. + $this->databaseDumpFiles = array( + drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.bare.standard_all.database.php.gz', + ); + parent::setUp(); + } + + /** + * Tests a successful point release update. + */ + public function testBasicStandardUpdate() { + $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.')); + + // Hit the frontpage. + $this->drupalGet(''); + $this->assertResponse(200); + + // Verify that we are still logged in. + $this->drupalGet('user'); + $this->clickLink(t('Edit')); + $this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), t('We are still logged in as admin at the end of the upgrade.')); + + // Logout and verify that we can login back in with our initial password. + $this->drupalLogout(); + $this->drupalLogin((object) array( + 'uid' => 1, + 'name' => 'admin', + 'pass_raw' => 'admin', + )); + + // The previous login should've triggered a password rehash, so login one + // more time to make sure the new hash is readable. + $this->drupalLogout(); + $this->drupalLogin((object) array( + 'uid' => 1, + 'name' => 'admin', + 'pass_raw' => 'admin', + )); + + // Test that the site name is correctly displayed. + $this->assertText('drupal', t('The site name is correctly displayed.')); + + // Verify that the main admin sections are available. + $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')); + + // Confirm that no {menu_links} entry exists for user/autocomplete. + $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField(); + $this->assertFalse($result, t('No {menu_links} entry exists for user/autocomplete')); + } +} + +/** + * Performs point release update tests on a bare database. + * + * Loads an installation of Drupal 7.0 and runs the update process on it. + * + * The install contains the minimal profile modules (without any generated + * content) so that an update from of a site under this profile may be tested. + */ +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() { + // Path to the database dump files. + $this->databaseDumpFiles = array( + drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.bare.minimal.database.php.gz', + ); + parent::setUp(); + } + + /** + * Tests a successful point release update. + */ + public function testBasicMinimalUpdate() { + $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.')); + + // Hit the frontpage. + $this->drupalGet(''); + $this->assertResponse(200); + + // Verify that we are still logged in. + $this->drupalGet('user'); + $this->clickLink(t('Edit')); + $this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), t('We are still logged in as admin at the end of the upgrade.')); + + // Logout and verify that we can login back in with our initial password. + $this->drupalLogout(); + $this->drupalLogin((object) array( + 'uid' => 1, + 'name' => 'admin', + 'pass_raw' => 'admin', + )); + + // The previous login should've triggered a password rehash, so login one + // more time to make sure the new hash is readable. + $this->drupalLogout(); + $this->drupalLogin((object) array( + 'uid' => 1, + 'name' => 'admin', + 'pass_raw' => 'admin', + )); + + // Test that the site name is correctly displayed. + $this->assertText('drupal', t('The site name is correctly displayed.')); + + // Verify that the main admin sections are available. + $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')); + + // Confirm that no {menu_links} entry exists for user/autocomplete. + $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField(); + $this->assertFalse($result, t('No {menu_links} entry exists for user/autocomplete')); + } +} + +/** + * Performs point release update tests on a 'filled' database. + * + * Loads an installation of Drupal 7.0 and runs the update process on it. + * + * The install contains the standard profile (plus all optional) modules + * with generated content so that an update from any of the modules under this + * profile installation can be wholly tested. + */ +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() { + // Path to the database dump files. + $this->databaseDumpFiles = array( + drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.filled.standard_all.database.php.gz', + ); + parent::setUp(); + } + + /** + * Tests a successful point release update. + */ + public function testFilledStandardUpdate() { + $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.')); + + // Hit the frontpage. + $this->drupalGet(''); + $this->assertResponse(200); + + // Verify that we are still logged in. + $this->drupalGet('user'); + $this->clickLink(t('Edit')); + $this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), t('We are still logged in as admin at the end of the upgrade.')); + + // Logout and verify that we can login back in with our initial password. + $this->drupalLogout(); + $this->drupalLogin((object) array( + 'uid' => 1, + 'name' => 'admin', + 'pass_raw' => 'admin', + )); + + // The previous login should've triggered a password rehash, so login one + // more time to make sure the new hash is readable. + $this->drupalLogout(); + $this->drupalLogin((object) array( + 'uid' => 1, + 'name' => 'admin', + 'pass_raw' => 'admin', + )); + + // Test that the site name is correctly displayed. + $this->assertText('drupal', t('The site name is correctly displayed.')); + + // Verify that the main admin sections are available. + $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')); + + // Confirm that no {menu_links} entry exists for user/autocomplete. + $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField(); + $this->assertFalse($result, t('No {menu_links} entry exists for user/autocomplete')); + } +} + +/** + * Performs point release update tests on a populated database. + * + * Loads an installation of Drupal 7.0 and runs the update process on it. + * + * The install contains the minimal profile modules (along with generated + * content) so that an update from of a site under this profile may be tested. + */ +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() { + // Path to the database dump files. + $this->databaseDumpFiles = array( + drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-7.filled.minimal.database.php.gz', + ); + parent::setUp(); + } + + /** + * Tests a successful point release update. + */ + public function testFilledStandardUpdate() { + $this->assertTrue($this->performUpgrade(), t('The upgrade was completed successfully.')); + + // Hit the frontpage. + $this->drupalGet(''); + $this->assertResponse(200); + + // Verify that we are still logged in. + $this->drupalGet('user'); + $this->clickLink(t('Edit')); + $this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), t('We are still logged in as admin at the end of the upgrade.')); + + // Logout and verify that we can login back in with our initial password. + $this->drupalLogout(); + $this->drupalLogin((object) array( + 'uid' => 1, + 'name' => 'admin', + 'pass_raw' => 'admin', + )); + + // The previous login should've triggered a password rehash, so login one + // more time to make sure the new hash is readable. + $this->drupalLogout(); + $this->drupalLogin((object) array( + 'uid' => 1, + 'name' => 'admin', + 'pass_raw' => 'admin', + )); + + // Test that the site name is correctly displayed. + $this->assertText('drupal', t('The site name is correctly displayed.')); + + // Verify that the main admin sections are available. + $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')); + + // Confirm that no {menu_links} entry exists for user/autocomplete. + $result = db_query('SELECT COUNT(*) FROM {menu_links} WHERE link_path = :user_autocomplete', array(':user_autocomplete' => 'user/autocomplete'))->fetchField(); + $this->assertFalse($result, t('No {menu_links} entry exists for user/autocomplete')); + } +} |