Major only as it makes performance improvements in the test base more difficult.

Problem/Motivation

#2747075: [meta] Improve WebTestCase / BrowserTestBase performance by 50% would like to change WebTestBase to allow caching per installation and installed modules and custom.

That can potentially speed up local development a lot.

A soft blocker for that is that all changes need to be done twice.

One part that makes BrowserTestBase / WebTestBase difficult to maintain is that many functions are identical in both classes, but play only an utility function.


Another part is that the installDrupal() function contains all the little sub-functions inline that the original function called as several helper functions.

BrowserTestBase is - after working a little with it - harder to read in that respect and we generally prefer many little helper functions doing one thing properly each.
(It is not immediately obvious, but after working with the code flow of WebTestBase for a while, the similarity can be seen.)

Untangle that back to the original helper functions and move it to the trait, ensure to not break BC of BrowserTestBase by resolving conflicts.

Proposed resolution

- Move identical functions to a trait in the core/tests space that are shared by both classes.
- Untangle installDrupal() of BrowserTestBase again to go back to the old structure of setUp() in WebTestBase.php, which called lots of helper functions.
- Move all those helper functions to the trait as well.

Remaining tasks

- Do it

Comments

Fabianx created an issue. See original summary.

fabianx’s picture

Title: Move similar methods in BrowserTestBase / WebTestBase to a trait » Move similar methods in BrowserTestBase / WebTestBase to a trait; untangle doInstall()
fabianx’s picture

Title: Move similar methods in BrowserTestBase / WebTestBase to a trait; untangle doInstall() » Move similar methods in BrowserTestBase / WebTestBase to a trait; untangle installDrupal()
Issue summary: View changes

List of methods that should be the same (from visual memory):

- prepareDatabasePrefix
- changeDatabasePrefix (90% identical)
- prepareSettings
- writeSettings
- rebuildContainer
- prepareRequestForGenerator
- resetAll
- refreshVariables
- setContainerParameter

AND:

installDrupal() replacing / hardcoding:

- initUserSession();
- doInstall
- initSettings
- initKernel
- initConfig
- installModulesFromClassProperty

