From 68ce258d630aa8715d8adce6ef1a624a4e3917de Mon Sep 17 00:00:00 2001
From: Nathaniel Catchpole <catch@35733.no-reply.drupal.org>
Date: Fri, 10 Jan 2014 11:48:37 +0000
Subject: [PATCH] Issue #2166065 by alexpott, mtift: Replace
 config_install_default_config with ConfigInstaller service.

---
 core/core.services.yml                        |   5 +-
 core/includes/config.inc                      |  81 -----------
 core/includes/install.inc                     |   6 +-
 .../Drupal/Core/Config/ConfigInstaller.php    | 130 ++++++++++++++++++
 .../Core/Config/ConfigInstallerInterface.php  |  40 ++++++
 .../Drupal/Core/Extension/ModuleHandler.php   |   2 +-
 .../Drupal/Core/Extension/ThemeHandler.php    |  31 +++--
 .../Drupal/ckeditor/Tests/CKEditorTest.php    |   2 +-
 .../Drupal/config/Tests/ConfigDiffTest.php    |   2 +-
 .../config/Tests/ConfigImporterTest.php       |   2 +-
 .../config/Tests/ConfigLanguageOverride.php   |   3 +-
 .../config/Tests/ConfigOverrideTest.php       |   2 +-
 .../Drupal/config/Tests/ConfigSchemaTest.php  |   4 +-
 .../config/Tests/ConfigSnapshotTest.php       |   5 +-
 .../lib/Drupal/field/Tests/FieldInfoTest.php  |  10 +-
 .../Drupal/filter/Tests/FilterUnitTest.php    |   2 +-
 .../Drupal/simpletest/DrupalUnitTestBase.php  |  19 ++-
 .../system/Tests/Common/XssUnitTest.php       |   4 +-
 core/modules/system/system.install            |   2 +-
 .../lib/Drupal/tour/Tests/TourPluginTest.php  |   2 +-
 .../Tests/Core/Extension/ThemeHandlerTest.php |  25 ++--
 21 files changed, 251 insertions(+), 128 deletions(-)
 create mode 100644 core/lib/Drupal/Core/Config/ConfigInstaller.php
 create mode 100644 core/lib/Drupal/Core/Config/ConfigInstallerInterface.php

diff --git a/core/core.services.yml b/core/core.services.yml
index 8e9ca23ef428..6134359ddd14 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -81,6 +81,9 @@ services:
       - { name: persist }
       - { name: event_subscriber }
     arguments: ['@config.storage', '@event_dispatcher', '@config.typed']
+  config.installer:
+    class: Drupal\Core\Config\ConfigInstaller
+    arguments: ['@config.factory', '@config.storage', '@config.typed', '@entity.manager', '@event_dispatcher']
   config.storage.staging:
     class: Drupal\Core\Config\FileStorage
     factory_class: Drupal\Core\Config\FileStorageFactory
@@ -177,7 +180,7 @@ services:
     arguments: ['@container.namespaces', '@cache.cache', '@language_manager', '@module_handler']
   theme_handler:
     class: Drupal\Core\Extension\ThemeHandler
-    arguments: ['@config.factory', '@module_handler', '@cache.cache', '@info_parser', '@router.builder']
+    arguments: ['@config.factory', '@module_handler', '@cache.cache', '@info_parser', '@config.installer', '@router.builder']
   entity.manager:
     class: Drupal\Core\Entity\EntityManager
     arguments: ['@container.namespaces', '@service_container', '@module_handler', '@cache.cache', '@language_manager', '@string_translation']
diff --git a/core/includes/config.inc b/core/includes/config.inc
index 71b4ab947518..28a7a7fd7528 100644
--- a/core/includes/config.inc
+++ b/core/includes/config.inc
@@ -16,87 +16,6 @@
  * This is the API for configuration storage.
  */
 
