Skip to content
Snippets Groups Projects
Commit e1dac5fb authored by Adam G-H's avatar Adam G-H
Browse files

Issue #3281397 by phenaproxima: VersionPolicyValidator should throw an...

Issue #3281397 by phenaproxima: VersionPolicyValidator should throw an exception if it can't determine the target version of Drupal
parent 71424c7b
No related branches found
No related tags found
1 merge request!327Issue #3281397: VersionPolicyValidator should throw an exception if it can't determine the target version of Drupal
......@@ -172,10 +172,15 @@ final class VersionPolicyValidator implements EventSubscriberInterface {
* The event object.
*
* @return string|null
* The target version of Drupal core, or NULL if it could not be determined.
* The target version of Drupal core, or NULL if it could not be determined
* during a readiness check.
*
* @todo Throw an exception in certain (maybe all) situations if we cannot
* figure out the target version in https://www.drupal.org/i/3280180.
* @throws \LogicException
* Thrown if the target version cannot be determined due to unexpected
* conditions. This can happen if, during a stage life cycle event (i.e.,
* NOT a readiness check), the event or updater does not have a list of
* desired package versions, or the list of package versions does not
* include any Drupal core packages.
*/
private function getTargetVersion(StageEvent $event): ?string {
$updater = $event->getStage();
......@@ -187,16 +192,24 @@ final class VersionPolicyValidator implements EventSubscriberInterface {
$package_versions = $updater->getPackageVersions()['production'];
}
$unknown_target = new \LogicException('The target version of Drupal core could not be determined.');
if ($package_versions) {
$core_package_name = key($updater->getActiveComposer()->getCorePackages());
return $package_versions[$core_package_name];
if ($core_package_name && array_key_exists($core_package_name, $package_versions)) {
return $package_versions[$core_package_name];
}
else {
throw $unknown_target;
}
}
elseif ($event instanceof ReadinessCheckEvent) {
// It's okay if this returns NULL; it means there's nothing to update to.
return $this->getTargetVersionFromAvailableReleases($updater);
}
else {
return NULL;
}
// If we got here, something has gone very wrong.
throw $unknown_target;
}
/**
......
......@@ -152,6 +152,13 @@ class TestUpdater extends Updater {
use TestStageTrait;
/**
* {@inheritdoc}
*/
public function setMetadata(string $key, $data): void {
parent::setMetadata($key, $data);
}
}
/**
......
......@@ -3,6 +3,8 @@
namespace Drupal\Tests\automatic_updates\Kernel\ReadinessValidation;
use Drupal\automatic_updates\CronUpdater;
use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\Exception\StageException;
use Drupal\package_manager\Exception\StageValidationException;
use Drupal\package_manager\ValidationResult;
use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase;
......@@ -462,4 +464,66 @@ class VersionPolicyValidatorTest extends AutomaticUpdatesKernelTestBase {
return ValidationResult::createError($messages, $summary);
}
/**
* Tests that an error is raised if there are no stored package versions.
*
* This is a contrived situation that should never happen in real life, but
* just in case it does, we need to be sure that it's an error condition.
*/
public function testNoStagedPackageVersions(): void {
// Remove the stored package versions from the updater's metadata.
$listener = function (PreCreateEvent $event): void {
/** @var \Drupal\Tests\automatic_updates\Kernel\TestUpdater $updater */
$updater = $event->getStage();
$updater->setMetadata('packages', [
'production' => [],
]);
};
$this->assertTargetVersionNotDiscoverable($listener);
}
/**
* Tests that an error is raised if no core packages are installed.
*
* This is a contrived situation that should never happen in real life, but
* just in case it does, we need to be sure that it's an error condition.
*/
public function testNoCorePackagesInstalled(): void {
// Clear the list of packages in the active directory's installed.json.
$listener = function (PreCreateEvent $event): void {
// We should have staged package versions.
/** @var \Drupal\automatic_updates\Updater $updater */
$updater = $event->getStage();
$this->assertNotEmpty($updater->getPackageVersions());
$active_dir = $this->container->get('package_manager.path_locator')
->getProjectRoot();
$installed = $active_dir . '/vendor/composer/installed.json';
$this->assertFileIsWritable($installed);
file_put_contents($installed, '{"packages": []}');
};
$this->assertTargetVersionNotDiscoverable($listener);
}
/**
* Asserts that an error is raised if the target version of Drupal is unknown.
*
* @param \Closure $listener
* A pre-create event listener to run before all validators. This should put
* the virtual project and/or updater into a state which will cause
* \Drupal\automatic_updates\Validator\VersionPolicyValidator::getTargetVersion()
* to throw an exception because the target version of Drupal core is not
* known.
*/
private function assertTargetVersionNotDiscoverable(\Closure $listener): void {
$this->createTestProject();
$this->container->get('event_dispatcher')
->addListener(PreCreateEvent::class, $listener, PHP_INT_MAX);
$this->expectException(StageException::class);
$this->expectExceptionMessage('The target version of Drupal core could not be determined.');
$this->container->get('automatic_updates.updater')
->begin(['drupal' => '9.8.1']);
}
}
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