diff --git a/automatic_updates_extensions/tests/src/Functional/UpdateErrorTest.php b/automatic_updates_extensions/tests/src/Functional/UpdateErrorTest.php index 83931efd553d38ea77fd1cfa6f4dc2941073f1ef..f72cd4a6ef95db9fe41053c775cd00b402d86956 100644 --- a/automatic_updates_extensions/tests/src/Functional/UpdateErrorTest.php +++ b/automatic_updates_extensions/tests/src/Functional/UpdateErrorTest.php @@ -7,7 +7,7 @@ namespace Drupal\Tests\automatic_updates_extensions\Functional; use Drupal\automatic_updates_test\EventSubscriber\TestSubscriber1; use Drupal\package_manager\Event\StatusCheckEvent; use Drupal\package_manager\ValidationResult; -use Drupal\package_manager_bypass\Committer; +use Drupal\package_manager_bypass\LoggingCommitter; use Drupal\package_manager_test_validation\EventSubscriber\TestSubscriber; /** @@ -38,7 +38,7 @@ class UpdateErrorTest extends UpdaterFormTestBase { $this->checkForMetaRefresh(); $this->assertUpdateStagedTimes(1); $assert_session->pageTextNotContains('The following dependencies will also be updated:'); - Committer::setException(new \Exception('failed at committer')); + LoggingCommitter::setException(new \Exception('failed at committer')); $page->pressButton('Continue'); $this->checkForMetaRefresh(); $assert_session->pageTextContainsOnce('An error has occurred.'); diff --git a/package_manager/tests/modules/package_manager_bypass/package_manager_bypass.info.yml b/package_manager/tests/modules/package_manager_bypass/package_manager_bypass.info.yml index b2731f7e944941af86eacf65e6cd89be7b7e0db0..4c3ed06efd484f208c1d1860e27a83f429bb9343 100644 --- a/package_manager/tests/modules/package_manager_bypass/package_manager_bypass.info.yml +++ b/package_manager/tests/modules/package_manager_bypass/package_manager_bypass.info.yml @@ -1,5 +1,5 @@ name: 'Package Manager Bypass' -description: 'Mocks Package Manager services for functional testing.' +description: 'Mocks PathLocator service, decorates Beginner & Committer services (adds logging) and by default bypasses the Stager service (to minimize I/O during tests).' type: module package: Testing dependencies: diff --git a/package_manager/tests/modules/package_manager_bypass/package_manager_bypass.services.yml b/package_manager/tests/modules/package_manager_bypass/package_manager_bypass.services.yml index da76b850debb14aebd68e160e3bd60f1fab20188..7881bb9a11d082203667328ff26828929f47dadb 100644 --- a/package_manager/tests/modules/package_manager_bypass/package_manager_bypass.services.yml +++ b/package_manager/tests/modules/package_manager_bypass/package_manager_bypass.services.yml @@ -1,9 +1,9 @@ services: package_manager_bypass.beginner: - class: Drupal\package_manager_bypass\Beginner + class: Drupal\package_manager_bypass\LoggingBeginner arguments: ['@state', '@package_manager_bypass.beginner.inner' ] decorates: 'package_manager.beginner' package_manager_bypass.committer: - class: Drupal\package_manager_bypass\Committer + class: Drupal\package_manager_bypass\LoggingCommitter arguments: [ '@state', '@package_manager_bypass.committer.inner' ] decorates: 'package_manager.committer' diff --git a/package_manager/tests/modules/package_manager_bypass/src/Beginner.php b/package_manager/tests/modules/package_manager_bypass/src/LoggingBeginner.php similarity index 89% rename from package_manager/tests/modules/package_manager_bypass/src/Beginner.php rename to package_manager/tests/modules/package_manager_bypass/src/LoggingBeginner.php index d19ba474b7c754806d8f850d30b184765f04cb1e..83b15c61d115838e17ea10dd07659e0d832050a8 100644 --- a/package_manager/tests/modules/package_manager_bypass/src/Beginner.php +++ b/package_manager/tests/modules/package_manager_bypass/src/LoggingBeginner.php @@ -12,9 +12,13 @@ use PhpTuf\ComposerStager\Domain\Value\Path\PathInterface; use PhpTuf\ComposerStager\Domain\Value\PathList\PathListInterface; /** - * Defines a service that decorates the Composer Stager beginner service. + * A composer-stager Beginner decorator that adds logging. + * + * @internal */ -class Beginner extends BypassedStagerServiceBase implements BeginnerInterface { +final class LoggingBeginner implements BeginnerInterface { + + use LoggingDecoratorTrait; /** * The decorated service. diff --git a/package_manager/tests/modules/package_manager_bypass/src/Committer.php b/package_manager/tests/modules/package_manager_bypass/src/LoggingCommitter.php similarity index 91% rename from package_manager/tests/modules/package_manager_bypass/src/Committer.php rename to package_manager/tests/modules/package_manager_bypass/src/LoggingCommitter.php index 5c3ea425193a8fa044fe48524b38af15203bcf4b..bafb28811ffbe00a22bc70b96e7cc5e7321b743f 100644 --- a/package_manager/tests/modules/package_manager_bypass/src/Committer.php +++ b/package_manager/tests/modules/package_manager_bypass/src/LoggingCommitter.php @@ -12,9 +12,13 @@ use PhpTuf\ComposerStager\Domain\Value\Path\PathInterface; use PhpTuf\ComposerStager\Domain\Value\PathList\PathListInterface; /** - * Defines a service that decorates the Composer Stager committer service. + * A composer-stager Committer decorator that adds logging. + * + * @internal */ -class Committer extends BypassedStagerServiceBase implements CommitterInterface { +final class LoggingCommitter implements CommitterInterface { + + use LoggingDecoratorTrait; /** * The decorated service. diff --git a/package_manager/tests/modules/package_manager_bypass/src/BypassedStagerServiceBase.php b/package_manager/tests/modules/package_manager_bypass/src/LoggingDecoratorTrait.php similarity index 96% rename from package_manager/tests/modules/package_manager_bypass/src/BypassedStagerServiceBase.php rename to package_manager/tests/modules/package_manager_bypass/src/LoggingDecoratorTrait.php index cb779b2770a57739bed9946cb76e923844f50ad0..3b079d9106828784e1a74404f45de99ac6902373 100644 --- a/package_manager/tests/modules/package_manager_bypass/src/BypassedStagerServiceBase.php +++ b/package_manager/tests/modules/package_manager_bypass/src/LoggingDecoratorTrait.php @@ -10,8 +10,10 @@ namespace Drupal\package_manager_bypass; * This can be used by functional tests to ensure that the bypassed Composer * Stager services were called as expected. Kernel and unit tests should use * regular mocks instead. + * + * @internal */ -abstract class BypassedStagerServiceBase { +trait LoggingDecoratorTrait { /** * The state service. diff --git a/package_manager/tests/modules/package_manager_bypass/src/PathLocator.php b/package_manager/tests/modules/package_manager_bypass/src/MockPathLocator.php similarity index 95% rename from package_manager/tests/modules/package_manager_bypass/src/PathLocator.php rename to package_manager/tests/modules/package_manager_bypass/src/MockPathLocator.php index 4bbfee5b57de40b07a915d0c61d91b63b387f433..cc90fd6b398befbe15846f9e6f1b364bba5a354a 100644 --- a/package_manager/tests/modules/package_manager_bypass/src/PathLocator.php +++ b/package_manager/tests/modules/package_manager_bypass/src/MockPathLocator.php @@ -9,9 +9,11 @@ use Drupal\package_manager\PathLocator as BasePathLocator; use Drupal\package_manager\Path; /** - * Overrides the path locator to return pre-set values for testing purposes. + * Mock path locator: allows specifying paths instead of discovering paths. + * + * @internal */ -class PathLocator extends BasePathLocator { +final class MockPathLocator extends BasePathLocator { /** * The state service. diff --git a/package_manager/tests/modules/package_manager_bypass/src/Stager.php b/package_manager/tests/modules/package_manager_bypass/src/NoOpStager.php similarity index 76% rename from package_manager/tests/modules/package_manager_bypass/src/Stager.php rename to package_manager/tests/modules/package_manager_bypass/src/NoOpStager.php index a5420693d836099f988778ae13cd701969a97bd8..a0ad0af166c8b652f15ebc7114c23ab2ba32dbde 100644 --- a/package_manager/tests/modules/package_manager_bypass/src/Stager.php +++ b/package_manager/tests/modules/package_manager_bypass/src/NoOpStager.php @@ -12,9 +12,22 @@ use PhpTuf\ComposerStager\Domain\Service\ProcessRunner\ProcessRunnerInterface; use PhpTuf\ComposerStager\Domain\Value\Path\PathInterface; /** - * Defines an update stager which doesn't actually do anything. + * A composer-stager Stager implementation that does nothing, except logging. + * + * By default, it will modify composer.lock in the stage directory, to fool the + * \Drupal\package_manager\Validator\LockFileValidator into thinking that there + * are pending composer operations. + * + * Opt out of this by calling @code setLockFileShouldChange(FALSE) @endcode. + * + * @see ::setLockFileShouldChange() + * @see \Drupal\package_manager\Validator\LockFileValidator + * + * @internal */ -class Stager extends BypassedStagerServiceBase implements StagerInterface { +final class NoOpStager implements StagerInterface { + + use LoggingDecoratorTrait; /** * Constructs a Stager object. diff --git a/package_manager/tests/modules/package_manager_bypass/src/PackageManagerBypassServiceProvider.php b/package_manager/tests/modules/package_manager_bypass/src/PackageManagerBypassServiceProvider.php index 171604c0b56a7fff8b037cc2c027aaca7bcae6a3..7c54315897d0ed5a569d2c3e774c833cc45de6c4 100644 --- a/package_manager/tests/modules/package_manager_bypass/src/PackageManagerBypassServiceProvider.php +++ b/package_manager/tests/modules/package_manager_bypass/src/PackageManagerBypassServiceProvider.php @@ -11,8 +11,10 @@ use Symfony\Component\DependencyInjection\Reference; /** * Defines services to bypass Package Manager's core functionality. + * + * @internal */ -class PackageManagerBypassServiceProvider extends ServiceProviderBase { +final class PackageManagerBypassServiceProvider extends ServiceProviderBase { /** * {@inheritdoc} @@ -21,12 +23,13 @@ class PackageManagerBypassServiceProvider extends ServiceProviderBase { parent::alter($container); $state = new Reference('state'); + // By default, \Drupal\package_manager_bypass\Stager if (Settings::get('package_manager_bypass_composer_stager', TRUE)) { - $container->getDefinition('package_manager.stager')->setClass(Stager::class)->setArguments([$state]); + $container->getDefinition('package_manager.stager')->setClass(NoOpStager::class)->setArguments([$state]); } $definition = $container->getDefinition('package_manager.path_locator') - ->setClass(PathLocator::class); + ->setClass(MockPathLocator::class); $arguments = $definition->getArguments(); array_unshift($arguments, $state); $definition->setArguments($arguments); diff --git a/package_manager/tests/src/Kernel/LockFileValidatorTest.php b/package_manager/tests/src/Kernel/LockFileValidatorTest.php index 9bb8e8bcda6ba40e94e8d0541451e329e4e6c844..48728582ed2afafb75ebeacec3d6131b4ef22c57 100644 --- a/package_manager/tests/src/Kernel/LockFileValidatorTest.php +++ b/package_manager/tests/src/Kernel/LockFileValidatorTest.php @@ -9,7 +9,7 @@ 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_bypass\Stager; +use Drupal\package_manager_bypass\NoOpStager; /** * @coversDefaultClass \Drupal\package_manager\Validator\LockFileValidator @@ -137,7 +137,7 @@ class LockFileValidatorTest extends PackageManagerKernelTestBase { */ public function testApplyWithNoChange(): void { // Leave the staged lock file alone. - Stager::setLockFileShouldChange(FALSE); + NoOpStager::setLockFileShouldChange(FALSE); $result = ValidationResult::createError([ t('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 000b5ff721d86511fc43d5028a91941cf2f70369..499ab51fb9b84d003492daa43dffd50c4b854636 100644 --- a/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php +++ b/package_manager/tests/src/Kernel/PackageManagerKernelTestBase.php @@ -267,7 +267,7 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase { // Ensure the path locator points to the test project. We assume that is its // own web root and the vendor directory is at its top level. - /** @var \Drupal\package_manager_bypass\PathLocator $path_locator */ + /** @var \Drupal\package_manager_bypass\MockPathLocator $path_locator */ $path_locator = $this->container->get('package_manager.path_locator'); $path_locator->setPaths($active_dir, $active_dir . '/vendor', '', $staging_root); diff --git a/package_manager/tests/src/Kernel/StageTest.php b/package_manager/tests/src/Kernel/StageTest.php index e135ec9e33d9c2d6d2955f32fe4bfa9b2b56c4b8..e68d564783a35febf2448b4a7d9bb55528592b96 100644 --- a/package_manager/tests/src/Kernel/StageTest.php +++ b/package_manager/tests/src/Kernel/StageTest.php @@ -18,7 +18,7 @@ use Drupal\package_manager\Event\StageEvent; use Drupal\package_manager\Exception\ApplyFailedException; use Drupal\package_manager\Exception\StageException; use Drupal\package_manager\Stage; -use Drupal\package_manager_bypass\Committer; +use Drupal\package_manager_bypass\LoggingCommitter; use PhpTuf\ComposerStager\Domain\Exception\InvalidArgumentException; use PhpTuf\ComposerStager\Domain\Exception\PreconditionException; use PhpTuf\ComposerStager\Domain\Service\Precondition\PreconditionInterface; @@ -63,7 +63,7 @@ class StageTest extends PackageManagerKernelTestBase { $validator = $this->container->get('package_manager.validator.file_system'); $this->container->get('event_dispatcher')->removeSubscriber($validator); - /** @var \Drupal\package_manager_bypass\PathLocator $path_locator */ + /** @var \Drupal\package_manager_bypass\MockPathLocator $path_locator */ $path_locator = $this->container->get('package_manager.path_locator'); $stage = $this->createStage(); @@ -188,7 +188,7 @@ class StageTest extends PackageManagerKernelTestBase { // testing purposes. $event->getStage()->destroy($force); // @see \PhpTuf\ComposerStager\Infrastructure\Service\Precondition\StagingDirDoesNotExist - Committer::setException( + LoggingCommitter::setException( new PreconditionException( $this->prophesize(PreconditionInterface::class)->reveal(), 'Stage directory does not exist', @@ -327,7 +327,7 @@ class StageTest extends PackageManagerKernelTestBase { else { $throwable = new $thrown_class($thrown_message, 123); } - Committer::setException($throwable); + LoggingCommitter::setException($throwable); try { $stage->apply(); @@ -360,7 +360,7 @@ class StageTest extends PackageManagerKernelTestBase { // Make the committer throw an exception, which should cause the failure // marker to be present. $thrown = new \Exception('Disastrous catastrophe!'); - Committer::setException($thrown); + LoggingCommitter::setException($thrown); try { $stage->apply(); $this->fail('Expected an exception.'); diff --git a/tests/src/Functional/UpdateFailedTest.php b/tests/src/Functional/UpdateFailedTest.php index 90f8db47473abbebe99b0b5c24153d8fe64ffca1..028e1b143eae0603320c8f3332987407406fbdea 100644 --- a/tests/src/Functional/UpdateFailedTest.php +++ b/tests/src/Functional/UpdateFailedTest.php @@ -4,7 +4,7 @@ declare(strict_types = 1); namespace Drupal\Tests\automatic_updates\Functional; -use Drupal\package_manager_bypass\Committer; +use Drupal\package_manager_bypass\LoggingCommitter; /** * @covers \Drupal\automatic_updates\Form\UpdaterForm @@ -31,7 +31,7 @@ class UpdateFailedTest extends UpdaterFormTestBase { $this->checkForMetaRefresh(); $this->assertUpdateStagedTimes(1); - Committer::setException(new \Exception('failed at committer')); + LoggingCommitter::setException(new \Exception('failed at committer')); $page->pressButton('Continue'); $this->checkForMetaRefresh(); $assert_session->pageTextContainsOnce('An error has occurred.'); diff --git a/tests/src/Kernel/CronUpdaterTest.php b/tests/src/Kernel/CronUpdaterTest.php index e1d16bf920412eb246d3135a0e21e97203afb6d0..a2160606359e55993385da29965ae084a7e8ea22 100644 --- a/tests/src/Kernel/CronUpdaterTest.php +++ b/tests/src/Kernel/CronUpdaterTest.php @@ -20,7 +20,7 @@ use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Exception\StageOwnershipException; use Drupal\package_manager\Exception\StageValidationException; use Drupal\package_manager\ValidationResult; -use Drupal\package_manager_bypass\Committer; +use Drupal\package_manager_bypass\LoggingCommitter; use Drupal\Tests\automatic_updates\Traits\EmailNotificationsTestTrait; use Drupal\Tests\package_manager\Kernel\TestStage; use Drupal\Tests\package_manager\Traits\PackageManagerBypassTestTrait; @@ -577,7 +577,7 @@ END; public function testApplyFailureEmail(): void { $this->getStageFixtureManipulator()->setCorePackageVersion('9.8.1'); $error = new \Exception('I drink your milkshake!'); - Committer::setException($error); + LoggingCommitter::setException($error); $this->container->get('cron')->run(); $expected_body = <<<END diff --git a/tests/src/Kernel/UpdaterTest.php b/tests/src/Kernel/UpdaterTest.php index 75b39992544b49a74e257fd00345eeae78978f38..5ce66877608e84aa4a7e9f66d470fa110b6b5588 100644 --- a/tests/src/Kernel/UpdaterTest.php +++ b/tests/src/Kernel/UpdaterTest.php @@ -11,7 +11,7 @@ use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Event\PreRequireEvent; use Drupal\package_manager\Exception\StageException; use Drupal\package_manager\ValidationResult; -use Drupal\package_manager_bypass\Committer; +use Drupal\package_manager_bypass\LoggingCommitter; use Drupal\Tests\package_manager\Kernel\TestStageValidationException; use Drupal\Tests\user\Traits\UserCreationTrait; use PhpTuf\ComposerStager\Domain\Exception\InvalidArgumentException; @@ -188,7 +188,7 @@ class UpdaterTest extends AutomaticUpdatesKernelTestBase { ]); $updater->stage(); $thrown_message = 'A very bad thing happened'; - Committer::setException(new $thrown_class($thrown_message, 123)); + LoggingCommitter::setException(new $thrown_class($thrown_message, 123)); $this->expectException($expected_class); $expected_message = $expected_class === UpdateException::class ? "The update operation failed to apply completely. All the files necessary to run Drupal correctly and securely are probably not present. It is strongly recommended to restore your site's code and database from a backup."