Commit 341b903d authored by catch's avatar catch

Issue #2228215 by znerol, Berdir: Remove module check in DrupalKernel.

parent 3a699a6a
......@@ -116,6 +116,13 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
*/
protected $allowDumping;
/**
* Whether the container can be loaded.
*
* @var bool
*/
protected $allowLoading;
/**
* Whether the container needs to be dumped once booting is complete.
*
......@@ -171,12 +178,16 @@ class DrupalKernel implements DrupalKernelInterface, TerminableInterface {
* @param bool $allow_dumping
* (optional) FALSE to stop the container from being written to or read
* from disk. Defaults to TRUE.
* @param bool $allow_loading
* (optional) FALSE to prevent the kernel attempting to read the dependency
* injection container from disk. Defaults to $allow_dumping.
*/
public function __construct($environment, ClassLoader $class_loader, $allow_dumping = TRUE) {
public function __construct($environment, ClassLoader $class_loader, $allow_dumping = TRUE, $allow_loading = NULL) {
$this->environment = $environment;
$this->booted = FALSE;
$this->classLoader = $class_loader;
$this->allowDumping = $allow_dumping;
$this->allowLoading = isset($allow_loading) ? $allow_loading : $allow_dumping;
}
/**
......@@ -344,6 +355,12 @@ public function updateModules(array $module_list, array $module_filenames = arra
foreach ($module_filenames as $name => $extension) {
$this->moduleData[$name] = $extension;
}
// This method is called whenever the list of modules changed. Therefore
// disable loading of a dumped container from the disk, because it is
// guaranteed to be out of date and needs to be rebuilt anyway.
$this->allowLoading = FALSE;
// If we haven't yet booted, we don't need to do anything: the new module
// list will take effect when boot() is called. If we have already booted,
// then reboot in order to refresh the serviceProvider list and container.
......@@ -397,7 +414,7 @@ protected function initializeContainer() {
$class = $this->getClassName();
$cache_file = $class . '.php';
if ($this->allowDumping) {
if ($this->allowLoading) {
// First, try to load.
if (!class_exists($class, FALSE)) {
$this->storage()->load($cache_file);
......@@ -417,33 +434,12 @@ protected function initializeContainer() {
$this->moduleList = $this->newModuleList;
unset($this->newModuleList);
}
// Second, check if some other request -- for example on another web
// frontend or during the installer -- changed the list of enabled modules.
if (isset($this->container)) {
// All namespaces must be registered before we attempt to use any service
// from the container.
$container_modules = $this->container->getParameter('container.modules');
$namespaces_before = $this->classLoader->getPrefixesPsr4();
$this->registerNamespacesPsr4($this->container->getParameter('container.namespaces'));
// If 'container.modules' is wrong, the container must be rebuilt.
if (!isset($this->moduleList)) {
$this->moduleList = $this->container->get('config.factory')->get('core.extension')->get('module') ?: array();
}
if (array_keys($this->moduleList) !== array_keys($container_modules)) {
$persist = $this->getServicesToPersist();
unset($this->container);
// Revert the class loader to its prior state. However,
// registerNamespaces() performs a merge rather than replace, so to
// effectively remove erroneous registrations, we must replace them with
// empty arrays.
$namespaces_after = $this->classLoader->getPrefixesPsr4();
$namespaces_before += array_fill_keys(array_diff(array_keys($namespaces_after), array_keys($namespaces_before)), array());
$this->registerNamespacesPsr4($namespaces_before);
}
}
if (!isset($this->container)) {
else {
$this->container = $this->buildContainer();
$this->persistServices($persist);
......
......@@ -57,7 +57,7 @@ abstract class NormalizerTestBase extends DrupalUnitTestBase {
protected $entityClass = 'Drupal\entity_test\Entity\EntityTest';
/**
* Overrides \Drupal\simpletest\DrupalUnitTestBase::setup().
* {@inheritdoc}
*/
function setUp() {
parent::setUp();
......
......@@ -970,7 +970,7 @@ private function changeDatabasePrefix() {
/**
* Act on global state information before the environment is altered for a test.
*
* Allows e.g. DrupalUnitTestBase to prime system/extension info from the
* Allows e.g. KernelTestBase to prime system/extension info from the
* parent site (and inject it into the test environment so as to improve
* performance).
*/
......@@ -1058,7 +1058,7 @@ private function prepareEnvironment() {
// Unregister all custom stream wrappers of the parent site.
// Availability of Drupal stream wrappers varies by test base class:
// - UnitTestBase operates in a completely empty environment.
// - DrupalUnitTestBase supports and maintains stream wrappers in a custom
// - 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.
......
......@@ -2,17 +2,17 @@
/**
* @file
* Contains \Drupal\simpletest\Tests\DrupalUnitTestBaseTest.
* Contains \Drupal\simpletest\Tests\KernelTestBaseTest.
*/
namespace Drupal\simpletest\Tests;
use Drupal\simpletest\DrupalUnitTestBase;
use Drupal\simpletest\KernelTestBase;
/**
* Tests DrupalUnitTestBase functionality.
* Tests KernelTestBase functionality.
*/
class DrupalUnitTestBaseTest extends DrupalUnitTestBase {
class KernelTestBaseTest extends KernelTestBase {
/**
* Modules to enable.
......@@ -23,8 +23,8 @@ class DrupalUnitTestBaseTest extends DrupalUnitTestBase {
public static function getInfo() {
return array(
'name' => 'DrupalUnitTestBase',
'description' => 'Tests DrupalUnitTestBase functionality.',
'name' => 'KernelTestBase',
'description' => 'Tests KernelTestBase functionality.',
'group' => 'SimpleTest',
);
}
......
......@@ -1094,7 +1094,7 @@ protected function rebuildContainer($environment = 'prod') {
$request_stack = \Drupal::service('request_stack');
}
$this->kernel = new DrupalKernel($environment, drupal_classloader(), FALSE);
$this->kernel = new DrupalKernel($environment, drupal_classloader(), TRUE, FALSE);
$this->kernel->boot();
// DrupalKernel replaces the container in \Drupal::getContainer() with a
// different object, so we need to replace the instance on this test class.
......
......@@ -27,7 +27,7 @@ public static function getInfo() {
function setUp() {
// DrupalKernel relies on global $config_directories and requires those
// directories to exist. Therefore, create the directories, but do not
// invoke DrupalUnitTestBase::setUp(), since that would set up further
// invoke KernelTestBase::setUp(), since that would set up further
// environment aspects, which would distort this test, because it tests
// the DrupalKernel (re-)building itself.
$this->prepareConfigDirectories();
......@@ -56,7 +56,6 @@ function testCompileDIC() {
// Instantiate it a second time and we should get the compiled Container
// class.
$kernel = new DrupalKernel('testing', $classloader);
$kernel->updateModules($module_enabled);
$kernel->boot();
$container = $kernel->getContainer();
$refClass = new \ReflectionClass($container);
......@@ -64,6 +63,10 @@ function testCompileDIC() {
$refClass->getParentClass()->getName() == 'Drupal\Core\DependencyInjection\Container' &&
!$refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder');
$this->assertTrue($is_compiled_container);
// Verify that the list of modules is the same for the initial and the
// compiled container.
$module_list = array_keys($container->get('module_handler')->getModuleList());
$this->assertEqual(array_values($module_enabled), $module_list);
// Now use the read-only storage implementation, simulating a "production"
// environment.
......@@ -71,7 +74,6 @@ function testCompileDIC() {
$php_storage['service_container']['class'] = 'Drupal\Component\PhpStorage\FileReadOnlyStorage';
$this->settingsSet('php_storage', $php_storage);
$kernel = new DrupalKernel('testing', $classloader);
$kernel->updateModules($module_enabled);
$kernel->boot();
$container = $kernel->getContainer();
$refClass = new \ReflectionClass($container);
......@@ -79,6 +81,10 @@ function testCompileDIC() {
$refClass->getParentClass()->getName() == 'Drupal\Core\DependencyInjection\Container' &&
!$refClass->isSubclassOf('Symfony\Component\DependencyInjection\ContainerBuilder');
$this->assertTrue($is_compiled_container);
// Verify that the list of modules is the same for the initial and the
// compiled container.
$module_list = array_keys($container->get('module_handler')->getModuleList());
$this->assertEqual(array_values($module_enabled), $module_list);
// Test that our synthetic services are there.
$classloader = $container->get('class_loader');
$refClass = new \ReflectionClass($classloader);
......
......@@ -15,7 +15,7 @@
/**
* Tests the text_plain field formatter.
*
* @todo Move assertion helper methods into DrupalUnitTestBase.
* @todo Move assertion helper methods into KernelTestBase.
* @todo Move field helper methods, $modules, and setUp() into a new
* FieldPluginUnitTestBase.
*/
......
......@@ -21,7 +21,6 @@
* ViewTestBase instead.
*
* @see \Drupal\views\Tests\ViewTestBase
* @see \Drupal\simpletest\DrupalUnitTestBase
*/
abstract class ViewUnitTestBase extends DrupalUnitTestBase {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment