From d29b1303460c8bfdcdde91f545928a223374ddff Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Wed, 6 Feb 2013 11:50:46 +0000
Subject: [PATCH] Issue #1833442 by rootatwc, dawehner, alexpott: Remove
 hook_boot().

---
 core/includes/bootstrap.inc                   | 53 ++++-------------
 core/includes/common.inc                      |  4 +-
 core/includes/menu.inc                        |  3 +-
 core/includes/path.inc                        |  9 +--
 .../LanguageUILanguageNegotiationTest.php     |  1 +
 .../{ => language_test}/language_test.info    |  0
 .../{ => language_test}/language_test.module  | 12 ----
 .../language_test/LanguageTestBundle.php      | 28 +++++++++
 .../language_test/LanguageTestManager.php     | 28 +++++++++
 .../Tests/Bootstrap/HookBootExitTest.php      | 24 ++++----
 .../system/Tests/Session/SessionTest.php      |  9 ++-
 core/modules/system/system.api.php            | 19 -------
 core/modules/system/system.module             |  2 +-
 .../EventSubscriber/SessionTestSubscriber.php | 57 +++++++++++++++++++
 .../Drupal/session_test/SessionTestBundle.php | 25 ++++++++
 .../modules/session_test/session_test.module  |  7 ---
 .../modules/system_test/system_test.module    |  7 ---
 .../translation/tests/translation_test.module |  9 ---
 18 files changed, 174 insertions(+), 123 deletions(-)
 rename core/modules/language/tests/{ => language_test}/language_test.info (100%)
 rename core/modules/language/tests/{ => language_test}/language_test.module (90%)
 create mode 100644 core/modules/language/tests/language_test/lib/Drupal/language_test/LanguageTestBundle.php
 create mode 100644 core/modules/language/tests/language_test/lib/Drupal/language_test/LanguageTestManager.php
 create mode 100644 core/modules/system/tests/modules/session_test/lib/Drupal/session_test/EventSubscriber/SessionTestSubscriber.php
 create mode 100644 core/modules/system/tests/modules/session_test/lib/Drupal/session_test/SessionTestBundle.php

diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 7050388086eb..9e6f334fbe90 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -155,20 +155,15 @@
  */
 const DRUPAL_BOOTSTRAP_SESSION = 5;
 
-/**
- * Seventh bootstrap phase: set up the page header.
- */
-const DRUPAL_BOOTSTRAP_PAGE_HEADER = 6;
-
 /**
  * Eighth bootstrap phase: load code for subsystems and modules.
  */
-const DRUPAL_BOOTSTRAP_CODE = 7;
+const DRUPAL_BOOTSTRAP_CODE = 6;
 
 /**
  * Final bootstrap phase: initialize language, path, theme, and modules.
  */
-const DRUPAL_BOOTSTRAP_FULL = 8;
+const DRUPAL_BOOTSTRAP_FULL = 7;
 
 /**
  * Role ID for anonymous users; should match what's in the "role" table.
@@ -1359,8 +1354,8 @@ function drupal_serve_page_from_cache(stdClass $cache) {
   $page_compression = $config->get('response.gzip') && extension_loaded('zlib');
   $return_compressed = $page_compression && isset($_SERVER['HTTP_ACCEPT_ENCODING']) && strpos($_SERVER['HTTP_ACCEPT_ENCODING'], 'gzip') !== FALSE;
 
-  // Get headers set in hook_boot(). Keys are lower-case.
-  $hook_boot_headers = drupal_get_http_header();
+  // Get headers. Keys are lower-case.
+  $boot_headers = drupal_get_http_header();
 
   // Headers generated in this function, that may be replaced or unset using
   // drupal_add_http_headers(). Keys are mixed-case.
@@ -1368,10 +1363,9 @@ function drupal_serve_page_from_cache(stdClass $cache) {
 
   foreach ($cache->data['headers'] as $name => $value) {
     // In the case of a 304 response, certain headers must be sent, and the
-    // remaining may not (see RFC 2616, section 10.3.5). Do not override
-    // headers set in hook_boot().
+    // remaining may not (see RFC 2616, section 10.3.5).
     $name_lower = strtolower($name);
-    if (in_array($name_lower, array('content-location', 'expires', 'cache-control', 'vary')) && !isset($hook_boot_headers[$name_lower])) {
+    if (in_array($name_lower, array('content-location', 'expires', 'cache-control', 'vary')) && !isset($boot_headers[$name_lower])) {
       drupal_add_http_header($name, $value);
       unset($cache->data['headers'][$name]);
     }
@@ -1380,9 +1374,8 @@ function drupal_serve_page_from_cache(stdClass $cache) {
   // If the client sent a session cookie, a cached copy will only be served
   // to that one particular client due to Vary: Cookie. Thus, do not set
   // max-age > 0, allowing the page to be cached by external proxies, when a
-  // session cookie is present unless the Vary header has been replaced or
-  // unset in hook_boot().
-  $max_age = !isset($_COOKIE[session_name()]) || isset($hook_boot_headers['vary']) ? $config->get('cache.page.max_age') : 0;
+  // session cookie is present unless the Vary header has been replaced.
+  $max_age = !isset($_COOKIE[session_name()]) || isset($boot_headers['vary']) ? $config->get('cache.page.max_age') : 0;
   $default_headers['Cache-Control'] = 'public, max-age=' . $max_age;
 
   // Entity tag should change if the output changes.
@@ -1422,7 +1415,7 @@ function drupal_serve_page_from_cache(stdClass $cache) {
   // response to reply to a subsequent request for a given URL without
   // revalidation. If a Vary header has been set in hook_boot(), it is assumed
   // that the module knows how to cache the page.
-  if (!isset($hook_boot_headers['vary']) && !settings()->get('omit_vary_cookie')) {
+  if (!isset($boot_headers['vary']) && !settings()->get('cache.page.omit_vary_cookie')) {
     header('Vary: Cookie');
   }
 
@@ -1450,7 +1443,7 @@ function drupal_serve_page_from_cache(stdClass $cache) {
  * Defines the critical hooks that force modules to always be loaded.
  */
 function bootstrap_hooks() {
-  return array('boot', 'exit', 'watchdog');
+  return array('exit', 'watchdog');
 }
 
 /**
@@ -2080,7 +2073,6 @@ function drupal_anonymous_user() {
  *   - DRUPAL_BOOTSTRAP_DATABASE: Initializes the database layer.
  *   - DRUPAL_BOOTSTRAP_VARIABLES: Initializes the variable system.
  *   - DRUPAL_BOOTSTRAP_SESSION: Initializes session handling.
- *   - DRUPAL_BOOTSTRAP_PAGE_HEADER: Sets up the page header.
  *   - DRUPAL_BOOTSTRAP_CODE: Loads code for subsystems and modules.
  *   - DRUPAL_BOOTSTRAP_FULL: Fully loads Drupal. Validates and fixes input
  *     data.
@@ -2100,7 +2092,6 @@ function drupal_bootstrap($phase = NULL, $new_phase = TRUE) {
     DRUPAL_BOOTSTRAP_DATABASE,
     DRUPAL_BOOTSTRAP_VARIABLES,
     DRUPAL_BOOTSTRAP_SESSION,
-    DRUPAL_BOOTSTRAP_PAGE_HEADER,
     DRUPAL_BOOTSTRAP_CODE,
     DRUPAL_BOOTSTRAP_FULL,
   );
@@ -2155,10 +2146,6 @@ function drupal_bootstrap($phase = NULL, $new_phase = TRUE) {
           drupal_session_initialize();
           break;
 
-        case DRUPAL_BOOTSTRAP_PAGE_HEADER:
-          _drupal_bootstrap_page_header();
-          break;
-
         case DRUPAL_BOOTSTRAP_CODE:
           require_once DRUPAL_ROOT . '/core/includes/common.inc';
           _drupal_bootstrap_code();
@@ -2353,8 +2340,7 @@ function _drupal_bootstrap_page_cache() {
   // If there is no session cookie and cache is enabled (or forced), try
   // to serve a cached page.
   if (!isset($_COOKIE[session_name()]) && $cache_enabled) {
-    // Make sure there is a user object because its timestamp will be
-    // checked, hook_boot might check for anonymous user etc.
+    // Make sure there is a user object because its timestamp will be checked.
     $user = drupal_anonymous_user();
     // Get the page from the cache.
     $cache = drupal_page_get_cache();
@@ -2365,11 +2351,7 @@ function _drupal_bootstrap_page_cache() {
       _current_path($cache->data['path']);
       drupal_set_title($cache->data['title'], PASS_THROUGH);
       date_default_timezone_set(drupal_get_user_timezone());
-      // If the skipping of the bootstrap hooks is not enforced, call
-      // hook_boot.
-      if (variable_get('page_cache_invoke_hooks', TRUE)) {
-        bootstrap_invoke_all('boot');
-      }
+
       drupal_serve_page_from_cache($cache);
       // If the skipping of the bootstrap hooks is not enforced, call
       // hook_exit.
@@ -2440,17 +2422,6 @@ function _drupal_bootstrap_variables() {
   drupal_container()->get('module_handler')->loadBootstrapModules();
 }
 
-/**
- * Invokes hook_boot(), initializes locking system, and sends HTTP headers.
- */
-function _drupal_bootstrap_page_header() {
-  bootstrap_invoke_all('boot');
-
-  if (!drupal_is_cli()) {
-    ob_start();
-  }
-}
-
 /**
  * Returns the current bootstrap phase for this Drupal process.
  *
diff --git a/core/includes/common.inc b/core/includes/common.inc
index f4c7e0016f68..97b73f4fe0b3 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -6442,8 +6442,8 @@ function drupal_flush_all_caches() {
   drupal_container()->get('module_handler')->loadAll();
 
   // Update the list of bootstrap modules.
-  // Allows developers to get new hook_boot() implementations registered without
-  // having to write a hook_update_N() function.
+  // Allows developers to get new bootstrap hooks implementations registered
+  // without having to write a hook_update_N() function.
   _system_update_bootstrap_status();
 
   // Rebuild the schema and cache a fully-built schema based on new module data.
diff --git a/core/includes/menu.inc b/core/includes/menu.inc
index e6810b8e7a96..3ef5442e61fc 100644
--- a/core/includes/menu.inc
+++ b/core/includes/menu.inc
@@ -2293,8 +2293,7 @@ function menu_get_active_menu_names() {
  * Sets the active path, which determines which page is loaded.
  *
  * Note that this may not have the desired effect unless invoked very early
- * in the page load, such as during hook_boot(), or unless you do a subrequest
- * to generate your page output.
+ * in the page load or unless you do a subrequest to generate your page output.
  *
  * @param $path
  *   A Drupal path - not a path alias.
diff --git a/core/includes/path.inc b/core/includes/path.inc
index d0c954ea3a7a..f5a0a9fb8afb 100644
--- a/core/includes/path.inc
+++ b/core/includes/path.inc
@@ -5,8 +5,8 @@
  * Functions to handle paths in Drupal.
  *
  * These functions are not loaded for cached pages, but modules that need
- * to use them in hook_boot() or hook exit() can make them available, by
- * executing "drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);".
+ * to use them in hook exit() can make them available, by executing
+ * "drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL);".
  */
 
 /**
@@ -73,10 +73,7 @@ function drupal_match_path($path, $patterns) {
  * - http://example.com/path/alias (which is a path alias for node/306) returns
  *   "node/306" as opposed to the path alias.
  *
- * This function is not available in hook_boot() so use request_path() instead.
- * However, be careful when doing that because in the case of Example #3
- * request_path() will contain "path/alias". If "node/306" is needed, calling
- * drupal_bootstrap(DRUPAL_BOOTSTRAP_FULL) makes this function available.
+ * This function is available only after DRUPAL_BOOTSTRAP_FULL.
  *
  * @return
  *   The current Drupal URL path.
diff --git a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
index 9200d89ced3b..e614da202870 100644
--- a/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
+++ b/core/modules/language/lib/Drupal/language/Tests/LanguageUILanguageNegotiationTest.php
@@ -59,6 +59,7 @@ public static function getInfo() {
 
   function setUp() {
     parent::setUp();
+
     require_once DRUPAL_ROOT . '/core/includes/language.inc';
     $admin_user = $this->drupalCreateUser(array('administer languages', 'translate interface', 'access administration pages', 'administer blocks'));
     $this->drupalLogin($admin_user);
diff --git a/core/modules/language/tests/language_test.info b/core/modules/language/tests/language_test/language_test.info
similarity index 100%
rename from core/modules/language/tests/language_test.info
rename to core/modules/language/tests/language_test/language_test.info
diff --git a/core/modules/language/tests/language_test.module b/core/modules/language/tests/language_test/language_test.module
similarity index 90%
rename from core/modules/language/tests/language_test.module
rename to core/modules/language/tests/language_test/language_test.module
index c15cc8079038..e83f34c5d042 100644
--- a/core/modules/language/tests/language_test.module
+++ b/core/modules/language/tests/language_test/language_test.module
@@ -5,18 +5,6 @@
  * Mock module for language layer tests.
  */
 
