Problem/Motivation

The \Drupal\Core\Extension\ExtensionDiscovery class documentation says that you can call ::scan($type, FALSE) to exclude test extensions explicitly.

This appears to work for modules and themes. But if you call ::scan('profile', FALSE) you end up with (this is output where I also collected the paths of each extension):

    [demo_umami] => core/profiles/demo_umami
    [minimal] => core/profiles/minimal
    [standard] => core/profiles/standard
    [testing] => core/profiles/testing
    [testing_config_import] => core/profiles/testing_config_import
    [testing_config_overrides] => core/profiles/testing_config_overrides
    [testing_install_profile_all_dependencies] => core/profiles/testing_install_profile_all_dependencies
    [testing_install_profile_dependencies] => core/profiles/testing_install_profile_dependencies
    [testing_install_profile_dependencies_bc] => core/profiles/testing_install_profile_dependencies_bc
    [testing_missing_dependencies] => core/profiles/testing_missing_dependencies
    [testing_multilingual] => core/profiles/testing_multilingual
    [testing_multilingual_with_english] => core/profiles/testing_multilingual_with_english
    [testing_requirements] => core/profiles/testing_requirements
    [testing_site_config] => core/profiles/testing_site_config

The reason is that when you set $include_tests explicitly to FALSE, it excludes any extensions that are under directories named "tests". But the testing profiles are not under such directories, so they are still returned.

Proposed resolution

One of the following:
a) Modify the scanning excludes somehow so that these profiles are detected.
b) Move the testing profiles under directories called "tests".
c) Modify the documentation so it says $include_tests only works for modules and themes, and you'll have to filter profiles yourself if you want to exclude test profiles.

We decided on (b).

Remaining tasks

Decide. Patch. Test.

User interface changes

None.

API changes

Not really, but some profiles have moved to new locations underneath "tests" directories, so they will now not be discovered during scanning for profiles, by default. This makes scanning for test profiles consistent with scanning for test modules and themes.

Data model changes

None.

Release notes snippet

Profiles that are meant for use in automated testing have been moved from being directly in core/profiles to either being under the core/profiles/tests or core/modules/config/tests/profiles directory. This means that they will not be detected by default when scanning for extensions, except when running in a test environment, which is consistent with how scanning for modules and themes works.

To force detecting test profiles, call

\Drupal\Core\Extension\ExtensionDiscovery::scan('profile', TRUE)

Comments

jhodgdon created an issue. See original summary.

jhodgdon’s picture

Issue summary: View changes

The problem appears to be that the decision about whether something is a "test" extension depends on it being under a directory called "tests". But these aren't. They're just marked "hidden" in their info files. This filtering is done in
https://api.drupal.org/api/drupal/core%21lib%21Drupal%21Core%21Extension...

I actually also ran into problems scanning for modules and themes, in that modules/themes underneath these testing profiles were returned, although they are definitely test modules/themes and some of them cannot even be installed. I got around this in the test I was writing by trying to say I didn't want any modules/themes underneath profiles at all, and I ran into #3076098: ExtensionDiscovery documentation is wrong about scanning profile directories, which I was able to work around by telling ExtensionDiscovery that I only wanted modules/themes under the nonexistent 'foo' profile.

But then I ran into this issue, so I went back to my original scheme for making a list of "relevant" modules/themes/profiles on #3066512: Add checks for syntax and display of help topic Twig template files and just used strpos like this, after getting the extension's path:

      if ((strpos($path, '/tests') === FALSE) &&
        (strpos($path, '/testing') === FALSE)) {

Anyway. It seems like excluding profiles as being "testing" based on them being underneath a "tests" directory is not very useful.

larowlan’s picture

I would think putting them in a tests subfolder would be consistent with modules

jhodgdon’s picture

Status: Active » Needs review
StatusFileSize
new11.98 KB

OK.

So... I guess the question is where to put the tests subfolder. Options I can think of:

a) core/profiles/tests -- people could find them easily if they knew where they were previously. But it's not all that consistent with where we put test modules/themes.

b) core/tests/profiles -- that would be a central location. However, there is no core/tests/modules or core/tests/themes directory.

c) core/[something]/tests/profiles -- might make sense for profiles that are only used by tests in a core/[something]/tests directory, like we do for test modules and themes.

So... Here is patch that is a combination of (a) and (c). Profiles that are for particular modules' tests I put into core/thatmodule/tests/profiles [that only applied to two that were for core/modules/config], and the others I moved into core/profiles/tests so they would still be easy to find.

