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
No related merge requests found
Showing
with 111 additions and 134 deletions
......@@ -28,6 +28,21 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase {
'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}
*/
......@@ -41,20 +56,12 @@ abstract class PackageManagerKernelTestBase extends KernelTestBase {
*/
public function register(ContainerBuilder $container) {
parent::register($container);
$this->disableValidators($container);
}
/**
* 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 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');
foreach ($this->disableValidators as $service_id) {
if ($container->hasDefinition($service_id)) {
$container->getDefinition($service_id)->clearTag('event_subscriber');
}
}
}
/**
......
......@@ -21,6 +21,14 @@ use Drupal\Core\DependencyInjection\ContainerBuilder;
*/
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}
*/
......@@ -33,14 +41,6 @@ class WritableFileSystemValidatorTest extends PackageManagerKernelTestBase {
->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().
*
......
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 @@
namespace Drupal\Tests\automatic_updates\Functional;
use Drupal\Component\Serialization\Yaml;
use Drupal\Tests\BrowserTestBase;
/**
......@@ -12,41 +13,54 @@ abstract class AutomaticUpdatesFunctionalTestBase extends BrowserTestBase {
/**
* {@inheritdoc}
*/
protected static $modules = [
'automatic_updates_test_disable_validators',
'update',
'update_test',
protected static $modules = ['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}
*/
protected function prepareSettings() {
parent::prepareSettings();
$settings['settings']['automatic_updates_disable_validators'] = (object) [
'value' => $this->disableValidators(),
'required' => TRUE,
];
$this->writeSettings($settings);
protected function setUp() {
parent::setUp();
$this->disableValidators($this->disableValidators);
}
/**
* 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.
*/
protected function disableValidators(): array {
// 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()
return [
'automatic_updates.validator.file_system_permissions',
'package_manager.validator.file_system',
];
protected function disableValidators(array $validators): void {
$services_file = $this->getDrupalRoot() . '/' . $this->siteDirectory . '/services.yml';
$this->assertFileIsWritable($services_file);
$services = file_get_contents($services_file);
$services = Yaml::decode($services);
foreach ($validators as $service_id) {
$services['services'][$service_id] = [
'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 {
$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.
*/
......@@ -388,6 +373,11 @@ class ReadinessValidationTest extends AutomaticUpdatesFunctionalTestBase {
* Tests that stored validation results are deleted after an update.
*/
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();
$page = $this->getSession()->getPage();
$this->drupalLogin($this->checkerRunnerUser);
......
......@@ -6,8 +6,8 @@ use Drupal\automatic_updates\Event\ReadinessCheckEvent;
use Drupal\package_manager\Event\PreCreateEvent;
use Drupal\package_manager\ValidationResult;
use Drupal\automatic_updates_test\ReadinessChecker\TestChecker1;
use Drupal\Tests\package_manager\Traits\PackageManagerBypassTestTrait;
use Drupal\Tests\automatic_updates\Traits\ValidationTestTrait;
use Drupal\Tests\package_manager\Traits\PackageManagerBypassTestTrait;
/**
* @covers \Drupal\automatic_updates\Form\UpdaterForm
......@@ -16,8 +16,8 @@ use Drupal\Tests\automatic_updates\Traits\ValidationTestTrait;
*/
class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
use ValidationTestTrait;
use PackageManagerBypassTestTrait;
use ValidationTestTrait;
/**
* {@inheritdoc}
......@@ -38,6 +38,11 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
* {@inheritdoc}
*/
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();
$this->setReleaseMetadata(__DIR__ . '/../../fixtures/release-history/drupal.9.8.1-security.xml');
......@@ -45,20 +50,6 @@ class UpdaterFormTest extends AutomaticUpdatesFunctionalTestBase {
$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.
*
......
......@@ -25,6 +25,21 @@ abstract class AutomaticUpdatesKernelTestBase extends KernelTestBase {
*/
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.
*
......@@ -93,20 +108,11 @@ abstract class AutomaticUpdatesKernelTestBase extends KernelTestBase {
$container->set('http_client', $this->client);
}
$this->disableValidators($container);
}
/**
* 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');
foreach ($this->disableValidators as $service_id) {
if ($container->hasDefinition($service_id)) {
$container->getDefinition($service_id)->clearTag('event_subscriber');
}
}
}
/**
......
......@@ -3,7 +3,6 @@
namespace Drupal\Tests\automatic_updates\Kernel\ReadinessValidation;
use Drupal\automatic_updates\Event\ReadinessCheckEvent;
use Drupal\Core\DependencyInjection\ContainerBuilder;
use Drupal\package_manager\Validator\PreOperationStageValidatorInterface;
use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase;
use Prophecy\Argument;
......@@ -33,9 +32,10 @@ class PackageManagerReadinessChecksTest extends AutomaticUpdatesKernelTestBase {
/**
* {@inheritdoc}
*/
protected function disableValidators(ContainerBuilder $container): void {
// No need to disable any validators in this test.
}
protected $disableValidators = [
// The parent class disables one of the validators that we're testing, so
// prevent that with an empty array.
];
/**
* Data provider for ::testValidatorInvoked().
......
......@@ -30,22 +30,21 @@ class StagedProjectsValidatorTest extends AutomaticUpdatesKernelTestBase {
/**
* {@inheritdoc}
*/
public function register(ContainerBuilder $container) {
parent::register($container);
$container->getDefinition('automatic_updates.updater')
->setClass(TestUpdater::class);
protected function setUp(): void {
// This test deals with fake sites that don't necessarily have lock files,
// so disable lock file validation.
$this->disableValidators[] = 'package_manager.validator.lock_file';
parent::setUp();
}
/**
* {@inheritdoc}
*/
protected function disableValidators(ContainerBuilder $container): void {
parent::disableValidators($container);
public function register(ContainerBuilder $container) {
parent::register($container);
// This test deals with fake sites that don't necessarily have lock files,
// so disable lock file validation.
$container->removeDefinition('package_manager.validator.lock_file');
$container->getDefinition('automatic_updates.updater')
->setClass(TestUpdater::class);
}
/**
......
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