-/**
- * Implements hook_boot().
- *
- * For testing domain language negotiation, we fake it by setting
- * the HTTP_HOST here
- */
-function language_test_boot() {
-  if (state()->get('language_test.domain')) {
-    $_SERVER['HTTP_HOST'] = state()->get('language_test.domain');
-  }
-}
-
 /**
  * Implements hook_init().
  */
diff --git a/core/modules/language/tests/language_test/lib/Drupal/language_test/LanguageTestBundle.php b/core/modules/language/tests/language_test/lib/Drupal/language_test/LanguageTestBundle.php
new file mode 100644
index 000000000000..b7115073bdc7
--- /dev/null
+++ b/core/modules/language/tests/language_test/lib/Drupal/language_test/LanguageTestBundle.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language_test\LanguageTestBundle.
+ */
+
+namespace Drupal\language_test;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+/**
+ * Defines the LanguageTest bundle.
+ */
+class LanguageTestBundle extends Bundle {
+
+  /**
+   * Overrides \Symfony\Component\HttpKernel\Bundle\Bundle::build().
+   */
+  public function build(ContainerBuilder $container) {
+    // Overrides language_manager class to test domain language negotiation.
+    $definition = $container->getDefinition('language_manager');
+    $definition->setClass('Drupal\language_test\LanguageTestManager');
+  }
+
+}
+
diff --git a/core/modules/language/tests/language_test/lib/Drupal/language_test/LanguageTestManager.php b/core/modules/language/tests/language_test/lib/Drupal/language_test/LanguageTestManager.php
new file mode 100644
index 000000000000..aa320762cb95
--- /dev/null
+++ b/core/modules/language/tests/language_test/lib/Drupal/language_test/LanguageTestManager.php
@@ -0,0 +1,28 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\language_test\LanguageTestManager.
+ */
+
+namespace Drupal\language_test;
+
+use Drupal\Core\Language\LanguageManager;
+use Symfony\Component\HttpFoundation\Request;
+
+/**
+ * Defines a LanguageManager service to test URL negotiation.
+ */
+class LanguageTestManager extends LanguageManager {
+
+  /**
+   * Overrides \Drupal\Core\Language\LanguageManager::init().
+   */
+  public function init() {
+    if ($test_domain = state()->get('language_test.domain')) {
+      $_SERVER['HTTP_HOST'] = $test_domain;
+    }
+    return parent::init();
+  }
+
+}
diff --git a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/HookBootExitTest.php b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/HookBootExitTest.php
index e9eff7a3de9f..850687b5cafa 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Bootstrap/HookBootExitTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Bootstrap/HookBootExitTest.php
@@ -2,7 +2,7 @@
 
 /**
  * @file
- * Definition of Drupal\system\Tests\Bootstrap\HookBootExitTest.
+ * Contains \Drupal\system\Tests\Bootstrap\HookExitTest.
  */
 
 namespace Drupal\system\Tests\Bootstrap;