Assuming the tests still pass (let's see what the bot says), let the bikeshedding begin!

Status: Needs review » Needs work

The last submitted patch, 4: 3076329-move-profiles-4.patch, failed testing. View results

baysaa’s picture

Great write up. However I don't think moving installation profiles elsewhere will work without extra changes. As the first error in the above tests shows, if the profile is being used, we can't move it elsewhere because the system can't find it when trying to install from that profile during the test,if we place it inside modules, or a core/profiles/tests/ subdir.

I haven't dug too deeply into directory discovery inside drupal, but I assume we can only use profiles/ and core/profiles/ dirs for placing installation profiles, and that also excludes subdirs like profiles/tests/profile_name I believe as I've just tried to move profiles into a tests subdir without success, tests fail with same error. So we either need to change the profile directory discoveries so it's consistent with modules (expects there to be a `tests` subdir), or change how $include_tests is used for profiles, but for now we should update the documentation (option C) :)

jhodgdon’s picture

Status: Needs work » Needs review

Well, I think that the first fail actually only indicates that we need to make a small change in a test that had the path to the profile hard-wired in it. I'll see if I can get the rest of the tests to pass. I think it may be possible. Those directories are definitely being scanned for profiles...

baysaa’s picture

Yep they're hardcoded, my bad should've looked closer.

jhodgdon’s picture

StatusFileSize
new10.41 KB
new22.39 KB

I managed to get all of the tests that failed to pass again. Most of them were failing due to hard-coded directories, which changed because the patch moved those profiles.

The last one was a bit different: Drupal\Tests\Core\Command\QuickStartTest

The reason that one was failing was that in both includes/install.core.inc and core/lib/Drupal/Core/Command/InstallCommand.php, there was an implicit assumption that ExtensionDiscovery::scan() would locate test install profiles (which it was doing, subject of this issue report). But now because those are under "tests" directories, that method doesn't find them unless you ask it to include tests (that's the whole point of this issue).

So I changed a few lines in those files to tell it to scan including test profiles. I'm assuming that we want the QuickStart and anything else that relies on includes/install.core.inc to work if someone actually wants to install with the "testing" profile.

Anyway... let's see what happens this time...

jhodgdon’s picture

So, this will change the behavior of ExtensionDiscovery::scan('profile') if you don't pass in a 2nd argument.

Previously, it would always find test install profiles (the subject of this bug). But now, if you don't pass in a 2nd argument, it will try to detect whether you wanted tests or not, and respect that choice. So when running within a test, it will find test profiles, but when running outside a test, unless you have that setting in your settings.php file, it won't. (Just like scanning for modules has always worked.)

So... just to make sure we aren't artificially missing a problem while running tests... I grepped the codebase to find out who might be calling scan('profile').

I found:
a) Several tests calling it, to figure out what profile you wanted to install with or things like that. That should be OK if they leave out the 2nd argument, because their behavior wouldn't change during testing.

b) The lines I already updated in this patch.

c) Other stuff:

./lib/Drupal/Core/Update/UpdateRegistry.php:    $profile_extensions = $extension_discovery->scan('profile');
./lib/Drupal/Core/Config/ExtensionInstallStorage.php:        $profile_list = $listing->scan('profile');
./lib/Drupal/Core/Config/ExtensionInstallStorage.php:            $profile_list = $listing->scan('profile');
./lib/Drupal/Core/Config/InstallStorage.php:        $profile_list = $listing->scan('profile');
./lib/Drupal/Core/Extension/ModuleExtensionList.php:    $all_profiles = $discovery->scan('profile');
./lib/Drupal/Core/DrupalKernel.php:      $all_profiles = $listing->scan('profile');

These probably need to be looked at. The behavior while running inside tests hasn't changed from before, but behavior when running outside of a test environment of these functions will change. I'll take a look tomorrow...

jhodgdon’s picture

