In #1821420: Convert mail variables to cmi the following change was made to simpletest.module:

     // Use the test mail class instead of the default mail handler class.
-    variable_set('mail_system', array('default-system' => 'Drupal\Core\Mail\VariableLog'));
+    config('system.mail')->set('interface.default', 'Drupal\Core\Mail\VariableLog')->save();

A subtle difference was introduced here when a custom module provides a different mail system implementation. Previously, the variable_set() would overwrite all mail system settings, so all test mails would be sent to VariableLog. Now, only the default implementation is changed, so any custom mail system implementations that might be set in e.g. hook_install() are left intact.

It is possible to work around this in tests by explicitly changing custom mail system settings in setUp(), as per http://drupalcode.org/project/ubercart.git/commitdiff/2139e13, but this should not be required.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

longwave’s picture

Status: Active » Needs review
FileSize
866 bytes

The attached patch restores the previous behaviour by overwriting all mail interfaces with the default.

TR’s picture

Status: Needs review » Reviewed & tested by the community

Yes, I think this is a very good idea.

The mail.system variable was dysfunctional in D7 - read my explanation at https://drupal.org/comment/4160574#comment-4160574. So one could argue that the D7 behavior was a bug and that D8 uses the improved config system to correct that. Which is true, but only for live sites. SimpleTest is another matter entirely.

The whole point of resetting this variable in SimpleTest is so that SimpleTest can capture any outgoing mail in order to test the mail functionality. Withoug this change, we cannot ever test a module that implements its own mail system.

So a big +1 for this change - it doesn't impact any tests unless you have your own mail system defined, and if you do it allows you to test your module, which is currently impossible without workarounds.

webchick’s picture

Nice catch. This looks like a typo; the system.mail.yml file defines this as:

interface:
 default: 'Drupal\Core\Mail\PhpMail'

... so I don't really see how the old code would've ever worked.

My only question is whether it's possible to add a test for this?

longwave’s picture

Status: Reviewed & tested by the community » Needs review
FileSize
2.03 KB
2.88 KB

The old code worked fine except when alternative mail system implementations were involved, and core does not use these.

The attached patches subvert the existing SimpleTest e-mail capture test to use an alternative implementation and demonstrate the bug, without needing any additional assertions.

The last submitted patch, 4: 2146971-simpletest-mail-handler-4-FAIL.patch, failed testing.

longwave’s picture

Status: Needs review » Needs work

The last submitted patch, 4: 2146971-simpletest-mail-handler-4-PASS.patch, failed testing.

longwave’s picture

Status: Needs work » Needs review
FileSize
2.89 KB

Rerolled.

longwave’s picture

Title: SimpleTest does not use VariableLog mail system for non-default implementations » SimpleTest does not use TestMailCollector for non-default mail system implementations
longwave’s picture

Title: SimpleTest does not use TestMailCollector for non-default mail system implementations » SimpleTest should override all mail system implementations with TestMailCollector

Less confusing title

Berdir’s picture

Following, let's do this after #2187495: Use plugin system for MailInterface classes. There is a test module but I can't see a test that would verify it? Also, the comment in the test module still references the old class name, but all of that should switch to plugins anyway after the pluginification.

longwave’s picture

@Berdir the test works as follows: MailCaptureTest installs mailsystem_test module, which sets the simpletest mail handler to PhpMail. With the existing bug, this causes MailCaptureTest to fail as the mails are not actually captured, instead PhpMail sends them as normal. After the bug is patched, mailsystem_test's setting is overridden inside the test environment so the mails are correctly captured. See the FAIL patch and results in #4 for full details.

Les Lim’s picture

This will also need a reroll because of #2171683: Remove all Simpletest overrides and rely on native multi-site functionality instead, which substantially rewrote WebTestBase.

There are tests that manipulate system.mail settings beyond what WebTestBase does; it would probably be a good idea to change those, as well. Here's what I found on a grep:

\Drupal\user\Tests\UserCreateFailMailTest:

    \Drupal::config('system.mail')->set('interface.default', 'Drupal\system_mail_failure_test\TestPhpMailFailure')->save();

\Drupal\system\Tests\InstallerTest:

    \Drupal::config('system.mail')
      ->set('interface.default', 'Drupal\Core\Mail\TestMailCollector')
      ->save();

\Drupal\system_mail_failure_test\TestPhpMailFailure:

/**
 * @code
 *   \Drupal::config('system.mail')->set('interface.default', 'Drupal\system_mail_failure_test\TestPhpMailFailure')->save();
 * @endcode
 */

\Drupal\system\Tests\Mail\MailTest does this as well, but the body of that test will change a lot if #2187495: Use plugin system for MailInterface classes lands.

longwave’s picture

WebTestBase and InstallerTestBase are expected to be extended by contrib which might provide alternative mail handlers, so this patch enforces the use of test_mail_collector for all mail handlers during testing. Other tests that previously changed the default mail handler only used the default mail handler anyway, so I don't think they need to be changed here.

I had to rearrange some code in WebTestBase so the mail handler is enforced after modules are installed; this means that modules that set up mail handlers in their hook_install are overridden during testing.

Status: Needs review » Needs work

The last submitted patch, 14: 2146971-simpletest-mail-handler-14-FAIL.patch, failed testing.

