Follow-up to #697760: Replace getInfo() in tests with native phpDoc + annotations (following PHPUnit)

Objective

  1. /core/tests/bootstrap.php contains custom code for discovering Drupal extensions + registering their namespaces + test namespaces.

  2. The intended logic is identical to TestDiscovery - duplicate code.

Proposed solution

  1. Replace the custom code and call TestDiscovery::registerNamespaces() instead.

    → No more duplicated code. Single code path. Simplified maintenance. Less bugs.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

sun’s picture

Status: Active » Needs review
FileSize
7.39 KB
andypost’s picture

  1. +++ b/core/lib/Drupal/Core/EventSubscriber/SpecialAttributesRouteSubscriber.php
    @@ -34,12 +34,10 @@ protected function alterRoutes(RouteCollection $collection) {
    -        $placeholders = array('@variables' => implode(', ', $not_allowed_variables));
    -        drupal_set_message(String::format('The following variables are reserved names by drupal: @variables', $placeholders));
    -        watchdog('error', 'The following variables are reserved names by drupal: @variables', $placeholders);
    -        return FALSE;
    +        $reserved = implode(', ', $not_allowed_variables);
    +        throw new \LogicException(sprintf('Route %s uses reserved variable names: %s', $name, $reserved));
    

    not sure route name is passed...

    also '@' check_plain() is removed, are you sure that all data secure?

  2. +++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
    @@ -136,7 +136,14 @@ public function scan($type, $include_tests = NULL) {
    +    if (function_exists('conf_path')) {
    ...
    +    else {
    +      $searchdirs[static::ORIGIN_SITE] = 'sites/default';
    

    why this is used?

sun’s picture

FileSize
4.63 KB
2.76 KB

Reverted change to SpecialAttributesRouteSubscriber. (@Crell raised concerns in IRC.)

sun’s picture

FWIW, there happens to be an existing issue for the changes reverted in #3: #2051877: Log error when people use invalid route parameters

sun’s picture

#2.2 is indeed the only difference between the current PHPUnit bootstrap.php in HEAD and TestDiscovery. Trying to dissect the situation for myself, and verbosely:

TestDiscovery retrieves the list of available extensions from ExtensionDiscovery, which scans in the current (single) site directory only. (by default, /sites/default)

The current bootstrap.php scans the /sites directory itself for site subdirectories, and includes extensions from all site directories.

I'm not sure how to address that yet, and also, whether we need to address it in the first place. Running tests from all site directories may work for pure unit tests, but as soon as we're going to run web/acceptance/BDD tests via PHPUnit, Drupal core's multi-site path discovery will kick in → A module located in a site-specific directory cannot be installed in the test, because it is not found to begin with.

run-tests.sh resolves that issue via the --url command line option, which causes the script to create a fake Request for the specified base URL, which in turn is used to discover the site-specific directory. If --url is omitted, then /sites/default is used (but web tests will not work, unless Drupal is served directly on http://localhost).

I just performed a quick test, and it appears to be possible to pass custom options to phpunit without causing it to break. A value that follows a long option (e.g., --url http://...) seems to be interpreted as the option's value and not as a separate argument to phpunit itself.

So theoretically, it might be possible to re-implement the site directory negotiation for phpunit. Whether that's a good idea is a different question, of course.

tstoeckler’s picture

+++ b/core/tests/bootstrap.php
@@ -2,88 +2,24 @@
+// As long as no further classes are needed, a single include is sufficient.
+require_once __DIR__ . '/../modules/simpletest/src/TestDiscovery.php';

Maybe not as part of this issue, but this hints to me that that class should be in \Drupal\Core.

Patch itself looks good.

Mile23’s picture

An OOP solution would be better of course. A solution that all systems could leverage would be ideal.

+++ b/core/lib/Drupal/Core/Extension/ExtensionDiscovery.php
@@ -136,7 +136,14 @@ public function scan($type, $include_tests = NULL) {
+      $searchdirs[static::ORIGIN_SITE] = conf_path();

You mean DrupalKernel::getSitePath() of course. :-)

That is, soon this bootstrap script will require a kernel object with a container.

Which is bad.

+require_once __DIR__ . '/../modules/simpletest/src/TestDiscovery.php';
Maybe not as part of this issue, but this hints to me that that class should be in \Drupal\Core.

Really \Drupal\Tests, which means SimpleTest can't get it. :-) That's one reason this script is lean and mean and functional.

Mile23’s picture

Title: Use TestDiscovery to register test namespaces for running PHPUnit » Use ExtensionDiscovery to register test namespaces for running PHPUnit
Assigned: sun » Unassigned
Category: Task » Bug report
Issue tags: +rc eligible
FileSize
35.19 KB
4.34 KB

So Drupal\Core\Extension\ExtensionDiscovery has reduced its dependencies, and you can (almost) inject the site path (see: #2605654: Modify Drupal\Core\Extension\ExtensionDiscovery to allow for scanning multiple file systems, enabling vfsStream testing).

Here are two patches:

The small one is a POC and changes core/tests/bootstrap.php to use ExtensionDiscovery. It will fail, because core/includes/bootstrap.inc is a dependency of ExtensionDiscovery, and many tests make stub definitions of functions declared in bootstrap.inc, so there will be errors. Also there are failures related to the issue linked above.

The large one changes many of these tests and their code in order to make some of them pass. This is a WIP. It touches a lot of code, so it might not be RC-able, but it should be. It includes the changes in #2605654: Modify Drupal\Core\Extension\ExtensionDiscovery to allow for scanning multiple file systems, enabling vfsStream testing patch #2, so a re-roll might be necessary at some point.

In my opinion this issue is a bug report, because we had false passes on a number of tests before making this change in dependencies. The best example of this is UpdateRegistryTest which uses vfsStream to mock a whole Drupal filesystem. If you run the test in isolation, ExtensionDiscovery only runs once, which hides its static problems.

The last submitted patch, 8: 2301873_big_8.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 8: 2301873_poc_8.patch, failed testing.

Version: 8.0.x-dev » 8.1.x-dev

Drupal 8.0.6 was released on April 6 and is the final bugfix release for the Drupal 8.0.x series. Drupal 8.0.x will not receive any further development aside from security fixes. Drupal 8.1.0-rc1 is now available and sites should prepare to update to 8.1.0.

Bug reports should be targeted against the 8.1.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.2.x-dev branch. For more information see the Drupal 8 minor version schedule and the Allowed changes during the Drupal 8 release cycle.

Mile23’s picture

Status: Needs work » Closed (won't fix)
Issue tags: -rc eligible

After #2499239: Use test suite classes to discover different test types under phpunit, allow contrib harmony with run-tests I'm calling this CWF, since the new behavior for the phpunit tool is to use TestDiscovery::scanDirectory() to find tests per testsuite. (This issue was originally about using TestDiscovery in bootstrap.php.)

bootstrap.php still uses its own functions to discover extensions, which is fine because we want to be able to test ExtensionDiscovery in isolation.

As always: Re-open if you disagree.