- rebuildAll (to be deprecated in #2795789: Do not rebuild the container so often in BTB, so don't bother with the part calling resetAll())

TestBase.php - not that interested, just here for completeness

- prepareEnvironment (70% similat in TestBase.php)
- getConfigSchemaExclusions

larowlan’s picture

Assigned: Unassigned » larowlan
larowlan’s picture

Assigned: larowlan » Unassigned
Status: Active » Needs review
StatusFileSize
new68.58 KB

let's see what blows up with this first attempt

Status: Needs review » Needs work

The last submitted patch, 5: 2796105-wtb-btb-traits.1.patch, failed testing.

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new399 bytes
new550 bytes

whoops - got the inheritance slightly wrong

larowlan’s picture

StatusFileSize
new68.41 KB

gah, muppet

The last submitted patch, 7: 2796105-wtb-btb-traits.2.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 8: 2796105-wtb-btb-traits.2.patch, failed testing.

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new774 bytes
new68.51 KB

still changing the inheritance

Status: Needs review » Needs work

The last submitted patch, 11: 2796105-wtb-btb-traits.3.patch, failed testing.

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new854 bytes
new68.61 KB

passRaw pass_raw mismatch

dawehner’s picture

Here is a conceptual question. If you look into TestSetupTrait and BrowserTestBase you see BTB overriding prepareDatabasePrefix.
This feels weird, because simpletest is the one that does actually more. Maybe we should move the override to WTB?

  1. +++ b/core/tests/Drupal/Tests/BrowserTestBase.php
    @@ -362,7 +273,7 @@ protected function initMink() {
        *
    -   * @return Behat\Mink\Driver\DriverInterface
    +   * @return \Behat\Mink\Driver\DriverInterface
        *   Instance of default Mink driver.
        *
    

    Nitpick: out of scope change :P

  2. +++ b/core/tests/Drupal/Tests/BrowserTestBase.php
    @@ -977,161 +888,14 @@ protected function getOptions($select, Element $container = NULL) {
    +    $this->initUserSession();
    +    $this->prepareSettings();
    +    $this->doInstall();
    +    $this->initSettings();
    +    $container = $this->initKernel(\Drupal::request());
    +    $this->initConfig($container);
    +    $this->installModulesFromClassProperty($container);
    +    $this->rebuildAll();
       }
    

    This is really nice code, IMHO

fabianx’s picture

This is really great work! Thanks so much for this cleanup!

I agree the code of installDrupal() is really nice to read now!

larowlan’s picture

Assigned: Unassigned » larowlan

addressing feedback

larowlan’s picture

Assigned: larowlan » Unassigned
StatusFileSize
new4.71 KB
new71.58 KB

killing time √

fabianx’s picture

Status: Needs review » Reviewed & tested by the community

RTBC - Looks great to me!

dawehner’s picture

Super nice work! This trait could be of course improved, but that would be out of the scope of this issue.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 17: 2796105-wtb-btb-traits.17.patch, failed testing.

fabianx’s picture

Issue tags: +Needs reroll

Needs a reroll

yogeshmpawar’s picture

Status: Needs work » Needs review
StatusFileSize
new71.93 KB

I have rerolled the patch for 8.3.x branch.

fabianx’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC, thank you #22!

naveenvalecha’s picture

Issue tags: -Needs reroll

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 22: wtb-btb-traits-2796105-22.patch, failed testing.

fabianx’s picture

Issue tags: +Needs reroll

This needs a reroll, but this might be a little more complicated.

yogeshmpawar’s picture

Assigned: Unassigned » yogeshmpawar
yogeshmpawar’s picture

Assigned: yogeshmpawar » Unassigned
Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new71.91 KB

@Fabianx - I have rerolled the patch to work with 8.3.x version.
please review

Status: Needs review » Needs work

The last submitted patch, 28: wtb-btb-traits-2796105-28.patch, failed testing.

dawehner’s picture

Status: Needs work » Needs review
StatusFileSize
new72.35 KB

Just a reroll as part of the research of moving UpdatePathTestBase

Status: Needs review » Needs work

The last submitted patch, 30: 2796105-30.patch, failed testing.

fabianx’s picture

Assigned: Unassigned » larowlan

Assigning back to larowlan in the hopes he can fix the test failures.

sam152’s picture

Assigned: larowlan » Unassigned
StatusFileSize
new72.42 KB
new928 bytes

Fix attached.

Edit: not actually sure why this works. I guess $this->$key = $value in UserSession::__construct isn't enough?

sam152’s picture

Status: Needs work » Needs review
sam152’s picture

StatusFileSize
new866 bytes
new72.4 KB

Ah, figured it out. So, passRaw is required by btb and pass_raw is required by wtb. This is also referenced in UserCreationTrait:

    // Add the raw password so that we can log in as this user.
    $account->pass_raw = $edit['pass'];
    // Support BrowserTestBase as well.
    $account->passRaw = $account->pass_raw;
dawehner’s picture

oh right, we've been there already biting us. Its good to have that so we have a better BC layer.

Thank you @Sam152 for the reroll!

fabianx’s picture

Status: Needs review » Reviewed & tested by the community

Thanks, I think we are back to RTBC.

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 35: 2796105-35.patch, failed testing.

fabianx’s picture

Issue tags: +Needs reroll

This needs a reroll

anish.a’s picture

Status: Needs work » Needs review
Issue tags: -Needs reroll
StatusFileSize
new72.41 KB

Rerolled

fabianx’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 40: 2796105-40.patch, failed testing.

anish.a’s picture

Status: Needs work » Reviewed & tested by the community

I assume it was a random failure. Back to RTBC.

fabianx’s picture

Issue tags: +Avoid commit conflicts

Adding tag.

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
  1. It's nice to see this code being shared between Simpletest and BrowserTestBase - certainly will make maintaining both through the D8 lifecycle simpler :)
  2. +++ b/core/lib/Drupal/Core/Test/TestSetupTrait.php
    @@ -0,0 +1,196 @@
    +  protected function prepareDatabasePrefix() {
    ...
    +  protected function changeDatabasePrefix() {
    
    +++ b/core/modules/simpletest/src/TestBase.php
    @@ -1125,36 +1023,6 @@ private function prepareDatabasePrefix() {
    -  private function changeDatabasePrefix() {
    
    +++ b/core/tests/Drupal/Tests/BrowserTestBase.php
    @@ -1241,65 +1005,6 @@ protected function installParameters() {
    -  private function prepareDatabasePrefix() {
    ...
    -  private function changeDatabasePrefix() {
    

    Change of scope - is that really right? Can a trait add a private method - I think it can. I'm not sure though.

  3. +++ b/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php
    @@ -0,0 +1,447 @@
    +trait FunctionalTestSetupTrait {
    ...
    +    $this->container = $this->kernel->rebuildContainer();
    
    +++ b/core/lib/Drupal/Core/Test/TestSetupTrait.php
    @@ -0,0 +1,196 @@
    +  /**
    +   * The dependency injection container used in the test.
    +   *
    +   * @var \Symfony\Component\DependencyInjection\ContainerInterface
    +   */
    +  protected $container;
    

    I think FunctionalTestSetupTrait should use TestSetupTrait so things like container are declared and I think you'd always want TestSetupTrait if you're using FunctionalTestSetupTrait.

  4. +++ b/core/lib/Drupal/Core/Test/TestSetupTrait.php
    @@ -0,0 +1,196 @@
    +  protected $kernel;
    +  /**
    

    Missing new line.

fabianx’s picture

#45: Thanks so much for the review:

I confirmed that traits can use private functions:

https://3v4l.org/m3NC9

Thanks!

larowlan’s picture

Status: Needs work » Needs review
StatusFileSize
new72.43 KB

first a reroll

larowlan’s picture

StatusFileSize
new1.18 KB
new72.43 KB
new53.93 KB

1) agree
2) done
3) if I do that, I get Drupal\simpletest\TestBase and Drupal\Core\Test\FunctionalTestSetupTrait define the same property ($configSchemaCheckerExclusions) in the composition of Drupal\simpletest\WebTestBase. However, the definition differs and is considered incompatible. i.e. TestBase in simpletest already includes the TestSetupTrait. So, in summary WebTestBase gets TestSetupTrait via inheriting it from TestBase. BrowserTestBase gets it from using both TestSetupTrait and FunctionalTestSetupTrait. Unfortunately, we're stuck with the deprecated KernelTestBase until 9.x, so until then, we can't get rid of TestBase and make TestSetupTrait used by FunctionalTestSetupTrait.
4) done

larowlan’s picture

paraphrasing #48.3

test test test blah test blah blah test test test blah i heard you like test with your test blah blah test test

fabianx’s picture

Status: Needs review » Reviewed & tested by the community

Back to RTBC, it would be great to get this in to unblock other work.

dawehner’s picture

Component: base system » phpunit
Issue tags: +PHPUnit

This certainly belongs into the phpunit initiative

larowlan’s picture

Thanks @dawehner

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
Issue tags: -Avoid commit conflicts
  1. Sorry for taking so long to re-review it
  2. Removing the avoid commit conflicts tag - not sure really what the tag means and its purpose here
  3. +++ b/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php
    @@ -0,0 +1,448 @@
    +    // @see TestBase::prepareEnvironment()
    ...
    +   * @see TestBase::prepareEnvironment()
    +   * @see TestBase::restoreEnvironment()
    ...
    +    // TestBase::restoreEnvironment() will delete the entire site directory.
    
    +++ b/core/lib/Drupal/Core/Test/TestSetupTrait.php
    @@ -0,0 +1,198 @@
    +use Drupal\simpletest\TestBase;
    ...
    +   * This is set in TestBase::prepareEnvironment().
    ...
    +   * This is set in TestBase::prepareEnvironment().
    ...
    +   * This is set in TestBase::prepareEnvironment().
    ...
    +   * @see TestBase::prepareEnvironment()
    

    Unused apart from in docs. And these docs need improving since they all point to TestBase but they need to point to both Drupal\simpletest\TestBase and \Drupal\Tests\BrowserTestBase

  4. +++ b/core/lib/Drupal/Core/Test/FunctionalTestSetupTrait.php
    @@ -0,0 +1,448 @@
    +  /**
    +   * Resets all data structures after having enabled new modules.
    +   *
    +   * This method is called by \Drupal\simpletest\WebTestBase::setUp() after
    +   * enabling the requested modules. It must be called again when additional
    +   * modules are enabled later.
    +   */
    +  protected function resetAll() {
    

    So is this method only used by WebTestBase? I think the main use is \Drupal\Core\Test\FunctionalTestSetupTrait::rebuildAll() which is called by both WebTestBase::setUp() and Drupal\Tests\BrowserTestBase::installDrupal()

  5. FILE: ...s/devdisk/dev/drupal/core/modules/simpletest/src/WebTestBase.php
    ----------------------------------------------------------------------
    FOUND 0 ERRORS AND 10 WARNINGS AFFECTING 10 LINES
    ----------------------------------------------------------------------
      6 | WARNING | [x] Unused use statement
     11 | WARNING | [x] Unused use statement
     12 | WARNING | [x] Unused use statement
     15 | WARNING | [x] Unused use statement
     19 | WARNING | [x] Unused use statement
     21 | WARNING | [x] Unused use statement
     24 | WARNING | [x] Unused use statement
     25 | WARNING | [x] Unused use statement
     32 | WARNING | [x] Unused use statement
     34 | WARNING | [x] Unused use statement
    ----------------------------------------------------------------------
    PHPCBF CAN FIX THE 10 MARKED SNIFF VIOLATIONS AUTOMATICALLY
    ----------------------------------------------------------------------
    
    Time: 186ms; Memory: 18Mb
    
    
    FILE: ...s/devdisk/dev/drupal/core/tests/Drupal/Tests/BrowserTestBase.php
    ----------------------------------------------------------------------
    FOUND 0 ERRORS AND 7 WARNINGS AFFECTING 7 LINES
    ----------------------------------------------------------------------
     10 | WARNING | [x] Unused use statement
     15 | WARNING | [x] Unused use statement
     16 | WARNING | [x] Unused use statement
     18 | WARNING | [x] Unused use statement
     19 | WARNING | [x] Unused use statement
     22 | WARNING | [x] Unused use statement
     30 | WARNING | [x] Unused use statement
    ----------------------------------------------------------------------
    PHPCBF CAN FIX THE 7 MARKED SNIFF VIOLATIONS AUTOMATICALLY
    ----------------------------------------------------------------------
    

    Lovely let's get rid of all these uses then!

alexpott’s picture

Status: Needs work » Needs review
StatusFileSize
new6.66 KB
new74.58 KB

Status: Needs review » Needs work

The last submitted patch, 54: 2796105-54.patch, failed testing.

alexpott’s picture

Status: Needs work » Needs review

Never seen that fail in Drupal\filter\Tests\FilterFormatAccessTest before - retesting.

fabianx’s picture

Status: Needs review » Reviewed & tested by the community

Nice changes! Thanks for the review and great work finding those.

Back to RTBC!

alexpott’s picture

Status: Reviewed & tested by the community » Fixed

Committed d2b4642 and pushed to 8.3.x. Thanks!

  • alexpott committed d2b4642 on 8.3.x
    Issue #2796105 by larowlan, Sam152, Yogesh Pawar, alexpott, dawehner,...
fabianx’s picture

Time to celebrate! Thanks, Alex!

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

frankcarey’s picture

Great work, Contrats!

tstoeckler’s picture

Title: Move similar methods in BrowserTestBase / WebTestBase to a trait; untangle installDrupal() » [followup/regression] Move similar methods in BrowserTestBase / WebTestBase to a trait; untangle installDrupal()
Status: Closed (fixed) » Needs review
StatusFileSize
new906 bytes

Unfortunately this caused a regression:

WebTestBase used to use $this->originalSite for the original site path while BrowserTestBase used $this->originalSiteDirectory. This is used to determine the path for the settings.testing.php and testing.services.yml files which can be used to influence the child site of the test.

While the reading of this value was consolidated in this issue to always read from $this->originalSite the setting of $this->originalSiteDirectory in BrowserTestBase was not updated accordingly.

Even though this is a regression between 8.2 and 8.3 I would personally propose not rolling this back for the reasons below, but posting the fix here instead of a new issue in case maintainers do think reverting is the best way to go:

  • 8.3 does not have a release (although I guess that can change any minute with the nearing alpha, but at least no stable release is near)
  • This was a pretty massive undertaking, would be unfortunate to have to re-do work on this
  • Not sure if rolling this back would impede/affect #2770921: Feb 21st: Convert chunk of WTB to BTB by just moving classes, changing use statements adding traits in any way
  • We cannot add any test coverage for this anyway as this is one of the few places which explicitly interacts with the host system
  • The followup is pretty trivial
  • The fallout is pretty minor because not many people know about settings.testing.php and testing.services.yml
cspitzlay’s picture

I can confirm that the patch from #63 solves the test failure we had on our CI system that was due to our settings.testing.php not being found.

Status: Needs review » Needs work

The last submitted patch, 63: 2796105-followup.patch, failed testing.

tstoeckler’s picture

Status: Needs work » Needs review

Testbot says:
18:25:12 Cannot connect to the Docker daemon. Is the docker daemon running on this host?

Next try.

cspitzlay’s picture

Status: Needs review » Reviewed & tested by the community

The patch fixes the regression and the test is green -> RTBC.

tstoeckler’s picture

Title: [followup/regression] Move similar methods in BrowserTestBase / WebTestBase to a trait; untangle installDrupal() » Move similar methods in BrowserTestBase / WebTestBase to a trait; untangle installDrupal()
Status: Reviewed & tested by the community » Fixed

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.