From 3af6a3e5382f58d57336f1b264341f1b9407b934 Mon Sep 17 00:00:00 2001
From: xjm <xjm@65776.no-reply.drupal.org>
Date: Thu, 19 Jan 2017 19:11:27 +0000
Subject: [PATCH] Issue #2754217 by alexpott, xjm, dawehner, martin107: Random
 Test Failure with "failed to open stream" for temporary://.htaccess

---
 core/includes/install.core.inc                | 16 ++++++++++++++
 .../Core/Test/FunctionalTestSetupTrait.php    | 17 +++++++-------
 core/lib/Drupal/Core/Test/TestSetupTrait.php  |  4 ++++
 .../src/Tests/WebTestBaseInstallTest.php      | 22 +++++++++++++++++++
 .../FunctionalTests/BrowserTestBaseTest.php   |  8 +++++++
 5 files changed, 58 insertions(+), 9 deletions(-)
 create mode 100644 core/modules/simpletest/src/Tests/WebTestBaseInstallTest.php

diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 1616f1891e1e..a016540328a4 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -20,6 +20,7 @@
 use Drupal\Core\Site\Settings;
 use Drupal\Core\StringTranslation\Translator\FileTranslation;
 use Drupal\Core\StackMiddleware\ReverseProxyMiddleware;
+use Drupal\Core\StreamWrapper\PublicStream;
 use Drupal\Core\Extension\ExtensionDiscovery;
 use Drupal\Core\DependencyInjection\ContainerBuilder;
 use Drupal\Core\Url;
@@ -1036,6 +1037,21 @@ function install_base_system(&$install_state) {
   // Install system.module.
   drupal_install_system($install_state);
 
+  // Prevent the installer from using the system temporary directory after the
+  // system module has been installed.
+  if (drupal_valid_test_ua()) {
+    // While the temporary directory could be preset/enforced in settings.php
+    // like the public files directory, some tests expect it to be configurable
+    // in the UI. If declared in settings.php, they would no longer be
+    // configurable. The temporary directory needs to match what is set in each
+    // test types ::prepareEnvironment() step.
+    $temporary_directory = dirname(PublicStream::basePath()) . '/temp';
+    file_prepare_directory($temporary_directory, FILE_MODIFY_PERMISSIONS | FILE_CREATE_DIRECTORY);
+    \Drupal::configFactory()->getEditable('system.file')
+      ->set('path.temporary', $temporary_directory)
+      ->save();
+  }
+
   // Call file_ensure_htaccess() to ensure that all of Drupal's standard
   // directories (e.g., the public files directory and config directory) have
   // appropriate .htaccess files. These directories will have already been
diff --git a/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php b/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php
index dbbd9623c955..25571b96a2b3 100644
--- a/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php
+++ b/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php
@@ -50,9 +50,15 @@ protected function prepareSettings() {
     $directory = DRUPAL_ROOT . '/' . $this->siteDirectory;
     copy(DRUPAL_ROOT . '/sites/default/default.settings.php', $directory . '/settings.php');
 
-    // All file system paths are created by System module during installation.
+    // The public file system path is created during installation. Additionally,
+    // during tests:
+    // - The temporary directory is set and created by install_base_system().
+    // - The private file directory is created post install by
+    //   FunctionalTestSetupTrait::initConfig().
     // @see system_requirements()
     // @see TestBase::prepareEnvironment()
+    // @see install_base_system()
+    // @see \Drupal\Core\Test\FunctionalTestSetupTrait::initConfig()
     $settings['settings']['file_public_path'] = (object) [
       'value' => $this->publicFilesDirectory,
       'required' => TRUE,
@@ -316,15 +322,8 @@ protected function initSettings() {
   protected function initConfig(ContainerInterface $container) {
     $config = $container->get('config.factory');
 
-    // Manually create and configure private and temporary files directories.
-    // While these could be preset/enforced in settings.php like the public
-    // files directory above, some tests expect them to be configurable in the
-    // UI. If declared in settings.php, they would no longer be configurable.
+    // Manually create the private directory.
     file_prepare_directory($this->privateFilesDirectory, FILE_CREATE_DIRECTORY);
-    file_prepare_directory($this->tempFilesDirectory, FILE_CREATE_DIRECTORY);
-    $config->getEditable('system.file')
-      ->set('path.temporary', $this->tempFilesDirectory)
-      ->save();
 
     // Manually configure the test mail collector implementation to prevent
     // tests from sending out emails and collect them in state instead.
diff --git a/core/lib/Drupal/Core/Test/TestSetupTrait.php b/core/lib/Drupal/Core/Test/TestSetupTrait.php
index 32e6fcaa8374..31849c825e18 100644
--- a/core/lib/Drupal/Core/Test/TestSetupTrait.php
+++ b/core/lib/Drupal/Core/Test/TestSetupTrait.php
@@ -92,8 +92,12 @@ trait TestSetupTrait {
   /**
    * The temporary file directory for the test environment.
    *
+   * This value has to match the temporary directory created in
+   * install_base_system() for test installs.
+   *
    * @see \Drupal\simpletest\TestBase::prepareEnvironment()
    * @see \Drupal\Tests\BrowserTestBase::prepareEnvironment()
+   * @see install_base_system()
    *
    * @var string
    */
diff --git a/core/modules/simpletest/src/Tests/WebTestBaseInstallTest.php b/core/modules/simpletest/src/Tests/WebTestBaseInstallTest.php
new file mode 100644
index 000000000000..857e3a33b914
--- /dev/null
+++ b/core/modules/simpletest/src/Tests/WebTestBaseInstallTest.php
@@ -0,0 +1,22 @@
+<?php
+
+namespace Drupal\simpletest\Tests;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests the test-specifics customisations done in the installation.
+ *
+ * @group simpletest
+ */
+class WebTestBaseInstallTest extends WebTestBase {
+
+  /**
+   * Tests the Drupal install done in \Drupal\simpletest\WebTestBase::setUp().
+   */
+  public function testInstall() {
+    $htaccess_filename = $this->getTempFilesDirectory() . '/.htaccess';
+    $this->assertTrue(file_exists($htaccess_filename), "$htaccess_filename exists");
+  }
+
+}
diff --git a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php
index 7241fe491647..199d25774d1b 100644
--- a/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php
+++ b/core/tests/Drupal/FunctionalTests/BrowserTestBaseTest.php
@@ -177,4 +177,12 @@ public function testCronRun() {
     $this->assertGreaterThan($last_cron_time, $next_cron_time);
   }
 
+  /**
+   * Tests the Drupal install done in \Drupal\Tests\BrowserTestBase::setUp().
+   */
+  public function testInstall() {
+    $htaccess_filename = $this->tempFilesDirectory . '/.htaccess';
+    $this->assertTrue(file_exists($htaccess_filename), "$htaccess_filename exists");
+  }
+
 }
-- 
GitLab