class UpdatePathTestBase

Same name in this branch
  1. 8.9.x core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php \Drupal\FunctionalTests\Update\UpdatePathTestBase
Same name and namespace in other branches
  1. 11.x core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php \Drupal\FunctionalTests\Update\UpdatePathTestBase
  2. 10 core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php \Drupal\FunctionalTests\Update\UpdatePathTestBase
  3. 9 core/tests/Drupal/FunctionalTests/Update/UpdatePathTestBase.php \Drupal\FunctionalTests\Update\UpdatePathTestBase

Provides a base class for writing an update test.

To write an update test:

  • Write the hook_update_N() implementations that you are testing.
  • Create one or more database dump files, which will set the database to the "before updates" state. Normally, these will add some configuration data to the database, set up some tables/fields, etc.
  • Create a class that extends this class.
  • In your setUp() method, point the $this->databaseDumpFiles variable to the database dump files, and then call parent::setUp() to run the base setUp() method in this class.
  • In your test method, call $this->runUpdates() to run the necessary updates, and then use test assertions to verify that the result is what you expect.
  • In order to test both with a "bare" database dump as well as with a database dump filled with content, extend your update path test class with a new test class that overrides the bare database dump. Refer to UpdatePathTestBaseFilledTest for an example.

Hierarchy

Expanded class hierarchy of UpdatePathTestBase

Deprecated

in drupal:8.4.0 and is removed from drupal:9.0.0. Use \Drupal\FunctionalTests\Update\UpdatePathTestBase.

See also

https://www.drupal.org/node/2896640

hook_update_N()

Related topics

File

core/modules/system/src/Tests/Update/UpdatePathTestBase.php, line 45

Namespace

Drupal\system\Tests\Update
View source
abstract class UpdatePathTestBase extends WebTestBase {
  use SchemaCheckTestTrait;
  
  /**
   * Modules to enable after the database is loaded.
   */
  protected static $modules = [];
  
  /**
   * The file path(s) to the dumped database(s) to load into the child site.
   *
   * The file system/tests/fixtures/update/drupal-8.bare.standard.php.gz is
   * normally included first -- this sets up the base database from a bare
   * standard Drupal installation.
   *
   * The file system/tests/fixtures/update/drupal-8.filled.standard.php.gz
   * can also be used in case we want to test with a database filled with
   * content, and with all core modules enabled.
   *
   * @var array
   */
  protected $databaseDumpFiles = [];
  
  /**
   * The install profile used in the database dump file.
   *
   * @var string
   */
  protected $installProfile = 'standard';
  
  /**
   * Flag that indicates whether the child site has been updated.
   *
   * @var bool
   */
  protected $upgradedSite = FALSE;
  
  /**
   * Array of errors triggered during the update process.
   *
   * @var array
   */
  protected $upgradeErrors = [];
  
  /**
   * Array of modules loaded when the test starts.
   *
   * @var array
   */
  protected $loadedModules = [];
  
  /**
   * Flag to indicate whether zlib is installed or not.
   *
   * @var bool
   */
  protected $zlibInstalled = TRUE;
  
  /**
   * Flag to indicate whether there are pending updates or not.
   *
   * @var bool
   */
  protected $pendingUpdates = TRUE;
  
  /**
   * The update URL.
   *
   * @var string
   */
  protected $updateUrl;
  
  /**
   * Disable strict config schema checking.
   *
   * The schema is verified at the end of running the update.
   *
   * @var bool
   */
  protected $strictConfigSchema = FALSE;
  
  /**
   * Fail the test if there are failed updates.
   *
   * @var bool
   */
  protected $checkFailedUpdates = TRUE;
  
  /**
   * Constructs an UpdatePathTestCase object.
   *
   * @param $test_id
   *   (optional) The ID of the test. Tests with the same id are reported
   *   together.
   */
  public function __construct($test_id = NULL) {
    parent::__construct($test_id);
    $this->zlibInstalled = function_exists('gzopen');
  }
  
