Skip to content
Snippets Groups Projects
Commit d4fb6ede authored by Ted Bowman's avatar Ted Bowman Committed by Adam G-H
Browse files

Issue #3260698 by phenaproxima, tedbow: Make it simpler to disable validators in tests

parent 9fb17ac7
No related branches found
No related tags found
1 merge request!188Issue #3260698: Make it simpler to disable validators in tests
Showing
with 111 additions and 134 deletions
...@@ -28,6 +28,21 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase { ...@@ -28,6 +28,21 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase {
'package_manager_bypass', 'package_manager_bypass',
]; ];
/**
* The service IDs of any validators to disable.
*
* @var string[]
*/
protected $disableValidators = [
// Disable the filesystem permissions validator, since we cannot guarantee
// that the current code base will be writable in all testing situations.
// We test this validator functionally in Automatic Updates' build tests,
// since those do give us control over the filesystem permissions.
// @see \Drupal\Tests\automatic_updates\Build\CoreUpdateTest::assertReadOnlyFileSystemError()
// @see \Drupal\Tests\package_manager\Kernel\WritableFileSystemValidatorTest
'package_manager.validator.file_system',
];
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -41,20 +56,12 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase { ...@@ -41,20 +56,12 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase {
*/ */
public function register(ContainerBuilder $container) { public function register(ContainerBuilder $container) {
parent::register($container); parent::register($container);
$this->disableValidators($container);
}
/** foreach ($this->disableValidators as $service_id) {
* Disables any validators that will interfere with this test. if ($container->hasDefinition($service_id)) {
*/ $container->getDefinition($service_id)->clearTag('event_subscriber');
protected function disableValidators(ContainerBuilder $container): void { }
// Disable the filesystem permissions validator, since we cannot guarantee }
// that the current code base will be writable in all testing situations.
// We test this validator functionally in Automatic Updates' build tests,
// since those do give us control over the filesystem permissions.
// @see \Drupal\Tests\automatic_updates\Build\CoreUpdateTest::assertReadOnlyFileSystemError()
// @see \Drupal\Tests\package_manager\Kernel\WritableFileSystemValidatorTest
$container->removeDefinition('package_manager.validator.file_system');
} }
/** /**
......
...@@ -21,6 +21,14 @@ use Drupal\Core\DependencyInjection\ContainerBuilder; ...@@ -21,6 +21,14 @@ use Drupal\Core\DependencyInjection\ContainerBuilder;
*/ */
class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase { class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase {
/**
* {@inheritdoc}
*/
protected $disableValidators = [
// The parent class disables the validator we're testing, so prevent that
// here with an empty array.
];
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
...@@ -33,14 +41,6 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase { ...@@ -33,14 +41,6 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase {
->setClass(TestWritableFileSystemValidator::class); ->setClass(TestWritableFileSystemValidator::class);
} }
/**
* {@inheritdoc}
*/
protected function disableValidators(ContainerBuilder $container): void {
// The parent method disables the validator we're testing, so we don't want
// to do anything here.
}
/** /**
* Data provider for ::testWritable(). * Data provider for ::testWritable().
* *
......
name: 'Automatic Updates Test: Disable validators'
description: Allows certain update validators to be disabled during testing.
type: module
package: Testing
<?php
namespace Drupal\automatic_updates_test_disable_validators;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\Core\DependencyInjection\ServiceProviderBase;
use Drupal\Core\Site\Settings;
/**
* Allows specific validators to be disabled by site settings.
*
* This should only really be used by functional tests. Kernel tests should
* override their ::register() method to remove service definitions; build tests
* should stay out of the API/services layer unless absolutely necessary.
*/
class AutomaticUpdatesTestDisableValidatorsServiceProvider extends ServiceProviderBase {
/**
* {@inheritdoc}
*/
public function alter(ContainerBuilder $container) {
$validators = Settings::get('automatic_updates_disable_validators', []);
array_walk($validators, [$container, 'removeDefinition']);
}
}
...@@ -2,6 +2,7 @@ ...@@ -2,6 +2,7 @@
namespace Drupal\Tests\automatic_updates\Functional; namespace Drupal\Tests\automatic_updates\Functional;
use Drupal\Component\Serialization\Yaml;
use Drupal\Tests\BrowserTestBase; use Drupal\Tests\BrowserTestBase;
/** /**
...@@ -12,41 +13,54 @@ abstract class AutomaticUpdatesFunctionalTestBase extends BrowserTestBase { ...@@ -12,41 +13,54 @@ abstract class AutomaticUpdatesFunctionalTestBase extends BrowserTestBase {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
protected static $modules = [ protected static $modules = ['update', 'update_test'];
'automatic_updates_test_disable_validators',
'update', /**
'update_test', * The service IDs of any validators to disable.
*
* @var string[]
*/
protected $disableValidators = [
// Disable the filesystem permissions validators, since we cannot guarantee
// that the current code base will be writable in all testing situations. We
// test these validators in our build tests, since those do give us control
// over the filesystem permissions.
// @see \Drupal\Tests\automatic_updates\Build\CoreUpdateTest::assertReadOnlyFileSystemError()
'automatic_updates.validator.file_system_permissions',
'package_manager.validator.file_system',
]; ];
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function prepareSettings() { protected function setUp() {
parent::prepareSettings(); parent::setUp();
$this->disableValidators($this->disableValidators);
$settings['settings']['automatic_updates_disable_validators'] = (object) [
'value' => $this->disableValidators(),
'required' => TRUE,
];
$this->writeSettings($settings);
} }
/** /**
* Returns the service IDs of any validators to disable. * Disables validators in the test site's services.yml.
*
* This modifies the service container such that the disabled validators are
* instances of stdClass, and not subscribed to any events.
* *
* @return string[] * @param string[] $validators
* The service IDs of the validators to disable. * The service IDs of the validators to disable.
*/ */
protected function disableValidators(): array { protected function disableValidators(array $validators): void {
// Disable the filesystem permissions validators, since we cannot guarantee $services_file = $this->getDrupalRoot() . '/' . $this->siteDirectory . '/services.yml';
// that the current code base will be writable in all testing situations. We $this->assertFileIsWritable($services_file);
// test these validators in our build tests, since those do give us control $services = file_get_contents($services_file);
// over the filesystem permissions. $services = Yaml::decode($services);
// @see \Drupal\Tests\automatic_updates\Build\CoreUpdateTest::assertReadOnlyFileSystemError()
return [ foreach ($validators as $service_id) {
'automatic_updates.validator.file_system_permissions', $services['services'][$service_id] = [
'package_manager.validator.file_system', 'class' => 'stdClass',
]; ];
}
file_put_contents($services_file, Yaml::encode($services));
// Ensure the container is rebuilt ASAP.
$this->kernel->invalidateContainer();
} }
/** /**
......
...@@ -70,21 +70,6 @@ class ReadinessValidationTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -70,21 +70,6 @@ class ReadinessValidationTest extends AutomaticUpdatesFunctionalTestBase {
$this->drupalLogin($this->reportViewerUser); $this->drupalLogin($this->reportViewerUser);
} }
/**
* {@inheritdoc}
*/
protected function disableValidators(): array {
$disable_validators = parent::disableValidators();
// Because all actual staging operations are bypassed by
// package_manager_bypass, disable this validator because it will complain
// if there's no actual Composer data to inspect.
// @todo Do this in ::testStoredResultsClearedAfterUpdate() only once
// https://www.drupal.org/project/automatic_updates/issues/3260698 is
// fixed.
$disable_validators[] = 'automatic_updates.staged_projects_validator';
return $disable_validators;
}
/** /**
* Tests readiness checkers on status report page. * Tests readiness checkers on status report page.
*/ */
...@@ -388,6 +373,11 @@ class ReadinessValidationTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -388,6 +373,11 @@ class ReadinessValidationTest extends AutomaticUpdatesFunctionalTestBase {
* Tests that stored validation results are deleted after an update. * Tests that stored validation results are deleted after an update.
*/ */
public function testStoredResultsClearedAfterUpdate(): void { public function testStoredResultsClearedAfterUpdate(): void {
// Because all actual staging operations are bypassed by
// package_manager_bypass, disable this validator because it will complain
// if there's no actual Composer data to inspect.
$this->disableValidators(['automatic_updates.staged_projects_validator']);
$assert_session = $this->assertSession(); $assert_session = $this->assertSession();
$page = $this->getSession()->getPage(); $page = $this->getSession()->getPage();
$this->drupalLogin($this->checkerRunnerUser); $this->drupalLogin($this->checkerRunnerUser);
......
...@@ -6,8 +6,8 @@ use Drupal\automatic_updates\Event\ReadinessCheckEvent; ...@@ -6,8 +6,8 @@ use Drupal\automatic_updates\Event\ReadinessCheckEvent;
use Drupal\package_manager\Event\PreCreateEvent; use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\ValidationResult; use Drupal\package_manager\ValidationResult;
use Drupal\automatic_updates_test\ReadinessChecker\TestChecker1; use Drupal\automatic_updates_test\ReadinessChecker\TestChecker1;
use Drupal\Tests\package_manager\Traits\PackageManagerBypassTestTrait;
use Drupal\Tests\automatic_updates\Traits\ValidationTestTrait; use Drupal\Tests\automatic_updates\Traits\ValidationTestTrait;
use Drupal\Tests\package_manager\Traits\PackageManagerBypassTestTrait;
/** /**
* @covers \Drupal\automatic_updates\Form\UpdaterForm * @covers \Drupal\automatic_updates\Form\UpdaterForm
...@@ -16,8 +16,8 @@ use Drupal\Tests\automatic_updates\Traits\ValidationTestTrait; ...@@ -16,8 +16,8 @@ use Drupal\Tests\automatic_updates\Traits\ValidationTestTrait;
*/ */
class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
use ValidationTestTrait;
use PackageManagerBypassTestTrait; use PackageManagerBypassTestTrait;
use ValidationTestTrait;
/** /**
* {@inheritdoc} * {@inheritdoc}
...@@ -38,6 +38,11 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -38,6 +38,11 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function setUp(): void { protected function setUp(): void {
// In this test class, all actual staging operations are bypassed by
// package_manager_bypass, which means this validator will complain because
// there is no actual Composer data for it to inspect.
$this->disableValidators[] = 'automatic_updates.staged_projects_validator';
parent::setUp(); parent::setUp();
$this->setReleaseMetadata(__DIR__ . '/../../fixtures/release-history/drupal.9.8.1-security.xml'); $this->setReleaseMetadata(__DIR__ . '/../../fixtures/release-history/drupal.9.8.1-security.xml');
...@@ -45,20 +50,6 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase { ...@@ -45,20 +50,6 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$this->checkForUpdates(); $this->checkForUpdates();
} }
/**
* {@inheritdoc}
*/
protected function disableValidators(): array {
$disabled_validators = parent::disableValidators();
// In this test class, all actual staging operations are bypassed by
// package_manager_bypass, which means this validator will complain because
// there is no actual Composer data for it to inspect.
$disabled_validators[] = 'automatic_updates.staged_projects_validator';
return $disabled_validators;
}
/** /**
* Data provider for URLs to the update form. * Data provider for URLs to the update form.
* *
......
...@@ -25,6 +25,21 @@ abstract class AutomaticUpdatesKernelTestBase extends KernelTestBase { ...@@ -25,6 +25,21 @@ abstract class AutomaticUpdatesKernelTestBase extends KernelTestBase {
*/ */
protected static $modules = ['system', 'update', 'update_test']; protected static $modules = ['system', 'update', 'update_test'];
/**
* The service IDs of any validators to disable.
*
* @var string[]
*/
protected $disableValidators = [
// Disable the filesystem permissions validator, since we cannot guarantee
// that the current code base will be writable in all testing situations.
// We test this validator functionally in our build tests, since those do
// give us control over the filesystem permissions.
// @see \Drupal\Tests\automatic_updates\Build\CoreUpdateTest::assertReadOnlyFileSystemError()
'automatic_updates.validator.file_system_permissions',
'package_manager.validator.file_system',
];
/** /**
* The mocked HTTP client that returns metadata about available updates. * The mocked HTTP client that returns metadata about available updates.
* *
...@@ -93,20 +108,11 @@ abstract class AutomaticUpdatesKernelTestBase extends KernelTestBase { ...@@ -93,20 +108,11 @@ abstract class AutomaticUpdatesKernelTestBase extends KernelTestBase {
$container->set('http_client', $this->client); $container->set('http_client', $this->client);
} }
$this->disableValidators($container); foreach ($this->disableValidators as $service_id) {
} if ($container->hasDefinition($service_id)) {
$container->getDefinition($service_id)->clearTag('event_subscriber');
/** }
* Disables any validators that will interfere with this test. }
*/
protected function disableValidators(ContainerBuilder $container): void {
// Disable the filesystem permissions validator, since we cannot guarantee
// that the current code base will be writable in all testing situations.
// We test this validator functionally in our build tests, since those do
// give us control over the filesystem permissions.
// @see \Drupal\Tests\automatic_updates\Build\CoreUpdateTest::assertReadOnlyFileSystemError()
$container->removeDefinition('automatic_updates.validator.file_system_permissions');
$container->removeDefinition('package_manager.validator.file_system');
} }
/** /**
......
...@@ -3,7 +3,6 @@ ...@@ -3,7 +3,6 @@
namespace Drupal\Tests\automatic_updates\Kernel\ReadinessValidation; namespace Drupal\Tests\automatic_updates\Kernel\ReadinessValidation;
use Drupal\automatic_updates\Event\ReadinessCheckEvent; use Drupal\automatic_updates\Event\ReadinessCheckEvent;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\package_manager\Validator\PreOperationStageValidatorInterface; use Drupal\package_manager\Validator\PreOperationStageValidatorInterface;
use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase; use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase;
use Prophecy\Argument; use Prophecy\Argument;
...@@ -33,9 +32,10 @@ class PackageManagerReadinessChecksTest extends AutomaticUpdatesKernelTestBase { ...@@ -33,9 +32,10 @@ class PackageManagerReadinessChecksTest extends AutomaticUpdatesKernelTestBase {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function disableValidators(ContainerBuilder $container): void { protected $disableValidators = [
// No need to disable any validators in this test. // The parent class disables one of the validators that we're testing, so
} // prevent that with an empty array.
];
/** /**
* Data provider for ::testValidatorInvoked(). * Data provider for ::testValidatorInvoked().
......
...@@ -30,22 +30,21 @@ class StagedProjectsValidatorTest extends AutomaticUpdatesKernelTestBase { ...@@ -30,22 +30,21 @@ class StagedProjectsValidatorTest extends AutomaticUpdatesKernelTestBase {
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
public function register(ContainerBuilder $container) { protected function setUp(): void {
parent::register($container); // This test deals with fake sites that don't necessarily have lock files,
// so disable lock file validation.
$container->getDefinition('automatic_updates.updater') $this->disableValidators[] = 'package_manager.validator.lock_file';
->setClass(TestUpdater::class); parent::setUp();
} }
/** /**
* {@inheritdoc} * {@inheritdoc}
*/ */
protected function disableValidators(ContainerBuilder $container): void { public function register(ContainerBuilder $container) {
parent::disableValidators($container); parent::register($container);
// This test deals with fake sites that don't necessarily have lock files, $container->getDefinition('automatic_updates.updater')
// so disable lock file validation. ->setClass(TestUpdater::class);
$container->removeDefinition('package_manager.validator.lock_file');
} }
/** /**
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment