cms/drupal/modules/simpletest/tests/upgrade/upgrade.test
changeset 541 e756a8c72c3d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/cms/drupal/modules/simpletest/tests/upgrade/upgrade.test	Fri Sep 08 12:04:06 2017 +0200
@@ -0,0 +1,737 @@
+<?php
+
+/**
+ * Perform end-to-end tests of the upgrade path.
+ */
+abstract class UpgradePathTestCase extends DrupalWebTestCase {
+
+  /**
+   * The file path(s) to the dumped database(s) to load into the child site.
+   *
+   * @var array
+   */
+  var $databaseDumpFiles = array();
+
+  /**
+   * Flag that indicates whether the child site has been upgraded.
+   */
+  var $upgradedSite = FALSE;
+
+  /**
+   * Array of errors triggered during the upgrade process.
+   */
+  var $upgradeErrors = array();
+
+  /**
+   * Array of modules loaded when the test starts.
+   */
+  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);
+  }
+
+  /**
+   * Overrides DrupalWebTestCase::setUp() for upgrade testing.
+   *
+   * @see DrupalWebTestCase::prepareDatabasePrefix()
+   * @see DrupalWebTestCase::changeDatabasePrefix()
+   * @see DrupalWebTestCase::prepareEnvironment()
+   */
+  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.
+    require_once DRUPAL_ROOT . '/includes/update.inc';
+
+    // Reset flags.
+    $this->upgradedSite = FALSE;
+    $this->upgradeErrors = array();
+
+    $this->loadedModules = module_list();
+
+    // Create the database prefix for this test.
+    $this->prepareDatabasePrefix();
+
+    // Prepare the environment for running tests.
+    $this->prepareEnvironment();
+    if (!$this->setupEnvironment) {
+      return FALSE;
+    }
+
+    // Reset all statics and variables to perform tests in a clean environment.
+    $conf = array();
+    drupal_static_reset();
+
+    // Change the database prefix.
+    // All static variables need to be reset before the database prefix is
+    // changed, since DrupalCacheArray implementations attempt to
+    // write back to persistent caches when they are destructed.
+    $this->changeDatabasePrefix();
+    if (!$this->setupDatabasePrefix) {
+      return FALSE;
+    }
+
+    // Unregister the registry.
+    // This is required to make sure that the database layer works properly.
+    spl_autoload_unregister('drupal_autoload_class');
+    spl_autoload_unregister('drupal_autoload_interface');
+
+    // 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;
+    }
+
+    // Set path variables.
+    $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.');
+
+    // Ensure that the session is not written to the new environment and replace
+    // the global $user session with uid 1 from the new test site.
+    drupal_save_session(FALSE);
+    // Login as uid 1.
+    $user = db_query('SELECT * FROM {users} WHERE uid = :uid', array(':uid' => 1))->fetchObject();
+
+    // Generate and set a D6-compatible session cookie.
+    $this->prepareD7Session();
+
+    // Restore necessary variables.
+    $this->variable_set('clean_url', $this->originalCleanUrl);
+    $this->variable_set('site_mail', 'simpletest@example.com');
+
+    drupal_set_time_limit($this->timeLimit);
+    $this->setup = TRUE;
+  }
+
+  /**
+   * Specialized variable_set() that works even if the child site is not upgraded.
+   *
+   * @param $name
+   *   The name of the variable to set.
+   * @param $value
+   *   The value to set. This can be any PHP data type; these functions take care
+   *   of serialization as necessary.
+   */
+  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');
+    }
+    // Since cache_bootstrap won't exist in a Drupal 6 site, ignore the
+    // exception if the above fails.
+    catch (Exception $e) {}
+  }
+
+  /**
+   * Specialized refreshVariables().
+   */
+  protected function refreshVariables() {
+    // No operation if the child has not been upgraded yet.
+    if (!$this->upgradedSite) {
+      return parent::refreshVariables();
+    }
+  }
+
+  /**
+   * Perform the upgrade.
+   *
+   * @param $register_errors
+   *   Register the errors during the upgrade process as failures.
+   * @return
+   *   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.
+    $this->drupalGet($update_url, array('external' => TRUE));
+    if (!$this->assertResponse(200)) {
+      return FALSE;
+    }
+
+    // Continue.
+    $this->drupalPost(NULL, array(), t('Continue'));
+    if (!$this->assertResponse(200)) {
+      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)) {
+      return FALSE;
+    }
+
+    // Check for errors during the update process.
+    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)) {
+      // Upgrade failed, the installation might be in an inconsistent state,
+      // don't process.
+      return FALSE;
+    }
+
+    // Check if there still are pending updates.
+    $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;
+    }
+
+    // Upgrade succeed, rebuild the environment so that we can call the API
+    // of the child site directly from this request.
+    $this->upgradedSite = TRUE;
+
+    // Reload module list. For modules that are enabled in the test database,
+    // but not on the test client, we need to load the code here.
+    $new_modules = array_diff(module_list(TRUE), $this->loadedModules);
+    foreach ($new_modules as $module) {
+      drupal_load('module', $module);
+    }
+
+    // Reload hook implementations
+    module_implements('', FALSE, TRUE);
+
+    // Rebuild caches.
+    drupal_static_reset();
+    drupal_flush_all_caches();
+
+    // Reload global $conf array and permissions.
+    $this->refreshVariables();
+    $this->checkPermissions(array(), TRUE);
+
+    return TRUE;
+  }
+
+  /**
+   * Force uninstall all modules from a test database, except those listed.
+   *
+   * @param $modules
+   *   The list of modules to keep installed. Required core modules will
+   *   always be kept.
+   */
+  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();
+  }
+
+}
+
+/**
+ * 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.
+ *
+ * The install only contains dblog (although it's optional, it's only so that
+ * another hook_watchdog module can take its place, the site is not functional
+ * without watchdog) and update.
+ */
+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() {
+    // Path to the database dump files.
+    $this->databaseDumpFiles = array(
+      drupal_get_path('module', 'simpletest') . '/tests/upgrade/drupal-6.bare.database.php',
+    );
+    parent::setUp();
+  }
+
+  /**
+   * Test a failed upgrade, and verify that the failure is reported.
+   */
+  public function testFailedUpgrade() {
+    // Destroy a table that the upgrade process needs.
+    db_drop_table('access');
+    // Assert that the upgrade fails.
+    $this->assertFalse($this->performUpgrade(FALSE) && $this->pendingUpdates, 'A failed upgrade should return messages.');
+  }
+
+  /**
+   * Test a successful upgrade.
+   */
+  public function testBasicUpgrade() {
+    $this->assertTrue($this->performUpgrade(), '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)), '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 6', '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, 'No {menu_links} entry exists for user/autocomplete');
+
+    // Test that the environment after the upgrade is in a consistent status.
+    $update_d6 = variable_get('update_d6', FALSE);
+    $this->assertFalse($update_d6, '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(), '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)), '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', '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, '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(), '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)), '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', '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, 'No {menu_links} entry exists for user/autocomplete');
+
+    // Confirm that a date format that just differs in the case can be added.
+    $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'));
+
+    // Add a new date format which just differs in the case.
+    $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.'));
+
+    // Verify that the unique key on {date_formats}.format still exists.
+    $this->assertTrue(db_index_exists('date_formats', 'formats'), 'Unique key on {date_formats} exists');
+  }
+}
+
+/**
+ * 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(), '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)), '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', '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, '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(), '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)), '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', '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, 'No {menu_links} entry exists for user/autocomplete');
+  }
+}