Issue #3063912 by alexpott, jhedstrom: Move UpdatePathTestBase::runUpdates() to a trait
(cherry picked from commit 68f74feca21c13782c8d2032d503fe724db98e0b)merge-requests/64/head
parent
8a2e4f35ea
commit
946fe169d4
|
@ -1,39 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Partial database to mimic the installation of the update_test_post_update
|
||||
* module.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
// Set the schema version.
|
||||
$connection->merge('key_value')
|
||||
->condition('collection', 'system.schema')
|
||||
->condition('name', 'update_test_postupdate')
|
||||
->fields([
|
||||
'collection' => 'system.schema',
|
||||
'name' => 'update_test_postupdate',
|
||||
'value' => 'i:8000;',
|
||||
])
|
||||
->execute();
|
||||
|
||||
// Update core.extension.
|
||||
$extensions = $connection->select('config')
|
||||
->fields('config', ['data'])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.extension')
|
||||
->execute()
|
||||
->fetchField();
|
||||
$extensions = unserialize($extensions);
|
||||
$extensions['module']['update_test_postupdate'] = 8000;
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => serialize($extensions),
|
||||
])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.extension')
|
||||
->execute();
|
|
@ -1,38 +0,0 @@
|
|||
<?php
|
||||
|
||||
/**
|
||||
* @file
|
||||
* Partial database to mimic the installation of the update_test_failing module.
|
||||
*/
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
|
||||
$connection = Database::getConnection();
|
||||
|
||||
// Set the schema version.
|
||||
$connection->merge('key_value')
|
||||
->condition('collection', 'system.schema')
|
||||
->condition('name', 'update_test_failing')
|
||||
->fields([
|
||||
'collection' => 'system.schema',
|
||||
'name' => 'update_test_failing',
|
||||
'value' => 'i:8000;',
|
||||
])
|
||||
->execute();
|
||||
|
||||
// Update core.extension.
|
||||
$extensions = $connection->select('config')
|
||||
->fields('config', ['data'])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.extension')
|
||||
->execute()
|
||||
->fetchField();
|
||||
$extensions = unserialize($extensions);
|
||||
$extensions['module']['update_test_failing'] = 8000;
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => serialize($extensions),
|
||||
])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.extension')
|
||||
->execute();
|
|
@ -3,15 +3,16 @@
|
|||
namespace Drupal\Tests\system\Functional\Update;
|
||||
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\UpdatePathTestTrait;
|
||||
|
||||
/**
|
||||
* Ensures that a broken or out-of-date element info cache is not used.
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class BrokenCacheUpdateTest extends UpdatePathTestBase {
|
||||
class BrokenCacheUpdateTest extends BrowserTestBase {
|
||||
use UpdatePathTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -21,10 +22,9 @@ class BrokenCacheUpdateTest extends UpdatePathTestBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../tests/fixtures/update/drupal-8.6.0.bare.testing.php.gz',
|
||||
];
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->ensureUpdatesToRun();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -40,7 +40,8 @@ class BrokenCacheUpdateTest extends UpdatePathTestBase {
|
|||
->execute();
|
||||
|
||||
// Create broken element info caches entries.
|
||||
$insert = $connection->insert('cache_discovery');
|
||||
$insert = $connection->upsert('cache_discovery');
|
||||
$insert->key('cid');
|
||||
$fields = [
|
||||
'cid' => 'element_info',
|
||||
'data' => 'BROKEN',
|
||||
|
|
|
@ -2,31 +2,23 @@
|
|||
|
||||
namespace Drupal\Tests\system\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\UpdatePathTestTrait;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
|
||||
/**
|
||||
* Modules can introduce new dependencies and enable them in update hooks.
|
||||
*
|
||||
* @group system
|
||||
* @group legacy
|
||||
*/
|
||||
class UpdatePathNewDependencyTest extends UpdatePathTestBase {
|
||||
class UpdatePathNewDependencyTest extends BrowserTestBase {
|
||||
use UpdatePathTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected $defaultTheme = 'stark';
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../tests/fixtures/update/drupal-8.6.0.bare.testing.php.gz',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that a module can add services that depend on new modules.
|
||||
*/
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
namespace Drupal\Tests\system\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\UpdatePathTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the presence of JavaScript at update.php.
|
||||
|
@ -10,7 +11,8 @@ use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
|||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class UpdatePathTestJavaScriptTest extends UpdatePathTestBase {
|
||||
class UpdatePathTestJavaScriptTest extends BrowserTestBase {
|
||||
use UpdatePathTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -20,10 +22,9 @@ class UpdatePathTestJavaScriptTest extends UpdatePathTestBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
];
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->ensureUpdatesToRun();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -2,13 +2,15 @@
|
|||
|
||||
namespace Drupal\Tests\system\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
|
||||
/**
|
||||
* Runs UpdatePathWithBrokenRoutingTest with a dump filled with content.
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class UpdatePathWithBrokenRoutingFilledTest extends UpdatePathWithBrokenRoutingTest {
|
||||
class UpdatePathWithBrokenRoutingFilledTest extends UpdatePathTestBase {
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -19,8 +21,30 @@ class UpdatePathWithBrokenRoutingFilledTest extends UpdatePathWithBrokenRoutingT
|
|||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
parent::setDatabaseDumpFiles();
|
||||
$this->databaseDumpFiles[0] = __DIR__ . '/../../../../tests/fixtures/update/drupal-8.filled.standard.php.gz';
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../tests/fixtures/update/drupal-8.8.0.filled.standard.php.gz',
|
||||
__DIR__ . '/../../../../tests/fixtures/update/drupal-8.broken_routing.php',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests running update.php with some form of broken routing.
|
||||
*/
|
||||
public function testWithBrokenRouting() {
|
||||
// Simulate a broken router, and make sure the front page is
|
||||
// inaccessible.
|
||||
\Drupal::state()->set('update_script_test_broken_inbound', TRUE);
|
||||
\Drupal::service('cache_tags.invalidator')->invalidateTags(['route_match', 'rendered']);
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertResponse(500);
|
||||
|
||||
$this->runUpdates();
|
||||
|
||||
// Remove the simulation of the broken router, and make sure we can get to
|
||||
// the front page again.
|
||||
\Drupal::state()->set('update_script_test_broken_inbound', FALSE);
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2,15 +2,17 @@
|
|||
|
||||
namespace Drupal\Tests\system\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\UpdatePathTestTrait;
|
||||
|
||||
/**
|
||||
* Tests the update path with a broken router.
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class UpdatePathWithBrokenRoutingTest extends UpdatePathTestBase {
|
||||
class UpdatePathWithBrokenRoutingTest extends BrowserTestBase {
|
||||
use UpdatePathTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -20,11 +22,9 @@ class UpdatePathWithBrokenRoutingTest extends UpdatePathTestBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
__DIR__ . '/../../../../tests/fixtures/update/drupal-8.broken_routing.php',
|
||||
];
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$this->ensureUpdatesToRun();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -34,11 +34,11 @@ class UpdatePathWithBrokenRoutingTest extends UpdatePathTestBase {
|
|||
// Simulate a broken router, and make sure the front page is
|
||||
// inaccessible.
|
||||
\Drupal::state()->set('update_script_test_broken_inbound', TRUE);
|
||||
\Drupal::service('cache_tags.invalidator')->invalidateTags(['route_match', 'rendered']);
|
||||
$this->resetAll();
|
||||
$this->drupalGet('<front>');
|
||||
$this->assertResponse(500);
|
||||
|
||||
$this->runUpdates();
|
||||
$this->runUpdates(Url::fromRoute('system.db_update', [], ['path_processing' => FALSE]));
|
||||
|
||||
// Remove the simulation of the broken router, and make sure we can get to
|
||||
// the front page again.
|
||||
|
|
|
@ -2,15 +2,17 @@
|
|||
|
||||
namespace Drupal\Tests\system\Functional\Update;
|
||||
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\UpdatePathTestTrait;
|
||||
|
||||
/**
|
||||
* Tests hook_post_update() when there are failing update hooks.
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class UpdatePostUpdateFailingTest extends UpdatePathTestBase {
|
||||
class UpdatePostUpdateFailingTest extends BrowserTestBase {
|
||||
use UpdatePathTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -20,11 +22,37 @@ class UpdatePostUpdateFailingTest extends UpdatePathTestBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
__DIR__ . '/../../../../tests/fixtures/update/drupal-8.update-test-postupdate-failing-enabled.php',
|
||||
];
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$connection = Database::getConnection();
|
||||
|
||||
// Set the schema version.
|
||||
$connection->merge('key_value')
|
||||
->condition('collection', 'system.schema')
|
||||
->condition('name', 'update_test_failing')
|
||||
->fields([
|
||||
'collection' => 'system.schema',
|
||||
'name' => 'update_test_failing',
|
||||
'value' => 'i:8000;',
|
||||
])
|
||||
->execute();
|
||||
|
||||
// Update core.extension.
|
||||
$extensions = $connection->select('config')
|
||||
->fields('config', ['data'])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.extension')
|
||||
->execute()
|
||||
->fetchField();
|
||||
$extensions = unserialize($extensions);
|
||||
$extensions['module']['update_test_failing'] = 8000;
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => serialize($extensions),
|
||||
])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.extension')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -3,15 +3,17 @@
|
|||
namespace Drupal\Tests\system\Functional\Update;
|
||||
|
||||
use Drupal\Component\Render\FormattableMarkup;
|
||||
use Drupal\FunctionalTests\Update\UpdatePathTestBase;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\UpdatePathTestTrait;
|
||||
|
||||
/**
|
||||
* Tests hook_post_update().
|
||||
*
|
||||
* @group Update
|
||||
* @group legacy
|
||||
*/
|
||||
class UpdatePostUpdateTest extends UpdatePathTestBase {
|
||||
class UpdatePostUpdateTest extends BrowserTestBase {
|
||||
use UpdatePathTestTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
|
@ -21,19 +23,43 @@ class UpdatePostUpdateTest extends UpdatePathTestBase {
|
|||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function setDatabaseDumpFiles() {
|
||||
$this->databaseDumpFiles = [
|
||||
__DIR__ . '/../../../../tests/fixtures/update/drupal-8.bare.standard.php.gz',
|
||||
__DIR__ . '/../../../../tests/fixtures/update/drupal-8.update-test-postupdate-enabled.php',
|
||||
];
|
||||
protected function setUp() {
|
||||
parent::setUp();
|
||||
$connection = Database::getConnection();
|
||||
|
||||
// Set the schema version.
|
||||
$connection->merge('key_value')
|
||||
->condition('collection', 'system.schema')
|
||||
->condition('name', 'update_test_postupdate')
|
||||
->fields([
|
||||
'collection' => 'system.schema',
|
||||
'name' => 'update_test_postupdate',
|
||||
'value' => 'i:8000;',
|
||||
])
|
||||
->execute();
|
||||
|
||||
// Update core.extension.
|
||||
$extensions = $connection->select('config')
|
||||
->fields('config', ['data'])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.extension')
|
||||
->execute()
|
||||
->fetchField();
|
||||
$extensions = unserialize($extensions);
|
||||
$extensions['module']['update_test_postupdate'] = 8000;
|
||||
$connection->update('config')
|
||||
->fields([
|
||||
'data' => serialize($extensions),
|
||||
])
|
||||
->condition('collection', '')
|
||||
->condition('name', 'core.extension')
|
||||
->execute();
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function doSelectionTest() {
|
||||
parent::doSelectionTest();
|
||||
|
||||
// Ensure that normal and post_update updates are merged together on the
|
||||
// selection page.
|
||||
$this->assertRaw('<ul><li>8001 - Normal update_N() function. </li><li>First update.</li><li>Second update.</li><li>Test0 update.</li><li>Test1 update.</li><li>Testing batch processing in post updates update.</li></ul>');
|
||||
|
|
|
@ -6,13 +6,12 @@ use Drupal\Component\Utility\Crypt;
|
|||
use Drupal\Core\Site\Settings;
|
||||
use Drupal\Core\Test\TestRunnerKernel;
|
||||
use Drupal\Tests\BrowserTestBase;
|
||||
use Drupal\Tests\SchemaCheckTestTrait;
|
||||
use Drupal\Core\Database\Database;
|
||||
use Drupal\Core\DependencyInjection\ContainerBuilder;
|
||||
use Drupal\Core\File\FileSystemInterface;
|
||||
use Drupal\Core\Language\Language;
|
||||
use Drupal\Core\Url;
|
||||
use Drupal\Tests\RequirementsPageTrait;
|
||||
use Drupal\Tests\UpdatePathTestTrait;
|
||||
use Drupal\user\Entity\User;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
|
@ -43,9 +42,9 @@ use Symfony\Component\HttpFoundation\Request;
|
|||
* @see hook_update_N()
|
||||
*/
|
||||
abstract class UpdatePathTestBase extends BrowserTestBase {
|
||||
|
||||
use SchemaCheckTestTrait;
|
||||
use RequirementsPageTrait;
|
||||
use UpdatePathTestTrait {
|
||||
runUpdates as doRunUpdates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Modules to enable after the database is loaded.
|
||||
|
@ -125,13 +124,6 @@ abstract class UpdatePathTestBase extends BrowserTestBase {
|
|||
*/
|
||||
protected $strictConfigSchema = FALSE;
|
||||
|
||||
/**
|
||||
* Fail the test if there are failed updates.
|
||||
*
|
||||
* @var bool
|
||||
*/
|
||||
protected $checkFailedUpdates = TRUE;
|
||||
|
||||
/**
|
||||
* Constructs an UpdatePathTestCase object.
|
||||
*
|
||||
|
@ -298,117 +290,7 @@ abstract class UpdatePathTestBase extends BrowserTestBase {
|
|||
$this->fail('Missing zlib requirement for update tests.');
|
||||
return FALSE;
|
||||
}
|
||||
// The site might be broken at the time so logging in using the UI might
|
||||
// not work, so we use the API itself.
|
||||
drupal_rewrite_settings([
|
||||
'settings' => [
|
||||
'update_free_access' => (object) [
|
||||
'value' => TRUE,
|
||||
'required' => TRUE,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$this->drupalGet($this->updateUrl);
|
||||
$this->updateRequirementsProblem();
|
||||
$this->clickLink(t('Continue'));
|
||||
|
||||
$this->doSelectionTest();
|
||||
// Run the update hooks.
|
||||
$this->clickLink(t('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':
|
||||
$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.
|
||||
foreach (array_keys(array_diff_key($config_module_list, $module_handler_list)) as $module) {
|
||||
$module_handler->addModule($module, drupal_get_path('module', $module));
|
||||
$modules_installed = TRUE;
|
||||
}
|
||||
$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);
|
||||
}
|
||||
|
||||
// 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.
|
||||
$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.');
|
||||
}
|
||||
}
|
||||
$this->doRunUpdates($this->updateUrl);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -449,13 +331,4 @@ abstract class UpdatePathTestBase extends BrowserTestBase {
|
|||
$account->save();
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests the selection page.
|
||||
*/
|
||||
protected function doSelectionTest() {
|
||||
// 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.
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
<?php
|
||||
|
||||
namespace Drupal\Tests;
|
||||
|
||||
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;
|
||||
|
||||
/**
|
||||
* Helper function to run pending database updates.
|
||||
*
|
||||
* @param string|null $update_url
|
||||
* The update URL.
|
||||
*/
|
||||
protected function runUpdates($update_url = NULL) {
|
||||
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(t('Continue'));
|
||||
|
||||
$this->doSelectionTest();
|
||||
// Run the update hooks.
|
||||
$this->clickLink(t('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':
|
||||
$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.
|
||||
foreach (array_keys(array_diff_key($config_module_list, $module_handler_list)) as $module) {
|
||||
$module_handler->addModule($module, drupal_get_path('module', $module));
|
||||
$modules_installed = TRUE;
|
||||
}
|
||||
$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);
|
||||
}
|
||||
|
||||
// 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.
|
||||
$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() {
|
||||
// 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() {
|
||||
\Drupal::service('module_installer')->install(['update_script_test']);
|
||||
// Reset the schema so there is an update to run.
|
||||
\Drupal::database()->update('key_value')
|
||||
->fields(['value' => serialize(8000)])
|
||||
->condition('collection', 'system.schema')
|
||||
->condition('name', 'update_script_test')
|
||||
->execute();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue