diff --git a/core/includes/update.inc b/core/includes/update.inc index e395fb6..61de857 100644 --- a/core/includes/update.inc +++ b/core/includes/update.inc @@ -229,6 +229,11 @@ function update_do_one($module, $number, $dependency_map, &$context) { function update_invoke_post_update($function, &$context) { $ret = []; + // Do not run any post update hooks if there are failed or pending updates. + if (!empty(update_get_update_list(TRUE))) { + return; + } + list($module, ) = explode('_post_update_', $function, 2); module_load_include('php', $module, $module . '.post_update'); if (function_exists($function)) { diff --git a/core/lib/Drupal/Core/Update/UpdateRegistry.php b/core/lib/Drupal/Core/Update/UpdateRegistry.php index 949d076..dc0bc3f 100644 --- a/core/lib/Drupal/Core/Update/UpdateRegistry.php +++ b/core/lib/Drupal/Core/Update/UpdateRegistry.php @@ -164,7 +164,7 @@ public function getMissingUpdateList() { // The description for an update comes from its Doxygen. $func = new \ReflectionFunction($function); $description = trim(str_replace(array("\n", '*', '/'), '', $func->getDocComment()), ' '); - $ret[$module]['pending'][$update] = "$description"; + $ret[$module]['pending'][$update] = $description; if (!isset($ret[$module]['start'])) { $ret[$module]['start'] = $update; } diff --git a/core/modules/system/src/Controller/DbUpdateController.php b/core/modules/system/src/Controller/DbUpdateController.php index 5aac272..c5fe862 100644 --- a/core/modules/system/src/Controller/DbUpdateController.php +++ b/core/modules/system/src/Controller/DbUpdateController.php @@ -287,7 +287,7 @@ protected function selection(Request $request) { '#type' => 'hidden', '#value' => $update['start'], ); - $build['start'][$module . '_updates'] = array( + $build['start'][$module . '_' . $update_type] = array( '#theme' => 'item_list', '#items' => $update['pending'], '#title' => $module . ' module', diff --git a/core/modules/system/src/Tests/Update/UpdatePathTestBase.php b/core/modules/system/src/Tests/Update/UpdatePathTestBase.php index 1b85098..c6281d0 100644 --- a/core/modules/system/src/Tests/Update/UpdatePathTestBase.php +++ b/core/modules/system/src/Tests/Update/UpdatePathTestBase.php @@ -124,6 +124,13 @@ protected $strictConfigSchema = FALSE; /** + * Fail the test if there are failed updates. + * + * @var bool + */ + protected $checkFailedUpdates = TRUE; + + /** * Constructs an UpdatePathTestCase object. * * @param $test_id @@ -246,7 +253,9 @@ protected function runUpdates() { $this->clickLink(t('Apply pending updates')); // Ensure there are no failed updates. - $this->assertNoRaw('' . t('Failed:') . ''); + if ($this->checkFailedUpdates) { + $this->assertNoRaw('' . t('Failed:') . ''); + } // 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 diff --git a/core/modules/system/src/Tests/Update/UpdatePostUpdateFailingTest.php b/core/modules/system/src/Tests/Update/UpdatePostUpdateFailingTest.php new file mode 100644 index 0000000..d348b8f --- /dev/null +++ b/core/modules/system/src/Tests/Update/UpdatePostUpdateFailingTest.php @@ -0,0 +1,54 @@ +databaseDumpFiles = [ + __DIR__ . '/../../../tests/fixtures/update/drupal-8.bare.standard.php.gz', + __DIR__ . '/../../../tests/fixtures/update/drupal-8.update-test-postupdate-failing-enabled.php', + ]; + } + + /** + * Tests hook_post_update_NAME(). + */ + public function testPostUpdate() { + // There are expected to be failed updates. + $this->checkFailedUpdates = FALSE; + + $this->runUpdates(); + + // There should be no post update hooks registered as being run. + $this->assertIdentical([], \Drupal::state()->get('post_update_test_execution', [])); + + $key_value = \Drupal::keyValue('update__post_update'); + $this->assertEqual([], $key_value->get('existing_updates')); + } + + /** + * {@inheritdoc} + * + * Check that all expected updates are displayed. + */ + protected function doSelectionTest() { + $this->assertRaw('8001 - This update will fail.'); + $this->assertRaw('8002 - A further update.'); + $this->assertRaw('Should not be run since there are pending updates.'); + } + +} diff --git a/core/modules/system/tests/fixtures/update/drupal-8.update-test-postupdate-failing-enabled.php b/core/modules/system/tests/fixtures/update/drupal-8.update-test-postupdate-failing-enabled.php new file mode 100644 index 0000000..f19a1f1 --- /dev/null +++ b/core/modules/system/tests/fixtures/update/drupal-8.update-test-postupdate-failing-enabled.php @@ -0,0 +1,39 @@ +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(); + diff --git a/core/modules/system/tests/modules/update_test_failing/update_test_failing.info.yml b/core/modules/system/tests/modules/update_test_failing/update_test_failing.info.yml new file mode 100644 index 0000000..f6841f3 --- /dev/null +++ b/core/modules/system/tests/modules/update_test_failing/update_test_failing.info.yml @@ -0,0 +1,6 @@ +name: 'Update test failing' +type: module +description: 'Support module for update testing when an update hook is failing.' +package: Testing +version: VERSION +core: 8.x diff --git a/core/modules/system/tests/modules/update_test_failing/update_test_failing.install b/core/modules/system/tests/modules/update_test_failing/update_test_failing.install new file mode 100644 index 0000000..a26c7f3 --- /dev/null +++ b/core/modules/system/tests/modules/update_test_failing/update_test_failing.install @@ -0,0 +1,22 @@ +get('post_update_test_execution', []); + $execution[] = __FUNCTION__; + \Drupal::state()->set('post_update_test_execution', $execution); +}