/** * Bootstraps a kernel for a test. */ private function bootKernel() { $this->setSetting('container_yamls', []); // Allow for test-specific overrides. $settings_services_file = $this->root . '/sites/default' . '/testing.services.yml'; if (file_exists($settings_services_file)) { // Copy the testing-specific service overrides in place. $testing_services_file = $this->root . '/' . $this->siteDirectory . '/services.yml'; copy($settings_services_file, $testing_services_file); $this->setSetting('container_yamls', [$testing_services_file]); } // Allow for global test environment overrides. if (file_exists($test_env = $this->root . '/sites/default/testing.services.yml')) { $GLOBALS['conf']['container_yamls']['testing'] = $test_env; } // Add this test class as a service provider. $GLOBALS['conf']['container_service_providers']['test'] = $this; $modules = self::getModulesToEnable(get_class($this)); // Prepare a precompiled container for all tests of this class. // Substantially improves performance, since ContainerBuilder::compile() // is very expensive. Encourages testing best practices (small tests). // Normally a setUpBeforeClass() operation, but object scope is required to // inject $this test class instance as a service provider (see above). $rc = new \ReflectionClass(get_class($this)); $test_method_count = count(array_filter($rc->getMethods(), function ($method) { // PHPUnit's @test annotations are intentionally ignored/not supported. return strpos($method->getName(), 'test') === 0; })); if ($test_method_count > 1 && !$this->isTestInIsolation()) { // Clone a precompiled, empty ContainerBuilder instance for each test. $container = $this->getCompiledContainerBuilder($modules); } // Bootstrap the kernel. Do not use createFromRequest() to retain Settings. $kernel = new DrupalKernel('testing', $this->classLoader, FALSE); $kernel->setSitePath($this->siteDirectory); // Boot the precompiled container. The kernel will enhance it with synthetic // services. if (isset($container)) { $kernel->setContainer($container); unset($container); } elseif ($modules && ($extensions = $this->getExtensionsForModules($modules))) { $kernel->updateModules($extensions, $extensions); } // DrupalKernel::boot() is not sufficient as it does not invoke preHandle(), // which is required to initialize legacy global variables. $request = Request::create('/'); $kernel->prepareLegacyRequest($request); // register() is only called if a new container was built/compiled. $this->container = $kernel->getContainer(); // Ensure database tasks have been run. 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)); } if ($modules) { $this->container->get('module_handler')->loadAll(); } $this->container->get('request_stack')->push($request); // Setup the destion to the be frontpage by default. \Drupal::destination()->set('/'); // Write the core.extension configuration. // Required for ConfigInstaller::installDefaultConfig() to work. $this->container->get('config.storage')->write('core.extension', array('module' => array_fill_keys($modules, 0), 'theme' => array())); $settings = Settings::getAll(); $settings['php_storage']['default'] = ['class' => '\\Drupal\\Component\\PhpStorage\\FileStorage']; new Settings($settings); // 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. $GLOBALS['config']['system.mail']['interface']['default'] = 'test_mail_collector'; }