/**
  * Tests \Drupal\Core\EventSubscriber\ReplicaDatabaseIgnoreSubscriber::checkReplicaServer().
  */
 function testSystemInitIgnoresSecondaries()
 {
     // Clone the master credentials to a replica connection.
     // Note this will result in two independent connection objects that happen
     // to point to the same place.
     $connection_info = Database::getConnectionInfo('default');
     Database::addConnectionInfo('default', 'replica', $connection_info['default']);
     db_ignore_replica();
     $kernel = new DrupalKernel('testing', drupal_classloader(), FALSE);
     $event = new GetResponseEvent($kernel, Request::create('http://example.com'), HttpKernelInterface::MASTER_REQUEST);
     $subscriber = new ReplicaDatabaseIgnoreSubscriber();
     $subscriber->checkReplicaServer($event);
     $db1 = Database::getConnection('default', 'default');
     $db2 = Database::getConnection('replica', 'default');
     $this->assertIdentical($db1, $db2, 'System Init ignores secondaries when requested.');
 }
Пример #2
0
 /**
  * Build a kernel for testings.
  *
  * Because the bootstrap is in DrupalKernel::boot and that involved loading
  * settings from the filesystem we need to go to extra lengths to build a kernel
  * for testing.
  *
  * @param \Symfony\Component\HttpFoundation\Request $request
  *   A request object to use in booting the kernel.
  * @param array $modules_enabled
  *   A list of modules to enable on the kernel.
  * @param bool $read_only
  *   Build the kernel in a read only state.
  * @return DrupalKernel
  */
 protected function getTestKernel(Request $request, array $modules_enabled = NULL, $read_only = FALSE)
 {
     // Manually create kernel to avoid replacing settings.
     $kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'testing');
     $this->settingsSet('hash_salt', $this->databasePrefix);
     if (isset($modules_enabled)) {
         $kernel->updateModules($modules_enabled);
     }
     $kernel->boot();
     if ($read_only) {
         $php_storage = Settings::get('php_storage');
         $php_storage['service_container']['class'] = 'Drupal\\Component\\PhpStorage\\FileReadOnlyStorage';
         $this->settingsSet('php_storage', $php_storage);
     }
     return $kernel;
 }
