Skip to content
Snippets Groups Projects
Commit 898d602c authored by Ted Bowman's avatar Ted Bowman Committed by Adam G-H
Browse files

Issue #3241380 by tedbow, phenaproxima: Ensure DB updates are not pending

parent 2a305405
No related branches found
No related tags found
No related merge requests found
......@@ -46,6 +46,14 @@ services:
- '@automatic_updates.path_locator'
tags:
- { name: event_subscriber }
automatic_updates.pending_updates_validator:
class: Drupal\automatic_updates\Validator\PendingUpdatesValidator
arguments:
- '%app.root%'
- '@update.post_update_registry'
- '@string_translation'
tags:
- { name: event_subscriber }
automatic_updates.validator.file_system_permissions:
class: Drupal\automatic_updates\Validator\WritableFileSystemValidator
arguments:
......
<?php
namespace Drupal\automatic_updates\Validator;
use Drupal\automatic_updates\AutomaticUpdatesEvents;
use Drupal\automatic_updates\Event\UpdateEvent;
use Drupal\automatic_updates\Validation\ValidationResult;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\Core\StringTranslation\TranslationInterface;
use Drupal\Core\Update\UpdateRegistry;
use Drupal\Core\Url;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
/**
* Validates that there are no pending database updates.
*/
class PendingUpdatesValidator implements EventSubscriberInterface {
use StringTranslationTrait;
/**
* The Drupal root.
*
* @var string
*/
protected $appRoot;
/**
* The update registry service.
*
* @var \Drupal\Core\Update\UpdateRegistry
*/
protected $updateRegistry;
/**
* Constructs an PendingUpdatesValidator object.
*
* @param string $app_root
* The Drupal root.
* @param \Drupal\Core\Update\UpdateRegistry $update_registry
* The update registry service.
* @param \Drupal\Core\StringTranslation\TranslationInterface $translation
* The translation service.
*/
public function __construct(string $app_root, UpdateRegistry $update_registry, TranslationInterface $translation) {
$this->appRoot = $app_root;
$this->updateRegistry = $update_registry;
$this->setStringTranslation($translation);
}
/**
* Validates that there are no pending database updates.
*
* @param \Drupal\automatic_updates\Event\UpdateEvent $event
* The update event.
*/
public function checkPendingUpdates(UpdateEvent $event) {
require_once $this->appRoot . '/core/includes/install.inc';
require_once $this->appRoot . '/core/includes/update.inc';
drupal_load_updates();
$hook_updates = update_get_update_list();
$post_updates = $this->updateRegistry->getPendingUpdateFunctions();
if ($hook_updates || $post_updates) {
$message = $this->t('Some modules have database schema updates to install. You should run the <a href=":update">database update script</a> immediately.', [
':update' => Url::fromRoute('system.db_update')->toString(),
]);
$error = ValidationResult::createError([$message]);
$event->addValidationResult($error);
}
}
/**
* {@inheritdoc}
*/
public static function getSubscribedEvents() {
return [
AutomaticUpdatesEvents::PRE_START => 'checkPendingUpdates',
AutomaticUpdatesEvents::READINESS_CHECK => 'checkPendingUpdates',
];
}
}
<?php
/**
* @file
* Contains a fake database update function for testing.
*/
/**
* Here is a fake update.
*/
function automatic_updates_update_50000() {
}
<?php
/**
* @file
* Contains a fake post-update function for testing.
*/
/**
* Here is a fake post-update.
*/
function automatic_updates_post_update_test() {
}
<?php
namespace Drupal\Tests\automatic_updates\Kernel\ReadinessValidation;
use Drupal\automatic_updates\Event\UpdateEvent;
use Drupal\automatic_updates\Validation\ValidationResult;
use Drupal\KernelTests\KernelTestBase;
use Drupal\Tests\automatic_updates\Traits\ValidationTestTrait;
/**
* @covers \Drupal\automatic_updates\Validator\PendingUpdatesValidator
*
* @group automatic_updates
*/
class PendingUpdatesValidatorTest extends KernelTestBase {
use ValidationTestTrait;
/**
* {@inheritdoc}
*/
protected static $modules = [
'automatic_updates',
'package_manager',
'system',
'update',
];
/**
* {@inheritdoc}
*/
protected function setUp(): void {
parent::setUp();
// Make the update system think that all of System's post-update functions
// have run. Since kernel tests don't normally install modules and register
// their updates, we need to do this so that the validator is being tested
// from a clean, fully up-to-date state.
$updates = $this->container->get('update.post_update_registry')
->getPendingUpdateFunctions();
$this->container->get('keyvalue')
->get('post_update')
->set('existing_updates', $updates);
}
/**
* Tests that no error is raised if there are no pending updates.
*/
public function testNoPendingUpdates(): void {
$event = new UpdateEvent();
$this->container->get('automatic_updates.pending_updates_validator')
->checkPendingUpdates($event);
$this->assertEmpty($event->getResults());
}
/**
* Tests that an error is raised if there are pending schema updates.
*/
public function testPendingUpdateHook(): void {
require __DIR__ . '/../../../fixtures/db_update.php';
$this->container->get('keyvalue')
->get('system.schema')
->set('automatic_updates', \Drupal::CORE_MINIMUM_SCHEMA_VERSION);
$result = ValidationResult::createError(['Some modules have database schema updates to install. You should run the <a href="/update.php">database update script</a> immediately.']);
$event = new UpdateEvent();
$this->container->get('automatic_updates.pending_updates_validator')
->checkPendingUpdates($event);
$this->assertValidationResultsEqual([$result], $event->getResults());
}
/**
* Tests that an error is raised if there are pending post-updates.
*/
public function testPendingPostUpdate(): void {
require __DIR__ . '/../../../fixtures/post_update.php';
$result = ValidationResult::createError(['Some modules have database schema updates to install. You should run the <a href="/update.php">database update script</a> immediately.']);
$event = new UpdateEvent();
$this->container->get('automatic_updates.pending_updates_validator')
->checkPendingUpdates($event);
$this->assertValidationResultsEqual([$result], $event->getResults());
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment