Initial Drupal 11 with DDEV setup
This commit is contained in:
185
web/core/tests/Drupal/Tests/UpdatePathTestTrait.php
Normal file
185
web/core/tests/Drupal/Tests/UpdatePathTestTrait.php
Normal file
@ -0,0 +1,185 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Drupal\Tests;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\Url;
|
||||
|
||||
/**
|
||||
* Trait UpdatePathTestTrait.
|
||||
*
|
||||
* For use on \Drupal\Tests\BrowserTestBase tests.
|
||||
*/
|
||||
trait UpdatePathTestTrait {
|
||||
use RequirementsPageTrait;
|
||||
use SchemaCheckTestTrait;
|
||||
|
||||
/**
|
||||
* Fail the test if there are failed updates.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $checkFailedUpdates = TRUE;
|
||||
|
||||
/**
|
||||
* Fail the test if there are entity field definition updates needed.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $checkEntityFieldDefinitionUpdates = TRUE;
|
||||
|
||||
/**
|
||||
* Helper function to run pending database updates.
|
||||
*
|
||||
* @param string|null $update_url
|
||||
* The update URL.
|
||||
*/
|
||||
protected function runUpdates($update_url = NULL): void {
|
||||
if (!$update_url) {
|
||||
$update_url = Url::fromRoute('system.db_update');
|
||||
}
|
||||
require_once $this->root . '/core/includes/update.inc';
|
||||
// The site might be broken at the time so logging in using the UI might
|
||||
// not work, so we use the API itself.
|
||||
$this->writeSettings([
|
||||
'settings' => [
|
||||
'update_free_access' => (object) [
|
||||
'value' => TRUE,
|
||||
'required' => TRUE,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->drupalGet($update_url);
|
||||
$this->updateRequirementsProblem();
|
||||
$this->clickLink('Continue');
|
||||
|
||||
$this->doSelectionTest();
|
||||
// Run the update hooks.
|
||||
$this->clickLink('Apply pending updates');
|
||||
$this->checkForMetaRefresh();
|
||||
|
||||
// Ensure there are no failed updates.
|
||||
if ($this->checkFailedUpdates) {
|
||||
$failure = $this->cssSelect('.failure');
|
||||
if ($failure) {
|
||||
$this->fail('The update failed with the following message: "' . reset($failure)->getText() . '"');
|
||||
}
|
||||
|
||||
// Ensure that there are no pending updates.
|
||||
foreach (['update', 'post_update'] as $update_type) {
|
||||
switch ($update_type) {
|
||||
case 'update':
|
||||
drupal_load_updates();
|
||||
$all_updates = update_get_update_list();
|
||||
break;
|
||||
|
||||
case 'post_update':
|
||||
$all_updates = \Drupal::service('update.post_update_registry')->getPendingUpdateInformation();
|
||||
break;
|
||||
}
|
||||
foreach ($all_updates as $module => $updates) {
|
||||
if (!empty($updates['pending'])) {
|
||||
foreach (array_keys($updates['pending']) as $update_name) {
|
||||
$this->fail("The $update_name() update function from the $module module did not run.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure that the container is updated if any modules are installed or
|
||||
// uninstalled during the update.
|
||||
/** @var \Drupal\Core\Extension\ModuleHandlerInterface $module_handler */
|
||||
$module_handler = $this->container->get('module_handler');
|
||||
$config_module_list = $this->config('core.extension')->get('module');
|
||||
$module_handler_list = $module_handler->getModuleList();
|
||||
$modules_installed = FALSE;
|
||||
// Modules that are in configuration but not the module handler have been
|
||||
// installed.
|
||||
$modules_installed = !empty(array_diff_key($config_module_list, $module_handler_list));
|
||||
$modules_uninstalled = FALSE;
|
||||
$module_handler_list = $module_handler->getModuleList();
|
||||
// Modules that are in the module handler but not configuration have been
|
||||
// uninstalled.
|
||||
foreach (array_keys(array_diff_key($module_handler_list, $config_module_list)) as $module) {
|
||||
$modules_uninstalled = TRUE;
|
||||
unset($module_handler_list[$module]);
|
||||
}
|
||||
if ($modules_installed || $modules_uninstalled) {
|
||||
// Note that resetAll() does not reset the kernel module list so we
|
||||
// have to do that manually.
|
||||
$this->kernel->updateModules($module_handler_list, $module_handler_list);
|
||||
}
|
||||
|
||||
// Close any open database connections. This allows DB drivers that store
|
||||
// static information to refresh it in the update runner.
|
||||
// @todo https://drupal.org/i/3222121 consider doing this in
|
||||
// \Drupal\Core\DrupalKernel::initializeContainer() for container
|
||||
// rebuilds.
|
||||
foreach (Database::getAllConnectionInfo() as $key => $info) {
|
||||
Database::closeConnection(NULL, $key);
|
||||
}
|
||||
|
||||
// If we have successfully clicked 'Apply pending updates' then we need to
|
||||
// clear the caches in the update test runner as this has occurred as part
|
||||
// of the updates.
|
||||
$this->resetAll();
|
||||
|
||||
// The config schema can be incorrect while the update functions are being
|
||||
// executed. But once the update has been completed, it needs to be valid
|
||||
// again. Assert the schema of all configuration objects now.
|
||||
$names = $this->container->get('config.storage')->listAll();
|
||||
|
||||
// Allow tests to opt out of checking specific configuration.
|
||||
$exclude = $this->getConfigSchemaExclusions();
|
||||
/** @var \Drupal\Core\Config\TypedConfigManagerInterface $typed_config */
|
||||
$typed_config = $this->container->get('config.typed');
|
||||
foreach ($names as $name) {
|
||||
if (in_array($name, $exclude, TRUE)) {
|
||||
// Skip checking schema if the config is listed in the
|
||||
// $configSchemaCheckerExclusions property.
|
||||
continue;
|
||||
}
|
||||
$config = $this->config($name);
|
||||
$this->assertConfigSchema($typed_config, $name, $config->get());
|
||||
}
|
||||
|
||||
// Ensure that the update hooks updated all entity schema.
|
||||
if ($this->checkEntityFieldDefinitionUpdates) {
|
||||
$needs_updates = \Drupal::entityDefinitionUpdateManager()->needsUpdates();
|
||||
if ($needs_updates) {
|
||||
foreach (\Drupal::entityDefinitionUpdateManager()->getChangeSummary() as $entity_type_id => $summary) {
|
||||
$entity_type_label = \Drupal::entityTypeManager()->getDefinition($entity_type_id)->getLabel();
|
||||
foreach ($summary as $message) {
|
||||
$this->fail("$entity_type_label: $message");
|
||||
}
|
||||
}
|
||||
// The above calls to `fail()` should prevent this from ever being
|
||||
// called, but it is here in case something goes really wrong.
|
||||
$this->assertFalse($needs_updates, 'After all updates ran, entity schema is up to date.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the selection page.
|
||||
*/
|
||||
protected function doSelectionTest(): void {
|
||||
// No-op. Tests wishing to do test the selection page or the general
|
||||
// update.php environment before running update.php can override this method
|
||||
// and implement their required tests.
|
||||
}
|
||||
|
||||
/**
|
||||
* Installs the update_script_test module and makes an update available.
|
||||
*/
|
||||
protected function ensureUpdatesToRun(): void {
|
||||
\Drupal::service('module_installer')->install(['update_script_test']);
|
||||
// Reset the schema so there is an update to run.
|
||||
\Drupal::service('update.update_hook_registry')->setInstalledVersion('update_script_test', 8000);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user