diff --git a/automatic_updates.info.yml b/automatic_updates.info.yml index 37d097bec121bc7e350c9a022692699ecf4e23bd..119d1f4b970b530d95ea7f019206fa28ad85f366 100644 --- a/automatic_updates.info.yml +++ b/automatic_updates.info.yml @@ -1,7 +1,7 @@ name: 'Automatic Updates' type: module description: 'Automatically updates Drupal core.' -core_version_requirement: ^9.3 +core_version_requirement: ^9.3 || ^10 dependencies: - drupal:package_manager - drupal:update diff --git a/automatic_updates.module b/automatic_updates.module index 83f563cfda0b822cde202cb0681d3ab58be87070..4f86a05f32636d07dd32ef13ad5486fcb07b54e4 100644 --- a/automatic_updates.module +++ b/automatic_updates.module @@ -164,6 +164,12 @@ function automatic_updates_module_implements_alter(&$implementations, $hook) { * Implements hook_cron(). */ function automatic_updates_cron() { + // @todo Refactor this after https://www.drupal.org/project/drupal/issues/2969056 + // @todo Remove this after https://www.drupal.org/project/drupal/issues/3318964 + if (defined('MAINTENANCE_MODE') || stripos($_SERVER['PHP_SELF'], 'update.php') !== FALSE) { + return; + } + /** @var \Drupal\automatic_updates\CronUpdater $updater */ $updater = \Drupal::service('automatic_updates.cron_updater'); $updater->handleCron(); diff --git a/automatic_updates_extensions/automatic_updates_extensions.info.yml b/automatic_updates_extensions/automatic_updates_extensions.info.yml index 1dc4083332e5a1eeb203d85dfffe37664a5350bf..d430f2f7819f995a9e89696fc68f79656077567c 100644 --- a/automatic_updates_extensions/automatic_updates_extensions.info.yml +++ b/automatic_updates_extensions/automatic_updates_extensions.info.yml @@ -1,7 +1,7 @@ name: 'Automatic Updates Extensions' type: module description: 'Allows updates to themes and modules' -core_version_requirement: ^9.3 +core_version_requirement: ^9.3 || ^10 lifecycle: experimental dependencies: - drupal:automatic_updates diff --git a/automatic_updates_extensions/tests/fixtures/new_module/1.0.0/new_module.info.yml.hide b/automatic_updates_extensions/tests/fixtures/new_module/1.0.0/new_module.info.yml.hide index 24cbeec14e6d1b8966cf9bfdeccdbee49e8c069b..4a4b0ec8038fd68108e9e7064bbeb823807b6154 100644 --- a/automatic_updates_extensions/tests/fixtures/new_module/1.0.0/new_module.info.yml.hide +++ b/automatic_updates_extensions/tests/fixtures/new_module/1.0.0/new_module.info.yml.hide @@ -1,4 +1,4 @@ name: 'New module' type: module -core_version_requirement: ^9 +core_version_requirement: ^9 || ^10 project: new_module diff --git a/automatic_updates_extensions/tests/fixtures/new_module/1.1.0/new_module.info.yml.hide b/automatic_updates_extensions/tests/fixtures/new_module/1.1.0/new_module.info.yml.hide index 24cbeec14e6d1b8966cf9bfdeccdbee49e8c069b..4a4b0ec8038fd68108e9e7064bbeb823807b6154 100644 --- a/automatic_updates_extensions/tests/fixtures/new_module/1.1.0/new_module.info.yml.hide +++ b/automatic_updates_extensions/tests/fixtures/new_module/1.1.0/new_module.info.yml.hide @@ -1,4 +1,4 @@ name: 'New module' type: module -core_version_requirement: ^9 +core_version_requirement: ^9 || ^10 project: new_module diff --git a/composer.json b/composer.json index 816fe8e97266df413f7c3c7ec3c4cd0ce252bd10..981d23d6407590698bd0f86c9e03e12be5d6a5e3 100644 --- a/composer.json +++ b/composer.json @@ -12,7 +12,7 @@ }, "require": { "ext-json": "*", - "drupal/core": "^9.3", + "drupal/core": "^9.3 || ^10", "php-tuf/composer-stager": "^1.2", "composer/composer": "^2.2.12 || ^2.3.5", "composer-runtime-api": "^2.1", @@ -39,6 +39,9 @@ "phpcs": "Checks code for standards compliance.", "test": "Runs PHPUnit tests.", "core-convert": "Converts this module to a core merge request. Excepts 2 arguments. 1) The core clone directory. 2) The core merge request branch." + }, + "require-dev": { + "colinodell/psr-testlogger": "^1" }, "autoload": { "psr-4": { diff --git a/dictionary.txt b/dictionary.txt index 7b028abdb9523c32e6d99b10c7cd6c07e771874b..0665a7c4f1069b7c6e197ebcf8d63ac0b54aeee6 100644 --- a/dictionary.txt +++ b/dictionary.txt @@ -1,8 +1,10 @@ -unrequested updater's stager's syncer syncers +unrequested kirk +colinodell +testlogger unwritable filedate diff --git a/drupalci.yml b/drupalci.yml index f2a7f57ff567b63582c5fd3673dc4e84091de05c..9f466e09e62e2946f9f8244d1f9225fdc99665df 100644 --- a/drupalci.yml +++ b/drupalci.yml @@ -32,6 +32,8 @@ build: - sed -i "s/yarn run -s spellcheck/yarn run -s spellcheck --root \$TOP_LEVEL/" modules/contrib/automatic_updates/commit-code-check.sh # Add our words to the dictionary. - cat modules/contrib/automatic_updates/dictionary.txt >> core/misc/cspell/dictionary.txt + # Ensure we have the full path to PHPStan. + - sed -i "s/vendor\/bin\/phpstan/\/var\/www\/html\/vendor\/bin\/phpstan/" modules/contrib/automatic_updates/commit-code-check.sh # After all of the shenanigans above, we're finally ready to run core's `commit-code-check.sh`! :) - "modules/contrib/automatic_updates/commit-code-check.sh --drupalci" # Restore the original permissions. diff --git a/package_manager/package_manager.info.yml b/package_manager/package_manager.info.yml index cf0acc27fbb3977de5d0d717c160d248fc85e3ea..714c91503b1379aeb434e4a7a6ed8d930f9c0a05 100644 --- a/package_manager/package_manager.info.yml +++ b/package_manager/package_manager.info.yml @@ -1,7 +1,7 @@ name: 'Package Manager' type: module description: 'API module providing functionality for staging package installs and updates with Composer.' -core_version_requirement: ^9.3 +core_version_requirement: ^9.3 || ^10 php: 7.4 dependencies: - drupal:update diff --git a/package_manager/src/ComposerUtility.php b/package_manager/src/ComposerUtility.php index be4053b1273bba512a891d4a995ffb567b3cf6f8..70e5b891c6d9659dc340aa5e57b786ed690a2468 100644 --- a/package_manager/src/ComposerUtility.php +++ b/package_manager/src/ComposerUtility.php @@ -8,6 +8,7 @@ use Composer\IO\NullIO; use Composer\Package\Loader\ValidatingArrayLoader; use Composer\Package\PackageInterface; use Composer\Package\Version\VersionParser; +use Composer\PartialComposer; use Composer\Semver\Comparator; use Drupal\Component\Serialization\Yaml; @@ -30,23 +31,46 @@ class ComposerUtility { */ private static $corePackages; + /** + * Whether to raise a deprecation error when the constructor is called. + * + * @var bool + */ + private static $triggerConstructorDeprecation = TRUE; + /** * Constructs a new ComposerUtility object. * - * @param \Composer\Composer $composer + * @param \Composer\Composer|\Composer\PartialComposer $composer * The Composer instance. */ - public function __construct(Composer $composer) { + public function __construct(object $composer) { + // @todo Remove this in https://www.drupal.org/project/automatic_updates/issues/3321474. + if (self::$triggerConstructorDeprecation) { + @trigger_error(__METHOD__ . '() is deprecated in automatic_updates:8.x-2.5 and will be removed in automatic_updates:3.0.0. Use ' . __CLASS__ . '::createForDirectory() instead. See https://www.drupal.org/node/3314137.', E_USER_DEPRECATED); + } + self::$triggerConstructorDeprecation = TRUE; + + // @todo Remove this check when either: + // - PHP 8 or later is required, in which case the $composer type hint + // should be Composer|PartialComposer. + // - Composer 2.3 or later is required, in which case the $composer type + // hint should be changed to PartialComposer. + // @todo Update in https://www.drupal.org/project/automatic_updates/issues/3321474 + // @todo Update in https://www.drupal.org/project/automatic_updates/issues/3321476 + if (!$composer instanceof Composer && !$composer instanceof PartialComposer) { + throw new \InvalidArgumentException('The $composer argument must be an instance of ' . Composer::class . ' or ' . PartialComposer::class); + } $this->composer = $composer; } /** * Returns the underlying Composer instance. * - * @return \Composer\Composer + * @return \Composer\Composer|\Composer\PartialComposer * The Composer instance. */ - public function getComposer(): Composer { + public function getComposer(): object { return $this->composer; } @@ -58,10 +82,21 @@ class ComposerUtility { * * @return \Drupal\package_manager\ComposerUtility * The utility object. + * + * @throws \InvalidArgumentException + * When $dir does not contain a composer.json file. */ public static function createForDirectory(string $dir): self { $io = new NullIO(); + + // Pre-load the contents of composer.json so that Factory::createComposer() + // won't try to call realpath(), which will fail if composer.json is in a + // virtual file system. $configuration = $dir . DIRECTORY_SEPARATOR . 'composer.json'; + if (file_exists($configuration)) { + $configuration = file_get_contents($configuration); + $configuration = json_decode($configuration, TRUE, 512, JSON_THROW_ON_ERROR); + } // The Composer factory requires that either the HOME or COMPOSER_HOME // environment variables be set, so momentarily set the COMPOSER_HOME @@ -87,6 +122,7 @@ class ComposerUtility { putenv("COMPOSER_HOME=$home"); putenv("COMPOSER_HTACCESS_PROTECT=$htaccess"); + self::$triggerConstructorDeprecation = FALSE; return new static($composer); } diff --git a/package_manager/tests/fixtures/alpha/1.0.0/alpha.info.yml.hide b/package_manager/tests/fixtures/alpha/1.0.0/alpha.info.yml.hide index 4b12c91c911ffd8506961b4e1aff65baedf28c9b..877af2ef708fc4ee6ff62ed5c8d0b9a7dd611e31 100644 --- a/package_manager/tests/fixtures/alpha/1.0.0/alpha.info.yml.hide +++ b/package_manager/tests/fixtures/alpha/1.0.0/alpha.info.yml.hide @@ -1,4 +1,4 @@ name: Alpha type: module -core_version_requirement: ^9 +core_version_requirement: ^9 || ^10 project: alpha diff --git a/package_manager/tests/fixtures/alpha/1.1.0/alpha.info.yml.hide b/package_manager/tests/fixtures/alpha/1.1.0/alpha.info.yml.hide index 4b12c91c911ffd8506961b4e1aff65baedf28c9b..877af2ef708fc4ee6ff62ed5c8d0b9a7dd611e31 100644 --- a/package_manager/tests/fixtures/alpha/1.1.0/alpha.info.yml.hide +++ b/package_manager/tests/fixtures/alpha/1.1.0/alpha.info.yml.hide @@ -1,4 +1,4 @@ name: Alpha type: module -core_version_requirement: ^9 +core_version_requirement: ^9 || ^10 project: alpha diff --git a/package_manager/tests/fixtures/post_update.php b/package_manager/tests/fixtures/post_update.php new file mode 100644 index 0000000000000000000000000000000000000000..a596cbe1d0f8f73ea3c53aaa58b3fc8b4f1e4acd --- /dev/null +++ b/package_manager/tests/fixtures/post_update.php @@ -0,0 +1,12 @@ +<?php + +/** + * @file + * Contains a fake database post-update function for testing. + */ + +/** + * Here is a fake post-update hook. + */ +function package_manager_post_update_test() { +} diff --git a/package_manager/tests/src/Build/TemplateProjectTestBase.php b/package_manager/tests/src/Build/TemplateProjectTestBase.php index 969f42bd342d06f15a6c6d2a986928253aca978a..d183bf6924f39d7a922ddb44e8d5fa49c577fe1f 100644 --- a/package_manager/tests/src/Build/TemplateProjectTestBase.php +++ b/package_manager/tests/src/Build/TemplateProjectTestBase.php @@ -217,6 +217,13 @@ END; // Disable Packagist entirely so that we don't test the Internet. $this->runComposer('composer config repo.packagist.org false', $template_dir); + // Allow any version of the Drupal core packages in the template project. + $this->runComposer('composer require --no-update drupal/core-recommended:* drupal/core-project-message:* drupal/core-composer-scaffold:*', $template_dir); + $this->runComposer('composer require --no-update --dev drupal/core-dev:*', $template_dir); + if ($template === 'LegacyProject') { + $this->runComposer('composer require --no-update drupal/core-vendor-hardening:*', $template_dir); + } + // Create the test project, defining its repository as part of the // `composer create-project` command. $repository = [ @@ -327,6 +334,11 @@ END; $package['require']['symfony/polyfill-php72'], $package['require']['symfony/polyfill-php73'] ); + // If we're running on Drupal 10, which requires PHP 8.1 or later, this + // polyfill won't be installed, so make sure it's not required. + if (str_starts_with(\Drupal::VERSION, '10.')) { + unset($package['require']['symfony/polyfill-php80']); + } // Disabling symlinks in the transport options doesn't seem to have an // effect, so we use the COMPOSER_MIRROR_PATH_REPOS environment variable // to force mirroring in ::createTestProject(). diff --git a/package_manager/tests/src/Kernel/ComposerPatchesValidatorTest.php b/package_manager/tests/src/Kernel/ComposerPatchesValidatorTest.php index 482f0a167d9261702de726c39abe03835b55ec45..389000e23f0e4e23b9b0781efd16528d21fd9b58 100644 --- a/package_manager/tests/src/Kernel/ComposerPatchesValidatorTest.php +++ b/package_manager/tests/src/Kernel/ComposerPatchesValidatorTest.php @@ -32,8 +32,11 @@ class ComposerPatchesValidatorTest extends PackageManagerKernelTestBase { ]; $file->write($data); + // Because ComposerUtility reads composer.json and passes it to the Composer + // factory as an array, Composer will assume that the configuration is + // coming from a config.json file, even if one doesn't exist. $error = ValidationResult::createError([ - 'The <code>cweagans/composer-patches</code> plugin is installed, but the <code>composer-exit-on-patch-failure</code> key is not set to <code>true</code> in the <code>extra</code> section of composer.json.', + "The <code>cweagans/composer-patches</code> plugin is installed, but the <code>composer-exit-on-patch-failure</code> key is not set to <code>true</code> in the <code>extra</code> section of $dir/config.json.", ]); $this->assertStatusCheckResults([$error]); $this->assertResults([$error], PreCreateEvent::class); diff --git a/package_manager/tests/src/Kernel/ComposerUtilityTest.php b/package_manager/tests/src/Kernel/ComposerUtilityTest.php index 5433200767efba239712f45ce94535a22daffd83..b60bcc3cd626be3e2884102cb724f626b98714e9 100644 --- a/package_manager/tests/src/Kernel/ComposerUtilityTest.php +++ b/package_manager/tests/src/Kernel/ComposerUtilityTest.php @@ -32,6 +32,17 @@ class ComposerUtilityTest extends KernelTestBase { static::copyFixtureFilesTo(__DIR__ . '/../../fixtures/project_package_conversion', $fixture->url()); } + /** + * Tests that ComposerUtility::CreateForDirectory() validates the directory. + */ + public function testCreateForDirectoryValidation(): void { + $this->expectException(\InvalidArgumentException::class); + $this->expectExceptionMessage('Composer could not find the config file: vfs://root/composer.json'); + + $dir = vfsStream::setup()->url(); + ComposerUtility::createForDirectory($dir); + } + /** * Tests that ComposerUtility disables automatic creation of .htaccess files. */ diff --git a/package_manager/tests/src/Kernel/ExecutableFinderTest.php b/package_manager/tests/src/Kernel/ExecutableFinderTest.php index ff7ed9933a83b3a466090a116f4d54a75956c298..c8da1b68dff9a21b7dd8fa7382653fcf5f80424a 100644 --- a/package_manager/tests/src/Kernel/ExecutableFinderTest.php +++ b/package_manager/tests/src/Kernel/ExecutableFinderTest.php @@ -24,7 +24,7 @@ class ExecutableFinderTest extends PackageManagerKernelTestBase { /** * {@inheritdoc} */ - public function find($name, $default = NULL, array $extraDirs = []) { + public function find($name, $default = NULL, array $extraDirs = []): ?string { return '/dev/null'; } diff --git a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php index 354f3099e869ecea0fc228242e5119321e4ce5c3..5170d92aa6571d266e303f7aa5ef3e59e03575c9 100644 --- a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php +++ b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php @@ -76,8 +76,9 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase { $this->createVirtualProject(); // The Update module's default configuration must be installed for our - // fake release metadata to be fetched. - $this->installConfig('update'); + // fake release metadata to be fetched, and the System module's to ensure + // the site has a name. + $this->installConfig(['system', 'update']); // Make the update system think that all of System's post-update functions // have run. diff --git a/package_manager/tests/src/Kernel/PendingUpdatesValidatorTest.php b/package_manager/tests/src/Kernel/PendingUpdatesValidatorTest.php index e41ccd8c9e8d5dbd84f572c92457c9706abda589..192073a644f7784a7bc048ff1374c73ae116b89c 100644 --- a/package_manager/tests/src/Kernel/PendingUpdatesValidatorTest.php +++ b/package_manager/tests/src/Kernel/PendingUpdatesValidatorTest.php @@ -52,8 +52,9 @@ class PendingUpdatesValidatorTest extends PackageManagerKernelTestBase { */ public function testPendingPostUpdate(): void { $this->registerPostUpdateFunctions(); - // The System module's post-update functions have not been registered, so - // the update registry will think they're pending. + // Make an additional post-update function available; the update registry + // will think it's pending. + require_once __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.', ]); diff --git a/package_manager/tests/src/Kernel/StageOwnershipTest.php b/package_manager/tests/src/Kernel/StageOwnershipTest.php index b945927b6fbfe52b3a47fd39fdf63ac0df745d2a..84f465782f5e7277428bb8bbcb6f459d3a06aedb 100644 --- a/package_manager/tests/src/Kernel/StageOwnershipTest.php +++ b/package_manager/tests/src/Kernel/StageOwnershipTest.php @@ -11,7 +11,7 @@ use Drupal\package_manager\Exception\StageOwnershipException; use Drupal\package_manager_bypass\Stager; use Drupal\package_manager_test_validation\EventSubscriber\TestSubscriber; use Drupal\Tests\user\Traits\UserCreationTrait; -use Psr\Log\Test\TestLogger; +use ColinODell\PsrTestLogger\TestLogger; /** * Tests that ownership of the stage is enforced. diff --git a/package_manager/tests/src/Kernel/StageTest.php b/package_manager/tests/src/Kernel/StageTest.php index 392d4e697c38a9f2758b493d94a02c80fa25a76b..61cf2a80ec53a6c5349601d6a673a9c56af5680a 100644 --- a/package_manager/tests/src/Kernel/StageTest.php +++ b/package_manager/tests/src/Kernel/StageTest.php @@ -20,7 +20,7 @@ use PhpTuf\ComposerStager\Domain\Exception\PreconditionException; use Drupal\package_manager_bypass\Beginner; use PhpTuf\ComposerStager\Domain\Service\Precondition\PreconditionInterface; use Psr\Log\LogLevel; -use Psr\Log\Test\TestLogger; +use ColinODell\PsrTestLogger\TestLogger; /** * @coversDefaultClass \Drupal\package_manager\Stage diff --git a/src/CronUpdater.php b/src/CronUpdater.php index 6f1e715b7d78daf15e3581cf56a0e3139f542a7a..d6eb0a1e417ff90b26ee47c0cfd04226c43c2ea6 100644 --- a/src/CronUpdater.php +++ b/src/CronUpdater.php @@ -54,13 +54,6 @@ class CronUpdater extends Updater { */ public const ALL = 'patch'; - /** - * The logger. - * - * @var \Psr\Log\LoggerInterface - */ - protected $logger; - /** * The cron release chooser service. * diff --git a/src/Validator/CronServerValidator.php b/src/Validator/CronServerValidator.php index 41e3fe3e61f18dc383bad3f85b5daafde3801f65..44d2eabdf9f16825a731f81ac4f705813d379ca2 100644 --- a/src/Validator/CronServerValidator.php +++ b/src/Validator/CronServerValidator.php @@ -5,13 +5,13 @@ namespace Drupal\automatic_updates\Validator; use Drupal\automatic_updates\CronUpdater; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Extension\ModuleHandlerInterface; -use Drupal\Core\Http\RequestStack; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\Url; use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Event\PreOperationStageEvent; use Drupal\package_manager\Event\StatusCheckEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; +use Symfony\Component\HttpFoundation\RequestStack; /** * Validates that the current server configuration can run cron updates. @@ -59,7 +59,7 @@ final class CronServerValidator implements EventSubscriberInterface { /** * Constructs a CronServerValidator object. * - * @param \Drupal\Core\Http\RequestStack $request_stack + * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack * The request stack service. * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory * The config factory service. diff --git a/src/Validator/VersionPolicy/ForbidDowngrade.php b/src/Validator/VersionPolicy/ForbidDowngrade.php index c71fc54fbeabfd78a5954610032bb4a8c476a256..3ddb310cc3c5118081890d64c30c3f52e5879920 100644 --- a/src/Validator/VersionPolicy/ForbidDowngrade.php +++ b/src/Validator/VersionPolicy/ForbidDowngrade.php @@ -29,6 +29,8 @@ final class ForbidDowngrade { * The error messages, if any. */ public function validate(string $installed_version, ?string $target_version): array { + // TRICKY: \Drupal\automatic_updates\Validator\VersionPolicyValidator::getTargetVersion() may potentially not be able to determine a version. + $target_version = $target_version ?? ''; if (Comparator::lessThan($target_version, $installed_version)) { return [ $this->t('Update version @target_version is lower than @installed_version, downgrading is not supported.', [ diff --git a/tests/fixtures/automatic_updates-installed.php b/tests/fixtures/automatic_updates-installed.php index 57c418d12b63f5ea5445af49eaa414014014fe50..b2f3c29f429989af6e3629b879cb238dd5c3eccf 100644 --- a/tests/fixtures/automatic_updates-installed.php +++ b/tests/fixtures/automatic_updates-installed.php @@ -45,6 +45,11 @@ $extensions = $connection->select('config', 'c') $extensions = unserialize($extensions); $extensions['module']['automatic_updates'] = 0; $extensions['module']['package_manager'] = 0; +// Install the mysql module manually because +// system_post_update_enable_provider_database_driver() makes reliable update +// path testing impossible. +// @see https://www.drupal.org/project/automatic_updates/issues/3314137#comment-14772840 +$extensions['module']['mysql'] = 0; $connection->update('config') ->fields([ 'data' => serialize($extensions), @@ -52,6 +57,26 @@ $connection->update('config') ->condition('name', 'core.extension') ->execute(); +// Add system_post_update_enable_provider_database_driver() as an existing +// update. +// @see https://www.drupal.org/project/automatic_updates/issues/3314137#comment-14772840 +$existing_updates = $connection->select('key_value') + ->fields('key_value', ['value']) + ->condition('collection', 'post_update') + ->condition('name', 'existing_updates') + ->execute() + ->fetchField(); +$existing_updates = unserialize($existing_updates); +$existing_updates = array_merge( + $existing_updates, + ['system_post_update_enable_provider_database_driver'], +); +$connection->update('key_value') + ->fields(['value' => serialize($existing_updates)]) + ->condition('collection', 'post_update') + ->condition('name', 'existing_updates') + ->execute(); + $connection->insert('key_value') ->fields(array( 'collection', diff --git a/tests/src/Functional/UpdatePathTest.php b/tests/src/Functional/UpdatePathTest.php index 15430da29b23bdfcfd9146bc6dfbf79221797c0e..ef600d67032c6001ada85da0e3c36cc46991c79f 100644 --- a/tests/src/Functional/UpdatePathTest.php +++ b/tests/src/Functional/UpdatePathTest.php @@ -14,8 +14,14 @@ class UpdatePathTest extends UpdatePathTestBase { * {@inheritdoc} */ protected function setDatabaseDumpFiles() { + // phpcs on 9.5 expects one thing, on 10.0 another. 🤷 + // @see https://www.drupal.org/project/automatic_updates/issues/3314137#comment-14771510 + // phpcs:disable + [$version] = explode('.', \Drupal::VERSION, 2); $this->databaseDumpFiles = [ - $this->getDrupalRoot() . '/core/modules/system/tests/fixtures/update/drupal-9.3.0.filled.standard.php.gz', + $version == 9 + ? $this->getDrupalRoot() . '/core/modules/system/tests/fixtures/update/drupal-9.3.0.filled.standard.php.gz' + : $this->getDrupalRoot() . '/core/modules/system/tests/fixtures/update/drupal-9.4.0.filled.standard.php.gz', __DIR__ . '/../../fixtures/automatic_updates-installed.php', ]; } @@ -32,11 +38,15 @@ class UpdatePathTest extends UpdatePathTestBase { 'readiness_validation_last_run' => 'status_check_last_run', 'readiness_check_timestamp' => 'status_check_timestamp', ]; + $expected_values = []; foreach ($map as $old_key => $new_key) { $this->assertFalse($key_value->has($new_key)); $value = $key_value->get($old_key); $this->assertNotEmpty($value); + // Allow testing that the values post-update are indeed the values + // pre-update and not recomputed ones. + $expected_values[$new_key] = $value; // Ensure the stored value will still be retrievable. $key_value->setWithExpire($old_key, $value, 3600); } @@ -44,9 +54,14 @@ class UpdatePathTest extends UpdatePathTestBase { $this->runUpdates(); - foreach ($map as $new_key) { - $this->assertNotEmpty($key_value->get($new_key)); - } + // TRICKY: we do expect `readiness_validation_last_run` to have been renamed + // to `status_check_last_run`, but then + // automatic_updates_post_update_create_status_check_mail_config() should + // cause that to be erased. + // @see automatic_updates_post_update_create_status_check_mail_config() + // @see \Drupal\automatic_updates\EventSubscriber\ConfigSubscriber::onConfigSave() + unset($expected_values['status_check_last_run']); + $this->assertSame($expected_values, $key_value->getMultiple(array_values($map))); $this->assertSame(StatusCheckMailer::ERRORS_ONLY, $this->config('automatic_updates.settings')->get('status_check_mail')); // Ensure that the router was rebuilt and routes have the expected changes. diff --git a/tests/src/Kernel/CronUpdaterTest.php b/tests/src/Kernel/CronUpdaterTest.php index de849ce684fe601cb0c35989be368ff28a91d25b..d1c6d84c697622d76ff9319ea69e98c48295ef10 100644 --- a/tests/src/Kernel/CronUpdaterTest.php +++ b/tests/src/Kernel/CronUpdaterTest.php @@ -23,7 +23,8 @@ use Drupal\Tests\automatic_updates\Traits\EmailNotificationsTestTrait; use Drupal\Tests\package_manager\Traits\PackageManagerBypassTestTrait; use Drupal\Tests\user\Traits\UserCreationTrait; use Drupal\update\UpdateSettingsForm; -use Psr\Log\Test\TestLogger; +use ColinODell\PsrTestLogger\TestLogger; +use Prophecy\Argument; use Symfony\Component\EventDispatcher\EventDispatcherInterface; /** @@ -163,6 +164,7 @@ class CronUpdaterTest extends AutomaticUpdatesKernelTestBase { // are called as expected, disable validation by replacing the event // dispatcher with a dummy version. $event_dispatcher = $this->prophesize(EventDispatcherInterface::class); + $event_dispatcher->dispatch(Argument::type('object'))->willReturnArgument(0); $this->container->set('event_dispatcher', $event_dispatcher->reveal()); // Run cron and ensure that Package Manager's services were called or diff --git a/tests/src/Kernel/StatusCheck/CronServerValidatorTest.php b/tests/src/Kernel/StatusCheck/CronServerValidatorTest.php index 0b4ecf939bbdd6bb3208b3b340f886fd3e0da580..5c39b0159655e324ba8299768ee7a6b5eadd8fc1 100644 --- a/tests/src/Kernel/StatusCheck/CronServerValidatorTest.php +++ b/tests/src/Kernel/StatusCheck/CronServerValidatorTest.php @@ -9,7 +9,7 @@ use Drupal\Core\Url; use Drupal\package_manager\Exception\StageValidationException; use Drupal\package_manager\ValidationResult; use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase; -use Psr\Log\Test\TestLogger; +use ColinODell\PsrTestLogger\TestLogger; /** * @covers \Drupal\automatic_updates\Validator\CronServerValidator diff --git a/tests/src/Kernel/StatusCheck/StagedDatabaseUpdateValidatorTest.php b/tests/src/Kernel/StatusCheck/StagedDatabaseUpdateValidatorTest.php index 29e7ae14d80655d7c90a01bdf5a41acc0e02adf3..8b5e709541e6f78f433b75c38ad6bc77b9a3a188 100644 --- a/tests/src/Kernel/StatusCheck/StagedDatabaseUpdateValidatorTest.php +++ b/tests/src/Kernel/StatusCheck/StagedDatabaseUpdateValidatorTest.php @@ -5,7 +5,7 @@ namespace Drupal\Tests\automatic_updates\Kernel\StatusCheck; use Drupal\Core\Logger\RfcLogLevel; use Drupal\package_manager\Event\PreApplyEvent; use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase; -use Psr\Log\Test\TestLogger; +use ColinODell\PsrTestLogger\TestLogger; /** * @covers \Drupal\automatic_updates\Validator\StagedDatabaseUpdateValidator diff --git a/tests/src/Kernel/StatusCheck/XdebugValidatorTest.php b/tests/src/Kernel/StatusCheck/XdebugValidatorTest.php index 14bdaffa7e1c04656c6b9d596e540403c6e37e81..7f23751d02f9d78b3a9ac6ee5c85bac80967d151 100644 --- a/tests/src/Kernel/StatusCheck/XdebugValidatorTest.php +++ b/tests/src/Kernel/StatusCheck/XdebugValidatorTest.php @@ -7,7 +7,7 @@ use Drupal\Core\Logger\RfcLogLevel; use Drupal\package_manager\ValidationResult; use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase; use Drupal\Tests\package_manager\Traits\PackageManagerBypassTestTrait; -use Psr\Log\Test\TestLogger; +use ColinODell\PsrTestLogger\TestLogger; /** * @covers \Drupal\automatic_updates\Validator\XdebugValidator