  /**
   * Overrides WebTestBase::setUp() for update testing.
   *
   * The main difference in this method is that rather than performing the
   * installation via the installer, a database is loaded. Additional work is
   * then needed to set various things such as the config directories and the
   * container that would normally be done via the installer.
   */
  protected function setUp() {
    $this->runDbTasks();
    // Allow classes to set database dump files.
    $this->setDatabaseDumpFiles();
    // 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;
    }
    // Set the update url. This must be set here rather than in
    // self::__construct() or the old URL generator will leak additional test
    // sites.
    $this->updateUrl = Url::fromRoute('system.db_update');
    // These methods are called from parent::setUp().
    $this->setBatch();
    $this->initUserSession();
    $this->prepareSettings();
    // Load the database(s).
    foreach ($this->databaseDumpFiles as $file) {
      if (substr($file, -3) == '.gz') {
        $file = "compress.zlib://{$file}";
      }
      require $file;
    }
    $this->initSettings();
    $request = Request::createFromGlobals();
    $container = $this->initKernel($request);
    $this->initConfig($container);
    // Restore the original Simpletest batch.
    $this->restoreBatch();
    // Set the container. parent::rebuildAll() would normally do this, but this
    // not safe to do here, because the database has not been updated yet.
    $this->container = \Drupal::getContainer();
    $this->replaceUser1();
    require_once \Drupal::root() . '/core/includes/update.inc';
  }
  
  /**
   * Set database dump files to be used.
   */
  abstract protected function setDatabaseDumpFiles();
  
  /**
   * Add settings that are missed since the installer isn't run.
   */
  protected function prepareSettings() {
    parent::prepareSettings();
    // Remember the profile which was used.
    $settings['settings']['install_profile'] = (object) [
      'value' => $this->installProfile,
      'required' => TRUE,
    ];
    // Generate a hash salt.
    $settings['settings']['hash_salt'] = (object) [
      'value' => Crypt::randomBytesBase64(55),
      'required' => TRUE,
    ];
    // Since the installer isn't run, add the database settings here too.
    $settings['databases']['default'] = (object) [
      'value' => Database::getConnectionInfo(),
      'required' => TRUE,
    ];
    $this->writeSettings($settings);
  }
  
  /**
   * Helper function to run pending database updates.
   */
  protected function runUpdates() {
    if (!$this->zlibInstalled) {
      $this->fail('Missing zlib requirement for update tests.');
      return FALSE;
    }
    // The site might be broken at the time so logging in using the UI might
    // not work, so we use the API itself.
    drupal_rewrite_settings([
      'settings' => [
        'update_free_access' => (object) [
          'value' => TRUE,
          'required' => TRUE,
        ],
      ],
    ]);
    $this->drupalGet($this->updateUrl);
    $this->clickLink(t('Continue'));
    $this->doSelectionTest();
    // Run the update hooks.
    $this->clickLink(t('Apply pending updates'));
    // Ensure there are no failed updates.
    if ($this->checkFailedUpdates) {
      $this->assertNoRaw('<strong>' . t('Failed:') . '</strong>');
      // Ensure that there are no pending updates.
      foreach ([
        'update',
        'post_update',
      ] as $update_type) {
        switch ($update_type) {
          case 'update':
            $all_updates = update_get_update_list();
            break;

          case 'post_update':
            $all_updates = \Drupal::service('update.post_update_registry')->getPendingUpdateInformation();
            break;

        }
        foreach ($all_updates as $module => $updates) {
          if (!empty($updates['pending'])) {
            foreach (array_keys($updates['pending']) as $update_name) {
              $this->fail("The {$update_name}() update function from the {$module} module did not run.");
            }
          }
        }
      }
      // Reset the static cache of drupal_get_installed_schema_version() so that
      // more complex update path testing works.
      drupal_static_reset('drupal_get_installed_schema_version');
      // The config schema can be incorrect while the update functions are being
      // executed. But once the update has been completed, it needs to be valid
      // again. Assert the schema of all configuration objects now.
      $names = $this->container
        ->get('config.storage')
        ->listAll();
      /** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config */
      $typed_config = $this->container
        ->get('config.typed');
      $typed_config->clearCachedDefinitions();
      foreach ($names as $name) {
        $config = $this->config($name);
        $this->assertConfigSchema($typed_config, $name, $config->get());
      }
      // Ensure that the update hooks updated all entity schema.
      $needs_updates = \Drupal::entityDefinitionUpdateManager()->needsUpdates();
      $this->assertFalse($needs_updates, 'After all updates ran, entity schema is up to date.');
      if ($needs_updates) {
        foreach (\Drupal::entityDefinitionUpdateManager()->getChangeSummary() as $entity_type_id => $summary) {
          foreach ($summary as $message) {
            $this->fail($message);
          }
        }
      }
    }
  }
  
  /**
   * Runs the install database tasks for the driver used by the test runner.
   */
  protected function runDbTasks() {
    // Create a minimal container so that t() works.
    // @see install_begin_request()
    $container = new ContainerBuilder();
    $container->setParameter('language.default_values', Language::$defaultValues);
    $container->register('language.default', 'Drupal\\Core\\Language\\LanguageDefault')
      ->addArgument('%language.default_values%');
    $container->register('string_translation', 'Drupal\\Core\\StringTranslation\\TranslationManager')
      ->addArgument(new Reference('language.default'));
    \Drupal::setContainer($container);
    require_once __DIR__ . '/../../../../../includes/install.inc';
    $connection = Database::getConnection();
    $errors = db_installer_object($connection->driver())
      ->runTasks();
    if (!empty($errors)) {
      $this->fail('Failed to run installer database tasks: ' . implode(', ', $errors));
    }
  }
  
  /**
   * Replace User 1 with the user created here.
   */
  protected function replaceUser1() {
    /** @var \Drupal\user\UserInterface $account */
    // @todo: Saving the account before the update is problematic.
    //   https://www.drupal.org/node/2560237
    $account = User::load(1);
    $account->setPassword($this->rootUser->pass_raw);
    $account->setEmail($this->rootUser
      ->getEmail());
    $account->setUsername($this->rootUser
      ->getAccountName());
    $account->save();
  }
  
  /**
   * Tests the selection page.
   */
  protected function doSelectionTest() {
    // No-op. Tests wishing to do test the selection page or the general
    // update.php environment before running update.php can override this method
    // and implement their required tests.
  }

}

Members

Title Sort descending Deprecated Modifiers Object type Summary Overriden Title Overrides
AssertPageCacheContextsAndTagsTrait::assertCacheContext protected function Asserts whether an expected cache context was present in the last response.
AssertPageCacheContextsAndTagsTrait::assertCacheContexts protected function Ensures that some cache contexts are present in the current response.
AssertPageCacheContextsAndTagsTrait::assertCacheMaxAge protected function Asserts the max age header.
AssertPageCacheContextsAndTagsTrait::assertCacheTags protected function Ensures that some cache tags are present in the current response.
AssertPageCacheContextsAndTagsTrait::assertNoCacheContext protected function Asserts that a cache context was not present in the last response.
AssertPageCacheContextsAndTagsTrait::assertPageCacheContextsAndTags protected function Asserts page cache miss, then hit for the given URL; checks cache headers.
AssertPageCacheContextsAndTagsTrait::debugCacheTags protected function Provides debug information for cache tags.
AssertPageCacheContextsAndTagsTrait::enablePageCaching protected function Enables page caching.
AssertPageCacheContextsAndTagsTrait::getCacheHeaderValues protected function Gets a specific header value as array.
TestBase::$assertions protected property Assertions thrown in that test case.
TestBase::$configImporter protected property The config importer that can used in a test.
TestBase::$databasePrefix protected property The database prefix of this test run.
TestBase::$dieOnFail public property Whether to die in case any test assertion fails.
TestBase::$httpAuthCredentials protected property HTTP authentication credentials (&lt;username&gt;:&lt;password&gt;).
TestBase::$httpAuthMethod protected property HTTP authentication method (specified as a CURLAUTH_* constant).
TestBase::$originalConf protected property The original configuration (variables), if available.
TestBase::$originalConfig protected property The original configuration (variables).
TestBase::$originalConfigDirectories protected property The original configuration directories.
TestBase::$originalContainer protected property The original container.
TestBase::$originalFileDirectory protected property The original file directory, before it was changed for testing purposes.
TestBase::$originalLanguage protected property The original language.
TestBase::$originalPrefix protected property The original database prefix when running inside Simpletest.
TestBase::$originalSessionName protected property The name of the session cookie of the test-runner.
TestBase::$originalSettings protected property The settings array.
TestBase::$results public property Current results of this test case.
TestBase::$skipClasses protected property This class is skipped when looking for the source of an assertion.
TestBase::$timeLimit protected property Time limit for the test.
TestBase::$translationFilesDirectory protected property The translation file directory for the test environment.
TestBase::$verbose public property TRUE if verbose debugging is enabled.
TestBase::$verboseClassName protected property Safe class name for use in verbose output filenames.
TestBase::$verboseDirectory protected property Directory where verbose output files are put.
TestBase::$verboseDirectoryUrl protected property URL to the verbose output file directory.
TestBase::$verboseId protected property Incrementing identifier for verbose output filenames.
TestBase::assert protected function Internal helper: stores the assert.
TestBase::assertEqual protected function Check to see if two values are equal.
TestBase::assertErrorLogged protected function Asserts that a specific error has been logged to the PHP error log.
TestBase::assertFalse protected function Check to see if a value is false.
TestBase::assertIdentical protected function Check to see if two values are identical.
TestBase::assertIdenticalObject protected function Checks to see if two objects are identical.
TestBase::assertNoErrorsLogged protected function Asserts that no errors have been logged to the PHP error.log thus far.
TestBase::assertNotEqual protected function Check to see if two values are not equal.
TestBase::assertNotIdentical protected function Check to see if two values are not identical.
TestBase::assertNotNull protected function Check to see if a value is not NULL.
TestBase::assertNull protected function Check to see if a value is NULL.
TestBase::assertTrue protected function Check to see if a value is not false.
TestBase::beforePrepareEnvironment protected function Act on global state information before the environment is altered for a test. 1
TestBase::checkRequirements protected function Checks the matching requirements for Test. 1
TestBase::checkTestHierarchyMismatch public function Fail the test if it belongs to a PHPUnit-based framework.
TestBase::config protected function Configuration accessor for tests. Returns non-overridden configuration.
TestBase::deleteAssert public static function Delete an assertion record by message ID.
TestBase::error protected function Fire an error assertion. 1
TestBase::errorHandler public function Handle errors during test runs.
TestBase::exceptionHandler protected function Handle exceptions.
TestBase::fail protected function Fire an assertion that is always negative.
TestBase::filePreDeleteCallback public static function Ensures test files are deletable.
TestBase::getAssertionCall protected function Cycles through backtrace until the first non-assertion method is found.
TestBase::getDatabasePrefix public function Gets the database prefix.
TestBase::getTempFilesDirectory public function Gets the temporary files directory.
TestBase::insertAssert Deprecated public static function Store an assertion from outside the testing context. 1
TestBase::pass protected function Fire an assertion that is always positive.
TestBase::prepareDatabasePrefix private function Generates a database prefix for running tests.
TestBase::restoreEnvironment private function Cleans up the test environment and restores the original environment.
TestBase::run public function Run all tests in this class. 2
TestBase::settingsSet protected function Changes in memory settings.
TestBase::storeAssertion protected function Helper method to store an assertion record in the configured database. 1
TestBase::verbose protected function Logs a verbose message in a text file.
UpdatePathTestBase::$checkFailedUpdates protected property Fail the test if there are failed updates.
UpdatePathTestBase::$databaseDumpFiles protected property The file path(s) to the dumped database(s) to load into the child site.
UpdatePathTestBase::$installProfile protected property The install profile used in the database dump file.
UpdatePathTestBase::$loadedModules protected property Array of modules loaded when the test starts.
UpdatePathTestBase::$modules protected static property Modules to enable after the database is loaded.
UpdatePathTestBase::$pendingUpdates protected property Flag to indicate whether there are pending updates or not.
UpdatePathTestBase::$strictConfigSchema protected property Disable strict config schema checking.
UpdatePathTestBase::$updateUrl protected property The update URL.
UpdatePathTestBase::$upgradedSite protected property Flag that indicates whether the child site has been updated.
UpdatePathTestBase::$upgradeErrors protected property Array of errors triggered during the update process.
UpdatePathTestBase::$zlibInstalled protected property Flag to indicate whether zlib is installed or not.
UpdatePathTestBase::doSelectionTest protected function Tests the selection page.
UpdatePathTestBase::prepareSettings protected function Add settings that are missed since the installer isn&#039;t run.
UpdatePathTestBase::replaceUser1 protected function Replace User 1 with the user created here.
UpdatePathTestBase::runDbTasks protected function Runs the install database tasks for the driver used by the test runner.
UpdatePathTestBase::runUpdates protected function Helper function to run pending database updates.
UpdatePathTestBase::setDatabaseDumpFiles abstract protected function Set database dump files to be used.
UpdatePathTestBase::setUp protected function Overrides WebTestBase::setUp() for update testing. Overrides WebTestBase::setUp
UpdatePathTestBase::__construct public function Constructs an UpdatePathTestCase object. Overrides WebTestBase::__construct
WebTestBase::$additionalCurlOptions protected property Additional cURL options.
WebTestBase::$assertAjaxHeader protected property Whether or not to assert the presence of the X-Drupal-Ajax-Token.
WebTestBase::$cookieFile protected property The current cookie file used by cURL.
WebTestBase::$cookies protected property The cookies of the page currently loaded in the internal browser.
WebTestBase::$curlCookies protected property Cookies to set on curl requests.
WebTestBase::$curlHandle protected property The handle of the current cURL connection.
WebTestBase::$customTranslations protected property An array of custom translations suitable for drupal_rewrite_settings().
WebTestBase::$dumpHeaders protected property Indicates that headers should be dumped if verbose output is enabled. 1
WebTestBase::$headers protected property The headers of the page currently loaded in the internal browser.
WebTestBase::$loggedInUser protected property The current user logged in using the internal browser.
WebTestBase::$maximumMetaRefreshCount protected property The number of meta refresh redirects to follow, or NULL if unlimited.
WebTestBase::$maximumRedirects protected property The maximum number of redirects to follow when handling responses.
WebTestBase::$metaRefreshCount protected property The number of meta refresh redirects followed during ::drupalGet().
WebTestBase::$originalBatch protected property The original batch, before it was changed for testing purposes.
WebTestBase::$originalShutdownCallbacks protected property The original shutdown handlers array, before it was cleaned for testing. Overrides TestBase::$originalShutdownCallbacks
WebTestBase::$originalUser protected property The original user, before it was changed to a clean uid = 1 for testing. Overrides TestBase::$originalUser
WebTestBase::$profile protected property The profile to install as a basis for testing. 2
WebTestBase::$redirectCount protected property The number of redirects followed during the handling of a request.
WebTestBase::$sessionId protected property The current session ID, if available.
WebTestBase::$url protected property The URL currently loaded in the internal browser.
WebTestBase::addCustomTranslations protected function Queues custom translations to be written to settings.php.
WebTestBase::assertBlockAppears protected function Checks to see whether a block appears on the page.
WebTestBase::assertCacheTag protected function Asserts whether an expected cache tag was present in the last response.
WebTestBase::assertHeader protected function Check if a HTTP response header exists and has the expected value.
WebTestBase::assertNoBlockAppears protected function Checks to see whether a block does not appears on the page.
WebTestBase::assertNoCacheTag protected function Asserts whether an expected cache tag was absent in the last response.
WebTestBase::assertNoResponse protected function Asserts the page did not return the specified response code.
WebTestBase::assertResponse protected function Asserts the page responds with the specified response code. 1
WebTestBase::assertUrl protected function Passes if the internal browser&#039;s URL matches the given path.
WebTestBase::buildUrl protected function Builds an a absolute URL from a system path or a URL object.
WebTestBase::checkForMetaRefresh protected function Checks for meta refresh tag and if found call drupalGet() recursively.
WebTestBase::clickLink protected function Follows a link by complete name.
WebTestBase::clickLinkHelper protected function Provides a helper for ::clickLink() and ::clickLinkPartialName().
WebTestBase::clickLinkPartialName protected function Follows a link by partial name.
WebTestBase::curlClose protected function Close the cURL handler and unset the handler.
WebTestBase::curlExec protected function Initializes and executes a cURL request. 1
WebTestBase::curlHeaderCallback protected function Reads headers and registers errors received from the tested site.
WebTestBase::curlInitialize protected function Initializes the cURL connection.
WebTestBase::drupalGet protected function Retrieves a Drupal path or an absolute path. 1
WebTestBase::drupalGetAjax protected function Requests a path or URL in drupal_ajax format and JSON-decodes the response.
WebTestBase::drupalGetHeader protected function Gets the value of an HTTP response header. 1
WebTestBase::drupalGetHeaders protected function Gets the HTTP response headers of the requested page. 1
WebTestBase::drupalGetJSON protected function Retrieves a Drupal path or an absolute path and JSON decodes the result.
WebTestBase::drupalGetWithFormat protected function Retrieves a Drupal path or an absolute path for a given format.
WebTestBase::drupalGetXHR protected function Requests a Drupal path or an absolute path as if it is a XMLHttpRequest.
WebTestBase::drupalHead protected function Retrieves only the headers for a Drupal path or an absolute path.
WebTestBase::drupalLogin protected function Log in a user with the internal browser.
WebTestBase::drupalLogout protected function Logs a user out of the internal browser and confirms.
WebTestBase::drupalPost protected function Perform a POST HTTP request.
WebTestBase::drupalPostAjaxForm protected function Executes an Ajax form submission.
WebTestBase::drupalPostForm protected function Executes a form submission.
WebTestBase::drupalPostWithFormat protected function Performs a POST HTTP request with a specific format.
WebTestBase::drupalProcessAjaxResponse protected function Processes an AJAX response into current content.
WebTestBase::drupalUserIsLoggedIn protected function Returns whether a given user account is logged in.
WebTestBase::findBlockInstance protected function Find a block instance on the page.
WebTestBase::getAbsoluteUrl protected function Takes a path and returns an absolute path.
WebTestBase::getAjaxPageStatePostData protected function Get the Ajax page state from drupalSettings and prepare it for POSTing.
WebTestBase::handleForm protected function Handles form input related to drupalPostForm().
WebTestBase::isInChildSite protected function Returns whether the test is being executed from within a test site.
WebTestBase::restoreBatch protected function Restore the original batch.
WebTestBase::serializePostValues protected function Serialize POST HTTP request values.
WebTestBase::setBatch protected function Preserve the original batch, and instantiate the test batch.
WebTestBase::setHttpResponseDebugCacheabilityHeaders protected function Enables/disables the cacheability headers.
WebTestBase::tearDown protected function Cleans up after testing. Overrides TestBase::tearDown 1
WebTestBase::translatePostValues protected function Transforms a nested array into a flat array suitable for WebTestBase::drupalPostForm().
WebTestBase::writeCustomTranslations protected function Writes custom translations to the test site&#039;s settings.php.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.