The last submitted patch, 14: 2146971-simpletest-mail-handler-14-FAIL.patch, failed testing.

longwave’s picture

Status: Needs work » Needs review
jhedstrom’s picture

Status: Needs review » Needs work
Issue tags: +Needs reroll
rpayanm’s picture

Status: Needs work » Needs review
FileSize
4.34 KB

Status: Needs review » Needs work

The last submitted patch, 19: 2146971-19.patch, failed testing.

ankitgarg’s picture

Status: Needs work » Needs review
FileSize
1.21 KB

rerolled

ankitgarg’s picture

rerolled

ankitgarg’s picture

rerolled

ankitgarg’s picture

rerolled

Status: Needs review » Needs work

The last submitted patch, 21: 2146971-simpletest-mail-handler-21.patch, failed testing.

ankitgarg’s picture

Status: Needs work » Needs review
FileSize
1.53 KB

Updated Rerole.

Status: Needs review » Needs work

The last submitted patch, 26: 2146971-simpletest-mail-handler-26.patch, failed testing.

ankitgarg’s picture

Status: Needs work » Needs review
FileSize
675 bytes
ravi.khetri’s picture

FileSize
2.88 KB

ReRolled.

Status: Needs review » Needs work

The last submitted patch, 29: 2146971_29.patch, failed testing.

jhedstrom’s picture

It looks like something has been lost in the last 2 rerolls compared to the patches in #14 and #19.

piyuesh23’s picture

Issue tags: +#DCM2015
piyuesh23’s picture

Status: Needs work » Needs review
FileSize
7.34 KB

Re-rolled patch. Added back missing elements.

Status: Needs review » Needs work

The last submitted patch, 33: 2146971-simpletest-mail-handler-33.patch, failed testing.

piyuesh23’s picture

Status: Needs work » Needs review
FileSize
7.17 KB

Fixed the PHP error. Uploading the patch again.

Status: Needs review » Needs work

The last submitted patch, 35: 2146971-simpletest-mail-handler-34.patch, failed testing.

kerby70’s picture

kerby70’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 37: simpletest_should-2146971-37.patch, failed testing.

TR’s picture

It's failing because the patch doesn't take into account the changes from #2392319: Config objects (but not config entities) should by default be immutable

kerby70’s picture

Adding the module file back in, to see if that is needed here. See what simpletest says.

kerby70’s picture

Status: Needs work » Needs review

Status: Needs review » Needs work

The last submitted patch, 41: simpletest_should-2146971-40.patch, failed testing.

kerby70’s picture

Status: Needs work » Needs review
FileSize
7.69 KB

Correcting because of #40, and re-removing the empty .module file (see #37).

kerby70’s picture

Is the following desirable still from #14, 19, 26, 28 and 29 but not in 33 or 35?

diff --git a/core/modules/simpletest/src/InstallerTestBase.php b/core/modules/simpletest/src/InstallerTestBase.php
index 2065075..bb6d154 100644
--- a/core/modules/simpletest/src/InstallerTestBase.php
+++ b/core/modules/simpletest/src/InstallerTestBase.php
@@ -161,7 +161,7 @@ protected function setUp() {
     // Manually configure the test mail collector implementation to prevent
     // tests from sending out e-mails and collect them in state instead.
     $config->get('system.mail')
-      ->set('interface.default', 'test_mail_collector')
+      ->set('interface', array('default' => 'test_mail_collector'))
       ->save();
 
     $this->isInstalled = TRUE;
kerby70’s picture

Berdir’s picture

Status: Needs review » Needs work
  1. +++ b/core/modules/simpletest/src/Tests/MailCaptureTest.php
    @@ -17,6 +17,13 @@
     class MailCaptureTest extends WebTestBase {
       /**
    +   * Modules to enable.
    +   *
    +   * @var array
    +   */
    +  public static $modules = array('mailsystem_test');
    +  ¶
    +  /**
    

    Nitpicks:

    There should be an empty line after the class and the docblock.

    Trailing spaces after the $modules lines.

  2. +++ b/core/modules/simpletest/tests/modules/mailsystem_test/mailsystem_test.info.yml
    @@ -0,0 +1,7 @@
    +core: 8.x
    +hidden: TRUE
    \ No newline at end of file
    
    +++ b/core/modules/simpletest/tests/modules/mailsystem_test/mailsystem_test.install
    @@ -0,0 +1,12 @@
    +}
    \ No newline at end of file
    

    make sure there's a newline at the end of those files, git doesn't like it if isn't.

rpayanm’s picture

Status: Needs work » Needs review
FileSize
977 bytes
7.66 KB
Mile23’s picture

andypost’s picture

  1. +++ b/core/modules/simpletest/src/Tests/MailCaptureTest.php
    @@ -16,6 +16,14 @@
    +  ¶
    

    trailing whitespace

  2. +++ b/core/modules/simpletest/tests/modules/mailsystem_test/mailsystem_test.info.yml
    @@ -0,0 +1,7 @@
    \ No newline at end of file
    

    (

Arla’s picture

Status: Needs review » Closed (duplicate)

Maybe a duplicate of #2609680

Agreed. (Although I think they had the wrong solution, as I stated there.)