From cdee22d7ca58e0ec9e9e3cd9e656dd2e0ad91fed Mon Sep 17 00:00:00 2001 From: phenaproxima <phenaproxima@205645.no-reply.drupal.org> Date: Thu, 5 May 2022 18:57:18 +0000 Subject: [PATCH] Issue #3279086 by phenaproxima: StagedDatabaseUpdateValidatorTest should use a virtual project --- .../fake_site/vendor/composer/installed.json | 8 +++++ .../src/EventSubscriber/FixtureStager.php | 26 ++++++++++++--- .../src/Kernel/LockFileValidatorTest.php | 14 ++++---- .../Kernel/PackageManagerKernelTestBase.php | 9 ++++- .../StagedDatabaseUpdateValidatorTest.php | 33 +++++++++---------- 5 files changed, 60 insertions(+), 30 deletions(-) create mode 100644 package_manager/tests/fixtures/fake_site/vendor/composer/installed.json diff --git a/package_manager/tests/fixtures/fake_site/vendor/composer/installed.json b/package_manager/tests/fixtures/fake_site/vendor/composer/installed.json new file mode 100644 index 0000000000..ad9a32852d --- /dev/null +++ b/package_manager/tests/fixtures/fake_site/vendor/composer/installed.json @@ -0,0 +1,8 @@ +{ + "packages": [ + { + "name": "drupal/core", + "version": "9.8.0" + } + ] +} diff --git a/package_manager/tests/modules/package_manager_test_fixture/src/EventSubscriber/FixtureStager.php b/package_manager/tests/modules/package_manager_test_fixture/src/EventSubscriber/FixtureStager.php index 11f8552ac6..fd5ecb7124 100644 --- a/package_manager/tests/modules/package_manager_test_fixture/src/EventSubscriber/FixtureStager.php +++ b/package_manager/tests/modules/package_manager_test_fixture/src/EventSubscriber/FixtureStager.php @@ -57,12 +57,27 @@ class FixtureStager implements EventSubscriberInterface { * @see \Drupal\Tests\automatic_updates\Functional\AutomaticUpdatesFunctionalTestBase::tearDown() */ public function copyFilesFromFixture(PostRequireEvent $event): void { - $fixturePath = $this->state->get(static::class); + [$fixturePath, $changeLock] = $this->state->get(static::class); + if ($fixturePath && is_dir($fixturePath)) { - $this->fileSystem->mirror($fixturePath, $event->getStage()->getStageDirectory(), NULL, [ + $destination = $event->getStage()->getStageDirectory(); + + $this->fileSystem->mirror($fixturePath, $destination, NULL, [ 'override' => TRUE, 'delete' => TRUE, ]); + + // Modify the lock file in the staging area, to simulate that a package + // was added, updated, or removed. Otherwise, tests must remember to + // disable the lock file validator. + // @see \Drupal\package_manager\Validator\LockFileValidator + $lock = $destination . '/composer.lock'; + if ($changeLock && file_exists($lock)) { + $data = file_get_contents($lock); + $data = json_decode($data); + $data->_time = microtime(); + file_put_contents($lock, json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PRETTY_PRINT)); + } } } @@ -80,9 +95,12 @@ class FixtureStager implements EventSubscriberInterface { * * @param string $path * The path of the fixture to copy into the staging area. + * @param bool $change_lock + * (optional) Whether to change the lock file, in order to simulate the + * addition, updating, or removal of a package. Defaults to TRUE. */ - public static function setFixturePath(string $path): void { - \Drupal::state()->set(static::class, $path); + public static function setFixturePath(string $path, bool $change_lock = TRUE): void { + \Drupal::state()->set(static::class, [$path, $change_lock]); } } diff --git a/package_manager/tests/src/Kernel/LockFileValidatorTest.php b/package_manager/tests/src/Kernel/LockFileValidatorTest.php index 757481d81b..0d3e5c6af6 100644 --- a/package_manager/tests/src/Kernel/LockFileValidatorTest.php +++ b/package_manager/tests/src/Kernel/LockFileValidatorTest.php @@ -2,12 +2,12 @@ namespace Drupal\Tests\package_manager\Kernel; -use Drupal\package_manager\Event\PostRequireEvent; use Drupal\package_manager\Event\PreApplyEvent; use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Event\PreRequireEvent; use Drupal\package_manager\Validator\LockFileValidator; use Drupal\package_manager\ValidationResult; +use Drupal\package_manager_test_fixture\EventSubscriber\FixtureStager; /** * @coversDefaultClass \Drupal\package_manager\Validator\LockFileValidator @@ -56,7 +56,7 @@ class LockFileValidatorTest extends PackageManagerKernelTestBase { // Change the lock file to ensure the stored hash of the previous version // has been deleted. - file_put_contents($this->activeDir . '/composer.lock', 'changed'); + file_put_contents($this->activeDir . '/composer.lock', '{"changed": true}'); $this->assertResults([]); } @@ -124,11 +124,11 @@ class LockFileValidatorTest extends PackageManagerKernelTestBase { * Tests validation when the staged and active lock files are identical. */ public function testApplyWithNoChange(): void { - $this->addListener(PostRequireEvent::class, function (PostRequireEvent $event) { - $stage_dir = $event->getStage()->getStageDirectory(); - mkdir($stage_dir); - copy("$this->activeDir/composer.lock", "$stage_dir/composer.lock"); - }); + // Ensure the lock file is not changed when the active directory is copied + // into the virtual staging area. + // @see \Drupal\package_manager_test_fixture\EventSubscriber\FixtureStager + FixtureStager::setFixturePath($this->activeDir, FALSE); + $result = ValidationResult::createError([ 'There are no pending Composer operations.', ]); diff --git a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php index cc2e2e4d4e..3a04735d0c 100644 --- a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php +++ b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php @@ -10,6 +10,7 @@ use Drupal\package_manager\Exception\StageException; use Drupal\package_manager\Exception\StageValidationException; use Drupal\package_manager\PathLocator; use Drupal\package_manager\Stage; +use Drupal\package_manager_test_fixture\EventSubscriber\FixtureStager; use Drupal\Tests\package_manager\Traits\ValidationTestTrait; use org\bovigo\vfs\vfsStream; use org\bovigo\vfs\vfsStreamDirectory; @@ -29,6 +30,7 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase { protected static $modules = [ 'package_manager', 'package_manager_bypass', + 'package_manager_test_fixture', ]; /** @@ -188,7 +190,12 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase { $this->vfsRoot->addChild($stage_dir); static::$testStagingRoot = $stage_dir->url(); - $path_locator = $this->mockPathLocator($active_dir->url()); + $active_dir = $active_dir->url(); + $path_locator = $this->mockPathLocator($active_dir); + + // Ensure that the active directory is copied into the virtual staging area, + // even if Package Manager's operations are bypassed. + FixtureStager::setFixturePath($active_dir); // Since the path locator now points to a virtual file system, we need to // replace the disk space validator with a test-only version that bypasses diff --git a/tests/src/Kernel/ReadinessValidation/StagedDatabaseUpdateValidatorTest.php b/tests/src/Kernel/ReadinessValidation/StagedDatabaseUpdateValidatorTest.php index ff06b1a4eb..1269a0cee0 100644 --- a/tests/src/Kernel/ReadinessValidation/StagedDatabaseUpdateValidatorTest.php +++ b/tests/src/Kernel/ReadinessValidation/StagedDatabaseUpdateValidatorTest.php @@ -29,40 +29,37 @@ class StagedDatabaseUpdateValidatorTest extends AutomaticUpdatesKernelTestBase { * {@inheritdoc} */ protected function setUp(): void { - // In this test, we want to disable the lock file validator because, even - // though both the active and stage directories will have a valid lock file, - // this validator will complain because they don't differ at all. - $this->disableValidators[] = 'package_manager.validator.lock_file'; parent::setUp(); - static::$testStagingRoot = $this->vfsRoot->url(); + $this->createTestProject(); /** @var \Drupal\Tests\automatic_updates\Kernel\TestCronUpdater $updater */ $updater = $this->container->get('automatic_updates.cron_updater'); $updater->begin(['drupal' => '9.8.2']); $updater->stage(); + } - $stage_dir = $updater->getStageDirectory(); - mkdir($stage_dir); + /** + * {@inheritdoc} + */ + protected function createTestProject(): void { + parent::createTestProject(); - // To satisfy StagedProjectsValidator, copy the active Composer files into - // the staging area. - $active_dir = $this->getDrupalRoot(); - @copy("$active_dir/composer.json", "$stage_dir/composer.json"); - @copy("$active_dir/composer.lock", "$stage_dir/composer.lock"); - mkdir("$stage_dir/vendor/composer", 0777, TRUE); - @copy("$active_dir/vendor/composer/installed.json", "$stage_dir/vendor/composer/installed.json"); + $drupal_root = $this->getDrupalRoot(); + $virtual_active_dir = $this->container->get('package_manager.path_locator') + ->getProjectRoot(); - // Copy the .install and .post_update.php files from every installed module - // into the staging directory. + // Copy the .install and .post_update.php files from every installed module, + // in the *actual* Drupal code base that is running this test, into the + // virtual project (i.e., the active directory). $module_list = $this->container->get('module_handler')->getModuleList(); foreach ($module_list as $name => $module) { $path = $module->getPath(); - @mkdir("$stage_dir/$path", 0777, TRUE); + @mkdir("$virtual_active_dir/$path", 0777, TRUE); foreach (static::SUFFIXES as $suffix) { // If the source file doesn't exist, silence the warning it raises. - @copy("$active_dir/$path/$name.$suffix", "$stage_dir/$path/$name.$suffix"); + @copy("$drupal_root/$path/$name.$suffix", "$virtual_active_dir/$path/$name.$suffix"); } } } -- GitLab