Пример #3
0
 /**
  * Sets up a Drupal site for running functional and integration tests.
  *
  * Installs Drupal with the installation profile specified in
  * \Drupal\simpletest\WebTestBase::$profile into the prefixed database.
  * Afterwards, installs any additional modules specified in the static
  * \Drupal\simpletest\WebTestBase::$modules property of each class in the
  * class hierarchy.
  *
  * After installation all caches are flushed and several configuration values
  * are reset to the values of the parent site executing the test, since the
  * default values may be incompatible with the environment in which tests are
  * being executed.
  */
 protected function setUp()
 {
     // When running tests through the Simpletest UI (vs. on the command line),
     // Simpletest's batch conflicts with the installer's batch. Batch API does
     // not support the concept of nested batches (in which the nested is not
     // progressive), so we need to temporarily pretend there was no batch.
     // Backup the currently running Simpletest batch.
     $this->originalBatch = batch_get();
     // Define information about the user 1 account.
     $this->root_user = new UserSession(array('uid' => 1, 'name' => 'admin', 'mail' => '*****@*****.**', 'pass_raw' => $this->randomName()));
     // Some tests (SessionTest and SessionHttpsTest) need to examine whether the
     // proper session cookies were set on a response. Because the child site
     // uses the same session name as the test runner, it is necessary to make
     // that available to test-methods.
     $this->session_name = $this->originalSessionName;
     // Reset the static batch to remove Simpletest's batch operations.
     $batch =& batch_get();
     $batch = array();
     // Get parameters for install_drupal() before removing global variables.
     $parameters = $this->installParameters();
     // Prepare installer settings that are not install_drupal() parameters.
     // Copy and prepare an actual settings.php, so as to resemble a regular
     // installation.
     // Not using File API; a potential error must trigger a PHP warning.
     $directory = DRUPAL_ROOT . '/' . $this->siteDirectory;
     copy(DRUPAL_ROOT . '/sites/default/default.settings.php', $directory . '/settings.php');
     // All file system paths are created by System module during installation.
     // @see system_requirements()
     // @see TestBase::prepareEnvironment()
     $settings['settings']['file_public_path'] = (object) array('value' => $this->public_files_directory, 'required' => TRUE);
     // Save the original site directory path, so that extensions in the
     // site-specific directory can still be discovered in the test site
     // environment.
     // @see \Drupal\Core\SystemListing::scan()
     $settings['settings']['test_parent_site'] = (object) array('value' => $this->originalSite, 'required' => TRUE);
     // Add the parent profile's search path to the child site's search paths.
     // @see \Drupal\Core\Extension\ExtensionDiscovery::getProfileDirectories()
     $settings['conf']['simpletest.settings']['parent_profile'] = (object) array('value' => $this->originalProfile, 'required' => TRUE);
     $this->writeSettings($settings);
     // Allow for test-specific overrides.
     $settings_testing_file = DRUPAL_ROOT . '/' . $this->originalSite . '/settings.testing.php';
     if (file_exists($settings_testing_file)) {
         // Copy the testing-specific settings.php overrides in place.
         copy($settings_testing_file, $directory . '/settings.testing.php');
         // Add the name of the testing class to settings.php and include the
         // testing specific overrides
         file_put_contents($directory . '/settings.php', "\n\$test_class = '" . get_class($this) . "';\n" . 'include DRUPAL_ROOT . \'/\' . $site_path . \'/settings.testing.php\';' . "\n", FILE_APPEND);
     }
     $settings_services_file = DRUPAL_ROOT . '/' . $this->originalSite . '/testing.services.yml';
     if (file_exists($settings_services_file)) {
         // Copy the testing-specific service overrides in place.
         copy($settings_services_file, $directory . '/services.yml');
     }
     // Since Drupal is bootstrapped already, install_begin_request() will not
     // bootstrap into DRUPAL_BOOTSTRAP_CONFIGURATION (again). Hence, we have to
     // reload the newly written custom settings.php manually.
     Settings::initialize($directory);
     // Execute the non-interactive installer.
     require_once DRUPAL_ROOT . '/core/includes/install.core.inc';
     install_drupal($parameters);
     // Import new settings.php written by the installer.
     Settings::initialize($directory);
     foreach ($GLOBALS['config_directories'] as $type => $path) {
         $this->configDirectories[$type] = $path;
     }
     // After writing settings.php, the installer removes write permissions
     // from the site directory. To allow drupal_generate_test_ua() to write
     // a file containing the private key for drupal_valid_test_ua(), the site
     // directory has to be writable.
     // TestBase::restoreEnvironment() will delete the entire site directory.
     // Not using File API; a potential error must trigger a PHP warning.
     chmod($directory, 0777);
     $request = \Drupal::request();
     $this->kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'prod', TRUE);
     $this->kernel->prepareLegacyRequest($request);
     // Force the container to be built from scratch instead of loaded from the
     // disk. This forces us to not accidently load the parent site.
     $container = $this->kernel->rebuildContainer();
     $config = $container->get('config.factory');
     // Manually create and configure private and temporary files directories.
     // While these could be preset/enforced in settings.php like the public
     // files directory above, some tests expect them to be configurable in the
     // UI. If declared in settings.php, they would no longer be configurable.
     file_prepare_directory($this->private_files_directory, FILE_CREATE_DIRECTORY);
     file_prepare_directory($this->temp_files_directory, FILE_CREATE_DIRECTORY);
     $config->get('system.file')->set('path.private', $this->private_files_directory)->set('path.temporary', $this->temp_files_directory)->save();
     // Manually configure the test mail collector implementation to prevent
     // tests from sending out emails and collect them in state instead.
     // While this should be enforced via settings.php prior to installation,
     // some tests expect to be able to test mail system implementations.
     $config->get('system.mail')->set('interface.default', 'test_mail_collector')->save();
     // By default, verbosely display all errors and disable all production
     // environment optimizations for all tests to avoid needless overhead and
     // ensure a sane default experience for test authors.
     // @see https://drupal.org/node/2259167
     $config->get('system.logging')->set('error_level', 'verbose')->save();
     $config->get('system.performance')->set('css.preprocess', FALSE)->set('js.preprocess', FALSE)->save();
     // Restore the original Simpletest batch.
     $batch =& batch_get();
     $batch = $this->originalBatch;
     // Collect modules to install.
     $class = get_class($this);
     $modules = array();
     while ($class) {
         if (property_exists($class, 'modules')) {
             $modules = array_merge($modules, $class::$modules);
         }
         $class = get_parent_class($class);
     }
     if ($modules) {
         $modules = array_unique($modules);
         $success = $container->get('module_handler')->install($modules, TRUE);
         $this->assertTrue($success, String::format('Enabled modules: %modules', array('%modules' => implode(', ', $modules))));
         $this->rebuildContainer();
     }
     // Reset/rebuild all data structures after enabling the modules, primarily
     // to synchronize all data structures and caches between the test runner and
     // the child site.
     // Affects e.g. file_get_stream_wrappers().
     // @see \Drupal\Core\DrupalKernel::bootCode()
     // @todo Test-specific setUp() methods may set up further fixtures; find a
     //   way to execute this after setUp() is done, or to eliminate it entirely.
     $this->resetAll();
     $this->kernel->prepareLegacyRequest($request);
     // Temporary fix so that when running from run-tests.sh we don't get an
     // empty current path which would indicate we're on the home page.
     $path = current_path();
     if (empty($path)) {
         _current_path('run-tests');
     }
 }
