Commit cdee22d7 authored by Adam G-H's avatar Adam G-H
Browse files

Issue #3279086 by phenaproxima: StagedDatabaseUpdateValidatorTest should use a virtual project

parent 349ea640
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
{
  "packages": [
    {
      "name": "drupal/core",
      "version": "9.8.0"
    }
  ]
}
+22 −4
Original line number Diff line number Diff line
@@ -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]);
  }

}
+7 −7
Original line number Diff line number Diff line
@@ -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.',
    ]);
+8 −1
Original line number Diff line number Diff line
@@ -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
+15 −18
Original line number Diff line number Diff line
@@ -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");
      }
    }
  }