I took a look at the other existing calls to ExtensionDiscovery::scan('profile') in Core (see comment #10, list in (c)).

UpdateRegistry:

    // Scan the module list.
    $extension_discovery = new ExtensionDiscovery($this->root, FALSE, [], $this->sitePath);
    $module_extensions = $extension_discovery->scan('module');

    $profile_extensions = $extension_discovery->scan('profile');

Since this code is also scanning modules using the default argument (ignore testing modules, unless the thing in settings.php is set or you're running a test), I think it's OK if it also ignores testing profiles for real.

ExtensionInstallStorage, InstallStorage:
What's going on there is similar. It's scanning modules, themes, and profiles in the same way, with the default argument.

ModuleExtensionList:
This should be fine too, I think... It's in ::getProfileDirectories(), which in turn is used to set the profile directory that can be scanned for modules. This class is used to make lists of modules, so it makes sense that if you want testing modules, you also want testing profiles, and if you don't, you don't. (Again, being consistent between the scan behavior of modules and profiles makes sense.)

DrupalKernel:
This is a copy/paste of the code in ModuleExtensionList, essentially. So again, being consistent between modules and profiles makes sense.

So. I think we're OK to go ahead and move the test profiles to "tests" directory, and have them only returned from ExtensionDiscovery under the same circumstances as we would return test modules and themes.

Anyone want to give this patch a review?

jhodgdon’s picture

I didn't mean for this to be a child issue.

jhodgdon’s picture

Issue summary: View changes

Updating issue summary. Also made a draft change notice
https://www.drupal.org/node/3076852

jhodgdon’s picture

I think this is going to need to be reviewed by the Framework managers, even though the patch is @larowlan's suggestion...

jhodgdon’s picture

Issue summary: View changes

fix typo in issue summary

Version: 8.8.x-dev » 8.9.x-dev

Drupal 8.8.0-alpha1 will be released the week of October 14th, 2019, which means new developments and disruptive changes should now be targeted against the 8.9.x-dev branch. (Any changes to 8.9.x will also be committed to 9.0.x in preparation for Drupal 9’s release, but some changes like significant feature additions will be deferred to 9.1.x.). For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

daffie’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll

The patch needs a reroll.

All code changes look good to me.

+++ b/core/includes/install.core.inc
@@ -449,10 +449,10 @@ function install_begin_request($class_loader, &$install_state) {
-  $listing->setProfileDirectories([]);

+++ b/core/lib/Drupal/Core/Command/InstallCommand.php
@@ -310,12 +310,11 @@ protected function validateProfile($install_profile, SymfonyStyle $io) {
-    $listing->setProfileDirectories([]);

Just one nitpick question: Why do you remove the these lines.

daffie’s picture

Found out in #3076098: ExtensionDiscovery documentation is wrong about scanning profile directories that $listing->setProfileDirectories([]); can be removed because it does not do anything.

kostyashupenko’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new22.08 KB
new1.7 KB

Status: Needs review » Needs work

The last submitted patch, 19: 3076329-move-profiles-fix-tests-19.patch, failed testing. View results

swatichouhan012’s picture

Status: Needs work » Needs review
StatusFileSize
new23.06 KB
new740 bytes

Removed deleted file from test file and updated patch #19, Kindly review

Status: Needs review » Needs work

The last submitted patch, 21: 3076329-21.patch, failed testing. View results

swatichouhan012’s picture

Status: Needs work » Needs review
StatusFileSize
new24 KB
new783 bytes

Correct weight_select_max number in tests.

Status: Needs review » Needs work

The last submitted patch, 23: 3076329-23.patch, failed testing. View results

Version: 8.9.x-dev » 9.1.x-dev

Drupal 8.9.0-beta1 was released on March 20, 2020. 8.9.x is the final, long-term support (LTS) minor release of Drupal 8, which means new developments and disruptive changes should now be targeted against the 9.1.x-dev branch. For more information see the Drupal 8 and 9 minor version schedule and the Allowed changes during the Drupal 8 and 9 release cycles.

Version: 9.1.x-dev » 9.2.x-dev

Drupal 9.1.0-alpha1 will be released the week of October 19, 2020, which means new developments and disruptive changes should now be targeted for the 9.2.x-dev branch. For more information see the Drupal 9 minor version schedule and the Allowed changes during the Drupal 9 release cycle.

Version: 9.2.x-dev » 9.3.x-dev

Drupal 9.2.0-alpha1 will be released the week of May 3, 2021, which means new developments and disruptive changes should now be targeted for the 9.3.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.3.x-dev » 9.4.x-dev

Drupal 9.3.0-rc1 was released on November 26, 2021, which means new developments and disruptive changes should now be targeted for the 9.4.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 9.4.x-dev » 9.5.x-dev

Drupal 9.4.0-alpha1 was released on May 6, 2022, which means new developments and disruptive changes should now be targeted for the 9.5.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

quietone’s picture

Component: base system » extension system

Just updating component.

Version: 9.5.x-dev » 10.1.x-dev

Drupal 9.5.0-beta2 and Drupal 10.0.0-beta2 were released on September 29, 2022, which means new developments and disruptive changes should now be targeted for the 10.1.x-dev branch. For more information see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

Version: 10.1.x-dev » 11.x-dev

Drupal core is moving towards using a “main” branch. As an interim step, a new 11.x branch has been opened, as Drupal.org infrastructure cannot currently fully support a branch named main. New developments and disruptive changes should now be targeted for the 11.x branch, which currently accepts only minor-version allowed changes. For more information, see the Drupal core minor version schedule and the Allowed changes during the Drupal core release cycle.

catch’s picture

Status: Needs work » Closed (duplicate)
Issue tags: -Needs framework manager review
Related issues: +#3490493: Test profiles should be in a tests directory

Ended up opening a duplicate of this without realising this issue was open. Since that issue is RTBC with an MR and the patch here is stale, closing this as duplicate but moving credit over #3490493: Test profiles should be in a tests directory.