Пример #4
0
 /**
  * {@inheritdoc}
  */
 protected function setUp()
 {
     $this->keyValueFactory = new KeyValueMemoryFactory();
     // Allow for test-specific overrides.
     $settings_services_file = DRUPAL_ROOT . '/' . $this->originalSite . '/testing.services.yml';
     if (file_exists($settings_services_file)) {
         // Copy the testing-specific service overrides in place.
         copy($settings_services_file, DRUPAL_ROOT . '/' . $this->siteDirectory . '/services.yml');
     }
     parent::setUp();
     // Create and set new configuration directories.
     $this->prepareConfigDirectories();
     // Add this test class as a service provider.
     // @todo Remove the indirection; implement ServiceProviderInterface instead.
     $GLOBALS['conf']['container_service_providers']['TestServiceProvider'] = 'Drupal\\simpletest\\TestServiceProvider';
     // Back up settings from TestBase::prepareEnvironment().
     $settings = Settings::getAll();
     // Bootstrap a new kernel. Don't use createFromRequest so we don't mess with settings.
     $this->kernel = new DrupalKernel('testing', drupal_classloader(), FALSE);
     $request = Request::create('/');
     $this->kernel->setSitePath(DrupalKernel::findSitePath($request));
     $this->kernel->boot();
     // Restore and merge settings.
     // DrupalKernel::boot() initializes new Settings, and the containerBuild()
     // method sets additional settings.
     new Settings($settings + Settings::getAll());
     // Set the request scope.
     $this->container = $this->kernel->getContainer();
     $this->container->get('request_stack')->push($request);
     $this->container->get('state')->set('system.module.files', $this->moduleFiles);
     $this->container->get('state')->set('system.theme.files', $this->themeFiles);
     // Create a minimal core.extension configuration object so that the list of
     // enabled modules can be maintained allowing
     // \Drupal\Core\Config\ConfigInstaller::installDefaultConfig() to work.
     // Write directly to active storage to avoid early instantiation of
     // the event dispatcher which can prevent modules from registering events.
     \Drupal::service('config.storage')->write('core.extension', array('module' => array(), 'theme' => array()));
     // Collect and set a fixed module list.
     $class = get_class($this);
     $modules = array();
     while ($class) {
         if (property_exists($class, 'modules')) {
             // Only add the modules, if the $modules property was not inherited.
             $rp = new \ReflectionProperty($class, 'modules');
             if ($rp->class == $class) {
                 $modules[$class] = $class::$modules;
             }
         }
         $class = get_parent_class($class);
     }
     // Modules have been collected in reverse class hierarchy order; modules
     // defined by base classes should be sorted first. Then, merge the results
     // together.
     $modules = array_reverse($modules);
     $modules = call_user_func_array('array_merge_recursive', $modules);
     if ($modules) {
         $this->enableModules($modules);
     }
     // In order to use theme functions default theme config needs to exist.
     \Drupal::config('system.theme')->set('default', 'stark');
     // Tests based on this class are entitled to use Drupal's File and
     // StreamWrapper APIs.
     // @todo Move StreamWrapper management into DrupalKernel.
     // @see https://drupal.org/node/2028109
     $this->streamWrappers = array();
     // The public stream wrapper only depends on the file_public_path setting,
     // which is provided by UnitTestBase::setUp().
     $this->registerStreamWrapper('public', 'Drupal\\Core\\StreamWrapper\\PublicStream');
     // The temporary stream wrapper is able to operate both with and without
     // configuration.
     $this->registerStreamWrapper('temporary', 'Drupal\\Core\\StreamWrapper\\TemporaryStream');
 }
