Commit 1c7dd34c authored by webchick's avatar webchick
Browse files

Issue #1949724 by chx, effulgentsia, xjm, jibran, rootatwc: Allow simpletest...

Issue #1949724 by chx, effulgentsia, xjm, jibran, rootatwc: Allow simpletest child sites to additionally load a test-specific settings.php to allow testing anonymous and configless updates.
parent a627a34e
......@@ -387,6 +387,13 @@ function conf_path($require_settings = TRUE, $reset = FALSE) {
return $conf;
}
// Check for a simpletest override.
if ($simpletest_conf_path = _drupal_simpletest_conf_path()) {
$conf = $simpletest_conf_path;
return $conf;
}
// Otherwise, use the normal $conf_path.
$script_name = $_SERVER['SCRIPT_NAME'];
if (!$script_name) {
$script_name = $_SERVER['SCRIPT_FILENAME'];
......@@ -396,6 +403,50 @@ function conf_path($require_settings = TRUE, $reset = FALSE) {
return $conf;
}
/**
* Determines whether to use an overridden value for conf_path().
*
* Simpletest may provide a secondary, test-specific settings.php file to load
* after the primary one used by the parent site and override its variables.
* - If the child settings.php does not override $conf_path, then this function
* returns FALSE and conf_path() returns the directory of the primary
* settings.php.
* - If the child settings.php does override $conf_path, then
* _drupal_load_test_overrides() sets the 'simpletest_conf_path' setting, and
* this function returns that to conf_path(), causing installations and
* upgrades to act on that one.
*
* @return string|false
* The overridden $conf_path, or FALSE if the $conf_path should not currently
* be overridden.
*
* @see conf_path()
* @see _drupal_load_test_overrides()
*/
function _drupal_simpletest_conf_path() {
// Ensure that the settings object is available. conf_path() is called once
// before the Settings class is included, and at that point it should still
// load the primary $conf_path. See drupal_settings_initialize().
if (!class_exists('Drupal\Component\Utility\Settings', FALSE)) {
return FALSE;
}
// If no $simpletest_conf_path is set, use the normal $conf_path.
if (!($simpletest_conf_path = settings()->get('simpletest_conf_path'))) {
return FALSE;
}
// Ensure that this is actually a simpletest request. We can't check this
// before settings.php is loaded.
if (!drupal_valid_test_ua()) {
return FALSE;
}
// When the $simpletest_conf_path is set in a valid test request,
// return that path.
return $simpletest_conf_path;
}
/**
* Finds the appropriate configuration directory for a given host and path.
*
......@@ -474,11 +525,7 @@ function find_conf_path($http_host, $script_name, $require_settings = TRUE) {
function config_get_config_directory($type = CONFIG_ACTIVE_DIRECTORY) {
global $config_directories;
if ($test_prefix = drupal_valid_test_ua()) {
// @see Drupal\simpletest\WebTestBase::setUp()
$path = conf_path() . '/files/simpletest/' . substr($test_prefix, 10) . '/config_' . $type;
}
elseif (!empty($config_directories[$type])) {
if (!empty($config_directories[$type])) {
// Allow a configuration directory path to be outside of webroot.
if (empty($config_directories[$type]['absolute'])) {
$path = conf_path() . '/files/' . $config_directories[$type]['path'];
......@@ -2566,6 +2613,7 @@ function drupal_valid_test_ua($new_prefix = NULL) {
// and the HMAC must match.
if ($time_diff >= 0 && $time_diff <= 5 && $hmac == drupal_hmac_base64($check_string, $key)) {
$test_prefix = $prefix;
_drupal_load_test_overrides($test_prefix);
return $test_prefix;
}
}
......@@ -2574,6 +2622,43 @@ function drupal_valid_test_ua($new_prefix = NULL) {
return $test_prefix;
}
/**
* Overrides low-level and environment-specific configuration.
*
* Very strictly for internal use only.
*
* Loads settings.php from the simpletest public files directory. These files
* can change the global $conf, the global $config_directories, the return
* value of conf_path(), and settings().
*
* @param string $test_prefix
* The simpletest prefix.
*/
function _drupal_load_test_overrides($test_prefix) {
global $conf, $config_directories;
// Do not use the parent site's config directories. Use only the child site's.
// @see Drupal\simpletest\TestBase::prepareConfigDirectories()
$path_prefix = 'simpletest/' . substr($test_prefix, 10);
$config_directories = array();
foreach (array(CONFIG_ACTIVE_DIRECTORY, CONFIG_STAGING_DIRECTORY) as $type) {
$config_directories[$type] = array('path' => $path_prefix . '/config_' . $type);
}
// Check for and load a settings.php file in the simpletest files directory.
$filename = conf_path() . '/files/' . $path_prefix . '/settings.php';
if (file_exists($filename)) {
$settings = settings()->getAll();
$conf_path = &drupal_static('conf_path');
// This can override $conf, $conf_path, $settings, and $config_directories.
include $filename;
// Keep the overriden $conf_path alive across drupal_static_reset() calls.
// @see conf_path()
$settings['simpletest_conf_path'] = $conf_path;
new Settings($settings);
}
}
/**
* Generates a user agent string with a HMAC and timestamp for simpletest.
*/
......
......@@ -858,6 +858,36 @@ protected function setUp() {
$this->setup = TRUE;
}
/**
* Writes a test-specific settings.php file for the child site.
*
* The child site loads this after the parent site's settings.php, so settings
* here override those.
*
* @param $settings An array of settings to write out, in the format expected
* by drupal_rewrite_settings().
*
* @see _drupal_load_test_overrides()
* @see drupal_rewrite_settings()
*/
protected function writeSettings($settings) {
// drupal_rewrite_settings() sets the in-memory global variables in addition
// to writing the file. We'll want to restore the original globals.
foreach (array_keys($settings) as $variable_name) {
$original_globals[$variable_name] = isset($GLOBALS[$variable_name]) ? $GLOBALS[$variable_name] : NULL;
}
include_once DRUPAL_ROOT . '/core/includes/install.inc';
$filename = $this->public_files_directory . '/settings.php';
file_put_contents($filename, "<?php\n");
drupal_rewrite_settings($settings, $filename);
// Restore the original globals.
foreach ($original_globals as $variable_name => $value) {
$GLOBALS[$variable_name] = $value;
}
}
/**
* Reset all data structures after having enabled new modules.
*
......
<?php
/**
* @file
* Contains \Drupal\system\Tests\Upgrade\BareMinimalAnonymousUpgradePathTest.
*/
namespace Drupal\system\Tests\Upgrade;
/**
* Tests the upgrade path without prior creation of config directions.
*/
class BareMinimalAnonymousUpgradePathTest extends BareMinimalUpgradePathTest {
public static function getInfo() {
return array(
'name' => 'Basic minimal profile upgrade, free access',
'description' => 'Basic upgrade path tests for a minimal profile install with a bare database and update_free_access set to TRUE.',
'group' => 'Upgrade path',
);
}
/**
* Overrides \Drupal\system\Tests\Upgrade\UpgradePathTestBase::setUp().
*/
public function setUp() {
parent::setUp();
// Override $update_free_access in settings.php to allow the anonymous user
// to run updates.
$settings['settings']['update_free_access'] = (object) array(
'value' => TRUE,
'required' => TRUE,
);
$this->writeSettings($settings);
}
/**
* Overrides \Drupal\system\Tests\Upgrade\UpgradePathTestBase::prepareD8Session().
*/
protected function prepareD8Session() {
// There is no active session, so nothing needs to be done here.
}
/**
* Overrides \Drupal\system\Tests\Upgrade\UpgradePathTestBase::assertSessionKept().
*/
protected function finishUpgradeSession() {
// There is no active session, so nothing needs to be done here.
}
}
<?php
/**
* @file
* Contains \Drupal\system\Tests\Upgrade\BareMinimalNoConfigUpgradePathTest.
*/
namespace Drupal\system\Tests\Upgrade;
/**
* Tests the database upgrade path without creating config directories.
*/
class BareMinimalNoConfigUpgradePathTest extends BareMinimalUpgradePathTest {
public static function getInfo() {
return array(
'name' => 'Basic minimal profile upgrade, no config',
'description' => 'Basic upgrade path tests for a minimal profile install with a bare database and config directory not pre-created.',
'group' => 'Upgrade path',
);
}
/**
* Overrides \Drupal\system\Tests\Upgrade\UpgradePathTestBase::setUp().
*/
public function setUp() {
parent::setUp();
// Override $conf_path and $config_directories in settings.php.
$settings['conf_path'] = (object) array(
'value' => $this->public_files_directory,
'required' => TRUE,
);
$settings['config_directories'] = (object) array(
'value' => array(),
'required' => TRUE,
);
$this->writeSettings($settings);
}
/**
* Overrides \Drupal\system\Tests\Upgrade\UpgradePathTestBase::refreshVariables().
*/
protected function refreshVariables() {
// Refresh the variables only if the site was already upgraded.
if ($this->upgradedSite) {
// update.php puts the new, randomized config directries in this file.
include $this->public_files_directory . '/settings.php';
$GLOBALS['config_directories'] = array();
foreach ($config_directories as $type => $data) {
// update.php runs as the child site, so writes the paths relative to
// that "$conf_path/files", but here, we're running as the parent site,
// so need to make the paths relative to our "conf_path()/files".
//
// Example:
// - Parent site conf_path(): 'sites/default'
// - Child site $conf_path: 'sites/default/files/simpletest/123456'
// - Child site $data['path']: 'config_xyz'
// - Desired result: 'simpletest/123456/files/config_xyz'
//
// @see config_get_config_directory()
$GLOBALS['config_directories'][$type]['path'] = substr($conf_path, strlen(conf_path() . '/files/')) . '/files/' . $data['path'];
}
parent::refreshVariables();
}
}
}
......@@ -2,7 +2,7 @@
/**
* @file
* Definition of Drupal\system\Tests\Upgrade\BareMinimalUpgradePathTest.
* Contains \Drupal\system\Tests\Upgrade\BareMinimalUpgradePathTest.
*/
namespace Drupal\system\Tests\Upgrade;
......@@ -16,6 +16,7 @@
* content) so that an upgrade from of a site under this profile may be tested.
*/
class BareMinimalUpgradePathTest extends UpgradePathTestBase {
public static function getInfo() {
return array(
'name' => 'Basic minimal profile upgrade path, bare database',
......@@ -43,12 +44,7 @@ public function testBasicMinimalUpgrade() {
$this->assertResponse(200);
// Verify that we are still logged in.
$this->drupalGet('user');
$this->clickLink(t('Edit'));
$this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), 'We are still logged in as admin at the end of the upgrade.');
// Logout and verify that we can login back in with our initial password.
$this->drupalLogout();
$this->finishUpgradeSession();
$this->drupalLogin((object) array(
'uid' => 1,
'name' => 'admin',
......@@ -95,4 +91,14 @@ public function testBasicMinimalUpgrade() {
$this->assertEqual(array('default' => 'Drupal\Core\Mail\PhpMail'), config('system.mail')->get('interface'), 'Default mail configuration set.');
}
/**
* Asserts that the session was kept during update. Also, log out.
*/
protected function finishUpgradeSession() {
$this->drupalGet('user');
$this->clickLink(t('Edit'));
$this->assertEqual($this->getUrl(), url('user/1/edit', array('absolute' => TRUE)), 'We are still logged in as admin at the end of the upgrade.');
$this->drupalLogout();
}
}
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