Skip to content

Commit 210757f

Browse files
committed
Issue #3455820 by nicxvan, alexpott, smustgrave: Decompress files for config_install
1 parent c8e00ee commit 210757f

File tree

247 files changed

+8121
-25
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

247 files changed

+8121
-25
lines changed

.cspell.json

+1
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
"modules/system/tests/logo.svgz",
2525
"node_modules/*",
2626
"profiles/demo_umami/modules/demo_umami_content/default_content/languages/es/**/*",
27+
"tests/fixtures/config_install/*",
2728
"tests/fixtures/files/*",
2829
"tests/Drupal/Tests/Component/Annotation/Doctrine/**",
2930
"tests/PHPStan/vendor/**",

.phpstan-baseline.php

+16-1
Original file line numberDiff line numberDiff line change
@@ -398,7 +398,7 @@
398398
'path' => __DIR__ . '/lib/Drupal/Core/Extension/ExtensionVersion.php',
399399
];
400400
$ignoreErrors[] = [
401-
'message' => '#^The "module_installer\\.uninstall_validators" service is deprecated in drupal:11.1.0 and is removed from drupal:12.0.0\\. Inject "\\!tagged_iterator module_install\\.uninstall_validator" instead\\. See https\\://www\\.drupal\\.org/node/3432595$#',
401+
'message' => '#^The "module_installer\\.uninstall_validators" service is deprecated in drupal\\:11\\.1\\.0 and is removed from drupal\\:12\\.0\\.0\\. Inject "\\!tagged_iterator module_install\\.uninstall_validator" instead\\. See https\\://www\\.drupal\\.org/node/3432595$#',
402402
'count' => 1,
403403
'path' => __DIR__ . '/lib/Drupal/Core/Extension/ModuleInstaller.php',
404404
];
@@ -2379,6 +2379,21 @@
23792379
'count' => 2,
23802380
'path' => __DIR__ . '/tests/Drupal/BuildTests/Framework/Tests/BuildTestTest.php',
23812381
];
2382+
$ignoreErrors[] = [
2383+
'message' => '#^Drupal\\\\Tests\\\\BrowserTestBase\\:\\:\\$defaultTheme is required\\. See https\\://www\\.drupal\\.org/node/3083055, which includes recommendations on which theme to use\\.$#',
2384+
'count' => 1,
2385+
'path' => __DIR__ . '/tests/Drupal/FunctionalTests/Installer/InstallerExistingConfigExistingSettingsTest.php',
2386+
];
2387+
$ignoreErrors[] = [
2388+
'message' => '#^Drupal\\\\Tests\\\\BrowserTestBase\\:\\:\\$defaultTheme is required\\. See https\\://www\\.drupal\\.org/node/3083055, which includes recommendations on which theme to use\\.$#',
2389+
'count' => 1,
2390+
'path' => __DIR__ . '/tests/Drupal/FunctionalTests/Installer/InstallerExistingConfigNoSystemSiteTest.php',
2391+
];
2392+
$ignoreErrors[] = [
2393+
'message' => '#^Drupal\\\\Tests\\\\BrowserTestBase\\:\\:\\$defaultTheme is required\\. See https\\://www\\.drupal\\.org/node/3083055, which includes recommendations on which theme to use\\.$#',
2394+
'count' => 1,
2395+
'path' => __DIR__ . '/tests/Drupal/FunctionalTests/Installer/InstallerExistingConfigTest.php',
2396+
];
23822397
$ignoreErrors[] = [
23832398
// identifier: variable.undefined
23842399
'message' => '#^Variable \\$found might not be defined\\.$#',
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,184 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Drupal\FunctionalTests\Installer;
6+
7+
use Drupal\Component\Serialization\Yaml;
8+
use Drupal\Core\Database\Database;
9+
use Drupal\Core\Installer\Form\SelectProfileForm;
10+
11+
/**
12+
* Provides a base class for testing installing from existing configuration.
13+
*/
14+
abstract class InstallerConfigDirectoryTestBase extends InstallerTestBase {
15+
16+
/**
17+
* This is set by the profile in the core.extension extracted.
18+
*
19+
* If set to FALSE, then the install will proceed without an install profile.
20+
*/
21+
protected $profile = NULL;
22+
23+
/**
24+
* @todo Fill out docblock.
25+
*/
26+
protected $existingSyncDirectory = FALSE;
27+
28+
/**
29+
* This copies a source directory to a destination directory recursively.
30+
*
31+
* @param string $source
32+
* Source directory.
33+
* @param string $destination
34+
* Destination directory.
35+
*/
36+
protected function copyDirectory(string $source, string $destination): void {
37+
if (!is_dir($destination)) {
38+
mkdir($destination, 0755, TRUE);
39+
}
40+
$files = scandir($source);
41+
foreach ($files as $file) {
42+
if ($file !== '.' && $file !== '..') {
43+
$sourceFile = $source . '/' . $file;
44+
$destinationFile = $destination . '/' . $file;
45+
if (is_dir($sourceFile)) {
46+
$this->copyDirectory($sourceFile, $destinationFile);
47+
}
48+
else {
49+
copy($sourceFile, $destinationFile);
50+
}
51+
}
52+
}
53+
}
54+
55+
/**
56+
* {@inheritdoc}
57+
*/
58+
protected function prepareEnvironment() {
59+
parent::prepareEnvironment();
60+
61+
if ($this->profile === NULL) {
62+
$core_extension_location = $this->getConfigLocation() . '/core.extension.yml';
63+
$core_extension = Yaml::decode(file_get_contents($core_extension_location));
64+
$this->profile = $core_extension['profile'];
65+
}
66+
67+
if ($this->profile !== FALSE) {
68+
// Create a profile for testing. We set core_version_requirement to '*' for
69+
// the test so that it does not need to be updated between major versions.
70+
$info = [
71+
'type' => 'profile',
72+
'core_version_requirement' => '*',
73+
'name' => 'Configuration installation test profile (' . $this->profile . ')',
74+
];
75+
76+
// File API functions are not available yet.
77+
$path = $this->siteDirectory . '/profiles/' . $this->profile;
78+
79+
// Put the sync directory inside the profile.
80+
$config_sync_directory = $path . '/config/sync';
81+
82+
mkdir($path, 0777, TRUE);
83+
file_put_contents("$path/{$this->profile}.info.yml", Yaml::encode($info));
84+
}
85+
else {
86+
// If we have no profile we must use an existing sync directory.
87+
$this->existingSyncDirectory = TRUE;
88+
$config_sync_directory = $this->siteDirectory . '/config/sync';
89+
}
90+
91+
if ($this->existingSyncDirectory) {
92+
$config_sync_directory = $this->siteDirectory . '/config/sync';
93+
$this->settings['settings']['config_sync_directory'] = (object) [
94+
'value' => $config_sync_directory,
95+
'required' => TRUE,
96+
];
97+
}
98+
99+
// Create config/sync directory and extract tarball contents to it.
100+
mkdir($config_sync_directory, 0777, TRUE);
101+
$this->copyDirectory($this->getConfigLocation(), $config_sync_directory);
102+
103+
// Add the module that is providing the database driver to the list of
104+
// modules that can not be uninstalled in the core.extension configuration.
105+
if (file_exists($config_sync_directory . '/core.extension.yml')) {
106+
$core_extension = Yaml::decode(file_get_contents($config_sync_directory . '/core.extension.yml'));
107+
$module = Database::getConnection()->getProvider();
108+
if ($module !== 'core') {
109+
$core_extension['module'][$module] = 0;
110+
$core_extension['module'] = module_config_sort($core_extension['module']);
111+
}
112+
if ($this->profile === FALSE && array_key_exists('profile', $core_extension)) {
113+
// Remove the profile.
114+
unset($core_extension['module'][$core_extension['profile']]);
115+
unset($core_extension['profile']);
116+
117+
// Set a default theme to the first theme that will be installed as this
118+
// can not be retrieved from the profile.
119+
$this->defaultTheme = array_key_first($core_extension['theme']);
120+
}
121+
file_put_contents($config_sync_directory . '/core.extension.yml', Yaml::encode($core_extension));
122+
}
123+
}
124+
125+
/**
126+
* Gets the path to the configuration directory.
127+
*
128+
* The directory will be copied to the install profile's config/sync
129+
* directory for testing.
130+
*
131+
* @return string
132+
* The path to the configuration directory.
133+
*/
134+
abstract protected function getConfigLocation();
135+
136+
/**
137+
* {@inheritdoc}
138+
*/
139+
protected function installParameters() {
140+
$parameters = parent::installParameters();
141+
142+
// The options that change configuration are disabled when installing from
143+
// existing configuration.
144+
unset($parameters['forms']['install_configure_form']['site_name']);
145+
unset($parameters['forms']['install_configure_form']['site_mail']);
146+
unset($parameters['forms']['install_configure_form']['enable_update_status_module']);
147+
unset($parameters['forms']['install_configure_form']['enable_update_status_emails']);
148+
149+
return $parameters;
150+
}
151+
152+
/**
153+
* Confirms that the installation installed the configuration correctly.
154+
*/
155+
public function testConfigSync(): void {
156+
// After installation there is no snapshot and nothing to import.
157+
$change_list = $this->configImporter()->getStorageComparer()->getChangelist();
158+
$expected = [
159+
'create' => [],
160+
// The system.mail is changed configuration because the test system
161+
// changes it to ensure that mails are not sent.
162+
'update' => ['system.mail'],
163+
'delete' => [],
164+
'rename' => [],
165+
];
166+
$this->assertEquals($expected, $change_list);
167+
}
168+
169+
/**
170+
* Installer step: Select installation profile.
171+
*/
172+
protected function setUpProfile() {
173+
if ($this->existingSyncDirectory) {
174+
$edit = [
175+
'profile' => SelectProfileForm::CONFIG_INSTALL_PROFILE_KEY,
176+
];
177+
$this->submitForm($edit, $this->translations['Save and continue']);
178+
}
179+
else {
180+
parent::setUpProfile();
181+
}
182+
}
183+
184+
}

tests/Drupal/FunctionalTests/Installer/InstallerExistingConfigMultilingualTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
* @group Installer
1313
*/
14-
class InstallerExistingConfigMultilingualTest extends InstallerExistingConfigTestBase {
14+
class InstallerExistingConfigMultilingualTest extends InstallerConfigDirectoryTestBase {
1515

1616
/**
1717
* {@inheritdoc}
@@ -21,8 +21,8 @@ class InstallerExistingConfigMultilingualTest extends InstallerExistingConfigTes
2121
/**
2222
* {@inheritdoc}
2323
*/
24-
protected function getConfigTarball() {
25-
return __DIR__ . '/../../../fixtures/config_install/multilingual.tar.gz';
24+
protected function getConfigLocation() {
25+
return __DIR__ . '/../../../fixtures/config_install/multilingual';
2626
}
2727

2828
/**

tests/Drupal/FunctionalTests/Installer/InstallerExistingConfigNoConfigTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
* @group Installer
1111
*/
12-
class InstallerExistingConfigNoConfigTest extends InstallerExistingConfigTestBase {
12+
class InstallerExistingConfigNoConfigTest extends InstallerConfigDirectoryTestBase {
1313

1414
/**
1515
* {@inheritdoc}
@@ -28,8 +28,8 @@ protected function setUpSite() {
2828
/**
2929
* {@inheritdoc}
3030
*/
31-
protected function getConfigTarball() {
32-
return __DIR__ . '/../../../fixtures/config_install/testing_config_install_no_config.tar.gz';
31+
protected function getConfigLocation() {
32+
return __DIR__ . '/../../../fixtures/config_install/testing_config_install_no_config';
3333
}
3434

3535
/**

tests/Drupal/FunctionalTests/Installer/InstallerExistingConfigNoSystemSiteTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
* @group Installer
1111
*/
12-
class InstallerExistingConfigNoSystemSiteTest extends InstallerExistingConfigTestBase {
12+
class InstallerExistingConfigNoSystemSiteTest extends InstallerConfigDirectoryTestBase {
1313

1414
/**
1515
* {@inheritdoc}
@@ -44,8 +44,8 @@ public function testConfigSync(): void {
4444
/**
4545
* {@inheritdoc}
4646
*/
47-
protected function getConfigTarball() {
48-
return __DIR__ . '/../../../fixtures/config_install/testing_config_install.tar.gz';
47+
protected function getConfigLocation() {
48+
return __DIR__ . '/../../../fixtures/config_install/testing_config_install';
4949
}
5050

5151
}

tests/Drupal/FunctionalTests/Installer/InstallerExistingConfigProfileHookInstall.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
* @group Installer
1111
*/
12-
class InstallerExistingConfigProfileHookInstall extends InstallerExistingConfigTestBase {
12+
class InstallerExistingConfigProfileHookInstall extends InstallerConfigDirectoryTestBase {
1313

1414
protected $profile = 'config_profile_with_hook_install';
1515

@@ -55,10 +55,10 @@ protected function setUpSite() {
5555
/**
5656
* {@inheritdoc}
5757
*/
58-
protected function getConfigTarball() {
58+
protected function getConfigLocation() {
5959
// We're not going to get to the config import stage so this does not
6060
// matter.
61-
return __DIR__ . '/../../../fixtures/config_install/testing_config_install_no_config.tar.gz';
61+
return __DIR__ . '/../../../fixtures/config_install/testing_config_install_no_config';
6262
}
6363

6464
/**

tests/Drupal/FunctionalTests/Installer/InstallerExistingConfigSyncDirectoryMultilingualTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
* @group Installer
1515
*/
16-
class InstallerExistingConfigSyncDirectoryMultilingualTest extends InstallerExistingConfigTestBase {
16+
class InstallerExistingConfigSyncDirectoryMultilingualTest extends InstallerConfigDirectoryTestBase {
1717

1818
/**
1919
* {@inheritdoc}
@@ -43,8 +43,8 @@ protected function setUpProfile() {
4343
/**
4444
* {@inheritdoc}
4545
*/
46-
protected function getConfigTarball() {
47-
return __DIR__ . '/../../../fixtures/config_install/multilingual.tar.gz';
46+
protected function getConfigLocation() {
47+
return __DIR__ . '/../../../fixtures/config_install/multilingual';
4848
}
4949

5050
/**

tests/Drupal/FunctionalTests/Installer/InstallerExistingConfigSyncDirectoryProfileHookInstall.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
* @group Installer
1111
*/
12-
class InstallerExistingConfigSyncDirectoryProfileHookInstall extends InstallerExistingConfigTestBase {
12+
class InstallerExistingConfigSyncDirectoryProfileHookInstall extends InstallerConfigDirectoryTestBase {
1313

1414
/**
1515
* {@inheritdoc}
@@ -74,8 +74,8 @@ protected function setUpSite() {
7474
/**
7575
* {@inheritdoc}
7676
*/
77-
protected function getConfigTarball() {
78-
return __DIR__ . '/../../../fixtures/config_install/multilingual.tar.gz';
77+
protected function getConfigLocation() {
78+
return __DIR__ . '/../../../fixtures/config_install/multilingual';
7979
}
8080

8181
/**

tests/Drupal/FunctionalTests/Installer/InstallerExistingConfigSyncDirectoryProfileMismatchTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
* @group Installer
1111
*/
12-
class InstallerExistingConfigSyncDirectoryProfileMismatchTest extends InstallerExistingConfigTestBase {
12+
class InstallerExistingConfigSyncDirectoryProfileMismatchTest extends InstallerConfigDirectoryTestBase {
1313

1414
/**
1515
* {@inheritdoc}
@@ -29,8 +29,8 @@ class InstallerExistingConfigSyncDirectoryProfileMismatchTest extends InstallerE
2929
/**
3030
* {@inheritdoc}
3131
*/
32-
protected function getConfigTarball() {
33-
return __DIR__ . '/../../../fixtures/config_install/multilingual.tar.gz';
32+
protected function getConfigLocation() {
33+
return __DIR__ . '/../../../fixtures/config_install/multilingual';
3434
}
3535

3636
/**

tests/Drupal/FunctionalTests/Installer/InstallerExistingConfigTest.php

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
*
1212
* @group Installer
1313
*/
14-
class InstallerExistingConfigTest extends InstallerExistingConfigTestBase {
14+
class InstallerExistingConfigTest extends InstallerConfigDirectoryTestBase {
1515

1616
/**
1717
* {@inheritdoc}
@@ -37,8 +37,8 @@ public function setUpSettings() {
3737
/**
3838
* {@inheritdoc}
3939
*/
40-
protected function getConfigTarball() {
41-
return __DIR__ . '/../../../fixtures/config_install/testing_config_install.tar.gz';
40+
protected function getConfigLocation() {
41+
return __DIR__ . '/../../../fixtures/config_install/testing_config_install';
4242
}
4343

4444
}

0 commit comments

Comments
 (0)