Пример #5
0
 /**
  * Overrides WebTestBase::setUp().
  */
 protected function setUp()
 {
     $this->isInstalled = FALSE;
     // Define information about the user 1 account.
     $this->root_user = new UserSession(array('uid' => 1, 'name' => 'admin', 'mail' => '*****@*****.**', 'pass_raw' => $this->randomMachineName()));
     // If any $settings are defined for this test, copy and prepare an actual
     // settings.php, so as to resemble a regular installation.
     if (!empty($this->settings)) {
         // Not using File API; a potential error must trigger a PHP warning.
         copy(DRUPAL_ROOT . '/sites/default/default.settings.php', DRUPAL_ROOT . '/' . $this->siteDirectory . '/settings.php');
         $this->writeSettings($this->settings);
     }
     // Note that WebTestBase::installParameters() returns form input values
     // suitable for a programmed drupal_form_submit().
     // @see WebTestBase::translatePostValues()
     $this->parameters = $this->installParameters();
     // Set up a minimal container (required by WebTestBase).
     // @see install_begin_request()
     $request = Request::create($GLOBALS['base_url'] . '/core/install.php');
     $this->container = new ContainerBuilder();
     $request_stack = new RequestStack();
     $request_stack->push($request);
     $this->container->set('request_stack', $request_stack);
     $this->container->setParameter('language.default_values', Language::$defaultValues);
     $this->container->register('language.default', 'Drupal\\Core\\Language\\LanguageDefault')->addArgument('%language.default_values%');
     $this->container->register('language_manager', 'Drupal\\Core\\Language\\LanguageManager')->addArgument(new Reference('language.default'));
     $this->container->register('string_translation', 'Drupal\\Core\\StringTranslation\\TranslationManager')->addArgument(new Reference('language_manager'));
     \Drupal::setContainer($this->container);
     $this->drupalGet($GLOBALS['base_url'] . '/core/install.php');
     // Select language.
     $this->setUpLanguage();
     // Select profile.
     $this->setUpProfile();
     // Configure settings.
     $this->setUpSettings();
     // @todo Allow test classes based on this class to act on further installer
     //   screens.
     // Configure site.
     $this->setUpSite();
     // Import new settings.php written by the installer.
     $request = Request::createFromGlobals();
     Settings::initialize(DrupalKernel::findSitePath($request));
     foreach ($GLOBALS['config_directories'] as $type => $path) {
         $this->configDirectories[$type] = $path;
     }
     // After writing settings.php, the installer removes write permissions
     // from the site directory. To allow drupal_generate_test_ua() to write
     // a file containing the private key for drupal_valid_test_ua(), the site
     // directory has to be writable.
     // WebTestBase::tearDown() will delete the entire test site directory.
     // Not using File API; a potential error must trigger a PHP warning.
     chmod(DRUPAL_ROOT . '/' . $this->siteDirectory, 0777);
     $this->kernel = DrupalKernel::createFromRequest($request, drupal_classloader(), 'prod', FALSE);
     $this->kernel->prepareLegacyRequest($request);
     $this->container = $this->kernel->getContainer();
     $config = $this->container->get('config.factory');
     // Manually configure the test mail collector implementation to prevent
     // tests from sending out e-mails and collect them in state instead.
     $config->get('system.mail')->set('interface.default', 'test_mail_collector')->save();
     // When running from run-tests.sh we don't get an empty current path which
     // would indicate we're on the home page.
     $path = current_path();
     if (empty($path)) {
         _current_path('run-tests');
     }
     $this->isInstalled = TRUE;
 }
Пример #6
0
 /**
  * {@inheritdoc}
  */
 public function boot()
 {
     if ($this->booted) {
         return $this;
     }
     // Start a page timer:
     Timer::start('page');
     drupal_classloader();
     // Load legacy and other functional code.
     require_once DRUPAL_ROOT . '/core/includes/common.inc';
     require_once DRUPAL_ROOT . '/core/includes/database.inc';
     require_once DRUPAL_ROOT . '/' . Settings::get('path_inc', 'core/includes/path.inc');
     require_once DRUPAL_ROOT . '/core/includes/module.inc';
     require_once DRUPAL_ROOT . '/core/includes/theme.inc';
     require_once DRUPAL_ROOT . '/core/includes/pager.inc';
     require_once DRUPAL_ROOT . '/' . Settings::get('menu_inc', 'core/includes/menu.inc');
     require_once DRUPAL_ROOT . '/core/includes/tablesort.inc';
     require_once DRUPAL_ROOT . '/core/includes/file.inc';
     require_once DRUPAL_ROOT . '/core/includes/unicode.inc';
     require_once DRUPAL_ROOT . '/core/includes/form.inc';
     require_once DRUPAL_ROOT . '/core/includes/mail.inc';
     require_once DRUPAL_ROOT . '/core/includes/ajax.inc';
     require_once DRUPAL_ROOT . '/core/includes/errors.inc';
     require_once DRUPAL_ROOT . '/core/includes/schema.inc';
     require_once DRUPAL_ROOT . '/core/includes/entity.inc';
     // Ensure that findSitePath is set.
     if (!$this->sitePath) {
         throw new \Exception('Kernel does not have site path set before calling boot()');
     }
     // Intialize the container.
     $this->initializeContainer();
     // Ensure mt_rand() is reseeded to prevent random values from one page load
     // being exploited to predict random values in subsequent page loads.
     $seed = unpack("L", Crypt::randomBytes(4));
     mt_srand($seed[1]);
     $this->booted = TRUE;
     return $this;
 }