Skip to content
Snippets Groups Projects
Commit 4a8c6cd1 authored by catch's avatar catch
Browse files

Merge branch '3487826-packagemanager-kernel-tests' into '11.x'

Start trying to optimize package manager kernel tests with CompserPluginsValidatorTest.

See merge request !10333
parents 4650172f 0fa807a0
No related branches found
No related tags found
No related merge requests found
Pipeline #349839 failed
Pipeline: drupal

#349841

    ......@@ -303,8 +303,10 @@ public function setCorePackageVersion(string $version): self {
    *
    * @param array $additional_config
    * The configuration to add.
    * @param bool $update_lock
    * Whether to run composer update --lock. Defaults to FALSE.
    */
    public function addConfig(array $additional_config): self {
    public function addConfig(array $additional_config, bool $update_lock = FALSE): self {
    if (empty($additional_config)) {
    throw new \InvalidArgumentException('No config to add.');
    }
    ......@@ -330,7 +332,9 @@ public function addConfig(array $additional_config): self {
    $command[] = $value;
    $this->runComposerCommand($command);
    }
    $this->runComposerCommand(['update', '--lock']);
    if ($update_lock) {
    $this->runComposerCommand(['update', '--lock']);
    }
    return $this;
    }
    ......@@ -348,8 +352,10 @@ public function commitChanges(string $dir): void {
    *
    * @param string $dir
    * The directory to commit the changes to.
    * @param bool $validate_composer
    * Whether to run composer validate or not.
    */
    final protected function doCommitChanges(string $dir): void {
    final protected function doCommitChanges(string $dir, $validate_composer = FALSE): void {
    if ($this->committed) {
    throw new \BadMethodCallException('Already committed.');
    }
    ......@@ -367,7 +373,9 @@ final protected function doCommitChanges(string $dir): void {
    }
    $this->committed = TRUE;
    $this->committingChanges = FALSE;
    $this->validateComposer();
    if ($validate_composer) {
    $this->validateComposer();
    }
    }
    /**
    ......@@ -623,8 +631,12 @@ private function addRepository(array $package): string {
    /**
    * Sets up the path repos at absolute paths.
    *
    * @param bool $composer_refresh
    * Whether to run composer update --lock && composer install. Defaults to
    * FALSE.
    */
    public function setUpRepos(): void {
    public function setUpRepos($composer_refresh = FALSE): void {
    $fs = new SymfonyFileSystem();
    $path_repo_base = \Drupal::state()->get(self::PATH_REPO_STATE_KEY);
    if (empty($path_repo_base)) {
    ......@@ -638,8 +650,10 @@ public function setUpRepos(): void {
    // repos at the absolute path.
    $composer_json = file_get_contents($this->dir . '/packages.json');
    assert(file_put_contents($this->dir . '/packages.json', str_replace('../path_repos/', "$path_repo_base/", $composer_json)) !== FALSE);
    $this->runComposerCommand(['update', '--lock']);
    $this->runComposerCommand(['install']);
    if ($composer_refresh) {
    $this->runComposerCommand(['update', '--lock']);
    $this->runComposerCommand(['install']);
    }
    }
    }
    <?php
    declare(strict_types=1);
    namespace Drupal\Tests\package_manager\Kernel;
    use Drupal\Core\StringTranslation\TranslatableMarkup;
    use Drupal\fixture_manipulator\ActiveFixtureManipulator;
    use Drupal\package_manager\Event\PreApplyEvent;
    use Drupal\package_manager\Event\PreCreateEvent;
    use Drupal\package_manager\Exception\StageEventException;
    use Drupal\package_manager\ValidationResult;
    /**
    * @covers \Drupal\package_manager\Validator\ComposerPluginsValidator
    * @group package_manager
    * @internal
    */
    class ComposerPluginsValidatorInsecureTest extends PackageManagerKernelTestBase {
    /**
    * Tests `config.allow-plugins: true` fails validation during pre-create.
    */
    public function testInsecureConfigurationFailsValidationPreCreate(): void {
    $active_manipulator = new ActiveFixtureManipulator();
    $active_manipulator->addConfig(['allow-plugins' => TRUE]);
    $active_manipulator->commitChanges();
    $expected_results = [
    ValidationResult::createError(
    [
    new TranslatableMarkup('All composer plugins are allowed because <code>config.allow-plugins</code> is configured to <code>true</code>. This is an unacceptable security risk.'),
    ],
    ),
    ];
    $this->assertStatusCheckResults($expected_results);
    $this->assertResults($expected_results, PreCreateEvent::class);
    }
    /**
    * Tests `config.allow-plugins: true` fails validation during pre-apply.
    */
    public function testInsecureConfigurationFailsValidationPreApply(): void {
    $stage_manipulator = $this->getStageFixtureManipulator();
    $stage_manipulator->addConfig(['allow-plugins' => TRUE]);
    $expected_results = [
    ValidationResult::createError(
    [
    new TranslatableMarkup('All composer plugins are allowed because <code>config.allow-plugins</code> is configured to <code>true</code>. This is an unacceptable security risk.'),
    ],
    ),
    ];
    $this->assertResults($expected_results, PreApplyEvent::class);
    }
    /**
    * Tests adding a plugin that's not allowed by the allow-plugins config.
    *
    * The exception that this test looks for is not necessarily triggered by
    * ComposerPluginsValidator; Composer will exit with an error if there is an
    * installed plugin that is not allowed by the `allow-plugins` config. In
    * practice, this means that whichever validator is the first one to do a
    * Composer operation (via ComposerInspector) will get the exception -- it
    * may or may not be ComposerPluginsValidator.
    *
    * This test is here to ensure that Composer's behavior remains consistent,
    * even if we're not explicitly testing ComposerPluginsValidator here.
    */
    public function testAddDisallowedPlugin(): void {
    $this->getStageFixtureManipulator()
    ->addPackage([
    'name' => 'composer/plugin-c',
    'version' => '16.4',
    'type' => 'composer-plugin',
    'require' => ['composer-plugin-api' => '*'],
    'extra' => ['class' => 'AnyClass'],
    ]);
    $expected_message = "composer/plugin-c contains a Composer plugin which is blocked by your allow-plugins config.";
    $stage = $this->createStage();
    $stage->create();
    $stage->require(['drupal/core:9.8.1']);
    try {
    // We are trying to add package plugin-c but not allowing it in config,
    // so we expect the operation to fail on PreApplyEvent.
    $stage->apply();
    }
    catch (StageEventException $e) {
    // Processing is required because the error message we get from Composer
    // contains multiple white spaces at the start or end of line.
    $this->assertStringContainsString($expected_message, preg_replace('/\s\s+/', '', $e->getMessage()));
    $this->assertInstanceOf(PreApplyEvent::class, $e->event);
    }
    }
    }
    ......@@ -9,7 +9,6 @@
    use Drupal\fixture_manipulator\ActiveFixtureManipulator;
    use Drupal\package_manager\Event\PreApplyEvent;
    use Drupal\package_manager\Event\PreCreateEvent;
    use Drupal\package_manager\Exception\StageEventException;
    use Drupal\package_manager\ValidationResult;
    /**
    ......@@ -19,42 +18,6 @@
    */
    class ComposerPluginsValidatorTest extends PackageManagerKernelTestBase {
    /**
    * Tests `config.allow-plugins: true` fails validation during pre-create.
    */
    public function testInsecureConfigurationFailsValidationPreCreate(): void {
    $active_manipulator = new ActiveFixtureManipulator();
    $active_manipulator->addConfig(['allow-plugins' => TRUE]);
    $active_manipulator->commitChanges();
    $expected_results = [
    ValidationResult::createError(
    [
    new TranslatableMarkup('All composer plugins are allowed because <code>config.allow-plugins</code> is configured to <code>true</code>. This is an unacceptable security risk.'),
    ],
    ),
    ];
    $this->assertStatusCheckResults($expected_results);
    $this->assertResults($expected_results, PreCreateEvent::class);
    }
    /**
    * Tests `config.allow-plugins: true` fails validation during pre-apply.
    */
    public function testInsecureConfigurationFailsValidationPreApply(): void {
    $stage_manipulator = $this->getStageFixtureManipulator();
    $stage_manipulator->addConfig(['allow-plugins' => TRUE]);
    $expected_results = [
    ValidationResult::createError(
    [
    new TranslatableMarkup('All composer plugins are allowed because <code>config.allow-plugins</code> is configured to <code>true</code>. This is an unacceptable security risk.'),
    ],
    ),
    ];
    $this->assertResults($expected_results, PreApplyEvent::class);
    }
    /**
    * Tests composer plugins are validated during pre-create.
    *
    ......@@ -102,46 +65,6 @@ public function testValidationDuringPreApply(array $composer_config_to_add, arra
    $this->assertResults($expected_results, PreApplyEvent::class);
    }
    /**
    * Tests adding a plugin that's not allowed by the allow-plugins config.
    *
    * The exception that this test looks for is not necessarily triggered by
    * ComposerPluginsValidator; Composer will exit with an error if there is an
    * installed plugin that is not allowed by the `allow-plugins` config. In
    * practice, this means that whichever validator is the first one to do a
    * Composer operation (via ComposerInspector) will get the exception -- it
    * may or may not be ComposerPluginsValidator.
    *
    * This test is here to ensure that Composer's behavior remains consistent,
    * even if we're not explicitly testing ComposerPluginsValidator here.
    */
    public function testAddDisallowedPlugin(): void {
    $this->getStageFixtureManipulator()
    ->addPackage([
    'name' => 'composer/plugin-c',
    'version' => '16.4',
    'type' => 'composer-plugin',
    'require' => ['composer-plugin-api' => '*'],
    'extra' => ['class' => 'AnyClass'],
    ]);
    $expected_message = "composer/plugin-c contains a Composer plugin which is blocked by your allow-plugins config.";
    $stage = $this->createStage();
    $stage->create();
    $stage->require(['drupal/core:9.8.1']);
    try {
    // We are trying to add package plugin-c but not allowing it in config,
    // so we expect the operation to fail on PreApplyEvent.
    $stage->apply();
    }
    catch (StageEventException $e) {
    // Processing is required because the error message we get from Composer
    // contains multiple white spaces at the start or end of line.
    $this->assertStringContainsString($expected_message, preg_replace('/\s\s+/', '', $e->getMessage()));
    $this->assertInstanceOf(PreApplyEvent::class, $e->event);
    }
    }
    /**
    * Tests additional composer plugins can be trusted during pre-create.
    *
    ......
    0% Loading or .
    You are about to add 0 people to the discussion. Proceed with caution.
    Please register or to comment