-/**
- * Installs the default configuration of a given extension.
- *
- * When an extension is installed, it searches all the default configuration
- * directories for all other extensions to locate any configuration with its
- * name prefix. For example, the Node module provides the frontpage view as a
- * default configuration file:
- * core/modules/node/config/views.view.frontpage.yml
- * When the Views module is installed after the Node module is already enabled,
- * the frontpage view will be installed.
- *
- * Additionally, the default configuration directory for the extension being
- * installed is searched to discover if it contains default configuration
- * that is owned by other enabled extensions. So, the frontpage view will also
- * be installed when the Node module is installed after Views.
- *
- * @param string $type
- *   The extension type; e.g., 'module' or 'theme'.
- * @param string $name
- *   The name of the module or theme to install default configuration for.
- *
- * @see \Drupal\Core\Config\ExtensionInstallStorage
- */
-function config_install_default_config($type, $name) {
-  // Get all default configuration owned by this extension.
-  $source_storage = new ExtensionInstallStorage();
-  $config_to_install = $source_storage->listAll($name . '.');
-
-  // Work out if this extension provides default configuration for any other
-  // enabled extensions.
-  $config_dir = drupal_get_path($type, $name) . '/config';
-  if (is_dir($config_dir)) {
-    $default_storage = new FileStorage($config_dir);
-    $other_module_config = array_filter($default_storage->listAll(),
-      function ($value) use ($name) {
-        return !preg_match('/^' . $name . '\./', $value);
-      }
-    );
-    $enabled_extensions = array_keys(\Drupal::moduleHandler()->getModuleList());
-    $enabled_extensions += array_keys(array_filter(list_themes(), function ($theme) {return $theme->status;}));
-
-    $other_module_config = array_filter($other_module_config, function ($config_name) use ($enabled_extensions) {
-      $provider = Unicode::substr($config_name, 0, strpos($config_name, '.'));
-      return in_array($provider, $enabled_extensions);
-    });
-
-    $config_to_install = array_merge($config_to_install, $other_module_config);
-  }
-  if (!empty($config_to_install)) {
-    $entity_manager = Drupal::service('entity.manager');
-    $config_factory = Drupal::service('config.factory');
-    $target_storage = Drupal::service('config.storage');
-    $typed_config = Drupal::service('config.typed');
-    $event_dispatcher = Drupal::service('event_dispatcher');
-
-    $config_factory->disableOverrides();
-    foreach ($config_to_install as $name) {
-      // Only import new config.
-      if ($target_storage->exists($name)) {
-        continue;
-      }
-
-      $new_config = new Config($name, $target_storage, $event_dispatcher, $typed_config);
-      $data = $source_storage->read($name);
-      if ($data !== FALSE) {
-        $new_config->setData($data);
-      }
-      if ($entity_type = config_get_entity_type_by_name($name)) {
-        $entity_manager
-          ->getStorageController($entity_type)
-          ->create($new_config->get())
-          ->save();
-      }
-      else {
-        $new_config->save();
-      }
-      $config_factory->enableOverrides();
-    }
-  }
-}
-
 /**
  * Uninstalls the default configuration of a given extension.
  *
diff --git a/core/includes/install.inc b/core/includes/install.inc
index 256c79e340c3..67c18b720bbb 100644
--- a/core/includes/install.inc
+++ b/core/includes/install.inc
@@ -639,8 +639,8 @@ function drupal_install_system() {
   \Drupal::keyValue('system.schema')->set('system', $system_version);
 
   // System module needs to be enabled and the system/module lists need to be
-  // reset first in order to allow config_install_default_config() to invoke
-  // config import callbacks.
+  // reset first in order to allow installation of default configuration to
+  // invoke config import callbacks.
   // @todo Installation profiles may override the system.module config object.
   \Drupal::config('system.module')
     ->set('enabled.system', 0)
@@ -649,7 +649,7 @@ function drupal_install_system() {
   // Update the module list to include it.
   \Drupal::moduleHandler()->setModuleList(array('system' => $system_path . '/system.module'));
 
-  config_install_default_config('module', 'system');
+  \Drupal::service('config.installer')->installDefaultConfig('module', 'system');
 
   module_invoke('system', 'install');
 }
diff --git a/core/lib/Drupal/Core/Config/ConfigInstaller.php b/core/lib/Drupal/Core/Config/ConfigInstaller.php
new file mode 100644
index 000000000000..dc4f3b928cd8
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/ConfigInstaller.php
@@ -0,0 +1,130 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Config\ConfigInstaller.
+ */
+
+namespace Drupal\Core\Config;
+
+use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Entity\EntityManagerInterface;
+use Symfony\Component\EventDispatcher\EventDispatcherInterface;
+
+class ConfigInstaller implements ConfigInstallerInterface {
+
+  /**
+   * The configuration factory.
+   *
+   * @var \Drupal\Core\Config\ConfigFactory
+   */
+  protected $configFactory;
+
+  /**
+   * The active configuration storage.
+   *
+   * @var \Drupal\Core\Config\StorageInterface
+   */
+  protected $activeStorage;
+
+  /**
+   * The typed configuration manager.
+   *
+   * @var \Drupal\Core\Config\TypedConfigManagerInterface
+   */
+  protected $typedConfig;
+
+  /**
+   * The entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManagerInterface
+   */
+  protected $entityManager;
+
+  /**
+   * The event dispatcher.
+   *
+   * @var \Symfony\Component\EventDispatcher\EventDispatcherInterface
+   */
+  protected $eventDispatcher;
+
+  /**
+   * Constructs the configuration installer.
+   *
+   * @param \Drupal\Core\Config\ConfigFactory $config_factory
+   *   The configuration factory.
+   * @param \Drupal\Core\Config\StorageInterface $active_storage
+   *   The active configuration storage.
+   * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config
+   *   The typed configuration manager.
+   * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager
+   *   The entity manager.
+   * @param \Symfony\Component\EventDispatcher\EventDispatcherInterface $event_dispatcher
+   *   The event dispatcher.
+   */
+  public function __construct(ConfigFactory $config_factory, StorageInterface $active_storage, TypedConfigManagerInterface $typed_config, EntityManagerInterface $entity_manager, EventDispatcherInterface $event_dispatcher) {
+    $this->configFactory = $config_factory;
+    $this->activeStorage = $active_storage;
+    $this->typedConfig = $typed_config;
+    $this->entityManager = $entity_manager;
+    $this->eventDispatcher = $event_dispatcher;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function installDefaultConfig($type, $name) {
+    // Get all default configuration owned by this extension.
+    $source_storage = new ExtensionInstallStorage();
+    $config_to_install = $source_storage->listAll($name . '.');
+
+    // Work out if this extension provides default configuration for any other
+    // enabled extensions.
+    $config_dir = drupal_get_path($type, $name) . '/config';
+    if (is_dir($config_dir)) {
+      $default_storage = new FileStorage($config_dir);
+      $other_module_config = array_filter($default_storage->listAll(), function ($value) use ($name) {
+        return !preg_match('/^' . $name . '\./', $value);
+      });
+
+      // Read enabled extensions directly from configuration to avoid circular
+      // dependencies with ModuleHandler and ThemeHandler.
+      $enabled_extensions = array_keys((array) $this->configFactory->get('system.module')->get('enabled'));
+      $enabled_extensions += array_keys((array) $this->configFactory->get('system.theme')->get('enabled'));
+
+      $other_module_config = array_filter($other_module_config, function ($config_name) use ($enabled_extensions) {
+        $provider = Unicode::substr($config_name, 0, strpos($config_name, '.'));
+        return in_array($provider, $enabled_extensions);
+      });
+
+      $config_to_install = array_merge($config_to_install, $other_module_config);
+    }
+
+    if (!empty($config_to_install)) {
+      $this->configFactory->disableOverrides();
+      foreach ($config_to_install as $name) {
+        // Only import new config.
+        if ($this->activeStorage->exists($name)) {
+          continue;
+        }
+
+        $new_config = new Config($name, $this->activeStorage, $this->eventDispatcher, $this->typedConfig);
+        $data = $source_storage->read($name);
+        if ($data !== FALSE) {
+          $new_config->setData($data);
+        }
+        if ($entity_type = config_get_entity_type_by_name($name)) {
+          $this->entityManager
+            ->getStorageController($entity_type)
+            ->create($new_config->get())
+            ->save();
+        }
+        else {
+          $new_config->save();
+        }
+      }
+      $this->configFactory->enableOverrides();
+    }
+  }
+
+}
diff --git a/core/lib/Drupal/Core/Config/ConfigInstallerInterface.php b/core/lib/Drupal/Core/Config/ConfigInstallerInterface.php
new file mode 100644
index 000000000000..927c6105422e
--- /dev/null
+++ b/core/lib/Drupal/Core/Config/ConfigInstallerInterface.php
@@ -0,0 +1,40 @@
+<?php
+
+/**
+ * @file
+ * Contains Drupal\Core\Config\ConfigInstallerInterface.
+ */
+
+namespace Drupal\Core\Config;
+
+/**
+ * Interface for classes that install config.
+ */
+interface ConfigInstallerInterface {
+
+  /**
+   * Installs the default configuration of a given extension.
+   *
+   * When an extension is installed, it searches all the default configuration
+   * directories for all other extensions to locate any configuration with its
+   * name prefix. For example, the Node module provides the frontpage view as a
+   * default configuration file:
+   * core/modules/node/config/views.view.frontpage.yml
+   * When the Views module is installed after the Node module is already
+   * enabled, the frontpage view will be installed.
+   *
+   * Additionally, the default configuration directory for the extension being
+   * installed is searched to discover if it contains default configuration
+   * that is owned by other enabled extensions. So, the frontpage view will also
+   * be installed when the Node module is installed after Views.
+   *
+   * @param string $type
+   *   The extension type; e.g., 'module' or 'theme'.
+   * @param string $name
+   *   The name of the module or theme to install default configuration for.
+   *
+   * @see \Drupal\Core\Config\ExtensionInstallStorage
+   */
+  public function installDefaultConfig($type, $name);
+
+}
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index 5b3d2b99b2c4..8a1abb4e4ebb 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -633,7 +633,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
         $version = $versions ? max($versions) : SCHEMA_INSTALLED;
 
         // Install default configuration of the module.
-        config_install_default_config('module', $module);
+        \Drupal::service('config.installer')->installDefaultConfig('module', $module);
 
         // If the module has no current updates, but has some that were
         // previously removed, set the version to the value of
diff --git a/core/lib/Drupal/Core/Extension/ThemeHandler.php b/core/lib/Drupal/Core/Extension/ThemeHandler.php
index 40e59cbd1b47..fbd42c59b486 100644
--- a/core/lib/Drupal/Core/Extension/ThemeHandler.php
+++ b/core/lib/Drupal/Core/Extension/ThemeHandler.php
@@ -10,6 +10,7 @@
 use Drupal\Component\Utility\String;
 use Drupal\Core\Cache\CacheBackendInterface;
 use Drupal\Core\Config\ConfigFactory;
+use Drupal\Core\Config\ConfigInstallerInterface;
 use Drupal\Core\Routing\RouteBuilder;
 use Drupal\Core\SystemListingInfo;
 
@@ -63,6 +64,13 @@ class ThemeHandler implements ThemeHandlerInterface {
    */
   protected $cacheBackend;
 
+  /**
+   *  The config installer to install configuration.
+   *
+   * @var \Drupal\Core\Config\ConfigInstallerInterface
+   */
+  protected $configInstaller;
+
   /**
    * The info parser to parse the theme.info.yml files.
    *
@@ -95,16 +103,21 @@ class ThemeHandler implements ThemeHandlerInterface {
    *   The cache backend to clear the local tasks cache.
    * @param \Drupal\Core\Extension\InfoParserInterface $info_parser
    *   The info parser to parse the theme.info.yml files.
+   * @param \Drupal\Core\Config\ConfigInstallerInterface $config_installer
+   *   (optional) The config installer to install configuration. This optional
+   *   to allow the theme handler to work before Drupal is installed and has a
+   *   database.
    * @param \Drupal\Core\Routing\RouteBuilder $route_builder
    *   (optional) The route builder to rebuild the routes if a theme is enabled.
    * @param \Drupal\Core\SystemListingInfo $system_list_info
    *   (optional) The system listing info.
    */
-  public function __construct(ConfigFactory $config_factory, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, InfoParserInterface $info_parser, RouteBuilder $route_builder = NULL, SystemListingInfo $system_list_info = NULL) {
+  public function __construct(ConfigFactory $config_factory, ModuleHandlerInterface $module_handler, CacheBackendInterface $cache_backend, InfoParserInterface $info_parser, ConfigInstallerInterface $config_installer = NULL, RouteBuilder $route_builder = NULL, SystemListingInfo $system_list_info = NULL) {
     $this->configFactory = $config_factory;
     $this->moduleHandler = $module_handler;
     $this->cacheBackend = $cache_backend;
     $this->infoParser = $info_parser;
+    $this->configInstaller = $config_installer;
     $this->routeBuilder = $route_builder;
     $this->systemListingInfo = $system_list_info;
   }
@@ -129,11 +142,11 @@ public function enable(array $theme_list) {
       $theme_config->set("enabled.$key", 0)->save();
       $disabled_themes->clear($key)->save();
 
-      // Refresh the theme list as config_install_default_config() needs an
-      // updated list to work.
+      // Refresh the theme list as installation of default configuration needs
+      // an updated list to work.
       $this->reset();
       // Install default configuration of the theme.
-      $this->configInstallDefaultConfig($key);
+      $this->configInstaller->installDefaultConfig('theme', $key);
     }
 
     $this->resetSystem();
@@ -441,16 +454,6 @@ protected function getSystemListingInfo() {
     return $this->systemListingInfo;
   }
 
-  /**
-   * Installs the default theme config.
-   *
-   * @param string $theme
-   *   The theme to install config for.
-   */
-  protected function configInstallDefaultConfig($theme) {
-    config_install_default_config('theme', $theme);
-  }
-
   /**
    * Resets some other systems like rebuilding the route information or caches.
    */
diff --git a/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php b/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php
index e4e821f24793..66a384fa6b0d 100644
--- a/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php
+++ b/core/modules/ckeditor/lib/Drupal/ckeditor/Tests/CKEditorTest.php
@@ -317,7 +317,7 @@ function testStylesComboGetConfig() {
   function testLanguages() {
     // Get CKEditor supported language codes and spot-check.
     $this->enableModules(array('language'));
-    config_install_default_config('module', 'language');
+    $this->installConfig(array('language'));
     $langcodes = $this->ckeditor->getLangcodes();
 
     // Language codes transformed with browser mappings.
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigDiffTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigDiffTest.php
index 09f126bb48de..5ffe66222e07 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigDiffTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigDiffTest.php
@@ -47,7 +47,7 @@ function testDiff() {
     );
 
     // Install the default config.
-    config_install_default_config('module', 'config_test');
+    $this->installConfig(array('config_test'));
 
     // Change a configuration value in staging.
     $staging_data = $original_data;
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php
index de7fc7f4d6a7..241c3396763a 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigImporterTest.php
@@ -44,7 +44,7 @@ function setUp() {
 
     $this->installSchema('system', 'config_snapshot');
 
-    config_install_default_config('module', 'config_test');
+    $this->installConfig(array('config_test'));
     // Installing config_test's default configuration pollutes the global
     // variable being used for recording hook invocations by this test already,
     // so it has to be cleared out manually.
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverride.php b/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverride.php
index e0cec2145446..4d7bdf942252 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverride.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigLanguageOverride.php
@@ -32,8 +32,7 @@ public static function getInfo() {
 
   public function setUp() {
     parent::setUp();
-    config_install_default_config('module', 'config_test');
-    config_install_default_config('module', 'locale');
+    $this->installConfig(array('config_test'));
     \Drupal::configFactory()->setLanguage(language_default());
   }
 
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php
index 5a077fbbea70..f6f3f46c79e3 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigOverrideTest.php
@@ -51,7 +51,7 @@ function testConfOverride() {
     $conf['config_test.system']['baz'] = 'injected';
     $conf['config_test.system']['404'] = 'derp';
 
-    config_install_default_config('module', 'config_test');
+    $this->installConfig(array('config_test'));
 
     // Verify that the original configuration data exists. Have to read storage
     // directly otherwise overrides will apply.
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php
index 663b456f1b91..5d8f2593fa9b 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigSchemaTest.php
@@ -33,9 +33,7 @@ public static function getInfo() {
 
   public function setUp() {
     parent::setUp();
-    config_install_default_config('module', 'system');
-    config_install_default_config('module', 'image');
-    config_install_default_config('module', 'config_test');
+    $this->installConfig(array('system', 'image', 'config_test'));
   }
 
   /**
diff --git a/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php b/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php
index 34743d5a2bb1..c277ac69bacd 100644
--- a/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php
+++ b/core/modules/config/lib/Drupal/config/Tests/ConfigSnapshotTest.php
@@ -33,6 +33,9 @@ public static function getInfo() {
   public function setUp() {
     parent::setUp();
     $this->installSchema('system', 'config_snapshot');
+    // Update the config snapshot. This allows the parent::setUp() to write
+    // configuration files.
+    config_import_create_snapshot(\Drupal::service('config.storage'), \Drupal::service('config.storage.snapshot'));
   }
 
   /**
@@ -54,7 +57,7 @@ function testSnapshot() {
     $this->assertFalse($active_snapshot_comparer->createChangelist()->hasChanges());
 
     // Install the default config.
-    config_install_default_config('module', 'config_test');
+    $this->installConfig(array('config_test'));
     // Although we have imported config this has not affected the snapshot.
     $this->assertTrue($active_snapshot_comparer->reset()->hasChanges());
 
diff --git a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
index 03fc5490c1ab..267c3617c402 100644
--- a/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
+++ b/core/modules/field/lib/Drupal/field/Tests/FieldInfoTest.php
@@ -173,6 +173,11 @@ function testInstancePrepare() {
    * Test that instances on disabled entity types are filtered out.
    */
   function testInstanceDisabledEntityType() {
+    // Disabling the comment module invokes user_modules_uninstalled() and calls
+    // drupal_flush_all_caches(). Install the necessary schema to support this.
+    $this->installSchema('user', array('users_data'));
+    $this->installSchema('system', array('router'));
+
     // For this test the field type and the entity type must be exposed by
     // different modules.
     $this->enableModules(array('node', 'comment'));
@@ -187,9 +192,10 @@ function testInstanceDisabledEntityType() {
       'entity_type' => 'comment',
       'bundle' => 'comment_node_article',
     );
-    entity_create('field_instance', $instance_definition);
+    entity_create('field_instance', $instance_definition)->save();
 
-    // Disable coment module. This clears field_info cache.
+    $this->assertNotNull(field_info_instance('comment', 'field', 'comment_node_article'), 'Instance is returned on enabled entity types.');
+    // Disable comment module. This clears field_info cache.
     module_uninstall(array('comment'));
     $this->assertNull(field_info_instance('comment', 'field', 'comment_node_article'), 'No instances are returned on disabled entity types.');
   }
diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterUnitTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterUnitTest.php
index 64b97228c9db..fb31a495987a 100644
--- a/core/modules/filter/lib/Drupal/filter/Tests/FilterUnitTest.php
+++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterUnitTest.php
@@ -37,7 +37,7 @@ public static function getInfo() {
 
   protected function setUp() {
     parent::setUp();
-    config_install_default_config('module', 'system');
+    $this->installConfig(array('system'));
 
     $manager = $this->container->get('plugin.manager.filter');
     $bag = new FilterBag($manager, array());
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php
index 879ca803a4ab..b7848dedfe76 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/DrupalUnitTestBase.php
@@ -102,6 +102,13 @@ protected function setUp() {
     $this->kernel = new DrupalKernel('unit_testing', drupal_classloader(), FALSE);
     $this->kernel->boot();
 
+    // Create a minimal system.module 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('system.module', array('enabled' => array()));
+
     // Collect and set a fixed module list.
     $class = get_class($this);
     $modules = array();
@@ -209,7 +216,7 @@ protected function installConfig(array $modules) {
           '@module' => $module,
         )));
       }
-      config_install_default_config('module', $module);
+      \Drupal::service('config.installer')->installDefaultConfig('module', $module);
     }
     $this->pass(format_string('Installed default config: %modules.', array(
       '%modules' => implode(', ', $modules),
@@ -268,9 +275,16 @@ protected function enableModules(array $modules) {
     // Set the list of modules in the extension handler.
     $module_handler = $this->container->get('module_handler');
     $module_filenames = $module_handler->getModuleList();
+    // Write directly to active storage to avoid early instantiation of
+    // the event dispatcher which can prevent modules from registering events.
+    $active_storage =  \Drupal::service('config.storage');
+    $system_config = $active_storage->read('system.module');
     foreach ($modules as $module) {
       $module_filenames[$module] = drupal_get_filename('module', $module);
+      // Maintain the list of enabled modules in configuration.
+      $system_config['enabled'][$module] = 0;
     }
+    $active_storage->write('system.module', $system_config);
     $module_handler->setModuleList($module_filenames);
     $module_handler->resetImplementations();
     // Update the kernel to make their services available.
@@ -299,9 +313,12 @@ protected function disableModules(array $modules) {
     // Unset the list of modules in the extension handler.
     $module_handler = $this->container->get('module_handler');
     $module_filenames = $module_handler->getModuleList();
+    $system_config = $this->container->get('config.factory')->get('system.module');
     foreach ($modules as $module) {
       unset($module_filenames[$module]);
+      $system_config->clear('enabled.' . $module);
     }
+    $system_config->save();
     $module_handler->setModuleList($module_filenames);
     $module_handler->resetImplementations();
     // Update the kernel to remove their services.
diff --git a/core/modules/system/lib/Drupal/system/Tests/Common/XssUnitTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/XssUnitTest.php
index 66213586be7c..bcafe3036a70 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Common/XssUnitTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/XssUnitTest.php
@@ -20,7 +20,7 @@ class XssUnitTest extends DrupalUnitTestBase {
    *
    * @var array
    */
-  public static $modules = array('filter');
+  public static $modules = array('filter', 'system');
 
   public static function getInfo() {
     return array(
@@ -32,7 +32,7 @@ public static function getInfo() {
 
   protected function setUp() {
     parent::setUp();
-    config_install_default_config('module', 'system');
+    $this->installConfig(array('system'));
   }
 
   /**
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index 34d8dde75103..4fd03afa41b0 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -557,7 +557,7 @@ function system_requirements($phase) {
 function system_install() {
   // Enable and set the default theme. Can't use theme_enable() this early in
   // installation.
-  config_install_default_config('theme', 'stark');
+  \Drupal::service('config.installer')->installDefaultConfig('theme', 'stark');
   \Drupal::config('system.theme')
     ->set('default', 'stark')
     ->save();
diff --git a/core/modules/tour/lib/Drupal/tour/Tests/TourPluginTest.php b/core/modules/tour/lib/Drupal/tour/Tests/TourPluginTest.php
index 460e4978e1c7..58e3e3b8cd93 100644
--- a/core/modules/tour/lib/Drupal/tour/Tests/TourPluginTest.php
+++ b/core/modules/tour/lib/Drupal/tour/Tests/TourPluginTest.php
@@ -39,7 +39,7 @@ public static function getInfo() {
   protected function setUp() {
     parent::setUp();
 
-    config_install_default_config('module', 'tour');
+    $this->installConfig(array('tour'));
     $this->pluginManager = $this->container->get('plugin.manager.tour.tip');
   }
 
diff --git a/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php b/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php
index 708ab210e1b8..717cee57194a 100644
--- a/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php
+++ b/core/tests/Drupal/Tests/Core/Extension/ThemeHandlerTest.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Extension\InfoParser;
 use Drupal\Core\Extension\ThemeHandler;
+use Drupal\Core\Config\ConfigInstaller;
 use Drupal\Tests\UnitTestCase;
 
 /**
@@ -56,6 +57,13 @@ class ThemeHandlerTest extends UnitTestCase {
    */
   protected $moduleHandler;
 
+  /**
+   * The mocked config installer.
+   *
+   * @var \Drupal\Core\Config\ConfigInstaller|\PHPUnit_Framework_MockObject_MockObject
+   */
+  protected $configInstaller;
+
   /**
    * The system listing info.
    *
@@ -89,14 +97,14 @@ protected function setUp() {
     $this->moduleHandler = $this->getMock('Drupal\Core\Extension\ModuleHandlerInterface');
     $this->cacheBackend = $this->getMock('Drupal\Core\Cache\CacheBackendInterface');
     $this->infoParser = $this->getMock('Drupal\Core\Extension\InfoParserInterface');
+    $this->configInstaller = $this->getMock('Drupal\Core\Config\ConfigInstallerInterface');
     $this->routeBuilder = $this->getMockBuilder('Drupal\Core\Routing\RouteBuilder')
       ->disableOriginalConstructor()
       ->getMock();
     $this->systemListingInfo = $this->getMockBuilder('Drupal\Core\SystemListingInfo')
       ->disableOriginalConstructor()
       ->getMock();
-
-    $this->themeHandler = new TestThemeHandler($this->configFactory, $this->moduleHandler, $this->cacheBackend, $this->infoParser, $this->routeBuilder, $this->systemListingInfo);
+    $this->themeHandler = new TestThemeHandler($this->configFactory, $this->moduleHandler, $this->cacheBackend, $this->infoParser, $this->configInstaller, $this->routeBuilder, $this->systemListingInfo);
   }
 
   /**
@@ -149,11 +157,15 @@ public function testEnableSingleTheme() {
       ->method('invokeAll')
       ->with('themes_enabled', array($theme_list));
 
+    // Ensure the config installer will be called.
+    $this->configInstaller->expects($this->once())
+      ->method('installDefaultConfig')
+      ->with('theme', $theme_list[0]);
+
     $this->themeHandler->enable($theme_list);
 
     $this->assertTrue($this->themeHandler->clearedCssCache);
     $this->assertTrue($this->themeHandler->registryRebuild);
-    $this->assertTrue($this->themeHandler->installedDefaultConfig['theme_test']);
   }
 
   /**
@@ -393,13 +405,6 @@ protected function themeRegistryRebuild() {
     $this->registryRebuild = TRUE;
   }
 
-  /**
-   * {@inheritdoc}
-   */
-  protected function configInstallDefaultConfig($theme) {
-    $this->installedDefaultConfig[$theme] = TRUE;
-  }
-
   /**
    * {@inheritdoc}
    */
-- 
GitLab