Skip to content
Snippets Groups Projects

Issue #3262303: Always clear stored validation results when modules are installed or uninstalled

Merged Issue #3262303: Always clear stored validation results when modules are installed or uninstalled
@@ -21,6 +21,7 @@ class ReadinessValidationManagerTest extends AutomaticUpdatesKernelTestBase {
* {@inheritdoc}
*/
protected static $modules = [
'automatic_updates',
'automatic_updates_test',
'package_manager',
'package_manager_bypass',
@@ -41,7 +42,7 @@ class ReadinessValidationManagerTest extends AutomaticUpdatesKernelTestBase {
* @covers ::getResults
*/
public function testGetResults(): void {
$this->enableModules(['automatic_updates', 'automatic_updates_test2']);
$this->enableModules(['automatic_updates_test2']);
$this->assertCheckerResultsFromManager([], TRUE);
$expected_results = [
@@ -86,135 +87,44 @@ class ReadinessValidationManagerTest extends AutomaticUpdatesKernelTestBase {
$this->assertCheckerResultsFromManager($errors_only_results, FALSE, SystemManager::REQUIREMENT_ERROR);
}
/**
* Tests that the manager is run after modules are installed.
*/
public function testRunOnInstall(): void {
$expected_results = [array_pop($this->testResults['checker_1'])];
TestChecker1::setTestResult($expected_results[0], ReadinessCheckEvent::class);
// Confirm that messages from an existing module are displayed when
// 'automatic_updates' is installed.
$this->container->get('module_installer')->install(['automatic_updates']);
$this->assertCheckerResultsFromManager($expected_results[0]);
// Confirm that the checkers are run when a module that provides a readiness
// checker is installed.
$expected_results = [
array_pop($this->testResults['checker_1']),
array_pop($this->testResults['checker_2']),
];
TestChecker1::setTestResult($expected_results[0], ReadinessCheckEvent::class);
TestChecker2::setTestResult($expected_results[1], ReadinessCheckEvent::class);
$this->container->get('module_installer')->install(['automatic_updates_test2']);
$expected_results_all = array_merge($expected_results[0], $expected_results[1]);
$this->assertCheckerResultsFromManager($expected_results_all);
// Confirm that the checkers are not run when a module that does not provide
// a readiness checker is installed.
$unexpected_results = [
array_pop($this->testResults['checker_1']),
array_pop($this->testResults['checker_2']),
];
TestChecker1::setTestResult($unexpected_results[0], ReadinessCheckEvent::class);
TestChecker2::setTestResult($unexpected_results[1], ReadinessCheckEvent::class);
$this->container->get('module_installer')->install(['help']);
$this->assertCheckerResultsFromManager($expected_results_all);
}
/**
* Tests that the manager is run after modules are uninstalled.
*/
public function testRunOnUninstall(): void {
$expected_results = [
array_pop($this->testResults['checker_1']),
array_pop($this->testResults['checker_2']),
];
TestChecker1::setTestResult($expected_results[0], ReadinessCheckEvent::class);
TestChecker2::setTestResult($expected_results[1], ReadinessCheckEvent::class);
// Confirm that messages from existing modules are displayed when
// 'automatic_updates' is installed.
$this->container->get('module_installer')->install(['automatic_updates', 'automatic_updates_test2', 'help']);
$expected_results_all = array_merge($expected_results[0], $expected_results[1]);
$this->assertCheckerResultsFromManager($expected_results_all);
// Confirm that the checkers are run when a module that provides a readiness
// checker is uninstalled.
$expected_results = [
array_pop($this->testResults['checker_1']),
];
TestChecker1::setTestResult($expected_results[0], ReadinessCheckEvent::class);
TestChecker2::setTestResult(array_pop($this->testResults['checker_2']), ReadinessCheckEvent::class);
$this->container->get('module_installer')->uninstall(['automatic_updates_test2']);
$this->assertCheckerResultsFromManager($expected_results[0]);
// Confirm that the checkers are not run when a module that does provide a
// readiness checker is uninstalled.
$unexpected_results = [
array_pop($this->testResults['checker_1']),
];
TestChecker1::setTestResult($unexpected_results[0], ReadinessCheckEvent::class);
$this->container->get('module_installer')->uninstall(['help']);
$this->assertCheckerResultsFromManager($expected_results[0]);
}
/**
* @covers ::runIfNoStoredResults
* @covers ::clearStoredResults
*/
public function testRunIfNeeded(): void {
$expected_results = array_pop($this->testResults['checker_1']);
/** @var \Drupal\automatic_updates\Validation\ReadinessValidationManager $manager */
$manager = $this->container->get('automatic_updates.readiness_validation_manager');
// Run readiness checks, so that there will be stored results.
$expected_results = $this->testResults['checker_1']['1 warning'];
TestChecker1::setTestResult($expected_results, ReadinessCheckEvent::class);
$this->container->get('module_installer')->install(['automatic_updates', 'automatic_updates_test2']);
$this->assertCheckerResultsFromManager($expected_results);
$this->assertValidationResultsEqual($expected_results, $manager->runIfNoStoredResults()->getResults());
$unexpected_results = array_pop($this->testResults['checker_1']);
// Because there are stored results, the readiness checks should not be
// run again; the results should be unchanged.
$unexpected_results = $this->testResults['checker_1']['2 warnings'];
TestChecker1::setTestResult($unexpected_results, ReadinessCheckEvent::class);
$manager = $this->container->get('automatic_updates.readiness_validation_manager');
// Confirm that the new results will not be returned because the checkers
// will not be run.
$manager->runIfNoStoredResults();
$this->assertCheckerResultsFromManager($expected_results);
$this->assertValidationResultsEqual($expected_results, $manager->runIfNoStoredResults()->getResults());
// Confirm that the new results will be returned because the checkers will
// be run if the stored results are deleted.
/** @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface $key_value */
$key_value = $this->container->get('keyvalue.expirable')->get('automatic_updates');
$key_value->delete('readiness_validation_last_run');
$manager->clearStoredResults();
$expected_results = $unexpected_results;
$manager->runIfNoStoredResults();
$this->assertCheckerResultsFromManager($expected_results);
$this->assertValidationResultsEqual($expected_results, $manager->runIfNoStoredResults()->getResults());
// Confirm that the results are the same after rebuilding the container.
$unexpected_results = array_pop($this->testResults['checker_1']);
$unexpected_results = $this->testResults['checker_1']['1 error'];
TestChecker1::setTestResult($unexpected_results, ReadinessCheckEvent::class);
/** @var \Drupal\Core\DrupalKernel $kernel */
$kernel = $this->container->get('kernel');
$this->container = $kernel->rebuildContainer();
$this->assertCheckerResultsFromManager($expected_results);
// Define a constant flag that will cause the readiness checker
// service priority to be altered. This will cause the priority of
// 'automatic_updates_test.checker' to change from 2 to 4 which will be now
// higher than 'automatic_updates_test2.checker' which has a priority of 3.
// Because the list of checker IDs is not identical to the previous checker
// run runIfNoStoredValidResults() will run the checkers again.
define('PACKAGE_MANAGER_TEST_VALIDATOR_PRIORITY', 1);
// Rebuild the container to trigger the readiness checker services to be
// reordered.
/** @var \Drupal\Core\DrupalKernelInterface $kernel */
$kernel = $this->container->get('kernel');
$this->container = $kernel->rebuildContainer();
$expected_results = $unexpected_results;
/** @var \Drupal\automatic_updates\Validation\ReadinessValidationManager $manager */
$manager = $this->container->get('automatic_updates.readiness_validation_manager');
$manager->runIfNoStoredResults();
$this->assertCheckerResultsFromManager($expected_results);
$this->assertValidationResultsEqual($expected_results, $manager->runIfNoStoredResults()->getResults());
}
/**
* Tests the Automatic Updates cron setting changes which stage class is used.
*/
public function testCronSetting(): void {
$this->enableModules(['automatic_updates']);
$stage_class = NULL;
$listener = function (ReadinessCheckEvent $event) use (&$stage_class): void {
$stage_class = get_class($event->getStage());
@@ -235,9 +145,6 @@ class ReadinessValidationManagerTest extends AutomaticUpdatesKernelTestBase {
* Tests that stored validation results are deleted after an update.
*/
public function testStoredResultsDeletedPostApply(): void {
$this->container->get('module_installer')
->install(['automatic_updates']);
// Ensure there's a simulated core release to update to.
$this->setReleaseMetadata(__DIR__ . '/../../../fixtures/release-history/drupal.9.8.2.xml');
@@ -276,25 +183,23 @@ class ReadinessValidationManagerTest extends AutomaticUpdatesKernelTestBase {
* Tests that stored results are cleared on module install or uninstall.
*/
public function testResultsClearedOnInstallAndUninstall(): void {
$this->enableModules(['automatic_updates']);
$expected_results = array_pop($this->testResults['checker_1']);
TestChecker1::setTestResult($expected_results, ReadinessCheckEvent::class);
/** @var \Drupal\automatic_updates\Validation\ReadinessValidationManager $manager */
$manager = $this->container->get('automatic_updates.readiness_validation_manager');
// Initially, there shouldn't be any stored results.
$this->assertNull($manager->getResults());
// Now run the validation, and ensure there are stored results (an empty
// array means the validation ran and produced no errors).
$this->assertSame([], $manager->runIfNoStoredResults()->getResults());
// Now install a module that has no readiness validators, and ensure the
// stored results were cleared.
// Run the validation, to ensure there are stored results.
$this->assertValidationResultsEqual($expected_results, $manager->runIfNoStoredResults()->getResults());
// Install a module and ensure that the stored results are cleared.
/** @var \Drupal\Core\Extension\ModuleInstallerInterface $module_installer */
$module_installer = $this->container->get('module_installer');
$module_installer->install(['help']);
$this->assertNull($manager->getResults());
// Run validation again, to ensure there are stored results (even if there
// no errors or warnings).
$this->assertSame([], $manager->runIfNoStoredResults()->getResults());
// Now uninstall a module and ensure the stored results are cleared.
// Run the validation again, to ensure there are stored results.
$this->assertValidationResultsEqual($expected_results, $manager->runIfNoStoredResults()->getResults());
// Uninstall a module and ensure that the stored results are cleared.
$module_installer->uninstall(['help']);
$this->assertNull($manager->getResults());
}
Loading