You are here

private function TestBase::prepareEnvironment in Drupal 8

Prepares the current environment for running the test.

Backups various current environment variables and resets them, so they do not interfere with the Drupal site installation in which tests are executed and can be restored in TestBase::restoreEnvironment().

Also sets up new resources for the testing environment, such as the public filesystem and configuration directories.

This method is private as it must only be called once by TestBase::run() (multiple invocations for the same test would have unpredictable consequences) and it must not be callable or overridable by test classes.

See also

TestBase::beforePrepareEnvironment()

1 call to TestBase::prepareEnvironment()
TestBase::run in core/modules/simpletest/src/TestBase.php
Run all tests in this class.

File

core/modules/simpletest/src/TestBase.php, line 1079

Class

TestBase
Base class for Drupal tests.

Namespace

Drupal\simpletest

Code

private function prepareEnvironment() {
  $user = \Drupal::currentUser();

  // Allow (base) test classes to backup global state information.
  $this
    ->beforePrepareEnvironment();

  // Create the database prefix for this test.
  $this
    ->prepareDatabasePrefix();
  $language_interface = \Drupal::languageManager()
    ->getCurrentLanguage();

  // When running the test runner within a test, back up the original database
  // prefix.
  if (DRUPAL_TEST_IN_CHILD_SITE) {
    $this->originalPrefix = drupal_valid_test_ua();
  }

  // Backup current in-memory configuration.
  $site_path = \Drupal::service('site.path');
  $this->originalSite = $site_path;
  $this->originalSettings = Settings::getAll();
  $this->originalConfig = $GLOBALS['config'];

  // @todo Remove all remnants of $GLOBALS['conf'].
  // @see https://www.drupal.org/node/2183323
  $this->originalConf = isset($GLOBALS['conf']) ? $GLOBALS['conf'] : NULL;

  // Backup statics and globals.
  $this->originalContainer = \Drupal::getContainer();
  $this->originalLanguage = $language_interface;

  // Save further contextual information.
  // Use the original files directory to avoid nesting it within an existing
  // simpletest directory if a test is executed within a test.
  $this->originalFileDirectory = Settings::get('file_public_path', $site_path . '/files');
  $this->originalUser = isset($user) ? clone $user : NULL;

  // Prevent that session data is leaked into the UI test runner by closing
  // the session and then setting the session-name (i.e. the name of the
  // session cookie) to a random value. If a test starts a new session, then
  // it will be associated with a different session-name. After the test-run
  // it can be safely destroyed.
  // @see TestBase::restoreEnvironment()
  if (PHP_SAPI !== 'cli' && session_status() === PHP_SESSION_ACTIVE) {
    session_write_close();
  }
  $this->originalSessionName = session_name();
  session_name('SIMPLETEST' . Crypt::randomBytesBase64());

  // Save and clean the shutdown callbacks array because it is static cached
  // and will be changed by the test run. Otherwise it will contain callbacks
  // from both environments and the testing environment will try to call the
  // handlers defined by the original one.
  $callbacks =& drupal_register_shutdown_function();
  $this->originalShutdownCallbacks = $callbacks;
  $callbacks = [];

  // Create test directory ahead of installation so fatal errors and debug
  // information can be logged during installation process.
  \Drupal::service('file_system')
    ->prepareDirectory($this->siteDirectory, FileSystemInterface::CREATE_DIRECTORY | FileSystemInterface::MODIFY_PERMISSIONS);

  // Prepare filesystem directory paths.
  $this->publicFilesDirectory = $this->siteDirectory . '/files';
  $this->privateFilesDirectory = $this->siteDirectory . '/private';
  $this->tempFilesDirectory = $this->siteDirectory . '/temp';
  $this->translationFilesDirectory = $this->siteDirectory . '/translations';
  $this->generatedTestFiles = FALSE;

  // Ensure the configImporter is refreshed for each test.
  $this->configImporter = NULL;

  // Unregister all custom stream wrappers of the parent site.
  // Availability of Drupal stream wrappers varies by test base class:
  // - KernelTestBase supports and maintains stream wrappers in a custom
  //   way.
  // - WebTestBase re-initializes Drupal stream wrappers after installation.
  // The original stream wrappers are restored after the test run.
  // @see TestBase::restoreEnvironment()
  $this->originalContainer
    ->get('stream_wrapper_manager')
    ->unregister();

  // Reset statics.
  drupal_static_reset();

  // Ensure there is no service container.
  $this->container = NULL;
  \Drupal::unsetContainer();

  // Unset globals.
  unset($GLOBALS['config_directories']);
  unset($GLOBALS['config']);
  unset($GLOBALS['conf']);

  // Log fatal errors.
  ini_set('log_errors', 1);
  ini_set('error_log', DRUPAL_ROOT . '/' . $this->siteDirectory . '/error.log');

  // Change the database prefix.
  $this
    ->changeDatabasePrefix();

  // After preparing the environment and changing the database prefix, we are
  // in a valid test environment.
  drupal_valid_test_ua($this->databasePrefix);

  // Reset settings.
  new Settings([
    // For performance, simply use the database prefix as hash salt.
    'hash_salt' => $this->databasePrefix,
    'container_yamls' => [],
  ]);
  Environment::setTimeLimit($this->timeLimit);
}