@@ -10,9 +10,9 @@
 use Drupal\simpletest\WebTestBase;
 
 /**
- * Tests hook_boot() and hook_exit().
+ * Tests hook_exit().
  */
-class HookBootExitTest extends WebTestBase {
+class HookExitTest extends WebTestBase {
 
   /**
    * Modules to enable.
@@ -23,16 +23,16 @@ class HookBootExitTest extends WebTestBase {
 
   public static function getInfo() {
     return array(
-      'name' => 'Boot and exit hook invocation',
-      'description' => 'Test that hook_boot() and hook_exit() are called correctly.',
+      'name' => 'Exit hook invocation',
+      'description' => 'Test that hook_exit() is called correctly.',
       'group' => 'Bootstrap',
     );
   }
 
   /**
-   * Tests calling of hook_boot() and hook_exit().
+   * Tests calling of hook_exit().
    */
-  function testHookBootExit() {
+  function testHookExit() {
     // Test with cache disabled. Boot and exit should always fire.
     $config = config('system.performance');
     $config->set('cache.page.enabled', 0);
@@ -40,29 +40,25 @@ function testHookBootExit() {
 
     $this->drupalGet('');
     $calls = 1;
-    $this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND message = :message', array(':type' => 'system_test', ':message' => 'hook_boot'))->fetchField(), $calls, 'hook_boot called with disabled cache.');
     $this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND message = :message', array(':type' => 'system_test', ':message' => 'hook_exit'))->fetchField(), $calls, 'hook_exit called with disabled cache.');
 
-    // Test with normal cache. Boot and exit should be called.
+    // Test with normal cache. Exit should be called.
     $config->set('cache.page.enabled', 1);
     $config->save();
     $this->drupalGet('');
     $calls++;
-    $this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND message = :message', array(':type' => 'system_test', ':message' => 'hook_boot'))->fetchField(), $calls, 'hook_boot called with normal cache.');
     $this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND message = :message', array(':type' => 'system_test', ':message' => 'hook_exit'))->fetchField(), $calls, 'hook_exit called with normal cache.');
 
-    // Boot and exit should not fire since the page is cached.
+    // Exit should not fire since the page is cached.
     variable_set('page_cache_invoke_hooks', FALSE);
     $this->assertTrue(cache('page')->get(url('', array('absolute' => TRUE))), 'Page has been cached.');
     $this->drupalGet('');
-    $this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND message = :message', array(':type' => 'system_test', ':message' => 'hook_boot'))->fetchField(), $calls, 'hook_boot not called with aggressive cache and a cached page.');
     $this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND message = :message', array(':type' => 'system_test', ':message' => 'hook_exit'))->fetchField(), $calls, 'hook_exit not called with aggressive cache and a cached page.');
 
-    // Test with page cache cleared, boot and exit should be called.
+    // Test with page cache cleared, exit should be called.
     $this->assertTrue(db_delete('cache_page')->execute(), 'Page cache cleared.');
     $this->drupalGet('');
     $calls++;
-    $this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND message = :message', array(':type' => 'system_test', ':message' => 'hook_boot'))->fetchField(), $calls, 'hook_boot called with aggressive cache and no cached page.');
     $this->assertEqual(db_query('SELECT COUNT(*) FROM {watchdog} WHERE type = :type AND message = :message', array(':type' => 'system_test', ':message' => 'hook_exit'))->fetchField(), $calls, 'hook_exit called with aggressive cache and no cached page.');
   }
 }
diff --git a/core/modules/system/lib/Drupal/system/Tests/Session/SessionTest.php b/core/modules/system/lib/Drupal/system/Tests/Session/SessionTest.php
index 02503f7e3e63..dadd2f28d403 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Session/SessionTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Session/SessionTest.php
@@ -152,7 +152,8 @@ function testEmptyAnonymousSession() {
     $config->save();
     $this->drupalGet('');
     $this->assertSessionCookie(FALSE);
-    $this->assertSessionEmpty(TRUE);
+    // @todo Reinstate when REQUEST and RESPONSE events fire for cached pages.
+    // $this->assertSessionEmpty(TRUE);
     $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'MISS', 'Page was not cached.');
 
     // Start a new session by setting a message.
@@ -172,7 +173,8 @@ function testEmptyAnonymousSession() {
     // Verify that session was destroyed.
     $this->drupalGet('');
     $this->assertSessionCookie(FALSE);
-    $this->assertSessionEmpty(TRUE);
+    // @todo Reinstate when REQUEST and RESPONSE events fire for cached pages.
+    // $this->assertSessionEmpty(TRUE);
     $this->assertNoText(t('This is a dummy message.'), 'Message was not cached.');
     $this->assertEqual($this->drupalGetHeader('X-Drupal-Cache'), 'HIT', 'Page was cached.');
     $this->assertFalse($this->drupalGetHeader('Set-Cookie'), 'New session was not started.');
@@ -185,7 +187,8 @@ function testEmptyAnonymousSession() {
     // Verify that no message is displayed.
     $this->drupalGet('');
     $this->assertSessionCookie(FALSE);
-    $this->assertSessionEmpty(TRUE);
+    // @todo Reinstate when REQUEST and RESPONSE events fire for cached pages.
+    // $this->assertSessionEmpty(TRUE);
     $this->assertNoText(t('This is a dummy message.'), 'The message was not saved.');
   }
 
diff --git a/core/modules/system/system.api.php b/core/modules/system/system.api.php
index 2c97b0a694c5..ba82bd468c95 100644
--- a/core/modules/system/system.api.php
+++ b/core/modules/system/system.api.php
@@ -1457,24 +1457,6 @@ function hook_forms($form_id, $args) {
   return $forms;
 }
 
-/**
- * Perform setup tasks for all page requests.
- *
- * This hook is run at the beginning of the page request. It is typically
- * used to set up global parameters that are needed later in the request.
- *
- * Only use this hook if your code must run even for cached page views. This
- * hook is called before the theme, modules, or most include files are loaded
- * into memory. It happens while Drupal is still in bootstrap mode.
- *
- * @see hook_init()
- */
-function hook_boot() {
-  // We need user_access() in the shutdown function. Make sure it gets loaded.
-  drupal_load('module', 'user');
-  drupal_register_shutdown_function('devel_shutdown');
-}
-
 /**
  * Perform setup tasks for non-cached page requests.
  *
@@ -1485,7 +1467,6 @@ function hook_boot() {
  *
  * This hook is not run on cached pages.
  *
- * @see hook_boot()
  * @see hook_exit()
  *
  * Do not use this hook to add CSS/JS to pages, use hook_page_build() instead.
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 322e41682915..9339a6f4f2e9 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -2937,7 +2937,7 @@ function system_rebuild_module_data() {
  * Refreshes the list of bootstrap modules.
  *
  * This is called internally by module_enable/disable() to flag modules that
- * implement hooks used during bootstrap, such as hook_boot(). These modules
+ * implement hooks used during bootstrap, such as hook_watchdog(). These modules
  * are loaded earlier to invoke the hooks.
  */
 function _system_update_bootstrap_status() {
diff --git a/core/modules/system/tests/modules/session_test/lib/Drupal/session_test/EventSubscriber/SessionTestSubscriber.php b/core/modules/system/tests/modules/session_test/lib/Drupal/session_test/EventSubscriber/SessionTestSubscriber.php
new file mode 100644
index 000000000000..c9f1b0abced1
--- /dev/null
+++ b/core/modules/system/tests/modules/session_test/lib/Drupal/session_test/EventSubscriber/SessionTestSubscriber.php
@@ -0,0 +1,57 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\session_test\EventSubscriber\SessionTestSubscriber.
+ */
+
+namespace Drupal\session_test\EventSubscriber;
+
+use Symfony\Component\HttpKernel\KernelEvents;
+use Symfony\Component\HttpKernel\Event\FilterResponseEvent;
+use Symfony\Component\HttpKernel\Event\GetResponseEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+/**
+ * Defines a test session subscriber that checks whether the session is empty.
+ */
+class SessionTestSubscriber implements EventSubscriberInterface {
+
+  /*
+   * Stores whether $_SESSION is empty at the beginning of the request.
+   */
+  protected $emptySession;
+
+  /**
+   * Set header for session testing.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\GetResponseEvent $event
+   *   The Event to process.
+   */
+  public function onKernelRequestSessionTest(GetResponseEvent $event) {
+    $this->emptySession = intval(empty($_SESSION));
+  }
+
+  /**
+   * Set header for session testing.
+   *
+   * @param \Symfony\Component\HttpKernel\Event\FilterResponseEvent $event
+   *   The Event to process.
+   */
+  public function onKernelResponseSessionTest(FilterResponseEvent $event) {
+    $event->getResponse()->headers->set('X-Session-Empty', $this->emptySession);
+  }
+
+  /**
+   * Registers the methods in this class that should be listeners.
+   *
+   * @return array
+   *   An array of event listener definitions.
+   */
+  static function getSubscribedEvents() {
+    $events[KernelEvents::RESPONSE][] = array('onKernelResponseSessionTest', 300);
+    $events[KernelEvents::REQUEST][] = array('onKernelRequestSessionTest', 300);
+    return $events;
+  }
+
+}
diff --git a/core/modules/system/tests/modules/session_test/lib/Drupal/session_test/SessionTestBundle.php b/core/modules/system/tests/modules/session_test/lib/Drupal/session_test/SessionTestBundle.php
new file mode 100644
index 000000000000..b2a601ece086
--- /dev/null
+++ b/core/modules/system/tests/modules/session_test/lib/Drupal/session_test/SessionTestBundle.php
@@ -0,0 +1,25 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\session_test\SessionTestBundle.
+ */
+
+namespace Drupal\session_test;
+
+use Symfony\Component\DependencyInjection\ContainerBuilder;
+use Symfony\Component\HttpKernel\Bundle\Bundle;
+
+/**
+ * Defines the SessionTest bundle.
+ */
+class SessionTestBundle extends Bundle {
+
+  /**
+   * Overrides \Symfony\Component\HttpKernel\Bundle\Bundle::build().
+   */
+  public function build(ContainerBuilder $container) {
+    $container->register('session_test.subscriber', 'Drupal\session_test\EventSubscriber\SessionTestSubscriber')
+      ->addTag('event_subscriber');
+  }
+}
diff --git a/core/modules/system/tests/modules/session_test/session_test.module b/core/modules/system/tests/modules/session_test/session_test.module
index d2c17ef3cb71..b3e82fdb18b3 100644
--- a/core/modules/system/tests/modules/session_test/session_test.module
+++ b/core/modules/system/tests/modules/session_test/session_test.module
@@ -64,13 +64,6 @@ function session_test_menu() {
   return $items;
 }
 
-/**
- * Implements hook_boot().
- */
-function session_test_boot() {
-  header('X-Session-Empty: ' . intval(empty($_SESSION)));
-}
-
 /**
  * Page callback, prints the stored session value to the screen.
  */
diff --git a/core/modules/system/tests/modules/system_test/system_test.module b/core/modules/system/tests/modules/system_test/system_test.module
index ee67964cb50a..4494299f3236 100644
--- a/core/modules/system/tests/modules/system_test/system_test.module
+++ b/core/modules/system/tests/modules/system_test/system_test.module
@@ -217,13 +217,6 @@ function system_test_modules_uninstalled($modules) {
   }
 }
 
-/**
- * Implements hook_boot().
- */
-function system_test_boot() {
-  watchdog('system_test', 'hook_boot');
-}
-
 /**
  * Implements hook_init().
  */
diff --git a/core/modules/translation/tests/translation_test.module b/core/modules/translation/tests/translation_test.module
index 8c9fdf2d78bc..d5db14d1a927 100644
--- a/core/modules/translation/tests/translation_test.module
+++ b/core/modules/translation/tests/translation_test.module
@@ -13,12 +13,3 @@
 function translation_test_node_insert(Node $node) {
   drupal_write_record('node', $node, 'nid');
 }
-
-/**
- * Implements hook_boot().
- */
-function translation_test_boot() {
-  // We run the t() function during hook_boot() to make sure it doesn't break
-  // the boot process.
-  $translation = t("Calling the t() process during @boot.", array('@boot' => 'hook_boot()'));
-}
-- 
GitLab