You are here

private function KernelTestBase::getCompiledContainerBuilder in Zircon Profile 8

Same name and namespace in other branches
  1. 8.0 core/tests/Drupal/KernelTests/KernelTestBase.php \Drupal\KernelTests\KernelTestBase::getCompiledContainerBuilder()

Prepares a precompiled ContainerBuilder for all tests of this class.

Avoids repetitive calls to ContainerBuilder::compile(), which is very slow.

Based on the (always identical) list of $modules to enable, an initial container is compiled, all instantiated services are reset/removed, and this precompiled container is stored in a static class property. (Static, because PHPUnit instantiates a new class instance for each test *method*.)

This method is not invoked if there is only a single test method. It is also not invoked for tests running in process isolation (since each test method runs in a separate process).

The ContainerBuilder is not dumped into the filesystem (which would yield an actually compiled Container class), because

1. PHP code cannot be unloaded, so e.g. 900 tests would load 900 different, full Container classes into memory, quickly exceeding any sensible memory consumption (GigaBytes). 2. Dumping a Container class requires to actually write to the system's temporary directory. This is not really easy with vfs, because vfs doesn't support yet "include 'vfs://container.php'.". Maybe we could fix that upstream. 3. PhpDumper is very slow on its own.

Parameters

string[] $modules: The list of modules to enable.

Return value

\Drupal\Core\DependencyInjection\ContainerBuilder A clone of the precompiled, empty service container.

1 call to KernelTestBase::getCompiledContainerBuilder()
KernelTestBase::bootKernel in core/tests/Drupal/KernelTests/KernelTestBase.php
Bootstraps a kernel for a test.

File

core/tests/Drupal/KernelTests/KernelTestBase.php, line 464
Contains \Drupal\KernelTests\KernelTestBase.

Class

KernelTestBase
Base class for functional integration tests.

Namespace

Drupal\KernelTests

Code

private function getCompiledContainerBuilder(array $modules) {
  if (!isset(self::$initialContainerBuilder)) {
    $kernel = new DrupalKernel('testing', $this->classLoader, FALSE);
    $kernel
      ->setSitePath($this->siteDirectory);
    if ($modules && ($extensions = $this
      ->getExtensionsForModules($modules))) {
      $kernel
        ->updateModules($extensions, $extensions);
    }
    $kernel
      ->boot();
    self::$initialContainerBuilder = $kernel
      ->getContainer();

    // Remove all instantiated services, so the container is safe for cloning.
    // Technically, ContainerBuilder::set($id, NULL) removes each definition,
    // but the container is compiled/frozen already.
    foreach (self::$initialContainerBuilder
      ->getServiceIds() as $id) {
      self::$initialContainerBuilder
        ->set($id, NULL);
    }

    // Destruct and trigger garbage collection.
    \Drupal::unsetContainer();
    $kernel
      ->shutdown();
    $kernel = NULL;

    // @see register()
    $this->container = NULL;
  }
  $container = clone self::$initialContainerBuilder;
  return $container;
}