Problem/Motivation

Performing outbound HTTP requests with KernelTestBase(TNG) fails. The reason is that in tests TestHttpClientMiddleware calls drupal_generate_test_ua(), which fails, because it is not properly set up.

Proposed resolution

?

Remaining tasks

User interface changes

None.

API changes

None.

Data model changes

None.

Comments

tstoeckler created an issue. See original summary.

Status: Needs review » Needs work

The last submitted patch, kernel-test-base-fail.patch, failed testing.

tstoeckler’s picture

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

The last submitted patch, kernel-test-base-fail.patch, failed testing.

Status: Needs review » Needs work

The last submitted patch, 3: 2571475-2.patch, failed testing.

The last submitted patch, 3: 2571475-2.patch, failed testing.

dawehner’s picture

mh

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.

mglaman’s picture

Just found this. Tried testing Commerce integration with a payment gateway's API in kernel test to find it exploded.

I tried unsetting test.http_client.middleware definition from the container in ::setUp but that failed. I think we need to add a check next to drupal_valid_test_ua that sees if DRUPAL_TEST_IN_CHILD_SITE is defined.

1) Drupal\Tests\commerce_authnet\Kernel\PaymentMethodTest::testRemotePaymentMethods
Use of undefined constant DRUPAL_TEST_IN_CHILD_SITE - assumed 'DRUPAL_TEST_IN_CHILD_SITE'

/Users/mglaman/Drupal/sites/commerce2x/web/core/includes/bootstrap.inc:666
/Users/mglaman/Drupal/sites/commerce2x/web/core/lib/Drupal/Core/Test/HttpClientMiddleware/TestHttpClientMiddleware.php:29
/Users/mglaman/Drupal/sites/commerce2x/vendor/guzzlehttp/guzzle/src/PrepareBodyMiddleware.php:72
/Users/mglaman/Drupal/sites/commerce2x/vendor/guzzlehttp/guzzle/src/Middleware.php:30
/Users/mglaman/Drupal/sites/commerce2x/vendor/guzzlehttp/guzzle/src/RedirectMiddleware.php:68
/Users/mglaman/Drupal/sites/commerce2x/vendor/guzzlehttp/guzzle/src/Middleware.php:59
/Users/mglaman/Drupal/sites/commerce2x/vendor/guzzlehttp/guzzle/src/HandlerStack.php:67
/Users/mglaman/Drupal/sites/commerce2x/vendor/guzzlehttp/guzzle/src/Client.php:275
/Users/mglaman/Drupal/sites/commerce2x/vendor/guzzlehttp/guzzle/src/Client.php:123
/Users/mglaman/Drupal/sites/commerce2x/vendor/guzzlehttp/guzzle/src/Client.php:129
/Users/mglaman/Drupal/sites/commerce2x/vendor/guzzlehttp/guzzle/src/Client.php:87
/Users/mglaman/Drupal/sites/commerce2x/vendor/commerceguys/authnet/src/Request/BaseRequest.php:82
/Users/mglaman/Drupal/sites/commerce2x/vendor/commerceguys/authnet/src/BaseApiRequest.php:67
/Users/mglaman/Drupal/sites/commerce2x/web/modules/contrib/commerce_authnet/src/Plugin/Commerce/PaymentGateway/AuthorizeNet.php:415
/Users/mglaman/Drupal/sites/commerce2x/web/modules/contrib/commerce_authnet/src/Plugin/Commerce/PaymentGateway/AuthorizeNet.php:339
/Users/mglaman/Drupal/sites/commerce2x/web/modules/contrib/commerce_authnet/tests/src/Kernel/PaymentMethodTest.php:65
mglaman’s picture

Status: Needs work » Needs review
StatusFileSize
new2.04 KB

This patch is allowing me to send an HTTP request to the service. This is a big blocker with using kernel tests to test integration with third party SDKs.

Status: Needs review » Needs work

The last submitted patch, 10: outbound_http_requests-2571475-10.patch, failed testing.

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

Drupal 8.1.9 was released on September 7 and is the final bugfix release for the Drupal 8.1.x series. Drupal 8.1.x will not receive any further development aside from security fixes. Drupal 8.2.0-rc1 is now available and sites should prepare to upgrade to 8.2.0.

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

sebas5384’s picture

I have the same issue, but I don't know if Kernel tests are supposed to be used to test third-party APIs for example.
Maybe exists other way of doing this.

dawehner’s picture

Interesting issue!

Version: 8.2.x-dev » 8.3.x-dev

Drupal 8.2.6 was released on February 1, 2017 and is the final full bugfix release for the Drupal 8.2.x series. Drupal 8.2.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.3.0 on April 5, 2017. (Drupal 8.3.0-alpha1 is available for testing.)

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

mglaman’s picture

Forgot, here's my workaround for now. Implement ServiceModifierInterface, then

  public function alter(ContainerBuilder $container) {
    $container->removeDefinition('test.http_client.middleware');
  }
dawehner’s picture

I believe #10 is pretty good, we just need to ensure that the constants exists, by probably not having the constant defined in the module.

blake.thompson’s picture

Just adding my experience with this issue. I tried defining the constant, for kicks, in my test setup, but that just led to this:

Drupal\Tests\mymodule\Kernel\MyTest::testMethod
file_put_contents(/vagrant/web/sites/simpletest/90225451/.htkey): failed to
open stream: No such file or directory

I ended up changing my tests that made HTTP requests to extend the BrowserTestBase instead.

mglaman’s picture

dawehner should we try to handle the constant definition, (I had same issue reported in #18) or just have base kernel test remove the service definition?

slv_’s picture

Hey there, just jumping in to mention I've experienced this problem too when trying to move convert FileDenormalizeTest (Simpletest) from the "hal" module into a KernelTest.

Not a problem for that one, as it can be simply extend BrowserTestBase instead and keep working as a functional test, but thought I'd mention it!

juampynr’s picture

Patch at #10 works fine for me.

jazzdrive3’s picture

Patch #10 also works for me.

Version: 8.3.x-dev » 8.4.x-dev

Drupal 8.3.6 was released on August 2, 2017 and is the final full bugfix release for the Drupal 8.3.x series. Drupal 8.3.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.4.0 on October 4, 2017. (Drupal 8.4.0-alpha1 is available for testing.)

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

almaudoh’s picture

Had this issue yesterday. I lost 4 hours trying to fix the test in different ways. I defined constant DRUPAL_TEST_IN_CHILD_SITE and ended up with

Drupal\Tests\mymodule\Kernel\MyTest::testMethod
file_put_contents(/webs/drupal8/sites/simpletest/XXXXXXX/.htkey): failed to
open stream: No such file or directory

I converted to BrowserTest and it still didn't work because BrowserTestBase doesn't have drupalPost(), only drupalPostForm(), and I needed to post JSON.

Eventually, I had to give up and revert to WebTestBase - bummer.

Can patch in #10 be committed?

ismail cherri’s picture

#16 worked for me actually!
Thanks @mglman

timmillwood’s picture

Status: Needs work » Needs review

I hit the same issue today.

Queued #10 for retesting.

timmillwood’s picture

Status: Needs review » Needs work

Test failed

Version: 8.4.x-dev » 8.5.x-dev

Drupal 8.4.4 was released on January 3, 2018 and is the final full bugfix release for the Drupal 8.4.x series. Drupal 8.4.x will not receive any further development aside from critical and security fixes. Sites should prepare to update to 8.5.0 on March 7, 2018. (Drupal 8.5.0-alpha1 is available for testing.)

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

Version: 8.5.x-dev » 8.6.x-dev

Drupal 8.5.6 was released on August 1, 2018 and is the final bugfix release for the Drupal 8.5.x series. Drupal 8.5.x will not receive any further development aside from security fixes. Sites should prepare to update to 8.6.0 on September 5, 2018. (Drupal 8.6.0-rc1 is available for testing.)

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

blazey’s picture

Got this error today while implementing kernel tests for webpack. The workaround from #16 solved it.

Jaesin’s picture

Un-needed re-roll

Jaesin’s picture

never mind pointless patch re-roll.

longmtran’s picture

Hit the same problem. Temporary workaround in #16 works for me!
Thanks @mglman

dakku’s picture

++ workaround in #16 works for me too!

millerrs’s picture

#16 works for me.

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

Drupal 8.6.x will not receive any further development aside from security fixes. Bug reports should be targeted against the 8.8.x-dev branch from now on, and new development or disruptive changes should be targeted against the 8.9.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.

mglaman’s picture

Status: Needs work » Needs review
StatusFileSize
new1.81 KB

Rerolled against 8.8.x.

arlina’s picture

#37 Worked for me.

eiriksm’s picture

StatusFileSize
new1.19 KB

Works for me, and patch looks good.

Uploading a test only patch (just copied from 37) to prove the bug. Will mark as RTBC if that fails.

Status: Needs review » Needs work

The last submitted patch, 39: 2571475-test-only.patch, failed testing. View results

eiriksm’s picture

Status: Needs work » Reviewed & tested by the community

🎊️

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 39: 2571475-test-only.patch, failed testing. View results

eiriksm’s picture

Status: Needs work » Reviewed & tested by the community

That was just the test only patch

alexpott’s picture

Status: Reviewed & tested by the community » Needs work
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -180,7 +180,7 @@ public function alter(ContainerBuilder $container) {
     // Do nothing if we are not in a test environment.
-    if (!drupal_valid_test_ua()) {
+    if (!defined('DRUPAL_TEST_IN_CHILD_SITE') || !drupal_valid_test_ua()) {
       return;
     }

Unfortunately the comment makes no sense. We're do nothing and we're in a test environment :)

The reason we have this problem is that under kernel tests \Drupal\Core\DrupalKernel::bootEnvironment() is never called and therefore DRUPAL_TEST_IN_CHILD_SITE is not defined. I spent some time considering if we should define DRUPAL_TEST_IN_CHILD_SITE in \Drupal\KernelTests\KernelTestBase::bootEnvironment() or \Drupal\KernelTests\KernelTestBase::bootKernel() and what that would look like. However I don't think that's right.

So I think we have 2 options here. The simple one is document this properly... i.e add something like

    // The test middleware is not required for kernel tests as there is no child site. DRUPAL_TEST_IN_CHILD_SITE is not defined is this case.
    if (!defined('DRUPAL_TEST_IN_CHILD_SITE')) {
       return;
     }

The comment probably can be improved but I think being explicit is useful.

The other option is to somehow check the Kernel environment in \Drupal\Core\CoreServiceProvider::registerTest() because in kernel tests we set it to 'testing' whereas in other tests its 'prod'. That said this solution also feels more fragile than the DRUPAL_TEST_IN_CHILD_SITE solution so let's do that - but with a more explicit comment.

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

Drupal 8.8.7 was released on June 3, 2020 and is the final full bugfix release for the Drupal 8.8.x series. Drupal 8.8.x will not receive any further development aside from security fixes. Sites should prepare to update to Drupal 8.9.0 or Drupal 9.0.0 for ongoing support.

Bug reports should be targeted against the 8.9.x-dev branch from now on, and new development or disruptive changes should 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.

otteverbeek’s picture

Any updates on this?

mxr576’s picture

I am using the workaround from #16

tedbow’s picture

Status: Needs work » Needs review
StatusFileSize
new855 bytes
new1.96 KB

Ran into this problem in #3041885: Display relevant Security Advisories data for Drupal when we just moved this functionality to the system module.

This bug makes \Drupal\KernelTests\Core\File\FileSystemRequirementsTest fail because we fetch the security advisories feed in system_requirements

Updated #37 with @alexpott's suggestion in #44 I agree it is better without it's own comment. I think the comment suggested is fine.

The test only patch in #39 can still work as the test only patch since the test has not changed. Will re-queue it.

Should we fix this first in 9.2.x now?

phenaproxima’s picture

Title: Outbound HTTP requests fail with KernelTestBase(TNG) » Outbound HTTP requests fail with KernelTestBase
Version: 8.9.x-dev » 9.2.x-dev
Status: Needs review » Reviewed & tested by the community
  1. +++ b/core/lib/Drupal/Core/CoreServiceProvider.php
    @@ -183,6 +183,11 @@ protected function registerTest(ContainerBuilder $container) {
    +    // site. DRUPAL_TEST_IN_CHILD_SITE is not defined is this case.
    

    That should be "...in this case".

  2. +++ b/core/tests/Drupal/KernelTests/KernelTestBaseTest.php
    @@ -164,6 +165,21 @@ public function testSubsequentContainerIsolation() {
    +      // Ignore any HTTP errors,
    

    That should end with a period, not a comma.

Both of these are fixable on commit, so I'm sending this right to RTBC on the assumption that the tests will come back green. Otherwise, this patch makes sense to me. I'm also re-titling the issue because I don't think we have the "old" KernelTestBase anymore anyway.

I would guess this will land in 9.2.x first and be backported, so I'm also changing the target version and queuing the latest patch up against 9.2.x.

alexpott’s picture

Version: 9.2.x-dev » 9.1.x-dev
Status: Reviewed & tested by the community » Patch (to be ported)

Committed 51e0c38 and pushed to 9.2.x. Thanks!

Will backport once bugfix releases are out and we're unfrozen.

diff --git a/core/lib/Drupal/Core/CoreServiceProvider.php b/core/lib/Drupal/Core/CoreServiceProvider.php
index fa989906b1..92e9594c34 100644
--- a/core/lib/Drupal/Core/CoreServiceProvider.php
+++ b/core/lib/Drupal/Core/CoreServiceProvider.php
@@ -132,7 +132,7 @@ protected function registerTest(ContainerBuilder $container) {
       return;
     }
     // The test middleware is not required for kernel tests as there is no child
-    // site. DRUPAL_TEST_IN_CHILD_SITE is not defined is this case.
+    // site. DRUPAL_TEST_IN_CHILD_SITE is not defined in this case.
     if (!defined('DRUPAL_TEST_IN_CHILD_SITE')) {
       return;
     }
diff --git a/core/tests/Drupal/KernelTests/KernelTestBaseTest.php b/core/tests/Drupal/KernelTests/KernelTestBaseTest.php
index 0f1d379e74..4775bf53fa 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBaseTest.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBaseTest.php
@@ -176,7 +176,7 @@ public function testOutboundHttpRequest() {
       $this->container->get('http_client')->get('http://example.com');
     }
     catch (GuzzleException $e) {
-      // Ignore any HTTP errors,
+      // Ignore any HTTP errors.
     }
   }
 

Fixed on commit.

  • alexpott committed 51e0c38 on 9.2.x
    Issue #2571475 by mglaman, tstoeckler, tedbow, eiriksm, Jaesin,...
mxr576’s picture

I'm glad that this finally fixed, but testOutboundHttpRequest() does not perform any actual assertion. Isn't that an antipattern that PHPunit also warns when it runs the test?

alexpott’s picture

@mxr576 good point - can you create a follow-up issue to add an assertion. It doesn't fail because we have an assertion in \Drupal\KernelTests\KernelTestBaseTest::tearDown()

mxr576’s picture

alexpott’s picture

Status: Patch (to be ported) » Fixed

Backported to 9.1.x.

  • alexpott committed ba2c6fb on 9.1.x
    Issue #2571475 by mglaman, tstoeckler, tedbow, eiriksm, Jaesin,...
phenaproxima’s picture

Status: Fixed » Needs work

Whilst debugging a test, @tedbow and I found a flaw in this logic: it doesn't account for DRUPAL_TEST_IN_CHILD_SITE being explicitly defined as FALSE. If the constant exists and is FALSE, then it registers the test middleware anyway, and things can get weird.

We only have been encountering this while working on #3041885: Display relevant Security Advisories data for Drupal, which adds code to the System module that uses the http_client service to make outbound HTTP requests. Adding this in System, which is a very foundational module that's close the bootstrapping and installation process, surfaces these sorts of things.

So I think we'll need to either reopen this issue, or open a follow-up, to handle the case where DRUPAL_TEST_IN_CHILD_SITE is FALSE.

tedbow’s picture

Status: Needs work » Fixed

Got some help from @mglaman on the problem in #57. Turns out we were able to solve it a different way
https://git.drupalcode.org/issue/drupal-3041885/-/compare/991f955548ef61...

I think in our case DRUPAL_TEST_IN_CHILD_SITE was actually to be TRUE anyways. So probably makes sense to open up a follow up for checking DRUPAL_TEST_IN_CHILD_SITE is FALSE but that won't have solved our problem

Status: Fixed » Closed (fixed)

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

dave reid’s picture

Version: 9.1.x-dev » 8.9.x-dev
Status: Closed (fixed) » Needs review

It looks like this should be able to be backported to Drupal 8.9 as well since it's a bug fix that touches no APIs. I've run into this several times with making HTTP requests in tests.

matroskeen’s picture

Title: Outbound HTTP requests fail with KernelTestBase » [backport] Outbound HTTP requests fail with KernelTestBase
Status: Needs review » Reviewed & tested by the community
Issue tags: +Bug Smash Initiative

Just ran into this as well (was writing a custom kernel test for 8.9.x project).

AFAIK, only Major bugs are eligible to be backported to 8.9.x. I'm gonna bump the priority because it's terrible for developer experience and would be great to have fixed in the next release.

I've applied a patch from commit to 9.1.x and it did the trick for me, therefore moving to RTBC.
Here is a link for quick access: https://git.drupalcode.org/project/drupal/commit/ba2c6fb.patch

Status: Reviewed & tested by the community » Needs work

The last submitted patch, 48: 2571475-48.patch, failed testing. View results

benjifisher’s picture

Please do not ask the testbot to try again until #3207086: [HEAD BROKEN] Consistent failure in MonthDatePluginTest is fixed.

alexpott’s picture

Status: Needs work » Reviewed & tested by the community
spokje’s picture

The fix for #3207086: [HEAD BROKEN] Consistent failure in MonthDatePluginTest still needs to be backported to the 8.9.x branch, so currently tests are still failing.

spokje’s picture

#3207086: [HEAD BROKEN] Consistent failure in MonthDatePluginTest has now been backported to branch 8.9.x.
Ordered a retest on the latest patch, which should come back green.

  • catch committed db7ab7e on 8.9.x authored by alexpott
    Issue #2571475 by mglaman, tstoeckler, tedbow, eiriksm, Jaesin,...
catch’s picture

Title: [backport] Outbound HTTP requests fail with KernelTestBase » Outbound HTTP requests fail with KernelTestBase
Status: Reviewed & tested by the community » Fixed

Backported to 8.9.x, thanks!

Status: Fixed » Closed (fixed)

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