diff --git a/src/Validator/XdebugValidator.php b/src/Validator/XdebugValidator.php index 84fa455bb16a593a1dbb569ee415901962be6eaf..b9237e1ed5df6cf1ec1c09ddcaa2dfbb0382d8ef 100644 --- a/src/Validator/XdebugValidator.php +++ b/src/Validator/XdebugValidator.php @@ -2,8 +2,11 @@ namespace Drupal\automatic_updates\Validator; +use Drupal\automatic_updates\CronUpdater; use Drupal\automatic_updates\Event\ReadinessCheckEvent; use Drupal\Core\StringTranslation\StringTranslationTrait; +use Drupal\package_manager\Event\PreCreateEvent; +use Drupal\package_manager\Event\PreOperationStageEvent; use Symfony\Component\EventDispatcher\EventSubscriberInterface; /** @@ -21,14 +24,21 @@ final class XdebugValidator implements EventSubscriberInterface { /** * Flags a warning if Xdebug is enabled. * - * @param \Drupal\automatic_updates\Event\ReadinessCheckEvent $event + * @param \Drupal\package_manager\Event\PreOperationStageEvent $event * The event object. */ - public function checkForXdebug(ReadinessCheckEvent $event): void { - if (extension_loaded('xdebug')) { - $event->addWarning([ + public function checkForXdebug(PreOperationStageEvent $event): void { + if (function_exists('xdebug_break')) { + $messages = [ $this->t('Xdebug is enabled, which may cause timeout errors.'), - ]); + ]; + + if ($event->getStage() instanceof CronUpdater && $event instanceof PreCreateEvent) { + $event->addError($messages); + } + else { + $event->addWarning($messages); + } } } @@ -38,6 +48,7 @@ final class XdebugValidator implements EventSubscriberInterface { public static function getSubscribedEvents() { return [ ReadinessCheckEvent::class => 'checkForXdebug', + PreCreateEvent::class => 'checkForXdebug', ]; } diff --git a/tests/src/Kernel/ReadinessValidation/XdebugValidatorTest.php b/tests/src/Kernel/ReadinessValidation/XdebugValidatorTest.php new file mode 100644 index 0000000000000000000000000000000000000000..87629be5ad06529640bb74ea39c59d5663e7c9af --- /dev/null +++ b/tests/src/Kernel/ReadinessValidation/XdebugValidatorTest.php @@ -0,0 +1,69 @@ +<?php + +namespace Drupal\Tests\automatic_updates\Kernel\ReadinessValidation; + +use Drupal\automatic_updates\CronUpdater; +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; + +/** + * @covers \Drupal\automatic_updates\Validator\XdebugValidator + * + * @group automatic_updates + */ +class XdebugValidatorTest extends AutomaticUpdatesKernelTestBase { + + use PackageManagerBypassTestTrait; + + /** + * {@inheritdoc} + */ + protected static $modules = ['automatic_updates']; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + // Ensure the validator will think Xdebug is enabled. + if (!function_exists('xdebug_break')) { + // @codingStandardsIgnoreLine + eval('function xdebug_break() {}'); + } + parent::setUp(); + + // The parent class unconditionally disables the Xdebug validator we're + // testing, so undo that here. + $validator = $this->container->get('automatic_updates.validator.xdebug'); + $this->container->get('event_dispatcher')->addSubscriber($validator); + } + + /** + * Tests warnings and/or errors if Xdebug is enabled. + */ + public function testXdebugValidation(): void { + $message = 'Xdebug is enabled, which may cause timeout errors.'; + + $result = ValidationResult::createWarning([$message]); + $this->assertCheckerResultsFromManager([$result], TRUE); + + // The parent class' setUp() method simulates an available security update, + // so ensure that the cron updater will try to update to it. + $this->config('automatic_updates.settings') + ->set('cron', CronUpdater::SECURITY) + ->save(); + + // Trying to do the update during cron should fail with an error. + $logger = new TestLogger(); + $this->container->get('logger.factory') + ->get('automatic_updates') + ->addLogger($logger); + + $this->container->get('cron')->run(); + $this->assertUpdateStagedTimes(0); + $this->assertTrue($logger->hasRecordThatMatches("/$message/", RfcLogLevel::ERROR)); + } + +}